distinguish global variables that get written to savefile

The g? structs had a mix of variables that were written to
the savefile, and those that were not.

For better clarity and to distinguish those that end up in
the savefile, relocate some g? variables that get written
directly to the savefile into different structs.

This updates EDITLEVEL, although technically it probably
didn't need to, since savefile contents are not changing.

Details:

    gb.bases            -> svb.bases
    gb.bbubbles         -> svb.bbubbles
    gb.branches         -> svb.branches
    gc.context          -> svc.context
    gd.disco            -> svd.disco
    gd.dndest           -> svd.dndest
    gd.doors            -> svd.doors
    gd.doors_alloc      -> svd.doors_alloc
    gd.dungeon_topology -> svd.dungeon_topology
    gd.dungeons         -> svd.dungeons
    ge.exclusion_zones  -> sve.exclusion_zones
    gh.hackpid          -> svh.hackpid
    gi.inv_pos          -> svi.inv_pos
    gk.killer           -> svk.killer
    gl.lastseentyp      -> svl.lastseentyp
    gl.level            -> svl.level
    gl.level_info       -> svl.level_info
    gm.mapseenchn       -> svm.mapseenchn
    gm.moves            -> svm.moves
    gm.mvitals          -> svm.mvitals
    gn.n_dgns           -> svn.n_dgns
    gn.n_regions        -> svn.n_regions
    gn.nroom            -> svn.nroom
    go.oracle_cnt       -> svo.oracle_cnt
    gp.pl_character     -> svp.pl_character
    gp.pl_fruit         -> svp.pl_fruit
    gp.plname           -> svp.plname
    gp.program_state    -> svp.program_state
    gq.quest_status     -> svq.quest_status
    gr.rooms            -> svr.rooms
    gs.sp_levchn        -> svs.sp_levchn
    gs.spl_book         -> svs.spl_book
    gt.timer_id         -> svt.timer_id
    gt.tune             -> svt.tune
    gu.updest           -> svu.updest
    gx.xmax             -> svx.xmax
    gx.xmin             -> svx.xmin
    gy.ymax             -> svy.ymax
    gy.ymin             -> svy.ymin

Related note:
There are some pointer variables that are heads of chains that were not
moved from 'g?' to 'sv?', because they are not actually written to the
savefile directly, but the objects/monst/trap/lightsource/timer in the
chains they point to are. That can be changed, if desired.
Examples: gi.invent, gm.migrating_objs, gb.billobjs, gm.migrating_mons,
          gf.ftrap, gl.light_base, gt.timer_base
This commit is contained in:
nhmall
2024-07-13 14:57:50 -04:00
parent 0e4083153c
commit 6c0ae092c6
174 changed files with 3502 additions and 3305 deletions

View File

