Give gremlin the property it stole, if possible

This commit is contained in:
Pasi Kallinen
2023-01-25 21:52:05 +02:00
parent 1b8edf852f
commit d19c92281a
6 changed files with 80 additions and 54 deletions

View File

@@ -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

View File

@@ -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 ### */

View File

@@ -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:

106
src/mon.c
View File

@@ -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)
{

View File

@@ -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*/

View File

@@ -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 */