Fixes and sanity checks for monster undetected and trapped states
Adds sanity checks for mtrapped and mundetected states. Fixes cases where those were left in wrong state. 1. Trapped monster (eg. a nymph) teleported out of a trap 2. Monster was hiding under ball or chain, which then got removed 3. While restoring a level, a zombie corpse revived while monster was hiding under it 4. A general case where the only object was deleted off floor and a monster was hiding under it Monsters hiding under ball or chain will now get revealed when the b or c are moved.
This commit is contained in:
@@ -1514,6 +1514,7 @@ E void FDECL(seemimic, (struct monst *));
|
||||
E void NDECL(rescham);
|
||||
E void NDECL(restartcham);
|
||||
E void FDECL(restore_cham, (struct monst *));
|
||||
E void FDECL(maybe_unhide_at, (XCHAR_P, XCHAR_P));
|
||||
E boolean FDECL(hideunder, (struct monst *));
|
||||
E void FDECL(hide_monst, (struct monst *));
|
||||
E void FDECL(mon_animal_list, (BOOLEAN_P));
|
||||
|
||||
@@ -162,7 +162,7 @@ unplacebc_core()
|
||||
obj_extract_self(uball);
|
||||
if (Blind && (u.bc_felt & BC_BALL)) /* drop glyph */
|
||||
levl[uball->ox][uball->oy].glyph = u.bglyph;
|
||||
|
||||
maybe_unhide_at(uball->ox, uball->oy);
|
||||
newsym(uball->ox, uball->oy);
|
||||
}
|
||||
obj_extract_self(uchain);
|
||||
@@ -536,9 +536,11 @@ xchar ballx, bally, chainx, chainy; /* only matter !before */
|
||||
}
|
||||
|
||||
remove_object(uchain);
|
||||
maybe_unhide_at(uchain->ox, uchain->oy);
|
||||
newsym(uchain->ox, uchain->oy);
|
||||
if (!carried(uball)) {
|
||||
remove_object(uball);
|
||||
maybe_unhide_at(uball->ox, uball->oy);
|
||||
newsym(uball->ox, uball->oy);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1225,8 +1225,10 @@ register struct obj *obj;
|
||||
}
|
||||
update_map = (obj->where == OBJ_FLOOR);
|
||||
obj_extract_self(obj);
|
||||
if (update_map)
|
||||
if (update_map) {
|
||||
maybe_unhide_at(obj->ox, obj->oy);
|
||||
newsym(obj->ox, obj->oy);
|
||||
}
|
||||
obfree(obj, (struct obj *) 0); /* frees contents also */
|
||||
}
|
||||
|
||||
|
||||
@@ -2175,6 +2175,10 @@ struct obj *obj;
|
||||
panic("dealloc_obj with nobj");
|
||||
if (obj->cobj)
|
||||
panic("dealloc_obj with cobj");
|
||||
if (obj == uball || obj == uchain)
|
||||
impossible("dealloc_obj called on %s, owornmask=%lx",
|
||||
(obj == uball) ? "uball" : "uchain",
|
||||
obj->owornmask);
|
||||
|
||||
/* free up any timers attached to the object */
|
||||
if (obj->timed)
|
||||
|
||||
36
src/mon.c
36
src/mon.c
@@ -99,6 +99,29 @@ const char *msg;
|
||||
/* guardian angel on astral level is tame but has emin rather than edog */
|
||||
if (mtmp->mtame && !has_edog(mtmp) && !mtmp->isminion)
|
||||
impossible("pet without edog (%s)", msg);
|
||||
|
||||
if (mtmp->mtrapped) {
|
||||
if (mtmp->wormno) {
|
||||
/* TODO: how to check worm in trap? */
|
||||
} else if (!t_at(mtmp->mx, mtmp->my))
|
||||
impossible("trapped without a trap (%s)", msg);
|
||||
}
|
||||
|
||||
/* monster is hiding? */
|
||||
if (mtmp->mundetected) {
|
||||
struct trap *t;
|
||||
|
||||
if (mtmp == u.ustuck)
|
||||
impossible("hiding monster stuck to you (%s)", msg);
|
||||
if (m_at(mtmp->mx, mtmp->my) == mtmp && hides_under(mtmp->data) && !OBJ_AT(mtmp->mx, mtmp->my))
|
||||
impossible("mon hiding under nonexistent obj (%s)", msg);
|
||||
if (mtmp->data->mlet == S_EEL && !is_pool(mtmp->mx, mtmp->my) && !Is_waterlevel(&u.uz))
|
||||
impossible("eel hiding out of water (%s)", msg);
|
||||
if (mtmp->mtrapped && (t = t_at(mtmp->mx, mtmp->my)) != 0
|
||||
&& !(t->ttyp == PIT || t->ttyp == SPIKED_PIT))
|
||||
impossible("hiding while trapped in a non-pit (%s)", msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3537,6 +3560,19 @@ register struct monst *mtmp;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* reveal a monster at x,y hiding under an object,
|
||||
if there are no objects there */
|
||||
void
|
||||
maybe_unhide_at(x, y)
|
||||
xchar x, y;
|
||||
{
|
||||
struct monst *mtmp;
|
||||
|
||||
if (!OBJ_AT(x, y) && (mtmp = m_at(x, y)) != 0
|
||||
&& mtmp->mundetected && hides_under(mtmp->data))
|
||||
(void) hideunder(mtmp);
|
||||
}
|
||||
|
||||
/* monster/hero tries to hide under something at the current location */
|
||||
boolean
|
||||
hideunder(mtmp)
|
||||
|
||||
@@ -1128,6 +1128,8 @@ xchar lev;
|
||||
place_monster(mtmp, mtmp->mx, mtmp->my);
|
||||
if (mtmp->wormno)
|
||||
place_wsegs(mtmp, NULL);
|
||||
if (hides_under(mtmp->data) && mtmp->mundetected)
|
||||
(void) hideunder(mtmp);
|
||||
|
||||
/* regenerate monsters while on another level */
|
||||
if (!u.uz.dlevel)
|
||||
|
||||
@@ -1258,6 +1258,10 @@ register int x, y;
|
||||
the latter only happens if you've attacked them with polymorph */
|
||||
if (resident_shk && !inhishop(mtmp))
|
||||
make_angry_shk(mtmp, oldx, oldy);
|
||||
|
||||
/* trapped monster teleported away */
|
||||
if (mtmp->mtrapped && !mtmp->wormno)
|
||||
(void) mintrap(mtmp);
|
||||
}
|
||||
|
||||
static stairway *
|
||||
|
||||
Reference in New Issue
Block a user