- [+] press ] then \ - CRASH.

- [+] if sound is behind walls:
    - [+] you hear a muffled explosion
    - [+] int canhear() needs one more optional  argument: 
          &numwallspassed
        - [+] if supplied, fill it in.
    - [+] in noise(), check numwallspassed. if there were any, then say
          'muffled'. or maybe if more than 2? play around with this.
- [+] listen skill should also give more info about NON monster sounds
    - [+] ie. direction, distance.
- [+] set user->changinglev when CHECKING stairs in the same way as
      when we use them.
- [+] monk abil - iron fist - use all remaining stamina as damage +
      knockback
* [+] HITCONFER - this should only work if you were attacked through a
      BITE or CLAW etc.
- [+] bug... werewolves etc not attacking properly after shapehifting
- [+] some tech/tools should be usable with hands (ie. watch).
      f_operwithouthands
- [+] werewolves sohuld keep f_hitconfer after shapeshifting
    - [+] done
- [+] summoned creatures from ai should never attack their masters!!!
- [+] only the PLAYER can be infected by a werewolf?  or only HUMANS ?
- [+] when a werewolf changes to animal form, no longer hide true race
      as 'human'
- [+] lycanthropy?
    - [+] how to get it:
        - [+] drink were-xxx blood (->potion of lycanthropy, never
              appears randomly)
        - [+] bitten by a lycanthrope (chance) with hitconfer  and fail
              a con check
    - [+] change f_lycanthrope so text = racename.
    - [+] effects when you get it:
        - [+] right away, add diseased with lycanthropy. incubatino
              infinite ?
        - [+] if you are incubating lycanthropy, you always change at
              the full moon (and get rage, and lose control).
            - [+] at this point, complete the incubation and...
            - [+] add f_hatesall
            - [+] lose control for a while
        - [+] after you change back the first time,  you can change at
              will. (but there is a risk each time of losing control)
            - [+] player regains control
            - [+] remove aicontrolled, hatesall, rage
            - [+] actually add f_lycanthrope, text=xxx, v0=4
        - [+] when f_lycanthrope  v0 drops to 0 or less...
            - [+] canwill shapeshift  with race:xxx
    - [+] how to remove it
        - [+] remove curse scroll 
        - [+] drink holy water
        - [+] these will:
            - [+] cure any incubating curse
            - [+] cure any f_poisoned curse
            - [+] cure lycanthropy, and any flags FROMLYCANTHROPY
    - [+] other effect
        - [+] wont/cant walk into holy circle?
        - [+] holy circle hurts you
- [+] shouldn't be able to get critical hits on you (ie. injuries) if
      you ahve heavenly armour
- [+] bug in f_poisoned text. i think i've fixed this now.
          Died on level 2 of the dungeon.
          Killed by venom poisoning
          from 5-10
- [+] donated objects count towards xp!
    - [+] -50% of value if not known.
    - [+] -25% of value if not id'd
    - [+] donating objects will anger felix
This commit is contained in:
Rob Pearce 2012-07-11 04:10:21 +00:00
parent e5c6d8b094
commit af3116f6d4
21 changed files with 737 additions and 189 deletions

21
ai.c
View File

