Merge remote-tracking branch 'origin/NetHack-3.6.0'
This commit is contained in:
13
src/apply.c
13
src/apply.c
@@ -1769,10 +1769,10 @@ int magic; /* 0=Physical, otherwise skill level */
|
||||
temp = -temp;
|
||||
if (range < temp)
|
||||
range = temp;
|
||||
(void) walk_path(&uc, &cc, hurtle_step, (genericptr_t) &range);
|
||||
/* hurtle_step results in (u.ux, u.uy) == (cc.x, cc.y) and usually
|
||||
* moves the ball if punished, but does not handle all the effects
|
||||
* of landing on the final position.
|
||||
(void) walk_path(&uc, &cc, hurtle_jump, (genericptr_t) &range);
|
||||
/* hurtle_jump -> hurtle_step results in <u.ux,u.uy> == <cc.x,cc.y>
|
||||
* and usually moves the ball if punished, but does not handle all
|
||||
* the effects of landing on the final position.
|
||||
*/
|
||||
teleds(cc.x, cc.y, FALSE);
|
||||
sokoban_guilt();
|
||||
@@ -1951,9 +1951,8 @@ struct obj *obj;
|
||||
if (ABASE(idx) >= AMAX(idx))
|
||||
continue;
|
||||
val_limit = AMAX(idx);
|
||||
/* don't recover strength lost from hunger */
|
||||
if (idx == A_STR && u.uhs >= WEAK)
|
||||
val_limit--;
|
||||
/* this used to adjust 'val_limit' for A_STR when u.uhs was
|
||||
WEAK or worse, but that's handled via ATEMP(A_STR) now */
|
||||
if (Fixed_abil) {
|
||||
/* potion/spell of restore ability override sustain ability
|
||||
intrinsic but unicorn horn usage doesn't */
|
||||
|
||||
19
src/attrib.c
19
src/attrib.c
@@ -366,20 +366,27 @@ set_moreluck()
|
||||
void
|
||||
restore_attrib()
|
||||
{
|
||||
int i;
|
||||
int i, equilibrium;;
|
||||
|
||||
/*
|
||||
* Note: this gets called on every turn but ATIME() is never set
|
||||
* to non-zero anywhere, and ATEMP() is only used for strength loss
|
||||
* from hunger, so it doesn't actually do anything.
|
||||
*/
|
||||
|
||||
for (i = 0; i < A_MAX; i++) { /* all temporary losses/gains */
|
||||
|
||||
if (ATEMP(i) && ATIME(i)) {
|
||||
equilibrium = (i == A_STR && u.uhs >= WEAK) ? -1 : 0;
|
||||
if (ATEMP(i) != equilibrium && ATIME(i) != 0) {
|
||||
if (!(--(ATIME(i)))) { /* countdown for change */
|
||||
ATEMP(i) += ATEMP(i) > 0 ? -1 : 1;
|
||||
|
||||
ATEMP(i) += (ATEMP(i) > 0) ? -1 : 1;
|
||||
context.botl = 1;
|
||||
if (ATEMP(i)) /* reset timer */
|
||||
ATIME(i) = 100 / ACURR(A_CON);
|
||||
}
|
||||
}
|
||||
}
|
||||
(void) encumber_msg();
|
||||
if (context.botl)
|
||||
(void) encumber_msg();
|
||||
}
|
||||
|
||||
#define AVAL 50 /* tune value for exercise gains */
|
||||
|
||||
269
src/cmd.c
269
src/cmd.c
@@ -114,6 +114,8 @@ static int NDECL(dosuspend_core); /**/
|
||||
|
||||
static int NDECL((*timed_occ_fn));
|
||||
|
||||
STATIC_PTR int NDECL(doherecmdmenu);
|
||||
STATIC_PTR int NDECL(dotherecmdmenu);
|
||||
STATIC_PTR int NDECL(doprev_message);
|
||||
STATIC_PTR int NDECL(timed_occupation);
|
||||
STATIC_PTR int NDECL(doextcmd);
|
||||
@@ -181,6 +183,10 @@ STATIC_DCL void FDECL(attributes_enlightenment, (int, int));
|
||||
static const char *readchar_queue = "";
|
||||
static coord clicklook_cc;
|
||||
|
||||
STATIC_DCL void FDECL(add_herecmd_menuitem, (winid, int NDECL((*)),
|
||||
const char *));
|
||||
STATIC_DCL char FDECL(here_cmd_menu, (BOOLEAN_P));
|
||||
STATIC_DCL char FDECL(there_cmd_menu, (BOOLEAN_P, int, int));
|
||||
STATIC_DCL char *NDECL(parse);
|
||||
STATIC_DCL void FDECL(show_direction_keys, (winid, CHAR_P, BOOLEAN_P));
|
||||
STATIC_DCL boolean FDECL(help_dir, (CHAR_P, int, const char *));
|
||||
@@ -2899,6 +2905,8 @@ struct ext_func_tab extcmdlist[] = {
|
||||
{ ';', "glance", "show what type of thing a map symbol corresponds to",
|
||||
doquickwhatis, IFBURIED | GENERALCMD },
|
||||
{ '?', "help", "give a help message", dohelp, IFBURIED | GENERALCMD },
|
||||
{ '\0', "herecmdmenu", "show menu of commands you can do here",
|
||||
doherecmdmenu, IFBURIED },
|
||||
{ 'V', "history", "show long version and game history",
|
||||
dohistory, IFBURIED | GENERALCMD },
|
||||
{ 'i', "inventory", "show your inventory", ddoinv, IFBURIED },
|
||||
@@ -2996,6 +3004,9 @@ struct ext_func_tab extcmdlist[] = {
|
||||
{ C('t'), "teleport", "teleport around the level", dotele, IFBURIED },
|
||||
{ '\0', "terrain", "show map without obstructions",
|
||||
doterrain, IFBURIED | AUTOCOMPLETE },
|
||||
{ '\0', "therecmdmenu",
|
||||
"show menu of commands you can do from here to adjacent spot",
|
||||
dotherecmdmenu },
|
||||
{ 't', "throw", "throw something", dothrow },
|
||||
{ '\0', "timeout", "look at timeout queue and hero's timed intrinsics",
|
||||
wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
|
||||
@@ -4658,6 +4669,251 @@ register int x, y;
|
||||
return x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1;
|
||||
}
|
||||
|
||||
/* #herecmdmenu command */
|
||||
STATIC_PTR int
|
||||
doherecmdmenu(VOID_ARGS)
|
||||
{
|
||||
char ch = here_cmd_menu(TRUE);
|
||||
|
||||
return ch ? 1 : 0;
|
||||
}
|
||||
|
||||
/* #therecmdmenu command, a way to test there_cmd_menu without mouse */
|
||||
STATIC_PTR int
|
||||
dotherecmdmenu(VOID_ARGS)
|
||||
{
|
||||
char ch;
|
||||
|
||||
if (!getdir((const char *) 0) || !isok(u.ux + u.dx, u.uy + u.dy))
|
||||
return 0;
|
||||
|
||||
if (u.dx || u.dy)
|
||||
ch = there_cmd_menu(TRUE, u.ux + u.dx, u.uy + u.dy);
|
||||
else
|
||||
ch = here_cmd_menu(TRUE);
|
||||
|
||||
return ch ? 1 : 0;
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
add_herecmd_menuitem(win, func, text)
|
||||
winid win;
|
||||
int NDECL((*func));
|
||||
const char *text;
|
||||
{
|
||||
char ch;
|
||||
anything any;
|
||||
|
||||
if ((ch = cmd_from_func(func)) != '\0') {
|
||||
any = zeroany;
|
||||
any.a_nfunc = func;
|
||||
add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, text, MENU_UNSELECTED);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_OVL char
|
||||
there_cmd_menu(doit, x, y)
|
||||
boolean doit;
|
||||
int x, y;
|
||||
{
|
||||
winid win;
|
||||
char ch;
|
||||
char buf[BUFSZ];
|
||||
schar typ = levl[x][y].typ;
|
||||
int npick, K = 0;
|
||||
menu_item *picks = (menu_item *) 0;
|
||||
struct trap *ttmp;
|
||||
struct monst *mtmp;
|
||||
|
||||
win = create_nhwindow(NHW_MENU);
|
||||
start_menu(win);
|
||||
|
||||
if (IS_DOOR(typ)) {
|
||||
boolean key_or_pick, card;
|
||||
int dm = levl[x][y].doormask;
|
||||
|
||||
if ((dm & (D_CLOSED | D_LOCKED))) {
|
||||
add_herecmd_menuitem(win, doopen, "Open the door"), ++K;
|
||||
/* unfortunately there's no lknown flag for doors to
|
||||
remember the locked/unlocked state */
|
||||
key_or_pick = (carrying(SKELETON_KEY) || carrying(LOCK_PICK));
|
||||
card = (carrying(CREDIT_CARD) != 0);
|
||||
if (key_or_pick || card) {
|
||||
Sprintf(buf, "%sunlock the door",
|
||||
key_or_pick ? "lock or " : "");
|
||||
add_herecmd_menuitem(win, doapply, upstart(buf)), ++K;
|
||||
}
|
||||
/* unfortunately there's no tknown flag for doors (or chests)
|
||||
to remember whether a trap had been found */
|
||||
add_herecmd_menuitem(win, dountrap,
|
||||
"Search the door for a trap"), ++K;
|
||||
/* [what about #force?] */
|
||||
add_herecmd_menuitem(win, dokick, "Kick the door"), ++K;
|
||||
} else if ((dm & D_ISOPEN)) {
|
||||
add_herecmd_menuitem(win, doclose, "Close the door"), ++K;
|
||||
}
|
||||
}
|
||||
|
||||
if (typ <= SCORR)
|
||||
add_herecmd_menuitem(win, dosearch, "Search for secret doors"), ++K;
|
||||
|
||||
if ((ttmp = t_at(x, y)) != 0 && ttmp->tseen) {
|
||||
add_herecmd_menuitem(win, doidtrap, "Examine trap"), ++K;
|
||||
if (ttmp->ttyp != VIBRATING_SQUARE)
|
||||
add_herecmd_menuitem(win, dountrap, "Attempt to disarm trap"), ++K;
|
||||
}
|
||||
|
||||
mtmp = m_at(x, y);
|
||||
if (mtmp && !canspotmon(mtmp))
|
||||
mtmp = 0;
|
||||
if (mtmp && which_armor(mtmp, W_SADDLE)) {
|
||||
char *mnam = x_monnam(mtmp, ARTICLE_THE, (char *) 0,
|
||||
SUPPRESS_SADDLE, FALSE);
|
||||
|
||||
if (!u.usteed) {
|
||||
Sprintf(buf, "Ride %s", mnam);
|
||||
add_herecmd_menuitem(win, doride, buf), ++K;
|
||||
}
|
||||
Sprintf(buf, "Remove saddle from %s", mnam);
|
||||
add_herecmd_menuitem(win, doloot, buf), ++K;
|
||||
}
|
||||
if (mtmp && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)
|
||||
&& carrying(SADDLE)) {
|
||||
Sprintf(buf, "Put saddle on %s", mon_nam(mtmp)), ++K;
|
||||
add_herecmd_menuitem(win, doapply, buf);
|
||||
}
|
||||
#if 0
|
||||
if (mtmp || glyph_is_invisible(glyph_at(x, y))) {
|
||||
/* "Attack %s", mtmp ? mon_nam(mtmp) : "unseen creature" */
|
||||
} else {
|
||||
/* "Move %s", direction */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (K) {
|
||||
end_menu(win, "What do you want to do?");
|
||||
npick = select_menu(win, PICK_ONE, &picks);
|
||||
} else {
|
||||
pline("No applicable actions.");
|
||||
npick = 0;
|
||||
}
|
||||
destroy_nhwindow(win);
|
||||
ch = '\0';
|
||||
if (npick > 0) {
|
||||
int NDECL((*func)) = picks->item.a_nfunc;
|
||||
free((genericptr_t) picks);
|
||||
|
||||
if (doit) {
|
||||
int ret = (*func)();
|
||||
|
||||
ch = (char) ret;
|
||||
} else {
|
||||
ch = cmd_from_func(func);
|
||||
}
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
STATIC_OVL char
|
||||
here_cmd_menu(doit)
|
||||
boolean doit;
|
||||
{
|
||||
winid win;
|
||||
char ch;
|
||||
char buf[BUFSZ];
|
||||
schar typ = levl[u.ux][u.uy].typ;
|
||||
int npick;
|
||||
menu_item *picks = (menu_item *) 0;
|
||||
|
||||
win = create_nhwindow(NHW_MENU);
|
||||
start_menu(win);
|
||||
|
||||
if (IS_FOUNTAIN(typ) || IS_SINK(typ)) {
|
||||
Sprintf(buf, "Drink from the %s",
|
||||
defsyms[IS_FOUNTAIN(typ) ? S_fountain : S_sink].explanation);
|
||||
add_herecmd_menuitem(win, dodrink, buf);
|
||||
}
|
||||
if (IS_FOUNTAIN(typ))
|
||||
add_herecmd_menuitem(win, dodip,
|
||||
"Dip something into the fountain");
|
||||
if (IS_THRONE(typ))
|
||||
add_herecmd_menuitem(win, dosit,
|
||||
"Sit on the throne");
|
||||
|
||||
if ((u.ux == xupstair && u.uy == yupstair)
|
||||
|| (u.ux == sstairs.sx && u.uy == sstairs.sy && sstairs.up)
|
||||
|| (u.ux == xupladder && u.uy == yupladder)) {
|
||||
Sprintf(buf, "Go up the %s",
|
||||
(u.ux == xupladder && u.uy == yupladder)
|
||||
? "ladder" : "stairs");
|
||||
add_herecmd_menuitem(win, doup, buf);
|
||||
}
|
||||
if ((u.ux == xdnstair && u.uy == ydnstair)
|
||||
|| (u.ux == sstairs.sx && u.uy == sstairs.sy && !sstairs.up)
|
||||
|| (u.ux == xdnladder && u.uy == ydnladder)) {
|
||||
Sprintf(buf, "Go down the %s",
|
||||
(u.ux == xupladder && u.uy == yupladder)
|
||||
? "ladder" : "stairs");
|
||||
add_herecmd_menuitem(win, dodown, buf);
|
||||
}
|
||||
if (u.usteed) { /* another movement choice */
|
||||
Sprintf(buf, "Dismount %s",
|
||||
x_monnam(u.usteed, ARTICLE_THE, (char *) 0,
|
||||
SUPPRESS_SADDLE, FALSE));
|
||||
add_herecmd_menuitem(win, doride, buf);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (Upolyd) { /* before objects */
|
||||
Sprintf(buf, "Use %s special ability",
|
||||
s_suffix(mons[u.umonnum].mname));
|
||||
add_herecmd_menuitem(win, domonability, buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (OBJ_AT(u.ux, u.uy)) {
|
||||
struct obj *otmp = level.objects[u.ux][u.uy];
|
||||
|
||||
Sprintf(buf, "Pick up %s", otmp->nexthere ? "items" : doname(otmp));
|
||||
add_herecmd_menuitem(win, dopickup, buf);
|
||||
|
||||
if (Is_container(otmp)) {
|
||||
Sprintf(buf, "Loot %s", doname(otmp));
|
||||
add_herecmd_menuitem(win, doloot, buf);
|
||||
}
|
||||
if (otmp->oclass == FOOD_CLASS) {
|
||||
Sprintf(buf, "Eat %s", doname(otmp));
|
||||
add_herecmd_menuitem(win, doeat, buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (invent)
|
||||
add_herecmd_menuitem(win, dodrop, "Drop items");
|
||||
|
||||
add_herecmd_menuitem(win, donull, "Rest one turn");
|
||||
add_herecmd_menuitem(win, dosearch, "Search around you");
|
||||
add_herecmd_menuitem(win, dolook, "Look at what is here");
|
||||
|
||||
end_menu(win, "What do you want to do?");
|
||||
npick = select_menu(win, PICK_ONE, &picks);
|
||||
destroy_nhwindow(win);
|
||||
ch = '\0';
|
||||
if (npick > 0) {
|
||||
int NDECL((*func)) = picks->item.a_nfunc;
|
||||
free((genericptr_t) picks);
|
||||
|
||||
if (doit) {
|
||||
int ret = (*func)();
|
||||
|
||||
ch = (char) ret;
|
||||
} else {
|
||||
ch = cmd_from_func(func);
|
||||
}
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
|
||||
static NEARDATA int last_multi;
|
||||
|
||||
/*
|
||||
@@ -4692,6 +4948,11 @@ int x, y, mod;
|
||||
}
|
||||
|
||||
if (x == 0 && y == 0) {
|
||||
if (iflags.herecmd_menu) {
|
||||
cmd[0] = here_cmd_menu(FALSE);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
/* here */
|
||||
if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)
|
||||
|| IS_SINK(levl[u.ux][u.uy].typ)) {
|
||||
@@ -4730,6 +4991,13 @@ int x, y, mod;
|
||||
&& !test_move(u.ux, u.uy, x, y, TEST_MOVE)) {
|
||||
cmd[1] = Cmd.dirchars[dir];
|
||||
cmd[2] = '\0';
|
||||
if (iflags.herecmd_menu) {
|
||||
cmd[0] = there_cmd_menu(FALSE, u.ux + x, u.uy + y);
|
||||
if (cmd[0] == '\0')
|
||||
cmd[1] = '\0';
|
||||
return cmd;
|
||||
}
|
||||
|
||||
if (IS_DOOR(levl[u.ux + x][u.uy + y].typ)) {
|
||||
/* slight assistance to the player: choose kick/open for them
|
||||
*/
|
||||
@@ -5096,6 +5364,7 @@ wiz_port_debug()
|
||||
num_menu_selections = SIZE(menu_selections) - 1;
|
||||
if (num_menu_selections > 0) {
|
||||
menu_item *pick_list;
|
||||
|
||||
win = create_nhwindow(NHW_MENU);
|
||||
start_menu(win);
|
||||
for (k = 0; k < num_menu_selections; ++k) {
|
||||
|
||||
@@ -519,6 +519,25 @@ genericptr_t arg;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* hack for hurtle_step() -- it ought to be changed to take an argument
|
||||
indicating lev/fly-to-dest vs lev/fly-to-dest-minus-one-land-on-dest
|
||||
vs drag-to-dest; original callers use first mode, jumping wants second,
|
||||
grappling hook backfire and thrown chained ball need third */
|
||||
boolean
|
||||
hurtle_jump(arg, x, y)
|
||||
genericptr_t arg;
|
||||
int x, y;
|
||||
{
|
||||
boolean res;
|
||||
long save_EWwalking = EWwalking;
|
||||
|
||||
/* prevent jumping over water from being placed in that water */
|
||||
EWwalking |= I_SPECIAL;
|
||||
res = hurtle_step(arg, x, y);
|
||||
EWwalking = save_EWwalking;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Single step for the hero flying through the air from jumping, flying,
|
||||
* etc. Called from hurtle() and jump() via walk_path(). We expect the
|
||||
@@ -606,8 +625,8 @@ int x, y;
|
||||
}
|
||||
if ((u.ux - x) && (u.uy - y) && bad_rock(youmonst.data, u.ux, y)
|
||||
&& bad_rock(youmonst.data, x, u.uy)) {
|
||||
boolean too_much =
|
||||
(invent && (inv_weight() + weight_cap() > 600));
|
||||
boolean too_much = (invent && (inv_weight() + weight_cap() > 600));
|
||||
|
||||
/* Move at a diagonal. */
|
||||
if (bigmonst(youmonst.data) || too_much) {
|
||||
You("%sget forcefully wedged into a crevice.",
|
||||
@@ -621,14 +640,43 @@ int x, y;
|
||||
}
|
||||
}
|
||||
|
||||
if ((mon = m_at(x, y)) != 0) {
|
||||
You("bump into %s.", a_monnam(mon));
|
||||
if ((mon = m_at(x, y)) != 0
|
||||
#if 0 /* we can't include these two exceptions unless we know we're
|
||||
* going to end up past the current spot rather than on it;
|
||||
* for that, we need to know that the range is not exhausted
|
||||
* and also that the next spot doesn't contain an obstacle */
|
||||
&& !(mon->mundetected && hides_under(mon) && (Flying || Levitation))
|
||||
&& !(mon->mundetected && mon->data->mlet == S_EEL
|
||||
&& (Flying || Levitation || Wwalking))
|
||||
#endif
|
||||
) {
|
||||
const char *mnam, *pronoun;
|
||||
int glyph = glyph_at(x, y);
|
||||
|
||||
mon->mundetected = 0; /* wakeup() will handle mimic */
|
||||
mnam = a_monnam(mon); /* after unhiding */
|
||||
pronoun = mhim(mon);
|
||||
if (!strcmp(mnam, "it")) {
|
||||
/* mhim() uses pronoun_gender() which forces neuter if monster
|
||||
can't be seen; we want him/her for humanoid sensed by touch */
|
||||
if (!strcmp(pronoun, "it") && humanoid(mon->data))
|
||||
pronoun = genders[mon->female].him;
|
||||
mnam = !strcmp(pronoun, "it") ? "something" : "someone";
|
||||
}
|
||||
if (!glyph_is_monster(glyph) && !glyph_is_invisible(glyph))
|
||||
You("find %s by bumping into %s.", mnam, pronoun);
|
||||
else
|
||||
You("bump into %s.", mnam);
|
||||
wakeup(mon, FALSE);
|
||||
if (!canspotmon(mon))
|
||||
map_invisible(mon->mx, mon->my);
|
||||
setmangry(mon, FALSE);
|
||||
wake_nearto(x,y, 10);
|
||||
wake_nearto(x, y, 10);
|
||||
return FALSE;
|
||||
}
|
||||
if ((u.ux - x) && (u.uy - y) && bad_rock(youmonst.data, u.ux, y)
|
||||
|
||||
if ((u.ux - x) && (u.uy - y)
|
||||
&& bad_rock(youmonst.data, u.ux, y)
|
||||
&& bad_rock(youmonst.data, x, u.uy)) {
|
||||
/* Move at a diagonal. */
|
||||
if (Sokoban) {
|
||||
|
||||
57
src/eat.c
57
src/eat.c
@@ -112,8 +112,11 @@ register struct obj *obj;
|
||||
void
|
||||
init_uhunger()
|
||||
{
|
||||
context.botl = (u.uhs != NOT_HUNGRY || ATEMP(A_STR) < 0);
|
||||
u.uhunger = 900;
|
||||
u.uhs = NOT_HUNGRY;
|
||||
if (ATEMP(A_STR) < 0)
|
||||
ATEMP(A_STR) = 0;
|
||||
}
|
||||
|
||||
/* tin types [SPINACH_TIN = -1, overrides corpsenm, nut==600] */
|
||||
@@ -2440,10 +2443,7 @@ doeat()
|
||||
* mails, players who polymorph back to human in the middle of their
|
||||
* metallic meal, etc....
|
||||
*/
|
||||
if (!(carried(otmp) ? retouch_object(&otmp, FALSE)
|
||||
: touch_artifact(otmp, &youmonst))) {
|
||||
return 1;
|
||||
} else if (!is_edible(otmp)) {
|
||||
if (!is_edible(otmp)) {
|
||||
You("cannot eat that!");
|
||||
return 0;
|
||||
} else if ((otmp->owornmask & (W_ARMOR | W_TOOL | W_AMUL | W_SADDLE))
|
||||
@@ -2451,6 +2451,9 @@ doeat()
|
||||
/* let them eat rings */
|
||||
You_cant("eat %s you're wearing.", something);
|
||||
return 0;
|
||||
} else if (!(carried(otmp) ? retouch_object(&otmp, FALSE)
|
||||
: touch_artifact(otmp, &youmonst))) {
|
||||
return 1; /* got blasted so use a turn */
|
||||
}
|
||||
if (is_metallic(otmp) && u.umonnum == PM_RUST_MONSTER
|
||||
&& otmp->oerodeproof) {
|
||||
@@ -2465,13 +2468,26 @@ doeat()
|
||||
/* The regurgitated object's rustproofing is gone now */
|
||||
otmp->oerodeproof = 0;
|
||||
make_stunned((HStun & TIMEOUT) + (long) rn2(10), TRUE);
|
||||
You("spit %s out onto the %s.", the(xname(otmp)),
|
||||
surface(u.ux, u.uy));
|
||||
if (carried(otmp)) {
|
||||
freeinv(otmp);
|
||||
dropy(otmp);
|
||||
/*
|
||||
* We don't expect rust monsters to be wielding welded weapons
|
||||
* or wearing cursed rings which were rustproofed, but guard
|
||||
* against the possibility just in case.
|
||||
*/
|
||||
if (welded(otmp) || (otmp->cursed && (otmp->owornmask & W_RING))) {
|
||||
otmp->bknown = 1; /* for ring; welded() does this for weapon */
|
||||
You("spit out %s.", the(xname(otmp)));
|
||||
} else {
|
||||
You("spit %s out onto the %s.", the(xname(otmp)),
|
||||
surface(u.ux, u.uy));
|
||||
if (carried(otmp)) {
|
||||
/* no need to check for leash in use; it's not metallic */
|
||||
if (otmp->owornmask)
|
||||
remove_worn_item(otmp, FALSE);
|
||||
freeinv(otmp);
|
||||
dropy(otmp);
|
||||
}
|
||||
stackobj(otmp);
|
||||
}
|
||||
stackobj(otmp);
|
||||
return 1;
|
||||
}
|
||||
/* KMH -- Slow digestion is... indigestible */
|
||||
@@ -2961,10 +2977,23 @@ boolean incr;
|
||||
}
|
||||
|
||||
if (newhs != u.uhs) {
|
||||
if (newhs >= WEAK && u.uhs < WEAK)
|
||||
losestr(1); /* this may kill you -- see below */
|
||||
else if (newhs < WEAK && u.uhs >= WEAK)
|
||||
losestr(-1);
|
||||
if (newhs >= WEAK && u.uhs < WEAK) {
|
||||
/* this used to be losestr(1) which had the potential to
|
||||
be fatal (still handled below) by reducing HP if it
|
||||
tried to take base strength below minimum of 3 */
|
||||
ATEMP(A_STR) = -1; /* temporary loss overrides Fixed_abil */
|
||||
/* defer context.botl status update until after hunger message */
|
||||
} else if (newhs < WEAK && u.uhs >= WEAK) {
|
||||
/* this used to be losestr(-1) which could be abused by
|
||||
becoming weak while wearing ring of sustain ability,
|
||||
removing ring, eating to 'restore' strength which boosted
|
||||
strength by a point each time the cycle was performed;
|
||||
substituting "while polymorphed" for sustain ability and
|
||||
"rehumanize" for ring removal might have done that too */
|
||||
ATEMP(A_STR) = 0; /* repair of loss also overrides Fixed_abil */
|
||||
/* defer context.botl status update until after hunger message */
|
||||
}
|
||||
|
||||
switch (newhs) {
|
||||
case HUNGRY:
|
||||
if (Hallucination) {
|
||||
|
||||
@@ -763,6 +763,7 @@ time_t when; /* date+time at end of game */
|
||||
dump_redirect(FALSE);
|
||||
#else
|
||||
nhUse(how);
|
||||
nhUse(when);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 options.c $NHDT-Date: 1507164574 2017/10/05 00:49:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.311 $ */
|
||||
/* NetHack 3.6 options.c $NHDT-Date: 1507846854 2017/10/12 22:20:54 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.315 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -129,6 +129,7 @@ static struct Bool_Opt {
|
||||
{ "fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE },
|
||||
{ "goldX", &iflags.goldX, FALSE, SET_IN_GAME },
|
||||
{ "help", &flags.help, TRUE, SET_IN_GAME },
|
||||
{ "herecmd_menu", &iflags.herecmd_menu, FALSE, SET_IN_GAME },
|
||||
{ "hilite_pet", &iflags.wc_hilite_pet, FALSE, SET_IN_GAME }, /*WC*/
|
||||
{ "hilite_pile", &iflags.hilite_pile, FALSE, SET_IN_GAME },
|
||||
{ "hitpointbar", &iflags.wc2_hitpointbar, FALSE, SET_IN_GAME }, /*WC2*/
|
||||
@@ -3719,8 +3720,19 @@ boolean tinitial, tfrom_file;
|
||||
vision_full_recalc = 1; /* delayed recalc */
|
||||
if (iflags.use_color)
|
||||
need_redraw = TRUE; /* darkroom refresh */
|
||||
} else if (boolopt[i].addr == &iflags.wc_tiled_map
|
||||
|| boolopt[i].addr == &flags.showrace
|
||||
} else if (boolopt[i].addr == &iflags.wc_ascii_map) {
|
||||
/* toggling ascii_map; set tiled_map to its opposite;
|
||||
what does it mean to turn off ascii map if tiled map
|
||||
isn't supported? -- right now, we do nothing */
|
||||
iflags.wc_tiled_map = negated;
|
||||
need_redraw = TRUE;
|
||||
} else if (boolopt[i].addr == &iflags.wc_tiled_map) {
|
||||
/* toggling tiled_map; set ascii_map to its opposite;
|
||||
as with ascii_map, what does it mean to turn off tiled
|
||||
map if ascii map isn't supported? */
|
||||
iflags.wc_ascii_map = negated;
|
||||
need_redraw = TRUE;
|
||||
} else if (boolopt[i].addr == &flags.showrace
|
||||
|| boolopt[i].addr == &iflags.use_inverse
|
||||
|| boolopt[i].addr == &iflags.hilite_pile
|
||||
|| boolopt[i].addr == &iflags.hilite_pet) {
|
||||
@@ -5523,7 +5535,8 @@ const char *mapping;
|
||||
ape = (struct autopickup_exception *) alloc(sizeof *ape);
|
||||
ape->regex = regex_init();
|
||||
if (!regex_compile(text, ape->regex)) {
|
||||
config_error_add("%s: %s", APE_regex_error, regex_error_desc(ape->regex));
|
||||
config_error_add("%s: %s", APE_regex_error,
|
||||
regex_error_desc(ape->regex));
|
||||
regex_free(ape->regex);
|
||||
free((genericptr_t) ape);
|
||||
return 0;
|
||||
@@ -6182,13 +6195,11 @@ STATIC_OVL boolean
|
||||
wc_supported(optnam)
|
||||
const char *optnam;
|
||||
{
|
||||
int k = 0;
|
||||
int k;
|
||||
|
||||
while (wc_options[k].wc_name) {
|
||||
if (!strcmp(wc_options[k].wc_name, optnam)
|
||||
&& (windowprocs.wincap & wc_options[k].wc_bit))
|
||||
return TRUE;
|
||||
k++;
|
||||
for (k = 0; wc_options[k].wc_name; ++k) {
|
||||
if (!strcmp(wc_options[k].wc_name, optnam))
|
||||
return (windowprocs.wincap & wc_options[k].wc_bit) ? TRUE : FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -6242,13 +6253,12 @@ STATIC_OVL boolean
|
||||
wc2_supported(optnam)
|
||||
const char *optnam;
|
||||
{
|
||||
int k = 0;
|
||||
int k;
|
||||
|
||||
while (wc2_options[k].wc_name) {
|
||||
if (!strcmp(wc2_options[k].wc_name, optnam)
|
||||
&& (windowprocs.wincap2 & wc2_options[k].wc_bit))
|
||||
return TRUE;
|
||||
k++;
|
||||
for (k = 0; wc2_options[k].wc_name; ++k) {
|
||||
if (!strcmp(wc2_options[k].wc_name, optnam))
|
||||
return (windowprocs.wincap2 & wc2_options[k].wc_bit) ? TRUE
|
||||
: FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -565,8 +565,8 @@ register struct obj *otmp;
|
||||
i = rn2(A_MAX); /* start at a random point */
|
||||
for (ii = 0; ii < A_MAX; ii++) {
|
||||
lim = AMAX(i);
|
||||
if (i == A_STR && u.uhs >= 3)
|
||||
--lim; /* WEAK */
|
||||
/* this used to adjust 'lim' for A_STR when u.uhs was
|
||||
WEAK or worse, but that's handled via ATEMP(A_STR) now */
|
||||
if (ABASE(i) < lim) {
|
||||
ABASE(i) = lim;
|
||||
context.botl = 1;
|
||||
|
||||
@@ -343,7 +343,7 @@ int trouble;
|
||||
u.utrap = 0;
|
||||
break;
|
||||
case TROUBLE_STARVING:
|
||||
losestr(-1);
|
||||
/* temporarily lost strength recovery now handled by init_uhunger() */
|
||||
/*FALLTHRU*/
|
||||
case TROUBLE_HUNGRY:
|
||||
Your("%s feels content.", body_part(STOMACH));
|
||||
|
||||
@@ -1714,6 +1714,7 @@ boolean confused, helmet_protects, byu, skip_uswallow;
|
||||
}
|
||||
} else
|
||||
dmg = 0;
|
||||
wake_nearto(u.ux, u.uy, 4 * 4);
|
||||
/* Must be before the losehp(), for bones files */
|
||||
if (!flooreffects(otmp2, u.ux, u.uy, "fall")) {
|
||||
place_object(otmp2, u.ux, u.uy);
|
||||
@@ -1779,7 +1780,10 @@ boolean confused, byu;
|
||||
pline("%s is killed.", Monnam(mtmp));
|
||||
mondied(mtmp);
|
||||
}
|
||||
} else {
|
||||
wakeup(mtmp, byu);
|
||||
}
|
||||
wake_nearto(x, y, 4 * 4);
|
||||
} else if (u.uswallow && mtmp == u.ustuck) {
|
||||
obfree(otmp2, (struct obj *) 0);
|
||||
/* fall through to player */
|
||||
|
||||
Reference in New Issue
Block a user