Paladin changes

- [+] average charisma + speech ?
- [+] lose all/most of  the warrior abilities
- [+] can only voluntarily wear known blessed items (add this to the
      description)
    - [+] (glorana must give holy water when you pray)
- [+] move most post-damage stuff into losehpeffects()
    - [+] pass "int doextraeffects" to losehp_real().
    - [+] during melee attack, delay this.
    - [+] otehrwise, it happens in losehp!
- [+] add constants for real_getobname params
- [+] add constants for real_losehp params
- [+] issue - should i be able to say 'have mercy' when i'm not
      adjacent?
    - [+] probably not!
- [+] don't sell credit cards in shops.
- [+] make crowns, velvet robes, wizard hats more likely to have brands
- [+] don't say "your feet get wet" when walking from water to water
- [+] fix bug in real_warnabout() where multiple warning_t instances
      were being made for the same text.
This commit is contained in:
Rob Pearce 2012-02-25 23:42:48 +00:00
parent 4808d2c9df
commit ff13f25bb9
13 changed files with 450 additions and 303 deletions

273
attack.c
View File

@ -306,7 +306,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
!lfhasflag(lf, F_RAGE)) {
char obname[BUFLEN],wepname[BUFLEN],buf[BUFLEN];
char ch;
real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
real_getobname(o, obname, o->amt, B_NOPREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOSHOWALL);
getobname(priwep, wepname, priwep->amt);
snprintf(buf, BUFLEN, "Attacking %s might damage your %s. Proceed?", obname, noprefix(wepname));
ch = askchar(buf, "yn","n", B_TRUE, B_FALSE);
@ -593,6 +593,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
int weppassthrough = B_FALSE;
int firstisbackstab = B_FALSE;
int blocked = B_FALSE,dodged = B_FALSE;
flag_t *magicarm = NULL;
int hit = B_FALSE;
int critical = 0;
char wepname[BUFLEN];
@ -750,7 +751,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
armour = getequippedob(victim->pack, critpos);
if (armour) {
char armname[BUFLEN];
real_getobname(armour, armname, 1, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
real_getobname(armour, armname, 1, B_NOPREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOSHOWALL);
sprintf(noun, "%s", noprefix(armname));
} else {
sprintf(noun, "%s", getbodypartname(victim, critpos));
@ -911,20 +912,19 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
if (ndam > 0) {
flag_t *f;
for (i = 0; i < ndam; i++) {
int reduceamt = 0;
int damreducedbyarmour = 0;
int backstab = B_FALSE;
int prebleed = B_FALSE;
flag_t *rust;
if (firstisbackstab && (i == 0)) backstab = B_TRUE;
//dblog("initial dam[%d] = %d",i,dam[i]);
// slightly more damage for heavy blows
if (lfhasflag(lf, F_HEAVYBLOW) || hasflag(wep->flags, F_HEAVYBLOW)) {
dam[i] = (int)pctof(110,dam[i]);
//dblog("heavy blow makes dam[%d] = %d",i,dam[i]);
}
// modify for rust
// modify for rusted weapon.
rust = hasflag(wep->flags, F_RUSTED);
if (rust) {
switch (damtype[i]) {
@ -943,13 +943,13 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
}
}
// blocked by defender's shield?
if (i == 0) {
int difficulty;
char attackname[BUFLEN];
if (lfhasflag(lf, F_HOLYAURA) && isvulnto(victim->flags, DT_HOLY, B_FALSE)) {
damtype[i] = DT_HOLY;
}
// blocked by defender's shield?
sprintf(attackname, "%s%s attack", attackername, getpossessive(attackername));
//difficulty = 20 + ((gethitdice(lf) - gethitdice(victim)) );
//difficulty = 20 + gethitdice(lf);
@ -960,105 +960,130 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
}
}
// modify based on resistances
// modify damage based on defender's resistances
adjustdamlf(victim, &dam[i], damtype[i]);
//dblog("adjusted for lf to dam[%d] = %d",i,dam[i]);
if (lfhasflag(lf, F_PHANTASM)) dam[0] = 0;
// can't do damage to phantasms
if (lfhasflag(lf, F_PHANTASM)) dam[i] = 0;
// armour doesn't reduce damage for backstabs or critical hits.
// BUT in the case of a critical hit, the armour might get
// damaged during criticalhit()
if ((dam[i] > 0) && !backstab && !critical && ismeleedam(damtype[i])) {
// modify for defender's armour
reduceamt = getarmourdamreduction(victim, wep, dam[i], damtype[i]);
applyarmourdamreduction(victim, wep, reduceamt, &dam[i], damtype[i]);
//dblog("reduced by armour to dam[%d] = %d",i,dam[i]);
// check for protective spells like heavenly armour
if (dam[i] > 0) {
if (isphysicaldam(damtype[i])) {
getflags(victim->flags, retflag, &nretflags, F_HEAVENARM, F_MAGICARMOUR, F_NONE);
if (nretflags) {
magicarm = retflag[0];
}
}
}
// if damage has dropped to zero, it's not a critical hit anymore.
if (dam[i] <= 0) {
critical = B_FALSE;
critpos = BP_NONE;
}
if (lfhasflag(lf, F_QUIVERINGPALM)) {
// make sure damage isn't fatal
if (!magicarm) {
// 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
damreducedbyarmour = getarmourdamreduction(victim, wep, dam[i], damtype[i]);
applyarmourdamreduction(victim, wep, damreducedbyarmour, &dam[i], damtype[i]);
}
// if damage has been reduced zero, it's not a critical hit anymore.
if (dam[i] <= 0) {
critical = B_FALSE;
critpos = BP_NONE;
}
// make sure quivering palm damage isn't fatal
// becquse we want them to explode
if (lfhasflag(lf, F_QUIVERINGPALM)) {
if (dam[i] >= victim->hp) {
dam[i] = victim->hp - 1;
}
}
// at this point, is the damage enough to be fatal? we need to know so we
// can determine whether monsters will use feign death or dodge abilities.
// NOTE: whether or not the attack is fatal is re-calculated again
// later on after damage is applied to ensure that the correct
// attack string is displayed ("you hit xxx" vs "you kill xxx").
if (dam[i] >= victim->hp) {
dam[i] = victim->hp - 1;
fatal = B_TRUE;
}
}
// at this point, will the damage be fatal? we need to know so we
// can determine whether monsters will use feign death or dodge abilities.
// NOTE: whether or not the attack is fatal is re-calculated again
// later on after damage is applied to ensure that the correct
// attack string is displayed ("you hit xxx" vs "you kill xxx").
if (dam[i] >= victim->hp) {
fatal = B_TRUE;
}
// another check for phantasms
if (lfhasflag(lf, F_PHANTASM)) dam[0] = 0;
if (lfhasflag(lf, F_PHANTASM)) dam[0] = 0;
// monsters feigning death?
if (lfhasflag(victim, F_FEIGNINGDEATH)) {
killflagsofid(victim->flags, F_FEIGNINGDEATH);
} else if (!fatal && !isplayer(victim) && cancast(victim, OT_A_FEIGNDEATH, NULL)) {
if (onein(2) || islowhp(victim)) {
// do it!
useability(victim, OT_A_FEIGNDEATH, lf, lf->cell);
feigneddeath = B_TRUE;
// is the victim feigning death? if so, stop now.
if (lfhasflag(victim, F_FEIGNINGDEATH)) {
killflagsofid(victim->flags, F_FEIGNINGDEATH);
} else if (!fatal && !isplayer(victim) && cancast(victim, OT_A_FEIGNDEATH, NULL)) {
// monsters might pretend to be dead.
if (onein(2) || islowhp(victim)) {
// do it!
useability(victim, OT_A_FEIGNDEATH, lf, lf->cell);
feigneddeath = B_TRUE;
}
}
}
if (fatal && !feigneddeath && lfhasflag(victim, F_DODGES) && cansee(victim, lf) && hasfreeaction(victim)) {
cell_t *adj;
int candodge = B_FALSE;
// did the defender use the Reflexive Dodging skill to dodge the attack?
if (fatal && !feigneddeath && lfhasflag(victim, F_DODGES) && cansee(victim, lf) && hasfreeaction(victim)) {
cell_t *adj;
int candodge = B_FALSE;
if (isplayer(victim)) {
if (getstamina(victim)) {
if (isplayer(victim)) {
if (getstamina(victim)) {
candodge = B_TRUE;
}
} else if (onein(3)) {
candodge = B_TRUE;
}
} else if (onein(3)) {
candodge = B_TRUE;
}
if (candodge) {
adj = getrandomadjcell(victim->cell, WE_WALKABLE, B_NOEXPAND);
if (adj) {
flag_t *f;
if (isplayer(victim) || cansee(player, victim)) {
if (cansee(player, lf)) {
msg("^w%s dodge%s %s%s attack!",victimname,isplayer(victim) ? "" : "s",
attackername, getpossessive(attackername));
} else {
msg("^w%s dodge%s an attack!",victimname,isplayer(victim) ? "" : "s");
if (candodge) {
adj = getrandomadjcell(victim->cell, WE_WALKABLE, B_NOEXPAND);
if (adj) {
flag_t *f;
if (isplayer(victim) || cansee(player, victim)) {
if (cansee(player, lf)) {
msg("^w%s dodge%s %s%s attack!",victimname,isplayer(victim) ? "" : "s",
attackername, getpossessive(attackername));
} else {
msg("^w%s dodge%s an attack!",victimname,isplayer(victim) ? "" : "s");
}
} else if (isplayer(lf)) {
msg("You attack something, but it dodges!");
} else if (cansee(player, lf)) {
msg("%s attacks something, but it dodges!", attackername);
}
} else if (isplayer(lf)) {
msg("You attack something, but it dodges!");
} else if (cansee(player, lf)) {
msg("%s attacks something, but it dodges!", attackername);
}
f = addflag(victim->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
moveto(victim, adj, B_FALSE, B_FALSE);
killflag(f);
f = addflag(victim->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
moveto(victim, adj, B_FALSE, B_FALSE);
killflag(f);
if (isplayer(victim)) {
setstamina(victim, 0);
if (isplayer(victim)) {
setstamina(victim, 0);
}
// remember that we dodged, to avoid otehr attack effects like
// heavy blow, etc.
dodged = B_TRUE;
// stop processing now.
break;
}
// remember that we dodged, to avoid otehr attack effects like
// heavy blow, etc.
dodged = B_TRUE;
// stop processing now.
break;
}
}
}
if (willheal) {
} // end if !magicarm
prebleed = isbleeding(victim);
// Now handle the actual hit.
if (magicarm) {
// if you have a forcefield/magic armour, you can never be killed until
// it vanishes.
fatal = B_FALSE;
} else if (willheal) {
// some magical weapons will heal instead of doing damage
if (cansee(player, victim)) {
flag_t *f;
if (areallies(player, victim)) {
@ -1072,12 +1097,13 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
}
}
gainhp(victim, dam[i]);
reduceamt = 0;
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);
reduceamt = 0;
losehp_real(victim, victim->hp, DT_EXPLOSIVE, lf, "a quivering palm strike", B_FALSE, NULL, B_FALSE, NULL, B_FALSE);
damreducedbyarmour = 0;
} else {
// actually deal the melee damage!
char attackername2[BUFLEN];
real_getlfname(lf, attackername2, B_FALSE, B_TRUE);
if (lf->race->raceclass->id == RC_GOD) {
@ -1090,11 +1116,11 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
}
strcat(attackername2, gf->text);
}
// victim loses hp
// don't adjust damage - we've already done that
// get name of weapon/attacker, for "killedby" text
if (wep && !isunarmed) {
char wepname[BUFLEN];
real_getobname(wep, wepname, 1, B_TRUE, B_FALSE, B_FALSE, B_TRUE, B_FALSE);
real_getobname(wep, wepname, 1, B_PREMODS, B_NOCONDITION, B_NOBLINDADJUST, B_BLESSINGS, B_NOSHOWALL);
/*
snprintf(buf, BUFLEN, "%s^%s %s",attackername2,
(lf == victim) ? "using" : "weilding",
@ -1105,7 +1131,18 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} else {
strcpy(buf, attackername2);
}
losehp_real(victim, dam[i], damtype[i], lf, buf, B_FALSE, wep, B_FALSE, &waskod);
// apply damage to victim
// note: we delay extra effects from the damage so that we get a chance to first annoiunce
// the hit.
//
// otherwise the messages are in the wrong order, eg:
// "the fire sets you alight!"
// "xxx hits you with a flaming sword."
// 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);
}
// was it fatal ? override previously calculated value.
if ((victim->hp <= 0) && !waskod) {
@ -1113,7 +1150,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} else {
fatal = B_FALSE;
}
// announce it
// announce the hit
if (!feigneddeath) {
if (isplayer(lf) || isplayer(victim) || cansee(player, lf) || cansee(player, victim)) {
construct_hit_string(lf, victim, attackername, victimname, victimbpname, wep, damtype[i], dam[i], victim->maxhp, i, backstab, critical, fatal, isunarmed, buf);
@ -1121,8 +1158,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
warn("%s", buf);
}
}
//if (!isplayer(lf) && !isplayer(victim)) {
//}
if (fatal) {
if (strstr(buf, "behead")) {
// we'll need to place the severed head object
@ -1135,20 +1170,53 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
}
}
}
} // end if !feigneddeath
// 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("^%c%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], damtype[i], lf);
// train armour
practice(victim, SK_ARMOUR, 1);
}
}
// make noise
noise(lf->cell, lf, NC_FIGHTING, SV_SHOUT, "fighting.", NULL);
// victim's armour loses hp
if (reduceamt && !critical) {
applyarmourdamage(victim, wep, dam[i], damtype[i], lf);
// train armour
practice(victim, SK_ARMOUR, 1);
}
if (backstab) {
practice(lf, SK_BACKSTAB, 1);
}
// now handle the extra hp loss effects which we postponed above.
losehpeffects(victim, dam[i], damtype[i], lf, wep, B_NORETALIATE, waskod, &waskod, prebleed);
if (fatal || waskod) break; // stop now!
} // end foreach damtype
@ -1186,10 +1254,10 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
char lfname[BUFLEN];
dam = rolldie(f->val[0], f->val[1]) + f->val[2];
real_getlfname(lf, lfname, B_FALSE, B_FALSE);
losehp_real(victim, dam, DT_BITE, lf, lfname, B_FALSE, NULL, B_FALSE, NULL);
if (isplayer(victim) || cansee(player, victim)) {
msg("^%c%s bites %s!", isplayer(victim) ? 'b' : 'n', lfname, victimname);
}
losehp_real(victim, dam, DT_BITE, lf, lfname, B_FALSE, NULL, B_FALSE, NULL, B_TRUE);
}
}
@ -1212,10 +1280,10 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
if (nmatched >= f->val[2]) {
char damstring[BUFLEN];
snprintf(damstring, BUFLEN, "%s pack", lfname);
losehp_real(victim, f->val[0], f->val[1], lf, damstring, B_TRUE, NULL, B_FALSE, NULL);
if (isplayer(victim) || cansee(player, victim)) {
msg("^%c%s pack attacks %s!", isplayer(victim) ? 'b' : 'c', lfname, victimname);
}
losehp_real(victim, f->val[0], f->val[1], lf, damstring, B_TRUE, NULL, B_FALSE, NULL, B_TRUE);
}
}
@ -1282,7 +1350,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(f->text));
losehp_real(lf, rdam, f->val[2], victim, damstring, B_TRUE, NULL, B_TRUE, NULL);
losehp_real(lf, rdam, f->val[2], victim, damstring, B_TRUE, NULL, B_TRUE, NULL, B_TRUE);
}
}
}
@ -1709,7 +1777,7 @@ int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE da
char victimname[BUFLEN];
getlfname(victim, victimname);
// announce
real_getobname(shield[i], shname, 1, B_TRUE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
real_getobname(shield[i], shname, 1, B_PREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOSHOWALL);
if (isplayer(lf)) { // player is atatcking
msg("%s blocks %s with %s.", victimname, attackname, shname);
} else if (cansee(player, lf) || cansee(player, victim)) { // monster is attacking
@ -1922,7 +1990,6 @@ int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE d
reduceamt = rnd(min, max);
// special case
if (damtype == DT_PROJECTILE) {
o = getequippedob(lf->pack, BP_BODY);

13
data.c
View File

@ -157,12 +157,12 @@ void initjobs(void) {
// subjob definitions - keep these in alphabetical order
addsubjob(SJ_BATTLEMAGE, "Battlemage", "Unlike other warriors Battlemages are skilled in magic, but at the expense of the regular warrior abilities.", 'b');
addsubjob(SJ_FIREMAGE, "Firemage", "", 'f');
addsubjob(SJ_ICEMAGE, "Icemage", "", 'i');
addsubjob(SJ_FIREMAGE, "Firemage", "Firemages weild the destructive powers of fire to incinerate their enemies.", 'f');
addsubjob(SJ_ICEMAGE, "Icemage", "Icemages are masters over the powers of cold. Their magic is less direct damaging than that of their fire-based cousins, but can also be used for defence.", 'i');
addsubjob(SJ_NECROMANCER, "Necromancer", "", 'n');
addsubjob(SJ_PALADIN, "Paladin", "Paladins are holy warriors dedicated to the Goddess of Life. They have access to powerful healing magic, but this power is dependant upon their goddess' approval.", 'p');
addsubjob(SJ_PALADIN, "Paladin", "Paladins are holy warriors dedicated to the Goddess of Life. They gain powerful abilities and have access to healing magics, but these powers are dependant upon their goddess' approval. Paladins must take holy vows to only ever use battle equipiment which has first been blessed.", 'p');
addsubjob(SJ_SCOURGE, "Scourge", "Scourges have dedicated their life to ridding the world of magic. Strict training has granted them an innate immunity to magic, but this immunity also extends to beneficial effects.", 's');
addsubjob(SJ_AIRMAGE, "Skymage", "", 's');
addsubjob(SJ_AIRMAGE, "Skymage", "Initially the weakest of the mages, higher level Skymages become both extremely versatile and extremely power.", 's');
addsubjob(SJ_WILDMAGE, "Wizard", "", 'w');
// job definitions
@ -5779,6 +5779,8 @@ void initobjects(void) {
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 75, NA, NA, NULL);
addflag(lastot->flags, F_BRANDCHANCE, 20, NA, NA, NULL);
// armour - shoulders
@ -6000,6 +6002,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 33, NA, NA, NULL);
addflag(lastot->flags, F_BRANDCHANCE, 30, NA, NA, NULL);
addot(OT_HELMBONE, "bone helmet", "Scary-looking helmet made from the bones of an animal (?).", MT_BONE, 1, OC_ARMOUR, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL);
@ -6016,6 +6019,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pointy hat");
addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL);
addflag(lastot->flags, F_BRANDCHANCE, 15, NA, NA, NULL);
// armour - ears
addot(OT_EARPLUGS, "set of earplugs", "A pair of cloth plugs designed to give the wearer a peaceful night's sleep. ", MT_CLOTH, 0.01, OC_ARMOUR, SZ_SMALL);
@ -9908,6 +9912,7 @@ void initrace(void) {
addrace(R_SPRITEGRAVE, "grave sprite", 5, 'n', C_BLUE, MT_FLESH, RC_MAGIC, "A small magical creature made from corpse dust.");
setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_NOCORPSE, NA, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL);

Binary file not shown.

25
defs.h
View File

@ -142,6 +142,29 @@
#define B_BIG (-1)
// for losehp_real
#define B_DAMADJUST (-1)
#define B_NODAMADJUST (0)
#define B_RETALIATE (-1)
#define B_NORETALIATE (0)
#define B_DAMEFFECTS (-1)
#define B_NODAMEFFECTS (0)
// for real_getobname
#define B_PREMODS (-1)
#define B_NOPREMODS (0)
#define B_CONDITION (-1)
#define B_NOCONDITION (0)
#define B_BLINDADJUST (-1)
#define B_NOBLINDADJUST (0)
#define B_BLESSINGS (-1)
#define B_NOBLESSINGS (0)
#define B_SHOWALL (-1)
#define B_NOSHOWALL (0)
// Limits
// must be >= max # of spells/abilities AND
@ -2140,6 +2163,7 @@ enum FLAG {
F_BATTLESPOILS, // this obejct was dropped by a monster which the
// player killed, and has not yet been touched.
F_BEINGUSED, // this object is currently being used
F_BRANDCHANCE, // this object has v0% extra chance of being branded
F_DEAD, // object will be removed
F_ONEPERCELL, // only one of these objects can exist per cell
F_ONLYINROOM, // object nay only appear in rooms (not corridors)
@ -3408,6 +3432,7 @@ enum ERROR {
E_NOLOS,
E_NOLOF,
E_IMPOSSIBLE,
E_PALADIN,
E_NOTARGET,
E_NOAMMO,
E_GRAVBOOSTED,

20
god.c
View File

@ -1661,6 +1661,7 @@ void pleasegodmaybe(enum RACE rid, int amt) {
int prayto(lifeform_t *lf, lifeform_t *god) {
int piety,i,x,y;
char assisttext[BUFLEN];
enum PIETYLEV plev;
taketime(lf, getactspeed(lf));
@ -1702,7 +1703,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
// if we get here, piety is >= 100.
// you get some help...
plev = getpietylev(god->race->id, NULL, NULL);
switch (god->race->id) {
case R_GODBATTLE:
strcpy(assisttext, "Message received, soldier!");
@ -2018,8 +2019,8 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
dospelleffects(NULL, OT_S_SATEHUNGER, 10, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE);
donesomething = B_TRUE;
}
if (lf->mp < getmaxmp(lf)) {
gainmp(lf, getmaxmp(lf));
if (lf->mp < (getmaxmp(lf)/2)) {
gainmp(lf, getmaxmp(lf)/2);
donesomething = B_TRUE;
}
if (lfhasflag(lf, F_INJURY)) {
@ -2030,13 +2031,20 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
gainhp(lf, lf->maxhp);
donesomething = B_TRUE;
statdirty = B_TRUE;
}
if (isinbattle(lf, B_TRUE)) {
enum PIETYLEV plev;
plev = getpietylev(R_GODLIFE, NULL, NULL);
if (plev >= PL_INDIFFERENT) {
dospelleffects(NULL, OT_S_HEAVENARM, plev+1, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE);
donesomething = B_TRUE;
}
}
// will bless player's water if nothing else done.
if (!donesomething && (plev >= PL_PLEASED)) {
object_t *o;
for (o = player->pack->first ; o ; o = o->next) {
if ((o->type->id == OT_POT_WATER) && !isblessed(o)) {
blessob(o);
}
}
}
if (donesomething) {

44
io.c
View File

@ -780,7 +780,7 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
if (o) {
char obname[BUFLEN];
char buf2[BUFLEN];
real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
real_getobname(o, obname, o->amt, B_NOPREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOSHOWALL);
if (strlen(extrainfo)) strcat(extrainfo, ", ");
snprintf(buf2, BUFLEN, "stuck in %s",obname);
strcat(extrainfo, buf2);
@ -2569,7 +2569,7 @@ int announceobflaggain(object_t *o, flag_t *f) {
wantpremods = B_FALSE;
}
real_getobname(o, obname, o->amt, wantpremods, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
real_getobname(o, obname, o->amt, wantpremods, B_NOPREMODS, B_CONDITION, B_BLESSINGS, B_NOSHOWALL);
if (o->pile->owner) {
@ -2622,7 +2622,7 @@ void announceobflagloss(object_t *o, flag_t *f) {
if (!haslos(player, loc)) {
return;
}
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
real_getobname(o, obname, o->amt, B_PREMODS, B_NOCONDITION, B_BLINDADJUST, B_BLESSINGS, B_NOSHOWALL);
if (o->pile->owner) {
if (isplayer(o->pile->owner)) {
@ -3951,23 +3951,24 @@ void docomms(lifeform_t *lf) {
}
}
if (areenemies(player, lf)) {
addchoice(&prompt, 'm', "Have mercy!", NULL, NULL, NULL);
}
// if you are allies, use 'trade items' instead
if (isadjacent(lf->cell, player->cell) && !areallies(player,lf)) {
if (isgod(lf)) {
// may only donate the godstone
godstone = hasob(player->pack, getopposinggodstone(lf->race->id));
if (godstone) {
char buf[BUFLEN],obname[BUFLEN];
getobname(godstone, obname, 1);
sprintf(buf, "(offer %s)", obname);
addchoice(&prompt, 'd', buf, NULL, NULL, NULL);
if (isadjacent(lf->cell, player->cell)) {
if (areenemies(player, lf)) {
addchoice(&prompt, 'm', "Have mercy!", NULL, NULL, NULL);
}
// if yo are allies, use 'trade items' instead
if (!areallies(player, lf)) {
if (isgod(lf)) {
// may only donate the godstone
godstone = hasob(player->pack, getopposinggodstone(lf->race->id));
if (godstone) {
char buf[BUFLEN],obname[BUFLEN];
getobname(godstone, obname, 1);
sprintf(buf, "(offer %s)", obname);
addchoice(&prompt, 'd', buf, NULL, NULL, NULL);
}
} else {
addchoice(&prompt, 'd', "(donate an item)", NULL, NULL, NULL);
}
} else {
addchoice(&prompt, 'd', "(donate an item)", NULL, NULL, NULL);
}
}
@ -12921,8 +12922,10 @@ int real_warnabout(char *what, int lifetime, int doquestion) {
// have we already warned about this?
w = findwarning(what);
if (w) {
w->lifetime = DEF_WARNINGTIME;
// if so, just update the existing warning's lifetime
w->lifetime = lifetime;
ch = 'y';
return B_TRUE;
} else if (doquestion) {
char ques[BUFLEN];
sprintf(ques, "%s", what);
@ -12934,6 +12937,7 @@ int real_warnabout(char *what, int lifetime, int doquestion) {
ch = 'y';
}
if (ch == 'y') {
// accepted the warning. add it to the list.
addwarning(what, lifetime);
return B_TRUE;
}

281
lf.c
View File

@ -16,6 +16,7 @@
#include "move.h"
#include "nexus.h"
#include "objects.h"
#include "shops.h"
#include "spell.h"
#include "text.h"
@ -1291,6 +1292,13 @@ int canwear(lifeform_t *lf, object_t *o, enum BODYPART where) {
reason = E_IMPOSSIBLE;
return B_FALSE;
}
// paladin?
if (getsubjob(lf) == SJ_PALADIN) {
if (!isblessed(o) || !o->blessknown) {
reason = E_PALADIN;
return B_FALSE;
}
}
// injuries?
if ((where == BP_HANDS) && lfhasflagval(lf, F_INJURY, IJ_HANDSWOLLEN, NA, NA, NULL)) {
reason = E_INJURED;
@ -1398,6 +1406,14 @@ int canweild(lifeform_t *lf, object_t *o) {
return B_FALSE;
}
// paladin?
if (getsubjob(lf) == SJ_PALADIN) {
if (!isblessed(o) || !o->blessknown) {
reason = E_PALADIN;
return B_FALSE;
}
}
// too heavy?
if (o && lfhasflagval(lf, F_INJURY, IJ_SHOULDERDISLOCATED, NA, NA, NULL)) {
if (isheavyweapon(o)) {
@ -2055,7 +2071,7 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
}
addflag(lf->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
lf->hp = 0;
real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_TRUE);
getobnametruebase(o, obname, o->amt);
setlastdam(lf, obname);
setkillverb(lf, "Drowned");
} else {
@ -2069,7 +2085,7 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
msg("^%c%s is drowning!", getlfcol(lf, CC_VBAD), lfname);
didsomething = B_TRUE;
}
real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_TRUE);
getobnametruebase(o, obname, o->amt);
losehp(lf, damamt, DT_DIRECT, NULL, obname);
setlastdam(lf, obname);
setkillverb(lf, "Drowned");
@ -3745,8 +3761,9 @@ int eat(lifeform_t *lf, object_t *o) {
}
if (fid != F_NONE) {
// lose half your max hp!
losehp_real(lf, (lf->maxhp/2), DT_DIRECT, NULL, "the shock of mutation",
B_FALSE, o, B_FALSE, NULL);
losehp_real(lf, (lf->maxhp/2), DT_DIRECT, NULL,
"the shock of mutation",
B_NODAMADJUST, o, B_NORETALIATE, NULL, B_DAMEFFECTS);
if (isplayer(lf)) {
msg("^%cYou convulse in agony as your body mutates!",
getlfcol(lf, CC_BAD));
@ -7807,7 +7824,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
wep = getweapon(lf);
if (wep) {
char obname[BUFLEN];
real_getobname(wep, obname, 1, B_TRUE, B_FALSE, B_FALSE, B_FALSE, B_FALSE);
real_getobname(wep, obname, 1, B_PREMODS, B_NOCONDITION, B_NOBLINDADJUST, B_NOBLESSINGS, B_NOSHOWALL);
snprintf(buf, BUFLEN, "%s%s%s",the,descstring,noprefix(obname));
} else {
snprintf(buf, BUFLEN, "%s%s%s%s",the,descstring,lname,jobstring);
@ -9435,9 +9452,11 @@ void givesubjob(lifeform_t *lf, enum SUBJOB sj) {
killflagsofid(lf->flags, F_LEVABIL);
break;
case SJ_PALADIN:
// healing magic
// extra skills - healing magic & speech
giveskilllev(lf, SK_SS_LIFE, PR_NOVICE);
sb1 = addob(lf->pack, "spellbook of life magic");
giveskilllev(lf, SK_SPEECH, PR_NOVICE);
// must worship glorana
if (isplayer(lf)) {
lifeform_t *god;
@ -9447,17 +9466,24 @@ void givesubjob(lifeform_t *lf, enum SUBJOB sj) {
// raise WIS to gtaverage for life magic
lf->baseatt[A_WIS] = rollattr(AT_GTAVERAGE);
lf->att[A_WIS] = lf->baseatt[A_WIS];
// raise CHA to average for speech
if (getattrbracket(getattr(lf, A_CHA), A_CHA, NULL) < AT_AVERAGE) {
lf->baseatt[A_CHA] = rollattr(AT_AVERAGE);
lf->att[A_CHA] = lf->baseatt[A_CHA];
}
// can permenantly turn undead for 0 power.
addtempflag(lf->flags, F_CANWILL, OT_S_TURNUNDEAD, NA, NA, NULL, FROMJOB);
if (isplayer(lf)) {
addflag(lf->flags, F_SHORTCUT, getnextshortcut(lf), NA, NA, "turn undead");
}
// all gear is blessed
// all starting gear is blessed
for (o = lf->pack->first ; o ; o = o->next) {
if (isequipped(o)) {
blessob(o);
}
}
// remove warrior's level abilities
killflagsofid(lf->flags, F_LEVABIL);
break;
case SJ_SCOURGE:
addtempflag(lf->flags, F_RESISTMAG, 5, NA, NA, NULL, FROMJOB);
@ -10126,7 +10152,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
default: break;
}
if (real_getrandomob(targmap, buf, targmap->depth + depthmod, NA, maxobsize, SK_NONE, B_TRUE, OC_NONE, DT_NONE)) {
if (isshop && strstr(buf, "gold coin")) strcpy(buf, "potion of water");
if (isshop) apply_shopob_restrictions(buf);
o = addob(op, buf);
}
}
@ -10145,7 +10171,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
}
if (real_getrandomob(targmap, buf, targmap->depth + depthmod, NA, maxobsize, SK_NONE, B_TRUE, OC_NONE, val[1], DT_NONE)) {
if (db) snprintf(buf2, BUFLEN, "finished startobdt successfuly.");
if (isshop && strstr(buf, "gold coin")) strcpy(buf, "potion of water");
if (isshop) apply_shopob_restrictions(buf);
o = addob(op, buf);
} else {
if (db) snprintf(buf2, BUFLEN, "finished startobdt, failed.");
@ -10192,7 +10218,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
if (real_getrandomob(targmap, buf, getmapdifficulty(targmap) + depthmod, NA, maxobsize, SK_NONE, B_TRUE,
val[1], OC_NONE, DT_NONE)) {
if (db) snprintf(buf2, BUFLEN, "finished startobclass, success.");
if (isshop && strstr(buf, "gold coin")) strcpy(buf, "potion of water");
if (isshop) apply_shopob_restrictions(buf);
o = addob(op, buf);
} else {
//obdb = B_FALSE;
@ -13507,18 +13533,16 @@ 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_TRUE, NULL, B_TRUE, NULL);
return losehp_real(lf, amt, damtype, fromlf, damsrc, B_DAMADJUST, NULL, B_RETALIATE, NULL, B_DAMEFFECTS);
}
// 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 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) {
char buf[BUFLEN];
char buf2[BUFLEN];
char lfname[BUFLEN];
int prelowhp = B_FALSE,postlowhp = B_FALSE,ko = B_FALSE;
int prelowhp = B_FALSE,ko = B_FALSE;
flag_t *f;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
if (gamemode < GM_GAMESTARTED) return 0;
@ -13532,43 +13556,6 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
prelowhp = B_TRUE;
}
// check for protective spells
if (amt > 0) {
if (isphysicaldam(damtype)) {
int i;
getflags(lf->flags, retflag, &nretflags, F_HEAVENARM, F_MAGICARMOUR, F_NONE);
for (i = 0; i < nretflags; i++) {
int damtaken;
f = retflag[i];
damtaken = amt;
if (damtaken > f->val[0]) {
damtaken = f->val[0];
}
f->val[0] -= damtaken;
if (f->val[0] <= 0) {
// from a spell?
if (f->lifetime == FROMSPELL) {
flag_t *spellflag;
spellflag = hasactivespell(lf, f->obfrom);
if (spellflag) {
killflag(spellflag);
}
}
killflag(f);
} else {
if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("%s%s %s pulses!", lfname, getpossessive(lfname), f->text);
}
}
// reduce damage
amt -= damtaken;
}
}
}
// adjust for source object's material
if (fromob) {
@ -13729,69 +13716,13 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
// if they died
if (lf->hp <= 0) {
//if (!fromlf || (fromlf == player)) {
if (fromlf && (getallegiance(fromlf) == AL_FRIENDLY)) {
addflag(lf->flags, F_KILLEDBYPLAYER, B_TRUE, NA, NA, NULL);
}
} else {
// effects based on damage type
if (damtype == DT_COLD) {
int i;
if (lfhasflag(lf, F_COLDBLOOD)) {
// slow them
addtempflag(lf->flags, F_SLOWMOVE, 5, NA, NA, NULL, 10);
}
// catch a cold?
if (!skillcheck(lf, SC_CON, (amt/2) + getexposedlimbs(lf), 0)) {
poison(lf, 20+(amt*3), P_COLD, 0, "the cold");
}
// cold will heal bruised limbs
getflags(lf->flags, retflag, &nretflags, F_INJURY, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if (f->lifetime > 0) {
if ((f->val[0] == IJ_LEGBRUISE) || (f->val[0] == IJ_BLACKEYE)) {
f->lifetime -= 5;
limit(&f->lifetime, 1, NA);
}
}
}
if (fromlf) {
angergodmaybe(R_GODFIRE, 25, GA_HERESY);
}
} else if (damtype == DT_FIRE) {
int i;
// fire will cauterise slash wounds
getflags(lf->flags, retflag, &nretflags, F_FLAMMABLELF, F_INJURY, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if (f->id == F_FLAMMABLELF) {
if (isplayer(lf)) {
msg("You are engulfed in flames!");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("%s is engulfed in flames!", lfname);
}
addobfast(lf->cell->obpile, OT_FIRESMALL);
} else if (f->id == F_INJURY) {
if ((f->val[1] == DT_SLASH) && (f->lifetime > 0)) {
f->lifetime -= 20;
limit(&f->lifetime, 1, NA);
}
}
}
} else if (damtype == DT_POISONGAS) {
if (amt > 0) {
if (!skillcheck(lf, SC_POISON, 35, 0)) { // HARD.
poison(lf, rnd(20,40), P_GAS, 2, "poison gas");
}
}
}
}
if (isbleeding(lf)) {
postlowhp = B_TRUE;
if (doeffects) {
losehpeffects(lf, amt, damtype, fromlf, fromob, retaliate, ko, waskod, prelowhp);
}
//////////////////////////////////////////
@ -13808,7 +13739,6 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
strcpy(buf, damsrc);
}
// fill in damage amount
snprintf(buf2, BUFLEN, "^%d damage",amt);
strcat(buf, buf2);
@ -13849,6 +13779,74 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
}
}
// update screen
drawstatus();
updatestatus();
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 postlowhp = B_FALSE;
flag_t *retflag[MAXCANDIDATES],*f;
int nretflags;
char buf[BUFLEN],lfname[BUFLEN];
if (lf->hp > 0) {
// effects based on damage type
if (damtype == DT_COLD) {
int i;
if (lfhasflag(lf, F_COLDBLOOD)) {
// slow them
addtempflag(lf->flags, F_SLOWMOVE, 5, NA, NA, NULL, 10);
}
// catch a cold?
if (!skillcheck(lf, SC_CON, (dam/2) + getexposedlimbs(lf), 0)) {
poison(lf, 20+(dam*3), P_COLD, 0, "the cold");
}
// cold will heal bruised limbs
getflags(lf->flags, retflag, &nretflags, F_INJURY, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if (f->lifetime > 0) {
if ((f->val[0] == IJ_LEGBRUISE) || (f->val[0] == IJ_BLACKEYE)) {
f->lifetime -= 5;
limit(&f->lifetime, 1, NA);
}
}
}
if (fromlf) {
angergodmaybe(R_GODFIRE, 25, GA_HERESY);
}
} else if (damtype == DT_FIRE) {
int i;
// fire will ignire flammable lifeforms, cauterise slash wounds, etc
getflags(lf->flags, retflag, &nretflags, F_FLAMMABLELF, F_INJURY, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if (f->id == F_FLAMMABLELF) {
if (isplayer(lf)) {
msg("You are engulfed in flames!");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("%s is engulfed in flames!", lfname);
}
addobfast(lf->cell->obpile, OT_FIRESMALL);
} else if (f->id == F_INJURY) {
if ((f->val[1] == DT_SLASH) && (f->lifetime > 0)) {
f->lifetime -= 20;
limit(&f->lifetime, 1, NA);
}
}
}
} else if (damtype == DT_POISONGAS) {
if (dam > 0) {
if (!skillcheck(lf, SC_POISON, 35, 0)) { // HARD.
poison(lf, rnd(20,40), P_GAS, 2, "poison gas");
}
}
}
} // end if hp > 0
// special cases
if (lf->race->id == R_FUNGUSDREAM) {
char buf2[BUFLEN];
@ -13862,6 +13860,11 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_RED, OT_A_RAGE, 8, B_TRUE, buf, buf2);
}
if (isbleeding(lf)) {
postlowhp = B_TRUE;
}
// further effects if not dead...
if (!isdead(lf)) {
// fight back if required
@ -13869,16 +13872,6 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
fightback(lf, fromlf);
}
// low hitpoint warning
if (isplayer(lf) && (amt > 0)) {
int warnthresh;
warnthresh = (int)((float)0.25 * (float)lf->maxhp);
if ((lf->hp <= warnthresh) && (lf->hp > 0)) {
warn("*** LOW HITPOINT WARNING ***");
more();
}
}
if (ko) {
int kotime;
// is waskod was passed, allow the calling function to actually
@ -13920,12 +13913,12 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
// fire: dam*10 chance of burning each object which is vulnerable to fire
for (o = lf->pack->first ; o ; o = nexto) {
nexto = o->next;
if (isvulnto(o->flags, DT_FIRE, B_FALSE) && pctchance(amt*10)) {
if (isvulnto(o->flags, DT_FIRE, B_FALSE) && pctchance(dam*10)) {
int newdam;
nburnt++;
if (nburnt >= (amt/5)) break;
if (nburnt >= (dam/5)) break;
// object takes 1/4 of damage
newdam = pctof(25, amt);
newdam = pctof(25, dam);
limit(&newdam, 1, NA);
takedamage(o, newdam, DT_FIRE);
}
@ -13935,10 +13928,10 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
// cold: dam*10 chance of shattering potions, or damaging other things.
for (o = lf->pack->first ; o ; o = nexto) {
nexto = o->next;
if (isvulnto(o->flags, DT_COLD, B_FALSE) && pctchance(amt*10)) {
if (isvulnto(o->flags, DT_COLD, B_FALSE) && pctchance(dam*10)) {
int newdam;
// object takes 1/4 of damage
newdam = pctof(25, amt);
newdam = pctof(25, dam);
limit(&newdam, 1, NA);
takedamage(o, newdam, DT_COLD);
}
@ -13948,12 +13941,16 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
extinguishlf(lf);
}
}
// update screen
drawstatus();
updatestatus();
return amt;
// low hitpoint warning for player
if (isplayer(lf) && (dam > 0)) {
int warnthresh;
warnthresh = (int)((float)0.25 * (float)lf->maxhp);
if ((lf->hp <= warnthresh) && (lf->hp > 0)) {
warn("*** LOW HITPOINT WARNING ***");
more();
}
}
} // end if !isdead
}
void losemp(lifeform_t *lf, int amt) {
@ -17444,7 +17441,6 @@ void startlfturn(lifeform_t *lf) {
lifeform_t *l;
int i;
int willvanish = B_FALSE;
int donefeetwet = B_FALSE;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
int movedlastturn = B_FALSE;
@ -17985,7 +17981,7 @@ void startlfturn(lifeform_t *lf) {
if (skillcheck(lf, SC_SEARCH, diff, mod)) {
char obname[BUFLEN];
// reveal it
real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_TRUE);
getobnametruebase(o, obname, o->amt);
msg("^wYou notice %s!",obname);
interrupt(lf);
killflag(f);
@ -18272,9 +18268,12 @@ void startlfturn(lifeform_t *lf) {
// certain combinations might give announcements...
switch (damtype) {
case DT_WATER:
if ((bp == BP_FEET) && isplayer(lf) && hasbp(lf, bp) && !donefeetwet) {
msg("Your %s get wet.", getbodypartname(lf, bp));
donefeetwet = B_TRUE; // don't keep repeating this
if ((bp == BP_FEET) && isplayer(lf) && hasbp(lf, bp)) {
char warntext[BUFLEN];
sprintf(warntext,"Your %s get wet.", getbodypartname(lf, bp));
// only announce this if you've had a turn
// without your feet wet.
real_warnabout(warntext, 2, B_FALSE);
}
break;
default:
@ -19266,7 +19265,7 @@ int touch(lifeform_t *lf, object_t *o) {
o->blessknown = B_TRUE;
}
// use real name here...
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_FALSE, B_TRUE, B_FALSE);
real_getobname(o, obname, o->amt, B_PREMODS, B_NOCONDITION, B_NOBLINDADJUST, B_BLESSINGS, B_NOSHOWALL);
snprintf(buf, BUFLEN, "touching %s",obname);
losehp(lf, 2, DT_HOLY, NULL, buf);
// drop the object if we're holding it
@ -20619,6 +20618,9 @@ int wear(lifeform_t *lf, object_t *o) {
case E_DOESNTFIT:
if (isplayer(lf)) msg("The unnatural shape of your %s prevents this from fitting.", getbodypartname(lf, bp));
break;
case E_PALADIN:
if (isplayer(lf)) msg("Your vows prevent you from wearing non-blessed armour.");
break;
case E_INJURED:
if (isplayer(lf)) msg("Your injuries prevent you from wearing this.");
break;
@ -20842,6 +20844,9 @@ int weild(lifeform_t *lf, object_t *o) {
case E_IMPOSSIBLE:
msg("You cannot weild weapons!");
break;
case E_PALADIN:
if (isplayer(lf)) msg("Your vows prevent you from weilding non-blessed weapons.");
break;
case E_NOHANDS:
msg("You do not have enough free hands to weild this weapon.");
break;

3
lf.h
View File

@ -359,7 +359,8 @@ int loadfirearmfast(lifeform_t *lf, int onpurpose);
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_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob, int retaliate, int *waskod);
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);
void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fromlf, object_t *fromob, int retaliate, int ko, int *waskod, int prelowhp);
void losemp(lifeform_t *lf, int amt);
void makefriendly(lifeform_t *lf, int howlong);
int makenauseated(lifeform_t *lf, int amt, int howlong);

View File

@ -2285,15 +2285,18 @@ void adjustdamob(object_t *o, int *dam, enum DAMTYPE damtype) {
// adjust damage
if (o->blessed == B_BLESSED) {
// high chance of no hp loss
if (pctchance(90)) {
if (pctchance(80)) {
lifeform_t *owner;
owner = o->pile->owner;
if (owner && isplayer(owner)) {
// become known if owned by player
if (owner && (isplayer(owner) || cansee(player, owner))) {
// become known if seen by player
if (!isblessknown(o)) {
char obname[BUFLEN];
char obname[BUFLEN],lfname[BUFLEN];
getlfname(owner, lfname);
getobname(o, obname, o->amt);
msg("Your %s pulses with holy light as it is struck!",noprefix(obname));
msg("%s%s %s pulses with holy light as it is struck!",
lfname, getpossessive(lfname),
noprefix(obname));
}
o->blessknown = B_TRUE;
}
@ -3036,7 +3039,7 @@ int doobdieconvert(object_t *o, int wantannounce) {
if (wantannounce && !hasflag(o->flags, F_NODIECONVERTTEXT)) {
char obname[BUFLEN];
// announce the change
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
real_getobname(o, obname, o->amt, B_PREMODS, B_NOCONDITION, B_BLINDADJUST, B_BLESSINGS, B_NOSHOWALL);
strcpy(desc, "");
@ -4803,18 +4806,22 @@ char *getshardobname(enum MATERIAL mid, char *buf) {
char *getshopobname(object_t *o, char *buf, int count) {
if (gettechlevel(o->type->id) > getskill(player, SK_TECHUSAGE)) {
// unidentified tech - hide the name
return real_getobname(o, buf, o->amt, B_TRUE, B_TRUE, B_TRUE, B_TRUE, B_FALSE);
return getobname(o, buf, o->amt);
}
// anything else - show the real name
return real_getobname(o, buf, o->amt, B_TRUE, B_TRUE, B_TRUE, B_TRUE, B_TRUE);
return getobnametrue(o, buf, o->amt);
}
char *getobname(object_t *o, char *buf, int count) {
return real_getobname(o, buf, count, B_TRUE, B_TRUE, B_TRUE, B_TRUE, B_FALSE);
return real_getobname(o, buf, count, B_PREMODS, B_CONDITION, B_BLINDADJUST, B_BLESSINGS, B_NOSHOWALL);
}
char *getobnametrue(object_t *o, char *buf, int count) {
return real_getobname(o, buf, count, B_TRUE, B_TRUE, B_FALSE, B_TRUE, B_TRUE);
return real_getobname(o, buf, count, B_PREMODS, B_CONDITION, B_NOBLINDADJUST, B_BLESSINGS, B_SHOWALL);
}
char *getobnametruebase(object_t *o, char *buf, int count) {
return real_getobname(o, buf, count, B_NOPREMODS, B_NOCONDITION, B_NOBLINDADJUST, B_NOBLESSINGS, B_SHOWALL);
}
// buf must already be allocated
@ -5732,6 +5739,7 @@ char *real_getrandomob(map_t *map, char *buf, int forcedepth, int forcehabitat,
habitat_t *hab;
char habname[BUFLEN];
int rrmoddir = -1;
int brandchance;
skill_t *wantsk = NULL;
if (!db) db = obdb;
@ -6069,19 +6077,21 @@ char *real_getrandomob(map_t *map, char *buf, int forcedepth, int forcehabitat,
strcat(cursestr, "tainted ");
}
// get random chance of having a brand (1% per depth)...
// get random chance of having a brand (1% per depth, plus object adjustments)...
// if so...
strcpy(brandname, "");
if (rnd(1,100) <= depth) {
sumflags(ot->flags, F_BRANDCHANCE, &brandchance, NULL, NULL);
brandchance += depth;
if (pctchance(brandchance)) {
brand_t *br;
br = getrandombrandfor(ot);
if (br) strcpy(brandname, br->suffix);
}
snprintf(buf, BUFLEN, "%d %s%s%s", amt, cursestr, pluralname,brandname);
if (db || partdb) dblog("random ob for %s: %d x %s ('%s')", habname, amt, ot->name,pluralname);
free(pluralname);
return buf;
@ -8239,7 +8249,7 @@ void obdie(object_t *o) {
if (!doobdieconvert(o, B_TRUE)) {
char desc[BUFLEN];
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
real_getobname(o, obname, o->amt, B_PREMODS, B_NOCONDITION, B_BLINDADJUST, B_BLESSINGS, B_NOSHOWALL);
if (!hasflag(o->flags, F_NOOBDIETEXT)) {
// announce the death
strcpy(desc, "");
@ -9067,7 +9077,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
// tell player
makeknown(o->type->id);
if (isplayer(lf)) {
real_getobname(o, obname, 1, B_FALSE, B_TRUE, B_FALSE, B_TRUE, B_FALSE); // don't adjust for blindness
real_getobname(o, obname, 1, B_NOPREMODS, B_CONDITION, B_NOBLINDADJUST, B_BLESSINGS, B_NOSHOWALL);
msg("This is %s!",obname);
}
}
@ -10047,7 +10057,7 @@ void quaff(lifeform_t *lf, object_t *o) {
drawmsg();
}
} else if (!isknown(o)) {
real_getobname(o, obname, 1, B_FALSE, B_TRUE, B_FALSE, B_TRUE, B_FALSE); // don't adjust for blindness
real_getobname(o, obname, 1, B_NOPREMODS, B_CONDITION, B_NOBLINDADJUST, B_BLESSINGS, B_NOSHOWALL); // don't adjust for blindness
if (isplayer(lf)) {
// tell the player
msg("This is %s!",obname);
@ -10690,7 +10700,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
makeknown(o->type->id);
}
o->blessknown = B_TRUE;
real_getobname(o, obname, 1, B_FALSE, B_TRUE, B_FALSE, B_TRUE, B_FALSE); // don't adjust for blindness
real_getobname(o, obname, 1, B_NOPREMODS, B_CONDITION, B_NOBLINDADJUST, B_BLESSINGS, B_NOSHOWALL);
if (isplayer(lf)) {
// tell the player
msg("This is %s!",obname);
@ -10764,7 +10774,8 @@ int readsomething(lifeform_t *lf, object_t *o) {
if (targob) {
if (isplayer(lf)) {
// this will be used by maketried() later
real_getobname(targob, triedonbuf, 1, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
real_getobname(targob, triedonbuf, 1, B_NOPREMODS, B_NOCONDITION,
B_BLINDADJUST, B_NOBLESSINGS, B_NOSHOWALL);
}
} else {
noeffect = B_TRUE;
@ -11069,7 +11080,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
if (isplayer(lf) && !isknown(o)) {
identify(o);
o->blessknown = B_TRUE;
real_getobname(o, obname, 1, B_FALSE, B_TRUE, B_FALSE, B_TRUE, B_FALSE); // don't adjust for blindness
real_getobname(o, obname, 1, B_NOPREMODS, B_CONDITION, B_NOBLINDADJUST, B_BLESSINGS, B_NOSHOWALL);
// tell the player
msg("This is %s!",obname);
more();
@ -11818,8 +11829,8 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
}
// now use the REAL name
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_FALSE, B_FALSE, B_TRUE);
losehp_real(owner, howmuch , damtype, NULL, obname, B_TRUE, o, B_FALSE, NULL);
real_getobname(o, obname, o->amt, B_PREMODS, B_NOCONDITION, B_NOBLINDADJUST, B_NOBLESSINGS, B_SHOWALL);
losehp_real(owner, howmuch , damtype, NULL, obname, B_DAMADJUST, o, B_NORETALIATE, NULL, B_DAMEFFECTS);
if (isdead(owner)) {
return howmuch;
}
@ -11831,7 +11842,7 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
if (o->material->id == MT_GLASS) {
char buf[BUFLEN];
char buf2[BUFLEN];
real_getobname(o, buf2, 1, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE);
real_getobname(o, buf2, 1, B_NOPREMODS, B_NOCONDITION, B_NOBLINDADJUST, B_NOBLESSINGS, B_NOSHOWALL);
snprintf(buf, BUFLEN, "a shattering %s", noprefix(buf2));
shatter(o, B_TRUE, buf, B_FALSE);
return howmuch;
@ -11949,7 +11960,7 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
addflag(o->flags, F_LASTDAMTYPE, damtype, NA, NA, NULL);
}
real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
real_getobname(o, obname, o->amt, B_NOPREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOSHOWALL);
getobconditionname(o, predamname);
hpflag = hasflag(o->flags, F_OBHP);
if (hpflag) {
@ -12715,7 +12726,8 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
if (thrower && (thrower->cell == srcloc)) {
whogetsxp = thrower;
}
losehp_real(target, dam, DT_PROJECTILE, whogetsxp, damstring, B_TRUE, o, B_TRUE, NULL);
losehp_real(target, dam, DT_PROJECTILE, whogetsxp, damstring, B_DAMADJUST, o,
B_RETALIATE, NULL, B_DAMEFFECTS);
}
if (reduceamt && (speed >= 3)) {

View File

@ -131,6 +131,7 @@ char *getobname(object_t *o, char *buf, int count);
char *getshardobname(enum MATERIAL mid, char *buf);
char *getshopobname(object_t *o, char *buf, int count);
char *getobnametrue(object_t *o, char *buf, int count);
char *getobnametruebase(object_t *o, char *buf, int count);
char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wantcondition, int adjustforblind, int wantblesscurse, int showall);
float getobpileweight(obpile_t *op);
char *getobconditionname(object_t *o, char *buf);

16
shops.c
View File

@ -29,6 +29,22 @@ extern prompt_t prompt;
extern lifeform_t *player;
extern WINDOW *mainwin;
// "buf" is the name of an object
//
// this function will adjust the object name to avoid objects which shouldn't appear in shops.
// returns TRUE if the name was modified.
int apply_shopob_restrictions(char *buf) {
if (strstr(buf, "gold coin")) {
strcpy(buf, "potion of water");
return B_TRUE;
}
if (strstr(buf, "credit card")) {
strcpy(buf, "paper clip");
return B_TRUE;
}
return B_FALSE;
}
// dir == 1 means "better skills increase the price"
// dir == -1 means "better skills decrease the price"
float applyshoppricemod(float origprice, lifeform_t *lf, object_t *shop, enum SHOPACTION action) {

View File

@ -1,5 +1,6 @@
#include "defs.h"
int apply_shopob_restrictions(char *buf);
float applyshoppricemod(float origprice, lifeform_t *lf, object_t *shop, enum SHOPACTION action);
int canafford(lifeform_t *lf, int amt);
int getshopblessprice(object_t *o, object_t *shop);

14
spell.c
View File

@ -1483,7 +1483,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// get helper ob
helpob = getworkhelpob(user->pack, o->material->id);
if (helpob) {
real_getobname(helpob, helpobname, helpob->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
real_getobname(helpob, helpobname, helpob->amt, B_PREMODS, B_NOCONDITION, B_BLINDADJUST, B_BLESSINGS, B_NOSHOWALL);
} else {
strcpy(helpobname, "");
}
@ -1493,14 +1493,14 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
f->val[0] = f->val[1];
if (isplayer(user)) {
char buf[BUFLEN],withbuf[BUFLEN];
real_getobname(o, buf, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
real_getobname(o, buf, o->amt, B_PREMODS, B_NOCONDITION, B_BLINDADJUST, B_BLESSINGS, B_NOSHOWALL);
if (helpob) sprintf(withbuf, " (with %s)", helpobname);
else strcpy(withbuf, "");
msg("You repair your %s%s.", noprefix(buf), withbuf);
} else {
char buf[BUFLEN],withbuf[BUFLEN];
real_getobname(o, buf, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
real_getobname(o, buf, o->amt, B_PREMODS, B_NOCONDITION, B_BLINDADJUST, B_BLESSINGS, B_NOSHOWALL);
if (helpob) sprintf(withbuf, " with %s", helpobname);
else strcpy(withbuf, "");
@ -7004,7 +7004,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
char extrabuf[BUFLEN];
identify(o);
//getobname(o, buf, o->amt);
real_getobname(o, buf, o->amt, B_TRUE, B_TRUE, B_TRUE, B_TRUE, B_TRUE);
getobnametrue(o, buf, o->amt);
getobextrainfo(o, extrabuf);
if (strlen(extrabuf)) strcat(buf, extrabuf);
@ -8384,7 +8384,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// on the ground?
for (o = c->obpile->first ; o ; o = o->next) {
char obname[BUFLEN];
real_getobname(o, obname, o->amt, B_TRUE, B_TRUE, B_FALSE, B_FALSE, B_FALSE);
real_getobname(o, obname, o->amt, B_PREMODS, B_CONDITION, B_NOBLINDADJUST,
B_NOBLESSINGS, B_NOSHOWALL);
if (strcasestr(obname, wantname)) {
char ptext[BUFLEN];
char distbuf[BUFLEN],dirbuf[BUFLEN];
@ -8398,7 +8399,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (c->lf) {
for (o = c->lf->pack->first ; o ; o = o->next) {
char obname[BUFLEN];
real_getobname(o, obname, o->amt, B_TRUE, B_TRUE, B_FALSE, B_FALSE, B_FALSE);
real_getobname(o, obname, o->amt, B_PREMODS, B_CONDITION,
B_NOBLINDADJUST, B_NOBLESSINGS, B_NOSHOWALL);
if (strcasestr(obname, wantname)) {
char ptext[BUFLEN];
char distbuf[BUFLEN],dirbuf[BUFLEN];