Merge branch 'NetHack-3.7' into fix322

This commit is contained in:
Michael Meyer
2020-12-30 14:05:16 -05:00
712 changed files with 36133 additions and 17024 deletions

132
src/do.c
View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 do.c $NHDT-Date: 1593953347 2020/07/05 12:49:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.246 $ */
/* NetHack 3.7 do.c $NHDT-Date: 1608673689 2020/12/22 21:48:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.256 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
@@ -254,6 +254,8 @@ deletedwithboulder:
pline("%s %s into %s %s.", The(xname(obj)),
otense(obj, "tumble"), the_your[t->madeby_u],
is_pit(t->ttyp) ? "pit" : "hole");
if (is_hole(t->ttyp) && ship_object(obj, x, y, FALSE))
return TRUE;
} else if (obj->globby) {
/* Globby things like puddings might stick together */
while (obj && (otmp = obj_nexto_xy(obj, x, y, TRUE)) != 0) {
@@ -698,8 +700,6 @@ boolean with_impact;
if (obj == uswapwep)
setuswapwep((struct obj *) 0);
if (!u.uswallow && flooreffects(obj, u.ux, u.uy, "drop"))
return;
if (u.uswallow) {
/* hero has dropped an item while inside an engulfer */
if (obj != uball) { /* mon doesn't pick up ball */
@@ -711,6 +711,8 @@ boolean with_impact;
(void) mpickobj(u.ustuck, obj);
}
} else {
if (flooreffects(obj, u.ux, u.uy, "drop"))
return;
place_object(obj, u.ux, u.uy);
if (with_impact)
container_impact_dmg(obj, u.ux, u.uy);
@@ -845,8 +847,9 @@ int retry;
} else if (flags.menu_style == MENU_FULL) {
all_categories = FALSE;
n = query_category("Drop what type of items?", g.invent,
UNPAID_TYPES | ALL_TYPES | CHOOSE_ALL | BUC_BLESSED
| BUC_CURSED | BUC_UNCURSED | BUC_UNKNOWN,
(UNPAID_TYPES | ALL_TYPES | CHOOSE_ALL
| BUC_BLESSED | BUC_CURSED | BUC_UNCURSED
| BUC_UNKNOWN | INCLUDE_VENOM),
&pick_list, PICK_ANY);
if (!n)
goto drop_done;
@@ -897,7 +900,8 @@ int retry;
} else {
/* should coordinate with perm invent, maybe not show worn items */
n = query_objlist("What would you like to drop?", &g.invent,
(USE_INVLET | INVORDER_SORT), &pick_list, PICK_ANY,
(USE_INVLET | INVORDER_SORT | INCLUDE_VENOM),
&pick_list, PICK_ANY,
all_categories ? allow_all : allow_category);
if (n > 0) {
/*
@@ -948,10 +952,9 @@ int
dodown()
{
struct trap *trap = 0;
boolean stairs_down = ((u.ux == xdnstair && u.uy == ydnstair)
|| (u.ux == g.sstairs.sx && u.uy == g.sstairs.sy
&& !g.sstairs.up)),
ladder_down = (u.ux == xdnladder && u.uy == ydnladder);
stairway *stway = stairway_at(u.ux, u.uy);
boolean stairs_down = (stway && !stway->up && !stway->isladder),
ladder_down = (stway && !stway->up && stway->isladder);
if (u_rooted())
return 1;
@@ -1103,6 +1106,8 @@ dodown()
int
doup()
{
stairway *stway = stairway_at(u.ux,u.uy);
if (u_rooted())
return 1;
@@ -1112,10 +1117,7 @@ doup()
return 1;
}
if ((u.ux != xupstair || u.uy != yupstair)
&& (!xupladder || u.ux != xupladder || u.uy != yupladder)
&& (!g.sstairs.sx || u.ux != g.sstairs.sx || u.uy != g.sstairs.sy
|| !g.sstairs.up)) {
if (!stway || (stway && !stway->up)) {
You_cant("go up here.");
return 0;
}
@@ -1446,7 +1448,7 @@ boolean at_stairs, falling, portal;
assign_level(&u.uz0, &u.uz);
assign_level(&u.uz, newlevel);
assign_level(&u.utolev, newlevel);
u.utotype = 0;
u.utotype = UTOTYPE_NONE;
if (!builds_up(&u.uz)) { /* usual case */
if (dunlev(&u.uz) > dunlev_reached(&u.uz))
dunlev_reached(&u.uz) = dunlev(&u.uz);
@@ -1456,6 +1458,7 @@ boolean at_stairs, falling, portal;
dunlev_reached(&u.uz) = dunlev(&u.uz);
}
stairway_free_all();
/* set default level change destination areas */
/* the special level code may override these */
(void) memset((genericptr_t) &g.updest, 0, sizeof g.updest);
@@ -1526,8 +1529,9 @@ boolean at_stairs, falling, portal;
}
} else if (at_stairs && !In_endgame(&u.uz)) {
if (up) {
if (g.at_ladder)
u_on_newpos(xdnladder, ydnladder);
stairway *stway = stairway_find_from(&u.uz0, g.at_ladder);
if (stway)
u_on_newpos(stway->sx, stway->sy);
else if (newdungeon)
u_on_sstairs(1);
else
@@ -1542,8 +1546,9 @@ boolean at_stairs, falling, portal;
(Flying && g.at_ladder) ? " along" : "",
g.at_ladder ? "ladder" : "stairs");
} else { /* down */
if (g.at_ladder)
u_on_newpos(xupladder, yupladder);
stairway *stway = stairway_find_from(&u.uz0, g.at_ladder);
if (stway)
u_on_newpos(stway->sx, stway->sy);
else if (newdungeon)
u_on_sstairs(0);
else
@@ -1781,24 +1786,13 @@ final_level()
/* change levels at the end of this turn, after monsters finish moving */
void
schedule_goto(tolev, at_stairs, falling, portal_flag, pre_msg, post_msg)
schedule_goto(tolev, utotype_flags, pre_msg, post_msg)
d_level *tolev;
boolean at_stairs, falling;
int portal_flag;
int utotype_flags;
const char *pre_msg, *post_msg;
{
int typmask = 0100; /* non-zero triggers `deferred_goto' */
/* destination flags (`goto_level' args) */
if (at_stairs)
typmask |= 1;
if (falling)
typmask |= 2;
if (portal_flag)
typmask |= 4;
if (portal_flag < 0)
typmask |= 0200; /* flag for portal removal */
u.utotype = typmask;
/* UTOTYPE_DEFERRED is used, so UTOTYPE_NONE can trigger deferred_goto() */
u.utotype = utotype_flags | UTOTYPE_DEFERRED;
/* destination level */
assign_level(&u.utolev, tolev);
@@ -1820,8 +1814,10 @@ deferred_goto()
assign_level(&oldlev, &u.uz);
if (g.dfr_pre_msg)
pline1(g.dfr_pre_msg);
goto_level(&dest, !!(typmask & 1), !!(typmask & 2), !!(typmask & 4));
if (typmask & 0200) { /* remove portal */
goto_level(&dest, !!(typmask & UTOTYPE_ATSTAIRS),
!!(typmask & UTOTYPE_FALLING),
!!(typmask & UTOTYPE_PORTAL));
if (typmask & UTOTYPE_RMPORTAL) { /* remove portal */
struct trap *t = t_at(u.ux, u.uy);
if (t) {
@@ -1832,7 +1828,7 @@ deferred_goto()
if (g.dfr_post_msg && !on_level(&u.uz, &oldlev))
pline1(g.dfr_post_msg);
}
u.utotype = 0; /* our caller keys off of this */
u.utotype = UTOTYPE_NONE; /* our caller keys off of this */
if (g.dfr_pre_msg)
free((genericptr_t) g.dfr_pre_msg), g.dfr_pre_msg = 0;
if (g.dfr_post_msg)
@@ -1944,7 +1940,7 @@ long timeout UNUSED;
/* corpse will revive somewhere else if there is a monster in the way;
Riders get a chance to try to bump the obstacle out of their way */
if ((mptr->mflags3 & M3_DISPLACES) != 0 && body->where == OBJ_FLOOR
if (is_displacer(mptr) && body->where == OBJ_FLOOR
&& get_obj_location(body, &x, &y, 0) && (mtmp = m_at(x, y)) != 0) {
boolean notice_it = canseemon(mtmp); /* before rloc() */
char *monname = Monnam(mtmp);
@@ -1966,9 +1962,7 @@ long timeout UNUSED;
if (is_rider(mptr) && rn2(99)) { /* Rider usually tries again */
action = REVIVE_MON;
for (when = 3L; when < 67L; when++)
if (!rn2(3))
break;
when = rider_revival_time(body, TRUE);
} else { /* rot this corpse away */
You_feel("%sless hassled.", is_rider(mptr) ? "much " : "");
action = ROT_CORPSE;
@@ -1980,22 +1974,58 @@ long timeout UNUSED;
}
}
/* Timeout callback. Revive the corpse as a zombie. */
/*ARGSUSED*/
void
zombify_mon(arg, timeout)
anything *arg;
long timeout UNUSED;
{
struct obj *body = arg->a_obj;
int zmon = zombie_form(&mons[body->corpsenm]);
if (zmon != NON_PM) {
if (has_omid(body))
free_omid(body);
if (has_omonst(body))
free_omonst(body);
body->corpsenm = zmon;
revive_mon(arg, timeout);
}
}
boolean
cmd_safety_prevention(cmddesc, act, flagcounter)
const char *cmddesc;
const char *act;
int *flagcounter;
{
if (flags.safe_wait && !iflags.menu_requested
&& !g.multi && monster_nearby()) {
char buf[QBUFSZ];
buf[0] = '\0';
if (iflags.cmdassist || !*flagcounter++)
Sprintf(buf, " Use '%s' prefix to force %s.",
visctrl(g.Cmd.spkeys[NHKF_REQMENU]), cmddesc);
Norep("%s%s", act, buf);
return TRUE;
}
*flagcounter = 0;
return FALSE;
}
/* '.' command: do nothing == rest; also the
' ' command iff 'rest_on_space' option is On */
int
donull()
{
if (!iflags.menu_requested && !g.multi && monster_nearby()) {
char buf[QBUFSZ];
buf[0] = '\0';
if (iflags.cmdassist || !g.did_nothing_flag++)
Sprintf(buf, " Use '%s' prefix to force a no-op (to rest).",
visctrl(g.Cmd.spkeys[NHKF_REQMENU])); /* default is "m" */
Norep("Are you waiting to get hit?%s", buf);
if (cmd_safety_prevention("a no-op (to rest)",
"Are you waiting to get hit?",
&g.did_nothing_flag))
return 0;
}
g.did_nothing_flag = 0; /* reset */
return 1; /* Do nothing, but let other things happen */
}