From 1ce457f801c69937104d0875d9c97faa52ddec2d Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 13 May 2022 14:46:02 -0700 Subject: [PATCH] display former possessions of dead monster Reported directly to devteam by a hardfought player and also by entrez. The recent mon_leaving_level() change resulted in objects dropped by a dying monster not being displayed immediately. It justed needed the relobj(mon, 0, FALSE) to relobj(mon, 1, FALSE) change in m_detach() but this does some related cleanup in mon_leaving_level()'s callers. wormgone() takes a long worm off the map but leaves its stale coordinates set because some code relied on that. This takes away the need for that but still doesn't actually clear them. This adds redundant 'return' statements at the end of a few void functions that are longer than fits within a typical screen display. They make searching for the end of the current routine in an editor or pager easier without resorting to regular expressions and can also be used to search for the beginning if/when preceding routine ends in 'return' too. --- doc/fixes3-7-0.txt | 6 +++++- src/dog.c | 45 ++++++++++++++++++++++++++------------------- src/mon.c | 37 +++++++++++++++++++++++++++++++------ 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 12eeb282a..48685adb4 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1,4 +1,4 @@ -HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.913 $ $NHDT-Date: 1652299940 2022/05/11 20:12:20 $ +HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.914 $ $NHDT-Date: 1652478351 2022/05/13 21:45:51 $ General Fixes and Modified Features ----------------------------------- @@ -1209,6 +1209,8 @@ revised monster teleportation message handling caused magic whistle to be changed to not operate on pets that were already adjacent; change back revised monster teleportation message handling could produce duplicate message when shopkeeper who left shop got returned to it +recent changes in removing a dead monster from the map didn't update screen + to show objects it dropped; they were present, just not displayed curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support @@ -1242,6 +1244,8 @@ tty: previous change resulted in remnants of previous level being shown on tty: for #wizidentify, using ^I as an unseen group accelerator to pick the 'all' choice was incorrectly checking menuitem_invert_test() and failing, so the 'all' choice wasn't being toggled on if user typed ^I +tty: changes to support utf8 resulted in lines of text windows being shown + starting at their second character Unix: after lua changes to Makefiles, 'make spotless' for dat subdirectory left some generated data files which should have been deleted Windows: new tile additions in win/share did not trigger the creation of a new diff --git a/src/dog.c b/src/dog.c index ad20f6637..8658582ad 100644 --- a/src/dog.c +++ b/src/dog.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dog.c $NHDT-Date: 1599330917 2020/09/05 18:35:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.104 $ */ +/* NetHack 3.7 dog.c $NHDT-Date: 1652478351 2022/05/13 21:45:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.118 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -653,16 +653,6 @@ keepdogs(boolean pets_only) /* true for ascension or final escape */ if (mtmp->isshk) set_residency(mtmp, TRUE); - if (mtmp->wormno) { - register int cnt; - /* NOTE: worm is truncated to # segs = max wormno size */ - cnt = count_wsegs(mtmp); - num_segs = min(cnt, MAX_NUM_WORMS - 1); - wormgone(mtmp); - place_monster(mtmp, mtmp->mx, mtmp->my); - } else - num_segs = 0; - /* set minvent's obj->no_charge to 0 */ for (obj = mtmp->minvent; obj; obj = obj->nobj) { if (Has_contents(obj)) @@ -670,8 +660,22 @@ keepdogs(boolean pets_only) /* true for ascension or final escape */ obj->no_charge = 0; } - relmon(mtmp, &g.mydogs); /* move it from map to g.mydogs */ - mtmp->mx = mtmp->my = 0; /* avoid mnexto()/MON_AT() problem */ + if (mtmp->wormno) { + int cnt = count_wsegs(mtmp); + + /* since monst->wormno is overloaded to hold the number of + tail segments during migration, a very long worm with + more segments than can fit in that field gets truncated */ + num_segs = min(cnt, MAX_NUM_WORMS - 1); + wormgone(mtmp); /* discard tail segments, take head off map */ + /* this used to be place_monster() but relmon() doesn't + need that as long as coordinates reflect actual state */ + mtmp->mx = mtmp->my = 0; /* off normal map */ + } else + num_segs = 0; + + /* take off map and move mtmp from fmon list to mydogs */ + relmon(mtmp, &g.mydogs); /* mtmp->mx,my get changed to 0,0 */ mtmp->wormno = num_segs; mtmp->mlstmv = g.moves; } else if (mtmp->iswiz) { @@ -698,7 +702,7 @@ migrate_to_level( { struct obj *obj; d_level new_lev; - xchar xyflags; + xchar xyflags, mx = mtmp->mx, my = mtmp->my; /* might be needed below */ int num_segs = 0; /* count of worm segments */ if (mtmp->isshk) @@ -712,7 +716,7 @@ migrate_to_level( wormgone(mtmp); /* destroys tail and takes head off map */ /* there used to be a place_monster() here for the relmon() below, but it doesn't require the monster to be on the map anymore */ - mtmp->mx = mtmp->my = 0; + mtmp->mx = mtmp->my = 0; /* wormgone() doesn't do this for us */ } /* set minvent's obj->no_charge to 0 */ @@ -726,7 +730,9 @@ migrate_to_level( mtmp->mtame--; m_unleash(mtmp, TRUE); } - relmon(mtmp, &g.migrating_mons); /* move it from map to g.migrating_mons */ + + /* take off map and move mtmp from fmon list to migrating_mons */ + relmon(mtmp, &g.migrating_mons); /* mtmp->mx,my get changed to 0,0 */ mtmp->mstate |= MON_MIGRATING; new_lev.dnum = ledger_to_dnum((xchar) tolev); @@ -740,13 +746,14 @@ migrate_to_level( mtmp->mlstmv = g.moves; mtmp->mtrack[2].x = u.uz.dnum; /* migrating from this dungeon */ mtmp->mtrack[2].y = u.uz.dlevel; /* migrating from this dungeon level */ - mtmp->mtrack[1].x = cc ? cc->x : mtmp->mx; - mtmp->mtrack[1].y = cc ? cc->y : mtmp->my; + mtmp->mtrack[1].x = cc ? cc->x : mx; + mtmp->mtrack[1].y = cc ? cc->y : my; mtmp->mtrack[0].x = xyloc; mtmp->mtrack[0].y = xyflags; mtmp->mux = new_lev.dnum; mtmp->muy = new_lev.dlevel; - mtmp->mx = mtmp->my = 0; /* this implies migration */ + mtmp->mx = mtmp->my = 0; /* this implies migration (note: already done + * by relmon() -> mon_leaving_level() above) */ /* don't extinguish a mobile light; it still exists but has changed from local (monst->mx > 0) to global (mx==0, not on this level) */ diff --git a/src/mon.c b/src/mon.c index 2686c3e98..6ed4c2e4d 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1651886997 2022/05/07 01:29:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.424 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1652478356 2022/05/13 21:45:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.426 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2322,6 +2322,10 @@ mon_leaving_level(struct monst *mon) remove_worm(mon); else remove_monster(mx, my); + + mon->mx = mon->my = 0; /* off normal map; if caller wants to use + * mon's coordinates after this, it must + * save those before calling us */ } if (onmap) { mon->mundetected = 0; /* for migration; doesn't matter for death */ @@ -2344,13 +2348,23 @@ m_detach( struct monst *mtmp, struct permonst *mptr) /* reflects mtmp->data _prior_ to mtmp's death */ { + xchar mx = mtmp->mx, my = mtmp->my; + if (mtmp->mleashed) m_unleash(mtmp, FALSE); if (mtmp->mx > 0 && emits_light(mptr)) del_light_source(LS_MONSTER, monst_to_any(mtmp)); - /* take mtmp off map but not out of fmon list yet (dmonsfree does that) */ + /* + * Take mtmp off map but not out of fmon list yet (dmonsfree does that). + * + * Sequencing issue: mtmp's inventory should be dropped before taking + * it off the map but if that includes a boulder and mtmp is at a pit + * location, dropping minvent ought to be deferred until its corpse + * gets placed. We compromise and just make sure mtmp is off the map + * before dropping its former belongings. + */ mon_leaving_level(mtmp); mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */ @@ -2362,8 +2376,13 @@ m_detach( leaddead(); if (mtmp->m_id == g.stealmid) thiefdead(); - /* release (drop onto map) all objects carried by mtmp */ - relobj(mtmp, 0, FALSE); + /* release (drop onto map) all objects carried by mtmp; first, + temporarily restore mtmp's internal location (without actually + putting it back on the map) because relobj() relies on that but + mon_leaving_level() just cleared that */ + mtmp->mx = mx, mtmp->my = my; + relobj(mtmp, 1, FALSE); /* drop mtmp->minvent, then issue newsym(mx,my) */ + mtmp->mx = mtmp->my = 0; if (mtmp->isshk) shkgone(mtmp); @@ -2842,6 +2861,7 @@ monstone(struct monst* mdef) You("%s through an opening in the new %s.", u_locomotion("jump"), xname(otmp)); } + return; } /* another monster has killed the monster mdef */ @@ -2886,6 +2906,7 @@ monkilled( if (rxt) pline("May %s %s in peace.", noit_mon_nam(mdef), rxt); } + return; } void @@ -3159,6 +3180,7 @@ xkilled( /* malign was already adjusted for u.ualign.type and randomization */ adjalign(mtmp->malign); + return; } /* changes the monster into a stone monster of the same type @@ -4483,8 +4505,11 @@ newcham( *p = '\0'; if (mtmp->wormno) { /* throw tail away */ - wormgone(mtmp); - place_monster(mtmp, mtmp->mx, mtmp->my); + xchar mx = mtmp->mx, my = mtmp->my; + + wormgone(mtmp); /* discards tail segments, takes head off the map */ + /* put the head back; it will morph into mtmp's new form */ + place_monster(mtmp, mx, my); } if (M_AP_TYPE(mtmp) && mdat->mlet != S_MIMIC) seemimic(mtmp); /* revert to normal monster */ -- 2.50.1