Merge branch 'NetHack-3.6'

This commit is contained in:
nhmall
2019-05-30 18:10:41 -04:00
6 changed files with 107 additions and 85 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 teleport.c $NHDT-Date: 1553885439 2019/03/29 18:50:39 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.86 $ */
/* NetHack 3.6 teleport.c $NHDT-Date: 1559227830 2019/05/30 14:50:30 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.87 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
@@ -36,7 +36,8 @@ unsigned gpflags;
* which could be co-located and thus get restricted a bit too much.
* oh well.
*/
if (mtmp != &g.youmonst && x == u.ux && y == u.uy
if (x == u.ux && y == u.uy
&& mtmp != &g.youmonst && (mtmp != u.ustuck || !u.uswallow)
&& (!u.usteed || mtmp != u.usteed))
return FALSE;
@@ -105,22 +106,24 @@ coord *cc;
register xchar xx, yy;
struct permonst *mdat;
{
return enexto_core(cc, xx, yy, mdat, 0);
return enexto_core(cc, xx, yy, mdat, NO_MM_FLAGS);
}
boolean
enexto_core(cc, xx, yy, mdat, entflags)
coord *cc;
register xchar xx, yy;
xchar xx, yy;
struct permonst *mdat;
unsigned entflags;
{
#define MAX_GOOD 15
coord good[MAX_GOOD], *good_ptr;
int x, y, range, i;
int xmin, xmax, ymin, ymax;
int xmin, xmax, ymin, ymax, rangemax;
struct monst fakemon; /* dummy monster */
boolean allow_xx_yy = (boolean) ((entflags & GP_ALLOW_XY) != 0);
entflags &= ~GP_ALLOW_XY;
if (!mdat) {
debugpline0("enexto() called with null mdat");
/* default to player's original monster type */
@@ -129,6 +132,13 @@ unsigned entflags;
fakemon = cg.zeromonst;
set_mon_data(&fakemon, mdat); /* set up for goodpos */
/* used to use 'if (range > ROWNO && range > COLNO) return FALSE' below,
so effectively 'max(ROWNO, COLNO)' which performs useless iterations
(possibly many iterations if <xx,yy> is in the center of the map) */
xmax = max(xx - 1, (COLNO - 1) - xx);
ymax = max(yy - 0, (ROWNO - 1) - yy);
rangemax = max(xmax, ymax);
/* setup: no suitable spots yet, first iteration checks adjacent spots */
good_ptr = good;
range = 1;
/*
@@ -141,7 +151,7 @@ unsigned entflags;
ymin = max(0, yy - range);
ymax = min(ROWNO - 1, yy + range);
for (x = xmin; x <= xmax; x++)
for (x = xmin; x <= xmax; x++) {
if (goodpos(x, ymin, &fakemon, entflags)) {
good_ptr->x = x;
good_ptr->y = ymin;
@@ -149,38 +159,46 @@ unsigned entflags;
if (good_ptr++ == &good[MAX_GOOD - 1])
goto full;
}
for (x = xmin; x <= xmax; x++)
if (goodpos(x, ymax, &fakemon, entflags)) {
good_ptr->x = x;
good_ptr->y = ymax;
/* beware of accessing beyond segment boundaries.. */
if (good_ptr++ == &good[MAX_GOOD - 1])
goto full;
}
for (y = ymin + 1; y < ymax; y++)
}
/* 3.6.3: this used to use 'ymin+1' which left top row unchecked */
for (y = ymin; y < ymax; y++) {
if (goodpos(xmin, y, &fakemon, entflags)) {
good_ptr->x = xmin;
good_ptr->y = y;
/* beware of accessing beyond segment boundaries.. */
if (good_ptr++ == &good[MAX_GOOD - 1])
goto full;
}
for (y = ymin + 1; y < ymax; y++)
if (goodpos(xmax, y, &fakemon, entflags)) {
good_ptr->x = xmax;
good_ptr->y = y;
/* beware of accessing beyond segment boundaries.. */
if (good_ptr++ == &good[MAX_GOOD - 1])
goto full;
}
range++;
}
} while (++range <= rangemax && good_ptr == good);
/* return if we've grown too big (nothing is valid) */
if (range > ROWNO && range > COLNO)
/* return False if we exhausted 'range' without finding anything */
if (good_ptr == good) {
/* 3.6.3: earlier versions didn't have the option to try <xx,yy>,
and left 'cc' uninitialized when returning False */
cc->x = xx, cc->y = yy;
/* if every spot other than <xx,yy> has failed, try <xx,yy> itself */
if (allow_xx_yy && goodpos(xx, yy, &fakemon, entflags)) {
return TRUE; /* 'cc' is set */
} else {
debugpline3("enexto(\"%s\",%d,%d) failed", mdat->mname, xx, yy);
return FALSE;
} while (good_ptr == good);
}
}
full:
full:
/* we've got between 1 and SIZE(good) candidates; choose one */
i = rn2((int) (good_ptr - good));
cc->x = good[i].x;
cc->y = good[i].y;
@@ -423,7 +441,7 @@ boolean force_it;
return FALSE;
} else {
Your("leash goes slack.");
release_it:
release_it:
m_unleash(mtmp, FALSE);
return TRUE;
}
@@ -792,7 +810,7 @@ level_tele()
schar destlev;
xchar destdnum;
levTport_menu:
levTport_menu:
destlev = 0;
destdnum = 0;
newlev = (int) print_dungeon(TRUE, &destlev, &destdnum);
@@ -860,7 +878,7 @@ level_tele()
if (In_quest(&u.uz) && newlev > 0)
newlev = newlev + g.dungeons[u.uz.dnum].depth_start - 1;
} else { /* involuntary level tele */
random_levtport:
random_levtport:
newlev = random_teleport_level();
if (newlev == depth(&u.uz)) {
You1(shudder_for_moment);
@@ -1143,7 +1161,7 @@ register int x, y;
register int oldx = mtmp->mx, oldy = mtmp->my;
boolean resident_shk = mtmp->isshk && inhishop(mtmp);
if (x == mtmp->mx && y == mtmp->my && m_at(x,y) == mtmp)
if (x == mtmp->mx && y == mtmp->my && m_at(x, y) == mtmp)
return; /* that was easy */
if (oldx) { /* "pick up" monster */
@@ -1164,11 +1182,11 @@ register int x, y;
if (u.ustuck == mtmp) {
if (u.uswallow) {
u.ux = x;
u.uy = y;
u_on_newpos(mtmp->mx, mtmp->my);
docrt();
} else
u.ustuck = 0;
} else if (distu(mtmp->mx, mtmp->my) > 2) {
unstuck(mtmp);
}
}
newsym(x, y); /* update new location */
@@ -1229,7 +1247,7 @@ boolean suppress_impossible;
impossible("rloc(): couldn't relocate monster");
return FALSE;
found_xy:
found_xy:
rloc_to(mtmp, x, y);
return TRUE;
}
@@ -1238,7 +1256,7 @@ STATIC_OVL void
mvault_tele(mtmp)
struct monst *mtmp;
{
register struct mkroom *croom = search_special(VAULT);
struct mkroom *croom = search_special(VAULT);
coord c;
if (croom && somexy(croom, &c) && goodpos(c.x, c.y, mtmp, 0)) {