- [+] corpse colours aren't working anymore.

- [+] bug: knocking a sleeping lf unconscious fails, they kepe
      sleeping.  need to change the f_sleeping flag! 
- [+] another secret door bug: can identify them in askcoords!! fixed.
- [+] wrong order for text:
    - [+] You attack the helpless kobold!  You kill the kobold!
          The kobold shouts "This isn't over!".
    - [+] SOLUTION: say "the dying kobold shouts ...."
- [+] only use death text somtimes. random chance.
- [+] force player sarting dir to be the one with the most LOS cells.
- [+] avian/ashkari monks
    - [+] at both initial creation and levleup:
        - [+] need to update hasattack claws, not hasattack fists.
        - [+] genericise this to just use whatever f_hasattack flag you
              have?
- [+] bug with flying creatures falling:
    - [+] You miss the giant bat.  The giant bat bites you.
          The giant bat stops flying.  The giant bat falls to the
          ground.
          The giant bat's ribs are cracked!
    - [+] was causing ATTACKER to fall, not defender.
- [+] fix bug with objects falling through pits.
- [+] new sewer map type:
    - [+] BUG:  getting empty map!!!
        - [+] roomon etc is good.
        - [+] but map empty
        - [+] probably an issue with corridor vs section size...
    - [+] make drains be locked again
    - [+] grating causes stench
    - [+] monsters:
        - [+] aquatic animals (piranha, merloch, etc)
        - [+] slimes
        - [+] troglodytes (and anything which causes stench)
        - [+] rats
        - [+] water snakes
    - [+] drains should make sounds ("you hear a drip")
- [+] snakes shouldn't get nauseated.
    - [+] F_NOSMELL.
- [+] feigh death shouldn't work on things which are attached to you
      (leech/mosquitoid)
- [+] stores should never sell gold coins!!!
    - [+] givestartobs() - give a potion of water instead if it's going
          to a shop
- [+] no resting when raged
- [+] make MAXIMUM map height higher. bumped from 20 to 30.
- [+] grating cell/object?
    - [+] liquids fall through it.
    - [+] to unlock it:
        - [+] loosen with spanner
        - [+] knock spell
        - [+] pick the lock
        - [+] lock hacker
This commit is contained in:
Rob Pearce 2011-11-30 02:06:16 +00:00
parent 6c26901e75
commit d2be8b6c6a
11 changed files with 352 additions and 191 deletions

24
ai.c
View File

@ -64,13 +64,15 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
// feigning death? // feigning death?
if (lfhasflag(victim, F_FEIGNINGDEATH)) { if (lfhasflag(victim, F_FEIGNINGDEATH)) {
int penalty; if (!lfhasflagval(lf, F_ATTACHEDTO, victim->id, NA, NA, NULL)) {
penalty = (getcelldist(lf->cell, victim->cell)-1); int penalty;
if (penalty < 0) penalty = 0; penalty = (getcelldist(lf->cell, victim->cell)-1);
penalty *= 3; if (penalty < 0) penalty = 0;
if (!skillcheckvs(lf, SC_IQ, -penalty, victim, SC_WILL, 5+gethitdice(victim))) { penalty *= 3;
dblog(".oO { attempted target fooled me with feign death. ignoring. }"); if (!skillcheckvs(lf, SC_IQ, -penalty, victim, SC_WILL, 5+gethitdice(victim))) {
return B_TRUE; dblog(".oO { attempted target fooled me with feign death. ignoring. }");
return B_TRUE;
}
} }
} }
@ -740,7 +742,7 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
/////////////////////////////////////////////// ///////////////////////////////////////////////
// need to heal? // need to heal?
if (needstorest(lf, NULL) && safetorest(lf)) { if (needstorest(lf, NULL) && safetorest(lf) && !hasflag(lf->flags, F_RAGE)) {
if (db) dblog(".oO { resting to heal }"); if (db) dblog(".oO { resting to heal }");
rest(lf, B_TRUE); rest(lf, B_TRUE);
return B_TRUE; return B_TRUE;
@ -2003,11 +2005,11 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
} }
} }
if (ot->id == OT_A_HIDE) { if (ot->id == OT_A_HIDE) {
if (lfhasflag(victim, F_HIDING)) { if (lfhasflag(lf, F_HIDING)) {
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} else if (lfhasflag(victim, F_FEIGNINGDEATH)) { } else if (lfhasflag(lf, F_FEIGNINGDEATH)) {
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} else if (!safetorest(victim)) { } else if (!safetorest(lf)) {
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
} }

View File

@ -1111,8 +1111,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
// if victim was flying and took >= 40% of its hit points, it drops to the ground. // if victim was flying and took >= 40% of its hit points, it drops to the ground.
if (isphysicaldam(damtype[i]) && (dam[i] >= pctof(40, lf->maxhp))) { if (isphysicaldam(damtype[i]) && (dam[i] >= pctof(40, victim->maxhp))) {
fall_from_air(lf); fall_from_air(victim);
} }
// if victim can still move... // if victim can still move...
if (hasfreeaction(victim)) { if (hasfreeaction(victim)) {

65
data.c
View File

@ -367,15 +367,14 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_COOKING, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_UNARMED, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_UNARMED, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SS_MENTAL, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SS_MENTAL, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_STAVES, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_STAVES, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_EXOTICWEPS, PR_NOVICE, NA, NULL);
// learnable skills // learnable skills
addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_EXOTICWEPS, PR_BEGINNER, NA, NULL); // limit addflag(lastjob->flags, F_CANLEARN, SK_EXOTICWEPS, PR_BEGINNER, NA, NULL); // limit
addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
@ -1309,14 +1308,16 @@ void initobjects(void) {
addot(OT_GRATINGFLOOR, "drainage grate", "A hatchway in the ground made of strong iron mesh.", MT_METAL, 40, OC_DFEATURE, SZ_MEDIUM); addot(OT_GRATINGFLOOR, "drainage grate", "A hatchway in the ground made of strong iron mesh.", MT_METAL, 40, OC_DFEATURE, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "a slow drip.");
addflag(lastot->flags, F_GLYPH, C_GREY, '#', NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, '#', NA, NULL);
addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, NULL); addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, NULL);
addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, NULL);
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_GRATINGROOF, NA, NA, NULL); addflag(lastot->flags, F_OPPOSITESTAIRS, OT_GRATINGROOF, NA, NA, NULL);
// TODO: add this back in ! addflag(lastot->flags, F_LOCKED, B_TRUE, 30, NA, NULL); // always starts locked
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_STENCH, B_TRUE, 1, NA, NULL);
addflag(lastot->flags, F_LOCKED, B_TRUE, 30, NA, NULL); // always starts locked
addot(OT_GRATINGROOF, "drain in the roof", "An open draining grate set into the roof.", MT_NOTHING, 0, OC_DFEATURE, SZ_LARGE); addot(OT_GRATINGROOF, "drain in the roof", "An open draining grate set into the roof.", MT_NOTHING, 0, OC_DFEATURE, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_BLUE, '<', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BLUE, '<', NA, NULL);
@ -1441,6 +1442,7 @@ void initobjects(void) {
addot(OT_TEMPLE, "temple", "A small structure dedicated to one of the gods.", MT_METAL, 500, OC_BUILDING, SZ_LARGE); addot(OT_TEMPLE, "temple", "A small structure dedicated to one of the gods.", MT_METAL, 500, OC_BUILDING, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_COMMON, "");
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "voices chanting.");
addflag(lastot->flags, F_SHOPMENU, 0, MA_GOTOMENU, 1, "a:speak to a deacon (earthly concerns)"); addflag(lastot->flags, F_SHOPMENU, 0, MA_GOTOMENU, 1, "a:speak to a deacon (earthly concerns)");
addflag(lastot->flags, F_SHOPMENU, 1, MA_GOTOMENU, 2, "b:speak to a priest (minor divine administration)"); addflag(lastot->flags, F_SHOPMENU, 1, MA_GOTOMENU, 2, "b:speak to a priest (minor divine administration)");
addflag(lastot->flags, F_SHOPMENU, 2, MA_GOTOMENU, 3, "c:speak to the bishop (major divine matters)"); addflag(lastot->flags, F_SHOPMENU, 2, MA_GOTOMENU, 3, "c:speak to the bishop (major divine matters)");
@ -1653,7 +1655,7 @@ void initobjects(void) {
// rocks // rocks
addot(OT_BOULDER, "boulder", "A massive stone boulder.", MT_STONE, 80, OC_ROCK, SZ_HUGE); addot(OT_BOULDER, "boulder", "A massive stone boulder.", MT_STONE, 80, OC_ROCK, SZ_HUGE);
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, "");
addflag(lastot->flags, F_GLYPH, NA, '\'', NA, NULL); addflag(lastot->flags, F_GLYPH, NA, '\'', NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL);
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
@ -4297,14 +4299,15 @@ void initobjects(void) {
addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LINKOB, OT_POT_ACID, NA, NA, NULL); addflag(lastot->flags, F_LINKOB, OT_POT_ACID, NA, NA, NULL);
addot(OT_SLIMEPOOL, "pool of slime", "A deep pool of sticky slime.", MT_SLIME, 300, OC_TERRAIN, SZ_HUGE); addot(OT_SLIMEPOOL, "pool of slime", "A deep pool of foul-smelling slime.", MT_SLIME, 300, OC_TERRAIN, SZ_HUGE);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_GREEN, UNI_SOLID, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREEN, UNI_SOLID, NA, NULL);
addflag(lastot->flags, F_STENCH, B_TRUE, 2, NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DEEPWATER, DP_MAX, NA, NA, NULL); addflag(lastot->flags, F_DEEPWATER, DP_MAX, NA, NA, NULL);
addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL);
addot(OT_SLIMEPUDDLE, "puddle of slime", "A disgusting mass of sticky slime.", MT_SLIME, 20, OC_MISC, SZ_MEDIUM); addot(OT_SLIMEPUDDLE, "puddle of slime", "A disgusting mass of foul-smelling slime.", MT_SLIME, 20, OC_MISC, SZ_MEDIUM);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL); addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL);
@ -4758,7 +4761,17 @@ void initobjects(void) {
addot(OT_POISONPUFF, "puff of poison gas", "A small puff of poisonous gas.", MT_GAS, 0, OC_EFFECT, SZ_MEDIUM); addot(OT_POISONPUFF, "puff of poison gas", "A small puff of poisonous gas.", MT_GAS, 0, OC_EFFECT, SZ_MEDIUM);
addflag(lastot->flags, F_GLYPH, C_GREEN, UNI_SHADELIGHT, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREEN, UNI_SHADELIGHT, NA, NULL);
addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "disperses"); addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_STENCH, B_TRUE, 1, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addot(OT_METHANEPUFF, "puff of methane gas", "A small puff of foul-smelling gas.", MT_GAS, 0, OC_EFFECT, SZ_MEDIUM);
addflag(lastot->flags, F_GLYPH, C_GREEN, UNI_SHADELIGHT, NA, NULL);
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, "disperses");
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
@ -6475,13 +6488,28 @@ void initrace(void) {
// penalties // penalties
addflag(lastrace->flags, F_PENDESC, 0, NA, NA, "Cannot use magic."); addflag(lastrace->flags, F_PENDESC, 0, NA, NA, "Cannot use magic.");
addflag(lastrace->flags, F_PENDESC, 1, NA, NA, "Vulnerable to Cold, Water and Electricity."); addflag(lastrace->flags, F_PENDESC, 1, NA, NA, "Vulnerable to Cold, Water and Electricity.");
addflag(lastrace->flags, F_PENDESC, 2, NA, NA, "Cannot wear armour on Legs, Hands, Feet or Fingers."); addflag(lastrace->flags, F_PENDESC, 2, NA, NA, "Low Agility and Wisdom.");
addflag(lastrace->flags, F_PENDESC, 3, NA, NA, "Low Agility and Wisdom."); addflag(lastrace->flags, F_PENDESC, 3, NA, NA, "Very low Charisma.");
addflag(lastrace->flags, F_PENDESC, 4, NA, NA, "Very low Charisma.");
addflag(lastrace->flags, F_DTVULN, DT_COLD, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_COLD, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_WATER, NA, NA, "2d6"); addflag(lastrace->flags, F_DTVULN, DT_WATER, NA, NA, "2d6");
addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SWIMMING, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_ALLOMANCY, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_MENTAL, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_NATURE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_AIR, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_DEATH, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_DIVINATION, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_ENCHANTMENT, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_FIRE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_COLD, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_GRAVITY, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_LIFE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_MODIFICATION, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_SUMMONING, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_TRANSLOCATION, NA, NA, NULL);
addflag(lastrace->flags, F_NOSKILL, SK_SS_WILD, NA, NA, NULL);
// other special stuff // other special stuff
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_VERYRARE, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_VERYRARE, NULL);
@ -6536,7 +6564,7 @@ void initrace(void) {
addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
// penalties // penalties
addflag(lastrace->flags, F_PENDESC, 0, NA, NA, "Below average Strength and low Wisdom, and slightly low Hit Points."); addflag(lastrace->flags, F_PENDESC, 0, NA, NA, "Below average Strength, low Wisdom, and slightly low Hit Points.");
addflag(lastrace->flags, F_PENDESC, 1, NA, NA, "Carnivorous (only eats meat)."); addflag(lastrace->flags, F_PENDESC, 1, NA, NA, "Carnivorous (only eats meat).");
addflag(lastrace->flags, F_PENDESC, 2, NA, NA, "Fast metabolism."); addflag(lastrace->flags, F_PENDESC, 2, NA, NA, "Fast metabolism.");
addflag(lastrace->flags, F_PENDESC, 3, NA, NA, "Vulnerable to Magic, Water and Sonic damage."); addflag(lastrace->flags, F_PENDESC, 3, NA, NA, "Vulnerable to Magic, Water and Sonic damage.");
@ -8842,6 +8870,7 @@ void initrace(void) {
setbodytype(lastrace, BT_SNAKE); setbodytype(lastrace, BT_SNAKE);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
@ -8865,6 +8894,7 @@ void initrace(void) {
addrace(R_SNAKECARPET, "carpet snake", 3, 's', C_GREY, MT_FLESH, RC_ANIMAL, "Non-venemous (but not quite harmless) snakes."); addrace(R_SNAKECARPET, "carpet snake", 3, 's', C_GREY, MT_FLESH, RC_ANIMAL, "Non-venemous (but not quite harmless) snakes.");
setbodytype(lastrace, BT_SNAKE); setbodytype(lastrace, BT_SNAKE);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
@ -8887,6 +8917,7 @@ void initrace(void) {
setbodytype(lastrace, BT_SNAKE); setbodytype(lastrace, BT_SNAKE);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
@ -8910,6 +8941,7 @@ void initrace(void) {
setbodytype(lastrace, BT_SNAKE); setbodytype(lastrace, BT_SNAKE);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
@ -8934,6 +8966,7 @@ void initrace(void) {
setbodytype(lastrace, BT_SNAKE); setbodytype(lastrace, BT_SNAKE);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
@ -8959,6 +8992,7 @@ void initrace(void) {
setbodytype(lastrace, BT_SNAKE); setbodytype(lastrace, BT_SNAKE);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
@ -8985,6 +9019,7 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_FREQUENT, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_FREQUENT, NULL);
addflag(lastrace->flags, F_RARITY, H_SEWER, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SEWER, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -9011,6 +9046,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+1"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+1");
@ -9036,6 +9072,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_CLIMBING, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_CLIMBING, PR_MASTER, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4+1"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4+1");
@ -9059,6 +9096,7 @@ void initrace(void) {
lastrace->baseid = R_SPIDER; lastrace->baseid = R_SPIDER;
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
@ -10477,6 +10515,7 @@ void initskills(void) {
void make_basic_shop(flagpile_t *fp) { void make_basic_shop(flagpile_t *fp) {
addflag(fp, F_SHOPMENU, 0, MA_GOTOMENU, SM_PURCHASEITEMS, "a:buy something"); addflag(fp, F_SHOPMENU, 0, MA_GOTOMENU, SM_PURCHASEITEMS, "a:buy something");
addflag(fp, F_SHOPMENU, 1, MA_QUIT, NA, "q:leave"); addflag(fp, F_SHOPMENU, 1, MA_QUIT, NA, "q:leave");
addflag(fp, F_MAKESNOISE, 33, 3, NA, "a cash register chiming.");
} }
void sortcommands(void) { void sortcommands(void) {

Binary file not shown.

23
defs.h
View File

@ -19,8 +19,10 @@
// for this many turns, abandon chase // for this many turns, abandon chase
#define DEF_ANIMDELAY (1000000 / 50) // 1/100 of a second #define DEF_ANIMDELAY (1000000 / 50) // 1/100 of a second
#define DEF_RESTHEALTIME (3) #define DEF_RESTHEALTIME (3)
#define DEF_SCREENW 80 #define DEF_SCREENW 80
#define DEF_SCREENH 24 #define DEF_SCREENH 24
#define DEF_RAGETIME 10 #define DEF_RAGETIME 10
#define DEF_SHOPIDENTPRICE (50) // cost to identify a just-purchased item #define DEF_SHOPIDENTPRICE (50) // cost to identify a just-purchased item
#define DEF_VAULTMARGIN (3) #define DEF_VAULTMARGIN (3)
@ -131,8 +133,10 @@
#define MAXFLAGS 500 #define MAXFLAGS 500
#define MAXFOLLOWLFS 15 // max # of lfs who will follow you up/down stairs #define MAXFOLLOWLFS 15 // max # of lfs who will follow you up/down stairs
#define MAXHISTORY 20 // max lines of history to keep #define MAXHISTORY 20 // max lines of history to keep
#define MAX_MAPW 80 #define MAX_MAPW 80
#define MAX_MAPH 20 #define MAX_MAPH 30
#define MAXPILEOBS 52 #define MAXPILEOBS 52
#define MAXRANDOMOBCANDIDATES 100 #define MAXRANDOMOBCANDIDATES 100
#define MAXRANDOMLFCANDIDATES 100 #define MAXRANDOMLFCANDIDATES 100
@ -382,8 +386,8 @@ enum COLOUR {
C_BOLDGREEN = 14, C_BOLDGREEN = 14,
C_DARKGREY = 15, C_DARKGREY = 15,
}; };
#define BLUEBG 50 #define BLUEBG 30
#define GREENBG 100 #define GREENBG 50
enum CASTTYPE { enum CASTTYPE {
CT_NORMAL = 0, CT_NORMAL = 0,
@ -988,6 +992,7 @@ enum MATSTATE {
MS_LIQUID, MS_LIQUID,
MS_GAS, MS_GAS,
MS_OTHER, MS_OTHER,
MS_ALL,
}; };
// Object Materials // Object Materials
@ -1563,6 +1568,7 @@ enum OBTYPE {
OT_MIST, OT_MIST,
OT_SMOKECLOUD, OT_SMOKECLOUD,
OT_SMOKEPUFF, OT_SMOKEPUFF,
OT_METHANEPUFF,
OT_POISONCLOUD, OT_POISONCLOUD,
OT_POISONPUFF, OT_POISONPUFF,
OT_VINE, OT_VINE,
@ -2071,6 +2077,10 @@ enum FLAG {
// v2 = sc_dodge difficulty // v2 = sc_dodge difficulty
F_OBJECTTRAP, // this trap can go onto an object (door, chest, etc) F_OBJECTTRAP, // this trap can go onto an object (door, chest, etc)
F_SMELLY, // lfs with enhacned scent can smell this object F_SMELLY, // lfs with enhacned scent can smell this object
F_MAKESNOISE, // object periodically makes noise.
// v0 = % chance of noise.
// v1 = volume.
// f->text is the sound made. ie. "a splash."
// shops // shops
F_BANNEDLF, // lfid v0 is not allowed to enter this shop F_BANNEDLF, // lfid v0 is not allowed to enter this shop
F_SHOP, // this object is a shop F_SHOP, // this object is a shop
@ -2280,6 +2290,8 @@ enum FLAG {
F_DONEDARKMSG, // tells the game not to say 'it is very dark here' F_DONEDARKMSG, // tells the game not to say 'it is very dark here'
F_DONELISTEN, // supress further 'you hear xx' messages this turn. F_DONELISTEN, // supress further 'you hear xx' messages this turn.
// lifeform flags / lf flags / monster flags // lifeform flags / lf flags / monster flags
F_NOSMELL, // lf can't smell. not affected by stench, and
// can't get enhancesmell.
F_RESTINGINMOTEL, // sounds will not wake up this lf. monster won't F_RESTINGINMOTEL, // sounds will not wake up this lf. monster won't
// see them. // see them.
// v0 = max time allowed to rest before checkout // v0 = max time allowed to rest before checkout
@ -2707,7 +2719,10 @@ enum FLAG {
F_STABILITY, // doesn't slip over F_STABILITY, // doesn't slip over
F_STAMREGEN, // boost stamina regeneration at 'text' per turn F_STAMREGEN, // boost stamina regeneration at 'text' per turn
// (this is a float) // (this is a float)
F_STENCH, // creatures within v0 gain f_nauseated = v1 F_STENCH, // on lifeforms:
// creatures within v0 gain f_nauseated = v1
// on objects:
// creatures standing on it gain f_nauseated = v1
F_STUNNED, // cannot attack or cast spells F_STUNNED, // cannot attack or cast spells
F_TREMORSENSE, // doesn't need eyes to see, can see in dark with v0 F_TREMORSENSE, // doesn't need eyes to see, can see in dark with v0
F_PRODUCESLIGHT, // produces light of val0 radius. F_PRODUCESLIGHT, // produces light of val0 radius.

7
io.c
View File

@ -7104,6 +7104,7 @@ void initgfx(void) {
} }
start_color(); start_color();
// 0 through 15
init_pair(C_BLACK, COLOR_BLACK, COLOR_BLACK); init_pair(C_BLACK, COLOR_BLACK, COLOR_BLACK);
init_pair(C_RED, COLOR_RED, COLOR_BLACK); init_pair(C_RED, COLOR_RED, COLOR_BLACK);
init_pair(C_GREEN, COLOR_GREEN, COLOR_BLACK); init_pair(C_GREEN, COLOR_GREEN, COLOR_BLACK);
@ -7113,7 +7114,6 @@ void initgfx(void) {
init_pair(C_MAGENTA, COLOR_MAGENTA, COLOR_BLACK); init_pair(C_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
init_pair(C_CYAN, COLOR_CYAN, COLOR_BLACK); init_pair(C_CYAN, COLOR_CYAN, COLOR_BLACK);
init_pair(C_GREY, COLOR_WHITE, COLOR_BLACK); init_pair(C_GREY, COLOR_WHITE, COLOR_BLACK);
init_pair(C_YELLOW, COLOR_YELLOW, COLOR_BLACK); init_pair(C_YELLOW, COLOR_YELLOW, COLOR_BLACK);
init_pair(C_WHITE, COLOR_WHITE, COLOR_BLACK); init_pair(C_WHITE, COLOR_WHITE, COLOR_BLACK);
init_pair(C_BOLDCYAN, COLOR_CYAN, COLOR_BLACK); init_pair(C_BOLDCYAN, COLOR_CYAN, COLOR_BLACK);
@ -7123,7 +7123,7 @@ void initgfx(void) {
init_pair(C_ORANGE, COLOR_RED, COLOR_BLACK); init_pair(C_ORANGE, COLOR_RED, COLOR_BLACK);
init_pair(C_DARKGREY, COLOR_BLACK, COLOR_BLACK); init_pair(C_DARKGREY, COLOR_BLACK, COLOR_BLACK);
// 30 through 45
init_pair(BLUEBG+C_BLACK, COLOR_BLACK, COLOR_BLUE); init_pair(BLUEBG+C_BLACK, COLOR_BLACK, COLOR_BLUE);
init_pair(BLUEBG+C_RED, COLOR_RED, COLOR_BLUE); init_pair(BLUEBG+C_RED, COLOR_RED, COLOR_BLUE);
init_pair(BLUEBG+C_GREEN, COLOR_GREEN, COLOR_BLUE); init_pair(BLUEBG+C_GREEN, COLOR_GREEN, COLOR_BLUE);
@ -7141,6 +7141,7 @@ void initgfx(void) {
init_pair(BLUEBG+C_BOLDGREEN, COLOR_GREEN, COLOR_BLUE); init_pair(BLUEBG+C_BOLDGREEN, COLOR_GREEN, COLOR_BLUE);
init_pair(BLUEBG+C_ORANGE, COLOR_RED, COLOR_BLUE); init_pair(BLUEBG+C_ORANGE, COLOR_RED, COLOR_BLUE);
// 50 through 65
init_pair(GREENBG+C_BLACK, COLOR_BLACK, COLOR_GREEN); init_pair(GREENBG+C_BLACK, COLOR_BLACK, COLOR_GREEN);
init_pair(GREENBG+C_RED, COLOR_RED, COLOR_GREEN); init_pair(GREENBG+C_RED, COLOR_RED, COLOR_GREEN);
init_pair(GREENBG+C_GREEN, COLOR_GREEN, COLOR_GREEN); init_pair(GREENBG+C_GREEN, COLOR_GREEN, COLOR_GREEN);
@ -10673,7 +10674,7 @@ void showlfstats(lifeform_t *lf, int showall) {
} else { } else {
f = lfhasknownflag(lf, F_ATTRMOD); f = lfhasknownflag(lf, F_ATTRMOD);
if (f && (f->known)) { if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s has been %s.", your(lf), getattrname(f->val[0]), (f->val[2] > 0) ? "increased" : "decreased"); mvwprintw(mainwin, y, 0, "%s %s has been %s.", your(lf), getattrname(f->val[0]), (f->val[1] > 0) ? "increased" : "decreased");
y++; y++;
} }
} }

155
lf.c
View File

@ -2289,7 +2289,9 @@ void die(lifeform_t *lf) {
// makenoise(lf, N_DIE); // makenoise(lf, N_DIE);
} }
} else if (cantalk(lf)) { } else if (cantalk(lf)) {
sayphrase(lf, SP_DIE, SV_SHOUT, NA, NULL); if (pctchance(33)) {
sayphrase(lf, SP_DIE, SV_SHOUT, NA, NULL);
}
} }
if (!hasflag(lf->flags, F_NODEATHANNOUNCE)) { if (!hasflag(lf->flags, F_NODEATHANNOUNCE)) {
@ -3329,8 +3331,10 @@ void enhanceskills(lifeform_t *lf) {
if (gainedxplev) { if (gainedxplev) {
// special cases which happen before doing hp/mp // special cases which happen before doing hp/mp
if (hasjob(lf, J_MONK) && (lf->level == 2)) { if (hasjob(lf, J_MONK) && (lf->level == 2) && !lfhasflag(lf, F_NOSPELLS)) {
addflag(lf->flags, F_MPDICE, 1, 0, NA, NULL); if (!lfhasflag(lf, F_MPDICE)) {
addflag(lf->flags, F_MPDICE, 1, 0, NA, NULL);
}
} }
// update hp // update hp
@ -3614,59 +3618,15 @@ void enhanceskills(lifeform_t *lf) {
// special case level-based job effects // special case level-based job effects
if (hasjob(lf, J_MONK)) { if (hasjob(lf, J_MONK)) {
// enhance fist strength // enhance fist strength
f = lfhasflagval(lf, F_HASATTACK, OT_FISTS, NA, NA, NULL); //f = lfhasflagval(lf, F_HASATTACK, OT_FISTS, NA, NA, NULL);
f = lfhasflag(lf, F_HASATTACK);
if (f) { if (f) {
int newdr; int newdr;
//newdr = ((lf->level+1) / 2) + 2;
newdr = lf->level+2; newdr = lf->level+2;
/* if (newdr <= f->val[1]) {
switch(lf->level) { // do nothing - your unarmed attack was already stronger or
case 2: // equivilant.
newdr = 4; break; } else if (newdr > f->val[1]) {
case 3:
newdr = 5; break;
case 4:
newdr = 6; break;
case 5:
newdr = 7; break;
case 6:
newdr = 8; break;
case 7:
newdr = 9; break;
case 8:
newdr = 10; break;
case 9:
case 10:
newdr = 11; break;
case 11:
case 12:
newdr = 12; break;
case 13:
case 14:
newdr = 13; break;
case 15:
case 16:
case 17:
newdr = 14; break;
strcpy(newtext,"4d6");
break;
case 18:
strcpy(newtext,"6d4");
break;
case 19:
strcpy(newtext,"5d6");
break;
case 20:
strcpy(newtext,"8d4");
break;
default:
strcpy(newtext,"6d6");
break;
}
*/
if (newdr != f->val[1]) {
//if (!streq(newtext, f->text)) {
// changeflagtext(f, newtext);
f->val[1] = newdr; f->val[1] = newdr;
if (isplayer(lf)) msg("^gYour unarmed attack damage has increased!"); if (isplayer(lf)) msg("^gYour unarmed attack damage has increased!");
} }
@ -3690,7 +3650,7 @@ void enhanceskills(lifeform_t *lf) {
} else if (lf->level >= 17) { } else if (lf->level >= 17) {
min = 3; max = 4; min = 3; max = 4;
} }
if ((min != f->val[0]) || (max != f->val[1])) { if ((min > f->val[0]) || (max > f->val[1])) {
f->val[0] = min; f->val[0] = min;
f->val[1] = max; f->val[1] = max;
if (isplayer(lf)) msg("^gYour number of unarmed attacks has increased!"); if (isplayer(lf)) msg("^gYour number of unarmed attacks has increased!");
@ -3785,8 +3745,14 @@ int fall(lifeform_t *lf, lifeform_t *fromlf, int announce) {
// if you are going to sleep on purpose, use 'gotosleep'. // if you are going to sleep on purpose, use 'gotosleep'.
// this function is for when it is forced upon you by a spell, etc. // this function is for when it is forced upon you by a spell, etc.
int fallasleep(lifeform_t *lf, enum SLEEPTYPE how, int howlong) { int fallasleep(lifeform_t *lf, enum SLEEPTYPE how, int howlong) {
if (lfhasflag(lf, F_ASLEEP)) { flag_t *f;
return B_TRUE; f = lfhasflag(lf, F_ASLEEP);
if (f) {
if (f->val[1] == how) {
return B_TRUE;
} else {
killflag(f);
}
} }
if ((how == ST_ASLEEP) && lfhasflag(lf, F_CAFFEINATED)) { if ((how == ST_ASLEEP) && lfhasflag(lf, F_CAFFEINATED)) {
@ -6307,12 +6273,24 @@ glyph_t *getlfglyph(lifeform_t *lf) {
if (lf->cell && (getcellwaterdepth(lf->cell, player) >= DP_WAIST)) { if (lf->cell && (getcellwaterdepth(lf->cell, player) >= DP_WAIST)) {
object_t *o; object_t *o;
int bgcol = 0;
o = hasobwithflag(lf->cell->obpile, F_DEEPWATER); o = hasobwithflag(lf->cell->obpile, F_DEEPWATER);
switch (o->type->material->id) { switch (o->type->material->id) {
case MT_WATER: tempglyph.colour += BLUEBG; break; case MT_WATER: bgcol = BLUEBG; break;
case MT_SLIME: tempglyph.colour += GREENBG; break; case MT_SLIME: bgcol = GREENBG; break;
default: break; default: break;
} }
if (bgcol) {
// avoid having the same foreground and background colour
int fixfg = B_FALSE;
if ((bgcol == BLUEBG) && (tempglyph.colour == C_BLUE)) {
fixfg = B_TRUE;
} else if ((bgcol == GREENBG) && (tempglyph.colour == C_GREEN)) {
fixfg = B_TRUE;
}
if (fixfg) tempglyph.colour = C_BLACK;
tempglyph.colour += bgcol;
}
} }
//return &lf->race->glyph; //return &lf->race->glyph;
@ -7998,13 +7976,16 @@ void givejob(lifeform_t *lf, enum JOB jobid) {
// special cases // special cases
if (j->id == J_MONK) { if (j->id == J_MONK) {
flag_t *f; flag_t *f;
f = lfhasflagval(lf, F_HASATTACK, OT_FISTS, NA, NA, NULL); // monk fists do more damage
// also, they always use fists, even if the race has claws etc.
f = lfhasflag(lf, F_HASATTACK);
if (f) { if (f) {
// monk fists do more damage f->val[0] = OT_FISTS;
f->val[1] = 3; f->val[1] = 3;
} }
} else if (j->id == J_PIRATE) { } else if (j->id == J_PIRATE) {
flag_t *f; flag_t *f;
// pirate has a hook instead of a hand
f = lfhasflagval(lf, F_HASATTACK, OT_FISTS, NA, NA, NULL); f = lfhasflagval(lf, F_HASATTACK, OT_FISTS, NA, NA, NULL);
if (f) { if (f) {
f->val[0] = OT_HOOKHAND; f->val[0] = OT_HOOKHAND;
@ -8425,6 +8406,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
obpile_t *op; obpile_t *op;
map_t *targmap; map_t *targmap;
enum LFSIZE maxobsize = SZ_MAX; enum LFSIZE maxobsize = SZ_MAX;
int isshop = B_FALSE;
if (targob) { if (targob) {
cell_t *c; cell_t *c;
@ -8432,6 +8414,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
c = getoblocation(targob); c = getoblocation(targob);
targmap = c->map; targmap = c->map;
maxobsize = getobsize(targob); maxobsize = getobsize(targob);
if (hasflag(targob->flags, F_SHOP)) isshop = B_TRUE;
} else { } else {
op = lf->pack; op = lf->pack;
targmap = lf->cell->map; targmap = lf->cell->map;
@ -8568,6 +8551,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
// if (getrandomobofsize(targmap, buf, maxobsize)) { // if (getrandomobofsize(targmap, buf, maxobsize)) {
if (real_getrandomob(targmap, buf, targmap->depth + depthmod, NA, maxobsize, B_TRUE, OC_NONE, DT_NONE)) { if (real_getrandomob(targmap, buf, targmap->depth + depthmod, NA, maxobsize, B_TRUE, OC_NONE, DT_NONE)) {
if (isshop && strstr(buf, "gold coin")) strcpy(buf, "potion of water");
o = addob(op, buf); o = addob(op, buf);
} }
} }
@ -8586,6 +8570,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
} }
if (real_getrandomob(targmap, buf, targmap->depth + depthmod, NA, maxobsize, B_TRUE, OC_NONE, val[1], DT_NONE)) { if (real_getrandomob(targmap, buf, targmap->depth + depthmod, NA, maxobsize, B_TRUE, OC_NONE, val[1], DT_NONE)) {
if (db) snprintf(buf2, BUFLEN, "finished startobdt successfuly."); if (db) snprintf(buf2, BUFLEN, "finished startobdt successfuly.");
if (isshop && strstr(buf, "gold coin")) strcpy(buf, "potion of water");
o = addob(op, buf); o = addob(op, buf);
} else { } else {
if (db) snprintf(buf2, BUFLEN, "finished startobdt, failed."); if (db) snprintf(buf2, BUFLEN, "finished startobdt, failed.");
@ -8611,6 +8596,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
if (real_getrandomob(targmap, buf, getmapdifficulty(targmap) + depthmod, NA, maxobsize, B_TRUE, if (real_getrandomob(targmap, buf, getmapdifficulty(targmap) + depthmod, NA, maxobsize, B_TRUE,
val[1], OC_NONE, DT_NONE)) { val[1], OC_NONE, DT_NONE)) {
if (db) snprintf(buf2, BUFLEN, "finished startobclass, success."); if (db) snprintf(buf2, BUFLEN, "finished startobclass, success.");
if (isshop && strstr(buf, "gold coin")) strcpy(buf, "potion of water");
o = addob(op, buf); o = addob(op, buf);
} else { } else {
//obdb = B_FALSE; //obdb = B_FALSE;
@ -11822,9 +11808,17 @@ void makefriendly(lifeform_t *who, int howlong) {
int makenauseated(lifeform_t *lf, int amt, int howlong) { int makenauseated(lifeform_t *lf, int amt, int howlong) {
flag_t *f; flag_t *f;
if (isundead(lf)) return B_TRUE; switch (lf->race->raceclass->id) {
if (!hasbp(lf, BP_HEAD)) return B_TRUE; // can't smell with no head case RC_HUMANOID:
case RC_ANIMAL:
break;
default:
return B_TRUE;
}
if (lfhasflag(lf, F_STENCH)) return B_TRUE; // your own smell makes you used to it if (lfhasflag(lf, F_STENCH)) return B_TRUE; // your own smell makes you used to it
if (lfhasflag(lf, F_NOSMELL)) return B_TRUE; // can't smell it.
if (!hasbp(lf, BP_HEAD)) return B_TRUE; // can't smell with no head
if (lfhasflag(lf, F_ENHANCESMELL)) amt += 2; if (lfhasflag(lf, F_ENHANCESMELL)) amt += 2;
@ -12337,7 +12331,11 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
*quotepos = '\0'; *quotepos = '\0';
strcat(realseetext, "something"); strcat(realseetext, "something");
} }
msg("%s %s.", lfname, realseetext); if (isdead(noisemaker)) {
msg("The dying %s %s.", noprefix(lfname), realseetext);
} else {
msg("%s %s.", lfname, realseetext);
}
if ((realseetext[0] == '\0') || !strlen(realseetext)) { if ((realseetext[0] == '\0') || !strlen(realseetext)) {
dblog("xxx"); dblog("xxx");
} }
@ -13258,6 +13256,10 @@ int startresting(lifeform_t *lf, int willtrain) {
return B_TRUE; return B_TRUE;
} }
} }
if (lfhasflag(lf, F_RAGE)) {
if (isplayer(lf)) msg("You are too enraged to rest!");
return B_TRUE;
}
// stop hiding // stop hiding
killflagsofid(lf->flags, F_HIDING); killflagsofid(lf->flags, F_HIDING);
@ -14781,12 +14783,6 @@ void startlfturn(lifeform_t *lf) {
} }
} }
// get nauseated if in the sewer
if (lf->cell && (lf->cell->habitat->id == H_SEWER)) {
makenauseated(lf, 2, 2);
}
// get more hungry // get more hungry
modhunger(lf, 1); modhunger(lf, 1);
@ -15003,6 +14999,11 @@ void startlfturn(lifeform_t *lf) {
if (f && f->lifetime > 0) { if (f && f->lifetime > 0) {
f->lifetime = DEF_RAGETIME/2; f->lifetime = DEF_RAGETIME/2;
} else { } else {
if (isplayer(lf)) {
char lfname[BUFLEN];
getlfname(otherlf, lfname);
msg("The sight of %s makes your blood boil!", lfname);
}
addtempflag(lf->flags, F_RAGE, B_TRUE, NA, NA, NULL, DEF_RAGETIME/2); addtempflag(lf->flags, F_RAGE, B_TRUE, NA, NA, NULL, DEF_RAGETIME/2);
if (getstamina(lf) < 1) setstamina(lf, 1); if (getstamina(lf) < 1) setstamina(lf, 1);
forceredraw(); forceredraw();
@ -15062,7 +15063,7 @@ void startlfturn(lifeform_t *lf) {
for (l = lf->cell->map->lf ; l ; l = l->next) { for (l = lf->cell->map->lf ; l ; l = l->next) {
if (!isdead(l) && (l != lf)) { if (!isdead(l) && (l != lf)) {
if (l->race->baseid != lf->race->baseid) { // can't smell your own race. if (l->race->baseid != lf->race->baseid) { // can't smell your own race.
// gains/loses stench? // gains/loses nauseation?
f = lfhasflag(l, F_STENCH); f = lfhasflag(l, F_STENCH);
if (f) { if (f) {
int range,power; int range,power;
@ -15147,7 +15148,7 @@ void startlfturn(lifeform_t *lf) {
if (skillcheck(lf, SC_SEARCH, diff, mod)) { if (skillcheck(lf, SC_SEARCH, diff, mod)) {
char obname[BUFLEN]; char obname[BUFLEN];
// reveal it // reveal it
getobname(o, obname, o->amt); real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_TRUE);
msg("^wYou notice %s!",obname); msg("^wYou notice %s!",obname);
interrupt(lf); interrupt(lf);
killflag(f); killflag(f);
@ -15326,7 +15327,7 @@ void startlfturn(lifeform_t *lf) {
} }
if (isdead(lf)) return; if (isdead(lf)) return;
// damage from cell objects? // effects from cell objects?
for (o = lf->cell->obpile->first ; o ; o = o->next) { for (o = lf->cell->obpile->first ; o ; o = o->next) {
f = hasflag(o->flags, F_WALKDAM); f = hasflag(o->flags, F_WALKDAM);
if (f) { if (f) {
@ -15351,6 +15352,10 @@ void startlfturn(lifeform_t *lf) {
} }
f = hasflag(o->flags, F_STENCH);
if (f) {
makenauseated(lf, f->val[1], 2);
}
// for flags which can occur multiple times // for flags which can occur multiple times
getflags(o->flags, retflag, &nretflags, F_DEEPWATER, F_WALKDAMBP, F_NONE); getflags(o->flags, retflag, &nretflags, F_DEEPWATER, F_WALKDAMBP, F_NONE);
@ -15400,6 +15405,7 @@ void startlfturn(lifeform_t *lf) {
if (isdead(lf)) return; if (isdead(lf)) return;
// effects for/on your own flags
getflags(lf->flags, retflag, &nretflags, F_ATTACHEDTO, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FLEEFROM, getflags(lf->flags, retflag, &nretflags, F_ATTACHEDTO, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FLEEFROM,
F_GRABBEDBY, F_GRABBING, F_GUNTARGET, F_BOOSTSPELL, F_FEIGNINGDEATH, F_INJURY, F_GRABBEDBY, F_GRABBING, F_GUNTARGET, F_BOOSTSPELL, F_FEIGNINGDEATH, F_INJURY,
F_NOFLEEFROM, F_PETOF, F_SPOTTED, F_STABBEDBY, F_TARGETCELL, F_TARGETLF, F_NONE); F_NOFLEEFROM, F_PETOF, F_SPOTTED, F_STABBEDBY, F_TARGETCELL, F_TARGETLF, F_NONE);
@ -16829,6 +16835,11 @@ int validateraces(void) {
printf("ERROR in race '%s' - has NOISETEXT but no volume.\n", r->name); printf("ERROR in race '%s' - has NOISETEXT but no volume.\n", r->name);
goterror = B_TRUE; goterror = B_TRUE;
} }
} else if (f->id == F_NOSMELL) {
if (hasflag(r->flags, F_ENHANCESMELL)) {
printf("ERROR in race '%s' - has both NOSMELL and ENHANCESMELL.\n", r->name);
goterror = B_TRUE;
}
} }
} // end foreach flag } // end foreach flag

53
map.c
View File

@ -2960,20 +2960,28 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
int numon = 0; int numon = 0;
char buf[BUFLEN]; char buf[BUFLEN];
// select room size corridorsize = rnd(2,3);
//roomsize = 5; roomfullsize = rnd(5,9); if ((roomfullsize % 2) == 0) roomfullsize++;
sectionsize = rnd(5,9); sectionsize = corridorsize + roomfullsize;
// must be an odd number roomsize = roomfullsize - 2; // don't include outer walls.
if ((sectionsize % 2) == 0) sectionsize++;
// subtract corridor size
corridorsize = rnd(2,3);
roomfullsize = sectionsize - corridorsize;
roomsize = roomsize - 2; // ie. don't include outer walls
// select how many very/horz rooms // select how many very/horz rooms
maxroomsx = (map->w - 1) / (sectionsize); // we are being over cautious here since "sectionsize"
maxroomsy = (map->h - 1) / (sectionsize); // is a room + corridor.
// (x-1) corridors. ie:
// Room --- Room --- Room xxx
// | | |
// | | |
// Room --- Room --- Room xxx
// x x x
// x x x
//
// == Across: 3 rooms, 2 corridors
// == Down: 2 rooms, 1 corridor
/// x = left over sectionsize
maxroomsx = ((map->w - 2) ) / (sectionsize);
maxroomsy = ((map->h - 2) ) / (sectionsize);
roomcountx = maxroomsx; roomcountx = maxroomsx;
roomcounty = maxroomsy; roomcounty = maxroomsy;
@ -2994,7 +3002,7 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
while (numon == 0) { while (numon == 0) {
for (ry = 0; ry < roomcounty; ry++) { for (ry = 0; ry < roomcounty; ry++) {
for (rx = 0; rx < roomcountx; rx++) { for (rx = 0; rx < roomcountx; rx++) {
i = rx * ry; i = (ry*roomcountx)+rx;
if (pctchance(66)) { if (pctchance(66)) {
roomon[i] = B_TRUE; roomon[i] = B_TRUE;
@ -3010,7 +3018,7 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
for (ry = 0; ry < roomcounty; ry++) { for (ry = 0; ry < roomcounty; ry++) {
rowfirst[ry] = -1; rowfirst[ry] = -1;
for (rx = 0; rx < roomcountx; rx++) { for (rx = 0; rx < roomcountx; rx++) {
i = rx * ry; i = (ry*roomcountx)+rx;
if (roomon[i]) { if (roomon[i]) {
if (rowfirst[ry] == -1) { if (rowfirst[ry] == -1) {
rowfirst[ry] = rx; rowfirst[ry] = rx;
@ -3023,7 +3031,7 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
for (rx = 0; rx < roomcountx; rx++) { for (rx = 0; rx < roomcountx; rx++) {
colfirst[rx] = -1; colfirst[rx] = -1;
for (ry = 0; ry < roomcounty; ry++) { for (ry = 0; ry < roomcounty; ry++) {
i = rx * ry; i = (ry*roomcountx)+rx;
if (roomon[i]) { if (roomon[i]) {
if (colfirst[rx] == -1) { if (colfirst[rx] == -1) {
colfirst[rx] = ry; colfirst[rx] = ry;
@ -3034,11 +3042,14 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
} }
dblog("SEWER debug:"); dblog("SEWER debug:");
dblog(" sectionsize is %d (room=%d, corridor=%d)", sectionsize, roomfullsize, corridorsize);
dblog(" roomcountx is %d, roomcounty is %d", roomcountx, roomcounty);
for (ry = 0; ry < roomcounty; ry++) { for (ry = 0; ry < roomcounty; ry++) {
char buf2[BUFLEN]; char buf2[BUFLEN];
strcpy(buf, ""); strcpy(buf, "");
for (rx = 0; rx < roomcountx; rx++) { for (rx = 0; rx < roomcountx; rx++) {
if (roomon[rx*ry]) { i = (ry*roomcountx)+rx;
if (roomon[i]) {
strcat(buf, "#"); strcat(buf, "#");
} else { } else {
strcat(buf, "-"); strcat(buf, "-");
@ -3057,7 +3068,8 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
// add square rooms in a gridlike layout // add square rooms in a gridlike layout
for (ry = 0; ry < roomcounty; ry++) { for (ry = 0; ry < roomcounty; ry++) {
for (rx = 0; rx < roomcountx; rx++) { for (rx = 0; rx < roomcountx; rx++) {
if (roomon[rx*ry]) { i = (ry*roomcountx)+rx;
if (roomon[i]) {
int thisid; int thisid;
int x2,y2; int x2,y2;
thisid = map->nrooms; thisid = map->nrooms;
@ -3117,6 +3129,7 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
} }
if (makewalkway) setcelltype(c, c->habitat->emptycelltype); if (makewalkway) setcelltype(c, c->habitat->emptycelltype);
} else if (c->type->id == CT_LOWFLOOR) { } else if (c->type->id == CT_LOWFLOOR) {
// any water cell orthogonally surrounded by water becomes very deep
int dir,surrounded = B_TRUE; int dir,surrounded = B_TRUE;
for (dir = D_N; dir <= D_W; dir++) { for (dir = D_N; dir <= D_W; dir++) {
c2 = getcellindir(c, dir); c2 = getcellindir(c, dir);
@ -3132,7 +3145,6 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
} }
} }
// any water cell orthogonally surrounded by water becomes very deep
// now move all objects out of the water // now move all objects out of the water
@ -3151,8 +3163,9 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
} }
// add the exit. make sure it's next to a wall so it's possible to climb to. // add the exit. make sure it's next to a wall so it's possible to climb to.
// also ensure it's not over water.
c = NULL; c = NULL;
while (!c || (countadjwalls(c) == 0)) { while (!c || (countadjwalls(c) == 0) || getcellwaterdepth(c, NULL)) {
c = getrandomroomcell(map, ANYROOM); c = getrandomroomcell(map, ANYROOM);
assert(c); assert(c);
} }
@ -3312,7 +3325,7 @@ void killfakes(map_t *map, cell_t *cell) {
// if 'wantfilled' is set, only link to "filled" cells. // if 'wantfilled' is set, only link to "filled" cells.
// return TRUE on failure. // return TRUE on failure.
int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) { int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
int db = B_TRUE; int db = B_FALSE;
int d, roomid; int d, roomid;
int poss2[MAXCANDIDATES],nposs2; int poss2[MAXCANDIDATES],nposs2;
int dist[MAXDIR_ORTH],hitsedge[MAXDIR_ORTH], sameroom[MAXDIR_ORTH]; int dist[MAXDIR_ORTH],hitsedge[MAXDIR_ORTH], sameroom[MAXDIR_ORTH];
@ -3702,7 +3715,7 @@ int linkexits(map_t *m, int roomid) {
int x,y,i; int x,y,i;
cell_t *poss[MAXCANDIDATES],*c; cell_t *poss[MAXCANDIDATES],*c;
int nposs = 0; int nposs = 0;
int db = B_TRUE; int db = B_FALSE;
int nadded = 0; int nadded = 0;
int minx = -1, miny = -1, maxx = -1, maxy = -1; int minx = -1, miny = -1, maxx = -1, maxy = -1;
int roomidx = -1; int roomidx = -1;

23
nexus.c
View File

@ -467,8 +467,22 @@ int main(int argc, char **argv) {
// redo light and player los // redo light and player los
calclight(player->cell->map); calclight(player->cell->map);
player->facing = rnd(DC_N, DC_NW);
precalclos(player); // make player face the direction which gives them the most visibility
if (newworld) {
int bestdir = D_NONE;
int bestlos = -1;
for (i = DC_N; i <= DC_NW; i++) {
setfacing(player, i);
precalclos(player);
if (player->nlos > bestlos) {
bestlos = player->nlos;
bestdir = i;
}
}
player->facing = bestdir;
precalclos(player);
}
// show level // show level
drawscreen(); drawscreen();
@ -1376,6 +1390,10 @@ int rollmpdice(lifeform_t *lf, int wantmax) {
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags; int nretflags;
if (lfhasflag(lf, F_NOSPELLS)) {
return 0;
}
f = hasflag(lf->flags, F_MPDICE); f = hasflag(lf->flags, F_MPDICE);
if (f) { if (f) {
ndice = f->val[0]; ndice = f->val[0];
@ -1601,6 +1619,7 @@ void timeeffectsworld(map_t *map, int updategametime) {
} }
pit = hasobwithflagval(c->obpile, F_PIT, D_DOWN, NA, NA, NULL); pit = hasobwithflagval(c->obpile, F_PIT, D_DOWN, NA, NA, NULL);
if (!pit) pit = hasob(c->obpile, OT_GRATINGFLOOR);
if (pit) { if (pit) {
obsfallthrough(c, pit); obsfallthrough(c, pit);
} }

163
objects.c
View File

@ -2558,16 +2558,17 @@ int checkobnames(char *haystack, char *needle) {
void colourmatchob(object_t *o, lifeform_t *lf) { void colourmatchob(object_t *o, lifeform_t *lf) {
flag_t *f; flag_t *f;
glyph_t *lfglyph; glyph_t *glyph;
lfglyph = getlfglyph(lf); enum COLOUR wantcol;
glyph = getlfglyph(lf);
wantcol = glyph->colour;
f = hasflag(o->flags, F_GLYPH); f = hasflag(o->flags, F_GLYPH);
if (f) { if (f) {
f->val[1] = lfglyph->colour; f->val[0] = wantcol;
} else { } else {
glyph_t *obglyph; glyph = getglyph(o);
obglyph = getglyph(o); addflag(o->flags, F_GLYPH, wantcol, glyph->ch, NA, NULL);
addflag(o->flags, F_GLYPH, lfglyph->colour, obglyph->ch, NA, NULL);
} }
} }
@ -4809,7 +4810,14 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
} }
if (issecretdoor(o)) { if (issecretdoor(o)) {
strcat(localbuf, "secret "); if (showall) {
strcat(localbuf, "secret ");
} else if (where) {
celltype_t *ct;
ct = findcelltype(where->map->habitat->solidcelltype);
// solid cell description
strcpy(pluralname, ct->name);
}
} }
// object name // object name
@ -7562,49 +7570,68 @@ flag_t *obrestrictsmovement(object_t *o, lifeform_t *lf) {
// returns # objects which fell through // returns # objects which fell through
int obsfallthrough(cell_t *c, object_t *pit) { int obsfallthrough(cell_t *c, object_t *pit) {
object_t *oo,*uphole; object_t *oo,*nextoo,*uphole = NULL;
cell_t *belowcell; cell_t *belowcell;
char obname[BUFLEN],downholename[BUFLEN],upholename[BUFLEN]; char obname[BUFLEN],downholename[BUFLEN],upholename[BUFLEN];
int nfallen = 0; int nfallen = 0;
belowcell = getstairdestination(pit, NULL); belowcell = getstairdestination(pit, NULL);
if (!belowcell) return 0;
uphole = hasobwithflagval(belowcell->obpile, F_PIT, D_UP, NA, NA, NULL);
getobname(pit,downholename, 1); getobname(pit,downholename, 1);
getobname(uphole,upholename, 1);
for (oo = c->obpile->first ; oo ; oo = oo->next) {
if (oo == pit) continue;
if (!hasflag(oo->flags, F_NOPICKUP)) {
int canseebelowlf = B_FALSE;
// fall through!
if (haslos(player, c)) {
// player can see the top of the hole
getobname(oo,obname, oo->amt);
msg("%s fall%s through %s.", obname,
(oo->amt == 1) ? "s" : "",
downholename);
}
if (belowcell) {
uphole = hasobwithflagval(belowcell->obpile, F_PIT, D_UP, NA, NA, NULL);
getobname(uphole,upholename, 1);
}
for (oo = c->obpile->first ; oo ; oo = nextoo) {
int canseebelowlf = B_FALSE;
char verb[BUFLEN];
nextoo = oo->next;
if (oo == pit) continue;
if (hasflag(pit->flags, F_PIT)) {
//nopickup objects don't fall down pits.
if (hasflag(oo->flags, F_NOPICKUP)) continue;
strcpy(verb, "fall");
} else if (pit->type->id == OT_GRATINGFLOOR) {
// only liquid falls through gratings
if (getmaterialstate(oo->material->id) != MS_LIQUID) continue;
strcpy(verb, "drain");
} else {
strcpy(verb, "fall");
}
// fall through!
if (haslos(player, c)) {
// player can see the top of the hole
getobname(oo,obname, oo->amt);
msg("%s %s%s through %s.", obname, verb,
(oo->amt == 1) ? "s" : "",
downholename);
}
nfallen++;
if (belowcell) {
// remember if we can see the bottom cell before the object drops // remember if we can see the bottom cell before the object drops
if (belowcell->lf && cansee(player, belowcell->lf)) { if (belowcell->lf && cansee(player, belowcell->lf)) {
canseebelowlf = B_TRUE; canseebelowlf = B_TRUE;
} }
moveob(oo, belowcell->obpile, oo->amt); oo = moveob(oo, belowcell->obpile, oo->amt);
if (haslos(player, belowcell)) { if (haslos(player, belowcell)) {
// player can see the bottom of the hole // player can see the bottom of the hole
getobname(oo,obname, oo->amt); getobname(oo,obname, oo->amt);
msg("%s fall%s through %s.", obname, msg("%s %s%s through %s.", obname, verb,
(oo->amt == 1) ? "s" : "", (oo->amt == 1) ? "s" : "",
upholename); upholename);
} }
// does the object hit anyone? // does the object hit anyone?
if (belowcell->lf) { if (belowcell->lf && (getmaterialstate(oo->material->id) == MS_SOLID)) {
lifeform_t *lf; lifeform_t *lf;
char dambuf[BUFLEN]; char dambuf[BUFLEN];
lf = belowcell->lf; lf = belowcell->lf;
@ -7620,8 +7647,8 @@ int obsfallthrough(cell_t *c, object_t *pit) {
snprintf(dambuf, BUFLEN, "a falling %s", oo->type->name); snprintf(dambuf, BUFLEN, "a falling %s", oo->type->name);
losehp(lf, getthrowdam(oo) * 6, DT_PROJECTILE, NULL, dambuf); losehp(lf, getthrowdam(oo) * 6, DT_PROJECTILE, NULL, dambuf);
} }
} else {
nfallen++; killob(oo);
} }
} }
return nfallen; return nfallen;
@ -8300,27 +8327,29 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
for (oo = c->obpile->first ; oo ; oo = nextoo) { for (oo = c->obpile->first ; oo ; oo = nextoo) {
nextoo = oo->next; nextoo = oo->next;
flag_t *f; flag_t *f;
f = hasflag(oo->flags, F_LOCKED); if (hasflag(oo->flags, F_LOCKABLE)) {
if (f) { f = hasflag(oo->flags, F_LOCKED);
killflag(f); if (f) {
if (isplayer(lf)) { killflag(f);
msg("Your %s beeps.", noprefix(obname)); if (isplayer(lf)) {
} else if (cansee(player, lf)) { msg("Your %s beeps.", noprefix(obname));
char lfname[BUFLEN]; } else if (cansee(player, lf)) {
getlfname(lf, lfname); char lfname[BUFLEN];
msg("%s%s %s beeps.", lfname, getpossessive(lfname), getlfname(lf, lfname);
noprefix(obname)); msg("%s%s %s beeps.", lfname, getpossessive(lfname),
} noprefix(obname));
} else { }
addflag(oo->flags, F_LOCKED, B_TRUE, 20, NA, NULL); } else {
if (isplayer(lf)) { addflag(oo->flags, F_LOCKED, B_TRUE, 20, NA, NULL);
msg("Your %s buzzes.", noprefix(obname)); if (isplayer(lf)) {
} else if (cansee(player, lf)) { msg("Your %s buzzes.", noprefix(obname));
char lfname[BUFLEN]; } else if (cansee(player, lf)) {
getlfname(lf, lfname); char lfname[BUFLEN];
msg("%s%s %s buzzes.", lfname, getpossessive(lfname), getlfname(lf, lfname);
noprefix(obname)); msg("%s%s %s buzzes.", lfname, getpossessive(lfname),
} noprefix(obname));
}
}
} }
} }
} else { } else {
@ -8366,12 +8395,15 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
int donesomething = B_FALSE; int donesomething = B_FALSE;
if (!where) { if (!where) {
if (isplayer(lf)) msg("There is nothing to use your spanner on there!"); if (isplayer(lf)) msg("There is nothing to use your spanner on there!");
} else if (where->lf) {
if (isplayer(lf)) msg("There is someone in your way!");
} else { } else {
object_t *o; object_t *o;
char ch; char ch;
flag_t *f; flag_t *f;
for (o = where->obpile->first ; o ; o = o->next) { for (o = where->obpile->first ; o ; o = o->next) {
int isopen; int isopen;
// jammed doors
if (isdoor(o, &isopen)) { if (isdoor(o, &isopen)) {
if (!isopen) { // ie. if closed. if (!isopen) { // ie. if closed.
f = hasflag(o->flags, F_JAMMED); f = hasflag(o->flags, F_JAMMED);
@ -8399,6 +8431,19 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
} }
} }
} }
// gratings
if ((o->type->id == OT_GRATINGFLOOR) && hasflag(o->flags, F_LOCKED)) {
char obname[BUFLEN];
getobname(o, obname, 1);
ch = askchar("It looks like you could remove the bolts. Do so", "yn", "y", B_TRUE, B_FALSE);
if (ch == 'y') {
msg("You remove the cover from %s.", obname);
killflagsofid(o->flags, F_LOCKED);
killflagsofid(o->flags, F_LOCKABLE);
taketime(lf, getactspeed(lf));
donesomething = B_TRUE;
}
}
} }
} }
if (!donesomething) { if (!donesomething) {
@ -11633,15 +11678,13 @@ void timeeffectsob(object_t *o) {
if (location) { if (location) {
//buildings/shops make noise // object makes noise?
if (o->type->obclass->id == OC_BUILDING) { f = hasflag(o->flags, F_MAKESNOISE);
if (onein(3)) { if (f && pctchance(f->val[0])) {
char noisebuf[BUFLEN]; // these are generally just to notify the player that something
switch (o->type->id) { // is nearby, so don't make noises the the player is already there.
case OT_TEMPLE: strcpy(noisebuf, "voices chanting."); break; if (location != player->cell) {
default: strcpy(noisebuf, "a cash register chiming."); break; noise(location, NULL, NC_OTHER, f->val[1], f->text, NULL);
}
noise(location, NULL, NC_OTHER, 3, noisebuf, NULL);
} }
} }
// does object's material change cell type? // does object's material change cell type?

26
spell.c
View File

@ -3580,8 +3580,16 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} else if (spellid == OT_S_CANINETRACKING) { } else if (spellid == OT_S_CANINETRACKING) {
int howlong; int howlong;
howlong = getspellduration(20,30,blessed) + (power*10); if (hasflag(caster->flags, F_NOSMELL)) {
addtempflag(caster->flags, F_ENHANCESMELL, 4, NA, NA, NULL, howlong); if (isplayer(caster)) {
nothinghappens();
} else {
fizzle(caster);
}
} else {
howlong = getspellduration(20,30,blessed) + (power*10);
addtempflag(caster->flags, F_ENHANCESMELL, 4, NA, NA, NULL, howlong);
}
} else if (spellid == OT_S_CONFISCATE) { } else if (spellid == OT_S_CONFISCATE) {
char ch = 'a'; char ch = 'a';
char obname[BUFLEN]; char obname[BUFLEN];
@ -6944,22 +6952,32 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
int gotit = B_FALSE; int gotit = B_FALSE;
int dooropen; int dooropen;
if (isdoor(o, &dooropen)) { if (isdoor(o, &dooropen)) {
// closed door?
if (!dooropen) { if (!dooropen) {
gotit = B_TRUE; gotit = B_TRUE;
} }
} else { } else {
// something else impassable
gotit = B_TRUE; gotit = B_TRUE;
} }
if (gotit) { if (gotit) {
if (haslos(player, targcell)) { if (haslos(player, targcell)) {
getobname(o, buf, o->amt); getobname(o, buf, o->amt);
msg("%s %s!",isplayer(caster) ? "You blast" : "Something blasts", buf); msg("%s %s!",isplayer(caster) ? "You blast" : "Something blasts", buf);
if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL); addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
if (seenbyplayer) *seenbyplayer = B_TRUE;
donesomething = B_TRUE; donesomething = B_TRUE;
} }
} else if (hasflag(o->flags, F_LOCKED)) {
// unlock it
if (haslos(player, targcell)) {
getobname(o, buf, 1);
msg("%s unlocks.", buf);
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
killflagsofid(o->flags, F_LOCKED);
donesomething = B_TRUE;
} }
} }