-/* NetHack 3.6 dothrow.c $NHDT-Date: 1556201496 2019/04/25 14:11:36 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.160 $ */
+/* NetHack 3.6 dothrow.c $NHDT-Date: 1573688688 2019/11/13 23:44:48 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.164 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
/* JNetHack Copyright */
/* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
-/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019 */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2021 */
/* JNetHack may be freely redistributed. See license for details. */
#include "hack.h"
boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
{
register struct monst *mon;
- register int range, urange;
- boolean crossbowing, impaired = (Confusion || Stunned || Blind
- || Hallucination || Fumbling);
- boolean tethered_weapon = (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0);
+ int range, urange;
+ boolean crossbowing, clear_thrownobj = FALSE,
+ impaired = (Confusion || Stunned || Blind
+ || Hallucination || Fumbling),
+ tethered_weapon = (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0);
notonhead = FALSE; /* reset potentially stale value */
if ((obj->cursed || obj->greased) && (u.dx || u.dy) && !rn2(7)) {
thrownobj = obj;
thrownobj->was_thrown = 1;
+ iflags.returning_missile = ((obj->oartifact == ART_MJOLLNIR
+ && Role_if(PM_VALKYRIE))
+ || tethered_weapon) ? (genericptr_t) obj
+ : (genericptr_t) 0;
+ /* NOTE: No early returns after this point or returning_missile
+ will be left with a stale pointer. */
if (u.uswallow) {
+ if (obj == uball) {
+ uball->ox = uchain->ox = u.ux;
+ uball->oy = uchain->oy = u.uy;
+ }
mon = u.ustuck;
bhitpos.x = mon->mx;
bhitpos.y = mon->my;
if (u.dz < 0
/* Mjollnir 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)
- || tethered_weapon)
+ && iflags.returning_missile
&& !impaired) {
#if 0 /*JP:T*/
pline("%s the %s and returns to your hand!", Tobjnam(obj, "hit"),
} else {
hitfloor(obj, TRUE);
}
- thrownobj = (struct obj *) 0;
- return;
+ clear_thrownobj = TRUE;
+ goto throwit_return;
} else if (obj->otyp == BOOMERANG && !Underwater) {
if (Is_airlevel(&u.uz) || Levitation)
setworn(obj, wep_mask);
u.twoweap = twoweap;
}
- thrownobj = (struct obj *) 0;
- return;
+ clear_thrownobj = TRUE;
+ goto throwit_return;
}
} else {
/* crossbow range is independent of strength */
we're about to return */
if (tethered_weapon)
tmp_at(DISP_END, 0);
- return;
+ goto throwit_return;
}
}
boolean obj_gone;
if (mon->isshk && obj->where == OBJ_MINVENT && obj->ocarry == mon) {
- thrownobj = (struct obj *) 0;
- return; /* alert shk caught it */
+ clear_thrownobj = TRUE;
+ goto throwit_return; /* alert shk caught it */
}
(void) snuff_candle(obj);
notonhead = (bhitpos.x != mon->mx || bhitpos.y != mon->my);
obj_gone = thitmonst(mon, obj);
- /* Monster may have been tamed; this frees old mon */
+ /* Monster may have been tamed; this frees old mon [obsolete] */
mon = m_at(bhitpos.x, bhitpos.y);
/* [perhaps this should be moved into thitmonst or hmon] */
hot_pursuit(mon);
if (obj_gone)
- thrownobj = 0;
+ thrownobj = (struct obj *) 0;
}
if (!thrownobj) {
/* missile has already been handled */
- if (tethered_weapon) tmp_at(DISP_END, 0);
- } else if (u.uswallow) {
- if (tethered_weapon) {
+ if (tethered_weapon)
tmp_at(DISP_END, 0);
-/*JP
- pline("%s returns to your hand!", The(xname(thrownobj)));
-*/
- pline("%s\82Í\82 \82È\82½\82Ì\8eè\82É\96ß\82Á\82Ä\82«\82½\81I", The(xname(thrownobj)));
- thrownobj = addinv(thrownobj);
- (void) encumber_msg();
- /* in case addinv() autoquivered */
- if (thrownobj->owornmask & W_QUIVER)
- setuqwep((struct obj *) 0);
- setuwep(thrownobj);
- } else {
- /* ball is not picked up by monster */
- if (obj != uball)
- (void) mpickobj(u.ustuck, obj);
- thrownobj = (struct obj *) 0;
- }
+ } else if (u.uswallow && !iflags.returning_missile) {
+ swallowit:
+ if (obj != uball)
+ (void) mpickobj(u.ustuck, obj); /* clears 'thrownobj' */
+ else
+ clear_thrownobj = TRUE;
+ goto throwit_return;
} else {
- /* Mjollnir 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))
- || tethered_weapon) {
+ /* Mjollnir must be wielded to be thrown--caller verifies this;
+ aklys must be wielded as primary to return when thrown */
+ if (iflags.returning_missile) { /* Mjollnir or aklys */
if (rn2(100)) {
if (tethered_weapon)
tmp_at(DISP_END, BACKTRACK);
}
#endif
}
- if (ship_object(obj, u.ux, u.uy, FALSE)) {
- thrownobj = (struct obj *) 0;
- return;
- }
- dropy(obj);
+
+ if (u.uswallow)
+ goto swallowit;
+ if (!ship_object(obj, u.ux, u.uy, FALSE))
+ dropy(obj);
}
- thrownobj = (struct obj *) 0;
- return;
+ clear_thrownobj = TRUE;
+ goto throwit_return;
} else {
if (tethered_weapon)
tmp_at(DISP_END, 0);
pline("%s to return!", Tobjnam(obj, "fail"));
*/
pline("%s\82Í\96ß\82é\82Ì\82É\8e¸\94s\82µ\82½\81I", xname(obj));
+
+ if (u.uswallow)
+ goto swallowit;
/* continue below with placing 'obj' at target location */
}
}
tmp_at(DISP_END, 0);
breakmsg(obj, cansee(bhitpos.x, bhitpos.y));
breakobj(obj, bhitpos.x, bhitpos.y, TRUE, TRUE);
- thrownobj = (struct obj *) 0;
- return;
+ clear_thrownobj = TRUE;
+ goto throwit_return;
}
/*JP
if (flooreffects(obj, bhitpos.x, bhitpos.y, "fall")) {
*/
if (flooreffects(obj,bhitpos.x, bhitpos.y, "\97\8e\82¿\82é")) {
- thrownobj = (struct obj *) 0;
- return;
+ clear_thrownobj = TRUE;
+ goto throwit_return;
}
obj_no_longer_held(obj);
if (mon && mon->isshk && is_pick(obj)) {
if (*u.ushops || obj->unpaid)
check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE);
(void) mpickobj(mon, obj); /* may merge and free obj */
- thrownobj = (struct obj *) 0;
- return;
+ clear_thrownobj = TRUE;
+ goto throwit_return;
}
(void) snuff_candle(obj);
if (!mon && ship_object(obj, bhitpos.x, bhitpos.y, FALSE)) {
- thrownobj = (struct obj *) 0;
- return;
+ clear_thrownobj = TRUE;
+ goto throwit_return;
}
thrownobj = (struct obj *) 0;
place_object(obj, bhitpos.x, bhitpos.y);
if (obj_sheds_light(obj))
vision_full_recalc = 1;
}
+
+ throwit_return:
+ iflags.returning_missile = (genericptr_t) 0;
+ if (clear_thrownobj)
+ thrownobj = (struct obj *) 0;
+ return;
}
/* an object may hit a monster; various factors adjust chance of hitting */