]> granicus.if.org Git - nethack/commitdiff
throw-and-return vs !fixinv
authorPatR <rankin@nethack.org>
Sun, 1 Mar 2020 14:46:37 +0000 (06:46 -0800)
committerPatR <rankin@nethack.org>
Sun, 1 Mar 2020 14:46:37 +0000 (06:46 -0800)
Implement the request that a wielded+thrown aklys be given the same
inventory letter when it returns and is caught and rewielded, even for
the !fixinv setting where inventory letters don't stick.  Works for
Valkyrie-thrown Mjollnir and returning (ie, didn't hit) boomerangs as
well as for aklys.

I'm not sure how useful this really is, because on the rare occasions
that it either doesn't return or fails to be caught, it won't be given
the same letter when subsequently picked up.  So the player who relies
on it will still be vulnerable to using the wrong letter next time a
throw is attempted.  But at least picking it up explicitly displays
the new inventory letter, unlike catching it upon return.

doc/fixes37.0
include/extern.h
src/dothrow.c
src/invent.c
src/polyself.c

index 79f198df499df630ff171957b8bf14c04e347a3a..b2155813b311e9a314b954ead110a47ee92fa72b 100644 (file)
@@ -1,4 +1,4 @@
-$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.107 $ $NHDT-Date: 1582364458 2020/02/22 09:40:58 $
+$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.114 $ $NHDT-Date: 1583073988 2020/03/01 14:46:28 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -167,6 +167,9 @@ tipping your cap might get a response
 special levels can be flipped horizontally and/or vertically
 new special level initialization routine, "swamp"
 demon lords and princes suppress teleporting in Gehennom
+for !fixinv option where inventory letters normally don't stick, try to put
+       a throw-and-return weapon back into the same inventory slot it gets
+       thrown from; only works if it does return and is successfully caught
 
 
 Platform- and/or Interface-Specific New Features
index 34d1766b2c80f41c32f82d491a57cebdc219de4c..bed33c9004a9e9445eb16b0c402c46d74aba529a 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 extern.h        $NHDT-Date: 1582592780 2020/02/25 01:06:20 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.804 $ */
+/* NetHack 3.6 extern.h        $NHDT-Date: 1583073988 2020/03/01 14:46:28 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.809 $ */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -575,7 +575,7 @@ E void FDECL(hitfloor, (struct obj *, BOOLEAN_P));
 E void FDECL(hurtle, (int, int, int, BOOLEAN_P));
 E void FDECL(mhurtle, (struct monst *, int, int, int));
 E boolean FDECL(throwing_weapon, (struct obj *));
-E void FDECL(throwit, (struct obj *, long, BOOLEAN_P));
+E void FDECL(throwit, (struct obj *, long, BOOLEAN_P, struct obj *));
 E int FDECL(omon_adj, (struct monst *, struct obj *, BOOLEAN_P));
 E int FDECL(thitmonst, (struct monst *, struct obj *));
 E int FDECL(hero_breaks, (struct obj *, XCHAR_P, XCHAR_P, BOOLEAN_P));
@@ -1024,8 +1024,9 @@ E int FDECL(ckunpaid, (struct obj *));
 E void FDECL(addinv_core1, (struct obj *));
 E void FDECL(addinv_core2, (struct obj *));
 E struct obj *FDECL(addinv, (struct obj *));
-E struct obj *FDECL(hold_another_object,
-                    (struct obj *, const char *, const char *, const char *));
+E struct obj *FDECL(addinv_before, (struct obj *, struct obj *));
+E struct obj *FDECL(hold_another_object, (struct obj *, const char *,
+                                          const char *, const char *));
 E void FDECL(useupall, (struct obj *));
 E void FDECL(useup, (struct obj *));
 E void FDECL(consume_obj_charge, (struct obj *, BOOLEAN_P));
index 6be4155ca5287c3caaa7ba6b6bba25cdcc7e775a..3af418ecd069067973a9777017d9368aa6ba8b5c 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 dothrow.c       $NHDT-Date: 1579655027 2020/01/22 01:03:47 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.181 $ */
+/* NetHack 3.6 dothrow.c       $NHDT-Date: 1583073990 2020/03/01 14:46:30 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.183 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2013. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -80,7 +80,7 @@ throw_obj(obj, shotlimit)
 struct obj *obj;
 int shotlimit;
 {
-    struct obj *otmp;
+    struct obj *otmp, *oldslot;
     int multishot;
     schar skill;
     long wep_mask;
@@ -228,6 +228,7 @@ int shotlimit;
     }
 
     wep_mask = obj->owornmask;
+    oldslot = 0;
     g.m_shot.o = obj->otyp;
     g.m_shot.n = multishot;
     for (g.m_shot.i = 1; g.m_shot.i <= g.m_shot.n; g.m_shot.i++) {
@@ -239,9 +240,10 @@ int shotlimit;
             otmp = obj;
             if (otmp->owornmask)
                 remove_worn_item(otmp, FALSE);
+            oldslot = obj->nobj;
         }
         freeinv(otmp);
-        throwit(otmp, wep_mask, twoweap);
+        throwit(otmp, wep_mask, twoweap, oldslot);
     }
     g.m_shot.n = g.m_shot.i = 0;
     g.m_shot.o = STRANGE_OBJECT;
@@ -429,7 +431,8 @@ boolean verbose;
     if (g.m_shot.i < g.m_shot.n) {
         if (verbose && !g.context.mon_moving) {
             You("stop %s after the %d%s %s.",
-                g.m_shot.s ? "firing" : "throwing", g.m_shot.i, ordin(g.m_shot.i),
+                g.m_shot.s ? "firing" : "throwing",
+                g.m_shot.i, ordin(g.m_shot.i),
                 g.m_shot.s ? "shot" : "toss");
         }
         g.m_shot.n = g.m_shot.i; /* make current shot be the last */
@@ -1107,10 +1110,11 @@ struct obj *obj;
 
 /* throw an object, NB: obj may be consumed in the process */
 void
-throwit(obj, wep_mask, twoweap)
+throwit(obj, wep_mask, twoweap, oldslot)
 struct obj *obj;
 long wep_mask; /* used to re-equip returning boomerang */
 boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
+struct obj *oldslot; /* for thrown-and-return used with !fixinv */
 {
     register struct monst *mon;
     int range, urange;
@@ -1183,7 +1187,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
             && !impaired) {
             pline("%s the %s and returns to your hand!", Tobjnam(obj, "hit"),
                   ceiling(u.ux, u.uy));
-            obj = addinv(obj);
+            obj = addinv_before(obj, oldslot);
             (void) encumber_msg();
             if (obj->owornmask & W_QUIVER) /* in case addinv() autoquivered */
                 setuqwep((struct obj *) 0);
@@ -1208,7 +1212,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
         mon = boomhit(obj, u.dx, u.dy);
         if (mon == &g.youmonst) { /* the thing was caught */
             exercise(A_DEX, TRUE);
-            obj = addinv(obj);
+            obj = addinv_before(obj, oldslot);
             (void) encumber_msg();
             if (wep_mask && !(obj->owornmask & wep_mask)) {
                 setworn(obj, wep_mask);
@@ -1340,7 +1344,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
 
                 if (!impaired && rn2(100)) {
                     pline("%s to your hand!", Tobjnam(obj, "return"));
-                    obj = addinv(obj);
+                    obj = addinv_before(obj, oldslot);
                     (void) encumber_msg();
                     /* addinv autoquivers an aklys if quiver is empty;
                        if obj is quivered, remove it before wielding */
@@ -1366,8 +1370,8 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
                               Tobjnam(obj, Blind ? "hit" : "fly"),
                               body_part(ARM));
                         if (obj->oartifact)
-                            (void) artifact_hit((struct monst *) 0, &g.youmonst,
-                                                obj, &dmg, 0);
+                            (void) artifact_hit((struct monst *) 0,
+                                                &g.youmonst, obj, &dmg, 0);
                         losehp(Maybe_Half_Phys(dmg), killer_xname(obj),
                                KILLED_BY);
                     }
index 0b468697efac69dbdb6a4930d4736b654d14d90b..a3d4ed209615c11857a5fa4807bb046583a8b8c3 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 invent.c        $NHDT-Date: 1581322662 2020/02/10 08:17:42 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.290 $ */
+/* NetHack 3.7 invent.c        $NHDT-Date: 1583073990 2020/03/01 14:46:30 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.294 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -19,6 +19,7 @@ static int FDECL(invletter_value, (CHAR_P));
 static int FDECL(CFDECLSPEC sortloot_cmp, (const genericptr,
                                                const genericptr));
 static void NDECL(reorder_invent);
+static struct obj *FDECL(addinv_core0, (struct obj *, struct obj *));
 static void FDECL(noarmor, (BOOLEAN_P));
 static void FDECL(invdisp_nothing, (const char *, const char *));
 static boolean FDECL(worn_wield_only, (struct obj *));
@@ -873,9 +874,9 @@ struct obj *obj;
  * Add obj to the hero's inventory.  Make sure the object is "free".
  * Adjust hero attributes as necessary.
  */
-struct obj *
-addinv(obj)
-struct obj *obj;
+static struct obj *
+addinv_core0(obj, other_obj)
+struct obj *obj, *other_obj;
 {
     struct obj *otmp, *prev;
     int saved_otyp = (int) obj->otyp; /* for panic */
@@ -893,6 +894,20 @@ struct obj *obj;
 
     addinv_core1(obj);
 
+    /* for addinv_before(); if something has been removed and is now being
+       reinserted, try to put it in the same place instead of merging or
+       placing at end; for thrown-and-return weapon with !fixinv setting */
+    if (other_obj) {
+        for (otmp = g.invent; otmp; otmp = otmp->nobj) {
+            if (otmp->nobj == other_obj) {
+                obj->nobj = other_obj;
+                otmp->nobj = obj;
+                obj->where = OBJ_INVENT;
+                goto added;
+            }
+        }
+    }
+
     /* merge with quiver in preference to any other inventory slot
        in case quiver and wielded weapon are both eligible; adding
        extra to quivered stack is more useful than to wielded one */
@@ -939,6 +954,22 @@ struct obj *obj;
     return obj;
 }
 
+/* add obj to the hero's inventory in the default fashion */
+struct obj *
+addinv(obj)
+struct obj *obj;
+{
+    return addinv_core0(obj, (struct obj *) 0);
+}
+
+/* add obj to the hero's inventory by inserting in front of a specific item */
+struct obj *
+addinv_before(obj, other_obj)
+struct obj *obj, *other_obj;
+{
+    return addinv_core0(obj, other_obj);
+}
+
 /*
  * Some objects are affected by being carried.
  * Make those adjustments here. Called _after_ the object
index 17fd657f44f78d272a0aa73922f03e0170a55150..210a5fc5390adc5ce66cee2690f2cf00eefc8cf2 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 polyself.c      $NHDT-Date: 1581886864 2020/02/16 21:01:04 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.150 $ */
+/* NetHack 3.6 polyself.c      $NHDT-Date: 1583073991 2020/03/01 14:46:31 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.152 $ */
 /*      Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -1203,7 +1203,7 @@ dospit()
             break;
         }
         otmp->spe = 1; /* to indicate it's yours */
-        throwit(otmp, 0L, FALSE);
+        throwit(otmp, 0L, FALSE, (struct obj *) 0);
     }
     return 1;
 }