pull request #892 - strength loss effects

Pull request from entrez, with several commits:  monster spell 'weaken'
didn't handle poly'd hero correctly, possibly continuing in poly'd
form with negative hit points.  Make losing strength (which takes away
HP if Str would drop below 3) take care of applying damage too so that
several callers don't need to do that.

Fixes #892
This commit is contained in:
PatR
2022-10-08 16:33:43 -07:00
7 changed files with 31 additions and 20 deletions

View File

@@ -114,7 +114,8 @@ extern struct obj *has_magic_key(struct monst *);
extern boolean adjattrib(int, int, int);
extern void gainstr(struct obj *, int, boolean);
extern void losestr(int);
extern void losestr(int, const char *, schar);
extern void poison_strdmg(int, int, const char *, schar);
extern void poisontell(int, boolean);
extern void poisoned(const char *, int, const char *, int, boolean);
extern void change_luck(schar);
@@ -977,7 +978,7 @@ extern int monster_nearby(void);
extern void end_running(boolean);
extern void nomul(int);
extern void unmul(const char *);
extern void losehp(int, const char *, boolean);
extern void losehp(int, const char *, schar);
extern int weight_cap(void);
extern int inv_weight(void);
extern int near_capacity(void);

View File

@@ -211,19 +211,24 @@ gainstr(struct obj *otmp, int incr, boolean givemsg)
/* may kill you; cause may be poison or monster like 'a' */
void
losestr(int num)
losestr(int num, const char *knam, schar k_format)
{
int uhpmin = minuhpmax(1), olduhpmax = u.uhpmax;
int ustr = ABASE(A_STR) - num;
while (ustr < 3) {
/* in case HP loss kills the hero once Str hits the minimum */
if (!knam || !*knam) {
knam = "terminal frailty";
k_format = KILLED_BY;
}
while (ustr < ATTRMIN(A_STR)) {
++ustr;
--num;
losehp(6, knam, k_format);
if (Upolyd) {
u.mh -= 6;
u.mhmax -= 6;
} else {
u.uhp -= 6;
setuhpmax(u.uhpmax - 6);
}
g.context.botl = TRUE;
@@ -236,6 +241,14 @@ losestr(int num)
(void) adjattrib(A_STR, -num, 1);
}
/* combined strength loss and damage from some poisons */
void
poison_strdmg(int strloss, int dmg, const char *knam, schar k_format)
{
losestr(strloss, knam, k_format);
losehp(dmg, knam, k_format);
}
static const struct poison_effect_message {
void (*delivery_func)(const char *, ...);
const char *effect_msg;

View File

@@ -1815,9 +1815,9 @@ eatcorpse(struct obj *otmp)
tp++;
pline("Ecch - that must have been poisonous!");
if (!Poison_resistance) {
losestr(rnd(4));
losehp(rnd(15), !glob ? "poisonous corpse" : "poisonous glob",
KILLED_BY_AN);
poison_strdmg(rnd(4), rnd(15),
!glob ? "poisonous corpse" : "poisonous glob",
KILLED_BY_AN);
} else
You("seem unaffected by the poison.");
@@ -2753,8 +2753,7 @@ doeat(void)
if (otmp->oclass == WEAPON_CLASS && otmp->opoisoned) {
pline("Ecch - that must have been poisonous!");
if (!Poison_resistance) {
losestr(rnd(4));
losehp(rnd(15), xname(otmp), KILLED_BY_AN);
poison_strdmg(rnd(4), rnd(15), xname(otmp), KILLED_BY_AN);
} else
You("seem unaffected by the poison.");
} else if (!nodelicious) {

View File

@@ -292,8 +292,8 @@ drinkfountain(void)
losehp(rnd(4), "unrefrigerated sip of juice", KILLED_BY_AN);
break;
}
losestr(rn1(4, 3));
losehp(rnd(10), "contaminated water", KILLED_BY);
poison_strdmg(rn1(4, 3), rnd(10), "contaminated water",
KILLED_BY);
exercise(A_CON, FALSE);
break;
case 22: /* Fountain of snakes! */

View File

@@ -3645,7 +3645,7 @@ maybe_wail(void)
}
void
losehp(int n, const char *knam, boolean k_format)
losehp(int n, const char *knam, schar k_format)
{
#if 0 /* code below is prepared to handle negative 'loss' so don't add this
* until we've verified that no callers intentionally rely on that */

View File

@@ -465,9 +465,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
dmg = mtmp->m_lev - 6;
if (Half_spell_damage)
dmg = (dmg + 1) / 2;
losestr(rnd(dmg));
if (u.uhp < 1)
done_in_by(mtmp, DIED);
losestr(rnd(dmg), (const char *) 0, 0);
}
dmg = 0;
break;

View File

@@ -152,9 +152,9 @@ cursed_book(struct obj* bp)
/* temp disable in_use; death should not destroy the book */
was_in_use = bp->in_use;
bp->in_use = FALSE;
losestr(Poison_resistance ? rn1(2, 1) : rn1(4, 3));
losehp(rnd(Poison_resistance ? 6 : 10), "contact-poisoned spellbook",
KILLED_BY_AN);
poison_strdmg(Poison_resistance ? rn1(2, 1) : rn1(4, 3),
rnd(Poison_resistance ? 6 : 10),
"contact-poisoned spellbook", KILLED_BY_AN);
bp->in_use = was_in_use;
break;
case 6: