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

View File

@@ -59,8 +59,6 @@ thonged club
it to be drawn back to the wielder after having been thrown.
It should not be confused with the atlatl, which is a device
used to throw spears for longer distances.
(NetHack's "aklys" is just a club and won't return if thrown.)
~agate ring
agate*
Translucent, cryptocrystalline variety of quartz and a subvariety

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 engulfed or underwater or when blessed clairvoyance finds a
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
@@ -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
won't uncurse a worn helm of opposite alignment since that would
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

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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1068,8 +1068,7 @@ void
throwit(obj, wep_mask, twoweap)
struct obj *obj;
long wep_mask; /* used to re-equip returning boomerang */
boolean
twoweap; /* used to restore twoweapon mode if wielded weapon returns */
boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
{
register struct monst *mon;
register int range, urange;
@@ -1120,7 +1119,11 @@ boolean
bhitpos.x = mon->mx;
bhitpos.y = mon->my;
} 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) {
pline("%s the %s and returns to your hand!", Tobjnam(obj, "hit"),
ceiling(u.ux, u.uy));
@@ -1253,47 +1256,63 @@ boolean
(void) mpickobj(u.ustuck, obj);
thrownobj = (struct obj *) 0;
} else {
/* the code following might become part of dropy() */
if (obj->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE)
&& rn2(100)) {
/* we must be wearing Gauntlets of Power to get here */
sho_obj_return_to_u(obj); /* display its flight */
/* Mjnollnir must we wielded to be thrown--caller verifies this;
aklys must we wielded as primary to return when thrown */
if ((obj->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE))
|| (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0)) {
if (rn2(100)) {
sho_obj_return_to_u(obj); /* display its flight */
if (!impaired && rn2(100)) {
pline("%s to your hand!", Tobjnam(obj, "return"));
obj = addinv(obj);
(void) encumber_msg();
setuwep(obj);
u.twoweap = twoweap;
if (cansee(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)));
if (!impaired && rn2(100)) {
pline("%s to your hand!", Tobjnam(obj, "return"));
obj = addinv(obj);
(void) encumber_msg();
setuwep(obj);
u.twoweap = twoweap;
if (cansee(bhitpos.x, bhitpos.y))
newsym(bhitpos.x, bhitpos.y);
} else {
dmg += rnd(3);
pline(Blind ? "%s your %s!"
: "%s back toward you, hitting your %s!",
Tobjnam(obj, Blind ? "hit" : "fly"),
body_part(ARM));
(void) artifact_hit((struct monst *) 0, &youmonst, obj,
&dmg, 0);
losehp(Maybe_Half_Phys(dmg), killer_xname(obj),
KILLED_BY);
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 {
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;
return;
}
dropy(obj);
thrownobj = (struct obj *) 0;
return;
} else {
/* when this location is stepped on, the weapon will be
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)) {

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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -598,6 +598,11 @@ struct obj *obj;
/* fill empty quiver if 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)))
setuqwep(obj);
added: