From: Pasi Kallinen Date: Wed, 25 Jan 2023 19:52:05 +0000 (+0200) Subject: Give gremlin the property it stole, if possible X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d19c92281ab39980a7321c4a45545402479292f5;p=nethack Give gremlin the property it stole, if possible --- 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,54 +1453,13 @@ meatcorpse( return 0; } -DISABLE_WARNING_FORMAT_NONLITERAL - -/* Maybe give an intrinsic to monster from eating corpse that confers it. */ +/* give monster property prop */ void -mon_givit(struct monst *mtmp, struct permonst *ptr) +mon_give_prop(struct monst *mtmp, int prop) { - int prop = corpse_intrinsic(ptr); - boolean vis = canseemon(mtmp); const char *msg = NULL; unsigned short intrinsic = 0; /* MR_* constant */ - if (ptr == &mons[PM_STALKER]) { - /* - * Invisible stalker isn't flagged as conferring invisibility - * so prop is 0. For hero, eating a stalker corpse confers - * temporary invisibility if hero is visible. When already - * invisible, if confers permanent invisibilty and also - * permanent see invisible. For monsters, only permanent - * invisibility is possible; temporary invisibility and see - * invisible aren't implemented for them. - * - * A monster being invisible gains no benefit against other - * monsters, and an invisible pet when hero can't see invisible - * is a nuisance at best, so this is probably detrimental. - * Players will just have to live with it if they want to be - * able to have pets gain intrinsics from eating corpses. - */ - if (!mtmp->perminvis || mtmp->invis_blkd) { - char mtmpbuf[BUFSZ]; - - Strcpy(mtmpbuf, Monnam(mtmp)); - mon_set_minvis(mtmp); - if (vis) - pline("%s %s.", mtmpbuf, - !canspotmon(mtmp) ? "vanishes" - : mtmp->invis_blkd ? "seems to flicker" - : "becomes invisible"); - } - mtmp->mstun = 1; /* no timeout but will eventually wear off */ - return; - } - - if (prop == 0) - return; /* no intrinsic from this corpse */ - - 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. */ @@ -1530,6 +1489,7 @@ mon_givit(struct monst *mtmp, struct permonst *ptr) msg = "%s looks healthy."; break; default: + return; /* can't give it */ break; } @@ -1543,11 +1503,59 @@ mon_givit(struct monst *mtmp, struct permonst *ptr) if (intrinsic) mtmp->mintrinsics |= intrinsic; - if (vis && msg) + if (canseemon(mtmp) && msg) { + DISABLE_WARNING_FORMAT_NONLITERAL pline(msg, Monnam(mtmp)); + RESTORE_WARNING_FORMAT_NONLITERAL + } } -RESTORE_WARNING_FORMAT_NONLITERAL +/* Maybe give an intrinsic to monster from eating corpse that confers it. */ +void +mon_givit(struct monst *mtmp, struct permonst *ptr) +{ + int prop = corpse_intrinsic(ptr); + boolean vis = canseemon(mtmp); + + if (ptr == &mons[PM_STALKER]) { + /* + * Invisible stalker isn't flagged as conferring invisibility + * so prop is 0. For hero, eating a stalker corpse confers + * temporary invisibility if hero is visible. When already + * invisible, if confers permanent invisibilty and also + * permanent see invisible. For monsters, only permanent + * invisibility is possible; temporary invisibility and see + * invisible aren't implemented for them. + * + * A monster being invisible gains no benefit against other + * monsters, and an invisible pet when hero can't see invisible + * is a nuisance at best, so this is probably detrimental. + * Players will just have to live with it if they want to be + * able to have pets gain intrinsics from eating corpses. + */ + if (!mtmp->perminvis || mtmp->invis_blkd) { + char mtmpbuf[BUFSZ]; + + Strcpy(mtmpbuf, Monnam(mtmp)); + mon_set_minvis(mtmp); + if (vis) + pline("%s %s.", mtmpbuf, + !canspotmon(mtmp) ? "vanishes" + : mtmp->invis_blkd ? "seems to flicker" + : "becomes invisible"); + } + mtmp->mstun = 1; /* no timeout but will eventually wear off */ + return; + } + + if (prop == 0) + return; /* no intrinsic from this corpse */ + + if (!should_givit(prop, ptr)) + return; /* failed die roll */ + + mon_give_prop(mtmp, prop); +} 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 */