From d19c92281ab39980a7321c4a45545402479292f5 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 25 Jan 2023 21:52:05 +0200 Subject: [PATCH] Give gremlin the property it stole, if possible --- doc/fixes3-7-0.txt | 1 + include/extern.h | 3 +- src/eat.c | 2 +- src/mon.c | 106 ++++++++++++++++++++++++--------------------- src/sit.c | 20 ++++++++- src/uhitm.c | 2 +- 6 files changed, 80 insertions(+), 54 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 5c03167fc..167e34fbc 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1099,6 +1099,7 @@ if a grave is created with the corpse lying on top (bones), don't find a kicking a headstone might summon a ghoul eating garlic makes nearby monsters flee giants occasionally get a battle axe or a two-handed sword +give gremlin the property it stole, if possible Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 240db5190..bfa8e3617 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1548,6 +1548,7 @@ extern void m_consume_obj(struct monst *, struct obj *); extern int meatmetal(struct monst *); extern int meatobj(struct monst *); extern int meatcorpse(struct monst *); +extern void mon_give_prop(struct monst *, int); extern void mon_givit(struct monst *, struct permonst *); extern void mpickgold(struct monst *); extern boolean mpickstuff(struct monst *, const char *); @@ -2581,7 +2582,7 @@ extern boolean is_izchak(struct monst *, boolean); extern void take_gold(void); extern int dosit(void); extern void rndcurse(void); -extern void attrcurse(void); +extern int attrcurse(void); /* ### sounds.c ### */ diff --git a/src/eat.c b/src/eat.c index e58b93002..6b4086cfb 100644 --- a/src/eat.c +++ b/src/eat.c @@ -1220,7 +1220,7 @@ cpostfx(int pm) /* picks an intrinsic at random and removes it; there's no feedback if hero already lacks the chosen ability */ debugpline0("using attrcurse to strip an intrinsic"); - attrcurse(); + (void) attrcurse(); break; case PM_DEATH: case PM_PESTILENCE: diff --git a/src/mon.c b/src/mon.c index 92523333f..a7f45c4f6 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1453,7 +1453,62 @@ meatcorpse( return 0; } -DISABLE_WARNING_FORMAT_NONLITERAL +/* give monster property prop */ +void +mon_give_prop(struct monst *mtmp, int prop) +{ + const char *msg = NULL; + unsigned short intrinsic = 0; /* MR_* constant */ + + /* Pets don't have all the fields that the hero does, so they can't get all + the same intrinsics. If it happens to choose strength gain or teleport + control or whatever, ignore it. */ + switch (prop) { + case FIRE_RES: + intrinsic = MR_FIRE; + msg = "%s shivers slightly."; + break; + case COLD_RES: + intrinsic = MR_COLD; + msg = "%s looks quite warm."; + break; + case SLEEP_RES: + intrinsic = MR_SLEEP; + msg = "%s looks wide awake."; + break; + case DISINT_RES: + intrinsic = MR_DISINT; + msg = "%s looks very firm."; + break; + case SHOCK_RES: + intrinsic = MR_ELEC; + msg = "%s crackles with static electricity."; + break; + case POISON_RES: + intrinsic = MR_POISON; + msg = "%s looks healthy."; + break; + default: + return; /* can't give it */ + break; + } + + /* Don't give message if it already had this property intrinsically, but + still do grant the intrinsic if it only had it from mresists. + Do print the message if it only had this property extrinsically, which + is why mon_resistancebits isn't used here. */ + if ((mtmp->data->mresists | mtmp->mintrinsics) & intrinsic) + msg = (const char *) 0; + + if (intrinsic) + mtmp->mintrinsics |= intrinsic; + + if (canseemon(mtmp) && msg) { + DISABLE_WARNING_FORMAT_NONLITERAL + pline(msg, Monnam(mtmp)); + RESTORE_WARNING_FORMAT_NONLITERAL + } +} /* Maybe give an intrinsic to monster from eating corpse that confers it. */ void @@ -1461,8 +1516,6 @@ mon_givit(struct monst *mtmp, struct permonst *ptr) { int prop = corpse_intrinsic(ptr); boolean vis = canseemon(mtmp); - const char *msg = NULL; - unsigned short intrinsic = 0; /* MR_* constant */ if (ptr == &mons[PM_STALKER]) { /* @@ -1501,54 +1554,9 @@ mon_givit(struct monst *mtmp, struct permonst *ptr) if (!should_givit(prop, ptr)) return; /* failed die roll */ - /* Pets don't have all the fields that the hero does, so they can't get all - the same intrinsics. If it happens to choose strength gain or teleport - control or whatever, ignore it. */ - switch (prop) { - case FIRE_RES: - intrinsic = MR_FIRE; - msg = "%s shivers slightly."; - break; - case COLD_RES: - intrinsic = MR_COLD; - msg = "%s looks quite warm."; - break; - case SLEEP_RES: - intrinsic = MR_SLEEP; - msg = "%s looks wide awake."; - break; - case DISINT_RES: - intrinsic = MR_DISINT; - msg = "%s looks very firm."; - break; - case SHOCK_RES: - intrinsic = MR_ELEC; - msg = "%s crackles with static electricity."; - break; - case POISON_RES: - intrinsic = MR_POISON; - msg = "%s looks healthy."; - break; - default: - break; - } - - /* Don't give message if it already had this property intrinsically, but - still do grant the intrinsic if it only had it from mresists. - Do print the message if it only had this property extrinsically, which - is why mon_resistancebits isn't used here. */ - if ((mtmp->data->mresists | mtmp->mintrinsics) & intrinsic) - msg = (const char *) 0; - - if (intrinsic) - mtmp->mintrinsics |= intrinsic; - - if (vis && msg) - pline(msg, Monnam(mtmp)); + mon_give_prop(mtmp, prop); } -RESTORE_WARNING_FORMAT_NONLITERAL - void mpickgold(register struct monst* mtmp) { diff --git a/src/sit.c b/src/sit.c index f835014d3..876f03444 100644 --- a/src/sit.c +++ b/src/sit.c @@ -447,15 +447,20 @@ rndcurse(void) } } -/* remove a random INTRINSIC ability */ -void +/* remove a random INTRINSIC ability from hero. + returns the intrinsic property which was removed, + or 0 if nothing was removed. */ +int attrcurse(void) { + int ret = 0; + switch (rnd(11)) { case 1: if (HFire_resistance & INTRINSIC) { HFire_resistance &= ~INTRINSIC; You_feel("warmer."); + ret = FIRE_RES; break; } /*FALLTHRU*/ @@ -463,6 +468,7 @@ attrcurse(void) if (HTeleportation & INTRINSIC) { HTeleportation &= ~INTRINSIC; You_feel("less jumpy."); + ret = TELEPORT; break; } /*FALLTHRU*/ @@ -470,6 +476,7 @@ attrcurse(void) if (HPoison_resistance & INTRINSIC) { HPoison_resistance &= ~INTRINSIC; You_feel("a little sick!"); + ret = POISON_RES; break; } /*FALLTHRU*/ @@ -479,6 +486,7 @@ attrcurse(void) if (Blind && !Blind_telepat) see_monsters(); /* Can't sense mons anymore! */ Your("senses fail!"); + ret = TELEPAT; break; } /*FALLTHRU*/ @@ -486,6 +494,7 @@ attrcurse(void) if (HCold_resistance & INTRINSIC) { HCold_resistance &= ~INTRINSIC; You_feel("cooler."); + ret = COLD_RES; break; } /*FALLTHRU*/ @@ -493,6 +502,7 @@ attrcurse(void) if (HInvis & INTRINSIC) { HInvis &= ~INTRINSIC; You_feel("paranoid."); + ret = INVIS; break; } /*FALLTHRU*/ @@ -507,6 +517,7 @@ attrcurse(void) } You("%s!", Hallucination ? "tawt you taw a puttie tat" : "thought you saw something"); + ret = SEE_INVIS; break; } /*FALLTHRU*/ @@ -514,6 +525,7 @@ attrcurse(void) if (HFast & INTRINSIC) { HFast &= ~INTRINSIC; You_feel("slower."); + ret = FAST; break; } /*FALLTHRU*/ @@ -521,6 +533,7 @@ attrcurse(void) if (HStealth & INTRINSIC) { HStealth &= ~INTRINSIC; You_feel("clumsy."); + ret = STEALTH; break; } /*FALLTHRU*/ @@ -529,6 +542,7 @@ attrcurse(void) if (HProtection & INTRINSIC) { HProtection &= ~INTRINSIC; You_feel("vulnerable."); + ret = PROTECTION; break; } /*FALLTHRU*/ @@ -536,12 +550,14 @@ attrcurse(void) if (HAggravate_monster & INTRINSIC) { HAggravate_monster &= ~INTRINSIC; You_feel("less attractive."); + ret = AGGRAVATE_MONSTER; break; } /*FALLTHRU*/ default: break; } + return ret; } /*sit.c*/ diff --git a/src/uhitm.c b/src/uhitm.c index 02a44bfbf..7f09598b5 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2773,7 +2773,7 @@ mhitm_ad_curs(struct monst *magr, struct attack *mattk, struct monst *mdef, rehumanize(); return; } - attrcurse(); + mon_give_prop(magr, attrcurse()); } } else { /* mhitm */