diff --git a/attack.c b/attack.c index 8b8c938..7d3a508 100644 --- a/attack.c +++ b/attack.c @@ -519,9 +519,6 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { angergodmaybe(R_GODMERCY, 25, GA_ATTACKALLY); angergodmaybe(R_GODPURITY, 100, GA_ATTACKALLY); switch (getalignment(attacktarget)) { - case AL_EVIL: - angergodmaybe(R_GODDEATH, 20, GA_ATTACKALLY); // even more - break; case AL_GOOD: angergodmaybe(R_GODPURITY, 20, GA_ATTACKALLY); // even more break; diff --git a/data.c b/data.c index 6f9c2e2..f855012 100644 --- a/data.c +++ b/data.c @@ -3100,12 +3100,13 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); - addot(OT_S_PURIFYFOOD, "purify food", "Removes rot or poison from food or drink.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_PURIFYFOOD, "purify food", "Changes any kind of harmful food or drink into a harmless equivilant.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); - addot(OT_S_STICKTOSNAKE, "sticks to snakes", "Transforms all seen wooden weapons into snakes.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_STICKTOSNAKE, "sticks to snakes", "Transforms all rod-shaped objects in sight into allied snakes.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "This spell does not affect the caster's weapon."); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); @@ -3454,7 +3455,7 @@ void initobjects(void) { addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // l2 - addot(OT_S_DISORIENT, "disorient", "Spins the target around to face a different direction. This will sometimes also make them dizzy.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_DISORIENT, "disorient", "Spins the target around to face away from the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 10, NA, NA, NULL); @@ -4390,6 +4391,7 @@ void initobjects(void) { addflag(lastot->flags, F_VALUE, 150, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_YELLOW, '(', NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_NOSTEAL, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); @@ -7888,7 +7890,7 @@ void initrace(void) { addflag(lastrace->flags, F_SACRIFICEOB, OT_BANDAGE, NA, 30, "OB IS consumed by a shaft of holy light."); addflag(lastrace->flags, F_SACRIFICEOBCLASS, OC_FOOD, NA, 3, "OB IS consumed by a shaft of holy light."); - addrace(R_GODDEATH, "Hecta", 100, '@', C_BOLDMAGENTA, MT_BONE, RC_GOD, "The skeletal god of death is garbed in a cloak made of pure shadow. and weilds an enormous scythe."); + addrace(R_GODDEATH, "Hecta", 100, '@', C_BOLDMAGENTA, MT_BONE, RC_GOD, "The skeletal god of Death is garbed in a cloak made of pure shadow. and weilds an enormous scythe."); setbodytype(lastrace, BT_HUMANOID); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, NA, NA, "80"); @@ -8045,7 +8047,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "raises her palms"); addflag(lastrace->flags, F_CASTCHANCE, 75, NA, NA, NULL); // god abilities - addflag(lastrace->flags, F_GODOF, B_FEMALE, NA, NA, "Mercy"); + addflag(lastrace->flags, F_GODOF, B_FEMALE, NA, NA, "Mercy & Forgiveness"); addflag(lastrace->flags, F_FLEEONHPPCT, 10, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_S_CUREPOISON, NA, NA, "pw:10;"); addflag(lastrace->flags, F_CANWILL, OT_S_HEALINGMAJ, NA, NA, "pw:10;"); @@ -11395,6 +11397,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_STR, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TOUCHBURN, 3, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "flares its flames^crackling flames"); + addflag(lastrace->flags, F_DAMAGEGROUNDOBS, 2, DT_FIRE, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_GLOWBUG, "glowbug", 1, 'i', C_WHITE, MT_FLESH, RC_INSECT, "Glowbugs are tiny flying creatures, magically producing light from their bodies."); @@ -11692,6 +11695,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_TOUCHCHILL, 7, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); + addflag(lastrace->flags, F_DAMAGEGROUNDOBS, 4, DT_COLD, B_TRUE, NULL); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "shoddy cloak"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "screeches^a screech"); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); diff --git a/defs.h b/defs.h index a04c50a..dbf8273 100644 --- a/defs.h +++ b/defs.h @@ -2151,6 +2151,7 @@ enum FLAG { // just convert the object) F_NOBLESS, // can't be blessed or cursed F_NOQUALITY, // can't be masterwork / shoddy + F_NOSTEAL, // this object can't be stolen, blown away, etc. F_SALTED, // this corpse has been salted and will not decay. F_CORPSEOF, // this is a corpse of montype val0. // text is how it died. @@ -2533,6 +2534,8 @@ enum FLAG { F_HOMEMAP, // which map did this lf get created on? F_TOOKACTION, // lf purposely took action in their last turn. F_JUSTENTERED, // lf just entered a new map. + F_DAMAGEGROUNDOBS, // lf causes v0 damage of type v1 to ground objects + // if v2 is TRUE, this happens even when lf is airborne F_MOVED, // lf purposely walked/flew/swum/moved in prev turn F_HASBEENMOVED, // an object moved this lf since their last turn. F_HOTFEET, // target takes v0 damage of type v1 unless they move. @@ -2651,8 +2654,8 @@ enum FLAG { F_NOSKILL, // lifeform CANNOT ever learn skill v0 F_LFSUFFIX, // text = suffix. eg. "skeleton" F_VISRANGE, // how far you can see (in the light) - F_VISRANGEMOD, // modifications to visrange - F_NIGHTVISRANGEMOD, // modifications to nightvisrange + F_VISRANGEMOD, // v0:modifications to visrange + F_NIGHTVISRANGEMOD, // v0:modifications to nightvisrange F_GUNTARGET, // current projectile weapon target // v0 is guntarget id. // text is targetting string (ie. Orc [50%]) diff --git a/flag.c b/flag.c index 8f7eb12..aac1115 100644 --- a/flag.c +++ b/flag.c @@ -637,14 +637,14 @@ int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid) { } flag_t *hasflag(flagpile_t *fp, int id) { - return hasflag_real(fp, id, NA, NULL); + return hasflag_real(fp, id, NA, NULL, NA); } flag_t *hasflagknown(flagpile_t *fp, int id) { - return hasflag_real(fp, id, B_TRUE, NULL); + return hasflag_real(fp, id, B_TRUE, NULL, NA); } -flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception) { +flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception, int lifetimeexception) { flag_t *f,*foundflag = NULL, *searchfrom = NULL; lifeform_t *owner; int pos; @@ -704,6 +704,7 @@ flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception) { while (f && (f->id == id)) { int valid = B_TRUE; if (f == exception) valid = B_FALSE; + if ((lifetimeexception != NA) && (f->lifetime == lifetimeexception)) valid = B_FALSE; if ((wantknown != NA) && (f->known != wantknown)) valid = B_FALSE; if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) valid = B_FALSE; //if (owner && (f->lifetime == FROMSKILL) && !getskill(owner, xxx)) valid = B_FALSE; @@ -743,11 +744,11 @@ flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception) { flag_t *hasflagval(flagpile_t *fp, int id, int val1, int val2, int val3, char *text) { - return hasflagval_real(fp, id, val1, val2, val3, text, B_FALSE); // doesn't have to be known + return hasflagval_real(fp, id, val1, val2, val3, text, B_FALSE, NA); // doesn't have to be known } flag_t *hasflagvalknown(flagpile_t *fp, int id, int val1, int val2, int val3, char *text) { - return hasflagval_real(fp, id, val1, val2, val3, text, B_TRUE); // must be known + return hasflagval_real(fp, id, val1, val2, val3, text, B_TRUE, NA); // must be known } int getcounter(flagpile_t *fp) { @@ -759,7 +760,7 @@ int getcounter(flagpile_t *fp) { return 0; } -flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, char *text, int wantknown) { +flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, char *text, int wantknown, int lifetimeexception) { flag_t *f,*foundflag = NULL, *searchfrom = NULL; lifeform_t *owner; int pos; @@ -816,7 +817,8 @@ flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, ch // now find a valid one f = searchfrom; while (f && (f->id == id)) { - if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) { + if ((lifetimeexception != NA) && (f->lifetime == lifetimeexception)) { + } else if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) { // invalid } else if ( ((val1 == NA) || (f->val[0] == val1)) && ((val2 == NA) || (f->val[1] == val2)) && diff --git a/flag.h b/flag.h index 5ea70d4..88f0071 100644 --- a/flag.h +++ b/flag.h @@ -25,10 +25,10 @@ cell_t *getflagpilelocation(flagpile_t *fp); int getflags(flagpile_t *fp, flag_t **retflag, int *nretflags, ... ); flag_t *hasflag(flagpile_t *fp, int id); flag_t *hasflagknown(flagpile_t *fp, int id); -flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception); +flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception, int lifetimeexception); flag_t *hasflagval(flagpile_t *fp, int id, int val1, int val2, int val3, /*@null@*/ char *text); flag_t *hasflagvalknown(flagpile_t *fp, int id, int val1, int val2, int val3, /*@null@*/ char *text); -flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, /*@null@*/ char *text, int wantknown); +flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, /*@null@*/ char *text, int wantknown, int lifetimeexception); int istransitoryflag(flag_t *f); int killflagsofid(flagpile_t *fp, enum FLAG fid); void killflag(flag_t *f); diff --git a/god.c b/god.c index a404177..b2974f8 100644 --- a/god.c +++ b/god.c @@ -62,20 +62,30 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) { } else if (rid == R_GODNATURE) { godsay(rid, B_TRUE, "You dare destroy my creations?"); break; } else { - godsay(rid, B_TRUE, "You dare destroy my symbols?"); break; + godsay(rid, B_TRUE, "You dare desecrate my symbols?"); break; } case GA_ASSAULT: - godsay(rid, B_TRUE, "You dare attack one of my innocent servants?"); break; + if (rid == R_GODDEATH) { + godsay(rid, B_TRUE, "You dare attack one of my servants?"); break; + } else { + godsay(rid, B_TRUE, "You dare attack an innocent?"); break; + } case GA_COWARD: godsay(rid, B_TRUE, "Coward!"); break; case GA_EAT: godsay(rid, B_TRUE, "That is NOT acceptable for consumption!"); break; case GA_HERESY: - godsay(rid, B_TRUE, "Heresy!"); break; + if (rid == R_GODFIRE) { + godsay(rid, B_TRUE, "HERESY!"); break; + } else if (rid == R_GODMAGIC) { + godsay(rid, B_TRUE, "One's mundanity is offensive!"); break; + } else { + godsay(rid, B_TRUE, "Heresy!"); break; + } case GA_MERCY: - godsay(rid, B_TRUE, "You allowed your foe to escape!"); break; + godsay(rid, B_TRUE, "You allowed my sacrifice to escape!"); break; case GA_MONEY: - godsay(rid, B_TRUE, "Where is your sense of greed?"); break; + godsay(rid, B_TRUE, "Where is your sense of greed?!"); break; case GA_MURDER: godsay(rid, B_TRUE, "You have taken a life!"); break; case GA_PRAY: dosay = B_TRUE; break; @@ -84,18 +94,35 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) { case GA_RACE: godsay(rid, B_TRUE, "Your form offends me!"); break; case GA_SPELL: - godsay(rid, B_TRUE, "Your magic offends me!"); break; + if (rid == R_GODBATTLE) { + godsay(rid, B_TRUE, "A true warrior does not resort to magic!"); break; + } else if (rid == R_GODFIRE) { + godsay(rid, B_TRUE, "NO COLD MAGIC!"); break; + } else if (rid == R_GODDEATH) { + godsay(rid, B_TRUE, "The stink of your vile magic offends me!"); break; + } else if (rid == R_GODLIFE) { + godsay(rid, B_TRUE, "I will not tolerate such evil magics!"); break; + } else { + godsay(rid, B_TRUE, "Your magic offends me!"); break; + } } // announce - if (plev == PL_ANGRY) { // minor bad stuff - godsay(rid,dosay, "You have angered me, mortal!"); - } else if (plev == PL_FURIOUS) { // major bad stuff - godsay(rid,dosay, "You go too far, mortal!"); - } else if (plev == PL_ENRAGED) { // god will attack - godsay(rid,dosay, "You will regret that!"); - } else { // not angry yet. - godsay(rid, dosay, "You are testing my patience, mortal!"); + switch (plev) { + case PL_ENRAGED: + godsay(rid,dosay, "Witness the wrath of a god!"); + break; + case PL_FURIOUS: + godsay(rid,dosay, "You go too far, mortal!"); + break; + case PL_ANGRY: + godsay(rid,dosay, "You have angered me, mortal!"); + break; + case PL_INDIFFERENT: // ie. not angry yet... + godsay(rid, dosay, "You are testing my patience, mortal!"); + break; + default: // ie. still happy + break; } // bad stuff @@ -784,7 +811,38 @@ int godgiftmaybe(enum RACE rid, int fromtemple) { killflagsofid(player->flags, F_ASLEEP); - godsay(god->race->id, B_TRUE, "I bestow a gift upon you, mortal!"); + + switch (god->race->id) { + case R_GODPURITY: + godsay(god->race->id, B_TRUE, "I bestow a gift upon you, mortal!"); + break; + case R_GODTHIEVES: + godsay(god->race->id, B_TRUE, "Loyalty has its rewards..."); + break; + case R_GODDEATH: + godsay(god->race->id, B_TRUE, "Your service has impressed me..."); + break; + case R_GODFIRE: + godsay(god->race->id, B_TRUE, "DESTROY IN MY NAME!"); + break; + case R_GODLIFE: + godsay(god->race->id, B_TRUE, "Use this gift to spread the joy of life!"); + break; + case R_GODMERCY: + godsay(god->race->id, B_TRUE, "As you have shown mercy, so shall you receive it!"); + break; + case R_GODNATURE: + godsay(god->race->id, B_TRUE, "Harvest nature's bounty!"); + break; + case R_GODBATTLE: + godsay(god->race->id, B_TRUE, "Gather up the spoils of battle!"); + break; + case R_GODMAGIC: + godsay(god->race->id, B_TRUE, "One has earned a reward!"); + break; + default: + break; + } strcpy(obtogive, ""); switch (god->race->id) { case R_GODBATTLE: diff --git a/io.c b/io.c index ed08017..b315df4 100644 --- a/io.c +++ b/io.c @@ -1736,7 +1736,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { break; case F_RESISTMAG: if (isplayer(lf)) { // don't know if monsters get it - msg("You feel %simmune to magic.", hasflag_real(lf->flags, F_RESISTMAG, NA, f) ? "more " : ""); + msg("You feel %simmune to magic.", hasflag_real(lf->flags, F_RESISTMAG, NA, f, NA) ? "more " : ""); donesomething = B_TRUE; } break; @@ -2366,7 +2366,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f) { break; case F_RESISTMAG: if (isplayer(lf)) { // don't know if monsters lose it - if (hasflag_real(lf->flags, F_RESISTMAG, NA, f)) { + if (hasflag_real(lf->flags, F_RESISTMAG, NA, f, NA)) { msg("You feel less immune to magic."); } else { msg("You are no longer immune to magic."); @@ -11436,6 +11436,7 @@ void showlfstats(lifeform_t *lf, int showall) { } } else if (mode == 'e') { int nfound = 0,luckmod; + enum LFSIZE racesize,cursize; x = 0; // override // down a line. centre(mainwin, C_WHITE, y, "EFFECTS"); @@ -11529,6 +11530,19 @@ void showlfstats(lifeform_t *lf, int showall) { y++; } + f = hasflag(lf->race->flags, F_SIZE); + if (f) { + racesize = f->val[0]; + } else { + racesize = SZ_HUMAN; // default + } + cursize = getlfsize(lf); + if (cursize != racesize) { + mvwprintw(mainwin, y, 0, "%s body has been magically %s.", your(lf), (cursize > racesize) ? "enlarged" : "shrunken"); + y++; + } + + // show racial effects if (hasjob(lf, J_PIRATE)) { mvwprintw(mainwin, y, 0, "%s can hold %s liquor well.", you(lf), isplayer(lf) ? "Your" : "its"); @@ -11562,8 +11576,8 @@ void showlfstats(lifeform_t *lf, int showall) { mvwprintw(mainwin, y, 0, "%s %s deaf.", you(lf), is(lf)); y++; } - f = lfhasknownflag(lf, F_ENHANCESMELL); - if (f && (f->lifetime != FROMRACE)) { + f = hasflag_real(lf->flags, F_ENHANCESMELL, B_TRUE, NULL, FROMRACE); + if (f) { mvwprintw(mainwin, y, 0, "%s %s an enhanced sense of smell.", you(lf), isplayer(lf) ? "have" : "has"); y++; } @@ -11573,8 +11587,8 @@ void showlfstats(lifeform_t *lf, int showall) { y++; } - f = lfhasknownflag(lf, F_HEAVYBLOW); - if (f && (f->lifetime != FROMRACE)) { + f = hasflag_real(lf->flags, F_HEAVYBLOW, B_TRUE, NULL, FROMRACE); + if (f) { snprintf(buf, BUFLEN,"%s%s attacks knock enemies back.", you(lf), getpossessive(you(lf))); mvwprintw(mainwin, y, 0, buf); y++; @@ -11613,43 +11627,67 @@ void showlfstats(lifeform_t *lf, int showall) { mvwprintw(mainwin, y, 0, "%s %s %s resistant to magic.", you(lf), is(lf), adjective); y++; } - f = lfhasknownflag(lf, F_TREMORSENSE); - if (f && (f->lifetime != FROMRACE)) { + f = hasflag_real(lf->flags, F_TREMORSENSE, B_TRUE, NULL, FROMRACE); + if (f) { mvwprintw(mainwin, y, 0, "%s can 'see' by sensing vibrations around %s.", you(lf), you(lf)); y++; } - f = lfhasflag(lf, F_STENCH); - if (f && (f->known) && (f->lifetime != FROMRACE)) { - mvwprintw(mainwin, y, 0, "%s smell%s terrible.", you(lf), isplayer(lf) ? "" : "s"); - y++; - } - f = lfhasknownflag(lf, F_SEEINDARK); - if (f && (f->known) && (f->lifetime != FROMRACE)) { + f = hasflag_real(lf->flags, F_SEEINDARK, B_TRUE, NULL, FROMRACE); + if (f) { mvwprintw(mainwin, y, 0, "%s can see in the dark.", you(lf)); y++; } - f = lfhasknownflag(lf, F_SEEINVIS); - if (f && (f->known) && (f->lifetime != FROMRACE)) { + f = hasflag_real(lf->flags, F_SEEINVIS, B_TRUE, NULL, FROMRACE); + if (f) { mvwprintw(mainwin, y, 0, "%s can see invisible things.", you(lf)); y++; } - f = lfhasknownflag(lf, F_SPIDERCLIMB); - if (f && (f->known) && (f->lifetime != FROMRACE)) { + f = hasflag_real(lf->flags, F_SPIDERCLIMB, B_TRUE, NULL, FROMRACE); + if (f) { mvwprintw(mainwin, y, 0, "%s adhesive skin allows %s to climb walls.", your(lf), you(lf)); y++; } - f = lfhasknownflag(lf, F_SIXTHSENSE); - if (f && (f->known) && (f->lifetime != FROMRACE)) { + f = hasflag_real(lf->flags, F_SIXTHSENSE, B_TRUE, NULL, FROMRACE); + if (f) { mvwprintw(mainwin, y, 0, "%s will be warned about nearby enemies.", you(lf)); y++; } - f = lfhasknownflag(lf, F_STABILITY); - if (f && (f->known) && (f->lifetime != FROMRACE)) { + f = hasflag_real(lf->flags, F_STABILITY, B_TRUE, NULL, FROMRACE); + if (f) { mvwprintw(mainwin, y, 0, "%s will not fall on slippery ground.", you(lf)); y++; } - f = lfhasknownflag(lf, F_XRAYVIS); - if (f && (f->known) && (f->lifetime != FROMRACE)) { + + // only show eating habits if not inherited from race + f = hasflag_real(lf->flags, F_CARNIVORE, B_TRUE, NULL, FROMRACE); + if (f) { + mvwprintw(mainwin, y, 0, "%s %s a carnivore (will not eat non-meat products).", you(lf), is(lf)); + y++; + } + f = hasflag_real(lf->flags, F_VEGETARIAN, B_TRUE, NULL, FROMRACE); + if (f) { + mvwprintw(mainwin, y, 0, "%s %s a vegetarian (will not eat meat).", you(lf), is(lf)); + y++; + } + f = hasflag_real(lf->flags, F_PARTVEGETARIAN, B_TRUE, NULL, FROMRACE); + if (f) { + mvwprintw(mainwin, y, 0, "%s %s a part vegetarian (will only eat meat when hunger).", you(lf), is(lf)); + y++; + } + + f = hasflag_real(lf->flags, F_VISRANGEMOD, B_TRUE, NULL, FROMRACE); + if (f) { + mvwprintw(mainwin, y, 0, "%s vision range has been %d.", your(lf), (f->val[0] > 0) ? "increased" : "decreased"); + y++; + } + f = hasflag_real(lf->flags, F_NIGHTVISRANGEMOD, B_TRUE, NULL, FROMRACE); + if (f) { + mvwprintw(mainwin, y, 0, "%s night vision range has been %d.", your(lf), (f->val[0] > 0) ? "increased" : "decreased"); + y++; + } + + f = hasflag_real(lf->flags, F_XRAYVIS, B_TRUE, NULL, FROMRACE); + if (f) { mvwprintw(mainwin, y, 0, "%s can see through walls.", you(lf)); y++; } @@ -11845,8 +11883,8 @@ void showlfstats(lifeform_t *lf, int showall) { mvwprintw(mainwin, y, 0, "%s identity is obscured.", your(lf)); y++; } - f = lfhasknownflag(lf, F_AWARENESS); - if (f && (f->lifetime != FROMRACE)) { + f = hasflag_real(lf->flags, F_AWARENESS, B_TRUE, NULL, FROMRACE); + if (f) { mvwprintw(mainwin, y, 0, "%s can see things which are behind %s.", you(lf), you(lf)); y++; } @@ -12114,8 +12152,8 @@ void showlfstats(lifeform_t *lf, int showall) { mvwprintw(mainwin, y, 0, "%s %s paralyzed.", you(lf), is(lf)); y++; } - f = lfhasflag(lf, F_PHOTOMEM); - if (f && (f->known) && (f->lifetime != FROMRACE)) { + f = hasflag_real(lf->flags, F_PHOTOMEM, B_TRUE, NULL, FROMRACE); + if (f) { mvwprintw(mainwin, y, 0, "%s do not forget your surroundings.", you(lf)); y++; } @@ -12146,8 +12184,8 @@ void showlfstats(lifeform_t *lf, int showall) { y++; } - f = lfhasflag(lf, F_STENCH); - if (f && (f->known) && (f->lifetime != FROMRACE)) { + f = hasflag_real(lf->flags, F_STENCH, B_TRUE, NULL, FROMRACE); + if (f) { mvwprintw(mainwin, y, 0, "%s %s emitting a foul stench, nauseating those nearby.", you(lf), is(lf)); y++; } diff --git a/lf.c b/lf.c index e9e7ea7..20422ea 100644 --- a/lf.c +++ b/lf.c @@ -1828,7 +1828,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar break; case SS_DEATH: pleasegodmaybe(R_GODDEATH, getspelllevel(sid)); - angergodmaybe(R_GODPURITY, getspelllevel(sid)*5, GA_SPELL); + angergodmaybe(R_GODLIFE, getspelllevel(sid)*5, GA_SPELL); break; case SS_FIRE: pleasegodmaybe(R_GODFIRE, getspelllevel(sid)*2); @@ -17334,7 +17334,6 @@ void startlfturn(lifeform_t *lf) { } if (isdead(lf)) return; - // effects for/on your own flags getflags(lf->flags, retflag, &nretflags, F_ATTACHEDTO, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FEIGNFOOLEDBY,F_FLEEFROM, F_GRABBEDBY, F_GRABBING, F_HIDING, F_BOOSTSPELL, F_FEIGNINGDEATH, F_HPDRAIN, F_INJURY, @@ -17554,6 +17553,8 @@ int steal(lifeform_t *lf, obpile_t *op, enum FLAG wantflag) { } else if (!canpickup(lf, o, 1)) { // can't pick it up ok = B_FALSE; + } else if (hasflag(o->flags, F_NOSTEAL)) { + ok = B_FALSE; } else if ((wantflag != F_NONE) && !hasflag(o->flags, wantflag)) { // don't have the right flag ok = B_FALSE; diff --git a/map.c b/map.c index ac3c7ed..9bba32e 100644 --- a/map.c +++ b/map.c @@ -6010,6 +6010,17 @@ object_t *hascloseddoor(cell_t *c) { return NULL; } +int hascrushableob(cell_t *c, lifeform_t *lf) { + object_t *o; + if (lfhasflag(lf, F_CAREFULMOVE)) { + return B_FALSE; + } + for (o = c->obpile->first ; o; o = o->next) { + if (cancrush(lf, o)) return B_TRUE; + } + return B_FALSE; +} + lifeform_t *haslf(cell_t *c) { if (c->lf && !isdead(c->lf)) { return c->lf; diff --git a/map.h b/map.h index 4f7102d..402a9d5 100644 --- a/map.h +++ b/map.h @@ -121,6 +121,7 @@ int getslipperyness(cell_t *c, object_t **slipob); cell_t *getstairdestination(object_t *o, int *madenewmap); object_t *hasenterableobject(cell_t *c); object_t *hascloseddoor(cell_t *c); +int hascrushableob(cell_t *c, lifeform_t *lf); lifeform_t *haslf(cell_t *c); int hasknownobject(cell_t *c); int hasobject(cell_t *c); diff --git a/move.c b/move.c index 640ff41..b6c5a8a 100644 --- a/move.c +++ b/move.c @@ -281,8 +281,17 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err } if (include_nonobvious) { for (o = cell->obpile->first ; o ; o = o->next) { - // don't walk on sharp objects without boots - if (!onlyifknown || (wis >= AT_AVERAGE)) { + if (wis >= AT_GTAVERAGE) { + // don't walk onto crushable objects if you worship ekrub + if (isplayer(lf) && cancrush(lf, o) && !lfhasflag(lf, F_CAREFULMOVE)) { + if (error) { + *error = E_AVOIDOB; + rdata = o; + } + return B_TRUE; + } + } if (wis >= AT_AVERAGE) { + // don't walk on sharp objects without boots if (hasflag(o->flags, F_SHARP)) { if (!getequippedob(lf->pack, BP_FEET)) { if (error) { @@ -292,7 +301,7 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err return B_TRUE; } } - } + } } } return B_FALSE; @@ -1098,6 +1107,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) { lifeform_t *l; int didmsg = B_FALSE; flag_t *f; + enum FLAG flying; int changedlev = B_FALSE; room_t *preroom = NULL, *postroom = NULL; int preshop = -1; @@ -1105,6 +1115,8 @@ int movelf(lifeform_t *lf, cell_t *newcell) { int prewater = B_FALSE; int preseenbyplayer = B_FALSE; vault_t *v; + flag_t *retflag[MAXCANDIDATES]; + int nretflags,i; assert(newcell); @@ -1268,7 +1280,8 @@ int movelf(lifeform_t *lf, cell_t *newcell) { } // check ground objects - if (!isairborne(lf)) { + flying = isairborne(lf); + if (flying == F_NONE) { for (o = newcell->obpile->first ; o ; o = nexto ) { nexto = o->next; @@ -1320,42 +1333,36 @@ int movelf(lifeform_t *lf, cell_t *newcell) { } } - f = hasflag(o->flags, F_CRUSHABLE); - if (f && !lfhasflag(lf, F_CAREFULMOVE)) { - enum LFSIZE crushsize; - crushsize = f->val[0]; + if (!lfhasflag(lf, F_CAREFULMOVE) && cancrush(lf, o)) { + // crush it + getobname(o, obname, 1); + + // special case + if (o->type->id == OT_BROKENGLASS) { + if (o->amt > 1) { + char *newname; + // we want 'xx steps on some pieces of broken glass' + // not 'xx steps on 5 pieces of broken glass' + newname = makeplural(obname); + newname = strrep(newname, "a ", "some ", NULL); + strcpy(obname, newname); + free(newname); + } + } - if (getlfsize(lf) >= crushsize) { - // crunch it broken glass - getobname(o, obname, 1); - - // special case - if (o->type->id == OT_BROKENGLASS) { - if (o->amt > 1) { - char *newname; - // we want 'xx steps on some pieces of broken glass' - // not 'xx steps on 5 pieces of broken glass' - newname = makeplural(obname); - newname = strrep(newname, "a ", "some ", NULL); - strcpy(obname, newname); - free(newname); - } - } - - if (isplayer(lf)) { - msg("You crush %s underfoot.",obname); - didmsg = B_TRUE; - } else if (haslos(player, newcell)) { - msg("%s crushes %s.",lfname, obname); - didmsg = B_TRUE; - } - // kill object which is being crushed. - removeob(o, o->amt); - if (isplayer(lf)) { - angergodmaybe(R_GODNATURE, 10, GA_ATTACKOBJECT); - } - continue; - } + if (isplayer(lf)) { + msg("You crush %s underfoot.",obname); + didmsg = B_TRUE; + } else if (haslos(player, newcell)) { + msg("%s crushes %s.",lfname, obname); + didmsg = B_TRUE; + } + // kill object which is being crushed. + removeob(o, o->amt); + if (isplayer(lf)) { + angergodmaybe(R_GODNATURE, 10, GA_ATTACKOBJECT); + } + continue; } // end if crushable if ((o->type->id == OT_VINE) && !hasjob(lf, J_DRUID)) { @@ -1516,6 +1523,16 @@ int movelf(lifeform_t *lf, cell_t *newcell) { msg("%s moves out of view.", lfname); } } + + getflags(lf->flags, retflag, &nretflags, F_DAMAGEGROUNDOBS, F_NONE); + for (i = 0; i < nretflags; i++) { + f = retflag[i]; + // will we cause damage to ground objects ? + if (!isairborne(lf) || (f->val[2] == B_TRUE)) { + damageallobs(NULL, lf->cell->obpile, f->val[0], f->val[1], lf); + } + } + // status bar if ((prespeed != postspeed) && isplayer(lf)) { statdirty = B_TRUE; diff --git a/objects.c b/objects.c index 2f5aade..25e8ddb 100644 --- a/objects.c +++ b/objects.c @@ -1975,8 +1975,10 @@ void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int all for (i = 0; i < ncells; i++) { c = cell[i]; - if (allowdupes || !hasob(c->obpile, ot->id)) { - addob(c->obpile, name); + if (!c->type->solid) { + if (allowdupes || !hasob(c->obpile, ot->id)) { + addob(c->obpile, name); + } } } } @@ -4783,7 +4785,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan char localbuf[BUFLEN]; char buf2[BUFLEN]; char triedbuf[BUFLEN]; - int venditem = B_FALSE; + int shopitem = B_FALSE; flag_t *f; brand_t *br; int hasunknownmod = B_FALSE; @@ -4793,16 +4795,12 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan int nretflags = 0; // default to normal name - if (hasflag(o->flags, F_VENDITEM)) { - venditem = B_TRUE; + if (hasflag(o->flags, F_SHOPITEM)) { + shopitem = B_TRUE; } where = getoblocation(o); - if (venditem) { - showall = B_TRUE; - } - f = hasflag(o->flags, F_TRAIL); if (f) { race_t *r = NULL; @@ -5357,8 +5355,9 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan } // show if we've tried this - if (gamemode == GM_GAMESTARTED) { + if (!shopitem && (gamemode == GM_GAMESTARTED)) { knowledge_t *k; + strcpy(triedbuf, ""); if (hasflag(o->flags, F_BEINGUSED)) { @@ -5423,8 +5422,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan } // in a shop? - f = hasflag(o->flags, F_SHOPITEM); - if (f) { + if (shopitem) { char pricebuf[BUFLEN]; // get price for _player_ snprintf(pricebuf, BUFLEN, " [$%d%s]", (int)getshopprice(o, player), o->pile->owner ? ", unpaid" : ""); @@ -13183,7 +13181,7 @@ void timeeffectsob(object_t *o) { object_t *splash; ourcell = getoblocation(o); // drip - if (!hasobwithflag(ourcell->obpile, F_DEEPWATER)) { + if (!ourcell->type->solid && !hasobwithflag(ourcell->obpile, F_DEEPWATER)) { splash = addob(ourcell->obpile, "splash of water"); } } @@ -13847,6 +13845,19 @@ int wepdullable(object_t *o) { } +int cancrush(lifeform_t *lf, object_t *o) { + flag_t *f; + f = hasflag(o->flags, F_CRUSHABLE); + if (f) { + enum LFSIZE crushsize; + crushsize = f->val[0]; + if (getlfsize(lf) >= crushsize) { + return B_TRUE; + } + } + return B_FALSE; +} + int willshatter(enum MATERIAL mat) { switch (mat) { case MT_GLASS: diff --git a/objects.h b/objects.h index d60f5d8..8e86deb 100644 --- a/objects.h +++ b/objects.h @@ -289,6 +289,7 @@ int usefountaincharge(object_t *o, flag_t *drinkflag); int validatehiddennames(void); int validateobs(void); int wepdullable(object_t *o); +int cancrush(lifeform_t *lf, object_t *o); int willshatter(enum MATERIAL mat); #endif diff --git a/spell.c b/spell.c index de9aefe..c9110f1 100644 --- a/spell.c +++ b/spell.c @@ -4,6 +4,7 @@ #include #include #include +#include "ai.h" #include "attack.h" #include "defs.h" #include "flag.h" @@ -5188,12 +5189,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else { int newdir; // make them face a random (different) direction - newdir = getrandomdirexcept(DT_COMPASS, target->facing); + newdir = getdiraway(targcell, caster->cell, NULL, B_FALSE, DT_ORTH, B_FALSE); setfacing(target, newdir); // ai loses target info - killflagsofid(target->flags, F_TARGETLF); - killflagsofid(target->flags, F_TARGETCELL); + loseaitargets(target); // announce if (isplayer(target)) { @@ -5205,11 +5205,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ msg("%s spins around to face %s.", tname, getdirname(target->facing)); if (seenbyplayer) *seenbyplayer = B_TRUE; } - // make them dizzy? - if (pctchance(power*10)) { - confuse(target, 2); - } - } } else if (spellid == OT_S_DETECTLIFE) { if (!target) { @@ -8363,9 +8358,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ for (o = op->first ; o ; o = nexto) { nexto = o->next; - if ((getobunitweight(o) <= 5) || - ((isweapon(o)) && (isequipped(o))) ) { - poss[nposs++] = o; + if (!hasflag(o->flags, F_NOSTEAL)) { + if ((getobunitweight(o) <= 5) || + ((isweapon(o)) && (isequipped(o))) ) { + poss[nposs++] = o; + } } } @@ -8548,11 +8545,25 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ flag_t *f; target = caster; + if (lfhasflag(target, F_NONCORPOREAL)) { + if (frompot) { + if (isplayer(caster)) nothinghappens(); + } else { + fizzle(caster); + } + return B_TRUE; + } + + if (isplayer(target) || cansee(player, target)) { + if (seenbyplayer) *seenbyplayer = B_TRUE; + } + howlong = getspellduration(5,10,blessed) + (power/2); f = addtempflag(target->flags, F_NONCORPOREAL, B_TRUE, NA, NA, NULL, howlong); f->obfrom = OT_S_PASSWALL; breakgrabs(target, B_TRUE, B_TRUE); + } else if ((spellid == OT_S_POLYMORPH) || (spellid == OT_S_SHAPESHIFT)) { race_t *r = NULL; @@ -9004,7 +9015,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ f = hasflag(targob->flags, F_CHARGES); if (!f) { - nothinghappens(); + if (isplayer(caster)) nothinghappens(); return B_TRUE; } @@ -9621,7 +9632,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ poss[nposs++] = caster->los[i]; } } - // for each cell we can see... + // for each cell we can see... (including our own) for (i = 0; i < caster->nlos; i++) { c = poss[i]; if (c->lf) { @@ -9629,7 +9640,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ for (o = c->lf->pack->first ; o ; o = nexto) { nexto = o->next; if ( hasflag(o->flags, F_RODSHAPED) && - isequipped(o) && + (!isequipped(o) || (c->lf != caster)) && (o->blessed == B_UNCURSED) && !hasflag(o->flags, F_HASBRAND)) { char obname[BUFLEN]; @@ -9672,7 +9683,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ for (o = c->obpile->first ; o ; o = nexto) { lifeform_t *snake = NULL; nexto = o->next; - if (hasflag(o->flags, F_RODSHAPED) && !isblessed(o)) { + if ( hasflag(o->flags, F_RODSHAPED) && + (o->blessed == B_UNCURSED) && + !hasflag(o->flags, F_HASBRAND)) { cell_t *newcell = NULL; char obname[BUFLEN];