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:
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user