@ -199,8 +199,11 @@ enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim) {
if (ok) { if (ok) {
// lycanthropes always change to animal form at midnight. // lycanthropes always change to animal form at midnight.
if (gettimephase() == TP_MIDNIGHT) { if (gettimephase() == TP_MIDNIGHT) {
flag_t *lyf;
lyf = lfhasflag(lf, F_LYCANTHROPE);
if ((f->val[0] == OT_S_SHAPESHIFT) && if ((f->val[0] == OT_S_SHAPESHIFT) &&
lfhasflag(lf, F_LYCANTHROPE)) { lyf && (lyf->val[0] != 0)) {
if (ispolymorphed(lf)) { if (ispolymorphed(lf)) {
// never change to human form. // never change to human form.
ok = B_FALSE; ok = B_FALSE;
@ -1775,6 +1778,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
} }
if (!movetowards(lf, target->cell, DT_ORTH, B_FALSE)) { if (!movetowards(lf, target->cell, DT_ORTH, B_FALSE)) {
dblog(".oO { successfully moved towards target. }");
turntoface(lf, target->cell); turntoface(lf, target->cell);
// success // success
return B_FALSE; return B_FALSE;
@ -2615,9 +2619,6 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
} }
if ((ot->id == OT_S_INVISIBILITY) && lfhasflag(victim, F_INVISIBLE)) {
specificcheckok = B_FALSE;
}
if ((ot->id == OT_S_PAIN) && lfhasflag(victim, F_PAIN)) { if ((ot->id == OT_S_PAIN) && lfhasflag(victim, F_PAIN)) {
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
@ -2627,6 +2628,12 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
if ((ot->id == OT_S_HEALINGMIN) && (lf->hp >= lf->maxhp)) { if ((ot->id == OT_S_HEALINGMIN) && (lf->hp >= lf->maxhp)) {
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
if ((ot->id == OT_S_INVISIBILITY) && lfhasflag(victim, F_INVISIBLE)) {
specificcheckok = B_FALSE;
}
if ((ot->id == OT_A_IRONFIST) && getweapon(lf)) {
specificcheckok = B_FALSE;
}
if ((ot->id == OT_S_PARALYZE) && lfhasflag(victim, F_PARALYZED)) { if ((ot->id == OT_S_PARALYZE) && lfhasflag(victim, F_PARALYZED)) {
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
@ -3126,6 +3133,12 @@ void makewantedoblist(lifeform_t *lf, int *noids, enum OBTYPE *oid, int *oidcove
// returns B_FALSE if successful // returns B_FALSE if successful
int useitemwithflag(lifeform_t *lf, enum FLAG whichflag) { int useitemwithflag(lifeform_t *lf, enum FLAG whichflag) {
object_t *o; object_t *o;
// can't use anything if enraged
if (lfhasflag(lf, F_RAGE)) return B_TRUE;
// aicontrolled human won't use items
if (lfhasflag(lf, F_AICONTROLLED)) return B_TRUE;
for (o = lf->pack->first ; o ; o = o->next) { for (o = lf->pack->first ; o ; o = o->next) {
if (hasflag(o->flags, whichflag)) { if (hasflag(o->flags, whichflag)) {
if (aiobok(lf, o, lf)) { if (aiobok(lf, o, lf)) {

View File

@ -205,6 +205,15 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
if (c->lf) { if (c->lf) {
// warnings // warnings
if (!force && isplayer(lf)) { if (!force && isplayer(lf)) {
int h,m,s;
splittime(&h,&m,&s);
if (godprayedto(R_GODLIFE) && (h == 6)) {
if (!warnabout("Really attack during Glorana's Peace?")) {
return B_TRUE;
}
}
if (isprone(lf)) { if (isprone(lf)) {
if (!warnabout("Really attack while prone (-4 accuracy)?")) { if (!warnabout("Really attack while prone (-4 accuracy)?")) {
return B_TRUE; return B_TRUE;
@ -463,8 +472,14 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
if (nweps <= 0) { if (nweps <= 0) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("You cannot attack!"); msg("You cannot attack!");
} else if (lfhasflag(lf, F_DEBUG)) {
msg("DB: %s cannot attack!",lf->race->name);
} }
if (op) killobpile(op); if (op) killobpile(op);
if (!isplayer(lf)) {
// avoid infinite loops
taketime(lf, getactspeed(lf));
}
return B_TRUE; return B_TRUE;
} }
@ -639,6 +654,8 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
if (isplayer(lf) && attacktarget) { if (isplayer(lf) && attacktarget) {
if (attacktype == AT_LF) { if (attacktype == AT_LF) {
if (!isgod(attacktarget)) { if (!isgod(attacktarget)) {
int h,m,s;
splittime(&h,&m,&s);
if (attackedfriend) { if (attackedfriend) {
angergodmaybe(R_GODMERCY, 25, GA_ATTACKALLY); angergodmaybe(R_GODMERCY, 25, GA_ATTACKALLY);
angergodmaybe(R_GODPURITY, 100, GA_ATTACKALLY); angergodmaybe(R_GODPURITY, 100, GA_ATTACKALLY);
@ -686,6 +703,9 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
killflagsofid(lf->flags, F_USEDPOISON); killflagsofid(lf->flags, F_USEDPOISON);
if (isplayer(lf)) god_usepoison_response(); if (isplayer(lf)) god_usepoison_response();
} }
if (godprayedto(R_GODLIFE) && (h == 6)) {
angergodmaybe(R_GODLIFE, 30, GA_PEACEHOUR);
}
} }
} else if (attacktype == AT_OB) { } else if (attacktype == AT_OB) {
angergodmaybe(R_GODNATURE, 10, GA_ATTACKOBJECT); angergodmaybe(R_GODNATURE, 10, GA_ATTACKOBJECT);
@ -865,6 +885,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
ndam = 0; ndam = 0;
hit = rolltohit(lf, victim, wep, &critical, &fumble); hit = rolltohit(lf, victim, wep, &critical, &fumble);
if (lfhasflag(victim, F_HEAVENARM)) {
critical = B_FALSE;
}
if (critical && !lfhasflag(lf, F_PHANTASM)) { if (critical && !lfhasflag(lf, F_PHANTASM)) {
object_t *armour; object_t *armour;
@ -1397,7 +1420,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
if (!isdead(victim) && !blocked && !dodged) { if (!isdead(victim) && !blocked && !dodged) {
// special weapon effects, as long as you're not doing a heavy blow // special weapon effects, as long as you're not doing a heavy blow
if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) { if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) {
wepeffects(wep->flags, victim->cell, damflag, dam[0]); wepeffects(wep->flags, victim->cell, damflag, dam[0], isunarmed);
} }
if (isunarmed) { if (isunarmed) {
f = lfhasflag(lf, F_FREEZINGTOUCH); f = lfhasflag(lf, F_FREEZINGTOUCH);
@ -1423,7 +1446,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
// confer flags from attacker? // confer flags from attacker?
if (dam[0]) { if (dam[0]) {
wepeffects(lf->flags, victim->cell, damflag, dam[0]); wepeffects(lf->flags, victim->cell, damflag, dam[0], isunarmed);
} }
// special lifeform-based effects // special lifeform-based effects
@ -1471,7 +1494,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
if (cansee(player, lf) || cansee(player, victim)) { if (cansee(player, lf) || cansee(player, victim)) {
char wepname[BUFLEN]; char wepname[BUFLEN];
real_getobname(wep, wepname, 1, B_PREMODS, B_NOCONDITION, B_NOBLINDADJUST, B_BLESSINGS, B_NOUSED, B_NOSHOWALL); real_getobname(wep, wepname, 1, B_PREMODS, B_NOCONDITION, B_NOBLINDADJUST, B_BLESSINGS, B_NOUSED, B_NOSHOWALL);
msg("^%d%s%s %s %s to %s!", getlfcol(lf, CC_BAD), msg("^%c%s%s %s %s to %s!", getlfcol(lf, CC_BAD),
attackername, getpossessive(attackername), noprefix(wepname), attackername, getpossessive(attackername), noprefix(wepname),
(wep->amt == 1) ? "sticks" : "stick", victimname); (wep->amt == 1) ? "sticks" : "stick", victimname);
} }
@ -1542,9 +1565,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
if (fumble) { if (fumble) {
if (wep && !isunarmed) { if (wep && !isunarmed) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("^%dYou fumble your attack!", getlfcol(lf, CC_BAD)); msg("^%cYou fumble your attack!", getlfcol(lf, CC_BAD));
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
msg("^%d%s fumbles its attack!", getlfcol(lf, CC_BAD), attackername); msg("^%c%s fumbles its attack!", getlfcol(lf, CC_BAD), attackername);
} }
drop(wep, ALL); drop(wep, ALL);
wep = NULL; wep = NULL;
@ -1771,7 +1794,7 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
if (!isdeadob(o)) { if (!isdeadob(o)) {
// special weapon effects, as long as you're not doing a heavy blow // special weapon effects, as long as you're not doing a heavy blow
if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) { if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) {
wepeffects(wep->flags, obloc, damflag, dam[0]); wepeffects(wep->flags, obloc, damflag, dam[0], isunarmed);
} }
} }
@ -2006,7 +2029,7 @@ int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE da
if (cansee(player, lf) || cansee(player, victim)) { if (cansee(player, lf) || cansee(player, victim)) {
char attname[BUFLEN]; char attname[BUFLEN];
getlfname(lf, attname); getlfname(lf, attname);
msg("^%d%s%s %s %s to %s!", getlfcol(victim, CC_BAD), msg("^%c%s%s %s %s to %s!", getlfcol(victim, CC_BAD),
victimname, getpossessive(victimname), noprefix(shname), victimname, getpossessive(victimname), noprefix(shname),
(shield[i]->amt == 1) ? "sticks" : "stick", attname); (shield[i]->amt == 1) ? "sticks" : "stick", attname);
} }
@ -2073,7 +2096,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, objec
} else { } else {
strcpy(lfname, "Something"); strcpy(lfname, "Something");
} }
msg("^%d%s slice%s off %s%s %s!", getlfcol(victim, CC_VBAD), msg("^%c%s slice%s off %s%s %s!", getlfcol(victim, CC_VBAD),
lfname, isplayer(lf) ? "" : "s", vname, getpossessive(vname), bpname); lfname, isplayer(lf) ? "" : "s", vname, getpossessive(vname), bpname);
} }
// take extra damage based on number of severable limbs // take extra damage based on number of severable limbs
@ -2848,7 +2871,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical,
return gothit; return gothit;
} }
void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) { void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam, int isunarmed) {
flag_t *f; flag_t *f;
lifeform_t *victim; lifeform_t *victim;
lifeform_t *owner = NULL; lifeform_t *owner = NULL;
@ -2888,6 +2911,12 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
// ie "a poisoned short sword" // ie "a poisoned short sword"
snprintf(frombuf, BUFLEN, "%s", wepname); snprintf(frombuf, BUFLEN, "%s", wepname);
} }
} else {
if (owner) {
real_getlfname(owner, frombuf, NULL, B_SHOWALL, B_REALRACE);
} else {
strcpy(frombuf, "something unknown");
}
} }
getflags(fp, retflag, &nretflags, F_FLAMESTRIKE, F_HEAVYBLOW, F_HITCONFER, F_RACESLAY, F_REVENGE, F_RUSTED, F_NONE); getflags(fp, retflag, &nretflags, F_FLAMESTRIKE, F_HEAVYBLOW, F_HITCONFER, F_RACESLAY, F_REVENGE, F_RUSTED, F_NONE);
@ -2982,6 +3011,14 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
fid = f->val[0]; fid = f->val[0];
ftext = f->text; ftext = f->text;
// hitconfer from owner can't be conferred if this was a weapon attack
// ie. if something has poisonous claws and hits you with a weapon, you
// don't get poisoned.
if (fp->owner && !isunarmed) {
continue;
}
// the f_poisoned flag stacks, others don't. // the f_poisoned flag stacks, others don't.
if (!lfhasflag(victim, fid) || (fid == F_POISONED)) { if (!lfhasflag(victim, fid) || (fid == F_POISONED)) {
int passedcheck = B_FALSE; int passedcheck = B_FALSE;
@ -3009,6 +3046,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
enum POISONTYPE ptype; enum POISONTYPE ptype;
int ppower; int ppower;
assert(valflag);
if (valflag) { if (valflag) {
ptype = valflag->val[0]; ptype = valflag->val[0];
if (valflag->val[1] == NA) { if (valflag->val[1] == NA) {
@ -3016,15 +3054,20 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
} else { } else {
ppower = valflag->val[1]; ppower = valflag->val[1];
} }
} else {
// should never happen.
ptype = P_VENOM;
ppower = 1;
} }
if (!wep && strlen(ftext)) { if (!wep && strlen(ftext)) {
strcpy(frombuf, ftext); strcpy(frombuf, ftext);
} else if (ptype == P_LYCANTHROPY) {
char *p;
// special case - we need to remember what kind of
// creature to change into. since lycanthropy isn't fatal
// as such we can use the 'what caused you damage' field for
// this information
p = readuntil(frombuf, valflag->text, '^');
readuntil(frombuf, p, '^');
} }
poison(victim, howlong, ptype, ppower, frombuf, owner ? owner->race->id : R_NONE); poison(victim, howlong, ptype, ppower, frombuf, owner ? owner->race->id : R_NONE);
} else { } else {
// flag values // flag values

View File

@ -30,4 +30,4 @@ int ismeleedam(enum DAMTYPE damtype);
int isphysicaldam(enum DAMTYPE damtype); int isphysicaldam(enum DAMTYPE damtype);
void modifyforsize(int *val, lifeform_t *lf, lifeform_t *victim, int howmuch, enum MODTYPE how); void modifyforsize(int *val, lifeform_t *lf, lifeform_t *victim, int howmuch, enum MODTYPE how);
int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical, int *fumble); int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical, int *fumble);
void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam); void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam, int isunarmed);

39
data.c
View File

@ -533,7 +533,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_LEVFLAG, 5, F_DISEASEIMMUNE, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 5, F_DISEASEIMMUNE, B_TRUE, NULL);
// 6: waterawlk via 'body equilibrium' (innate) // 6: waterawlk via 'body equilibrium' (innate)
addflag(lastjob->flags, F_LEVABIL, 6, OT_A_AIMEDSTRIKE, NA, NULL); addflag(lastjob->flags, F_LEVABIL, 6, OT_A_AIMEDSTRIKE, NA, NULL);
// 7: iron fist - converts all remaining stamina to damage+knockback. addflag(lastjob->flags, F_LEVABIL, 7, OT_A_IRONFIST, NA, NULL);
// 8: molecular manipulation (ie. lower hardness of physical obs by level-7, not lfs) (innate) // 8: molecular manipulation (ie. lower hardness of physical obs by level-7, not lfs) (innate)
addflag(lastjob->flags, F_LEVFLAG, 8, F_TREMORSENSE, NA, NULL); addflag(lastjob->flags, F_LEVFLAG, 8, F_TREMORSENSE, NA, NULL);
// 9: resistance to charm, hypnosis, sleep (innate) // 9: resistance to charm, hypnosis, sleep (innate)
@ -1029,6 +1029,7 @@ void initobjects(void) {
addpoisontype(P_FOOD, "gastroenteritis", "Poisoned", "^bYOU vomit#S violently.", OT_VOMITPOOL, 1, 25, PS_POISON,20); addpoisontype(P_FOOD, "gastroenteritis", "Poisoned", "^bYOU vomit#S violently.", OT_VOMITPOOL, 1, 25, PS_POISON,20);
addpoisontype(P_FOODBAD, "salmonella poisoning", "Poisoned", "^bYOU vomit#S violently.", OT_VOMITPOOL, 2, 33, PS_POISON, 30); addpoisontype(P_FOODBAD, "salmonella poisoning", "Poisoned", "^bYOU vomit#S violently.", OT_VOMITPOOL, 2, 33, PS_POISON, 30);
addpoisontype(P_GAS, "gas inhalation", "Poisoned", "^bYOU cough#S.", OT_NONE, 1, 25, PS_POISON,0); addpoisontype(P_GAS, "gas inhalation", "Poisoned", "^bYOU cough#S.", OT_NONE, 1, 25, PS_POISON,0);
addpoisontype(P_LYCANTHROPY, "lycanthropy", "Cursed", "", OT_NONE, 0, 0, PS_CURSE, -1);
addpoisontype(P_ROT, "the mummy's curse", "Cursed", "", OT_NONE, 0, 0, PS_CURSE, 0); addpoisontype(P_ROT, "the mummy's curse", "Cursed", "", OT_NONE, 0, 0, PS_CURSE, 0);
addpoisontype(P_TETANUS, "tetanus", "Sick", "^bYOUR muscles spasm violently!", OT_NONE, 0, 3, PS_DISEASE, 15); addpoisontype(P_TETANUS, "tetanus", "Sick", "^bYOUR muscles spasm violently!", OT_NONE, 0, 3, PS_DISEASE, 15);
addpoisontype(P_VENOM, "venom poisoning", "Poisoned", "^bYOU cough#S up blood.", OT_BLOODSPLASH, 1, 25, PS_POISON, 0); addpoisontype(P_VENOM, "venom poisoning", "Poisoned", "^bYOU cough#S up blood.", OT_BLOODSPLASH, 1, 25, PS_POISON, 0);
@ -2788,6 +2789,8 @@ void initobjects(void) {
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 150, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 150, NA, NA, NULL);
addot(OT_POT_LYCANTHROPY, "potion of lycanthropy", "Infects the drinker with the curse of lycanthropy.", MT_GLASS, 1, OC_POTION, SZ_TINY);
addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL);
addot(OT_POT_LEVITATION, "potion of levitation", "Causes the drinker to float up in the air.", MT_GLASS, 1, OC_POTION, SZ_TINY); addot(OT_POT_LEVITATION, "potion of levitation", "Causes the drinker to float up in the air.", MT_GLASS, 1, OC_POTION, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL);
addflag(lastot->flags, F_VALUE, 150, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 150, NA, NA, NULL);
@ -4779,6 +4782,10 @@ void initobjects(void) {
addflag(lastot->flags, F_STAMCOST, 4, NA, NA, NULL); addflag(lastot->flags, F_STAMCOST, 4, NA, NA, NULL);
addot(OT_A_INSPECT, "inspect item", "Try to identify an unknown scroll, book, wand or ring from your pack.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addot(OT_A_INSPECT, "inspect item", "Try to identify an unknown scroll, book, wand or ring from your pack.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addot(OT_A_IRONFIST, "iron fist", "Channel all your remaining stamina into one almighty blow.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
addflag(lastot->flags, F_STAMCOST, 1, NA, NA, NULL);
addot(OT_A_JUMP, "jump", "You can leap large distances.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addot(OT_A_JUMP, "jump", "You can leap large distances.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL);
@ -4972,6 +4979,7 @@ void initobjects(void) {
addflag(lastot->flags, F_THE, NA, NA, NA, NULL); addflag(lastot->flags, F_THE, NA, NA, NA, NULL);
addflag(lastot->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OPERWITHOUTHANDS, B_TRUE, NA, NA, NULL);
addot(OT_KEYIRON, "ancient iron key", "An ancient key made from iron. It looks important.", MT_METAL, 2, OC_TOOLS, SZ_SMALL); addot(OT_KEYIRON, "ancient iron key", "An ancient key made from iron. It looks important.", MT_METAL, 2, OC_TOOLS, SZ_SMALL);
addflag(lastot->flags, F_GLYPH, C_GREY, '[', NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, '[', NA, NULL);
@ -5349,6 +5357,7 @@ void initobjects(void) {
addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_HOLDCONFER, F_KNOWSTIME, B_FALSE, IFKNOWN, NULL); addflag(lastot->flags, F_HOLDCONFER, F_KNOWSTIME, B_FALSE, IFKNOWN, NULL);
addflag(lastot->flags, F_OPERWITHOUTHANDS, B_TRUE, NA, NA, NULL);
addot(OT_DIGITALWATCH, "digital watch", "An electronic timekeeping device which shows the time as a number.", MT_METAL, 0.1, OC_TECH, SZ_TINY); addot(OT_DIGITALWATCH, "digital watch", "An electronic timekeeping device which shows the time as a number.", MT_METAL, 0.1, OC_TECH, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, 85, NA, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 85, NA, NULL);
addflag(lastot->flags, F_VALUE, 50, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 50, NA, NA, NULL);
@ -5356,6 +5365,7 @@ void initobjects(void) {
addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_HOLDCONFER, F_KNOWSTIME, B_TRUE, IFKNOWN, NULL); addflag(lastot->flags, F_HOLDCONFER, F_KNOWSTIME, B_TRUE, IFKNOWN, NULL);
addflag(lastot->flags, F_OPERWITHOUTHANDS, B_TRUE, NA, NA, NULL);
addot(OT_INSECTICIDE, "can of insecticide", "A spraycan containing poisonous chemicals.", MT_METAL, 0.5, OC_TECH, SZ_TINY); addot(OT_INSECTICIDE, "can of insecticide", "A spraycan containing poisonous chemicals.", MT_METAL, 0.5, OC_TECH, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_SWAMP, 85, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_SWAMP, 85, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 85, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 85, RR_UNCOMMON, NULL);
@ -17222,7 +17232,7 @@ void initrace(void) {
addflag(lastrace->flags, F_SPELLSPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_SPELLSPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 6, NA, NA, NULL); addflag(lastrace->flags, F_TR, 6, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 6, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL);
addflag(lastrace->flags, F_REGENERATES, 1, NA, NA, NULL); addflag(lastrace->flags, F_REGENERATES, 1, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:2d8;"); addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:2d8;");
@ -17239,10 +17249,13 @@ void initrace(void) {
addflag(lastrace->flags, F_HATESRACE, R_WERERAT, NA, NA, NULL); addflag(lastrace->flags, F_HATESRACE, R_WERERAT, NA, NA, NULL);
addflag(lastrace->flags, F_HATESRACE, R_WEREWOLF, NA, NA, NULL); addflag(lastrace->flags, F_HATESRACE, R_WEREWOLF, NA, NA, NULL);
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_LYCANTHROPE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_LYCANTHROPE, -1, NA, NA, "grizzly bear");
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL);
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 25, NULL);
addflag(lastrace->flags, F_HITCONFERVALS, P_LYCANTHROPY, -1, PERMENANT, "10^grizzly bear");
addflag(lastrace->flags, F_FILLPOT, OT_POT_LYCANTHROPY, NA, NA, NULL);
addrace(R_WERERAT, "wererat", 50, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Weedy humans with shifty eyes and whiskers, wererats are known for their extreme cunning."); addrace(R_WERERAT, "wererat", 50, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Weedy humans with shifty eyes and whiskers, wererats are known for their extreme cunning.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -17266,10 +17279,12 @@ void initrace(void) {
addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL); addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 2, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
addflag(lastrace->flags, F_REGENERATES, 1, NA, NA, NULL); addflag(lastrace->flags, F_REGENERATES, 1, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_SHAPESHIFT, 3, 3, "pw:1;race:plague rat;"); addflag(lastrace->flags, F_CANCAST, OT_S_SHAPESHIFT, 3, 3, "pw:1;race:plague rat;");
addflag(lastrace->flags, F_CANCAST, OT_S_SUMMONANIMALSSM, 10, 10, "pw:5;race:giant rat;count:5;"); addflag(lastrace->flags, F_CANCAST, OT_S_SUMMONANIMALSSM, 10, 10, "pw:5;race:giant rat;count:5;");
addflag(lastrace->flags, F_STARTOBWEPSK, 100, SK_SHORTBLADES, NA, NULL); addflag(lastrace->flags, F_STARTOBWEPSK, 40, SK_SHORTBLADES, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 10, NA, NA, "potion of rum"); addflag(lastrace->flags, F_STARTOB, 10, NA, NA, "potion of rum");
addflag(lastrace->flags, F_AISPELLTARGETOVERRIDE, OT_S_SHAPESHIFT, F_AICASTTOFLEE, ST_SELF, "100"); addflag(lastrace->flags, F_AISPELLTARGETOVERRIDE, OT_S_SHAPESHIFT, F_AICASTTOFLEE, ST_SELF, "100");
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL);
@ -17279,8 +17294,11 @@ void initrace(void) {
addflag(lastrace->flags, F_WANTS, OT_POT_RUM, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_POT_RUM, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "twitches its nose"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "twitches its nose");
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_LYCANTHROPE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_LYCANTHROPE, -1, NA, NA, "dire rat");
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 25, NULL);
addflag(lastrace->flags, F_HITCONFERVALS, P_LYCANTHROPY, -1, PERMENANT, "10^dire rat");
addflag(lastrace->flags, F_FILLPOT, OT_POT_LYCANTHROPY, NA, NA, NULL);
addrace(R_WEREWOLF, "werewolf", 100, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Shaggy humans with the uncanny ability to shapeshift into a ferocious wolf."); addrace(R_WEREWOLF, "werewolf", 100, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Shaggy humans with the uncanny ability to shapeshift into a ferocious wolf.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -17302,7 +17320,9 @@ void initrace(void) {
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 4, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 4, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); addflag(lastrace->flags, F_TR, 4, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 6, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 4, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 6, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
addflag(lastrace->flags, F_REGENERATES, 1, NA, NA, NULL); addflag(lastrace->flags, F_REGENERATES, 1, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_SHAPESHIFT, 3, 3, "pw:1;race:dire wolf;"); addflag(lastrace->flags, F_CANCAST, OT_S_SHAPESHIFT, 3, 3, "pw:1;race:dire wolf;");
addflag(lastrace->flags, F_CANCAST, OT_S_SUMMONANIMALSMD, 10, 10, "pw:5;race:young wolf;"); addflag(lastrace->flags, F_CANCAST, OT_S_SUMMONANIMALSMD, 10, 10, "pw:5;race:young wolf;");
@ -17313,11 +17333,14 @@ void initrace(void) {
addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "howls"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "howls");
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_LYCANTHROPE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_LYCANTHROPE, -1, NA, NA, "dire wolf");
addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); // ie. cats will know! addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); // ie. cats will know!
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 6, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 6, NA, NA, NULL);
addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 25, NULL);
addflag(lastrace->flags, F_HITCONFERVALS, P_LYCANTHROPY, -1, PERMENANT, "10^dire wolf");
addflag(lastrace->flags, F_FILLPOT, OT_POT_LYCANTHROPY, NA, NA, NULL);
// special monsters // special monsters
addrace(R_GASCLOUD, "cloud of gas", 0.1, 'y', C_GREY, MT_GAS, RC_OTHER, "A large cloud of gas which seems to move with a life of its own..."); addrace(R_GASCLOUD, "cloud of gas", 0.1, 'y', C_GREY, MT_GAS, RC_OTHER, "A large cloud of gas which seems to move with a life of its own...");

Binary file not shown.

20
defs.h
View File

@ -23,6 +23,9 @@
#define TEXT_WARN_MUTABLE "(you can now gain attributes by eating corpses)" #define TEXT_WARN_MUTABLE "(you can now gain attributes by eating corpses)"
#define TEXT_WARN_NOXP_GOODVSPEACEFUL "Warning: Only Evil players gain XP for peaceful kills." #define TEXT_WARN_NOXP_GOODVSPEACEFUL "Warning: Only Evil players gain XP for peaceful kills."
// F_SCOREBONUS text args
#define SCB_DONATIONS "charitable donations"
// Defaults // Defaults
#define DEF_AIFOLLOWTIME (20) // if target lf is out of view #define DEF_AIFOLLOWTIME (20) // if target lf is out of view
@ -477,6 +480,7 @@ enum SHOPACTION {
#define PERMENANT (-9873) #define PERMENANT (-9873)
#define FROMSPELL (-9863) #define FROMSPELL (-9863)
#define FROMPOISON (-9862) #define FROMPOISON (-9862)
#define FROMLYCANTHROPY (-9861)
// flag lifetimes - external sources (ie. don't kill them) // flag lifetimes - external sources (ie. don't kill them)
#define FROMEXTERNAL_HIGH (-7000) #define FROMEXTERNAL_HIGH (-7000)
@ -560,6 +564,7 @@ enum GODANGERREASON {
GA_MERCY, // allowed something to flee GA_MERCY, // allowed something to flee
GA_MONEY, // paid money to someone GA_MONEY, // paid money to someone
GA_MURDER, // killed someone peaceful GA_MURDER, // killed someone peaceful
GA_PEACEHOUR, // attacked during glorana's peace
GA_POISON, // used poison GA_POISON, // used poison
GA_PRAY, // pestering through constant prayer GA_PRAY, // pestering through constant prayer
GA_RACE, // prayed while a hated race. GA_RACE, // prayed while a hated race.
@ -1527,6 +1532,7 @@ enum OBTYPE {
OT_POT_INVIS, OT_POT_INVIS,
OT_POT_INVULN, OT_POT_INVULN,
OT_POT_LEVITATION, OT_POT_LEVITATION,
OT_POT_LYCANTHROPY,
OT_POT_MAGIC, OT_POT_MAGIC,
OT_POT_OIL, OT_POT_OIL,
OT_POT_POISON, OT_POT_POISON,
@ -1865,6 +1871,7 @@ enum OBTYPE {
OT_A_HEAVYBLOW, OT_A_HEAVYBLOW,
OT_A_HIDE, OT_A_HIDE,
OT_A_INSPECT, OT_A_INSPECT,
OT_A_IRONFIST,
OT_A_HURRICANESTRIKE, OT_A_HURRICANESTRIKE,
OT_A_PICKLOCK, OT_A_PICKLOCK,
OT_A_POLYREVERT, OT_A_POLYREVERT,
@ -2411,6 +2418,7 @@ enum POISONTYPE {
P_FOOD, P_FOOD,
P_FOODBAD, P_FOODBAD,
P_GAS, P_GAS,
P_LYCANTHROPY,
P_MIGRAINE, P_MIGRAINE,
P_ROT, P_ROT,
P_TETANUS, P_TETANUS,
@ -2705,6 +2713,8 @@ enum FLAG {
// -1 means "nutrition is weight x abs(val1)" // -1 means "nutrition is weight x abs(val1)"
// if v2=DONTKILL, this object does NOT die when drunk. // if v2=DONTKILL, this object does NOT die when drunk.
F_OPERABLE, // can operate? F_OPERABLE, // can operate?
F_OPERWITHOUTHANDS, // can operate without having hands or being
// humanoid
F_OPERWITHOUTID, // can operate without knowing what it is? F_OPERWITHOUTID, // can operate without knowing what it is?
F_NOTRIED, // don't show '[tried]' or update knowledge F_NOTRIED, // don't show '[tried]' or update knowledge
// after you have tried this object. // after you have tried this object.
@ -2795,6 +2805,8 @@ enum FLAG {
F_SHARP, // does damage when you step on it. v0/1 are min/max dam F_SHARP, // does damage when you step on it. v0/1 are min/max dam
F_SCARY, // gives other lfs a penalty to morale checks against you, F_SCARY, // gives other lfs a penalty to morale checks against you,
// v0 = penalty amt. // v0 = penalty amt.
F_SCOREBONUS, // player gains (v1*65535)+v0 points at end game.
// text = reason (ie 'donated items' etc)
F_SLIPPERY, // you might slip when stepping on it. v0 is amt F_SLIPPERY, // you might slip when stepping on it. v0 is amt
F_SLIPMOVE, // if someone slips on this, it will move to an adj cell F_SLIPMOVE, // if someone slips on this, it will move to an adj cell
F_FLAMMABLE, // object will catch alight if burnt (ie fire damage) F_FLAMMABLE, // object will catch alight if burnt (ie fire damage)
@ -2984,6 +2996,7 @@ enum FLAG {
// OR // OR
// eating this object gives it. // eating this object gives it.
// player only flags // player only flags
F_AICONTROLLED, // player will be controlled by the computer
F_DONEBURNMSG, // tells the game not to say 'the {celltype} burns!' F_DONEBURNMSG, // tells the game not to say 'the {celltype} burns!'
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.
@ -3452,7 +3465,12 @@ enum FLAG {
F_HUMANOID, // this race is a humanoid F_HUMANOID, // this race is a humanoid
// (can wear armour / use weapons) // (can wear armour / use weapons)
F_INSECT, // this race is classed as an insect F_INSECT, // this race is classed as an insect
F_LYCANTHROPE, // this race is a lycanthrope. text = what to turn into. F_LYCANTHROPE, // this race is a lycanthrope.
// text = what to turn into.
// v0 = # of automatic full moon chnages left.
// each auto change will decrement this, down
// to zero.
// -1 means always change on full moon.
F_UNDEAD, // this race is classed as undead F_UNDEAD, // this race is classed as undead
F_COLDBLOOD, // this race is coldblooded F_COLDBLOOD, // this race is coldblooded
F_NOBODYPART, // this race doesn't have bodypart val0 F_NOBODYPART, // this race doesn't have bodypart val0

11
flag.c
View File

@ -1385,6 +1385,17 @@ void timeeffectsflag(flag_t *f, int howlong) {
} }
} }
int flagretainedduringpoly(enum FLAG fid) {
switch (fid) {
case F_FLEEFROM:
case F_HOSTILE:
case F_LYCANTHROPE:
return B_TRUE;
default: break;
}
return B_FALSE;
}
int flagtomaxhp(flag_t *f) { int flagtomaxhp(flag_t *f) {
int hp; int hp;
int nsides = HITDIESIDES; int nsides = HITDIESIDES;

1
flag.h
View File

@ -22,6 +22,7 @@ int flagcausesinterrupt(flag_t *f, enum GAINORLOSS gol);
int flagcausesloscalc(enum FLAG fid); int flagcausesloscalc(enum FLAG fid);
int flagcausesredraw(lifeform_t *lf, enum FLAG fid); int flagcausesredraw(lifeform_t *lf, enum FLAG fid);
int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid); int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid);
int flagretainedduringpoly(enum FLAG fid);
int flagstacks(enum FLAG fid); int flagstacks(enum FLAG fid);
int flagtomaxhp(flag_t *f); int flagtomaxhp(flag_t *f);
cell_t *getflagpilelocation(flagpile_t *fp); cell_t *getflagpilelocation(flagpile_t *fp);

3
god.c
View File

@ -113,6 +113,9 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) {
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: case GA_MURDER:
godsay(rid, B_TRUE, "You have taken a life!"); break; godsay(rid, B_TRUE, "You have taken a life!"); break;
case GA_PEACEHOUR:
godsay(rid, B_TRUE, "You dare violate the sanctity of Glorana's Peace?"); break;
break;
case GA_PRAY: dosay = B_TRUE; break; case GA_PRAY: dosay = B_TRUE; break;
case GA_POISON: case GA_POISON:
godsay(rid, B_TRUE, "I do not condone the use of poison!"); break; godsay(rid, B_TRUE, "I do not condone the use of poison!"); break;

72
io.c
View File

@ -1316,12 +1316,18 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
} }
switch (f->id) { switch (f->id) {
case F_AICONTROLLED:
if (isplayer(lf)) {
msg("^%cYou lose control of your body!", getlfcol(lf, CC_VBAD));
donesomething = B_TRUE;
}
break;
case F_ANTICIPATE: case F_ANTICIPATE:
if (isplayer(lf)) { if (isplayer(lf)) {
lf2 = findlf(NULL, f->val[0]); lf2 = findlf(NULL, f->val[0]);
if (lf2) { if (lf2) {
getlfname(lf2, buf); getlfname(lf2, buf);
msg("^%d%s%s intentions enter your mind!", getlfcol(lf, CC_GOOD), buf, getpossessive(buf)); msg("^%c%s%s intentions enter your mind!", getlfcol(lf, CC_GOOD), buf, getpossessive(buf));
donesomething = B_TRUE; donesomething = B_TRUE;
} }
} }
@ -1610,10 +1616,10 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
break; break;
case F_HEAVENARM: case F_HEAVENARM:
if (isplayer(lf)) { // don't know if monsters get it if (isplayer(lf)) { // don't know if monsters get it
msg("^%dYou are surrounded by a %s!", getlfcol(lf, CC_GOOD), f->text); msg("^%cYou are surrounded by a %s!", getlfcol(lf, CC_GOOD), f->text);
donesomething = B_TRUE; donesomething = B_TRUE;
} else { } else {
msg("^%d%s is surrounded by a %s!", getlfcol(lf, CC_GOOD), lfname, f->text); msg("^%c%s is surrounded by a %s!", getlfcol(lf, CC_GOOD), lfname, f->text);
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; break;
@ -1693,9 +1699,9 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
pt = findpoisontype(f->val[0]); pt = findpoisontype(f->val[0]);
if (isplayer(lf)) { if (isplayer(lf)) {
if (streq(pt->desc, "Sick") || (pt->id == P_FOOD) || (pt->id == P_FOODBAD)) { if (streq(pt->desc, "Sick") || (pt->id == P_FOOD) || (pt->id == P_FOODBAD)) {
msg("^%cYou have contracted %s.", getlfcol(lf, CC_VBAD), pt->name);
} else {
msg("^%cYou are sick with %s.", getlfcol(lf, CC_VBAD), pt->name); msg("^%cYou are sick with %s.", getlfcol(lf, CC_VBAD), pt->name);
} else {
msg("^%cYou have contracted %s.", getlfcol(lf, CC_VBAD), pt->name);
} }
more(); more();
} else { } else {
@ -2097,12 +2103,18 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
return B_FALSE; return B_FALSE;
} }
switch (f->id) { switch (f->id) {
case F_AICONTROLLED:
if (isplayer(lf)) {
msg("You have regained control of your body.");
donesomething = B_TRUE;
}
break;
case F_ANTICIPATE: case F_ANTICIPATE:
if (isplayer(lf)) { if (isplayer(lf)) {
lf2 = findlf(NULL, f->val[0]); lf2 = findlf(NULL, f->val[0]);
if (lf2) { if (lf2) {
getlfname(lf2, buf); getlfname(lf2, buf);
msg("^%dYou no longer know %s%s intentions.", getlfcol(lf, CC_BAD), buf, getpossessive(buf)); msg("^%cYou no longer know %s%s intentions.", getlfcol(lf, CC_BAD), buf, getpossessive(buf));
donesomething = B_TRUE; donesomething = B_TRUE;
} }
} }
@ -2387,13 +2399,13 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
break; break;
case F_HEAVENARM: case F_HEAVENARM:
if (isplayer(lf)) { // don't know if monsters get it if (isplayer(lf)) { // don't know if monsters get it
msg("^%dYour %s vanishes!", getlfcol(lf, CC_BAD), f->text); msg("^%cYour %s vanishes!", getlfcol(lf, CC_BAD), f->text);
donesomething = B_TRUE; donesomething = B_TRUE;
} else { } else {
char text[BUFLEN]; char text[BUFLEN];
sprintf(text,"%s%s %s vanishes!", lfname, getpossessive(lfname), f->text); sprintf(text,"%s%s %s vanishes!", lfname, getpossessive(lfname), f->text);
capitalise(text); capitalise(text);
msg("^%d%s", getlfcol(lf, CC_BAD), text); msg("^%c%s", getlfcol(lf, CC_BAD), text);
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; break;
@ -4231,7 +4243,12 @@ void docomms(lifeform_t *lf) {
if (!isgod(lf) && ispeaceful(lf) && cantalk(lf)) { if (!isgod(lf) && ispeaceful(lf) && cantalk(lf)) {
enum SKILLLEVEL slev; enum SKILLLEVEL slev;
job_t *j;
slev = getskill(player, SK_SPEECH); slev = getskill(player, SK_SPEECH);
// same race or job?
j = getjob(player);
if ((slev != PR_MASTER) && j && (j == getjob(lf))) slev++;
if ((slev != PR_MASTER) && (player->race->id == lf->race->id)) slev++;
if (slev >= PR_NOVICE) { if (slev >= PR_NOVICE) {
addchoice(&prompt, 'x', "Any dangers nearby that I should look out for?", NULL, NULL, NULL); addchoice(&prompt, 'x', "Any dangers nearby that I should look out for?", NULL, NULL, NULL);
} }
@ -4304,7 +4321,7 @@ void docomms(lifeform_t *lf) {
getlfname(lf2, lfname2); getlfname(lf2, lfname2);
msg("You say \"Attack %s!\" to %s.",isplayer(lf2) ? "me" : lfname2, lfname); msg("You say \"Attack %s!\" to %s.",isplayer(lf2) ? "me" : lfname2, lfname);
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); msg("%s doesn't respond.", lfname);
break; break;
} }
@ -4334,7 +4351,7 @@ void docomms(lifeform_t *lf) {
break; break;
case 'c': case 'c':
msg("You say \"Come here!\" to %s.",lfname); msg("You say \"Come here!\" to %s.",lfname);
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); msg("%s doesn't respond.", lfname);
break; break;
} }
@ -4548,7 +4565,7 @@ void docomms(lifeform_t *lf) {
// stop attacking all current targets first... // stop attacking all current targets first...
killflagsofid(lf->flags, F_TARGETLF); killflagsofid(lf->flags, F_TARGETLF);
msg("You say \"Go over there!\" to %s.", lfname); msg("You say \"Go over there!\" to %s.", lfname);
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); msg("%s doesn't respond.", lfname);
break; break;
} }
@ -4572,7 +4589,7 @@ void docomms(lifeform_t *lf) {
case 'j': case 'j':
// charisma check to see if they'll join you. // charisma check to see if they'll join you.
msg("You say \"Join me on my quest!\" to %s.", lfname); msg("You say \"Join me on my quest!\" to %s.", lfname);
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); msg("%s doesn't respond.", lfname);
break; break;
} }
@ -4598,7 +4615,7 @@ void docomms(lifeform_t *lf) {
} }
if (islowhp(player) && if (islowhp(player) &&
cantalk(lf) && cantalk(lf) &&
canhear(lf, player->cell, SV_SHOUT) && canhear(lf, player->cell, SV_SHOUT, NULL) &&
(getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) > IQ_ANIMAL) && (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) > IQ_ANIMAL) &&
!isundead(lf)) { !isundead(lf)) {
if (skillcheck(player, SC_SPEECH, 30, alignmod)) { if (skillcheck(player, SC_SPEECH, 30, alignmod)) {
@ -4663,7 +4680,7 @@ void docomms(lifeform_t *lf) {
*/ */
case 'r': case 'r':
msg("You say \"Get some rest.\" to %s.", lfname); msg("You say \"Get some rest.\" to %s.", lfname);
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); msg("%s doesn't respond.", lfname);
break; break;
} }
@ -4736,7 +4753,7 @@ void docomms(lifeform_t *lf) {
break; break;
case '<': case '<':
msg("You say \"Stay close!\" to %s.", lfname); msg("You say \"Stay close!\" to %s.", lfname);
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); msg("%s doesn't respond.", lfname);
break; break;
} }
@ -4748,7 +4765,7 @@ void docomms(lifeform_t *lf) {
break; break;
case '>': case '>':
msg("You say \"Keep your distance!\" to %s.", lfname); msg("You say \"Keep your distance!\" to %s.", lfname);
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); msg("%s doesn't respond.", lfname);
break; break;
} }
@ -10998,7 +11015,11 @@ void drawstatus(void) {
pt = findpoisontype(f->val[0]); pt = findpoisontype(f->val[0]);
// find highest amount of poison // find highest amount of poison
if (getskill(player, SK_FIRSTAID) >= PR_ADEPT) { if (getskill(player, SK_FIRSTAID) >= PR_ADEPT) {
if (poisonthreatenslife(player, f)) { if (pt->severity == PS_CURSE) {
setcol(statwin, C_RED);
wprintw(statwin, " %s", pt->desc);
unsetcol(statwin, C_RED);
} else if (poisonthreatenslife(player, f)) {
setcol(statwin, C_RED); setcol(statwin, C_RED);
wprintw(statwin, " %s(bad)", pt->desc); wprintw(statwin, " %s(bad)", pt->desc);
unsetcol(statwin, C_RED); unsetcol(statwin, C_RED);
@ -11304,10 +11325,14 @@ void showlfarmour(lifeform_t *lf) {
enum BODYPART bp; enum BODYPART bp;
object_t *o; object_t *o;
object_t *arm[MAXBODYPARTS]; object_t *arm[MAXBODYPARTS];
int y; int y,i;
char buf[BUFLEN],ch; char buf[BUFLEN],ch;
int keepgoing = B_TRUE; int keepgoing = B_TRUE;
for (i = 0; i < MAXBODYPARTS; i++) {
arm[i] = NULL;
}
while (keepgoing) { while (keepgoing) {
cls(); cls();
if (isplayer(lf)) { if (isplayer(lf)) {
@ -13427,14 +13452,21 @@ void showlfstats(lifeform_t *lf, int showall) {
} }
} }
if (pt->id == P_LYCANTHROPY) {
snprintf(buf, BUFLEN, "%s %s afflicted with %s.", you(lf), is(lf),
pt->name);
} else {
snprintf(buf, BUFLEN, "%s %s sick with %s%s.", you(lf), is(lf), snprintf(buf, BUFLEN, "%s %s sick with %s%s.", you(lf), is(lf),
pt->name, knownfatal ? ", potentially fatally" : ""); pt->name, knownfatal ? ", potentially fatally" : "");
}
if (pt->severity != PS_CURSE) {
if (lfhasflag(lf, F_EXTRAINFO) || lfhasflag(lf, F_OMNIPOTENT) || if (lfhasflag(lf, F_EXTRAINFO) || lfhasflag(lf, F_OMNIPOTENT) ||
(getskill(player, SK_FIRSTAID) >= PR_ADEPT) ) { (getskill(player, SK_FIRSTAID) >= PR_ADEPT) ) {
char buf2[BUFLEN]; char buf2[BUFLEN];
snprintf(buf2, BUFLEN, " [max %d turns left]", f->lifetime); snprintf(buf2, BUFLEN, " [max %d turns left]", f->lifetime);
strcat(buf, buf2); strcat(buf, buf2);
} }
}
mvwprintw(mainwin, y, 0, buf); mvwprintw(mainwin, y, 0, buf);
y++; y++;
} }
@ -13442,7 +13474,11 @@ void showlfstats(lifeform_t *lf, int showall) {
if (f->known && (f->id == F_INCUBATING)) { if (f->known && (f->id == F_INCUBATING)) {
poisontype_t *pt; poisontype_t *pt;
pt = findpoisontype(f->val[0]); pt = findpoisontype(f->val[0]);
if (pt->id == P_LYCANTHROPY) {
snprintf(buf, BUFLEN, "%s %s afflicted with early onset %s.", you(lf), is(lf), pt->name);
} else {
snprintf(buf, BUFLEN, "%s %s incubating %s.", you(lf), is(lf), pt->name); snprintf(buf, BUFLEN, "%s %s incubating %s.", you(lf), is(lf), pt->name);
}
mvwprintw(mainwin, y, 0, buf); mvwprintw(mainwin, y, 0, buf);
y++; y++;
} }

320
lf.c
View File

@ -316,13 +316,23 @@ long calcscore(lifeform_t *lf) {
flag_t *f; flag_t *f;
long points = 0; long points = 0;
object_t *o; object_t *o;
flag_t *retflag[MAXCANDIDATES];
int nretflags,i;
if (lfhasflag(lf, F_NOSCORE)) { if (lfhasflag(lf, F_NOSCORE)) {
return 0; return 0;
} }
// objects // objects
for (o = lf->pack->first ; o ; o = o->next) { for (o = lf->pack->first ; o ; o = o->next) {
// full points
points += getobpoints(o); points += getobpoints(o);
} }
// donated items etc
getflags(lf->flags, retflag, &nretflags, F_SCOREBONUS, F_NONE);
for (i = 0; i < nretflags; i++) {
long thisamt;
thisamt = (retflag[i]->val[1] * 65535) + retflag[i]->val[0];
points += thisamt;
}
// points for xp // points for xp
points += (lf->xp / 10); points += (lf->xp / 10);
@ -869,7 +879,7 @@ int canhaverandombehaviour(lifeform_t *lf) {
} }
// ie. will sound from 'dest' reach the ears of 'lf' // ie. will sound from 'dest' reach the ears of 'lf'
int canhear(lifeform_t *lf, cell_t *dest, int volume) { int canhear(lifeform_t *lf, cell_t *dest, int volume, int *numwalls) {
int numpixels; int numpixels;
int i; int i;
int x1,y1; int x1,y1;
@ -879,6 +889,8 @@ int canhear(lifeform_t *lf, cell_t *dest, int volume) {
cell_t *retcell[MAXRETCELLS]; cell_t *retcell[MAXRETCELLS];
int celldist; int celldist;
if (numwalls) *numwalls = 0;
if (!lf) return B_FALSE; if (!lf) return B_FALSE;
if (!dest) return B_FALSE; if (!dest) return B_FALSE;
if (!lf->cell) return B_FALSE; if (!lf->cell) return B_FALSE;
@ -937,6 +949,7 @@ int canhear(lifeform_t *lf, cell_t *dest, int volume) {
if (i != 0) { if (i != 0) {
// solid cells decrease hearing range // solid cells decrease hearing range
if (cell->type->solid) { if (cell->type->solid) {
if (numwalls) (*numwalls)++;
sounddist--; sounddist--;
} }
// magic barriers stop all sound // magic barriers stop all sound
@ -1913,7 +1926,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
if (cansee(player, lf)) { if (cansee(player, lf)) {
doannounce = B_TRUE; doannounce = B_TRUE;
} else if ((casttype == CT_SOUNDBASED) && canhear(player, lf->cell, SV_TALK)) { } else if ((casttype == CT_SOUNDBASED) && canhear(player, lf->cell, SV_TALK, NULL)) {
doannounce = B_TRUE; doannounce = B_TRUE;
} }
if (doannounce) { if (doannounce) {
@ -2402,7 +2415,7 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%dThe running water burns %s!", getlfcol(lf, CC_BAD), lfname); msg("^%cThe running water burns %s!", getlfcol(lf, CC_BAD), lfname);
} }
losehp(lf, roll("6d6"), DT_DIRECT, NULL, "running water"); losehp(lf, roll("6d6"), DT_DIRECT, NULL, "running water");
} }
@ -2424,7 +2437,7 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%d%s drowns.",getlfcol(lf, CC_BAD) , lfname); msg("^%c%s drowns.",getlfcol(lf, CC_BAD) , lfname);
didsomething = B_TRUE; didsomething = B_TRUE;
} }
addflag(lf->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL); addflag(lf->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
@ -2441,7 +2454,7 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%d%s is drowning!", getlfcol(lf, CC_VBAD), lfname); msg("^%c%s is drowning!", getlfcol(lf, CC_VBAD), lfname);
didsomething = B_TRUE; didsomething = B_TRUE;
} }
getobnametruebase(o, obname, o->amt); getobnametruebase(o, obname, o->amt);
@ -2523,6 +2536,22 @@ float comparelfs(lifeform_t *lf1, lifeform_t *lf2) {
return ratio; return ratio;
} }
// note: this will kill incubateflag!
void completeincubation(lifeform_t *lf, flag_t *incubateflag) {
// parse flag text to get power & whatfrom
char *p;
char buf[BUFLEN];
int power;
enum POISONTYPE ptype;
ptype = incubateflag->val[0];
p = readuntil(buf, incubateflag->text, '^');
power = atoi(buf);
readuntil(buf, p, '^');
addtempflag(lf->flags, F_POISONED, ptype, power, incubateflag->obfrom, buf, incubateflag->val[2]);
poisoneffects(lf, ptype, power);
killflag(incubateflag);
}
int confuse(lifeform_t *lf, int howlong) { int confuse(lifeform_t *lf, int howlong) {
flag_t *f; flag_t *f;
f = lfhasflag(lf, F_CONFUSED); f = lfhasflag(lf, F_CONFUSED);
@ -3182,7 +3211,7 @@ void die(lifeform_t *lf) {
// intelligent monsters will say something // intelligent monsters will say something
if (!hasflag(lf->flags, F_NODEATHSPEECH) && !lfhasflag(lf, F_SUMMONEDBY)) { if (!hasflag(lf->flags, F_NODEATHSPEECH) && !lfhasflag(lf, F_SUMMONEDBY)) {
if (ispetof(lf, player)) { if (ispetof(lf, player)) {
if (cantalk(lf) && canhear(player, lf->cell, 4)) { if (cantalk(lf) && canhear(player, lf->cell, 4, NULL)) {
sayphrase(lf, SP_DIE, SV_SHOUT, NA, NULL); sayphrase(lf, SP_DIE, SV_SHOUT, NA, NULL);
} else if (!cansee(player, lf)) { } else if (!cansee(player, lf)) {
warn("You feel a profound sense of loss."); warn("You feel a profound sense of loss.");
@ -3203,14 +3232,14 @@ void die(lifeform_t *lf) {
if (cansee(player, lf)) { if (cansee(player, lf)) {
getlfname(lf, buf); getlfname(lf, buf);
if (lf->lastdamtype == DT_EXPLOSIVE) { if (lf->lastdamtype == DT_EXPLOSIVE) {
msg("^%d%s is vaporised!",getlfcol(lf, CC_BAD), buf); msg("^%c%s is vaporised!",getlfcol(lf, CC_BAD), buf);
vaporised = B_TRUE; vaporised = B_TRUE;
} else if (lf->lastdamtype == DT_MELT) { } else if (lf->lastdamtype == DT_MELT) {
msg("^%d%s completely melts.",getlfcol(lf, CC_BAD), buf); msg("^%c%s completely melts.",getlfcol(lf, CC_BAD), buf);
} else if ((lf->lastdamtype == DT_BASH) && lfhasflag(lf, F_FROZEN)) { } else if ((lf->lastdamtype == DT_BASH) && lfhasflag(lf, F_FROZEN)) {
msg("^%d%s shatters!",getlfcol(lf, CC_BAD), buf); msg("^%c%s shatters!",getlfcol(lf, CC_BAD), buf);
} else { } else {
msg("^%d%s dies.",getlfcol(lf, CC_BAD), buf); msg("^%c%s dies.",getlfcol(lf, CC_BAD), buf);
} }
} }
} }
@ -3347,7 +3376,7 @@ void die(lifeform_t *lf) {
if (isplayer(souleater)) { if (isplayer(souleater)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%dYou consume %s%s soul!", getlfcol(souleater, CC_VGOOD), lfname, getpossessive(lfname)); msg("^%cYou consume %s%s soul!", getlfcol(souleater, CC_VGOOD), lfname, getpossessive(lfname));
soulflag->known = B_TRUE; soulflag->known = B_TRUE;
revealflagob(souleater, soulflag); revealflagob(souleater, soulflag);
@ -3355,7 +3384,7 @@ void die(lifeform_t *lf) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
getlfname(souleater, buf); getlfname(souleater, buf);
msg("^%d%s consumes %s%s soul!", getlfcol(souleater, CC_VGOOD), buf, lfname, getpossessive(lfname)); msg("^%c%s consumes %s%s soul!", getlfcol(souleater, CC_VGOOD), buf, lfname, getpossessive(lfname));
soulflag->known = B_TRUE; soulflag->known = B_TRUE;
} }
amt = pctof( rnd(1,soulflag->val[0]), lf->maxhp); amt = pctof( rnd(1,soulflag->val[0]), lf->maxhp);
@ -4875,7 +4904,7 @@ void endlfturn(lifeform_t *lf) {
if (islowhp(lf) && onein(3) && !hasflag(lf->flags, F_ASLEEP)) { if (islowhp(lf) && onein(3) && !hasflag(lf->flags, F_ASLEEP)) {
// TODO: replace 4 // TODO: replace 4
if (ispetof(lf, player)) { if (ispetof(lf, player)) {
if (!canhear(player, lf->cell, 4)) { if (!canhear(player, lf->cell, 4, NULL)) {
char realname[BUFLEN]; char realname[BUFLEN];
real_getlfname(lf, realname, NULL, B_NOSHOWALL, B_REALRACE); real_getlfname(lf, realname, NULL, B_NOSHOWALL, B_REALRACE);
warn("You feel worried about %s%s.", lfhasflag(lf, F_NAME) ? "" : "your ", noprefix(realname)); warn("You feel worried about %s%s.", lfhasflag(lf, F_NAME) ? "" : "your ", noprefix(realname));
@ -5931,6 +5960,38 @@ subjob_t *findsubjob(enum SUBJOB sjid) {
return NULL; return NULL;
} }
// returns true if we did somethign
int fixcurses(lifeform_t *lf) {
int donesomething = B_FALSE;
flag_t *f,*nextf;
for (f = lf->flags->first ; f ; f = nextf) {
nextf = f->next;
if (f->id == F_LYCANTHROPE) {
donesomething = B_TRUE;
killflag(f);
continue;
} else if ((f->id == F_INCUBATING) || (f->id == F_POISONED)) {
poisontype_t *pt;
pt = findpoisontype(f->val[0]);
if (pt->severity == PS_CURSE) {
donesomething = B_TRUE;
killflag(f);
continue;
}
} else if (f->lifetime == FROMLYCANTHROPY) {
donesomething = B_TRUE;
killflag(f);
continue;
}
}
if (donesomething) {
if (isplayer(lf)) {
msg("^%cYour curses are lifted!", getlfcol(lf, CC_VGOOD));
}
}
return donesomething;
}
// try to actually do the 'run away' action for // try to actually do the 'run away' action for
// anyone we are fleeing from. // anyone we are fleeing from.
// returns TRUE if we ran away from something // returns TRUE if we ran away from something
@ -9023,8 +9084,8 @@ char *real_getlfname(lifeform_t *lf, char *buf, lifeform_t *usevis, int showall,
} }
if (!lfrace) { if (!lfrace) {
if (lfhasflag(lf, F_LYCANTHROPE)) { if (lfhasflag(lf, F_LYCANTHROPE) && !ispolymorphed(lf)) {
// lycanthropes appear as human unless you know better // lycanthropes in human form appear as human unless you know better
if ((getlorelevel(player, RC_HUMANOID) >= PR_ADEPT) || if ((getlorelevel(player, RC_HUMANOID) >= PR_ADEPT) ||
(getlorelevel(player, RC_MAGIC) >= PR_BEGINNER)) { (getlorelevel(player, RC_MAGIC) >= PR_BEGINNER)) {
lfrace = lf->race; lfrace = lf->race;
@ -9199,8 +9260,8 @@ char *real_getlfnamea(lifeform_t *lf, char *buf, lifeform_t * usevis, int showal
} }
if (!lfrace) { if (!lfrace) {
if (lfhasflag(lf, F_LYCANTHROPE)) { if (lfhasflag(lf, F_LYCANTHROPE) && !ispolymorphed(lf)) {
// lycanthropes appear as human unless you know better // lycanthropes in human form appear as human unless you know better
if (getlorelevel(player, RC_HUMANOID) >= PR_ADEPT) { if (getlorelevel(player, RC_HUMANOID) >= PR_ADEPT) {
lfrace = lf->race; lfrace = lf->race;
} else { } else {
@ -9803,6 +9864,35 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
return r; return r;
} }
race_t *getrandomracewithflag(enum FLAG fid) {
race_t **poss;
race_t *r;
int nposs = 0;
int sel;
int count = 0;
// count races
for (r = firstrace ; r ; r = r->next) {
if (hasflag(r->flags, fid)) {
count++;
}
}
poss = malloc(count * sizeof(race_t *));
for (r = firstrace ; r ; r = r->next) {
if (hasflag(r->flags, fid)) {
poss[nposs] = r;
nposs++;
}
}
sel = rnd(0,nposs-1);
r = poss[sel];
free(poss);
return r;
}
race_t *getreallyrandomrace(enum RACECLASS wantrc) { race_t *getreallyrandomrace(enum RACECLASS wantrc) {
race_t **poss; race_t **poss;
race_t *r; race_t *r;
@ -11769,7 +11859,7 @@ void growhydrahead(lifeform_t *lf, int announce) {
getlfname(lf, vname); getlfname(lf, vname);
// regrow // regrow
if (cansee(player, lf)) { if (cansee(player, lf)) {
msg("^%d%s grow%s two more heads!", getlfcol(lf, CC_GOOD), vname, isplayer(lf) ? "" : "s"); msg("^%c%s grow%s two more heads!", getlfcol(lf, CC_GOOD), vname, isplayer(lf) ? "" : "s");
} }
} }
@ -12147,7 +12237,7 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype, enum INJUR
if (isplayer(lf)) { if (isplayer(lf)) {
msg("^BYour brain is ruptured!"); msg("^BYour brain is ruptured!");
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
msg("^%d%s%s brain ruptures!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname)); msg("^%c%s%s brain ruptures!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname));
} }
if (lf->hp > 0) { if (lf->hp > 0) {
setlastdam(lf, "a ruptured brain"); setlastdam(lf, "a ruptured brain");
@ -12204,7 +12294,7 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype, enum INJUR
if (isplayer(lf)) { if (isplayer(lf)) {
msg("^BYour heart is pierced!"); msg("^BYour heart is pierced!");
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
msg("^%d%s%s heart is pierced!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname)); msg("^%c%s%s heart is pierced!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname));
} }
if (lf->hp > 0) { if (lf->hp > 0) {
setlastdam(lf, "a pierced heart"); setlastdam(lf, "a pierced heart");
@ -14458,7 +14548,7 @@ void applywalkdam(lifeform_t *lf, int dam, enum DAMTYPE damtype, object_t *o) {
if (isplayer(lf) || cansee(player, lf)) { if (isplayer(lf) || cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%d%s choke%s on %s!", getlfcol(lf, CC_BAD), lfname, isplayer(lf) ? "" : "s", buf); msg("^%c%s choke%s on %s!", getlfcol(lf, CC_BAD), lfname, isplayer(lf) ? "" : "s", buf);
} }
} else { } else {
if (isplayer(lf)) { if (isplayer(lf)) {
@ -14467,7 +14557,7 @@ void applywalkdam(lifeform_t *lf, int dam, enum DAMTYPE damtype, object_t *o) {
char lfname[BUFLEN]; char lfname[BUFLEN];
char buf2[BUFLEN]; char buf2[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
snprintf(buf2, BUFLEN, "^%d%s %ss %s!", getlfcol(lf, CC_BAD), buf, getattackverb(NULL, NULL, damtype, dam,lf->maxhp), lfname); snprintf(buf2, BUFLEN, "^%c%s %ss %s!", getlfcol(lf, CC_BAD), buf, getattackverb(NULL, NULL, damtype, dam,lf->maxhp), lfname);
msg("%s", buf2); msg("%s", buf2);
} }
} }
@ -16235,7 +16325,7 @@ int modattr(lifeform_t *lf, enum ATTRIB attr, int amt) {
break; break;
} }
} }
msg("^%d%s %s %s!", getlfcol(lf, (amt > 0) ? CC_GOOD : CC_BAD), lfname, verb, adverb); msg("^%c%s %s %s!", getlfcol(lf, (amt > 0) ? CC_GOOD : CC_BAD), lfname, verb, adverb);
more(); more();
} }
return B_FALSE; return B_FALSE;
@ -16323,7 +16413,7 @@ void modhunger(lifeform_t *lf, int amt) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
gethungername(lf, posthlev, buf); gethungername(lf, posthlev, buf);
msg("^%d%s looks %s%c", getlfcol(lf, CC_BAD), lfname, buf, (needexclam) ? '!' : '.'); msg("^%c%s looks %s%c", getlfcol(lf, CC_BAD), lfname, buf, (needexclam) ? '!' : '.');
} }
if ((posthlev >= H_VHUNGRY) && (amt > 0)) { if ((posthlev >= H_VHUNGRY) && (amt > 0)) {
@ -16490,6 +16580,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
int dist; int dist;
int difficulty; int difficulty;
int lbonus; int lbonus;
int nwalls = 0;
flag_t *f; flag_t *f;
if (l == noisemaker) continue; if (l == noisemaker) continue;
@ -16524,7 +16615,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
// skillcheck to hear this // skillcheck to hear this
if ( (isplayer(l) && haslos(l, c)) || // only player can "hear by seeing" if ( (isplayer(l) && haslos(l, c)) || // only player can "hear by seeing"
(canhear(l, c, volume) && (alwayshear || skillcheck(l, SC_LISTEN, difficulty, lbonus)) ) ) { (canhear(l, c, volume, &nwalls) && (alwayshear || skillcheck(l, SC_LISTEN, difficulty, lbonus)) ) ) {
flag_t *f; flag_t *f;
// announce? // announce?
if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) { if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) {
@ -16564,10 +16655,38 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
char textnopunc[BUFLEN]; char textnopunc[BUFLEN];
char punc; char punc;
int dist; int dist;
int muffled = B_FALSE;
char prefix[BUFLEN];
enum SKILLLEVEL slev;
char distbuf[BUFLEN],distbufbad[BUFLEN];
char dirbuf[BUFLEN];
char localtext[BUFLEN];
if (nwalls >= 1) muffled = B_TRUE;
if (muffled) {
char *p;
// "you hear [a xxx]"
// becomes:
// "you hear [a muffled xxx]"
p = strstartswitha(text, prefix);
if (p) {
sprintf(localtext, "%smuffled %s", prefix, p);
} else {
// "you hear [xxx]"
// becomes:
// "you hear muffled [xxx]"
//
sprintf(localtext, "muffled %s", text);
}
} else {
strcpy(localtext, text);
}
//punc = text[strlen(text)-1]; //punc = text[strlen(text)-1];
//strncpy(textnopunc, text, strlen(text)-1); //strncpy(textnopunc, text, strlen(text)-1);
strcpy(textnopunc, text); strcpy(textnopunc, localtext);
punc = textnopunc[strlen(textnopunc)-1]; punc = textnopunc[strlen(textnopunc)-1];
if (punc == '\"') { if (punc == '\"') {
// ie. someone saying something // ie. someone saying something
@ -16580,18 +16699,16 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
// adjust text if you are deaf. // adjust text if you are deaf.
getdisttext(l->cell, c, distbuf, distbufbad, dirbuf);
slev = getskill(l, SK_LISTEN);
// listen skill gives you more info about monsters // listen skill gives you more info about monsters
if (noisemaker) { if (noisemaker) {
enum SKILLLEVEL slev;
char lfname[BUFLEN];
char distbuf[BUFLEN],distbufbad[BUFLEN];
char dirbuf[BUFLEN];
int detectdist = 0; int detectdist = 0;
char lfname[BUFLEN];
real_getlfnamea(noisemaker, lfname, NULL, B_NOSHOWALL, B_CURRACE); real_getlfnamea(noisemaker, lfname, NULL, B_NOSHOWALL, B_CURRACE);
getdisttext(l->cell, c, distbuf, distbufbad, dirbuf);
slev = getskill(l, SK_LISTEN);
detectdist = getlistendetectrange(l); detectdist = getlistendetectrange(l);
// //
// high listen skill lets you know more info. // high listen skill lets you know more info.
@ -16611,7 +16728,11 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
} }
// now announce it. // now announce it.
if (slev >= PR_EXPERT) { if (slev >= PR_EXPERT) {
if (muffled) {
msg("You hear a muffled %s%s to the %s%c", noprefix(lfname), distbuf, dirbuf, punc);
} else {
msg("You hear %s%s to the %s%c", lfname, distbuf, dirbuf, punc); msg("You hear %s%s to the %s%c", lfname, distbuf, dirbuf, punc);
}
rv = B_TRUE; rv = B_TRUE;
} else if (slev >= PR_BEGINNER) { } else if (slev >= PR_BEGINNER) {
msg("You hear %s%s to the %s%c", textnopunc, distbuf, dirbuf, punc); msg("You hear %s%s to the %s%c", textnopunc, distbuf, dirbuf, punc);
@ -16620,13 +16741,18 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
msg("You hear %s%s%c", textnopunc, distbufbad, punc); msg("You hear %s%s%c", textnopunc, distbufbad, punc);
rv = B_TRUE; rv = B_TRUE;
} else { } else {
assert(text); msg("You hear %s", localtext);
msg("You hear %s", text);
rv = B_TRUE; rv = B_TRUE;
} }
} else { } else {
assert(text); assert(text);
msg("You hear %s", text); if (slev >= PR_BEGINNER) {
msg("You hear %s%s to the %s%c", textnopunc, distbuf, dirbuf, punc);
} else if (slev >= PR_NOVICE) {
msg("You hear %s%s%c", textnopunc, distbufbad, punc);
} else {
msg("You hear %s", localtext);
}
rv = B_TRUE; rv = B_TRUE;
} }
// can only hear one 'walk' sound per turn. // can only hear one 'walk' sound per turn.
@ -16666,7 +16792,6 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
if (isplayer(l)) { if (isplayer(l)) {
char wakenoise[BUFLEN]; char wakenoise[BUFLEN];
char *punc; char *punc;
assert(text);
strcpy(wakenoise, text); strcpy(wakenoise, text);
// omit punctuation // omit punctuation
punc = &(wakenoise[strlen(wakenoise)-1]); punc = &(wakenoise[strlen(wakenoise)-1]);
@ -16951,6 +17076,11 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char
pt = findpoisontype(ptype); pt = findpoisontype(ptype);
srcrace = findrace(srcraceid); srcrace = findrace(srcraceid);
// special case - lycanthropy only affects players
if ((pt->id == P_LYCANTHROPY) && !isplayer(lf)) {
return;
}
// are you immune to disease/poison? // are you immune to disease/poison?
psev = pt->severity; psev = pt->severity;
switch (psev) { switch (psev) {
@ -16991,11 +17121,11 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char
// announce - announceflaggain won't be called // announce - announceflaggain won't be called
// since this isn't a new flag. // since this isn't a new flag.
if (isplayer(lf)) { if (isplayer(lf)) {
msg("^%dYou feel more sick.", getlfcol(lf, CC_VBAD)); msg("^%cYou feel more sick.", getlfcol(lf, CC_VBAD));
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%d%s looks even more sick.", getlfcol(lf, CC_VBAD), lfname); msg("^%c%s looks even more sick.", getlfcol(lf, CC_VBAD), lfname);
} }
found = B_TRUE; found = B_TRUE;
@ -17008,6 +17138,7 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char
flag_t *ii; flag_t *ii;
int multiplier = 0; int multiplier = 0;
int tempmult; int tempmult;
if (pt->incubationtime != -1) {
// modify incubation time based on metabolism // modify incubation time based on metabolism
sumflags(lf->flags, F_FASTMETAB, &tempmult, NULL, NULL); sumflags(lf->flags, F_FASTMETAB, &tempmult, NULL, NULL);
multiplier += tempmult; multiplier += tempmult;
@ -17019,8 +17150,10 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char
} else if (multiplier < 0) { } else if (multiplier < 0) {
howlong *= abs(multiplier); howlong *= abs(multiplier);
} }
}
ii = lfhasflagval(lf, F_INCUBATING, ptype, NA, NA, NULL); ii = lfhasflagval(lf, F_INCUBATING, ptype, NA, NA, NULL);
if (ii) { if (ii) {
if (ptype != P_LYCANTHROPY) {
// will happen faster // will happen faster
ii->val[2] /= 2; ii->val[2] /= 2;
if (ii->val[2] < 1) ii->val[2] = 1; if (ii->val[2] < 1) ii->val[2] = 1;
@ -17028,6 +17161,7 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char
ii->known = B_TRUE; ii->known = B_TRUE;
msg("^BYou recognise the increased onset of %s.", pt->name); msg("^BYou recognise the increased onset of %s.", pt->name);
} }
}
} else { } else {
char ftext[BUFLEN]; char ftext[BUFLEN];
sprintf(ftext, "%d^%s", power, fromwhat); sprintf(ftext, "%d^%s", power, fromwhat);
@ -18623,6 +18757,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
race_t *origrace = NULL; race_t *origrace = NULL;
int nretflags; int nretflags;
int reverting = B_FALSE; int reverting = B_FALSE;
int lycanthrope = B_FALSE;
lifeform_t *l; lifeform_t *l;
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
@ -18666,6 +18801,31 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
} }
//} //}
// reverting from initial lycanthrope change?
if (lfhasflagval(lf, F_POISONED, P_LYCANTHROPY, NA, NA, NULL) &&
lfhasflag(lf, F_AICONTROLLED) && !lfhasflag(lf, F_LYCANTHROPE)) {
// add lycanthropy flag
addflag(lf->flags, F_LYCANTHROPE, 4, NA, NA, lf->race->name);
killflagsofid(lf->flags, F_AICONTROLLED);
killflagsofid(lf->flags, F_RAGE);
if (isplayer(lf)) killflagsofid(lf->flags, F_HATESALL);
} else {
flag_t *lyflag;
lyflag = lfhasflag(lf, F_LYCANTHROPE);
if (lyflag && (lyflag->val[0] > 0)) {
// reduce # of auto changes
lyflag->val[0]--;
if (lyflag->val[0] <= 0) {
char cwtext[BUFLEN];
if (isplayer(lf)) {
msg("^%cYou have gained control of your lycanthropy.", getlfcol(lf, CC_GOOD));
}
sprintf(cwtext, "pw:1;race:%s;", lf->race->name);
addtempflag(lf->flags, F_CANWILL, OT_S_SHAPESHIFT, NA, NA, cwtext, FROMLYCANTHROPY);
}
}
}
if ((lf->race->id == R_GASCLOUD) && (origrace->id == R_VAMPIRE)) { if ((lf->race->id == R_GASCLOUD) && (origrace->id == R_VAMPIRE)) {
if (!isplayer(lf)) { if (!isplayer(lf)) {
f = lfhasflagval(lf, F_WANTS, OT_COFFIN, NA, NA, NULL); f = lfhasflagval(lf, F_WANTS, OT_COFFIN, NA, NA, NULL);
@ -18703,19 +18863,39 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
// stop stoning. // stop stoning.
killflagsofid(lf->flags, F_BEINGSTONED); killflagsofid(lf->flags, F_BEINGSTONED);
if (lfhasflag(lf, F_LYCANTHROPE)) {
lycanthrope = B_TRUE;
}
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
// first remove flags from existing race, or temporary ones // first remove flags from existing race, or temporary ones
lf->born = B_FALSE; lf->born = B_FALSE;
for (f = lf->flags->first ; f ; f = nextf) { for (f = lf->flags->first ; f ; f = nextf) {
nextf = f->next; nextf = f->next;
if (frompolymorph && flagretainedduringpoly(f->id)) continue;
if (lycanthrope) {
switch (f->id) {
case F_DTVULN:
case F_MATVULN:
case F_HITCONFER:
case F_HITCONFERVALS:
case F_CANEATRAW:
case F_CARNIVORE:
case F_VEGETARIAN:
case F_FILLPOT:
continue;
break;
default:
break;
}
}
if (f->lifetime == FROMRACE) { if (f->lifetime == FROMRACE) {
killflag(f); killflag(f);
nkilled++; nkilled++;
} else if ((f->lifetime > 0) && (f->id != F_POLYMORPHED)) { } else if ((f->lifetime > 0) && (f->id != F_POLYMORPHED)) {
// kill most temporary flags, with exceptions // kill most temporary flags, with exceptions
switch (f->id) { switch (f->id) {
case F_FLEEFROM:
break;
default: default:
killflag(f); killflag(f);
nkilled++; nkilled++;
@ -18746,7 +18926,8 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
} }
// don't change hostility when polymorphing // don't change hostility when polymorphing
if (frompolymorph) { if (frompolymorph) {
if (f->id == F_HOSTILE) ignorethis = B_TRUE; if (flagretainedduringpoly(f->id)) ignorethis = B_TRUE;
//if (f->id == F_HOSTILE) ignorethis = B_TRUE;
} }
if (!ignorethis) { if (!ignorethis) {
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
@ -19764,7 +19945,7 @@ void startlfturn(lifeform_t *lf) {
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%d%s is suffocating!", getlfcol(lf, CC_VBAD), lfname); msg("^%c%s is suffocating!", getlfcol(lf, CC_VBAD), lfname);
} }
dam = lf->maxhp / 3; dam = lf->maxhp / 3;
limit(&dam, 1, NA); limit(&dam, 1, NA);
@ -19779,7 +19960,7 @@ void startlfturn(lifeform_t *lf) {
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%dThe sunlight burns %s!", getlfcol(lf, CC_BAD), lfname); msg("^%cThe sunlight burns %s!", getlfcol(lf, CC_BAD), lfname);
} }
losehp(lf, roll("6d6"), DT_DIRECT, NULL, "sunlight"); losehp(lf, roll("6d6"), DT_DIRECT, NULL, "sunlight");
if (isdead(lf)) return; if (isdead(lf)) return;
@ -20569,7 +20750,7 @@ void startlfturn(lifeform_t *lf) {
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%d%s%s spine snaps!", getlfcol(lf, CC_VBAD), msg("^%c%s%s spine snaps!", getlfcol(lf, CC_VBAD),
lfname, getpossessive(lfname)); lfname, getpossessive(lfname));
} }
losehp_real(lf, lf->maxhp, DT_DIRECT, NULL, "tetanus", B_FALSE, NULL, B_FALSE, NULL, B_FALSE); losehp_real(lf, lf->maxhp, DT_DIRECT, NULL, "tetanus", B_FALSE, NULL, B_FALSE, NULL, B_FALSE);
@ -20604,7 +20785,7 @@ void startlfturn(lifeform_t *lf) {
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%d%s shivers.", getlfcol(lf, CC_BAD), lfname); msg("^%c%s shivers.", getlfcol(lf, CC_BAD), lfname);
} }
wep = getweapon(lf); wep = getweapon(lf);
if (wep) { if (wep) {
@ -20652,7 +20833,7 @@ void startlfturn(lifeform_t *lf) {
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%d%s %s.", getlfcol(lf, CC_BAD), lfname, rnd(0,1) ? "retches" : "gags"); msg("^%c%s %s.", getlfcol(lf, CC_BAD), lfname, rnd(0,1) ? "retches" : "gags");
} }
taketime(lf,getactspeed(lf)); taketime(lf,getactspeed(lf));
@ -20670,7 +20851,7 @@ void startlfturn(lifeform_t *lf) {
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%d%s melts a little.",getlfcol(lf, CC_BAD), lfname); msg("^%c%s melts a little.",getlfcol(lf, CC_BAD), lfname);
} }
} }
} }
@ -20719,7 +20900,7 @@ void startlfturn(lifeform_t *lf) {
getlfname(lf, lfname); getlfname(lf, lfname);
getobname(bloodamu, obname, 1); getobname(bloodamu, obname, 1);
getobname(o, bname, 1); getobname(o, bname, 1);
msg("^%d%s%s %s sucks up %s!", getlfcol(lf, CC_GOOD), lfname, getpossessive(lfname), noprefix(obname), bname); msg("^%c%s%s %s sucks up %s!", getlfcol(lf, CC_GOOD), lfname, getpossessive(lfname), noprefix(obname), bname);
makeknown(bloodamu->type->id); makeknown(bloodamu->type->id);
} }
} }
@ -20728,6 +20909,21 @@ void startlfturn(lifeform_t *lf) {
continue; continue;
} }
if (o->type->id == OT_HOLYCIRCLE) {
if (isundead(lf) || lfhasflag(lf, F_LYCANTHROPE)) {
char obname[BUFLEN];
getobname(o, obname, 1);
if (isplayer(lf)) {
msg("^%c%s burns you!^n", getlfcol(lf, CC_BAD), obname);
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("^%c%s burns %s!^n", getlfcol(lf, CC_BAD), obname, lfname);
}
losehp(lf, rnd(10,20), DT_HOLY, NULL, "a holy circle");
}
}
/* /*
f = hasflag(o->flags, F_GODSTONE); f = hasflag(o->flags, F_GODSTONE);
if (f && (f->val[2] == B_TRUE)) { if (f && (f->val[2] == B_TRUE)) {
@ -20897,21 +21093,11 @@ void startlfturn(lifeform_t *lf) {
} }
} }
if (f->id == F_INCUBATING) { if ((f->id == F_INCUBATING) && (f->val[1] > 0)) {
f->val[1]--; f->val[1]--;
if (f->val[1] <= 0) { if (f->val[1] <= 0) {
// parse text to get power & whatfrom // note: this functino will kill f
char *p; completeincubation(lf, f);
char buf[BUFLEN];
int power;
enum POISONTYPE ptype;
ptype = f->val[0];
p = readuntil(buf, f->text, '^');
power = atoi(buf);
readuntil(buf, p, '^');
addtempflag(lf->flags, F_POISONED, ptype, power, f->obfrom, buf, f->val[2]);
poisoneffects(lf, ptype, power);
killflag(f);
continue; continue;
} }
} }
@ -21152,9 +21338,9 @@ int steal(lifeform_t *lf, obpile_t *op, enum FLAG wantflag) {
if (op->owner) { if (op->owner) {
getlfname(op->owner, targname); getlfname(op->owner, targname);
if (isplayer(lf)) { if (isplayer(lf)) {
msg("^%dYou steal %s from %s!", getlfcol(op->owner, CC_BAD), obname, targname); msg("^%cYou steal %s from %s!", getlfcol(op->owner, CC_BAD), obname, targname);
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
msg("^%d%s steals %s from %s!", getlfcol(op->owner, CC_BAD), lfname, obname, targname); msg("^%c%s steals %s from %s!", getlfcol(op->owner, CC_BAD), lfname, obname, targname);
} }
} else { } else {
if (isplayer(lf)) { if (isplayer(lf)) {
@ -21204,7 +21390,7 @@ int stone(lifeform_t *lf) {
addflag(lf->flags, F_CORPSETYPE, B_TRUE, NA, NA, statname); addflag(lf->flags, F_CORPSETYPE, B_TRUE, NA, NA, statname);
if (cansee(player, lf)) { if (cansee(player, lf)) {
msg("^%d%s %s to stone!", getlfcol(lf, CC_VBAD), lfname, isplayer(lf) ? "turn" : "turns"); msg("^%c%s %s to stone!", getlfcol(lf, CC_VBAD), lfname, isplayer(lf) ? "turn" : "turns");
} }
setlastdam(lf, "petrification"); setlastdam(lf, "petrification");
lf->hp = 0; lf->hp = 0;
@ -22510,7 +22696,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
if (isimmuneto(lf->flags, DT_FALL, B_FALSE)) { if (isimmuneto(lf->flags, DT_FALL, B_FALSE)) {
msg("%s lands gently on the ground.", lfname); msg("%s lands gently on the ground.", lfname);
} else { } else {
msg("^%d%s slams into the ground!", getlfcol(lf, CC_BAD), lfname); msg("^%c%s slams into the ground!", getlfcol(lf, CC_BAD), lfname);
} }
} }
// how far did you fall? // how far did you fall?
@ -22541,7 +22727,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("^bYou slam into the roof!"); msg("^bYou slam into the roof!");
} else if (cansee(player, lf)){ } else if (cansee(player, lf)){
msg("^%d%s slams into the roof!",getlfcol(lf, CC_BAD), lfname); msg("^%c%s slams into the roof!",getlfcol(lf, CC_BAD), lfname);
} }
// how far did you fall? // how far did you fall?
sumflags(lf->flags, F_FALLDISTANCE, &howfar, NULL, NULL); sumflags(lf->flags, F_FALLDISTANCE, &howfar, NULL, NULL);
@ -23657,7 +23843,7 @@ int wear(lifeform_t *lf, object_t *o) {
} }
} else if (o->type->id == OT_AMU_CHOKING) { } else if (o->type->id == OT_AMU_CHOKING) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("^%d%s starts to constrict around your neck!", getlfcol(lf, CC_VBAD), obname); msg("^%c%s starts to constrict around your neck!", getlfcol(lf, CC_VBAD), obname);
makeknown(o->type->id); makeknown(o->type->id);
if (!needstobreath(lf)) { if (!needstobreath(lf)) {
msg("Luckily, you don't need to breath."); msg("Luckily, you don't need to breath.");

5
lf.h
View File

@ -47,7 +47,7 @@ int canclimb(lifeform_t *lf, enum ERROR *reason);
int candrink(lifeform_t *lf, object_t *o); int candrink(lifeform_t *lf, object_t *o);
int caneat(lifeform_t *lf, object_t *o); int caneat(lifeform_t *lf, object_t *o);
int canhaverandombehaviour(lifeform_t *lf); int canhaverandombehaviour(lifeform_t *lf);
int canhear(lifeform_t *lf, cell_t *c, int volume); int canhear(lifeform_t *lf, cell_t *c, int volume, int *numwalls);
int canlearn(lifeform_t *lf, enum SKILL skid); int canlearn(lifeform_t *lf, enum SKILL skid);
int canmakerecipe(lifeform_t *lf, recipe_t *rec); int canmakerecipe(lifeform_t *lf, recipe_t *rec);
int canopendoors(lifeform_t *lf); int canopendoors(lifeform_t *lf);
@ -75,6 +75,7 @@ int check_rest_ok(lifeform_t *lf);
//void checkxp(enum RACE rid); //void checkxp(enum RACE rid);
lifeform_t *clonelf(lifeform_t *src, cell_t *where); lifeform_t *clonelf(lifeform_t *src, cell_t *where);
float comparelfs(lifeform_t *lf1, lifeform_t *lf2); float comparelfs(lifeform_t *lf1, lifeform_t *lf2);
void completeincubation(lifeform_t *lf, flag_t *incubateflag);
int confuse(lifeform_t *lf, int howlong); int confuse(lifeform_t *lf, int howlong);
void copycorpseflags(flagpile_t *dst, flagpile_t *src); void copycorpseflags(flagpile_t *dst, flagpile_t *src);
int continuedigging(lifeform_t *lf); int continuedigging(lifeform_t *lf);
@ -121,6 +122,7 @@ skill_t *findskill(enum SKILL id);
skill_t *findskillbyname(char *name); skill_t *findskillbyname(char *name);
enum SKILLLEVEL findskilllevbyname(char *name); enum SKILLLEVEL findskilllevbyname(char *name);
subjob_t *findsubjob(enum SUBJOB sjid); subjob_t *findsubjob(enum SUBJOB sjid);
int fixcurses(lifeform_t *lf);
int flee(lifeform_t *lf); int flee(lifeform_t *lf);
void fleefrom(lifeform_t *lf, lifeform_t *enemy, int howlong, int onpurpose); void fleefrom(lifeform_t *lf, lifeform_t *enemy, int howlong, int onpurpose);
int fovlist_contains(int *endx, int *endy, int nendcells, int x, int y); int fovlist_contains(int *endx, int *endy, int nendcells, int x, int y);
@ -255,6 +257,7 @@ race_t *getrandomcorpserace(cell_t *c);
job_t *getrandomjob(int onlyplayerjobs); job_t *getrandomjob(int onlyplayerjobs);
int getrandommonlevel(race_t *r, map_t *m); int getrandommonlevel(race_t *r, map_t *m);
race_t *getrandomrace(cell_t *c, int forcedepth); race_t *getrandomrace(cell_t *c, int forcedepth);
race_t *getrandomracewithflag(enum FLAG fid);
race_t *getreallyrandomrace(enum RACECLASS wantrc); race_t *getreallyrandomrace(enum RACECLASS wantrc);
enum SKILL getrandomskill(void); enum SKILL getrandomskill(void);
object_t *getrestob(lifeform_t *lf); object_t *getrestob(lifeform_t *lf);

2
map.c
View File

@ -7472,7 +7472,7 @@ int isinscanrange(cell_t *c, void **thing, char *desc, glyph_t *glyph) {
int i; int i;
// handle scanner // handle scanner
if (c->lf) { if (c->lf) {
if (areallies(player, c->lf) && !isplayer(c->lf) && canhear(player, c, SV_SHOUT)) { if (areallies(player, c->lf) && !isplayer(c->lf) && canhear(player, c, SV_SHOUT, NULL)) {
// assume that allies will keep in contact with the player, as long // assume that allies will keep in contact with the player, as long
// as they're not asleep // as they're not asleep
if (!lfhasflag(c->lf, F_ASLEEP)) { if (!lfhasflag(c->lf, F_ASLEEP)) {

10
move.c
View File

@ -215,6 +215,12 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
} }
} }
} }
} else if (o->type->id == OT_HOLYCIRCLE) {
if (isundead(lf) || lfhasflag(lf, F_LYCANTHROPE)) {
*error = E_AVOIDOB;
rdata = o;
return B_TRUE;
}
} }
f = hasflag(o->flags, F_PIT); f = hasflag(o->flags, F_PIT);
if (f && (f->val[0] == D_DOWN)) { if (f && (f->val[0] == D_DOWN)) {
@ -955,7 +961,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
} else { // ie door or object } else { // ie door or object
getobname(rdata, thing, 1); getobname(rdata, thing, 1);
} }
if (seen) msg("^%d%s slam%s into %s!^n",getlfcol(lf, CC_BAD), lfname,isplayer(lf) ? "" : "s", thing); if (seen) msg("^%c%s slam%s into %s!^n",getlfcol(lf, CC_BAD), lfname,isplayer(lf) ? "" : "s", thing);
snprintf(buf, BUFLEN, "slamming into %s", thing); snprintf(buf, BUFLEN, "slamming into %s", thing);
// 1d6 dam per cell pushed // 1d6 dam per cell pushed
dam = rolldie(howfar, 6); dam = rolldie(howfar, 6);
@ -2859,7 +2865,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
setfacing(lf, dir); setfacing(lf, dir);
drawscreen(); drawscreen();
if (isplayer(lf)) { if (isplayer(lf) && !lfhasflag(lf, F_AICONTROLLED)) {
addflagifneeded(lf->flags, F_TURNED, B_TRUE, NA, NA, NULL); addflagifneeded(lf->flags, F_TURNED, B_TRUE, NA, NA, NULL);
lf->turncounter++; lf->turncounter++;
if (lf->turncounter >= 5) { if (lf->turncounter >= 5) {

99
nexus.c
View File

@ -774,20 +774,72 @@ void donextturn(map_t *map) {
// do we need to run away from something? // do we need to run away from something?
if (!flee(who)) { if (!flee(who)) {
int donormalmove = B_TRUE; int donormalmove = B_TRUE;
flag_t *f; flag_t *f = NULL,*lyflag = NULL;
// lycanthrope in human form at midnight? // lycanthrope in human form at midnight?
if (gettimephase() == TP_MIDNIGHT) { if (gettimephase() == TP_MIDNIGHT) {
flag_t *f; char changerace[BUFLEN];
f = lfhasflag(who, F_LYCANTHROPE); int willchange = B_FALSE;
if (f && !ispolymorphed(who)) { int willrage = B_FALSE;
//int mintime=20,maxtime=30;
strcpy(changerace, "");
if (!ispolymorphed(who)) {
lyflag = lfhasflag(who, F_LYCANTHROPE);
if (lyflag && (lyflag->val[0] != 0)) {
strcpy(changerace, lyflag->text);
willchange = B_TRUE;
} else {
flag_t *incflag;
incflag = lfhasflagval(who, F_INCUBATING, P_LYCANTHROPY, NA, NA, NULL);
if (incflag) {
char *p;
char *localtext;
char buf[BUFLEN];
// figure out race name from f_incubating flag.
localtext = strdup(incflag->text);
p = readuntil(buf, localtext, '^');
readuntil(buf, p, '^');
strcpy(changerace, buf);
// turn f_incubating into f_poisoned
completeincubation(who, incflag);
willchange = B_TRUE;
free(localtext);
addflag(who->flags, F_AICONTROLLED, B_TRUE, NA, NA, NULL);
if (isplayer(who)) {
addflag(who->flags, F_HATESALL, B_TRUE, NA, NA, NULL);
}
willrage = B_TRUE;
}
}
}
if (willchange) {
race_t *r; race_t *r;
if (isplayer(who)) { if (isplayer(who)) {
msg("You feel a change coming over your body!"); msg("You feel a change coming over your body!");
} }
r = findracebyname(f->text); r = findracebyname(changerace);
polymorphto(who, r->id, rnd(50,100)); //polymorphto(who, r->id, rnd(mintime,maxtime));
polymorphto(who, r->id, PERMENANT);
donormalmove = B_FALSE; donormalmove = B_FALSE;
if (willrage) {
addflag(who->flags, F_RAGE, B_TRUE, NA, NA, NULL);
}
}
} else if (ispolymorphed(who)) {
int autorevert = B_FALSE;
// not midnight. polymorphed uncontrollably?
if (lfhasflagval(who, F_POISONED, P_LYCANTHROPY, NA, NA, NULL) &&
lfhasflag(who, F_AICONTROLLED)) {
autorevert = B_TRUE;
} else if (isplayer(who)) {
flag_t *lyflag;
lyflag = lfhasflag(who, F_LYCANTHROPE);
if (lyflag && (lyflag->val[0] > 0)) {
autorevert = B_TRUE;
}
}
if (autorevert) {
abilityeffects(who, OT_A_POLYREVERT, who->cell, who, NULL);
} }
} }
@ -988,7 +1040,11 @@ void donextturn(map_t *map) {
if (isplayer(who)) { if (isplayer(who)) {
drawcursor(); drawcursor();
// find out what player wants to do // find out what player wants to do
if (lfhasflag(who, F_AICONTROLLED)) {
aiturn(who);
} else {
handleinput(); handleinput();
}
if (who->bartimer) { if (who->bartimer) {
who->bartimer--; who->bartimer--;
if (who->bartimer == 0) { if (who->bartimer == 0) {
@ -1231,6 +1287,14 @@ int init(void) {
return B_FALSE; return B_FALSE;
} }
void inctime(long nunits) {
curtime += (nunits*(TIMECONST));
// don't let it get higher than 23:59
while (curtime >= DAYSECS) {
curtime -= DAYSECS;
}
}
// retcell[0] will be initial location // retcell[0] will be initial location
void calcbresnham(map_t *m, int x1, int y1, int x2, int y2, cell_t **retcell, int *numpixels) { void calcbresnham(map_t *m, int x1, int y1, int x2, int y2, cell_t **retcell, int *numpixels) {
int xinc1,xinc2,yinc1,yinc2,dinc1,dinc2,d; int xinc1,xinc2,yinc1,yinc2,dinc1,dinc2,d;
@ -1719,6 +1783,21 @@ dblog("doing sort...");
} }
*/ */
void setcurtime(int hours, int minutes) {
int h = -1,m = -1,s = -1;
splittime(&h, &m, &s);
while ((h != hours) || (m != minutes)) {
curtime += TIMECONST;
// don't let it get higher than 23:59
while (curtime >= DAYSECS) {
curtime -= DAYSECS;
}
splittime(&h, &m, &s);
}
msg("DEBUG: time fastforwarded to %d:%d",hours, minutes);
}
void timeeffectsworld(map_t *map, int updategametime) { void timeeffectsworld(map_t *map, int updategametime) {
@ -1893,11 +1972,7 @@ void timeeffectsworld(map_t *map, int updategametime) {
if (updategametime) { if (updategametime) {
// inc game time // inc game time
curtime += (firstlftime*(TIMECONST)); inctime(firstlftime);
// don't let it get higher than 23:59
while (curtime >= DAYSECS) {
curtime -= DAYSECS;
}
// inc total gametime passed // inc total gametime passed
gamesecs += firstlftime; gamesecs += firstlftime;
@ -1920,7 +1995,7 @@ void timeeffectsworld(map_t *map, int updategametime) {
char text[BUFLEN]; char text[BUFLEN];
switch (rnd(1,4)) { switch (rnd(1,4)) {
case 1: sprintf(text, "The hour of Glorana's Peace is here."); break; case 1: sprintf(text, "The hour of Glorana's Peace is here."); break;
case 2: sprintf(text, "Mortal, rejoice in Glorana's Peace!"); break; case 2: sprintf(text, "Mortal, rejoice in the hour of Glorana's Peace!"); break;
case 3: sprintf(text, "Now is the time of Glorana's Peace."); break; case 3: sprintf(text, "Now is the time of Glorana's Peace."); break;
case 4: sprintf(text, "Be healed my child - Glorana's Peace is upon you."); break; case 4: sprintf(text, "Be healed my child - Glorana's Peace is upon you."); break;
} }

View File

@ -18,6 +18,7 @@ enum COLOUR getpctcol(float num, float max);
char getpctletter(float num, float max); char getpctletter(float num, float max);
void getrarityrange(int depth, int *min, int *max, int range, int oodok); void getrarityrange(int depth, int *min, int *max, int range, int oodok);
int init(void); int init(void);
void inctime(long nunits);
void calcbresnham(map_t *m, int x1, int y1, int x2, int y2, cell_t **retcell, int *numpixels); void calcbresnham(map_t *m, int x1, int y1, int x2, int y2, cell_t **retcell, int *numpixels);
void initbresnham(int x1, int y1, int x2, int y2, int *xinc1, int *yinc1, int *dinc1, int *xinc2, int *yinc2, int *dinc2, int *numpixels, int *d); void initbresnham(int x1, int y1, int x2, int y2, int *xinc1, int *yinc1, int *dinc1, int *xinc2, int *yinc2, int *dinc2, int *numpixels, int *d);
int isplayerturn(void); int isplayerturn(void);
@ -38,6 +39,7 @@ int roll(char *string);
int rolldie(int ndice, int sides); int rolldie(int ndice, int sides);
int rollhitdice(lifeform_t *lf, int wantmax); int rollhitdice(lifeform_t *lf, int wantmax);
int rollmpdice(lifeform_t *lf, int wantmax); int rollmpdice(lifeform_t *lf, int wantmax);
void setcurtime(int hours, int minutes);
//void sortlf(map_t *map); //void sortlf(map_t *map);
void timeeffectsworld(map_t *map, int updategametime); void timeeffectsworld(map_t *map, int updategametime);
void usage(char *progname); void usage(char *progname);

View File

@ -9121,12 +9121,14 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
int wastech = B_FALSE; int wastech = B_FALSE;
if (!lfhasflag(lf, F_HUMANOID) || !hasbp(lf, BP_HANDS)) { if (!lfhasflag(lf, F_HUMANOID) || !hasbp(lf, BP_HANDS)) {
if (!hasflag(o->flags, F_OPERWITHOUTHANDS)) {
// only humanoids can zap things // only humanoids can zap things
if (isplayer(lf)) { if (isplayer(lf)) {
msg("You lack the manual dexterity to operate this."); msg("You lack the manual dexterity to operate this.");
} }
return B_TRUE; return B_TRUE;
} }
}
if (lfhasflag(lf, F_RAGE)) { if (lfhasflag(lf, F_RAGE)) {
if (isplayer(lf)) { if (isplayer(lf)) {
@ -10915,6 +10917,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
int failed; int failed;
int seenbyplayer; int seenbyplayer;
object_t *o2; object_t *o2;
race_t *r;
flag_t *f; flag_t *f;
if (isplayer(lf)) { if (isplayer(lf)) {
@ -11167,6 +11170,12 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
i = rnd(5,20); i = rnd(5,20);
addtempflag(lf->flags, F_LEVITATING, B_TRUE, NA, NA, NULL, i); addtempflag(lf->flags, F_LEVITATING, B_TRUE, NA, NA, NULL, i);
break; break;
case OT_POT_LYCANTHROPY:
if (isplayer(lf)) msg("Yuck, this tastes like blood!");
// find random lycanthrope type
r = getrandomracewithflag(F_LYCANTHROPE);
poison(lf, PERMENANT, P_LYCANTHROPY, 1, r->name, R_NONE);
break;
case OT_POT_MAGIC: case OT_POT_MAGIC:
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, -10)) { if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, -10)) {
if (isplayer(lf)) { if (isplayer(lf)) {
@ -11285,7 +11294,9 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
} }
losehp(lf, rnd(5,15), DT_HOLY, NULL, "drinking holy water"); losehp(lf, rnd(5,15), DT_HOLY, NULL, "drinking holy water");
} else { } else {
if (isplayer(lf)) msg("Mmm, holy water."); if (isplayer(lf)) msg("A feeling of holiness spreads through your body.");
// cure any curses, and lycanthropy
fixcurses(lf);
} }
break; break;
case B_UNCURSED: case B_UNCURSED:
@ -11882,8 +11893,6 @@ int readsomething(lifeform_t *lf, object_t *o) {
} else if (o->type->id == OT_SCR_REMOVECURSE) { } else if (o->type->id == OT_SCR_REMOVECURSE) {
int seen = B_FALSE; int seen = B_FALSE;
flag_t *retflag[MAXCANDIDATES];
int i,nretflags = 0;
object_t *oo; object_t *oo;
// remove curses! // remove curses!
for (oo = lf->pack->first ; oo ; oo = oo->next) { for (oo = lf->pack->first ; oo ; oo = oo->next) {
@ -11897,16 +11906,9 @@ int readsomething(lifeform_t *lf, object_t *o) {
} }
} }
// fix player curses // fix player curses
getflags(lf->flags, retflag, &nretflags, F_POISONED, F_NONE); if (fixcurses(lf)) {
for (i = 0; i < nretflags; i++) {
poisontype_t *pt;
pt = findpoisontype(retflag[i]->val[0]);
if (pt->severity == PS_CURSE) {
} else {
killflag(retflag[i]);
if (isplayer(lf) || cansee(player, lf)) seen = B_TRUE; if (isplayer(lf) || cansee(player, lf)) seen = B_TRUE;
} }
}
if (seen) { if (seen) {
// id the scroll now // id the scroll now
@ -13792,7 +13794,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
applyarmourdamage(target, o, reduceamt, DT_PROJECTILE, NULL); applyarmourdamage(target, o, reduceamt, DT_PROJECTILE, NULL);
} }
wepeffects(o->flags, target->cell, hasflag(o->flags, F_DAM), dam); wepeffects(o->flags, target->cell, hasflag(o->flags, F_DAM), dam, B_FALSE);
missiledam += ((speed*2)+rnd(1,4)); missiledam += ((speed*2)+rnd(1,4));
@ -13852,7 +13854,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
stuck = B_TRUE; stuck = B_TRUE;
if (cansee(player, target)) { if (cansee(player, target)) {
if (thrower) { if (thrower) {
msg("^%d%s sticks to %s!", getlfcol(thrower, CC_BAD), obname, targetname); msg("^%c%s sticks to %s!", getlfcol(thrower, CC_BAD), obname, targetname);
} else { } else {
msg("%s sticks to %s!", obname, targetname); msg("%s sticks to %s!", obname, targetname);
} }
@ -14381,7 +14383,7 @@ void timeeffectsob(object_t *o) {
if (cansee(player, lf)) { if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%dPowerful winds pummel %s!^n", getlfcol(lf, CC_BAD), lfname); msg("^%cPowerful winds pummel %s!^n", getlfcol(lf, CC_BAD), lfname);
} }
// lfs here take damage // lfs here take damage
if (creator) { if (creator) {

36
shops.c
View File

@ -438,7 +438,8 @@ enum SHOPRETURN shopdonate(lifeform_t *lf, object_t *vm, int starty, char *topte
// validate it // validate it
if (o) { if (o) {
int goldgiven = 0; long goldgiven = 0;
long multi = 0;
flag_t *f; flag_t *f;
// can we remove it? // can we remove it?
if (isequipped(o)) { if (isequipped(o)) {
@ -467,16 +468,27 @@ enum SHOPRETURN shopdonate(lifeform_t *lf, object_t *vm, int starty, char *topte
} else { } else {
object_t *newob; object_t *newob;
char let; char let;
int thisval,pct = 100;
if (vm->contents->first) { if (vm->contents->first) {
let = vm->contents->last->letter + 1; let = vm->contents->last->letter + 1;
} else { } else {
let = 'a'; let = 'a';
} }
thisval = getobvalue(o);
if (!isknown(o)) {
pct -= 50;
}
if (!isidentified(o)) {
pct -= 25;
}
thisval = pctof(pct, thisval);
newob = moveob(o, vm->contents, count); newob = moveob(o, vm->contents, count);
newob->letter = let; newob->letter = let;
(*ndonated)++; (*ndonated)++;
practice(player, SK_SPEECH, 1); practice(player, SK_SPEECH, 1);
goldgiven += getobvalue(o); goldgiven += thisval;
} }
if ((vm->type->id == OT_TEMPLE) && goldgiven) { if ((vm->type->id == OT_TEMPLE) && goldgiven) {
@ -500,9 +512,29 @@ enum SHOPRETURN shopdonate(lifeform_t *lf, object_t *vm, int starty, char *topte
} else { } else {
addflag(vm->flags, F_SHOPDONATED, goldgiven, NA, NA, NULL); addflag(vm->flags, F_SHOPDONATED, goldgiven, NA, NA, NULL);
} }
// remember amount donated, for addition to final score
f = lfhasflagval(lf, F_SCOREBONUS, NA, NA, NA, SCB_DONATIONS);
if (f) {
multi = f->val[1];
goldgiven += f->val[0];
} else {
f = addflag(lf->flags, F_SCOREBONUS, 0, NA, NA, SCB_DONATIONS);
multi = 0;
}
// cope with >= 65535
while (goldgiven > 65535) {
goldgiven -= 65535;
multi++;
}
f->val[0] = goldgiven;
f->val[1] = multi;
} else { } else {
return SR_BACK; return SR_BACK;
} }
angergodmaybe(R_GODTHIEVES, 10, GA_MONEY);
return SR_CONTINUE; return SR_CONTINUE;
} }

85
spell.c
View File

@ -288,6 +288,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} }
// find out where the other end goes... // find out where the other end goes...
user->changinglev = B_TRUE;
c = getstairdestination(stairs, &madenewmap); c = getstairdestination(stairs, &madenewmap);
// show --more-- after we have the destination // show --more-- after we have the destination
@ -295,6 +296,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (!c) { if (!c) {
msg("These stairs don't seem to go anywhere!"); msg("These stairs don't seem to go anywhere!");
user->changinglev = B_FALSE;
return B_TRUE; return B_TRUE;
} }
@ -341,7 +343,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
nposs = 1; nposs = 1;
} }
} else { } else {
// get all lfs within hearing of the other end int nwalls;
// get all lfs within direct hearing (not through walls) of the other end
for (lf = c->map->lf ; lf ; lf = lf->next) { for (lf = c->map->lf ; lf ; lf = lf->next) {
if (lf == user) continue; if (lf == user) continue;
// get movement text // get movement text
@ -350,7 +353,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// overwrite name // overwrite name
real_getlfnamea(lf, thismovetext, NULL, B_NOSHOWALL, B_CURRACE); real_getlfnamea(lf, thismovetext, NULL, B_NOSHOWALL, B_CURRACE);
} }
if (canhear(user, lf->cell, vol)) { if (canhear(user, lf->cell, vol, &nwalls) && (nwalls == 0)) {
// already have this text? // already have this text?
found = B_FALSE; found = B_FALSE;
for (n = 0; n < nposs; n++) { for (n = 0; n < nposs; n++) {
@ -520,6 +523,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} }
} }
} }
user->changinglev = B_FALSE;
// announce // announce
if (nposs) { if (nposs) {
for (n = 0; n < nposs; n++) { for (n = 0; n < nposs; n++) {
@ -1732,8 +1736,11 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} }
} }
// shield gets damaged if (!touch(target, shield)) {
// if the victim touching the shield didn't destroy it, the shield gets damaged
takedamage(shield, roll("1d3"), DT_DIRECT); takedamage(shield, roll("1d3"), DT_DIRECT);
}
} else if (abilid == OT_A_SNATCH) { } else if (abilid == OT_A_SNATCH) {
object_t *o = NULL; object_t *o = NULL;
flag_t *f; flag_t *f;
@ -1795,7 +1802,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
f = lfhasflagval(user, F_NOTIME, OT_A_SNATCH, NA, NA, NULL); f = lfhasflagval(user, F_NOTIME, OT_A_SNATCH, NA, NA, NULL);
if (f) killflag(f); if (f) killflag(f);
} else if (abilid == OT_A_SONICBOLT) { } else if (abilid == OT_A_SONICBOLT) {
int volume; int volume,nwalls;
if (!validatespellcell(user, &targcell,TT_MONSTER, abilid, power, B_FALSE)) return B_TRUE; if (!validatespellcell(user, &targcell,TT_MONSTER, abilid, power, B_FALSE)) return B_TRUE;
target = targcell->lf; target = targcell->lf;
@ -1808,12 +1815,14 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} else { } else {
volume = power; volume = power;
} }
if (target && canhear(target, user->cell, volume)) { if (target && canhear(target, user->cell, volume, &nwalls)) {
if (nwalls == 0) {
if (isplayer(target)) { if (isplayer(target)) {
msg("Pain shoots through your eardrums!"); msg("Pain shoots through your eardrums!");
} }
losehp(target, roll(damstr), DT_SONIC, user, "a bolt of sound"); losehp(target, roll(damstr), DT_SONIC, user, "a bolt of sound");
} }
}
} else if (abilid == OT_A_SPRINT) { } else if (abilid == OT_A_SPRINT) {
flag_t *f; flag_t *f;
f = lfhasflag(user, F_SPRINTING); f = lfhasflag(user, F_SPRINTING);
@ -3277,7 +3286,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
default: default:
break; break;
} }
if (ok && canhear(target, user->cell, 4)) { if (ok && canhear(target, user->cell, 4, NULL)) {
scare(target, user, rnd(5,10), 0); scare(target, user, rnd(5,10), 0);
} }
} }
@ -3484,6 +3493,61 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
addflag(user->flags, F_FAILEDINSPECT, o->type->id, NA, NA, NULL); addflag(user->flags, F_FAILEDINSPECT, o->type->id, NA, NA, NULL);
} }
taketime(user, getactspeed(user)); taketime(user, getactspeed(user));
} else if (abilid == OT_A_IRONFIST) {
char dirch,tname[BUFLEN];
int dam,dir = D_NONE;
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
if (isplayer(user)) msg("You lack the stability to invoke the iron fist manouver while swimming.");
return B_TRUE;
}
if (getweapon(user)) {
if (isplayer(user)) msg("You must be unarmed to invoke the iron fist.");
return B_TRUE;
}
// ask for direction
if (!targcell) {
dirch = askchar("Iron fist in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
if (dirch == '.') {
// yourself!
targcell = user->cell;
} else {
dir = chartodir(dirch);
if (dir == D_NONE) {
if (isplayer(user)) msg("Cancelled.");
return B_TRUE ;
} else {
targcell = getcellindir(user->cell, dir);
}
}
}
target = targcell->lf;
if (!target) {
if (isplayer(user)) msg("There is nobody there to attack!");
return B_TRUE;
}
getlfname(target, tname);
if (isplayer(user)) {
msg("^%cYou strike %s with THE IRON FIST!",getlfcol(user, CC_GOOD),tname);
} else if (cansee(player, user)) {
msg("^%c%s strikes %s with THE IRON FIST!",getlfcol(user, CC_GOOD),username, tname);
}
// convert all remaining stamina into damage.
dam = getstamina(user);
setstamina(user, 0);
sprintf(damstr, "%s%s invocation of the iron fist",username,getpossessive(username));
losehp(target, dam, DT_DIRECT, user, damstr);
if (dir != D_NONE) {
// knockback too
knockback(target, dir, dam, user, 0, B_TRUE);
}
} }
// expire ability // expire ability
@ -5553,7 +5617,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// all in range must pass a magic resistance check or die // all in range must pass a magic resistance check or die
for (target = caster->cell->map->lf ; target ; target = target->next) { for (target = caster->cell->map->lf ; target ; target = target->next) {
if (target != caster) { if (target != caster) {
if (canhear(target, caster->cell, SV_TALK)) { int nwalls;
if (canhear(target, caster->cell, SV_TALK, &nwalls)) {
if (nwalls == 0) {
if (spellresisted(target, caster, spellid, power, seenbyplayer, B_TRUE)) { if (spellresisted(target, caster, spellid, power, seenbyplayer, B_TRUE)) {
} else { } else {
losehp(target, target->hp, DT_SONIC, caster, "a banshee's wail"); losehp(target, target->hp, DT_SONIC, caster, "a banshee's wail");
@ -5561,6 +5627,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} }
} }
}
} else if (spellid == OT_S_DETECTAURA) { } else if (spellid == OT_S_DETECTAURA) {
if (isplayer(caster)) { if (isplayer(caster)) {
object_t *o; object_t *o;
@ -11918,6 +11985,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
summoner = caster; summoner = caster;
} }
if (!isplayer(caster)) {
friendly = B_TRUE;
}
ngot = summonlfs(caster, caster->cell, wantrace, wantrc, wantsize, AL_NONE, nwant, lifetime, friendly); ngot = summonlfs(caster, caster->cell, wantrace, wantrc, wantsize, AL_NONE, nwant, lifetime, friendly);
if (!ngot) { if (!ngot) {
fizzle(caster); fizzle(caster);

24
text.c
View File

@ -1086,7 +1086,7 @@ char *getflagsourcetext(flag_t *f) {
int gethitconferlifetime(char *text, int *min, int *max) { int gethitconferlifetime(char *text, int *min, int *max) {
int howlong; int howlong;
int localmin = -1,localmax = -1; int localmin = -1,localmax = -1;
if (text) { if (text && strlen(text)) {
char loctext[BUFLEN]; char loctext[BUFLEN];
char *word, *dummy; char *word, *dummy;
strcpy(loctext,text); strcpy(loctext,text);
@ -2318,6 +2318,28 @@ char *strstarts(char *a, char *prefix) {
return NULL; return NULL;
} }
// if string starts with 'a ', 'an ' or 'the ', then return the position after it,
// and write the prefix into 'prefix'.
// otherwise return null.
//
char *strstartswitha(char *text, char *retprefix) {
char *prefix[] = {
"the ",
"an ",
"a "
};
int nprefixes = 3,i;
for (i = 0; i < nprefixes; i++) {
if (strstarts(text, prefix[i])) {
if (retprefix) {
strcpy(retprefix, prefix[i]);
}
return text + strlen(prefix[i]);
}
}
return NULL;
}
int strlen_without_colours(char *buf) { int strlen_without_colours(char *buf) {
char *p; char *p;
int len = 0; int len = 0;

1
text.h
View File

@ -70,6 +70,7 @@ char *strends(char *a, char *suffix);
char *strcasestarts(char *a, char *prefix); char *strcasestarts(char *a, char *prefix);
material_t *strmatchesmaterial(char *p); material_t *strmatchesmaterial(char *p);
char *strstarts(char *a, char *prefix); char *strstarts(char *a, char *prefix);
char *strstartswitha(char *text, char *retprefix);
int strlen_without_colours(char *buf); int strlen_without_colours(char *buf);
int strpixmatch(char *haystack, char *needle); int strpixmatch(char *haystack, char *needle);
int texttodice(char *text, int *ndice, int *nsides, int *bonus); int texttodice(char *text, int *ndice, int *nsides, int *bonus);