]> granicus.if.org Git - nethack/commitdiff
display former possessions of dead monster
authorPatR <rankin@nethack.org>
Fri, 13 May 2022 21:46:02 +0000 (14:46 -0700)
committerPatR <rankin@nethack.org>
Fri, 13 May 2022 21:46:02 +0000 (14:46 -0700)
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
src/dog.c
src/mon.c

index 12eeb282a39ecdcd85b5a68207bb6735be2d8e76..48685adb40b20072e3a7ab40e8368f452288f993 100644 (file)
@@ -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
index ad20f6637bc077a4ab26befd6e4da3621192dc47..8658582ad44653ab9c9b17c9a9e6018be3d121bd 100644 (file)
--- 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) */
index 2686c3e981bcf0fa085e386f14c8df576afb2e86..6ed4c2e4d16dc7234b7704892741166adb2bd1b5 100644 (file)
--- 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 */