removing a monster from current level

I ended up not using this, but it might as well be included for
potential future use.  Extend mlevel_tele_trap() to support forcing
a monster off the current level to make room either for the hero or
some other monster.  goto_level() does something similar when the
hero is arriving on a level.  This is for situations where the hero
is already there (such as divine aid attempting to fix STUCK_IN_WALL).

mlevel_tele_trap(mon, (struct trap *) 0) will usually move 'mon' off
the level, scheduled to migrate back if the hero leaves the level and
subsequently returns.  'Usually' because it doesn't work in endgame
and certain monsters are excluded regardless of dungeon location, so
caller has to be prepared to try to move another monster (or resort
to goto_level()'s unconditional forced migration).
This commit is contained in:
PatR
2018-03-05 12:01:31 -08:00
parent b416564f39
commit 8279aa4384

View File

@@ -198,6 +198,8 @@ STATIC_OVL boolean
tele_jump_ok(x1, y1, x2, y2)
int x1, y1, x2, y2;
{
if (!isok(x2, y2))
return FALSE;
if (dndest.nlx > 0) {
/* if inside a restricted region, can't teleport outside */
if (within_bounded_area(x1, y1, dndest.nlx, dndest.nly, dndest.nhx,
@@ -1135,8 +1137,7 @@ struct trap *trap;
boolean force_it;
int in_sight;
{
int tt = trap->ttyp;
struct permonst *mptr = mtmp->data;
int tt = (trap ? trap->ttyp : NO_TRAP);
if (mtmp == u.ustuck) /* probably a vortex */
return 0; /* temporary? kludge */
@@ -1157,8 +1158,8 @@ int in_sight;
}
} else if (tt == MAGIC_PORTAL) {
if (In_endgame(&u.uz)
&& (mon_has_amulet(mtmp) || is_home_elemental(mptr))) {
if (in_sight && mptr->mlet != S_ELEMENTAL) {
&& (mon_has_amulet(mtmp) || is_home_elemental(mtmp->data))) {
if (in_sight && mtmp->data->mlet != S_ELEMENTAL) {
pline("%s seems to shimmer for a moment.", Monnam(mtmp));
seetrap(trap);
}
@@ -1167,27 +1168,44 @@ int in_sight;
assign_level(&tolevel, &trap->dst);
migrate_typ = MIGR_PORTAL;
}
} else { /* (tt == LEVEL_TELEP) */
} else if (tt == LEVEL_TELEP || tt == NO_TRAP) {
int nlev;
if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) {
if (mon_has_amulet(mtmp) || In_endgame(&u.uz)
/* NO_TRAP is used when forcing a monster off the level;
onscary(0,0,) is true for the Wizard, Riders, lawful
minions, Angels of any alignment, shopkeeper or priest
currently inside his or her own special room */
|| (tt == NO_TRAP && onscary(0, 0, mtmp))) {
if (in_sight)
pline("%s seems very disoriented for a moment.",
Monnam(mtmp));
return 0;
}
nlev = random_teleport_level();
if (nlev == depth(&u.uz)) {
if (in_sight)
pline("%s shudders for a moment.", Monnam(mtmp));
return 0;
if (tt == NO_TRAP) {
/* creature is being forced off the level to make room;
it will try to return to this level (at a random spot
rather than its current one) if the level is left by
the hero and then revisited */
assign_level(&tolevel, &u.uz);
} else {
nlev = random_teleport_level();
if (nlev == depth(&u.uz)) {
if (in_sight)
pline("%s shudders for a moment.", Monnam(mtmp));
return 0;
}
get_level(&tolevel, nlev);
}
get_level(&tolevel, nlev);
} else {
impossible("mlevel_tele_trap: unexpected trap type (%d)", tt);
return 0;
}
if (in_sight) {
pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
seetrap(trap);
if (trap)
seetrap(trap);
}
migrate_to_level(mtmp, ledger_no(&tolevel), migrate_typ, (coord *) 0);
return 3; /* no longer on this level */