github issue #1275: curses init vs pauper
Reported by ars3niy, the curses interface could behave strangely on the first turn if the 'pauper' option/conduct was specified. There isn't any definitive flag indicating whether or not the game has started. Since 'moves' has traditionally been initialized to 1 rather than to 0, there were several instances of | if (moves <= 1 && invent != NULL) being used to determine the starting state on the assumption that once hero has inventory, the game has begun. Introduction of the 'pauper' option made the test for non-Null invent become unreliable. For paupers, the program would behave as if the game hadn't started yet until the player finally made a time-consuming move. This changes compile-time initialization of 'moves' from 1 to 0, then sets it to 1 when initial inventory would be bestowed (even when 'pauper' inhibits that). That's probably not the best place for it, but testing for 'moves==0' now should produce an identical effect as 'moves<=1 && invent!=NULL' used to accomplish. It would have been much simpler just to give paupers 1 gold piece, or perhaps one rock, in place of usual starting gear so that their initial inventory wouldn't be empty, but the moves+invent way of checking for start-of-play has always bothered me. Should 'pauper' be preventing 'nethack -X' from giving its starting wand of wishing? Conducts and explore mode don't really overlap so maybe it doesn't matter. Fixes #1275
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1464 $ $NHDT-Date: 1723945837 2024/08/18 01:50:37 $
|
||||
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1471 $ $NHDT-Date: 1725138479 2024/08/31 21:07:59 $
|
||||
|
||||
General Fixes and Modified Features
|
||||
-----------------------------------
|
||||
@@ -2021,6 +2021,9 @@ having #terrain display gas cloud regions as if they were traps didn't work
|
||||
when a monster within a gas cloud was displayed on the map because the hero
|
||||
was next to it, it remained displayed if hero moved away
|
||||
eating a pyrolisk egg on the floor triggered an "object lost" panic
|
||||
core object creation and the curses interface's window handling both became
|
||||
confused by the 'pauper' option/conduct because they assumed that invent
|
||||
being Null meant that the game hadn't started yet
|
||||
|
||||
|
||||
Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 attrib.c $NHDT-Date: 1651908297 2022/05/07 07:24:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.86 $ */
|
||||
/* NetHack 3.7 attrib.c $NHDT-Date: 1725138479 2024/08/31 21:07:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */
|
||||
/* Copyright 1988, 1989, 1990, 1992, M. Stephenson */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1072,7 +1072,7 @@ newhp(void)
|
||||
hp += rnd(gu.urole.hpadv.inrnd);
|
||||
if (gu.urace.hpadv.inrnd > 0)
|
||||
hp += rnd(gu.urace.hpadv.inrnd);
|
||||
if (svm.moves <= 1L) { /* initial hero; skip for polyself to new man */
|
||||
if (svm.moves == 0) { /* initial hero; skip for polyself to new man */
|
||||
/* Initialize alignment stuff */
|
||||
u.ualign.type = aligns[flags.initalign].value;
|
||||
u.ualign.record = gu.urole.initrecord;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 decl.c $NHDT-Date: 1720074480 2024/07/04 06:28:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.334 $ */
|
||||
/* NetHack 3.7 decl.c $NHDT-Date: 1725138480 2024/08/31 21:08:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.337 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Michael Allison, 2009. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -963,7 +963,7 @@ static const struct instance_globals_saved_m init_svm = {
|
||||
/* dungeon.c */
|
||||
UNDEFINED_PTR, /* mapseenchn */
|
||||
/* decl.c */
|
||||
1L, /* moves; misnamed turn counter */
|
||||
0L, /* moves; misnamed turn counter */
|
||||
{ UNDEFINED_VALUES } /* mvitals */
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 mkobj.c $NHDT-Date: 1718999849 2024/06/21 19:57:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.299 $ */
|
||||
/* NetHack 3.7 mkobj.c $NHDT-Date: 1725138481 2024/08/31 21:08:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.304 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1160,7 +1160,7 @@ mksobj(int otyp, boolean init, boolean artif)
|
||||
|
||||
otmp = newobj();
|
||||
*otmp = cg.zeroobj;
|
||||
otmp->age = svm.moves;
|
||||
otmp->age = max(svm.moves, 1L);
|
||||
otmp->o_id = next_ident();
|
||||
otmp->quan = 1L;
|
||||
otmp->oclass = let;
|
||||
@@ -1341,7 +1341,7 @@ start_corpse_timeout(struct obj *body)
|
||||
|
||||
action = ROT_CORPSE; /* default action: rot away */
|
||||
rot_adjust = gi.in_mklev ? 25 : 10; /* give some variation */
|
||||
age = svm.moves - body->age;
|
||||
age = max(svm.moves, 1) - body->age;
|
||||
if (age > ROT_AGE)
|
||||
when = rot_adjust;
|
||||
else
|
||||
@@ -2381,8 +2381,7 @@ obj_timer_checks(
|
||||
|
||||
/* mark the corpse as being on ice */
|
||||
otmp->on_ice = 1;
|
||||
debugpline3("%s is now on ice at <%d,%d>.", The(xname(otmp)), x,
|
||||
y);
|
||||
debugpline3("%s is now on ice at <%d,%d>.", The(xname(otmp)), x, y);
|
||||
/* Adjust the time remaining */
|
||||
tleft *= ROT_ICE_ADJUSTMENT;
|
||||
restart_timer = TRUE;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 u_init.c $NHDT-Date: 1711165379 2024/03/23 03:42:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ */
|
||||
/* NetHack 3.7 u_init.c $NHDT-Date: 1725138482 2024/08/31 21:08:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.110 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2017. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -617,6 +617,12 @@ u_init_role(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* the program used to check moves<=1 && invent==NULL do decide whether
|
||||
a new game has started, but due to the 'pauper' option/conduct, can't
|
||||
rely on invent becoming non-Null anymore; instead, initialize moves
|
||||
to 0 instead of 1 and then set it to 1 here, where invent init occurs */
|
||||
svm.moves = 1L;
|
||||
|
||||
switch (Role_switch) {
|
||||
/* rn2(100) > 50 necessary for some choices because some
|
||||
* random number generators are bad enough to seriously
|
||||
|
||||
@@ -227,7 +227,7 @@ curses_character_input_dialog(
|
||||
re-activate them now that input is being requested */
|
||||
curses_got_input();
|
||||
|
||||
if (gi.invent || (svm.moves > 1)) {
|
||||
if (svm.moves > 0) {
|
||||
curses_get_window_size(MAP_WIN, &map_height, &map_width);
|
||||
} else {
|
||||
map_height = term_rows;
|
||||
@@ -789,7 +789,7 @@ curses_display_nhmenu(
|
||||
menu_determine_pages(current_menu);
|
||||
|
||||
/* Display pre and post-game menus centered */
|
||||
if ((svm.moves <= 1 && !gi.invent) || program_state.gameover) {
|
||||
if (svm.moves == 0 || program_state.gameover) {
|
||||
win = curses_create_window(wid, current_menu->width,
|
||||
current_menu->height, CENTER);
|
||||
} else { /* Display during-game menus on the right out of the way */
|
||||
|
||||
@@ -69,7 +69,7 @@ curses_create_window(int wid, int width, int height, orient orientation)
|
||||
|
||||
if ((orientation == UP) || (orientation == DOWN) ||
|
||||
(orientation == LEFT) || (orientation == RIGHT)) {
|
||||
if (gi.invent || (svm.moves > 1)) {
|
||||
if (svm.moves > 0) {
|
||||
map_border = curses_window_has_border(MAP_WIN);
|
||||
curses_get_window_xy(MAP_WIN, &mapx, &mapy);
|
||||
curses_get_window_size(MAP_WIN, &maph, &mapw);
|
||||
@@ -104,7 +104,7 @@ curses_create_window(int wid, int width, int height, orient orientation)
|
||||
starty = (term_rows / 2) - (height / 2);
|
||||
break;
|
||||
case UP:
|
||||
if (gi.invent || (svm.moves > 1)) {
|
||||
if (svm.moves > 0) {
|
||||
startx = (mapw / 2) - (width / 2) + mapx + mapb_offset;
|
||||
} else {
|
||||
startx = 0;
|
||||
@@ -113,7 +113,7 @@ curses_create_window(int wid, int width, int height, orient orientation)
|
||||
starty = mapy + mapb_offset;
|
||||
break;
|
||||
case DOWN:
|
||||
if (gi.invent || (svm.moves > 1)) {
|
||||
if (svm.moves > 0) {
|
||||
startx = (mapw / 2) - (width / 2) + mapx + mapb_offset;
|
||||
} else {
|
||||
startx = 0;
|
||||
@@ -129,7 +129,7 @@ curses_create_window(int wid, int width, int height, orient orientation)
|
||||
starty = term_rows - height;
|
||||
break;
|
||||
case RIGHT:
|
||||
if (gi.invent || (svm.moves > 1)) {
|
||||
if (svm.moves > 0) {
|
||||
startx = (mapw + mapx + (mapb_offset * 2)) - width;
|
||||
} else {
|
||||
startx = term_cols - width;
|
||||
@@ -222,7 +222,7 @@ curses_refresh_nethack_windows(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((svm.moves <= 1) && !gi.invent) {
|
||||
if (svm.moves == 0) {
|
||||
/* Main windows not yet displayed; refresh base window instead */
|
||||
touchwin(stdscr);
|
||||
refresh();
|
||||
|
||||
Reference in New Issue
Block a user