-/* NetHack 3.6 display.h $NHDT-Date: 1447729027 2015/11/17 02:57:07 $ $NHDT-Branch: master $:$NHDT-Revision: 1.26 $ */
+/* NetHack 3.6 display.h $NHDT-Date: 1525012585 2018/04/29 14:36:25 $ $NHDT-Branch: master $:$NHDT-Revision: 1.28 $ */
/* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */
/* and Dave Cohrs, 1990. */
/* NetHack may be freely redistributed. See license for details. */
*/
#define DISP_BEAM (-1) /* Keep all glyphs showing & clean up at end. */
#define DISP_ALL (-2) /* Like beam, but still displayed if not visible. */
-#define DISP_FLASH (-3) /* Clean up each glyph before displaying new one. */
-#define DISP_ALWAYS (-4) /* Like flash, but still displayed if not visible. */
-#define DISP_CHANGE (-5) /* Change glyph. */
-#define DISP_END (-6) /* Clean up. */
-#define DISP_FREEMEM (-7) /* Free all memory during exit only. */
+#define DISP_TETHER (-3) /* Like beam, but tether glyph differs from final */
+#define DISP_FLASH (-4) /* Clean up each glyph before displaying new one. */
+#define DISP_ALWAYS (-5) /* Like flash, but still displayed if not visible. */
+#define DISP_CHANGE (-6) /* Change glyph. */
+#define DISP_END (-7) /* Clean up. */
+#define DISP_FREEMEM (-8) /* Free all memory during exit only. */
/* Total number of cmap indices in the shield_static[] array. */
#define SHIELD_COUNT 21
+#define BACKTRACK (-1) /* flag for DISP_END to display each prior location */
/*
* display_self()
-/* NetHack 3.6 extern.h $NHDT-Date: 1518053385 2018/02/08 01:29:45 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.625 $ */
+/* NetHack 3.6 extern.h $NHDT-Date: 1525012590 2018/04/29 14:36:30 $ $NHDT-Branch: master $:$NHDT-Revision: 1.629 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
E const char *FDECL(exclam, (int force));
E void FDECL(hit, (const char *, struct monst *, const char *));
E void FDECL(miss, (const char *, struct monst *));
-E struct monst *FDECL(bhit, (int, int, int, int, int (*)(MONST_P, OBJ_P),
+E struct monst *FDECL(bhit, (int, int, int, enum bhit_call_types,
+ int (*)(MONST_P, OBJ_P),
int (*)(OBJ_P, OBJ_P), struct obj **));
E struct monst *FDECL(boomhit, (struct obj *, int, int));
E int FDECL(zhitm, (struct monst *, int, int, struct obj **));
-/* NetHack 3.6 hack.h $NHDT-Date: 1490908464 2017/03/30 21:14:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.76 $ */
+/* NetHack 3.6 hack.h $NHDT-Date: 1525012595 2018/04/29 14:36:35 $ $NHDT-Branch: master $:$NHDT-Revision: 1.82 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Pasi Kallinen, 2017. */
/* NetHack may be freely redistributed. See license for details. */
enum bhit_call_types {
ZAPPED_WAND = 0,
THROWN_WEAPON,
+ THROWN_TETHERED_WEAPON,
KICKED_WEAPON,
FLASHED_LIGHT,
INVIS_BEAM
-/* NetHack 3.6 display.c $NHDT-Date: 1524780381 2018/04/26 22:06:21 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.90 $ */
+/* NetHack 3.6 display.c $NHDT-Date: 1525012604 2018/04/29 14:36:44 $ $NHDT-Branch: master $:$NHDT-Revision: 1.91 $ */
/* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */
/* and Dave Cohrs, 1990. */
/* NetHack may be freely redistributed. See license for details. */
}
}
+int
+tether_glyph(x, y)
+{
+ int tdx, tdy;
+ tdx = u.ux - x;
+ tdy = u.uy - y;
+ return zapdir_to_glyph(sgn(tdx),sgn(tdy), 2);
+}
+
/*
* tmp_at()
*
*
* DISP_BEAM - Display the given glyph at each location, but do not erase
* any until the close call.
+ * DISP_TETHER- Display a tether glyph at each location, and the tethered
+ * object at the farthest location, but do not erase any
+ * until the return trip or close.
* DISP_FLASH - Display the given glyph at each location, but erase the
* previous location's glyph.
* DISP_ALWAYS- Like DISP_FLASH, but vision is not taken into account.
switch (x) {
case DISP_BEAM:
case DISP_ALL:
+ case DISP_TETHER:
case DISP_FLASH:
case DISP_ALWAYS:
if (!tglyph)
/* Erase (reset) from source to end */
for (i = 0; i < tglyph->sidx; i++)
newsym(tglyph->saved[i].x, tglyph->saved[i].y);
+ } else if (tglyph->style == DISP_TETHER) {
+ int i;
+
+ if (y == BACKTRACK && tglyph->sidx > 1) {
+ /* backtrack */
+ for (i = tglyph->sidx - 1; i > 0; i--) {
+ newsym(tglyph->saved[i].x, tglyph->saved[i].y);
+ show_glyph(tglyph->saved[i - 1].x,
+ tglyph->saved[i - 1].y, tglyph->glyph);
+ flush_screen(0); /* make sure it shows up */
+ delay_output();
+ }
+ tglyph->sidx = 1;
+ }
+ for (i = 0; i < tglyph->sidx; i++)
+ newsym(tglyph->saved[i].x, tglyph->saved[i].y);
} else { /* DISP_FLASH or DISP_ALWAYS */
if (tglyph->sidx) /* been called at least once */
newsym(tglyph->saved[0].x, tglyph->saved[0].y);
tglyph->saved[tglyph->sidx].x = x;
tglyph->saved[tglyph->sidx].y = y;
tglyph->sidx += 1;
+ } else if (tglyph->style == DISP_TETHER) {
+ if (tglyph->sidx >= TMP_AT_MAX_GLYPHS)
+ break; /* too many locations */
+ if (tglyph->sidx) {
+ int px, py;
+
+ px = tglyph->saved[tglyph->sidx-1].x;
+ py = tglyph->saved[tglyph->sidx-1].y;
+ show_glyph(px, py, tether_glyph(px, py));
+ }
+ /* save pos for later use or erasure */
+ tglyph->saved[tglyph->sidx].x = x;
+ tglyph->saved[tglyph->sidx].y = y;
+ tglyph->sidx += 1;
} else { /* DISP_FLASH/ALWAYS */
if (tglyph->sidx) { /* not first call, so reset previous pos */
newsym(tglyph->saved[0].x, tglyph->saved[0].y);
-/* NetHack 3.6 dothrow.c $NHDT-Date: 1522967321 2018/04/05 22:28:41 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.135 $ */
+/* NetHack 3.6 dothrow.c $NHDT-Date: 1525012611 2018/04/29 14:36:51 $ $NHDT-Branch: master $:$NHDT-Revision: 1.137 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
register int range, urange;
boolean crossbowing, impaired = (Confusion || Stunned || Blind
|| Hallucination || Fumbling);
+ boolean 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)) {
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)
- || (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0))
+ && ((Role_if(PM_VALKYRIE) && obj->oartifact == ART_MJOLLNIR) || tethered_weapon)
&& !impaired) {
pline("%s the %s and returns to your hand!", Tobjnam(obj, "hit"),
ceiling(u.ux, u.uy));
range = 20; /* you must be giant */
else if (obj->oartifact == ART_MJOLLNIR)
range = (range + 1) / 2; /* it's heavy */
- else if (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0)
+ else if (tethered_weapon) /* primary weapon is aklys */
/* if an aklys is going to return, range is limited by the
length of the attached cord [implicit aspect of item] */
range = min(range, BOLT_LIM / 2);
if (Underwater)
range = 1;
- mon = bhit(u.dx, u.dy, range, THROWN_WEAPON,
+ mon = bhit(u.dx, u.dy, range,
+ tethered_weapon ? THROWN_TETHERED_WEAPON : THROWN_WEAPON,
(int FDECL((*), (MONST_P, OBJ_P))) 0,
(int FDECL((*), (OBJ_P, OBJ_P))) 0, &obj);
thrownobj = obj; /* obj may be null now */
if (Is_airlevel(&u.uz) || Levitation)
hurtle(-u.dx, -u.dy, urange, TRUE);
- if (!obj)
+ if (!obj) {
+ /* bhit display cleanup was left with this caller
+ for tethered_weapon, but clean it up now since
+ we're about to return */
+ if (tethered_weapon)
+ tmp_at(DISP_END, 0);
return;
+ }
}
if (mon) {
}
if (!thrownobj) {
- ; /* missile has already been handled */
+ /* missile has already been handled */
+ if (tethered_weapon) tmp_at(DISP_END, 0);
} else if (u.uswallow) {
+ if (tethered_weapon)
+ tmp_at(DISP_END, 0);
/* ball is not picked up by monster */
if (obj != uball)
(void) mpickobj(u.ustuck, obj);
/* 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))
- || (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0)) {
+ || tethered_weapon) {
if (rn2(100)) {
- sho_obj_return_to_u(obj); /* display its flight */
+ if (tethered_weapon)
+ tmp_at(DISP_END, BACKTRACK);
+ else
+ sho_obj_return_to_u(obj); /* display its flight */
if (!impaired && rn2(100)) {
pline("%s to your hand!", Tobjnam(obj, "return"));
thrownobj = (struct obj *) 0;
return;
} else {
+ if (tethered_weapon) tmp_at(DISP_END, 0);
/* 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
-/* NetHack 3.6 objnam.c $NHDT-Date: 1521507553 2018/03/20 00:59:13 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.199 $ */
+/* NetHack 3.6 objnam.c $NHDT-Date: 1525012618 2018/04/29 14:36:58 $ $NHDT-Branch: master $:$NHDT-Revision: 1.202 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
if (bimanual(obj))
hand_s = makeplural(hand_s);
- Sprintf(eos(bp), " (weapon in %s)", hand_s);
+ Sprintf(eos(bp), " (%sweapon in %s)",
+ (obj->otyp == AKLYS) ? "tethered " : "", hand_s);
if (warn_obj_cnt && obj == uwep && (EWarn_of_mon & W_WEP) != 0L) {
/* presumably can be felt when blind */
-/* NetHack 3.6 wield.c $NHDT-Date: 1496959480 2017/06/08 22:04:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.54 $ */
+/* NetHack 3.6 wield.c $NHDT-Date: 1525012623 2018/04/29 14:37:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.56 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2009. */
/* NetHack may be freely redistributed. See license for details. */
long dummy = wep->owornmask;
wep->owornmask |= W_WEP;
+ if (wep->otyp == AKLYS && (wep->owornmask & W_WEP) != 0)
+ You("secure the tether.");
prinv((char *) 0, wep, 0L);
wep->owornmask = dummy;
}
-/* NetHack 3.6 zap.c $NHDT-Date: 1524470244 2018/04/23 07:57:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.275 $ */
+/* NetHack 3.6 zap.c $NHDT-Date: 1525012627 2018/04/29 14:37:07 $ $NHDT-Branch: master $:$NHDT-Revision: 1.277 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
struct monst *
bhit(ddx, ddy, range, weapon, fhitm, fhito, pobj)
register int ddx, ddy, range; /* direction and range */
-int weapon; /* see values in hack.h */
+enum bhit_call_types weapon; /* defined in hack.h */
int FDECL((*fhitm), (MONST_P, OBJ_P)), /* fns called when mon/obj hit */
FDECL((*fhito), (OBJ_P, OBJ_P));
struct obj **pobj; /* object tossed/used, set to NULL
uchar typ;
boolean shopdoor = FALSE, point_blank = TRUE;
boolean in_skip = FALSE, allow_skip = FALSE;
+ boolean tethered_weapon = FALSE;
int skiprange_start = 0, skiprange_end = 0, skipcount = 0;
if (weapon == KICKED_WEAPON) {
if (weapon == FLASHED_LIGHT) {
tmp_at(DISP_BEAM, cmap_to_glyph(S_flashbeam));
+ } else if (weapon == THROWN_TETHERED_WEAPON && obj) {
+ tethered_weapon = TRUE;
+ weapon = THROWN_WEAPON; /* simplify if's that follow below */
+ tmp_at(DISP_TETHER, obj_to_glyph(obj));
} else if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM)
tmp_at(DISP_FLASH, obj_to_glyph(obj));
if (!mtmp->minvis || perceives(mtmp->data))
return mtmp;
} else if (weapon != ZAPPED_WAND) {
+
/* THROWN_WEAPON, KICKED_WEAPON */
- tmp_at(DISP_END, 0);
+ if (!tethered_weapon)
+ tmp_at(DISP_END, 0);
+
if (cansee(bhitpos.x, bhitpos.y) && !canspotmon(mtmp))
map_invisible(bhitpos.x, bhitpos.y);
return mtmp;
point_blank = FALSE; /* affects passing through iron bars */
}
- if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM)
+ if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM && !tethered_weapon)
tmp_at(DISP_END, 0);
if (shopdoor)