diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 79f198df4..b2155813b 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -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 diff --git a/include/extern.h b/include/extern.h index 34d1766b2..bed33c900 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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)); diff --git a/src/dothrow.c b/src/dothrow.c index 6be4155ca..3af418ecd 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -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); } diff --git a/src/invent.c b/src/invent.c index 0b468697e..a3d4ed209 100644 --- a/src/invent.c +++ b/src/invent.c @@ -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 diff --git a/src/polyself.c b/src/polyself.c index 17fd657f4..210a5fc53 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -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; }