From: nhmall Date: Mon, 27 May 2019 20:38:09 +0000 (-0400) Subject: Merge branch 'NetHack-3.6' X-Git-Tag: NetHack-3.7.0_WIP~400 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=df495c2ce6be65e6ad6bb0578fd79a96f7f0dcf8;p=nethack Merge branch 'NetHack-3.6' --- df495c2ce6be65e6ad6bb0578fd79a96f7f0dcf8 diff --cc src/end.c index 21a10c5e3,67ae532f1..daebeb9e2 --- a/src/end.c +++ b/src/end.c @@@ -973,6 -997,55 +974,55 @@@ int what } #endif + /* deal with some objects which may be in an abnormal state at end of game */ + STATIC_OVL void + done_object_cleanup() + { + int ox, oy; + + /* might have been killed while using a disposable item, so make sure + it's gone prior to inventory disclosure and creation of bones */ + inven_inuse(TRUE); + /* + * Hero can die when throwing an object (by hitting an adjacent + * gas spore, for instance, or being hit by mis-returning Mjollnir), + * or while in transit (from falling down stairs). If that happens, + * some object(s) might be in limbo rather than on the map or in + * any inventory. Saving bones with an active light source in limbo + * would trigger an 'object not local' panic. + * - * We used to use dealloc_obj() on thrownobj and kickedobj but ++ * We used to use dealloc_obj() on g.thrownobj and g.kickedobj but + * that keeps them out of bones and could leave uball in a confused + * state (gone but still attached). Place them on the map but + * bypass flooreffects(). That could lead to minor anomalies in + * bones, like undamaged paper at water or lava locations or piles + * not being knocked down holes, but it seems better to get this + * game over with than risk being tangled up in more and more details. + */ + ox = u.ux + u.dx, oy = u.uy + u.dy; + if (!isok(ox, oy) || !accessible(ox, oy)) + ox = u.ux, oy = u.uy; + /* put thrown or kicked object on map (for bones); location might + be incorrect (perhaps killed by divine lightning when throwing at + a temple priest?) but this should be better than just vanishing + (fragile stuff should be taken care of before getting here) */ - if (thrownobj && thrownobj->where == OBJ_FREE) { - place_object(thrownobj, ox, oy); - stackobj(thrownobj), thrownobj = 0; ++ if (g.thrownobj && g.thrownobj->where == OBJ_FREE) { ++ place_object(g.thrownobj, ox, oy); ++ stackobj(g.thrownobj), g.thrownobj = 0; + } - if (kickedobj && kickedobj->where == OBJ_FREE) { - place_object(kickedobj, ox, oy); - stackobj(kickedobj), kickedobj = 0; ++ if (g.kickedobj && g.kickedobj->where == OBJ_FREE) { ++ place_object(g.kickedobj, ox, oy); ++ stackobj(g.kickedobj), g.kickedobj = 0; + } + /* if Punished hero dies during level change or dies or quits while + swallowed, uball and uchain will be in limbo; put them on floor + so bones will have them and object list cleanup finds them */ + if (uchain && uchain->where == OBJ_FREE) { + placebc(); + } + return; + } + /* called twice; first to calculate total, then to list relevant items */ STATIC_OVL void artifact_score(list, counting, endwin) @@@ -1144,15 -1217,10 +1194,10 @@@ int how /* render vision subsystem inoperative */ iflags.vision_inited = 0; - /* might have been killed while using a disposable item, so make sure - it's gone prior to inventory disclosure and creation of bones data */ - inven_inuse(TRUE); - /* maybe not on object lists; if an active light source, would cause - big trouble (`obj_is_local' panic) for savebones() -> savelev() */ - if (g.thrownobj && g.thrownobj->where == OBJ_FREE) - dealloc_obj(g.thrownobj); - if (g.kickedobj && g.kickedobj->where == OBJ_FREE) - dealloc_obj(g.kickedobj); + /* maybe use up active invent item(s), place thrown/kicked missile, + deal with ball and chain possibly being temporarily off the map */ - if (!program_state.panicking) ++ if (!g.program_state.panicking) + done_object_cleanup(); /* remember time of death here instead of having bones, rip, and topten figure it out separately and possibly getting different @@@ -1279,16 -1347,14 +1324,14 @@@ int mnum = u.umonnum; if (!Upolyd) { - /* Base corpse on race when not poly'd since original - * u.umonnum is based on role, and all role monsters - * are human. - */ + /* Base corpse on race when not poly'd since original u.umonnum + is based on role, and all role monsters are human. */ - mnum = (flags.female && urace.femalenum != NON_PM) - ? urace.femalenum - : urace.malenum; + mnum = (flags.female && g.urace.femalenum != NON_PM) + ? g.urace.femalenum + : g.urace.malenum; } - corpse = mk_named_object(CORPSE, &mons[mnum], u.ux, u.uy, plname); - Sprintf(pbuf, "%s, ", plname); + corpse = mk_named_object(CORPSE, &mons[mnum], u.ux, u.uy, g.plname); + Sprintf(pbuf, "%s, ", g.plname); formatkiller(eos(pbuf), sizeof pbuf - strlen(pbuf), how, TRUE); make_grave(u.ux, u.uy, pbuf); }