throw-and-return for aklys

The comment I added to data.base--to explain that despite what the
short description says, an aklys wouldn't return to sender after being
thrown--was bugging me, so I've made aklyses behave like Mjollnir.
If thrown when wielded as primary weapon, it will usually return and
usually be re-wielded.  I also added a new message when either thrown
Mjollnir or thrown aklys is expected to return and fails to do so.

Most of the diff to dothrow.c is a change in indentation level.  The
amount of code needed was quite small.

Autopickup for thrown Mjollnir which had failed to return was putting
it into the quiver slot if that was empty.  Note quite an outright bug,
but it started wielded and can't be thrown if quivered, so exclude it
from the stuff that will auto-fill the quiver slot when added to invent
(post-3.6.0 issue).
This commit is contained in:
PatR
2018-02-26 11:18:29 -08:00
parent f3aaee792f
commit b73d45fd66
4 changed files with 71 additions and 44 deletions
-2
View File
@@ -59,8 +59,6 @@ thonged club
it to be drawn back to the wielder after having been thrown. it to be drawn back to the wielder after having been thrown.
It should not be confused with the atlatl, which is a device It should not be confused with the atlatl, which is a device
used to throw spears for longer distances. used to throw spears for longer distances.
(NetHack's "aklys" is just a club and won't return if thrown.)
~agate ring ~agate ring
agate* agate*
Translucent, cryptocrystalline variety of quartz and a subvariety Translucent, cryptocrystalline variety of quartz and a subvariety
+5
View File
@@ -595,6 +595,8 @@ unix: fix for freeing MAIL also introduced a memory leak whenever new mail
when clairvoyance lets you move the cursor to examine the map (if it occurs when clairvoyance lets you move the cursor to examine the map (if it occurs
when engulfed or underwater or when blessed clairvoyance finds a when engulfed or underwater or when blessed clairvoyance finds a
monster), the "for instructions type '?'" prompt could be confusing monster), the "for instructions type '?'" prompt could be confusing
prevent Mjollnir from being auto-quivered if it's been thrown without return
and then picked back up while quiver slot is empty
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
@@ -785,6 +787,9 @@ change #adjust's behavior when collecting compatible stacks; that used to
a prayer result which results in uncursing some or all of the hero's items a prayer result which results in uncursing some or all of the hero's items
won't uncurse a worn helm of opposite alignment since that would won't uncurse a worn helm of opposite alignment since that would
facilitate the hero switching to another god by taking it off facilitate the hero switching to another god by taking it off
wielded aklys behaves like Mjollnir when thrown--it usually returns; unlike
Mjollnir, it isn't limited to Valkyries or need gauntlets of power
(so far, hero-only; an aklys won't return if thrown by a monster)
Platform- and/or Interface-Specific New Features Platform- and/or Interface-Specific New Features
+60 -41
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 dothrow.c $NHDT-Date: 1502243899 2017/08/09 01:58:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.125 $ */ /* NetHack 3.6 dothrow.c $NHDT-Date: 1519672703 2018/02/26 19:18:23 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.130 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1068,8 +1068,7 @@ void
throwit(obj, wep_mask, twoweap) throwit(obj, wep_mask, twoweap)
struct obj *obj; struct obj *obj;
long wep_mask; /* used to re-equip returning boomerang */ long wep_mask; /* used to re-equip returning boomerang */
boolean boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
twoweap; /* used to restore twoweapon mode if wielded weapon returns */
{ {
register struct monst *mon; register struct monst *mon;
register int range, urange; register int range, urange;
@@ -1120,7 +1119,11 @@ boolean
bhitpos.x = mon->mx; bhitpos.x = mon->mx;
bhitpos.y = mon->my; bhitpos.y = mon->my;
} else if (u.dz) { } else if (u.dz) {
if (u.dz < 0 && Role_if(PM_VALKYRIE) && obj->oartifact == ART_MJOLLNIR if (u.dz < 0
/* Mjnollnir must we wielded to be thrown--caller verifies this;
aklys must we wielded as primary to return when thrown */
&& ((Role_if(PM_VALKYRIE) && obj->oartifact == ART_MJOLLNIR)
|| (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0))
&& !impaired) { && !impaired) {
pline("%s the %s and returns to your hand!", Tobjnam(obj, "hit"), pline("%s the %s and returns to your hand!", Tobjnam(obj, "hit"),
ceiling(u.ux, u.uy)); ceiling(u.ux, u.uy));
@@ -1253,47 +1256,63 @@ boolean
(void) mpickobj(u.ustuck, obj); (void) mpickobj(u.ustuck, obj);
thrownobj = (struct obj *) 0; thrownobj = (struct obj *) 0;
} else { } else {
/* the code following might become part of dropy() */ /* Mjnollnir must we wielded to be thrown--caller verifies this;
if (obj->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE) aklys must we wielded as primary to return when thrown */
&& rn2(100)) { if ((obj->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE))
/* we must be wearing Gauntlets of Power to get here */ || (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0)) {
sho_obj_return_to_u(obj); /* display its flight */ if (rn2(100)) {
sho_obj_return_to_u(obj); /* display its flight */
if (!impaired && rn2(100)) { if (!impaired && rn2(100)) {
pline("%s to your hand!", Tobjnam(obj, "return")); pline("%s to your hand!", Tobjnam(obj, "return"));
obj = addinv(obj); obj = addinv(obj);
(void) encumber_msg(); (void) encumber_msg();
setuwep(obj); setuwep(obj);
u.twoweap = twoweap; u.twoweap = twoweap;
if (cansee(bhitpos.x, bhitpos.y)) if (cansee(bhitpos.x, bhitpos.y))
newsym(bhitpos.x, bhitpos.y); newsym(bhitpos.x, bhitpos.y);
} else {
int dmg = rn2(2);
if (!dmg) {
pline(Blind ? "%s lands %s your %s."
: "%s back to you, landing %s your %s.",
Blind ? Something : Tobjnam(obj, "return"),
Levitation ? "beneath" : "at",
makeplural(body_part(FOOT)));
} else { } else {
dmg += rnd(3); int dmg = rn2(2);
pline(Blind ? "%s your %s!"
: "%s back toward you, hitting your %s!", if (!dmg) {
Tobjnam(obj, Blind ? "hit" : "fly"), pline(Blind ? "%s lands %s your %s."
body_part(ARM)); : "%s back to you, landing %s your %s.",
(void) artifact_hit((struct monst *) 0, &youmonst, obj, Blind ? Something : Tobjnam(obj, "return"),
&dmg, 0); Levitation ? "beneath" : "at",
losehp(Maybe_Half_Phys(dmg), killer_xname(obj), makeplural(body_part(FOOT)));
KILLED_BY); } else {
dmg += rnd(3);
pline(Blind ? "%s your %s!"
: "%s back toward you, hitting your %s!",
Tobjnam(obj, Blind ? "hit" : "fly"),
body_part(ARM));
if (obj->oartifact)
(void) artifact_hit((struct monst *) 0, &youmonst,
obj, &dmg, 0);
losehp(Maybe_Half_Phys(dmg), killer_xname(obj),
KILLED_BY);
}
if (ship_object(obj, u.ux, u.uy, FALSE)) {
thrownobj = (struct obj *) 0;
return;
}
dropy(obj);
} }
if (ship_object(obj, u.ux, u.uy, FALSE)) { thrownobj = (struct obj *) 0;
thrownobj = (struct obj *) 0; return;
return; } else {
} /* when this location is stepped on, the weapon will be
dropy(obj); auto-picked up due to 'obj->was_thrown' of 1;
addinv() prevents thrown Mjollnir from being placed
into the quiver slot, but an aklys will end up there if
that slot is empty at the time; since hero will need to
explicitly rewield the weapon to get throw-and-return
capability back anyway, quivered or not shouldn't matter */
pline("%s fails to return!",
upstart(obj->oartifact ? ONAME(obj)
: thesimpleoname(obj)));
/* continue with placing 'obj' at target location */
} }
thrownobj = (struct obj *) 0;
return;
} }
if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ) && breaktest(obj)) { if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ) && breaktest(obj)) {
+6 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 invent.c $NHDT-Date: 1518053384 2018/02/08 01:29:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.224 $ */ /* NetHack 3.6 invent.c $NHDT-Date: 1519672703 2018/02/26 19:18:23 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.225 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -598,6 +598,11 @@ struct obj *obj;
/* fill empty quiver if obj was thrown */ /* fill empty quiver if obj was thrown */
if (flags.pickup_thrown && !uquiver && obj_was_thrown if (flags.pickup_thrown && !uquiver && obj_was_thrown
/* if Mjollnir is thrown and fails to return, we want to
auto-pick it when we move to its spot, but not into quiver;
aklyses behave like Mjollnir when thrown while wielded, but
we lack sufficient information here make them exceptions */
&& obj->oartifact != ART_MJOLLNIR
&& (throwing_weapon(obj) || is_ammo(obj))) && (throwing_weapon(obj) || is_ammo(obj)))
setuqwep(obj); setuqwep(obj);
added: added: