Merge branch 'NetHack-3.6.2'

This commit is contained in:
nhmall
2019-05-05 23:30:50 -04:00
18 changed files with 218 additions and 87 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 ball.c $NHDT-Date: 1450402033 2015/12/18 01:27:13 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.29 $ */
/* NetHack 3.6 ball.c $NHDT-Date: 1557088406 2019/05/05 20:33:26 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.36 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) David Cohrs, 2006. */
/* NetHack may be freely redistributed. See license for details. */
@@ -24,12 +24,14 @@ boolean showmsg;
setuswapwep((struct obj *) 0);
if (uquiver == uball)
setuqwep((struct obj *) 0);
;
if (uwep != uball)
freeinv(uball);
/* [this used to test 'if (uwep != uball)' but that always passes
after the setuwep() above] */
freeinv(uball); /* remove from inventory but don't place on floor */
encumber_msg();
}
}
/* ball&chain might hit hero when falling through a trap door */
void
ballfall()
{
@@ -40,6 +42,7 @@ ballfall()
ballrelease(TRUE);
if (gets_hit) {
int dmg = rn1(7, 25);
pline_The("iron ball falls on your %s.", body_part(HEAD));
if (uarmh) {
if (is_metallic(uarmh)) {
@@ -113,9 +116,9 @@ placebc()
(void) flooreffects(uchain, u.ux, u.uy, ""); /* chain might rust */
if (carried(uball)) /* the ball is carried */
if (carried(uball)) { /* the ball is carried */
u.bc_order = BCPOS_DIFFER;
else {
} else {
/* ball might rust -- already checked when carried */
(void) flooreffects(uball, u.ux, u.uy, "");
place_object(uball, u.ux, u.uy);
@@ -411,6 +414,7 @@ boolean allow_drag;
/* only need to move the chain? */
if (carried(uball) || distmin(x, y, uball->ox, uball->oy) <= 2) {
xchar oldchainx = uchain->ox, oldchainy = uchain->oy;
*bc_control = BC_CHAIN;
move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy);
if (carried(uball)) {
@@ -584,7 +588,7 @@ boolean allow_drag;
return TRUE;
}
drag:
drag:
if (near_capacity() > SLT_ENCUMBER && dist2(x, y, u.ux, u.uy) <= 2) {
You("cannot %sdrag the heavy iron ball.",
@@ -774,21 +778,24 @@ xchar x, y;
}
}
/* ball&chain cause hero to randomly lose stuff from inventory */
STATIC_OVL void
litter()
{
struct obj *otmp = g.invent, *nextobj;
struct obj *otmp, *nextobj = 0;
int capacity = weight_cap();
while (otmp) {
for (otmp = g.invent; otmp; otmp = nextobj) {
nextobj = otmp->nobj;
if ((otmp != uball) && (rnd(capacity) <= (int) otmp->owt)) {
if (canletgo(otmp, "")) {
pline("%s you down the stairs.", Yobjnam2(otmp, "follow"));
You("drop %s and %s %s down the stairs with you.",
yname(otmp), (otmp->quan == 1L) ? "it" : "they",
otense(otmp, "fall"));
dropx(otmp);
encumber_msg(); /* drop[xyz]() probably ought to to this... */
}
}
otmp = nextobj;
}
}
@@ -839,4 +846,65 @@ drag_down()
}
}
void
bc_sanity_check()
{
int otyp;
unsigned save_nameknown;
const char *onam;
if (Punished && (!uball || !uchain)) {
impossible("Punished without %s%s%s?",
!uball ? "iron ball" : "",
(!uball && !uchain) ? " and " : "",
!uchain ? "attached chain" : "");
} else if (!Punished && (uball || uchain)) {
impossible("Attached %s%s%s without being Punished?",
uchain ? "chain" : "",
(uchain && uball) ? " and " : "",
uball ? "iron ball" : "");
}
/* ball is free when swallowed, changing levels, other times? */
if (uball && (uball->otyp != HEAVY_IRON_BALL
|| (uball->where != OBJ_FLOOR
&& uball->where != OBJ_INVENT
&& uball->where != OBJ_FREE)
|| (uball->owornmask & W_BALL) == 0L
|| (uball->owornmask & ~(W_BALL | W_WEAPON)) != 0L)) {
otyp = uball->otyp;
if (otyp < STRANGE_OBJECT || otyp >= NUM_OBJECTS
|| !OBJ_NAME(objects[otyp])) {
onam = "glorkum";
} else {
save_nameknown = objects[otyp].oc_name_known;
objects[otyp].oc_name_known = 1;
onam = simple_typename(otyp);
objects[otyp].oc_name_known = save_nameknown;
}
impossible("uball: type %d (%s), where %d, wornmask=0x%08lx",
otyp, onam, uball->where, uball->owornmask);
}
/* similar check to ball except can't be in inventory */
if (uchain && (uchain->otyp != IRON_CHAIN
|| (uchain->where != OBJ_FLOOR
&& uchain->where != OBJ_FREE)
/* [could simplify this to owornmask != W_CHAIN] */
|| (uchain->owornmask & W_CHAIN) == 0L
|| (uchain->owornmask & ~W_CHAIN) != 0L)) {
otyp = uchain->otyp;
if (otyp < STRANGE_OBJECT || otyp >= NUM_OBJECTS
|| !OBJ_NAME(objects[otyp])) {
onam = "glorkum";
} else {
save_nameknown = objects[otyp].oc_name_known;
objects[otyp].oc_name_known = 1;
onam = simple_typename(otyp);
objects[otyp].oc_name_known = save_nameknown;
}
impossible("uchain: type %d (%s), where %d, wornmask=0x%08lx",
otyp, onam, uchain->where, uchain->owornmask);
}
/* [check bc_order too?] */
}
/*ball.c*/

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 bones.c $NHDT-Date: 1539653203 2018/10/16 01:26:43 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.73 $ */
/* NetHack 3.6 bones.c $NHDT-Date: 1557092711 2019/05/05 21:45:11 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.75 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -212,8 +212,8 @@ char *namebuf;
/* called by savebones(); also by finish_paybill(shk.c) */
void
drop_upon_death(mtmp, cont, x, y)
struct monst *mtmp;
struct obj *cont;
struct monst *mtmp; /* monster if hero turned into one (other than ghost) */
struct obj *cont; /* container if hero is turned into a statue */
int x, y;
{
struct obj *otmp;
@@ -221,9 +221,13 @@ int x, y;
u.twoweap = 0; /* ensure curse() won't cause swapwep to drop twice */
while ((otmp = g.invent) != 0) {
obj_extract_self(otmp);
obj_no_longer_held(otmp);
/* when turning into green slime, all gear remains held;
other types "arise from the dead" do aren't holding
equipment during their brief interval as a corpse */
if (!mtmp || is_undead(mtmp->data))
obj_no_longer_held(otmp);
otmp->owornmask = 0;
otmp->owornmask = 0L;
/* lamps don't go out when dropped */
if ((cont || artifact_light(otmp)) && obj_is_burning(otmp))
end_burn(otmp, TRUE); /* smother in statue */
@@ -363,7 +367,7 @@ struct obj *corpse;
return;
}
make_bones:
make_bones:
unleash_all();
/* in case these characters are not in their home bases */
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
@@ -388,7 +392,7 @@ make_bones:
/* check iron balls separately--maybe they're not carrying it */
if (uball)
uball->owornmask = uchain->owornmask = 0;
uball->owornmask = uchain->owornmask = 0L;
/* dispose of your possessions, usually cursed */
if (u.ugrave_arise == (NON_PM - 1)) {
@@ -420,21 +424,21 @@ make_bones:
g.in_mklev = TRUE; /* use <u.ux,u.uy> as-is */
mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy, NO_MINVENT);
g.in_mklev = FALSE;
if (!mtmp) {
if (!mtmp) { /* arise-type might have been genocided */
drop_upon_death((struct monst *) 0, (struct obj *) 0, u.ux, u.uy);
u.ugrave_arise = NON_PM; /* in case caller cares */
return;
}
/* give mummy-from-hero a wrapping unless hero already
carries one; don't bother forcing it to become worn */
if (mtmp->data->mlet == S_MUMMY && !carrying(MUMMY_WRAPPING))
(void) mongets(mtmp, MUMMY_WRAPPING);
mtmp = christen_monst(mtmp, g.plname);
newsym(u.ux, u.uy);
/* ["Your body rises from the dead as an <mname>..." used
to be given here, but it has been moved to done() so that
it gets delivered even when savebones() isn't called] */
drop_upon_death(mtmp, (struct obj *) 0, u.ux, u.uy);
/* 'mtmp' now has hero's inventory; if 'mtmp' is a mummy, give it
a wrapping unless already carrying one */
if (mtmp->data->mlet == S_MUMMY && !m_carrying(mtmp, MUMMY_WRAPPING))
(void) mongets(mtmp, MUMMY_WRAPPING);
m_dowear(mtmp, TRUE);
}
if (mtmp) {

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 botl.c $NHDT-Date: 1554857126 2019/04/10 00:45:26 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.144 $ */
/* NetHack 3.6 botl.c $NHDT-Date: 1557094795 2019/05/05 22:19:55 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.145 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */
@@ -772,7 +772,15 @@ boolean *valsetlist;
}
#endif
if (g.update_all || chg || reset) {
/*
* TODO?
* It's possible for HPmax (or ENEmax) to change while current
* HP (or energy) stays the same. [Perhaps current and maximum
* both go up, then before the next status update takes place
* current goes down again.] If that happens with HPmax, we
* ought to force the windowport to treat current HP as changed
* if hitpointbar is On, in order for that to be re-rendered.
*/
idxmax = curr->idxmax;
pc = (idxmax >= 0) ? percentage(curr, &g.blstats[idx][idxmax]) : 0;
@@ -853,8 +861,8 @@ boolean *valsetlist;
if (g.context.botlx && (windowprocs.wincap2 & WC2_RESET_STATUS) != 0L)
status_update(BL_RESET, (genericptr_t) 0, 0, 0,
NO_COLOR, (unsigned long *) 0);
else if ((updated || g.context.botlx) &&
(windowprocs.wincap2 & WC2_FLUSH_STATUS) != 0L)
else if ((updated || g.context.botlx)
&& (windowprocs.wincap2 & WC2_FLUSH_STATUS) != 0L)
status_update(BL_FLUSH, (genericptr_t) 0, 0, 0,
NO_COLOR, (unsigned long *) 0);
@@ -1335,7 +1343,8 @@ const char *name;
STATIC_OVL boolean
hilite_reset_needed(bl_p, augmented_time)
struct istat_s *bl_p;
long augmented_time;
long augmented_time; /* no longer augmented; it once encoded fractional
* amounts for multiple moves within same turn */
{
/*
* This 'multi' handling may need some tuning...
@@ -1393,7 +1402,7 @@ status_eval_next_unhilite()
}
}
/* called by options handling when 'statushilites' boolean is toggled */
/* called by options handling when 'statushilites' value is changed */
void
reset_status_hilites()
{

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 cmd.c $NHDT-Date: 1549327488 2019/02/05 00:44:48 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.331 $ */
/* NetHack 3.6 cmd.c $NHDT-Date: 1557088405 2019/05/05 20:33:25 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.333 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
@@ -4087,6 +4087,7 @@ sanity_check()
timer_sanity_check();
mon_sanity_check();
light_sources_sanity_check();
bc_sanity_check();
}
#ifdef DEBUG_MIGRATING_MONS

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 dogmove.c $NHDT-Date: 1551493951 2019/03/02 02:32:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.72 $ */
/* NetHack 3.6 dogmove.c $NHDT-Date: 1557094801 2019/05/05 22:20:01 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.74 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -618,7 +618,6 @@ int after, udist, whappr;
return appr;
}
STATIC_OVL struct monst *
find_targ(mtmp, dx, dy, maxdist)
register struct monst *mtmp;
@@ -647,14 +646,13 @@ int maxdist;
if (!m_cansee(mtmp, curx, cury))
break;
targ = m_at(curx, cury);
if (curx == mtmp->mux && cury == mtmp->muy)
return &g.youmonst;
if (targ) {
if ((targ = m_at(curx, cury)) != 0) {
/* Is the monster visible to the pet? */
if ((!targ->minvis || perceives(mtmp->data)) && !targ->mundetected)
if ((!targ->minvis || perceives(mtmp->data))
&& !targ->mundetected)
break;
/* If the pet can't see it, it assumes it aint there */
targ = 0;
@@ -810,7 +808,6 @@ struct monst *mtmp, *mtarg;
return score;
}
STATIC_OVL struct monst *
best_target(mtmp)
struct monst *mtmp; /* Pet */
@@ -862,7 +859,6 @@ struct monst *mtmp; /* Pet */
return best_targ;
}
/* return 0 (no move), 1 (move) or 2 (dead) */
int
dog_move(mtmp, after)
@@ -1127,7 +1123,7 @@ int after; /* this is extra fast monster movement */
chcnt = 0;
chi = i;
}
nxti:
nxti:
;
}
@@ -1142,6 +1138,7 @@ int after; /* this is extra fast monster movement */
/* How hungry is the pet? */
if (!mtmp->isminion) {
struct edog *dog = EDOG(mtmp);
hungry = (g.monstermoves > (dog->hungrytime + 300));
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 end.c $NHDT-Date: 1554591224 2019/04/06 22:53:44 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.168 $ */
/* NetHack 3.6 end.c $NHDT-Date: 1557094801 2019/05/05 22:20:01 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.170 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -479,6 +479,15 @@ int how;
}
Strcpy(g.killer.name, buf);
/*
* Chicken and egg issue:
* Ordinarily Unchanging ought to override something like this,
* but the transformation occurs at death. With the current code,
* the effectiveness of Unchanging stops first, but a case could
* be made that it should last long enough to prevent undead
* transformation. (Turning to slime isn't an issue here because
* Unchanging prevents that from happening.)
*/
if (mptr->mlet == S_WRAITH)
u.ugrave_arise = PM_WRAITH;
else if (mptr->mlet == S_MUMMY && g.urace.mummynum != NON_PM)

View File

@@ -842,6 +842,8 @@ xchar x, y; /* clone's preferred location or 0 (near mon) */
m2->mx = mm.x;
m2->my = mm.y;
m2->mundetected = 0;
m2->mtrapped = 0;
m2->mcloned = 1;
m2->minvent = (struct obj *) 0; /* objects don't clone */
m2->mleashed = FALSE;

View File

@@ -408,7 +408,8 @@ register struct monst *magr, *mdef;
|| objects[g.otmp->otyp].oc_material == METAL))
&& mdef->mhp > 1
&& !mdef->mcan) {
if (clone_mon(mdef, 0, 0)) {
struct monst *mclone;
if ((mclone = clone_mon(mdef, 0, 0)) != 0) {
if (g.vis && canspotmon(mdef)) {
char buf[BUFSZ];
@@ -416,6 +417,7 @@ register struct monst *magr, *mdef;
pline("%s divides as %s hits it!", buf,
mon_nam(magr));
}
mintrap(mclone);
}
}
} else

View File

@@ -320,6 +320,8 @@ xchar rtype;
boolean oneshot;
d_level *lev;
{
struct monst *mtmp;
if (bad_location(x, y, nlx, nly, nhx, nhy)) {
if (!oneshot) {
return FALSE; /* caller should try again */
@@ -340,11 +342,12 @@ d_level *lev;
case LR_UPTELE:
case LR_DOWNTELE:
/* "something" means the player in this case */
if (MON_AT(x, y)) {
if ((mtmp = m_at(x, y)) != 0) {
/* move the monster if no choice, or just try again */
if (oneshot)
(void) rloc(m_at(x, y), FALSE);
else
if (oneshot) {
if (!rloc(mtmp, TRUE))
m_into_limbo(mtmp);
} else
return FALSE;
}
u_on_newpos(x, y);

View File

@@ -1685,6 +1685,7 @@ struct monst **monst_list; /* &g.migrating_mons or &g.mydogs or null */
}
if (on_map) {
mon->mtrapped = 0;
if (mon->wormno)
remove_worm(mon);
else

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 monmove.c $NHDT-Date: 1545596010 2018/12/23 20:13:30 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.111 $ */
/* NetHack 3.6 monmove.c $NHDT-Date: 1557094802 2019/05/05 22:20:02 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.113 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1030,7 +1030,7 @@ register int after;
if ((likegold || likegems || likeobjs || likemagic || likerock
|| conceals) && (!*in_rooms(omx, omy, SHOPBASE)
|| (!rn2(25) && !mtmp->isshk))) {
look_for_obj:
look_for_obj:
oomx = min(COLNO - 1, omx + minr);
oomy = min(ROWNO - 1, omy + minr);
lmx = max(1, omx - minr);
@@ -1620,6 +1620,7 @@ register struct monst *mtmp;
if (!gotu) {
register int try_cnt = 0;
do {
if (++try_cnt > 200)
goto found_you; /* punt */
@@ -1633,7 +1634,7 @@ register struct monst *mtmp;
&& (can_ooze(mtmp) || can_fog(mtmp)))))
|| !couldsee(mx, my));
} else {
found_you:
found_you:
mx = u.ux;
my = u.uy;
}

View File

@@ -1222,7 +1222,8 @@ int dieroll;
/* but not bashing with darts, arrows or ya */
&& !(is_ammo(obj) || is_missile(obj)))
&& hand_to_hand) {
if (clone_mon(mon, 0, 0)) {
struct monst *mclone;
if ((mclone = clone_mon(mon, 0, 0)) != 0) {
char withwhat[BUFSZ];
withwhat[0] = '\0';
@@ -1230,6 +1231,7 @@ int dieroll;
Sprintf(withwhat, " with %s", yname(obj));
pline("%s divides as you hit it%s!", Monnam(mon), withwhat);
hittxt = TRUE;
mintrap(mclone);
}
}