fix issue #843 - vampire revival sequencing
Reported by Umbire: |You kill SpaceMannSpiff! SpaceMannSpiff puts on a dwarvish cloak. |SpaceMannSpiff puts on a dwarvish iron helm. |The seemingly dead SpaceMannSpiff suddenly transforms and rises as | a Vampire. This was tough to reproduce but I finally managed it. The issue text mentions that it was fixed by copperwater in xNetHack with commit 8c4af50f0aa3e72522f3eb98df039ff25c2a1ea0 to the repository for that variant. My attempt to cherry-pick that failed--I'm not even sure whether it should have been expected to work--and some of the code has been impinged upon by changes, so I ended up applying the contents of that commit manually. The commit changes how/when monsters put on new armor rather than anything directly related to vampires. Circumstances similar to the example above now yield: |You kill SpaceMannSpiff! |The seemingly dead SpaceMannSpiff suddenly transforms and rises as | a Vampire. on one turn, then on the next turn the revived vampire produces: |SpaceMannSpiff puts on a dwarvish cloak. My test case only had one item of interest; I assume that the second item of armor gets worn on a subsequent turn rather than at the same time as the first one. Fixes #843
This commit is contained in:
@@ -502,7 +502,7 @@ dog_invent(struct monst *mtmp, struct edog *edog, int udist)
|
||||
mtmp->weapon_check = NEED_HTH_WEAPON;
|
||||
(void) mon_wield_item(mtmp);
|
||||
}
|
||||
m_dowear(mtmp, FALSE);
|
||||
check_gear_next_turn(mtmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
34
src/mon.c
34
src/mon.c
@@ -1009,11 +1009,18 @@ movemon_singlemon(struct monst *mtmp)
|
||||
if (mtmp->misc_worn_check & I_SPECIAL) {
|
||||
long oldworn;
|
||||
|
||||
mtmp->misc_worn_check &= ~I_SPECIAL;
|
||||
oldworn = mtmp->misc_worn_check;
|
||||
m_dowear(mtmp, FALSE);
|
||||
if (mtmp->misc_worn_check != oldworn || !mtmp->mcanmove)
|
||||
return FALSE;
|
||||
/* hostiles only try to equip things if they think hero isn't
|
||||
* nearby; if they think hero is nearby, leave the flag intact so
|
||||
* that it can be checked again on subsequent moves until the hero
|
||||
* is perceived to be farther away. */
|
||||
if (mtmp->mpeaceful || mtmp->mtame
|
||||
|| dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) > (3 * 3)) {
|
||||
mtmp->misc_worn_check &= ~I_SPECIAL;
|
||||
oldworn = mtmp->misc_worn_check;
|
||||
m_dowear(mtmp, FALSE);
|
||||
if (mtmp->misc_worn_check != oldworn || !mtmp->mcanmove)
|
||||
return FALSE; /* is spending this turn equipping */
|
||||
}
|
||||
}
|
||||
|
||||
if (is_hider(mtmp->data)) {
|
||||
@@ -1636,7 +1643,8 @@ mpickstuff(struct monst *mtmp, const char *str)
|
||||
}
|
||||
obj_extract_self(otmp3); /* remove from floor */
|
||||
(void) mpickobj(mtmp, otmp3); /* may merge and free otmp3 */
|
||||
m_dowear(mtmp, FALSE);
|
||||
/* let them try and equip it on the next turn */
|
||||
check_gear_next_turn(mtmp);
|
||||
newsym(mtmp->mx, mtmp->my);
|
||||
return TRUE; /* pick only one object */
|
||||
}
|
||||
@@ -2519,7 +2527,7 @@ lifesaved_monster(struct monst* mtmp)
|
||||
}
|
||||
m_useup(mtmp, lifesave);
|
||||
/* equip replacement amulet, if any, on next move */
|
||||
mtmp->misc_worn_check |= I_SPECIAL;
|
||||
check_gear_next_turn(mtmp);
|
||||
|
||||
surviver = !(g.mvitals[monsndx(mtmp->data)].mvflags & G_GENOD);
|
||||
mtmp->mcanmove = 1;
|
||||
@@ -4757,7 +4765,7 @@ newcham(
|
||||
if (!(mtmp->misc_worn_check & W_ARMG))
|
||||
mselftouch(mtmp, "No longer petrify-resistant, ",
|
||||
!g.context.mon_moving);
|
||||
m_dowear(mtmp, FALSE);
|
||||
check_gear_next_turn(mtmp);
|
||||
|
||||
/* This ought to re-test can_carry() on each item in the inventory
|
||||
* rather than just checking ex-giants & boulders, but that'd be
|
||||
@@ -5160,4 +5168,14 @@ usmellmon(struct permonst* mdat)
|
||||
return msg_given ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/* setting misc_worn_check's I_SPECIAL bit flags a monster to reassess
|
||||
and potentially re-equip gear at the start of its next move;
|
||||
this hides the details of that */
|
||||
void
|
||||
check_gear_next_turn(mon)
|
||||
struct monst *mon;
|
||||
{
|
||||
mon->misc_worn_check |= I_SPECIAL;
|
||||
}
|
||||
|
||||
/*mon.c*/
|
||||
|
||||
@@ -1145,7 +1145,7 @@ extract_from_minvent(
|
||||
mon->misc_worn_check &= ~unwornmask;
|
||||
/* give monster a chance to wear other equipment on its next
|
||||
move instead of waiting until it picks something up */
|
||||
mon->misc_worn_check |= I_SPECIAL;
|
||||
check_gear_next_turn(mon);
|
||||
}
|
||||
obj_no_longer_held(obj);
|
||||
if (unwornmask & W_WEP) {
|
||||
|
||||
@@ -178,7 +178,8 @@ bhitm(struct monst *mtmp, struct obj *otmp)
|
||||
if (disguised_mimic)
|
||||
seemimic(mtmp);
|
||||
mon_adjust_speed(mtmp, -1, otmp);
|
||||
m_dowear(mtmp, FALSE); /* might want speed boots */
|
||||
check_gear_next_turn(mtmp); /* might want speed boots */
|
||||
|
||||
if (engulfing_u(mtmp) && is_whirly(mtmp->data)) {
|
||||
You("disrupt %s!", mon_nam(mtmp));
|
||||
pline("A huge hole opens up...");
|
||||
@@ -191,7 +192,7 @@ bhitm(struct monst *mtmp, struct obj *otmp)
|
||||
if (disguised_mimic)
|
||||
seemimic(mtmp);
|
||||
mon_adjust_speed(mtmp, 1, otmp);
|
||||
m_dowear(mtmp, FALSE); /* might want speed boots */
|
||||
check_gear_next_turn(mtmp); /* might want speed boots */
|
||||
}
|
||||
if (mtmp->mtame)
|
||||
helpful_gesture = TRUE;
|
||||
|
||||
Reference in New Issue
Block a user