@@ -177,7 +177,7 @@ staticfn boolean
may_generate_eroded(struct obj *otmp)
{
/* initial hero inventory */
if (gm.moves <= 1 && !gi.in_mklev)
if (svm.moves <= 1 && !gi.in_mklev)
return FALSE;
/* already erodeproof or cannot be eroded */
if (otmp->oerodeproof || !erosion_matters(otmp) || !is_damageable(otmp))
@@ -283,18 +283,18 @@ mkobj(int oclass, boolean artif)
}
if (oclass == SPBOOK_no_NOVEL) {
i = rnd_class(gb.bases[SPBOOK_CLASS], SPE_BLANK_PAPER);
i = rnd_class(svb.bases[SPBOOK_CLASS], SPE_BLANK_PAPER);
oclass = SPBOOK_CLASS; /* for sanity check below */
} else {
prob = rnd(go.oclass_prob_totals[oclass]);
i = gb.bases[oclass];
i = svb.bases[oclass];
while ((prob -= objects[i].oc_prob) > 0)
++i;
}
if (objects[i].oc_class != oclass || !OBJ_NAME(objects[i])) {
impossible("probtype error, oclass=%d i=%d", (int) oclass, i);
i = gb.bases[oclass];
i = svb.bases[oclass];
}
return mksobj(i, TRUE, artif);
@@ -321,7 +321,7 @@ mkbox_cnts(struct obj *box)
case SACK:
case OILSKIN_SACK:
/* initial inventory: sack starts out empty */
if (gm.moves <= 1 && !gi.in_mklev) {
if (svm.moves <= 1 && !gi.in_mklev) {
n = 0;
break;
}
@@ -473,8 +473,8 @@ splitobj(struct obj *obj, long num)
otmp->lua_ref_cnt = 0;
otmp->pickup_prev = 0;
gc.context.objsplit.parent_oid = obj->o_id;
gc.context.objsplit.child_oid = otmp->o_id;
svc.context.objsplit.parent_oid = obj->o_id;
svc.context.objsplit.child_oid = otmp->o_id;
obj->nobj = otmp;
/* Only set nexthere when on the floor; nexthere is also used
as a back pointer to the container object when contained.
@@ -504,7 +504,7 @@ splitobj(struct obj *obj, long num)
unsigned
next_ident(void)
{
unsigned res = gc.context.ident;
unsigned res = svc.context.ident;
/* +rnd(2): originally just +1; changed to rnd() to avoid potential
exploit of player using #adjust to split an object stack in a manner
@@ -514,14 +514,14 @@ next_ident(void)
next object to be created was knowable and player could make a wish
under controlled circumstances for an item that is affected by the
low bits of its obj->o_id [particularly helm of opposite alignment] */
gc.context.ident += rnd(2); /* ready for next new object or monster */
svc.context.ident += rnd(2); /* ready for next new object or monster */
/* if ident has wrapped to 0, force it to be non-zero; if/when it
ever wraps past 0 (unlikely, but possible on a configuration which
uses 16-bit 'int'), just live with that and hope no o_id conflicts
between objects or m_id conflicts between monsters arise */
if (!gc.context.ident)
gc.context.ident = rnd(2);
if (!svc.context.ident)
svc.context.ident = rnd(2);
return res;
}
@@ -532,7 +532,7 @@ staticfn unsigned
nextoid(struct obj *oldobj, struct obj *newobj)
{
int olddif, newdif, trylimit = 256; /* limit of 4 suffices at present */
unsigned oid = gc.context.ident - 1; /* loop increment will reverse -1 */
unsigned oid = svc.context.ident - 1; /* loop increment will reverse -1 */
olddif = oid_price_adjustment(oldobj, oldobj->o_id);
do {
@@ -541,7 +541,7 @@ nextoid(struct obj *oldobj, struct obj *newobj)
++oid;
newdif = oid_price_adjustment(newobj, oid);
} while (newdif != olddif && --trylimit >= 0);
gc.context.ident = oid; /* update 'last ident used' */
svc.context.ident = oid; /* update 'last ident used' */
(void) next_ident(); /* increment context.ident for next use */
return oid; /* caller will use this ident */
}
@@ -582,17 +582,17 @@ unsplitobj(struct obj *obj)
}
/* first try the expected case; obj is split from another stack */
if (obj->o_id == gc.context.objsplit.child_oid) {
if (obj->o_id == svc.context.objsplit.child_oid) {
/* parent probably precedes child and will require list traversal */
ochild = obj;
target_oid = gc.context.objsplit.parent_oid;
target_oid = svc.context.objsplit.parent_oid;
if (obj->nobj && obj->nobj->o_id == target_oid)
oparent = obj->nobj;
} else if (obj->o_id == gc.context.objsplit.parent_oid) {
} else if (obj->o_id == svc.context.objsplit.parent_oid) {
/* alternate scenario: another stack was split from obj;
child probably follows parent and will be found here */
oparent = obj;
target_oid = gc.context.objsplit.child_oid;
target_oid = svc.context.objsplit.child_oid;
if (obj->nobj && obj->nobj->o_id == target_oid)
ochild = obj->nobj;
}
@@ -621,7 +621,7 @@ unsplitobj(struct obj *obj)
void
clear_splitobjs(void)
{
gc.context.objsplit.parent_oid = gc.context.objsplit.child_oid = 0;
svc.context.objsplit.parent_oid = svc.context.objsplit.child_oid = 0;
}
/*
@@ -666,7 +666,7 @@ replace_object(struct obj *obj, struct obj *otmp)
obj->nobj = otmp;
obj->nexthere = otmp;
extract_nobj(obj, &fobj);
extract_nexthere(obj, &gl.level.objects[obj->ox][obj->oy]);
extract_nexthere(obj, &svl.level.objects[obj->ox][obj->oy]);
break;
default:
panic("replace_object: obj position");
@@ -889,11 +889,11 @@ mksobj_init(struct obj *otmp, boolean artif)
tryct = 50;
do
otmp->corpsenm = undead_to_corpse(rndmonnum());
while ((gm.mvitals[otmp->corpsenm].mvflags & G_NOCORPSE)
while ((svm.mvitals[otmp->corpsenm].mvflags & G_NOCORPSE)
&& (--tryct > 0));
if (tryct == 0) {
/* perhaps rndmonnum() only wants to make G_NOCORPSE
monsters on this gl.level; create an adventurer's
monsters on this svl.level; create an adventurer's
corpse instead, then */
otmp->corpsenm = PM_HUMAN;
}
@@ -919,7 +919,7 @@ mksobj_init(struct obj *otmp, boolean artif)
for (tryct = 200; tryct > 0; --tryct) {
mndx = undead_to_corpse(rndmonnum());
if (mons[mndx].cnutrit
&& !(gm.mvitals[mndx].mvflags & G_NOCORPSE)) {
&& !(svm.mvitals[mndx].mvflags & G_NOCORPSE)) {
otmp->corpsenm = mndx;
set_tin_variety(otmp, RANDOM_TIN);
break;
@@ -928,7 +928,7 @@ mksobj_init(struct obj *otmp, boolean artif)
blessorcurse(otmp, 10);
break;
case SLIME_MOLD:
otmp->spe = gc.context.current_fruit;
otmp->spe = svc.context.current_fruit;
flags.made_fruit = TRUE;
break;
case KELP_FROND:
@@ -1046,7 +1046,7 @@ mksobj_init(struct obj *otmp, boolean artif)
break;
case AMULET_CLASS:
if (otmp->otyp == AMULET_OF_YENDOR)
gc.context.made_amulet = TRUE;
svc.context.made_amulet = TRUE;
if (rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION
|| otmp->otyp == AMULET_OF_CHANGE
|| otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) {
@@ -1086,7 +1086,7 @@ mksobj_init(struct obj *otmp, boolean artif)
otmp = mk_artifact(otmp, (aligntyp) A_NONE);
/* simulate lacquered armor for samurai */
if (Role_if(PM_SAMURAI) && otmp->otyp == SPLINT_MAIL
&& (gm.moves <= 1 || In_quest(&u.uz))) {
&& (svm.moves <= 1 || In_quest(&u.uz))) {
#ifdef UNIXPC
/* optimizer bitfield bug */
otmp->oerodeproof = 1;
@@ -1160,7 +1160,7 @@ mksobj(int otyp, boolean init, boolean artif)
otmp = newobj();
*otmp = cg.zeroobj;
otmp->age = gm.moves;
otmp->age = svm.moves;
otmp->o_id = next_ident();
otmp->quan = 1L;
otmp->oclass = let;
@@ -1181,7 +1181,7 @@ mksobj(int otyp, boolean init, boolean artif)
case CORPSE:
if (otmp->corpsenm == NON_PM) {
otmp->corpsenm = undead_to_corpse(rndmonnum());
if (gm.mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE | G_GONE))
if (svm.mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE | G_GONE))
otmp->corpsenm = gu.urole.mnum;
}
/*FALLTHRU*/
@@ -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 = gm.moves - body->age;
age = svm.moves - body->age;
if (age > ROT_AGE)
when = rot_adjust;
else
@@ -1460,9 +1460,9 @@ shrink_glob(
/*
* If shrinkage occurred while we were on another level, catch up now.
*/
if (expire_time < gm.moves && globloc != BURIED_UNDER_ICE) {
if (expire_time < svm.moves && globloc != BURIED_UNDER_ICE) {
/* number of units of weight to remove */
long delta = (gm.moves - expire_time + 24L) / 25L,
long delta = (svm.moves - expire_time + 24L) / 25L,
/* leftover amount to use for new timer */
moddelta = 25L - (delta % 25L);
@@ -1501,7 +1501,7 @@ shrink_glob(
*/
if (eating_glob(obj)
|| globloc == BURIED_UNDER_ICE
|| (globloc == SET_ON_ICE && (gm.moves % 3L) == 1L)) {
|| (globloc == SET_ON_ICE && (svm.moves % 3L) == 1L)) {
/* schedule next shrink attempt; for the being eaten case, the
glob and its timer might be deleted before this kicks in */
start_glob_timeout(obj, 0L);
@@ -1803,7 +1803,7 @@ set_bknown(
{
if (obj->bknown != onoff) {
obj->bknown = onoff;
if (obj->where == OBJ_INVENT && gm.moves > 1L)
if (obj->where == OBJ_INVENT && svm.moves > 1L)
update_inventory();
}
}
@@ -1964,7 +1964,7 @@ fixup_oil(
} else if (source && source->otyp == POT_OIL) {
/* potion is no longer oil, being turned into non-oil */
if (potion->age == source->age)
potion->age = gm.moves;
potion->age = svm.moves;
/* when source is a partly used oil, mark potion as diluted */
if (source->age < MAX_OIL_IN_FLASK)
potion->odiluted = 1;
@@ -2246,7 +2246,7 @@ place_object(struct obj *otmp, coordxy x, coordxy y)
safe_typename(otmp->otyp), otmp->where);
assert(x >= 0 && x < COLNO && y >= 0 && y < ROWNO);
otmp2 = gl.level.objects[x][y];
otmp2 = svl.level.objects[x][y];
obj_no_longer_held(otmp);
if (otmp->otyp == BOULDER) {
@@ -2266,7 +2266,7 @@ place_object(struct obj *otmp, coordxy x, coordxy y)
} else {
/* put on top of current pile */
otmp->nexthere = otmp2;
gl.level.objects[x][y] = otmp;
svl.level.objects[x][y] = otmp;
}
/* set the object's new location */
@@ -2294,7 +2294,7 @@ recreate_pile_at(coordxy x, coordxy y)
struct obj *otmp, *next_obj, *reversed = 0;
/* remove all objects at <x,y>, saving a reversed temporary list */
for (otmp = gl.level.objects[x][y]; otmp; otmp = next_obj) {
for (otmp = svl.level.objects[x][y]; otmp; otmp = next_obj) {
next_obj = otmp->nexthere;
remove_object(otmp); /* obj_extract_self() for floor */
otmp->nobj = reversed;
@@ -2319,12 +2319,12 @@ obj_ice_effects(coordxy x, coordxy y, boolean do_buried)
{
struct obj *otmp;
for (otmp = gl.level.objects[x][y]; otmp; otmp = otmp->nexthere) {
for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) {
if (otmp->timed)
obj_timer_checks(otmp, x, y, 0);
}
if (do_buried) {
for (otmp = gl.level.buriedobjlist; otmp; otmp = otmp->nobj) {
for (otmp = svl.level.buriedobjlist; otmp; otmp = otmp->nobj) {
if (otmp->ox == x && otmp->oy == y) {
if (otmp->timed)
obj_timer_checks(otmp, x, y, 0);
@@ -2347,12 +2347,12 @@ peek_at_iced_corpse_age(struct obj *otmp)
if (otmp->otyp == CORPSE && otmp->on_ice) {
/* Adjust the age; must be same as obj_timer_checks() for off ice*/
age = gm.moves - otmp->age;
age = svm.moves - otmp->age;
retval += age * (ROT_ICE_ADJUSTMENT - 1) / ROT_ICE_ADJUSTMENT;
debugpline3(
"The %s age has ice modifications: otmp->age = %ld, returning %ld.",
s_suffix(doname(otmp)), otmp->age, retval);
debugpline1("Effective age of corpse: %ld.", gm.moves - retval);
debugpline1("Effective age of corpse: %ld.", svm.moves - retval);
}
return retval;
}
@@ -2391,8 +2391,8 @@ obj_timer_checks(
later calculations behave as if it had been on ice during
that time (longwinded way of saying this is the inverse
of removing it from the ice and of peeking at its age). */
age = gm.moves - otmp->age;
otmp->age = gm.moves - (age * ROT_ICE_ADJUSTMENT);
age = svm.moves - otmp->age;
otmp->age = svm.moves - (age * ROT_ICE_ADJUSTMENT);
}
/* Check for corpses coming off ice */
@@ -2413,7 +2413,7 @@ obj_timer_checks(
tleft /= ROT_ICE_ADJUSTMENT;
restart_timer = TRUE;
/* Adjust the age */
age = gm.moves - otmp->age;
age = svm.moves - otmp->age;
otmp->age += age * (ROT_ICE_ADJUSTMENT - 1) / ROT_ICE_ADJUSTMENT;
}
}
@@ -2433,7 +2433,7 @@ remove_object(struct obj *otmp)
if (otmp->where != OBJ_FLOOR)
panic("remove_object: obj not on floor");
extract_nexthere(otmp, &gl.level.objects[x][y]);
extract_nexthere(otmp, &svl.level.objects[x][y]);
extract_nobj(otmp, &fobj);
/* update vision iff this was the only boulder at its spot */
if (otmp->otyp == BOULDER && !sobj_at(BOULDER, x, y))
@@ -2502,7 +2502,7 @@ obj_extract_self(struct obj *obj)
extract_nobj(obj, &gm.migrating_objs);
break;
case OBJ_BURIED:
extract_nobj(obj, &gl.level.buriedobjlist);
extract_nobj(obj, &svl.level.buriedobjlist);
break;
case OBJ_ONBILL:
extract_nobj(obj, &gb.billobjs);
@@ -2645,8 +2645,8 @@ add_to_buried(struct obj *obj)
panic("add_to_buried: obj not free");
obj->where = OBJ_BURIED;
obj->nobj = gl.level.buriedobjlist;
gl.level.buriedobjlist = obj;
obj->nobj = svl.level.buriedobjlist;
svl.level.buriedobjlist = obj;
}
/* recalculate weight of object, which doesn't have to be a container
@@ -2706,9 +2706,9 @@ dealloc_obj(struct obj *obj)
/* if obj came from the most recent splitobj(), it's no longer eligible
for unsplitobj(); perform inline clear_splitobjs() */
if (obj->o_id == gc.context.objsplit.parent_oid
|| obj->o_id == gc.context.objsplit.child_oid)
gc.context.objsplit.parent_oid = gc.context.objsplit.child_oid = 0;
if (obj->o_id == svc.context.objsplit.parent_oid
|| obj->o_id == svc.context.objsplit.child_oid)
svc.context.objsplit.parent_oid = svc.context.objsplit.child_oid = 0;
if (obj->lua_ref_cnt) {
/* obj is referenced from a lua script, let lua gc free it */
@@ -2871,7 +2871,7 @@ obj_sanity_check(void)
for (y = 0; y < ROWNO; y++) {
char at_fmt[BUFSZ];
otop = gl.level.objects[x][y];
otop = svl.level.objects[x][y];
prevo = 0;
for (obj = otop; obj; prevo = obj, obj = prevo->nexthere) {
/* <ox,oy> should match <x,y>; <0,*> should always be empty */
@@ -2905,7 +2905,7 @@ obj_sanity_check(void)
objlist_sanity(gi.invent, OBJ_INVENT, "invent sanity");
objlist_sanity(gm.migrating_objs, OBJ_MIGRATING, "migrating sanity");
objlist_sanity(gl.level.buriedobjlist, OBJ_BURIED, "buried sanity");
objlist_sanity(svl.level.buriedobjlist, OBJ_BURIED, "buried sanity");
objlist_sanity(gb.billobjs, OBJ_ONBILL, "bill sanity");
objlist_sanity(go.objs_deleted, OBJ_DELETED, "deleted object sanity");
@@ -3262,7 +3262,7 @@ init_dummyobj(struct obj *obj, short otyp, long oquan)
obj->next_boulder = 0; /* overloads corpsenm, avoid NON_PM */
/* but suppressing fruit details leads to "bad fruit #0" */
if (obj->otyp == SLIME_MOLD)
obj->spe = gc.context.current_fruit;
obj->spe = svc.context.current_fruit;
}
return obj;
}
@@ -3621,11 +3621,11 @@ obj_absorb(struct obj **obj1, struct obj **obj2)
o2wt = otmp2->oeaten ? otmp2->oeaten : otmp2->owt;
/* averaging the relative ages is less likely to overflow
than averaging the absolute ages directly */
agetmp = (((gm.moves - otmp1->age) * o1wt
+ (gm.moves - otmp2->age) * o2wt)
agetmp = (((svm.moves - otmp1->age) * o1wt
+ (svm.moves - otmp2->age) * o2wt)
/ (o1wt + o2wt));
/* convert relative age back to absolute age */
otmp1->age = gm.moves - agetmp;
otmp1->age = svm.moves - agetmp;
otmp1->owt += o2wt;
if (otmp1->oeaten || otmp2->oeaten)
otmp1->oeaten = o1wt + o2wt;