restore vs perm_invent

Redo how updates of permanent inventory window are suppressed during
restore.  Reverses part of e9f1e03271
which included a simpler attempt to deal with this.

It looks like we should have been getting impossible "unpaid_cost:
object wasn't on any bill" but segfault was reported; I haven't tried
to figure out why.  The band in xname() ought to be redundant now but
is included for bulletproofing.
This commit is contained in:
PatR
2018-07-05 16:06:31 -07:00
parent 2596052c39
commit 777d9d922d
5 changed files with 28 additions and 17 deletions

View File

@@ -65,6 +65,9 @@ eating rings while polymorphed didn't handle bonus/penalty for increase damage,
shopkeeper's position in front of shop door didn't correctly handle bottom
edge of irregularly shaped shop due to typo or copy+paste error
(latent bug; no such shops are present in 3.6.x)
attempting to update permanent inventory window during restore had problems
with unpaid items (needed shop bill before shop and its shopkeeper
were restored) and named fruit
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository

View File

@@ -1194,7 +1194,9 @@ unsigned doname_flags;
Strcat(bp, " (at the ready)");
}
}
if (!iflags.suppress_price && is_unpaid(obj)) {
/* treat 'restoring' like suppress_price because shopkeeper and
bill might not be available yet while restore is in progress */
if (!iflags.suppress_price && !restoring && is_unpaid(obj)) {
long quotedprice = unpaid_cost(obj, TRUE);
Sprintf(eos(bp), " (%s, %ld %s)",

View File

@@ -35,8 +35,7 @@ STATIC_DCL struct monst *FDECL(restmonchn, (int, BOOLEAN_P));
STATIC_DCL struct fruit *FDECL(loadfruitchn, (int));
STATIC_DCL void FDECL(freefruitchn, (struct fruit *));
STATIC_DCL void FDECL(ghostfruit, (struct obj *));
STATIC_DCL boolean
FDECL(restgamestate, (int, unsigned int *, unsigned int *));
STATIC_DCL boolean FDECL(restgamestate, (int, unsigned int *, unsigned int *));
STATIC_DCL void FDECL(restlevelstate, (unsigned int, unsigned int));
STATIC_DCL int FDECL(restlevelfile, (int, XCHAR_P));
STATIC_OVL void FDECL(restore_msghistory, (int));
@@ -521,6 +520,7 @@ unsigned int *stuckid, *steedid;
struct obj *otmp, *tmp_bc;
char timebuf[15];
unsigned long uid;
boolean defer_perm_invent;
mread(fd, (genericptr_t) &uid, sizeof uid);
if (SYSOPT_CHECK_SAVE_UID
@@ -531,7 +531,7 @@ unsigned int *stuckid, *steedid;
if (!wizard)
return FALSE;
}
mread(fd, (genericptr_t) &context, sizeof(struct context_info));
mread(fd, (genericptr_t) &context, sizeof (struct context_info));
if (context.warntype.speciesidx >= LOW_PM)
context.warntype.species = &mons[context.warntype.speciesidx];
@@ -539,7 +539,13 @@ unsigned int *stuckid, *steedid;
file option values instead of keeping old save file option values
if partial restore fails and we resort to starting a new game */
newgameflags = flags;
mread(fd, (genericptr_t) &flags, sizeof(struct flag));
mread(fd, (genericptr_t) &flags, sizeof (struct flag));
/* avoid keeping permanent inventory window up to date during restore
(setworn() calls update_inventory); attempting to include the cost
of unpaid items before shopkeeper's bill is available is a no-no;
named fruit names aren't accessible yet either */
defer_perm_invent = flags.perm_invent;
flags.perm_invent = FALSE;
/* wizard and discover are actually flags.debug and flags.explore;
player might be overriding the save file values for them;
in the discover case, we don't want to set that for a normal
@@ -645,14 +651,14 @@ unsigned int *stuckid, *steedid;
restlevchn(fd);
mread(fd, (genericptr_t) &moves, sizeof moves);
mread(fd, (genericptr_t) &monstermoves, sizeof monstermoves);
mread(fd, (genericptr_t) &quest_status, sizeof(struct q_score));
mread(fd, (genericptr_t) spl_book, sizeof(struct spell) * (MAXSPELL + 1));
mread(fd, (genericptr_t) &quest_status, sizeof (struct q_score));
mread(fd, (genericptr_t) spl_book, (MAXSPELL + 1) * sizeof (struct spell));
restore_artifacts(fd);
restore_oracles(fd);
if (u.ustuck)
mread(fd, (genericptr_t) stuckid, sizeof(*stuckid));
mread(fd, (genericptr_t) stuckid, sizeof *stuckid);
if (u.usteed)
mread(fd, (genericptr_t) steedid, sizeof(*steedid));
mread(fd, (genericptr_t) steedid, sizeof *steedid);
mread(fd, (genericptr_t) pl_character, sizeof pl_character);
mread(fd, (genericptr_t) pl_fruit, sizeof pl_fruit);
@@ -665,6 +671,8 @@ unsigned int *stuckid, *steedid;
/* must come after all mons & objs are restored */
relink_timers(FALSE);
relink_light_sources(FALSE);
/* inventory display is now viable */
flags.perm_invent = defer_perm_invent;
return TRUE;
}

View File

@@ -112,7 +112,6 @@ register struct obj *obj;
: !is_weptool(obj) && !is_wet_towel(obj);
} else
unweapon = TRUE; /* for "bare hands" message */
update_inventory();
}
STATIC_OVL boolean
@@ -230,7 +229,9 @@ setuqwep(obj)
register struct obj *obj;
{
setworn(obj, W_QUIVER);
update_inventory();
/* no extra handling needed; this used to include a call to
update_inventory() but that's already performed by setworn() */
return;
}
void
@@ -238,7 +239,7 @@ setuswapwep(obj)
register struct obj *obj;
{
setworn(obj, W_SWAPWEP);
update_inventory();
return;
}
/*** Commands to change particular slot(s) ***/

View File

@@ -106,8 +106,7 @@ long mask;
}
}
}
if (!restoring)
update_inventory();
update_inventory();
}
/* called e.g. when obj is destroyed */
@@ -138,9 +137,7 @@ register struct obj *obj;
if ((p = w_blocks(obj, wp->w_mask)) != 0)
u.uprops[p].blocked &= ~wp->w_mask;
}
/* setnotworn() isn't called during restore but parallel setworn() */
if (!restoring)
update_inventory();
update_inventory();
}
/* return item worn in slot indiciated by wornmask; needed by poly_obj() */