- [+] fixed CRASH when energy blade vanishes
- [+] gods of opposing alignments should never make offers. - [+] new armour flag: - [+] f_underclothing - [+] getequippedob() - get the outer one. - [+] if you have f_underclothing, can wear other armour on top of it. - [+] can't remove underclothes without removing outer first. - [+] TEST with cotton shirt - [+] make sure autoequip handles undercltohing - [+] fix other objects - [+] adjust ']' output - [+] make armour help against some magical damage too - [+] move armour check and reduction into losehpeffects(). - [+] pass damreducedbyarmour to losehpeffects - [+] psionic spells: - [+] dampen missiles - lots of extra evasion vs missiles only * [+] soul link (l4, share damage) - [+] mind sheidl (l4, like the amulet) - [+] delay death (l5, don't die if hp <= 0 and this spell is active) - [+] remote ko (l6) - [+] Silence spell / effect - air. - [+] f_silenced. - [+] announce in io.c - [+] prevents spellcasting - [+] prevents docomms() - [+] prevents reading scrolls - [+] prevents speech-based abilities like warcry and sonic bolt - [+] say() will fail - [+] sayphrase() wil fail - [+] test the spell....... - [+] CRASH when adjusting glyph on edge of map - [+] non-humanoids can't climb without climb skill. - [+] player sohuld be able to swap with unconscious/asleep lfs <= same size - [+] too easy to knock things unconscious??? bug. fixed. - [+] reusable cells being set to empty! think this was a vault definition problem. - [+] demon chameleon / deech - [+] low-level mosnter which can hide
This commit is contained in:
parent
38a788ca5f
commit
d7f6991a40
15
ai.c
15
ai.c
|
@ -1763,7 +1763,7 @@ int ai_inventory_mgt(lifeform_t *lf, int *canattack) {
|
|||
// is it red hot?
|
||||
if (curarm && hasflag(curarm->flags, F_HOT) && !isimmuneto(lf->flags, DT_FIRE, B_FALSE)) {
|
||||
if (db) dblog("%s o O { wearing a red-hot item. will try to remove it. } ", lf->race->name);
|
||||
if (cantakeoff(lf, curarm)) {
|
||||
if (cantakeoff(lf, curarm, NULL)) {
|
||||
if (!takeoff(lf, curarm)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -2606,6 +2606,11 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_SILENCED)) {
|
||||
if (db) dblog(".oO { can't cast spells, i am silenced }");
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
ot = findot(spellid);
|
||||
if (ot) {
|
||||
flag_t *f;
|
||||
|
@ -3151,6 +3156,9 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
if ((ot->id == OT_S_SMITEEVIL) && (getalignment(victim) != AL_EVIL)) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_A_SONICBOLT) && lfhasflag(lf, F_SILENCED)) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if (ot->id == OT_S_SPIKEVOLLEY) {
|
||||
if ((lf->race->id == R_MANTICORE) && lfhasflagval(lf, F_INJURY, IJ_TAILBROKEN, NA, NA, NULL)) {
|
||||
specificcheckok = B_FALSE;
|
||||
|
@ -3219,6 +3227,9 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
specificcheckok = B_FALSE;
|
||||
}
|
||||
}
|
||||
if ((ot->id == OT_A_WARCRY) && lfhasflag(lf, F_SILENCED)) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
|
||||
if ((ot->id == OT_S_WARPWOOD)) {
|
||||
specificcheckok = B_FALSE;
|
||||
|
@ -3661,7 +3672,7 @@ int useitemwithflag(lifeform_t *lf, enum FLAG whichflag) {
|
|||
quaff(lf, o);
|
||||
return B_FALSE;
|
||||
}
|
||||
} else if (o->type->obclass->id == OC_SCROLL) {
|
||||
} else if ((o->type->obclass->id == OC_SCROLL) && !lfhasflag(lf, F_SILENCED)) {
|
||||
if (!readsomething(lf, o)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
|
117
attack.c
117
attack.c
|
@ -41,8 +41,8 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty
|
|||
// special case - missiles always hit flak jacket
|
||||
if (damtype == DT_PROJECTILE) {
|
||||
object_t *o;
|
||||
o = getequippedob(lf->pack, BP_BODY);
|
||||
if (o && (o->type->id == OT_FLAKJACKET)) {
|
||||
o = hasequippedobid(lf->pack, OT_FLAKJACKET);
|
||||
if (o) {
|
||||
armour = o;
|
||||
}
|
||||
}
|
||||
|
@ -1056,7 +1056,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
if (critpos == BP_NONE) {
|
||||
strcpy(victimbpname, victimname);
|
||||
} else {
|
||||
armour = getequippedob(victim->pack, critpos);
|
||||
armour = getouterequippedob(victim, critpos);
|
||||
if (armour) {
|
||||
char armname[BUFLEN];
|
||||
real_getobname(armour, armname, 1, B_NOPREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOUSED, B_NOSHOWALL);
|
||||
|
@ -1152,7 +1152,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
dam[0] = getdamroll(wep, victim, damflag);
|
||||
if (isunarmed) {
|
||||
object_t *gloves;
|
||||
gloves = getequippedob(lf->pack, BP_HANDS);
|
||||
gloves = getouterequippedob(lf, BP_HANDS);
|
||||
if (gloves && hasflag(gloves->flags, F_HARDNESS)) {
|
||||
dam[0]++;
|
||||
}
|
||||
|
@ -1318,12 +1318,13 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
// armour doesn't reduce damage for backstabs or critical hits.
|
||||
// BUT in the case of a critical hit, the armour might get
|
||||
// damaged during the call to criticalhit() later on.
|
||||
if ((dam[i] > 0) && !backstab && !critical && ismeleedam(damtype[i])) {
|
||||
// modify for defender's armour
|
||||
// first figure out how much to reduce the damage by.
|
||||
damreducedbyarmour = getarmourdamreduction(victim, wep, dam[i], damtype[i]);
|
||||
// now actually reduce the damage amount
|
||||
applyarmourdamreduction(victim, wep, damreducedbyarmour, &dam[i], damtype[i]);
|
||||
|
||||
//
|
||||
// normally armour would be handled by losehp() & losehpeffects(), but
|
||||
// in this case we need to know whether the armour was hit beforehand,
|
||||
// in order to construct the "you hit xxx" string.
|
||||
if ((dam[i] > 0) && !backstab && !critical) {
|
||||
damreducedbyarmour = handlearmour(victim, wep, &dam[i], damtype[i]);
|
||||
}
|
||||
|
||||
// if damage has been reduced zero, it's not a critical hit anymore.
|
||||
|
@ -1436,7 +1437,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
damreducedbyarmour = 0;
|
||||
} else if (lfhasflag(lf, F_QUIVERINGPALM)) {
|
||||
// victim explodes!
|
||||
losehp_real(victim, victim->hp, DT_EXPLOSIVE, lf, "a quivering palm strike", B_FALSE, NULL, B_FALSE, NULL, B_FALSE, BP_NONE);
|
||||
losehp_real(victim, victim->hp, DT_EXPLOSIVE, lf, "a quivering palm strike", B_FALSE, NULL, B_FALSE, NULL, B_FALSE, BP_NONE, B_NOCRIT);
|
||||
damreducedbyarmour = 0;
|
||||
} else {
|
||||
// actually deal the melee damage!
|
||||
|
@ -1478,7 +1479,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
|
||||
// don't adjust damage for resistences - we've already done that
|
||||
losehp_real(victim, dam[i], damtype[i], lf, buf, B_NODAMADJUST, wep, B_NORETALIATE,
|
||||
&waskod, B_NODAMEFFECTS, critpos);
|
||||
&waskod, B_NODAMEFFECTS, critpos, critical);
|
||||
}
|
||||
// was it fatal ? override previously calculated value.
|
||||
if ((victim->hp <= 0) && !waskod) {
|
||||
|
@ -1557,40 +1558,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
}
|
||||
}
|
||||
|
||||
// now magic armour will pulse and maybe vanish.
|
||||
if (magicarm) {
|
||||
int damprevented;
|
||||
// prevent all damage if possible
|
||||
damprevented = dam[i];
|
||||
magicarm->val[0] -= damprevented;
|
||||
if (magicarm->val[0] <= 0) {
|
||||
// did magic armour come from a spell?
|
||||
if (magicarm->lifetime == FROMSPELL) {
|
||||
flag_t *spellflag;
|
||||
spellflag = hasactivespell(victim, magicarm->obfrom);
|
||||
if (spellflag) {
|
||||
killflag(spellflag);
|
||||
}
|
||||
}
|
||||
// magic armour vanishes now.
|
||||
killflag(magicarm);
|
||||
} else {
|
||||
if (cansee(player, victim)) {
|
||||
msg("^%d%s%s %s pulses!^n",
|
||||
CC_GOOD,
|
||||
victimname, getpossessive(victimname),
|
||||
magicarm->text);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// victim's armour loses hp. note that it loses the full
|
||||
// amount of damage dealt, not just what it reduced.
|
||||
if (damreducedbyarmour && !critical) {
|
||||
applyarmourdamage(victim, wep, dam[i] + damreducedbyarmour, damtype[i], lf);
|
||||
// train armour
|
||||
practice(victim, SK_ARMOUR, 1);
|
||||
}
|
||||
}
|
||||
/// ... used to apply armour damage here...
|
||||
|
||||
// make noise
|
||||
// UNLESS this fighting involved the player.
|
||||
|
@ -1606,8 +1574,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
}
|
||||
|
||||
// now handle the extra hp loss effects which we postponed above.
|
||||
losehpeffects(victim, dam[i], damtype[i], lf, wep, B_NORETALIATE, waskod, &waskod, prebleed,
|
||||
BP_NONE);
|
||||
losehpeffects(victim, dam[i], damtype[i], lf, wep, B_NORETALIATE, waskod,
|
||||
&waskod, prebleed, BP_NONE, damreducedbyarmour, critical);
|
||||
|
||||
if (fatal || waskod || dodged || stopnow) break; // stop now, don't process further damtypes!
|
||||
} // end foreach damtype
|
||||
|
@ -1722,7 +1690,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
attackername);
|
||||
}
|
||||
snprintf(damstring, BUFLEN, "%s%s %s", victimname, getpossessive(victimname), noprefix(obname));
|
||||
losehp_real(lf, rdam, f->val[0], victim, damstring, B_TRUE, NULL, B_TRUE, NULL, B_TRUE, critpos);
|
||||
losehp_real(lf, rdam, f->val[0], victim, damstring, B_TRUE, NULL, B_TRUE, NULL, B_TRUE, critpos, critical);
|
||||
free(loctext);
|
||||
}
|
||||
}
|
||||
|
@ -1975,7 +1943,7 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
|
||||
if ((i == 0) && (wep->type->id == OT_FISTS) && hasflag(o->flags, F_HARDNESS)) {
|
||||
object_t *gloves;
|
||||
gloves = getequippedob(lf->pack, BP_HANDS);
|
||||
gloves = getouterequippedob(lf, BP_HANDS);
|
||||
if (gloves && hasflag(gloves->flags, F_HARDNESS)) {
|
||||
// ok
|
||||
} else if ((o->material->id == MT_WOOD) && (getskill(lf, SK_UNARMED) >= PR_ADEPT)) {
|
||||
|
@ -2174,7 +2142,7 @@ int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag) {
|
|||
|
||||
if ((i == 0) && (wep->type->id == OT_FISTS) && hasflag(c->type->material->flags, F_HARDNESS)) {
|
||||
object_t *gloves;
|
||||
gloves = getequippedob(lf->pack, BP_HANDS);
|
||||
gloves = getouterequippedob(lf, BP_HANDS);
|
||||
if (gloves && hasflag(gloves->flags, F_HARDNESS)) {
|
||||
// ok
|
||||
} else if ((c->type->material->id == MT_WOOD) && (getskill(lf, SK_UNARMED) >= PR_ADEPT)) {
|
||||
|
@ -2563,12 +2531,10 @@ int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE d
|
|||
int ar,min,max;
|
||||
//int pctrange;
|
||||
object_t *o;
|
||||
flag_t *pierce = NULL;
|
||||
|
||||
if (hasflag(wep->flags, F_ARMOURIGNORE)) {
|
||||
reduceamt = 0;
|
||||
if (wep && hasflag(wep->flags, F_ARMOURIGNORE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ar = getarmourrating(lf, NULL, NULL, NULL, NULL);
|
||||
|
||||
// between 25% and 75% of AR.
|
||||
|
@ -2582,22 +2548,25 @@ int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE d
|
|||
|
||||
// special case
|
||||
if (damtype == DT_PROJECTILE) {
|
||||
o = getequippedob(lf->pack, BP_BODY);
|
||||
if (o && (o->type->id == OT_FLAKJACKET)) {
|
||||
o = hasequippedobid(lf->pack, OT_FLAKJACKET);
|
||||
if (o) {
|
||||
// stop ALL missile damage
|
||||
reduceamt = dam;
|
||||
}
|
||||
}
|
||||
|
||||
// and if weapon is armour piercing, you always take at least its
|
||||
// armourpiercing valut.
|
||||
pierce = hasflag(wep->flags, F_ARMOURPIERCE);
|
||||
if (pierce) {
|
||||
if (pierce->val[0] < 0) reduceamt = 0;
|
||||
else reduceamt -= pierce->val[0];
|
||||
if (wep && reduceamt) {
|
||||
flag_t *pierce = NULL;
|
||||
// and if weapon is armour piercing, you always take at least its
|
||||
// armourpiercing valut.
|
||||
pierce = hasflag(wep->flags, F_ARMOURPIERCE);
|
||||
if (pierce) {
|
||||
if (pierce->val[0] < 0) reduceamt = 0;
|
||||
else reduceamt -= pierce->val[0];
|
||||
}
|
||||
}
|
||||
limit(&reduceamt, 0, dam);
|
||||
|
||||
if (reduceamt < 0) reduceamt = 0;
|
||||
return reduceamt;
|
||||
}
|
||||
|
||||
|
@ -2934,6 +2903,26 @@ int getstrdammod(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
|
||||
int armourcanstopdam(enum DAMTYPE damtype) {
|
||||
switch (damtype) {
|
||||
case DT_PIERCE:
|
||||
case DT_SLASH:
|
||||
case DT_BASH:
|
||||
case DT_BITE:
|
||||
case DT_CHOP:
|
||||
case DT_PROJECTILE:
|
||||
case DT_UNARMED:
|
||||
case DT_ACID:
|
||||
case DT_EXPLOSIVE:
|
||||
case DT_MAGIC:
|
||||
case DT_CRUSH:
|
||||
return B_TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// ie. caused by hitting something with a melee weapon
|
||||
int ismeleedam(enum DAMTYPE damtype) {
|
||||
switch (damtype) {
|
||||
|
|
1
attack.h
1
attack.h
|
@ -26,6 +26,7 @@ int getdamroll(object_t *o, lifeform_t *victim, flag_t *damflag);
|
|||
//int getunarmeddamroll(flag_t *f);
|
||||
int getstrdammod(lifeform_t *lf);
|
||||
//obpile_t *getunarmedweapon(lifeform_t *lf, flag_t **uflag);
|
||||
int armourcanstopdam(enum DAMTYPE damtype);
|
||||
int iskineticdam(enum DAMTYPE damtype);
|
||||
int ismeleedam(enum DAMTYPE damtype);
|
||||
int isphysicaldam(enum DAMTYPE damtype);
|
||||
|
|
89
data.c
89
data.c
|
@ -4365,6 +4365,13 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_VARPOWER, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
||||
addot(OT_S_SILENCE, "silence", "Prevents vibration of air molecules around the target's mouth, preventing them from uttering a sound.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the silence will last.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
||||
addot(OT_S_SLOW, "slowness", "Causes the air around the target to thicken to a water-like consistency, greatly decreasing their speed.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the slowness will last.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
|
@ -5162,6 +5169,9 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
||||
addot(OT_S_STUN, "stun", "Stuns the target, preventing them from taking agressive action for a few seconds.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power I-IV, target is stunned for 2 turns.");
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power V-IX, target is stunned for 3 turns.");
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power X, target is stunned for 4 turns.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||
|
@ -5233,6 +5243,12 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_SLOWMISSILES, "dampen missiles", "Creates a weak wall of outward psionic force around you, slowing down incoming projectiles and making them easier to dodge.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL);
|
||||
// l3
|
||||
addot(OT_S_ANTICIPATE, "anticipate action", "Allows the caster to automatically dodge the target's attacks.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power detemines the number of attacks dodged.");
|
||||
|
@ -5267,7 +5283,7 @@ void initobjects(void) {
|
|||
addot(OT_S_BAFFLE, "baffle", "Confuses the target, causing them to lose control of their movement.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The target will be confused for ^bpower^n*4 turns.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
|
@ -5305,20 +5321,51 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
||||
addot(OT_S_SOULLINK, "soul link", "Creates a psychic bond between two creatures. As long as the bond holds, damage dealt to either creature will be felt by the other.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power I, you can only link creatures to yourself.");
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power III, you can form a link between two other creatures.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_STASIS, "stasis", "Freezes time inside your body, preventing many effects such as poison, hunger, and even breathing.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Note that health regeneration is also prevented while in stasis.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
// l5
|
||||
addot(OT_S_CHARM, "charm", "Causes another lifeform to temporary become friendly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines resistability and duration.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_MINDSHIELD, "mind shield", "Erects an impenetrable mental shield around the caster's mind, rendering them immune to all psionic abilities (but also unable to use them).", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
||||
// l5
|
||||
addot(OT_S_DELAYDEATH, "delay death", "This power will allow its user to defy death itself, remaining alive even after their HP drops to zero.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "WARNING: losing concentration before damage is healed will result in instant death.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
||||
// l6
|
||||
addot(OT_S_REMOTEKO, "remote ko", "Disable the conscious part of a creature's mind, instantly knocking it unconscious.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
///////////////////
|
||||
// summoning
|
||||
///////////////////
|
||||
|
@ -7483,7 +7530,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SHRINKSTO, OT_STICK, VT_OB, NA, NULL);
|
||||
|
||||
addot(OT_BARRICADE, "barricade", "A short barricade constructed of metal. Looks like you might able to climb over it.", MT_METAL, 200, OC_DFEATURE, SZ_HUMAN);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_RARE, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_METAL, '\\', NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
|
@ -7866,6 +7913,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GOESON, BP_HANDS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ARMOURRATING, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_UNDERCLOTHING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 0, 5, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_COLD, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
|
||||
|
@ -7892,6 +7940,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL);
|
||||
addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_UNDERCLOTHING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_AGI, 15, NA, NULL);
|
||||
|
@ -7905,6 +7954,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
|
||||
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ARMOURRATING, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_UNDERCLOTHING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_FIRE, NA, NULL);
|
||||
addflag(lastot->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 40, 40, NA, NULL);
|
||||
|
@ -8003,6 +8053,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL);
|
||||
addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_UNDERCLOTHING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_AGI, 15, NA, NULL);
|
||||
|
@ -12065,7 +12116,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_EATCONFER, F_MUTABLE, B_TRUE, NA, "100");
|
||||
|
||||
addrace(R_CENTAUR, "centaur", 500, 'u', C_BROWN, MT_FLESH, RC_ANIMAL, "Centaurs look like horses with their neck upwards replaced by a human torso and arms.");
|
||||
addrace(R_CENTAUR, "centaur", 500, 'u', C_FLESH, MT_FLESH, RC_ANIMAL, "Centaurs look like horses with their neck upwards replaced by a human torso and arms.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
addbodypart(lastrace, BP_TAIL, NULL);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL);
|
||||
|
@ -18797,6 +18848,34 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming barbed whip");
|
||||
addflag(lastrace->flags, F_RESISTMAG, 10, NA, NA, NULL);
|
||||
|
||||
addrace(R_DEECH, "deech", 20, ':', C_MAGENTA, MT_FLESH, RC_DEMON, "The name deech is short for 'Demon Chameleon'. These minor demonic reptiles can blend into their surroundings, becoming all but invisible to their prey.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
addbodypart(lastrace, BP_TAIL, NULL);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_RARE, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_RARE, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 2, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_RANDOM, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_RANDOM, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "hisses^a hiss");
|
||||
addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_HIDE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTHIDDENPCT, 100, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_STEALTH, PR_EXPERT, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addrace(R_DRETCH, "dretch", 30, '&', C_BROWN, MT_FLESH, RC_DEMON, "An ape-like creature with extended forearms ending in clawed hands. They stand about 4 feet tall and weigh 60 pounds.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
|
@ -15,6 +15,7 @@ d:cell:dirt wall
|
|||
.:cell:dirt
|
||||
O:exit
|
||||
R:reusable
|
||||
R:cell:dirt wall
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
|
@ -28,6 +28,7 @@ C:ob:ornate chest
|
|||
X:ob:hut's doorway
|
||||
w:ob:great random weapon
|
||||
r:reusable
|
||||
r:cell:brick wall
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
|
@ -15,6 +15,7 @@ O:ob:boulder
|
|||
O:exit
|
||||
B:mon:grizzly bear
|
||||
r:reusable
|
||||
r:cell:dirt wall
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
|
@ -14,6 +14,7 @@ rrr######rr
|
|||
O:ob:boulder
|
||||
O:exit
|
||||
r:reusable
|
||||
r:cell:SOLID
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
|
@ -27,6 +27,7 @@ _:ob:pentagram
|
|||
_:ob:ancient stone key
|
||||
C:ob:ornate chest
|
||||
r:reusable
|
||||
r:cell:metal wall
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
|
@ -29,6 +29,7 @@ _:ob:cursed excellent weapon
|
|||
_:ob:ancient stone key
|
||||
C:ob:ornate chest
|
||||
r:reusable
|
||||
r:cell:metal wall
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
|
@ -16,6 +16,7 @@ rr###+###rr
|
|||
+:ob:wooden door
|
||||
+:exit
|
||||
r:reusable
|
||||
r:cell:SOLID
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
|
@ -16,6 +16,7 @@ r##..#..##r
|
|||
O:ob:large fire:50
|
||||
X:exit
|
||||
r:reusable
|
||||
r:cell:SOLID
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
|
@ -19,6 +19,7 @@ f:ob:immutable large fire
|
|||
c:ob:untrapped ornate chest
|
||||
d:ob:secret door:15:cell:SOLID
|
||||
r:reusable
|
||||
r:cell:SOLID
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
|
@ -15,6 +15,7 @@ r#ggggg#r
|
|||
g:cell:glass wall
|
||||
w:ob:very deep water:100
|
||||
r:reusable
|
||||
r:cell:SOLID
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
|
@ -14,6 +14,7 @@ rr##+##rr
|
|||
+:ob:wooden door
|
||||
+:exit
|
||||
r:reusable
|
||||
r:cell:SOLID
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
|
@ -14,6 +14,7 @@ _:ob:barricade
|
|||
m:mon:humanoid with firearm
|
||||
X:exit
|
||||
r:reusable
|
||||
r:cell:SOLID
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
|
@ -13,6 +13,7 @@ r#####r
|
|||
p:ob:playerstart
|
||||
x:exit
|
||||
r:reusable
|
||||
r:cell:SOLID
|
||||
@end
|
||||
@flags
|
||||
goesin:dungeon
|
||||
|
|
|
@ -15,6 +15,7 @@ rrr###
|
|||
p:ob:playerstart
|
||||
x:exit
|
||||
r:reusable
|
||||
r:cell:SOLID
|
||||
@end
|
||||
@flags
|
||||
goesin:dungeon
|
||||
|
|
|
@ -13,6 +13,7 @@ r##x##r
|
|||
#:cell:SOLID
|
||||
x:exit
|
||||
r:reusable
|
||||
r:cell:SOLID
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
|
@ -10,6 +10,7 @@ r#+#r
|
|||
@legend
|
||||
#:cell:wyrmwood wall
|
||||
r:reusable
|
||||
r:cell:wyrmwood wall
|
||||
+:exit
|
||||
+:ob:wooden door
|
||||
h:cell:tiled floor
|
||||
|
|
|
@ -10,6 +10,7 @@ r#########r
|
|||
#:cell:SOLID
|
||||
X:exit
|
||||
r:reusable
|
||||
r:cell:SOLID
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
20
defs.h
20
defs.h
|
@ -109,6 +109,9 @@
|
|||
#define B_MAYBE (-2)
|
||||
#define B_ONEOF (-3)
|
||||
|
||||
#define B_FROMCRIT (-1)
|
||||
#define B_NOCRIT (0)
|
||||
|
||||
#define B_BLINDABLE (-1)
|
||||
|
||||
#define B_ALLOWEXTRA (-1)
|
||||
|
@ -259,6 +262,7 @@
|
|||
|
||||
// must be >= max # of spells/abilities AND
|
||||
// >= max # of cells on the map
|
||||
// >= MAXFLAGS
|
||||
#define MAXCANDIDATES 2048
|
||||
|
||||
#define MAXCHOICES 400
|
||||
|
@ -1493,6 +1497,7 @@ enum RACE {
|
|||
R_STIRGE,
|
||||
// demons
|
||||
R_BALROG,
|
||||
R_DEECH,
|
||||
R_DRETCH,
|
||||
R_GRIDDLER,
|
||||
R_LURKINGHORROR,
|
||||
|
@ -1996,6 +2001,7 @@ enum OBTYPE {
|
|||
OT_S_GRAVBOOST,
|
||||
OT_S_HASTE,
|
||||
OT_S_LEVITATION,
|
||||
OT_S_SILENCE,
|
||||
OT_S_SLOW,
|
||||
OT_S_TRUESTRIKE,
|
||||
OT_S_WHATGOESUP,
|
||||
|
@ -2019,6 +2025,7 @@ enum OBTYPE {
|
|||
OT_S_CHARM,
|
||||
OT_S_CHIBOLT,
|
||||
OT_S_CHISTRIKE,
|
||||
OT_S_DELAYDEATH,
|
||||
OT_S_DISORIENT,
|
||||
OT_S_HUNGER,
|
||||
OT_S_LETHARGY,
|
||||
|
@ -2026,6 +2033,7 @@ enum OBTYPE {
|
|||
OT_S_KNOWWEAKNESS,
|
||||
OT_S_MFEEDBACK,
|
||||
OT_S_MINDSCAN,
|
||||
OT_S_MINDSHIELD,
|
||||
OT_S_MINDWHIP,
|
||||
OT_S_MIRRORIMAGE,
|
||||
OT_S_PACIFY,
|
||||
|
@ -2033,8 +2041,11 @@ enum OBTYPE {
|
|||
OT_S_PSIBLAST,
|
||||
OT_S_PSYARMOUR,
|
||||
OT_S_PSYSHOVE,
|
||||
OT_S_REMOTEKO,
|
||||
OT_S_SLEEP,
|
||||
OT_S_SLEEPMASS,
|
||||
OT_S_SLOWMISSILES,
|
||||
OT_S_SOULLINK,
|
||||
OT_S_STASIS,
|
||||
OT_S_STUN,
|
||||
OT_S_TELEKINESIS,
|
||||
|
@ -2910,6 +2921,8 @@ enum FLAG {
|
|||
F_GOESON, // val0 = where it can be equipped.
|
||||
F_GOESONMULTI, // ob is equipped on _ALL_ F_GOESON flags, rather than
|
||||
// equipped on _ONE OF_ the.
|
||||
F_UNDERCLOTHING, // yuo can wear other armour on top of this one
|
||||
// (on the same body part)
|
||||
F_BONUS, // val0=bonus/penalty to damage+accuracy/armour. ie. +1 sword
|
||||
F_THROWMISSILE, // weapon would make a good thrown missle - used by AI
|
||||
F_THROWNBY, // this object was thrown by lifeform id v0.
|
||||
|
@ -4041,8 +4054,12 @@ enum FLAG {
|
|||
F_AWARENESS, // you can see 360 degrees around yourself
|
||||
F_BEINGSTONED,// turn to stone when v0 drops to zero. (drops 1/turn)
|
||||
F_BLIND, // cannot see anything
|
||||
F_SOULLINK, // lf is soul-linked to lfid v0. if they take damage, so do
|
||||
// we.
|
||||
// text = damstring, ie. "x's soullink spell"
|
||||
F_CONFUSED, // move randomly about
|
||||
F_DEAF, // cannot hear
|
||||
F_SILENCED, // cannot make nosies
|
||||
F_NEEDOBFORSPELLS, // if v0 != NA, lf can only cast spells if
|
||||
// it has object v0
|
||||
// if v1 != NA, lf can only cast spells if they
|
||||
|
@ -4492,6 +4509,7 @@ enum ERROR {
|
|||
E_NOUNARMEDATTACK,
|
||||
E_NOTEQUIPPED,
|
||||
E_EQUIPPED,
|
||||
E_UNDERNEATH,
|
||||
E_NOPICKUP,
|
||||
E_STUCK,
|
||||
E_MONSTERNEARBY,
|
||||
|
@ -4516,6 +4534,7 @@ enum ERROR {
|
|||
E_NOTARGET,
|
||||
E_NOAMMO,
|
||||
E_GRAVBOOSTED,
|
||||
E_NOABIL,
|
||||
E_NOMP,
|
||||
E_NOSTAM,
|
||||
E_NOSPELLS,
|
||||
|
@ -4542,6 +4561,7 @@ enum ERROR {
|
|||
E_OFFMAP,
|
||||
E_RAGE,
|
||||
E_STUNNED,
|
||||
E_SILENCED,
|
||||
// charm failure reasons
|
||||
// LOWIQ
|
||||
E_UNDEAD,
|
||||
|
|
1
flag.c
1
flag.c
|
@ -763,6 +763,7 @@ int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid) {
|
|||
case F_PRODUCESLIGHT:
|
||||
case F_PRONE:
|
||||
case F_RAGE:
|
||||
case F_SILENCED:
|
||||
case F_SPRINTING:
|
||||
case F_SLOWMOVE:
|
||||
case F_STUNNED:
|
||||
|
|
127
io.c
127
io.c
|
@ -2092,6 +2092,14 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_SILENCED:
|
||||
if (isplayer(lf)) {
|
||||
msg("^%cYou are surrounded in a field of silence!",getlfcol(lf, CC_BAD));
|
||||
} else {
|
||||
msg("^%c%s is surrounded in a field of silence!", getlfcol(lf, CC_BAD), lfname);
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_SILENTMOVE:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You now move silently.");
|
||||
|
@ -2116,6 +2124,23 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
msg("^%c%s %s",getlfcol(lf, CC_VBAD), lfname, isplayer(lf) ? "feel slow and sluggish." : "looks slow and sluggish.");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_SOULLINK:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
lf2 = findlf(lf->cell->map, f->val[0]);
|
||||
if (lf2) {
|
||||
if (cansee(player, lf2)) {
|
||||
real_getlfname(lf2, buf, NULL, B_NOSHOWALL, B_REALRACE);
|
||||
} else {
|
||||
real_getlfnamea(lf2, buf, NULL, B_NOSHOWALL, B_REALRACE);
|
||||
}
|
||||
msg("^wA psychic bond forms between you and %s!", buf);
|
||||
} else {
|
||||
// shouldn't happen.
|
||||
msg("^wA psychic bond forms between you and something unknown.");
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_SPIDERCLIMB:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("Your skin becomes adhesive!");
|
||||
|
@ -2881,6 +2906,14 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_SILENCED:
|
||||
if (isplayer(lf)) {
|
||||
msg("You can now make noises again.");
|
||||
} else {
|
||||
msg("The field of silence around %s vanishes.", lfname);
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_SILENTMOVE:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
msg("You no longer move silently.");
|
||||
|
@ -2905,6 +2938,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_SOULLINK:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("^wYour psychic soul-link vanishes.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_SPIDERCLIMB:
|
||||
if (isplayer(lf)) {
|
||||
msg("Your skin is no longer adhesive.");
|
||||
|
@ -5030,6 +5069,12 @@ void docomms(lifeform_t *lf) {
|
|||
char ch;
|
||||
lifeform_t *lfarg;
|
||||
cell_t *cellarg;
|
||||
|
||||
if (lfhasflag(player, F_SILENCED)) {
|
||||
msg("You are unable to make a sound!");
|
||||
return;
|
||||
}
|
||||
|
||||
//int moneyowing = 0;
|
||||
if (!lf) {
|
||||
where = askcoords("Talk to who?", "Talk->", TT_MONSTER, player, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
|
@ -6054,7 +6099,7 @@ char *makedesc_ob(object_t *o, char *retbuf) {
|
|||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
if (f->id == F_GOESON) {
|
||||
compareob = getequippedob(player->pack, f->val[0]);
|
||||
compareob = getouterequippedob(player, f->val[0]);
|
||||
if (compareob) {
|
||||
break;
|
||||
}
|
||||
|
@ -7352,6 +7397,10 @@ char *makedesc_ob(object_t *o, char *retbuf) {
|
|||
sprintf(buf2, "%s prevents distant creatures from seeing you.\n", buf);
|
||||
strncat(retbuf, buf2, HUGEBUFLEN);
|
||||
break;
|
||||
case F_SILENCED:
|
||||
sprintf(buf2, "%s prevents you from making sounds.\n", buf);
|
||||
strncat(retbuf, buf2, HUGEBUFLEN);
|
||||
break;
|
||||
case F_SILENTMOVE:
|
||||
sprintf(buf2, "%s allows you to move silently.\n", buf);
|
||||
strncat(retbuf, buf2, HUGEBUFLEN);
|
||||
|
@ -11332,12 +11381,25 @@ void drawstatus(void) {
|
|||
unsetcol(statwin, C_LIGHTBLUE);
|
||||
}
|
||||
|
||||
if (hasactivespell(player, OT_S_DELAYDEATH)) {
|
||||
setcol(statwin, C_LIGHTBLUE);
|
||||
wprintw(statwin, " DelayDeath");
|
||||
unsetcol(statwin, C_LIGHTBLUE);
|
||||
}
|
||||
|
||||
if (lfhasflag(player, F_RAGE)) {
|
||||
setcol(statwin, C_RED);
|
||||
wprintw(statwin, " Rage");
|
||||
unsetcol(statwin, C_RED);
|
||||
}
|
||||
|
||||
if (lfhasflag(player, F_SILENCED)) {
|
||||
setcol(statwin, C_RED);
|
||||
wprintw(statwin, " Mute");
|
||||
unsetcol(statwin, C_RED);
|
||||
}
|
||||
|
||||
|
||||
if (isswimming(player)) {
|
||||
setcol(statwin, C_LIGHTBLUE);
|
||||
wprintw(statwin, " Swim");
|
||||
|
@ -11847,12 +11909,13 @@ int showhiscoreline(void *hilitescore, int ncols, char **argv, char **colname) {
|
|||
void showlfarmour(lifeform_t *lf) {
|
||||
enum BODYPART bp;
|
||||
object_t *o;
|
||||
object_t *arm[MAXBODYPARTS];
|
||||
object_t *arm[MAXBODYPARTS*2];
|
||||
int narm = 0;
|
||||
int y,i;
|
||||
char buf[BUFLEN],ch;
|
||||
int keepgoing = B_TRUE;
|
||||
|
||||
for (i = 0; i < MAXBODYPARTS; i++) {
|
||||
for (i = 0; i < MAXBODYPARTS*2; i++) {
|
||||
arm[i] = NULL;
|
||||
}
|
||||
|
||||
|
@ -11870,17 +11933,27 @@ void showlfarmour(lifeform_t *lf) {
|
|||
char rhs[BUFLEN];
|
||||
// default
|
||||
strcpy(rhs, "");
|
||||
|
||||
if (hasbp(lf, bp)) {
|
||||
object_t *outerob;
|
||||
object_t *oo;
|
||||
int nhere = 0;
|
||||
snprintf(buf, BUFLEN, "%13s:%1s",getbodypartname(lf, bp), " ");
|
||||
o = getequippedob(lf->pack, bp);
|
||||
arm[bp] = o; // remember for later
|
||||
// get outermost armour here so that we can show 'covered' if needed
|
||||
outerob = getouterequippedob(lf, bp);
|
||||
if (o) {
|
||||
|
||||
for (oo = lf->pack->first ;oo ; oo = oo->next) {
|
||||
flag_t *f;
|
||||
int thisar = 0,showar = B_FALSE;
|
||||
char obname[BUFLEN];
|
||||
o = NULL;
|
||||
// is this object equipped in the right place?
|
||||
if (hasflagval(oo->flags, F_EQUIPPED, bp, NA, NA, NULL)) {
|
||||
o = oo;
|
||||
nhere++;
|
||||
}
|
||||
if (!o) continue;
|
||||
|
||||
arm[narm++] = o; // remember for later
|
||||
|
||||
// two handed weapons.
|
||||
if ((bp == BP_SECWEAPON ) && (o == arm[BP_WEAPON])) {
|
||||
|
@ -11923,16 +11996,22 @@ void showlfarmour(lifeform_t *lf) {
|
|||
strcat(rhs, numbuf);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
strcpy(rhs, "-");
|
||||
}
|
||||
|
||||
mvwprintw(mainwin, y, 0, "%s", buf);
|
||||
if (o) setobcolour(mainwin, o, B_TRUE);
|
||||
//wprintw(mainwin, "%s", rhs);
|
||||
textwithcol(mainwin, rhs);
|
||||
if (o) setobcolour(mainwin, o, B_FALSE);
|
||||
y++;
|
||||
mvwprintw(mainwin, y, 0, "%s", buf);
|
||||
setobcolour(mainwin, o, B_TRUE);
|
||||
//wprintw(mainwin, "%s", rhs);
|
||||
textwithcol(mainwin, rhs);
|
||||
setobcolour(mainwin, o, B_FALSE);
|
||||
y++;
|
||||
}
|
||||
// no armour in this body part?
|
||||
if (!nhere) {
|
||||
strcpy(rhs, "-");
|
||||
mvwprintw(mainwin, y, 0, "%s", buf);
|
||||
//wprintw(mainwin, "%s", rhs);
|
||||
textwithcol(mainwin, rhs);
|
||||
y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11945,9 +12024,9 @@ void showlfarmour(lifeform_t *lf) {
|
|||
keepgoing = B_FALSE;
|
||||
} else {
|
||||
// does it match an object?
|
||||
for (bp = BP_WEAPON; bp < MAXBODYPARTS; bp++) {
|
||||
if (arm[bp] && (arm[bp]->letter == ch)) {
|
||||
describeob(arm[bp]);
|
||||
for (o = 0; i < MAXBODYPARTS*2; i++) {
|
||||
if (arm[i] && (arm[i]->letter == ch)) {
|
||||
describeob(arm[i]);
|
||||
}
|
||||
}
|
||||
keepgoing = B_TRUE;
|
||||
|
@ -13615,7 +13694,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
f = hasflag_real(lf->flags, F_VEGETARIAN, B_TRUE, NULL, FROMRACE);
|
||||
if (f) {
|
||||
getflagsourcetext(f,source);
|
||||
mvwprintw(mainwin, y, 0, "%s %s a vegetarian (will not eat meat).%s", you(lf), is(lf));
|
||||
mvwprintw(mainwin, y, 0, "%s %s a vegetarian (will not eat meat).%s", you(lf), is(lf),source);
|
||||
y++;
|
||||
}
|
||||
f = hasflag_real(lf->flags, F_PARTVEGETARIAN, B_TRUE, NULL, FROMRACE);
|
||||
|
@ -14380,6 +14459,14 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
y++;
|
||||
}
|
||||
|
||||
f = hasflag_real(lf->flags, F_SILENCED, B_TRUE, NULL, FROMRACE);
|
||||
if (f) {
|
||||
getflagsourcetext(f,source);
|
||||
mvwprintw(mainwin, y, 0, "%s %s been magically silenced.%s", you(lf),
|
||||
isplayer(lf) ? "have" : "has", source);
|
||||
y++;
|
||||
}
|
||||
|
||||
f = lfhasflag(lf, F_STRIKETOKO);
|
||||
if (f && (f->known)) {
|
||||
getflagsourcetext(f,source);
|
||||
|
|
497
lf.c
497
lf.c
|
@ -108,6 +108,7 @@ void autoweild(lifeform_t *lf) {
|
|||
object_t *o,*firearm;
|
||||
int donesecondary = B_FALSE;
|
||||
int pretimespent;
|
||||
int pass;
|
||||
|
||||
pretimespent = lf->timespent;
|
||||
|
||||
|
@ -128,15 +129,22 @@ void autoweild(lifeform_t *lf) {
|
|||
|
||||
// weild armour/2nd weapons if required,
|
||||
// and mark other weapons as secondary
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
if (isweapon(o) && !isequipped(o) && getskill(lf, SK_TWOWEAPON) && !getequippedob(lf->pack, BP_SECWEAPON) && canweild(lf, o)) {
|
||||
weild(lf, o);
|
||||
} else if (!donesecondary && isweapon(o) && !isequipped(o)) {
|
||||
addflag(o->flags, F_SECONDARY, B_TRUE, NA, NA, NULL);
|
||||
donesecondary = B_TRUE;
|
||||
} else {
|
||||
if (canwear(lf, o, BP_NONE)) {
|
||||
wear(lf, o);
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
if (isweapon(o) && !isequipped(o) && getskill(lf, SK_TWOWEAPON) &&
|
||||
!getequippedob(lf->pack, BP_SECWEAPON) && canweild(lf, o)) {
|
||||
weild(lf, o);
|
||||
} else if (!donesecondary && isweapon(o) && !isequipped(o)) {
|
||||
addflag(o->flags, F_SECONDARY, B_TRUE, NA, NA, NULL);
|
||||
donesecondary = B_TRUE;
|
||||
} else {
|
||||
if (canwear(lf, o, BP_NONE)) {
|
||||
if ((pass == 0) && !hasflag(o->flags, F_UNDERCLOTHING)) {
|
||||
// only equip underclothing on the first pass.
|
||||
} else {
|
||||
wear(lf, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -701,8 +709,10 @@ int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) {
|
|||
flag_t *f;
|
||||
objecttype_t *ot;
|
||||
int stamcost = 0;
|
||||
// TODO: check for mute?
|
||||
|
||||
if (lfhasflag(lf, F_SILENCED)) {
|
||||
reason = E_SILENCED;
|
||||
return B_FALSE;
|
||||
}
|
||||
if (lfhasflag(lf, F_STUNNED)) {
|
||||
reason = E_STUNNED;
|
||||
return B_FALSE;
|
||||
|
@ -879,6 +889,9 @@ int canclimb(lifeform_t *lf, enum ERROR *reason) {
|
|||
} else if (isburdened(lf) || lfhasflag(lf, F_GRAVBOOSTED)) {
|
||||
if (reason) *reason = E_TOOHEAVY;
|
||||
return B_FALSE;
|
||||
} else if ((getraceclass(lf) != RC_HUMANOID) && !getskill(lf, SK_CLIMBING)) {
|
||||
if (reason) *reason = E_NOABIL;
|
||||
return B_FALSE;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -1625,7 +1638,7 @@ int canwear(lifeform_t *lf, object_t *o, enum BODYPART where) {
|
|||
return B_FALSE;
|
||||
}
|
||||
// is the GIVEN part free?
|
||||
if (!isfreebp(lf, where)) {
|
||||
if (!isfreebp(lf, where, o)) {
|
||||
reason = E_WEARINGSOMETHINGELSE;
|
||||
return B_FALSE;
|
||||
}
|
||||
|
@ -1633,7 +1646,7 @@ int canwear(lifeform_t *lf, object_t *o, enum BODYPART where) {
|
|||
if (hasflag(o->flags, F_GOESONMULTI)) {
|
||||
// are ALL of these body parts free?
|
||||
for (i = 0; i < nparts; i++) {
|
||||
if (!isfreebp(lf, possbp[i])) {
|
||||
if (!isfreebp(lf, possbp[i], o)) {
|
||||
reason = E_WEARINGSOMETHINGELSE;
|
||||
return B_FALSE;
|
||||
}
|
||||
|
@ -1643,7 +1656,7 @@ int canwear(lifeform_t *lf, object_t *o, enum BODYPART where) {
|
|||
int ok = B_FALSE;
|
||||
// are ANY of these body parts free?
|
||||
for (i = 0; i < nparts; i++) {
|
||||
if (isfreebp(lf, possbp[i])) {
|
||||
if (isfreebp(lf, possbp[i], o)) {
|
||||
ok = B_TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -1769,8 +1782,12 @@ int canweild(lifeform_t *lf, object_t *o) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
int cantakeoff(lifeform_t *lf, object_t *o) {
|
||||
int cantakeoff(lifeform_t *lf, object_t *o, object_t **errob) {
|
||||
flag_t *f;
|
||||
object_t *oo;
|
||||
enum BODYPART bp = BP_NONE;
|
||||
|
||||
if (errob) *errob = NULL;
|
||||
|
||||
reason = E_OK;
|
||||
f = hasflag(o->flags, F_EQUIPPED);
|
||||
|
@ -1778,6 +1795,14 @@ int cantakeoff(lifeform_t *lf, object_t *o) {
|
|||
reason = E_NOTEQUIPPED;
|
||||
return B_FALSE;
|
||||
}
|
||||
bp = f->val[0];
|
||||
// something else equipped here?
|
||||
oo = getouterequippedob(lf, bp);
|
||||
if (oo && (oo != o)) {
|
||||
if (errob) *errob = oo;
|
||||
reason = E_UNDERNEATH;
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// cursed?
|
||||
if (o->blessed == B_CURSED) {
|
||||
|
@ -1798,6 +1823,9 @@ int cantakeoff(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
|
||||
int cantalk(lifeform_t *lf) {
|
||||
if (lfhasflag(lf, F_SILENCED)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
// phantasms dont talk
|
||||
if (lfhasflag(lf, F_PHANTASM)) {
|
||||
return B_FALSE;
|
||||
|
@ -1884,6 +1912,9 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
|||
case E_STUNNED:
|
||||
msg("You can't cast spells while stunned.");
|
||||
break;
|
||||
case E_SILENCED:
|
||||
msg("You are unable to utter the words to your spell!");
|
||||
break;
|
||||
default:
|
||||
msg("For some reason, you can't cast that.");
|
||||
break;
|
||||
|
@ -5231,18 +5262,20 @@ int eat(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if ((fid != F_NONE) && f->id == F_EATMUTATE) {
|
||||
// lose half your max hp!
|
||||
losehp_real(lf, (lf->maxhp/2), DT_DIRECT, NULL,
|
||||
"the shock of mutation",
|
||||
B_NODAMADJUST, o, B_NORETALIATE, NULL, B_DAMEFFECTS,
|
||||
BP_NONE);
|
||||
if (isplayer(lf)) {
|
||||
msg("^%cYou convulse in agony as your body mutates!",
|
||||
getlfcol(lf, CC_BAD));
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("^%c%s convulses in agony as its body mutates!",
|
||||
getlfcol(lf, CC_BAD), lfname);
|
||||
if (fid != F_NONE) {
|
||||
if (f->id == F_EATMUTATE) {
|
||||
// lose half your max hp!
|
||||
losehp_real(lf, (lf->maxhp/2), DT_DIRECT, NULL,
|
||||
"the shock of mutation",
|
||||
B_NODAMADJUST, o, B_NORETALIATE, NULL, B_DAMEFFECTS,
|
||||
BP_NONE, B_NOCRIT);
|
||||
if (isplayer(lf)) {
|
||||
msg("^%cYou convulse in agony as your body mutates!",
|
||||
getlfcol(lf, CC_BAD));
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("^%c%s convulses in agony as its body mutates!",
|
||||
getlfcol(lf, CC_BAD), lfname);
|
||||
}
|
||||
}
|
||||
// still alive? you gain the ability!
|
||||
if (!isdead(lf)) {
|
||||
|
@ -8331,12 +8364,28 @@ char *getbodypartequipname(enum BODYPART bp) {
|
|||
}
|
||||
|
||||
object_t *getequippedob(obpile_t *op, enum BODYPART bp) {
|
||||
object_t *o;
|
||||
object_t *o,*poss[MAXCANDIDATES];
|
||||
int nposs = 0,i;
|
||||
|
||||
// first get a list of all objects equipped there.
|
||||
// normally there will only be one, unless we have
|
||||
// underclothing (ie. shirt + body armour).
|
||||
for (o = op->first; o ; o = o->next) {
|
||||
if (hasflagval(o->flags, F_EQUIPPED, bp, NA, NA, NULL)) {
|
||||
return o;
|
||||
poss[nposs++] = o;
|
||||
}
|
||||
}
|
||||
if (!nposs) {
|
||||
return NULL;
|
||||
} else if (nposs == 1) {
|
||||
return poss[0];
|
||||
}
|
||||
// we have more than one item equipped. get the inner one with F_UNDERCLOTHING.
|
||||
for(i = 0; i < nposs; i++) {
|
||||
if (hasflag(poss[i]->flags, F_UNDERCLOTHING)) return poss[i];
|
||||
}
|
||||
// should never get here...
|
||||
assert("bug in getequippedob()." == 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -9364,23 +9413,45 @@ char *getlfconditionname(enum LFCONDITION cond) {
|
|||
}
|
||||
|
||||
object_t *getouterequippedob(lifeform_t *lf, enum BODYPART bp) {
|
||||
object_t *o;
|
||||
object_t *o,*poss[MAXCANDIDATES];
|
||||
enum BODYPART where = bp;
|
||||
int i,nposs = 0;
|
||||
|
||||
switch (bp) {
|
||||
case BP_RIGHTFINGER:
|
||||
case BP_LEFTFINGER:
|
||||
o = getequippedob(lf->pack, BP_HANDS);
|
||||
if (o) return o;
|
||||
else return getequippedob(lf->pack, bp);
|
||||
if (getequippedob(lf->pack, BP_HANDS)) {
|
||||
where = BP_HANDS;
|
||||
}
|
||||
break;
|
||||
case BP_BODY:
|
||||
o = getequippedob(lf->pack, BP_SHOULDERS);
|
||||
if (o) return o;
|
||||
else return getequippedob(lf->pack, bp);
|
||||
if (getequippedob(lf->pack, BP_SHOULDERS)) {
|
||||
where = BP_SHOULDERS;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return getequippedob(lf->pack, bp);
|
||||
// get all obs equipped here.
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
if (hasflagval(o->flags, F_EQUIPPED, where, NA, NA, NULL)) {
|
||||
poss[nposs++] = o;
|
||||
}
|
||||
}
|
||||
if (!nposs) {
|
||||
return NULL;
|
||||
} else if (nposs == 1) {
|
||||
return poss[0];
|
||||
}
|
||||
// return the OUTER one.
|
||||
for (i = 0;i < nposs; i++) {
|
||||
if (!hasflag(poss[i]->flags, F_UNDERCLOTHING)) {
|
||||
return poss[i];
|
||||
}
|
||||
}
|
||||
// should never get here.
|
||||
assert("bug in getouterequippedob()." == 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -10106,7 +10177,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, lifeform_t *usevis, int showall,
|
|||
racesize = SZ_HUMAN; // default
|
||||
}
|
||||
size = getlfsize(lf);
|
||||
if (size != racesize) {
|
||||
if (!useorigrace && (size != racesize)) {
|
||||
strcat(descstring, getsizetext(size));
|
||||
strcat(descstring, " ");
|
||||
}
|
||||
|
@ -13939,6 +14010,17 @@ void loseobflags(lifeform_t *lf, object_t *o, int kind) {
|
|||
}
|
||||
}
|
||||
|
||||
int handlearmour(lifeform_t *lf, object_t *fromob, int *dam, enum DAMTYPE dt) {
|
||||
int damreducedbyarmour = 0;
|
||||
if (!armourcanstopdam(dt)) return 0;
|
||||
// modify for defender's armour
|
||||
// first figure out how much to reduce the damage by.
|
||||
damreducedbyarmour = getarmourdamreduction(lf, fromob, *dam, dt);
|
||||
// now actually reduce the damage amount
|
||||
applyarmourdamreduction(lf, fromob, damreducedbyarmour, dam, dt);
|
||||
return damreducedbyarmour;
|
||||
}
|
||||
|
||||
int hasbp(lifeform_t *lf, enum BODYPART bp) {
|
||||
int i;
|
||||
if (lfhasflagval(lf, F_NOBODYPART, bp, NA, NA, NULL)) {
|
||||
|
@ -14408,7 +14490,12 @@ int isclimbing(lifeform_t *lf) {
|
|||
|
||||
int isdead(lifeform_t *lf) {
|
||||
if (!lf->alive) return B_TRUE;
|
||||
if (lf->hp <= 0) return B_TRUE;
|
||||
if (lf->hp <= 0) {
|
||||
if (hasactivespell(lf, OT_S_DELAYDEATH) && (lf->hp > -15)) {
|
||||
} else {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -14550,8 +14637,17 @@ int isflyingwithwings(lifeform_t *lf) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
int isfreebp(lifeform_t *lf, enum BODYPART bp) {
|
||||
if (hasobwithflagval(lf->pack, F_EQUIPPED, bp, NA, NA, NULL)) return B_FALSE;
|
||||
int isfreebp(lifeform_t *lf, enum BODYPART bp, object_t *whatfor) {
|
||||
object_t *o;
|
||||
o = hasobwithflagval(lf->pack, F_EQUIPPED, bp, NA, NA, NULL);
|
||||
if (o) {
|
||||
if (whatfor && !hasflag(whatfor->flags, F_UNDERCLOTHING) &&
|
||||
hasflag(o->flags, F_UNDERCLOTHING)) {
|
||||
// ok.
|
||||
} else {
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasbp(lf, bp)) return B_FALSE;
|
||||
|
||||
|
@ -16839,15 +16935,15 @@ void loseconsciousness(lifeform_t *lf, int howlong, lifeform_t *fromlf) {
|
|||
|
||||
// lose hp, and adjust damage based on resistances
|
||||
int losehp(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc) {
|
||||
return losehp_real(lf, amt, damtype, fromlf, damsrc, B_DAMADJUST, NULL, B_RETALIATE, NULL, B_DAMEFFECTS, BP_NONE);
|
||||
return losehp_real(lf, amt, damtype, fromlf, damsrc, B_DAMADJUST, NULL, B_RETALIATE, NULL, B_DAMEFFECTS, BP_NONE, B_NOCRIT);
|
||||
}
|
||||
|
||||
int losehp_bp(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int bodypart) {
|
||||
return losehp_real(lf, amt, damtype, fromlf, damsrc, B_DAMADJUST, NULL, B_RETALIATE, NULL, B_DAMEFFECTS, bodypart);
|
||||
return losehp_real(lf, amt, damtype, fromlf, damsrc, B_DAMADJUST, NULL, B_RETALIATE, NULL, B_DAMEFFECTS, bodypart, B_NOCRIT);
|
||||
}
|
||||
|
||||
// returns the amt of damage taken
|
||||
int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob, int retaliate, int *waskod, int doeffects, int bodypart) {
|
||||
int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob, int retaliate, int *waskod, int doeffects, int bodypart, int fromcrit) {
|
||||
char buf[BUFLEN];
|
||||
char buf2[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
|
@ -16855,6 +16951,8 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
int murder = B_FALSE;
|
||||
flag_t *f;
|
||||
int predead = B_FALSE;
|
||||
int damreducedbyarm = 0;
|
||||
int hpleftafterdam;
|
||||
|
||||
if (gamemode < GM_GAMESTARTED) return 0;
|
||||
|
||||
|
@ -16876,6 +16974,11 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
murder = B_TRUE;
|
||||
}
|
||||
|
||||
if (doeffects) {
|
||||
// handle armour
|
||||
damreducedbyarm = handlearmour(lf, fromob, &amt, damtype);
|
||||
}
|
||||
|
||||
// adjust for source object's material
|
||||
if (fromob) {
|
||||
if (lfhasflagval(lf, F_MATIMMUNE, fromob->material->id, NA, NA, NULL)) {
|
||||
|
@ -16910,13 +17013,16 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
killflagsofid(lf->flags, F_HIDING);
|
||||
|
||||
// methods of knocking unconscious
|
||||
if (lfcanbekod(lf)) {
|
||||
// would this damage reduce the lf to < 0 hp ???
|
||||
hpleftafterdam = lf->hp - amt;
|
||||
if (lfcanbekod(lf) && (lf->hp > 1) && (hpleftafterdam <= 0)) {
|
||||
int threshold = 0,kochance = 0;
|
||||
// merciful weapons - these will ALWAYS ko, even if
|
||||
// they are already unconscious.
|
||||
if (!ko && fromob) {
|
||||
f = hasflag(fromob->flags, F_MERCIFUL);
|
||||
if (f && (amt >= lf->hp)) {
|
||||
ko = B_TRUE;
|
||||
kochance = 100;
|
||||
if (fromob->pile->owner && cansee(player, fromob->pile->owner)) {
|
||||
f->known = B_TRUE;
|
||||
}
|
||||
|
@ -16926,7 +17032,6 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
// bashing damage sometimes ko's
|
||||
// damage when eating corpses also does this.
|
||||
if (!ko && !isunconscious(lf)) {
|
||||
int threshold,kochance = 0;
|
||||
int damtypeok = B_FALSE;
|
||||
int playerinvolved = B_FALSE;
|
||||
|
||||
|
@ -16946,28 +17051,34 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
if (playerinvolved && godprayedto(R_GODMERCY)) {
|
||||
threshold = -10;
|
||||
if (isplayer(lf)) {
|
||||
kochance = 75;
|
||||
// player being hit?
|
||||
kochance += 75;
|
||||
} else {
|
||||
kochance = 50;
|
||||
// player hitting something else?
|
||||
kochance += 30;
|
||||
}
|
||||
} else {
|
||||
threshold = -5;
|
||||
kochance = 30;
|
||||
kochance += 15; // base chance to KO with bashing.
|
||||
}
|
||||
|
||||
// TRYING to ko rather than kill?
|
||||
if (fromlf && lfhasflag(fromlf, F_STRIKETOKO)) {
|
||||
if (cansee(fromlf, lf)) {
|
||||
kochance += 30;
|
||||
threshold -= 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (kochance) {
|
||||
int hpleftafterdam;
|
||||
// if this damage would reduce the lf to between -threshold and 0 hp
|
||||
hpleftafterdam = lf->hp - amt;
|
||||
if ((lf->hp > 1) && (hpleftafterdam >= threshold) && (hpleftafterdam <= 0)) {
|
||||
if (pctchance(kochance)) {
|
||||
ko = B_TRUE;
|
||||
}
|
||||
if (kochance && (hpleftafterdam >= threshold)) {
|
||||
if (pctchance(kochance)) {
|
||||
ko = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (!ko && !isunconscious(lf)) {
|
||||
if (fromlf && lfhasflag(fromlf, F_STRIKETOKO)) {
|
||||
if (cansee(fromlf, lf)) {
|
||||
|
@ -16975,11 +17086,13 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// just knock them out, don't kill.
|
||||
if (ko) {
|
||||
amt = lf->hp - 1; // ie end up at 1hp
|
||||
}
|
||||
}
|
||||
|
||||
// just knock them out, don't kill.
|
||||
if (ko) {
|
||||
amt = lf->hp - 1; // ie end up at 1hp
|
||||
}
|
||||
|
||||
|
||||
|
@ -17051,7 +17164,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
}
|
||||
|
||||
if (doeffects || ko) {
|
||||
losehpeffects(lf, amt, damtype, fromlf, fromob, retaliate, ko, waskod, prelowhp, bodypart);
|
||||
losehpeffects(lf, amt, damtype, fromlf, fromob, retaliate, ko, waskod, prelowhp, bodypart, damreducedbyarm, fromcrit);
|
||||
}
|
||||
|
||||
if ((lf->hp > 0) && !ko && fromlf && (getcelldist(lf->cell, fromlf->cell) > 1)) {
|
||||
|
@ -17141,15 +17254,70 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
// update screen
|
||||
drawstatus();
|
||||
updatestatus();
|
||||
|
||||
f = lfhasflag(lf, F_SOULLINK);
|
||||
if (f && (damtype != DT_DIRECT)) {
|
||||
lifeform_t *otherlf;
|
||||
otherlf = findlf(lf->cell->map, f->val[0]);
|
||||
if (otherlf) {
|
||||
losehp_real(otherlf, amt, DT_DIRECT, lf, f->text, B_FALSE, NULL, B_FALSE, NULL, B_NODAMEFFECTS, BP_NONE, B_NOCRIT);
|
||||
}
|
||||
}
|
||||
|
||||
return amt;
|
||||
}
|
||||
|
||||
void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fromlf, object_t *fromob, int retaliate, int ko, int *waskod, int prelowhp, int bodypart) {
|
||||
void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fromlf, object_t *fromob, int retaliate, int ko, int *waskod, int prelowhp, int bodypart, int damreducedbyarm, int crit) {
|
||||
int postlowhp = B_FALSE;
|
||||
flag_t *retflag[MAXCANDIDATES],*f;
|
||||
flag_t *retflag[MAXCANDIDATES],*f,*magicarm = NULL;
|
||||
int nretflags;
|
||||
char buf[BUFLEN],lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
|
||||
// armour damage
|
||||
if ((dam > 0) && isphysicaldam(damtype)) {
|
||||
getflags(lf->flags, retflag, &nretflags, F_HEAVENARM, F_MAGICARMOUR, F_NONE);
|
||||
if (nretflags) {
|
||||
magicarm = retflag[0];
|
||||
}
|
||||
}
|
||||
// now magic armour will pulse and maybe vanish.
|
||||
if (magicarm) {
|
||||
int damprevented;
|
||||
// prevent all damage if possible
|
||||
damprevented = dam;
|
||||
magicarm->val[0] -= damprevented;
|
||||
if (magicarm->val[0] <= 0) {
|
||||
// did magic armour come from a spell?
|
||||
if (magicarm->lifetime == FROMSPELL) {
|
||||
flag_t *spellflag;
|
||||
spellflag = hasactivespell(lf, magicarm->obfrom);
|
||||
if (spellflag) {
|
||||
killflag(spellflag);
|
||||
}
|
||||
}
|
||||
// magic armour vanishes now.
|
||||
killflag(magicarm);
|
||||
} else {
|
||||
if (cansee(player, lf)) {
|
||||
msg("^%d%s%s %s pulses!^n",
|
||||
CC_GOOD,
|
||||
lfname, getpossessive(lfname),
|
||||
magicarm->text);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// victim's armour loses hp. note that it loses the full
|
||||
// amount of damage dealt, not just what it reduced.
|
||||
if (damreducedbyarm && !crit) {
|
||||
applyarmourdamage(lf, fromob, dam + damreducedbyarm, damtype, fromlf);
|
||||
// train armour
|
||||
practice(lf, SK_ARMOUR, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (lf->hp > 0) {
|
||||
// effects based on damage type, if lf is still alive
|
||||
if (damtype == DT_COLD) {
|
||||
|
@ -17227,7 +17395,7 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr
|
|||
for (i = 0 ; i < nretcells; i++) {
|
||||
if (retcell[i]->lf && (retcell[i]->lf != lf)) {
|
||||
if (!isairborne(retcell[i]->lf, NULL)) {
|
||||
losehp_real(retcell[i]->lf, dam, DT_ELECTRIC, fromlf, "an electric shock", B_TRUE, NULL, B_FALSE, NULL, B_FALSE, BP_NONE);
|
||||
losehp_real(retcell[i]->lf, dam, DT_ELECTRIC, fromlf, "an electric shock", B_TRUE, NULL, B_FALSE, NULL, B_FALSE, BP_NONE, B_NOCRIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17744,7 +17912,7 @@ int makelearnable(lifeform_t *lf, enum SKILL skid) {
|
|||
|
||||
// returns TRUE on failure.
|
||||
int makenauseated(lifeform_t *lf, int amt, int howlong, enum ERROR *why) {
|
||||
flag_t *f;
|
||||
flag_t *f,*nflag = NULL;
|
||||
if (why) *why = E_OK;
|
||||
|
||||
switch (lf->race->raceclass->id) {
|
||||
|
@ -17777,27 +17945,28 @@ int makenauseated(lifeform_t *lf, int amt, int howlong, enum ERROR *why) {
|
|||
|
||||
//if (!lfhasflag(lf, F_HUMANOID)) return B_TRUE;
|
||||
|
||||
nflag = lfhasflag(lf, F_NAUSEATED);
|
||||
|
||||
// skillcheck to avoid this.
|
||||
if (skillcheck(lf, SC_CON, 80 + (amt*10), gettr(lf)*2)) {
|
||||
// passed skillcheck
|
||||
if (why) *why = E_RESISTED;
|
||||
// announce
|
||||
if (isplayer(lf)) {
|
||||
msg("You feel momentarily unwell.");
|
||||
msg("You feel momentarily %sunwell.", nflag ? "more " : "");
|
||||
} else if (cansee(player, lf)) {
|
||||
char buf[BUFLEN];
|
||||
getlfname(lf, buf);
|
||||
msg("%s looks momentarily unwell.", buf);
|
||||
msg("%s looks momentarily %sunwell.", buf, nflag ? "more " : "");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// already nauseated?
|
||||
f = lfhasflag(lf, F_NAUSEATED);
|
||||
if (f) {
|
||||
if ((f->lifetime >= 0) && (f->lifetime < howlong)) {
|
||||
f->lifetime = howlong;
|
||||
f->val[0] = MAXOF(f->val[0], amt);
|
||||
if (nflag) {
|
||||
if ((nflag->lifetime >= 0) && (nflag->lifetime < howlong)) {
|
||||
nflag->lifetime = howlong;
|
||||
nflag->val[0] = MAXOF(f->val[0], amt);
|
||||
}
|
||||
} else {
|
||||
addtempflag(lf->flags, F_NAUSEATED, amt, NA, NA, NULL, howlong);
|
||||
|
@ -18615,57 +18784,9 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
}
|
||||
} // end if isplayer and not asleep
|
||||
|
||||
// wake up a little
|
||||
f = lfhasflag(l, F_ASLEEP);
|
||||
if (f && (f->val[1] != ST_KO)) {
|
||||
if (f->lifetime > 0) { // ie. temporary
|
||||
timeeffectsflag(f, myvol + rnd(1,3));
|
||||
} else if (f->lifetime == PERMENANT) {
|
||||
if (f->val[2] == NA) {
|
||||
// ie asleep rather than 'resting'
|
||||
// wake up!
|
||||
if (isplayer(l)) {
|
||||
msg("^wA nearby noise %s you!", (f->val[1] == ST_MEDITATING) ? "" : "awakens" );
|
||||
rv = B_TRUE;
|
||||
}
|
||||
killflag(f);
|
||||
} else {
|
||||
// ie resting on purpose via 'R'
|
||||
// only wake up if the sound if very close
|
||||
if (myvol >= getcelldist(c, l->cell)) {
|
||||
// wake up!
|
||||
if (isplayer(l)) {
|
||||
char wakenoise[BUFLEN];
|
||||
char *punc;
|
||||
strcpy(wakenoise, text);
|
||||
// omit punctuation
|
||||
punc = &(wakenoise[strlen(wakenoise)-1]);
|
||||
switch (*punc) {
|
||||
case '"': break;
|
||||
default:
|
||||
*punc = '\0';
|
||||
break;
|
||||
}
|
||||
//msg("A nearby noise awakens you!");
|
||||
msg("^wThe sound of %s awakens you!", wakenoise);
|
||||
rv = B_TRUE;
|
||||
}
|
||||
killflag(f);
|
||||
}
|
||||
}
|
||||
// make it temporary
|
||||
//f->lifetime = rnd(1,10);
|
||||
}
|
||||
|
||||
// still asleep?
|
||||
f = lfhasflag(l, F_ASLEEP);
|
||||
if (f && (f->val[1] == ST_ASLEEP) && cansee(player, l)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(l, lfname);
|
||||
msg("%s stir%s in %s slumber...", lfname,
|
||||
isplayer(l) ? "" : "s",
|
||||
isplayer(l) ? "your" : "its");
|
||||
}
|
||||
stir(l,myvol,getcelldist(c, l->cell), text);
|
||||
} else { // not asleep, but can hear it.
|
||||
// monsters will go to investigate the sound, as long as they're
|
||||
// not otherwise occupied
|
||||
|
@ -20173,6 +20294,10 @@ int say(lifeform_t *lf, char *text, int volume) {
|
|||
char *localtext;
|
||||
int rv;
|
||||
|
||||
if (lf && lfhasflag(lf, F_SILENCED)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
localtext = strdup(text);
|
||||
|
||||
// adjust text and volume for gods
|
||||
|
@ -20245,6 +20370,9 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
|
|||
char buf3[BUFLEN];
|
||||
char *p,*p2;
|
||||
race_t *r;
|
||||
if (lf && lfhasflag(lf, F_SILENCED)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
switch (what) {
|
||||
case SP_ALLY_ATTACK:
|
||||
switch (rnd(1,3)) {
|
||||
|
@ -22373,6 +22501,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
|
||||
if (db) dblog("startlfturn for lf id %d %s", lf->id, lf->race->name);
|
||||
|
||||
// if (lf->hp < 0) lf->hp = 0;
|
||||
|
||||
// debugging
|
||||
lf->redraws = 0;
|
||||
|
@ -23463,7 +23592,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
msg("^%c%s%s spine snaps!", getlfcol(lf, CC_VBAD),
|
||||
lfname, getpossessive(lfname));
|
||||
}
|
||||
losehp_real(lf, lf->maxhp, DT_DIRECT, NULL, "tetanus", B_FALSE, NULL, B_FALSE, NULL, B_FALSE, BP_NONE);
|
||||
losehp_real(lf, lf->maxhp, DT_DIRECT, NULL, "tetanus", B_FALSE, NULL, B_FALSE, NULL, B_FALSE, BP_NONE, B_FROMCRIT);
|
||||
}
|
||||
break;
|
||||
case BP_TAIL:
|
||||
|
@ -23816,7 +23945,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
// effects for/on your own flags
|
||||
getflags(lf->flags, retflag, &nretflags, F_ANTICIPATE, F_ATTACHEDTO, F_CANCAST, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FEIGNFOOLEDBY,F_FLEEFROM,
|
||||
F_GRABBEDBY, F_GRABBING, F_HIDING, F_BOOSTSPELL, F_FEIGNINGDEATH, F_FULLSHIELD,F_HPDRAIN, F_INCUBATING, F_INJURY,
|
||||
F_NOFLEEFROM, F_PETOF, F_SIZETIMER, F_SPOTTED, F_STRIKETOKO, F_TARGETCELL, F_TARGETLF, F_NONE);
|
||||
F_NOFLEEFROM, F_PETOF, F_SIZETIMER, F_SOULLINK, F_SPOTTED, F_STRIKETOKO, F_TARGETCELL, F_TARGETLF, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
// remove impossible/expired flags
|
||||
|
@ -23909,7 +24038,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
|
||||
if (f->obfrom == B_NEWINJURY) f->obfrom = B_FALSE;
|
||||
|
||||
arm = getequippedob(lf->pack, f->val[1]);
|
||||
arm = getouterequippedob(lf, f->val[1]);
|
||||
if (arm && !hasobmod(arm, findobmod(OM_BLOODSTAINED)) && pctchance(5)) applyobmod(arm, findobmod(OM_BLOODSTAINED));
|
||||
}
|
||||
|
||||
|
@ -23934,6 +24063,14 @@ void startlfturn(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
*/
|
||||
if (f->id == F_SOULLINK) {
|
||||
lifeform_t *lf2;
|
||||
lf2 = findlf(lf->cell->map, f->val[0]);
|
||||
if (!lf2) {
|
||||
killflag(f);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (f->id == F_SPOTTED) {
|
||||
lifeform_t *lf2;
|
||||
lf2 = findlf(NULL, f->val[0]);
|
||||
|
@ -24173,6 +24310,68 @@ int steal(lifeform_t *lf, obpile_t *op, enum FLAG wantflag) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// returns TRUE if l woke up.
|
||||
int stir(lifeform_t *l, int vol, int dist, char *noisetext) {
|
||||
flag_t *f;
|
||||
int rv = B_FALSE;
|
||||
|
||||
// wake up a little
|
||||
f = lfhasflag(l, F_ASLEEP);
|
||||
if (f && (f->val[1] != ST_KO)) {
|
||||
if (f->lifetime > 0) { // ie. temporary
|
||||
timeeffectsflag(f, vol + rnd(1,3));
|
||||
} else if (f->lifetime == PERMENANT) {
|
||||
if (f->val[2] == NA) {
|
||||
// ie asleep rather than 'resting'
|
||||
// wake up!
|
||||
if (isplayer(l)) {
|
||||
msg("^wA nearby noise %s you!", (f->val[1] == ST_MEDITATING) ? "startles" : "awakens" );
|
||||
rv = B_TRUE;
|
||||
}
|
||||
killflag(f);
|
||||
} else {
|
||||
// ie resting on purpose via 'R'
|
||||
// only wake up if the sound if very close
|
||||
if (vol >= dist) {
|
||||
// wake up!
|
||||
if (isplayer(l)) {
|
||||
if (noisetext) {
|
||||
char wakenoise[BUFLEN];
|
||||
char *punc;
|
||||
strcpy(wakenoise, noisetext);
|
||||
// omit punctuation
|
||||
punc = &(wakenoise[strlen(wakenoise)-1]);
|
||||
switch (*punc) {
|
||||
case '"': break;
|
||||
default:
|
||||
*punc = '\0';
|
||||
break;
|
||||
}
|
||||
msg("^wThe sound of %s awakens you!", wakenoise);
|
||||
} else {
|
||||
msg("Something awakens you!");
|
||||
}
|
||||
rv = B_TRUE;
|
||||
}
|
||||
killflag(f);
|
||||
}
|
||||
}
|
||||
// make it temporary
|
||||
//f->lifetime = rnd(1,10);
|
||||
}
|
||||
|
||||
// still asleep?
|
||||
f = lfhasflag(l, F_ASLEEP);
|
||||
if (f && (f->val[1] == ST_ASLEEP) && cansee(player, l)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(l, lfname);
|
||||
msg("%s stir%s in %s slumber...", lfname,
|
||||
isplayer(l) ? "" : "s",
|
||||
isplayer(l) ? "your" : "its");
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
int stone(lifeform_t *lf) {
|
||||
char lfname[BUFLEN];
|
||||
|
@ -24364,6 +24563,7 @@ lifeform_t *summonmonster(lifeform_t *caster, cell_t *c, enum RACE rid, char *ra
|
|||
int takeoff(lifeform_t *lf, object_t *o) {
|
||||
char obname[BUFLEN];
|
||||
char buf[BUFLEN];
|
||||
object_t *errob = NULL;
|
||||
|
||||
if (!isarmour(o)) {
|
||||
return unweild(lf, o);
|
||||
|
@ -24376,7 +24576,7 @@ int takeoff(lifeform_t *lf, object_t *o) {
|
|||
|
||||
getobname(o, obname, 1);
|
||||
|
||||
if (!cantakeoff(lf, o)) {
|
||||
if (!cantakeoff(lf, o, &errob)) {
|
||||
switch (reason) {
|
||||
case E_CURSED:
|
||||
if (isplayer(lf)) {
|
||||
|
@ -24396,6 +24596,16 @@ int takeoff(lifeform_t *lf, object_t *o) {
|
|||
msg("Your injury prevents you from removing your %s.", noprefix(obname));
|
||||
}
|
||||
break;
|
||||
case E_UNDERNEATH:
|
||||
if (isplayer(lf)) {
|
||||
if (errob) {
|
||||
getobname(errob, buf, 1);
|
||||
msg("Your %s is in the way!", noprefix(buf));
|
||||
} else {
|
||||
msg("You will need to remove your outer armour first.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (isplayer(lf)) {
|
||||
msg("For some reason, you cannot remove your %s!", noprefix(obname));
|
||||
|
@ -24819,7 +25029,7 @@ int real_touch(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
f = hasflag(lf->flags, F_FREEZINGTOUCH);
|
||||
if (f) {
|
||||
// not wearing gloves?
|
||||
if (!getequippedob(lf->pack, BP_HANDS)) {
|
||||
if (!getouterequippedob(lf, BP_HANDS)) {
|
||||
// default power of 4
|
||||
dospelleffects(lf, OT_S_FREEZEOB, 4, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE, NULL);
|
||||
|
||||
|
@ -24838,7 +25048,7 @@ int real_touch(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
}
|
||||
}
|
||||
|
||||
gloves = getequippedob(lf->pack, BP_HANDS);
|
||||
gloves = getouterequippedob(lf, BP_HANDS);
|
||||
|
||||
// undead and blessed objects?
|
||||
if (isundead(lf) && isblessed(o)) {
|
||||
|
@ -25138,6 +25348,7 @@ void unsummon(lifeform_t *lf, int vanishobs) {
|
|||
int unweild(lifeform_t *lf, object_t *o) {
|
||||
char obname[BUFLEN];
|
||||
char buf[BUFLEN];
|
||||
object_t *errob;
|
||||
|
||||
getobname(o, obname, 1);
|
||||
|
||||
|
@ -25146,7 +25357,7 @@ int unweild(lifeform_t *lf, object_t *o) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (!cantakeoff(lf, o)) {
|
||||
if (!cantakeoff(lf, o, &errob)) {
|
||||
switch (reason) {
|
||||
case E_CURSED:
|
||||
if (isplayer(lf)) {
|
||||
|
@ -25161,9 +25372,19 @@ int unweild(lifeform_t *lf, object_t *o) {
|
|||
msg("You are not weilding that!");
|
||||
}
|
||||
break;
|
||||
case E_UNDERNEATH:
|
||||
if (isplayer(lf)) {
|
||||
if (errob) {
|
||||
getobname(errob, buf, 1);
|
||||
msg("Your %s is in the way!", noprefix(buf));
|
||||
} else {
|
||||
msg("You will need to remove your outer armour first.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (isplayer(lf)) {
|
||||
msg("For some reason, you cannot stop weilding your %s!", noprefix(obname));
|
||||
msg("For some reason, you cannot take off your %s!", noprefix(obname));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -26457,7 +26678,7 @@ int wear(lifeform_t *lf, object_t *o) {
|
|||
if (o->type->obclass->id == OC_RING) {
|
||||
bp = BP_NONE;
|
||||
for (i = 0; i < nparts; i++) {
|
||||
if (isfreebp(lf, possbp[i])) {
|
||||
if (isfreebp(lf, possbp[i], o)) {
|
||||
bp = possbp[i];
|
||||
break;
|
||||
}
|
||||
|
@ -26478,11 +26699,15 @@ int wear(lifeform_t *lf, object_t *o) {
|
|||
initprompt(&prompt, buf);
|
||||
for (i = 0; i < nparts; i++) {
|
||||
object_t *inway;
|
||||
inway = getequippedob(lf->pack, possbp[i]);
|
||||
inway = getouterequippedob(lf, possbp[i]);
|
||||
if (inway) {
|
||||
char inwayname[BUFLEN];
|
||||
getobname(inway, inwayname, inway->amt);
|
||||
snprintf(buf, BUFLEN, "%s (replace %s)", getbodypartname(lf, possbp[i]), inwayname);
|
||||
if (hasflag(inway->flags, F_UNDERCLOTHING)) {
|
||||
snprintf(buf, BUFLEN, "%s (over %s)", getbodypartname(lf, possbp[i]), inwayname);
|
||||
} else {
|
||||
snprintf(buf, BUFLEN, "%s (replace %s)", getbodypartname(lf, possbp[i]), inwayname);
|
||||
}
|
||||
} else {
|
||||
snprintf(buf, BUFLEN, "%s", getbodypartname(lf, possbp[i]));
|
||||
}
|
||||
|
@ -27227,8 +27452,8 @@ int willbackstab(lifeform_t *lf, lifeform_t *victim, object_t *wep) {
|
|||
|
||||
int willbleedfrom(lifeform_t *lf, enum BODYPART bp) {
|
||||
object_t *o;
|
||||
o = getequippedob(lf->pack, bp);
|
||||
if (o && (o->type->id == OT_BANDAGE)) {
|
||||
o = hasequippedobidon(lf->pack, OT_BANDAGE, bp);
|
||||
if (o) {
|
||||
// don't bleed.
|
||||
return B_FALSE;
|
||||
}
|
||||
|
|
10
lf.h
10
lf.h
|
@ -72,7 +72,7 @@ int canthrow(lifeform_t *lf, object_t *o, enum ERROR *why);
|
|||
int canuseweapons(lifeform_t *lf);
|
||||
int canwear(lifeform_t *lf, object_t *o, enum BODYPART where);
|
||||
int canweild(lifeform_t *lf, object_t *o);
|
||||
int cantakeoff(lifeform_t *lf, object_t *o);
|
||||
int cantakeoff(lifeform_t *lf, object_t *o, object_t **errob);
|
||||
int cantalk(lifeform_t *lf);
|
||||
int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *targob, cell_t *targcell, object_t *fromob, int *seen);
|
||||
int celllitfor(lifeform_t *lf, cell_t *c, int maxvisrange, int nightvisrange);
|
||||
|
@ -347,6 +347,7 @@ int lfproduceslight(lifeform_t *lf, object_t **fromwhat);
|
|||
int lighthurtseyes(lifeform_t *lf);
|
||||
int lockpick(lifeform_t *lf, cell_t *targcell, object_t *target, object_t *device);
|
||||
void loseobflags(lifeform_t *lf, object_t *o, int kind);
|
||||
int handlearmour(lifeform_t *lf, object_t *fromob, int *dam, enum DAMTYPE dt);
|
||||
int hasbp(lifeform_t *lf, enum BODYPART bp);
|
||||
flag_t *hasactivespell(lifeform_t *lf, enum OBTYPE sid);
|
||||
int haslof(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest);
|
||||
|
@ -371,7 +372,7 @@ object_t *isdualweilding(lifeform_t *lf);
|
|||
flag_t *isfleeing(lifeform_t *lf);
|
||||
flag_t *isfleeingfrom(lifeform_t *lf, lifeform_t *runfrom);
|
||||
int isflyingwithwings(lifeform_t *lf);
|
||||
int isfreebp(lifeform_t *lf, enum BODYPART bp);
|
||||
int isfreebp(lifeform_t *lf, enum BODYPART bp, object_t *whatfor);
|
||||
int isfriendly(lifeform_t *lf);
|
||||
int isfullyhealed(lifeform_t *lf);
|
||||
int isexhausted(lifeform_t *lf);
|
||||
|
@ -425,8 +426,8 @@ void loseconcentration(lifeform_t *lf);
|
|||
void loseconsciousness(lifeform_t *lf, int howlong, lifeform_t *fromlf);
|
||||
int losehp(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc);
|
||||
int losehp_bp(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int bodypart);
|
||||
int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob, int retaliate, int *waskod, int doeffects, int bodypart);
|
||||
void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fromlf, object_t *fromob, int retaliate, int ko, int *waskod, int prelowhp, int bodypart);
|
||||
int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob, int retaliate, int *waskod, int doeffects, int bodypart, int fromcrit);
|
||||
void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fromlf, object_t *fromob, int retaliate, int ko, int *waskod, int prelowhp, int bodypart, int damreducebyarm, int crit);
|
||||
void losemp(lifeform_t *lf, int amt);
|
||||
void loselevel(lifeform_t *lf, int amt, lifeform_t *fromlf);
|
||||
void loseskill(lifeform_t *lf, enum SKILL skid);
|
||||
|
@ -519,6 +520,7 @@ int slipon(lifeform_t *lf, object_t *o);
|
|||
void sortlf(map_t *map, lifeform_t *lf);
|
||||
void startlfturn(lifeform_t *lf);
|
||||
int steal(lifeform_t *lf, obpile_t *op, enum FLAG wantflag);
|
||||
int stir(lifeform_t *lf, int vol, int dist, char *noisetext);
|
||||
int stone(lifeform_t *lf);
|
||||
int stopclimbing(lifeform_t *lf, int onpurpose);
|
||||
void stopeating(lifeform_t *lf);
|
||||
|
|
45
map.c
45
map.c
|
@ -985,24 +985,37 @@ void adjustcellglyph(cell_t *c, glyph_t *g, enum CELLADJUSTTYPE how) {
|
|||
if ((how == CA_CH) || (how == CA_BOTH)) {
|
||||
// for certain cell types, select glyph based on surrounding cells of same type
|
||||
if (g->ch == UNI_DYNAMIC) {
|
||||
int adj = 0,i;
|
||||
int adj = 0,i,ndirslinked = 0,n;
|
||||
cell_t *c2;
|
||||
for (i = D_N; i <= D_W; i++) {
|
||||
int this;
|
||||
c2 = getcellindir(c,i);
|
||||
if (c2 && c2->known && ((c2->type->id == c->type->id) || hasdoor(c2)) ) {
|
||||
//if (c2 && c2->known && (issolid(c2) || hasdoor(c2)) ) {
|
||||
this = 1;
|
||||
// we want:
|
||||
// N E S W
|
||||
// 8 4 2 1
|
||||
if (i == D_N) this <<= 3;
|
||||
else if (i == D_E) this <<= 2;
|
||||
else if (i == D_S) this <<= 1;
|
||||
} else {
|
||||
this = 0;
|
||||
for (n = 0; ((ndirslinked == 0) && (n < 2)); n++) {
|
||||
for (i = D_N; i <= D_W; i++) {
|
||||
int this = 0;
|
||||
int typematches = B_FALSE;
|
||||
c2 = getcellindir(c,i);
|
||||
if (c2) {
|
||||
if (n == 0) { // first pass
|
||||
if (c2->type->id == c->type->id) {
|
||||
typematches = B_TRUE;
|
||||
}
|
||||
} else { // second pass
|
||||
if (issolid(c2)) {
|
||||
typematches = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (c2->known && (typematches || hasdoor(c2)) ) {
|
||||
this = 1;
|
||||
ndirslinked++;
|
||||
// we want:
|
||||
// N E S W
|
||||
// 8 4 2 1
|
||||
if (i == D_N) this <<= 3;
|
||||
else if (i == D_E) this <<= 2;
|
||||
else if (i == D_S) this <<= 1;
|
||||
}
|
||||
}
|
||||
adj |= this;
|
||||
}
|
||||
adj |= this;
|
||||
}
|
||||
switch (adj) {
|
||||
case 1: // left
|
||||
|
|
22
move.c
22
move.c
|
@ -132,17 +132,18 @@ int canswapwith(lifeform_t *lf, lifeform_t *lf2) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// cannot swap with sleeping lfs
|
||||
if (lfhasflag(lf2, F_ASLEEP)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// allies can always swap
|
||||
if (areallies(lf, lf2)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
if (isplayer(lf) && !areenemies(lf, lf2)) {
|
||||
if (isknownpeaceful(lf2)) {
|
||||
|
||||
if (isplayer(lf)) {
|
||||
if (lfhasflag(lf2, F_ASLEEP)) {
|
||||
if (getlfsize(lf2) <= getlfsize(lf)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
} else if (!areenemies(lf, lf2) && isknownpeaceful(lf2)) {
|
||||
// player can swap with peaceful lfs
|
||||
// if they are a lot smaller
|
||||
//if (getlfsize(lf) - getlfsize(lf2) >= 2) {
|
||||
|
@ -1459,7 +1460,7 @@ int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) {
|
|||
if (f && hasbp(lf, BP_FEET) && !lfhasflag(lf, F_CAREFULMOVE) && !isairborne(lf, NULL)) {
|
||||
object_t *boots;
|
||||
// has boots on?
|
||||
boots = getequippedob(lf->pack, BP_FEET);
|
||||
boots = getouterequippedob(lf, BP_FEET);
|
||||
if (!boots) {
|
||||
// take damage
|
||||
getobname(o, obname, 1);
|
||||
|
@ -2862,6 +2863,11 @@ void swapplaces(lifeform_t *lf1, lifeform_t *lf2, int changedir1, int changedir2
|
|||
}
|
||||
setlosdirty(lf1);
|
||||
setlosdirty(lf2);
|
||||
|
||||
// ie. asleep, meditating or unconscious
|
||||
if (lfhasflag(lf2, F_ASLEEP)) {
|
||||
stir(lf2, SV_TALK, 1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// teleport somewhere, along with puffs of smoke etc
|
||||
|
@ -3061,7 +3067,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
|||
*/
|
||||
|
||||
// warn before moving onto dangerous cells
|
||||
if (onpurpose && isplayer(lf) && !lfhasflag(lf, F_CAREFULMOVE) && !rndmove) {
|
||||
if (onpurpose && isplayer(lf) && !lfhasflag(lf, F_CAREFULMOVE) && !rndmove && !lfhasflag(lf, F_RAGE)) {
|
||||
char ques[BUFLEN];
|
||||
char ch;
|
||||
if (cell && celldangerous(lf, cell, B_TRUE, &errcode)) {
|
||||
|
|
9
nexus.c
9
nexus.c
|
@ -810,9 +810,12 @@ void checkdeath(void) {
|
|||
removedeadobs(lf->pack);
|
||||
// check for death
|
||||
if (lf->hp <= 0) {
|
||||
// die!
|
||||
die(lf);
|
||||
continue;
|
||||
if (hasactivespell(lf, OT_S_DELAYDEATH) && (lf->hp > -15)) {
|
||||
} else {
|
||||
// die!
|
||||
die(lf);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
30
objects.c
30
objects.c
|
@ -7430,6 +7430,13 @@ object_t *hasequippedobid(obpile_t *op, enum OBTYPE oid) {
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
object_t *hasequippedobidon(obpile_t *op, enum OBTYPE oid, enum BODYPART bp) {
|
||||
object_t *o;
|
||||
for (o = op->first ; o ; o = o->next) {
|
||||
if ((o->type->id == oid) && isequippedon(o, bp)) return o;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
object_t *hasknownob(obpile_t *op, enum OBTYPE oid) {
|
||||
object_t *o;
|
||||
|
@ -12818,6 +12825,15 @@ int readsomething(lifeform_t *lf, object_t *o) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_SILENCED)) {
|
||||
if (o->type->obclass->id != OC_BOOK) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You are unable to make a sound!");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(triedonbuf, "");
|
||||
|
||||
getobname(o, obname, 1);
|
||||
|
@ -14179,7 +14195,7 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce, lif
|
|||
|
||||
// now use the REAL name
|
||||
real_getobname(o, obname, o->amt, B_PREMODS, B_NOCONDITION, B_NOBLINDADJUST, B_NOBLESSINGS, B_NOUSED, B_SHOWALL);
|
||||
losehp_real(owner, howmuch , damtype, NULL, obname, B_DAMADJUST, o, B_NORETALIATE, NULL, B_DAMEFFECTS, f ? f->val[0] : BP_NONE);
|
||||
losehp_real(owner, howmuch , damtype, NULL, obname, B_DAMADJUST, o, B_NORETALIATE, NULL, B_DAMEFFECTS, f ? f->val[0] : BP_NONE, B_NOCRIT);
|
||||
if (isdead(owner)) {
|
||||
return howmuch;
|
||||
}
|
||||
|
@ -15009,6 +15025,16 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
|
|||
youhit = B_FALSE;
|
||||
myroll = rnd(1,100);
|
||||
|
||||
// target has 'nudge missiles' spell? penalty, and the missile
|
||||
// gets slightly slowed.
|
||||
if (target && hasactivespell(target, OT_S_SLOWMISSILES)) {
|
||||
myroll += 10;
|
||||
if (speed > 1) speed--;
|
||||
}
|
||||
|
||||
// easier to hit with faster projectiles.
|
||||
myroll -= (speed*2);
|
||||
|
||||
// blessed projectile vs undead? 20% bonus.
|
||||
if (isblessed(o) && isundead(target)) {
|
||||
myroll -= 20;
|
||||
|
@ -15261,7 +15287,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
|
|||
whogetsxp = thrower;
|
||||
}
|
||||
losehp_real(target, dam, DT_PROJECTILE, whogetsxp, damstring, B_DAMADJUST, o,
|
||||
B_RETALIATE, NULL, B_DAMEFFECTS, BP_NONE);
|
||||
B_RETALIATE, NULL, B_DAMEFFECTS, BP_NONE, B_NOCRIT);
|
||||
}
|
||||
|
||||
if (reduceamt && (speed >= 3)) {
|
||||
|
|
|
@ -167,6 +167,7 @@ char *gettopobname(cell_t *c, char *retbuf);
|
|||
enum BODYPART getweildloc(object_t *o, lifeform_t *lf, enum BODYPART *otherloc, int *twohanded);
|
||||
int hasedibleob(obpile_t *op);
|
||||
object_t *hasequippedobid(obpile_t *op, enum OBTYPE oid);
|
||||
object_t *hasequippedobidon(obpile_t *op, enum OBTYPE oid, enum BODYPART bp);
|
||||
object_t *hasknownob(obpile_t *op, enum OBTYPE oid);
|
||||
object_t *hasob(obpile_t *op, enum OBTYPE oid);
|
||||
object_t *hasobletter(obpile_t *op, char letter);
|
||||
|
|
270
spell.c
270
spell.c
|
@ -826,6 +826,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
case E_LFINWAY: msg("Something is in the way!"); break;
|
||||
case E_SWIMMING: msg("You can't climb while swimming!"); break;
|
||||
case E_TOOHEAVY: msg("Your load is too heavy to climb with!"); break;
|
||||
case E_NOABIL: msg("You cannot climb!"); break;
|
||||
default: msg("For some reason, you can't climb."); break;
|
||||
}
|
||||
}
|
||||
|
@ -2206,6 +2207,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (f) killflag(f);
|
||||
} else if (abilid == OT_A_SONICBOLT) {
|
||||
int volume,nwalls;
|
||||
if (lfhasflag(user, F_SILENCED)) {
|
||||
if (isplayer(user)) msg("You are unable to make a sound!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (!validatespellcell(user, &targcell,TT_MONSTER, abilid, power, B_FALSE)) return B_TRUE;
|
||||
target = targcell->lf;
|
||||
|
@ -3668,6 +3673,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
practice(user, SK_THIEVERY, 1);
|
||||
}
|
||||
} else if (abilid == OT_A_WARCRY) {
|
||||
if (lfhasflag(user, F_SILENCED)) {
|
||||
if (isplayer(user)) msg("You are unable to make a sound!");
|
||||
return B_TRUE;
|
||||
}
|
||||
// announce
|
||||
if (isplayer(user)) {
|
||||
msg("You shout a blood-curdling war cry!");
|
||||
|
@ -3965,6 +3974,43 @@ void addbuildchoice(prompt_t *p, lifeform_t *lf, enum OBTYPE oid, char *ch) {
|
|||
}
|
||||
|
||||
|
||||
// returns true if you can't charm them.
|
||||
int checkcharm(lifeform_t *caster, lifeform_t *target) {
|
||||
char targetname[BUFLEN];
|
||||
getlfname(target, targetname);
|
||||
// if the target is of a different raceclass, you usually
|
||||
// can't charm them.
|
||||
if (getraceclass(target) != getraceclass(caster)) {
|
||||
int willfail = B_FALSE;
|
||||
switch (getraceclass(target)) {
|
||||
case RC_DEMON:
|
||||
case RC_DRAGON:
|
||||
case RC_GOD:
|
||||
case RC_SLIME:
|
||||
case RC_MAGIC:
|
||||
case RC_PLANT:
|
||||
willfail = B_TRUE;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
if (willfail) {
|
||||
if (isplayer(caster)) {
|
||||
msg("%s%s mind is too alien for you to charm.",targetname,getpossessive(targetname));
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ischarmable(target)) {
|
||||
if (isplayer(caster)) {
|
||||
err_nocharm(reason, targetname);
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
// ok
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// returns TRUE on error
|
||||
int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer, int frompot, object_t *fromob) {
|
||||
char buf[BUFLEN];
|
||||
|
@ -5473,60 +5519,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
getlfname(target, targetname);
|
||||
|
||||
// if the target is of a different raceclass, you usually
|
||||
// can't charm them.
|
||||
if (getraceclass(target) != getraceclass(caster)) {
|
||||
int willfail = B_FALSE;
|
||||
switch (getraceclass(target)) {
|
||||
case RC_DEMON:
|
||||
case RC_DRAGON:
|
||||
case RC_GOD:
|
||||
case RC_SLIME:
|
||||
case RC_MAGIC:
|
||||
case RC_PLANT:
|
||||
willfail = B_TRUE;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
if (willfail) {
|
||||
if (isplayer(caster)) {
|
||||
msg("%s%s mind is too alien for you to charm.",targetname,getpossessive(targetname));
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
if (checkcharm(caster, target)) return B_FALSE;
|
||||
|
||||
if (!ischarmable(target)) {
|
||||
if (isplayer(caster)) {
|
||||
switch (reason) {
|
||||
case E_DRUNK:
|
||||
msg("%s%s mind is too alcohol-impaired for you to charm.",targetname,getpossessive(targetname));
|
||||
break;
|
||||
case E_LOWIQ:
|
||||
msg("%s%s intellect is too simple for you to charm.",targetname,getpossessive(targetname));
|
||||
break;
|
||||
case E_UNDEAD:
|
||||
msg("The undead are immune to charming.");
|
||||
break;
|
||||
case E_ROBOT:
|
||||
msg("Robots are immune to charming.");
|
||||
break;
|
||||
case E_ALREADYUSING:
|
||||
msg("%s is already charmed by another!", targetname);
|
||||
break;
|
||||
default:
|
||||
msg("You cannot charm %s.", targetname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (getallegiance(caster) == AL_PEACEFUL) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
if (ispetof(target, caster)) {
|
||||
if ((getallegiance(target) == AL_PEACEFUL) || ispetof(target, caster)) {
|
||||
if (isplayer(caster)) {
|
||||
msg("%s is already allied with you!",targetname);
|
||||
}
|
||||
|
@ -5575,31 +5570,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (!ischarmable(target)) {
|
||||
if (isplayer(caster)) {
|
||||
switch (reason) {
|
||||
case E_DRUNK:
|
||||
msg("%s%s mind is too alcohol-impaired for you to charm.",targetname,getpossessive(targetname));
|
||||
break;
|
||||
case E_LOWIQ:
|
||||
msg("%s%s intellect is too simple for you to charm.",targetname,getpossessive(targetname));
|
||||
break;
|
||||
case E_UNDEAD:
|
||||
msg("The undead are immune to charming.");
|
||||
break;
|
||||
case E_ROBOT:
|
||||
msg("Robots are immune to charming.");
|
||||
break;
|
||||
case E_ALREADYUSING:
|
||||
msg("%s is already charmed by another!", targetname);
|
||||
break;
|
||||
default:
|
||||
msg("You cannot charm %s.", targetname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
if (checkcharm(caster, target)) return B_FALSE;
|
||||
|
||||
if (getallegiance(caster) == AL_PEACEFUL) {
|
||||
fizzle(caster);
|
||||
|
@ -6257,6 +6228,15 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (spellid == OT_S_DELAYDEATH) {
|
||||
if (!target) {
|
||||
target = caster;
|
||||
}
|
||||
if (isplayer(target)) {
|
||||
msg("^gYou bend your psionic will towards defying death!");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
statdirty = B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_DETECTAURA) {
|
||||
if (isplayer(caster)) {
|
||||
object_t *o;
|
||||
|
@ -8704,6 +8684,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_MINDSHIELD) {
|
||||
flag_t *f;
|
||||
f = addtempflag(caster->flags, F_MINDSHIELD, B_TRUE, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_MINDWHIP) {
|
||||
target = targcell->lf;
|
||||
if (!target) {
|
||||
|
@ -8816,6 +8800,14 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
f = addtempflag(caster->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_SLOWMISSILES) {
|
||||
if (!target) {
|
||||
target = caster;
|
||||
}
|
||||
if (isplayer(target)) {
|
||||
msg("^gYou attune your mind to deflect incoming projectiles.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_NULLIFY) {
|
||||
flag_t *retflag[MAXCANDIDATES],*poss[MAXCANDIDATES],*f;
|
||||
int nretflags,i,ndone = 0,nposs;
|
||||
|
@ -11295,6 +11287,28 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
msg("^%c%s%s body seems to shimmer and bend!", getlfcol(caster, CC_GOOD),
|
||||
castername, getpossessive(castername));
|
||||
}
|
||||
} else if (spellid == OT_S_REMOTEKO) {
|
||||
char targetname[BUFLEN];
|
||||
|
||||
target = targcell->lf;
|
||||
|
||||
if (!target) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
getlfname(target, targetname);
|
||||
|
||||
if (checkcharm(caster, target)) return B_FALSE;
|
||||
|
||||
if (spellresisted(target, caster, spellid, power, seenbyplayer, B_TRUE)) {
|
||||
// they get angry!
|
||||
if (!isplayer(target) && cansee(target, caster)) {
|
||||
fightback(target, caster);
|
||||
}
|
||||
} else {
|
||||
// ko !
|
||||
loseconsciousness(target, rnd(50,100), caster);
|
||||
}
|
||||
} else if (spellid == OT_S_REPELINSECTS) {
|
||||
// just announce
|
||||
if (isplayer(caster)) {
|
||||
|
@ -11702,6 +11716,35 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_SILENCE) {
|
||||
int howlong = 30;
|
||||
target = targcell->lf;
|
||||
|
||||
if (!target || hasflag(target->flags, F_SILENCED)) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (spellresisted(target, caster, spellid, power, seenbyplayer, B_FALSE)) {
|
||||
if (!isdeaf(player)) {
|
||||
if (isplayer(target)) {
|
||||
msg("Noise around you sound softer for a moment.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else if (haslos(player, target->cell)) {
|
||||
getlfname(target, buf);
|
||||
msg("Noises around %s sound softer for a moment.", buf);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
howlong = rnd(20,30) + power*2;
|
||||
|
||||
addtempflag(target->flags, F_SILENCED, NA, NA, NA, NULL, howlong);
|
||||
if (isplayer(target) || haslos(player, target->cell)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_SIXTHSENSE) {
|
||||
flag_t *f;
|
||||
if (!target) target = caster;
|
||||
|
@ -11859,6 +11902,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
int howlong = 15;
|
||||
target = targcell->lf;
|
||||
|
||||
if (!target) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (spellresisted(target, caster, spellid, power, seenbyplayer, B_FALSE)) {
|
||||
if (isplayer(target)) {
|
||||
msg("You feel momentarily slower.");
|
||||
|
@ -12063,6 +12111,64 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_SOULLINK) {
|
||||
lifeform_t *targ2 = NULL;
|
||||
char buf[BUFLEN],tname[BUFLEN],t2name[BUFLEN];
|
||||
if (caster && !isplayer(caster)) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
if (!target) {
|
||||
target = targcell->lf;
|
||||
}
|
||||
if (!target || (target == caster)) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
real_getlfnamea(target, tname, NULL, B_SHOWALL, B_REALRACE);
|
||||
|
||||
if (power < 3) {
|
||||
// link caster to target
|
||||
targ2 = caster;
|
||||
} else {
|
||||
cell_t *where;
|
||||
char smallprompt[BUFLEN];
|
||||
// link target to target2
|
||||
// ask for a target cell
|
||||
snprintf(buf, BUFLEN, "Who will you soul-link %s to?", tname);
|
||||
snprintf(smallprompt, BUFLEN, "soul link:%s->", tname);
|
||||
where = askcoords(buf, smallprompt, TT_MONSTER, caster, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (where && where->lf && cansee(caster, where->lf)) {
|
||||
targ2 = where->lf;
|
||||
} else {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (targ2 == target) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
real_getlfnamea(targ2, t2name, NULL, B_SHOWALL, B_REALRACE);
|
||||
|
||||
if (hasflag(target->flags, F_SOULLINK) || hasflag(targ2->flags, F_SOULLINK)) {
|
||||
msg("^bAn existing soul link prevents your spell from working!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// link caster to target
|
||||
sprintf(buf, "%s%s soul link spell", castername, getpossessive(castername));
|
||||
addflag(target->flags, F_SOULLINK, targ2->id, NA, NA, buf);
|
||||
addflag(targ2->flags, F_SOULLINK, target->id, NA, NA, buf);
|
||||
|
||||
// soullink flag is only announce for the player, so oif we linked to someone else,
|
||||
// provide some feedback.
|
||||
if (targ2 != player) {
|
||||
msg("^gYou establish a soul link between %s and %s!",tname,t2name);
|
||||
}
|
||||
} else if (spellid == OT_S_SPARK) {
|
||||
object_t *o,*nexto;
|
||||
int donesomething = B_FALSE;
|
||||
|
@ -15206,8 +15312,12 @@ int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power
|
|||
bonus += 8;
|
||||
}
|
||||
|
||||
if (spellisfromschool(spellid, SS_MENTAL) && lfhasflag(target, F_MINDSHIELD)) {
|
||||
resisted = B_TRUE;
|
||||
if (spellisfromschool(spellid, SS_MENTAL)) {
|
||||
if (lfhasflag(target, F_MINDSHIELD)) {
|
||||
resisted = B_TRUE;
|
||||
} else {
|
||||
resisted = skillcheck(target, SC_IQ, getmrdiff(spellid,power), bonus);
|
||||
}
|
||||
} else {
|
||||
resisted = skillcheck(target, SC_RESISTMAG, getmrdiff(spellid,power), bonus);
|
||||
}
|
||||
|
|
1
spell.h
1
spell.h
|
@ -4,6 +4,7 @@
|
|||
|
||||
int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifeform_t *target, flag_t *cwflag);
|
||||
void addbuildchoice(prompt_t *p, lifeform_t *lf, enum OBTYPE oid, char *ch);
|
||||
int checkcharm(lifeform_t *caster, lifeform_t *target);
|
||||
int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer, int frompot, object_t *fromob);
|
||||
objecttype_t *findspelln(char *buf);
|
||||
enum SPELLSCHOOL findspellschoolbyname(char *buf);
|
||||
|
|
32
text.c
32
text.c
|
@ -7,6 +7,7 @@
|
|||
#include "attack.h"
|
||||
#include "defs.h"
|
||||
#include "flag.h"
|
||||
#include "io.h"
|
||||
#include "lf.h"
|
||||
#include "map.h"
|
||||
#include "move.h"
|
||||
|
@ -485,6 +486,29 @@ char *dicetotext(int ndice, int nsides, int bonus, int *min, int *max, char *dic
|
|||
return dicebuf;
|
||||
}
|
||||
|
||||
void err_nocharm(enum ERROR reason, char *targetname) {
|
||||
switch (reason) {
|
||||
case E_DRUNK:
|
||||
msg("%s%s mind is too alcohol-impaired for you to charm.",targetname,getpossessive(targetname));
|
||||
break;
|
||||
case E_LOWIQ:
|
||||
msg("%s%s intellect is too simple for you to charm.",targetname,getpossessive(targetname));
|
||||
break;
|
||||
case E_UNDEAD:
|
||||
msg("The undead are immune to charming.");
|
||||
break;
|
||||
case E_ROBOT:
|
||||
msg("Robots are immune to charming.");
|
||||
break;
|
||||
case E_ALREADYUSING:
|
||||
msg("%s is already charmed by another!", targetname);
|
||||
break;
|
||||
default:
|
||||
msg("You cannot charm %s.", targetname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int flip(int ch) {
|
||||
switch (ch) {
|
||||
case 'a': return 0x0250;
|
||||
|
@ -1278,14 +1302,14 @@ char *getflagsourcetext(flag_t *f, char *buf) {
|
|||
case FROMOBEQUIP:
|
||||
case FROMOBHOLD:
|
||||
case FROMOBACTIVATE:
|
||||
if (f->lifetime == FROMOBEQUIP) strcpy(action, "equipping");
|
||||
else if (f->lifetime == FROMOBEQUIP) strcpy(action, "holding");
|
||||
else strcpy(action, "activating");
|
||||
if (f->lifetime == FROMOBEQUIP) strcpy(action, "equipped");
|
||||
else if (f->lifetime == FROMOBEQUIP) strcpy(action, "held");
|
||||
else strcpy(action, "activated");
|
||||
|
||||
if (f->pile->ob) {
|
||||
getobname(f->pile->ob, obname, f->pile->ob->amt);
|
||||
} else {
|
||||
strcpy(obname, "an object");
|
||||
strcpy(obname, "object");
|
||||
}
|
||||
sprintf(buf," (from %s %s)", action, obname);
|
||||
break;
|
||||
|
|
1
text.h
1
text.h
|
@ -8,6 +8,7 @@ char *capitaliseall(char *text);
|
|||
enum COLOUR chartocol(char ch);
|
||||
char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackername, char *victimname, char *victimbpname, object_t *wep, enum DAMTYPE damtype, int dam, int maxhp, int damidx, int critical, int backstab, int fatal, int isunarmed, char *retbuf);
|
||||
char *dicetotext(int ndice, int nsides, int bonus, int *min, int *max, char *dicebuf, char *minmaxbuf);
|
||||
void err_nocharm(enum ERROR reason, char *targetname);
|
||||
int flip(int ch);
|
||||
char *getaccuracyname(int accpct);
|
||||
int getaccuracymodnum(int accmodpct);
|
||||
|
|
Loading…
Reference in New Issue