diff --git a/include/extern.h b/include/extern.h index 8647997af..5d9141eae 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1707547708 2024/02/10 06:48:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1381 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1708126520 2024/02/16 23:35:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1384 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -577,7 +577,7 @@ extern char *coord_desc(coordxy, coordxy, char *, char) NONNULLARG3; extern void auto_describe(coordxy, coordxy); extern boolean getpos_menu(coord *, int) NONNULLARG1; extern int getpos(coord *, boolean, const char *) NONNULLARG1; -extern void getpos_sethilite(void(*f)(int), boolean(*d)(coordxy,coordxy)); +extern void getpos_sethilite(void(*f)(boolean), boolean(*d)(coordxy,coordxy)); extern void new_mgivenname(struct monst *, int) NONNULLARG1; extern void free_mgivenname(struct monst *) NONNULLARG1; extern void new_oname(struct obj *, int) NONNULLARG1; diff --git a/src/apply.c b/src/apply.c index 31048fa5a..0d6c4c1db 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 apply.c $NHDT-Date: 1695159606 2023/09/19 21:40:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.422 $ */ +/* NetHack 3.7 apply.c $NHDT-Date: 1708126533 2024/02/16 23:35:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.437 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -21,7 +21,7 @@ static void use_candle(struct obj **); static void use_lamp(struct obj *); static void light_cocktail(struct obj **); static int rub_ok(struct obj *); -static void display_jump_positions(int); +static void display_jump_positions(boolean); static void use_tinning_kit(struct obj *); static int use_figurine(struct obj **); static int grease_ok(struct obj *); @@ -30,12 +30,13 @@ static void use_trap(struct obj *); static int touchstone_ok(struct obj *); static int use_stone(struct obj *); static int set_trap(void); /* occupation callback */ -static void display_polearm_positions(int); +static void display_polearm_positions(boolean); static int use_cream_pie(struct obj *); static int jelly_ok(struct obj *); static int use_royal_jelly(struct obj **); static int grapple_range(void); static boolean can_grapple_location(coordxy, coordxy); +static void display_grapple_positions(boolean); static int use_grapple(struct obj *); static void discard_broken_wand(void); static void broken_wand_explode(struct obj *, int, int); @@ -1934,21 +1935,22 @@ get_valid_jump_position(coordxy x, coordxy y) } static void -display_jump_positions(int state) +display_jump_positions(boolean on_off) { - if (state == 0) { - tmp_at(DISP_BEAM, cmap_to_glyph(S_goodpos)); - } else if (state == 1) { - coordxy x, y, dx, dy; + coordxy x, y, dx, dy; + if (on_off) { + /* on */ + tmp_at(DISP_BEAM, cmap_to_glyph(S_goodpos)); for (dx = -4; dx <= 4; dx++) for (dy = -4; dy <= 4; dy++) { x = dx + (coordxy) u.ux; y = dy + (coordxy) u.uy; - if (get_valid_jump_position(x, y)) + if (get_valid_jump_position(x, y) && !u_at(x, y)) tmp_at(x, y); } } else { + /* off */ tmp_at(DISP_END, 0); } } @@ -2033,21 +2035,26 @@ jump(int magic) /* 0=Physical, otherwise skill level */ return ECMD_CANCEL; /* user pressed ESC */ if (!is_valid_jump_pos(cc.x, cc.y, magic, TRUE)) { return ECMD_FAIL; + } else if (u.usteed && u_at(cc.x, cc.y)) { + pline("%s isn't capable of jumping in place.", + upstart(y_monnam(u.usteed))); + return ECMD_FAIL; } else { coord uc; + long side; int range, temp; + boolean wastrapped = FALSE; - if (u.utrap) + if (u.utrap) { + wastrapped = TRUE; switch (u.utraptype) { - case TT_BEARTRAP: { - long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE; - + case TT_BEARTRAP: + side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE; You("rip yourself free of the bear trap! Ouch!"); losehp(Maybe_Half_Phys(rnd(10)), "jumping out of a bear trap", KILLED_BY); set_wounded_legs(side, rn1(1000, 500)); break; - } case TT_PIT: You("leap from the pit!"); break; @@ -2057,8 +2064,8 @@ jump(int magic) /* 0=Physical, otherwise skill level */ break; case TT_LAVA: You("pull yourself above the %s!", hliquid("lava")); - reset_utrap(TRUE); - return ECMD_TIME; + cc.x = u.ux, cc.y = u.uy; /* take u_at() 'if' below */ + break; case TT_BURIEDBALL: case TT_INFLOOR: You("strain your %s, but you're still %s.", @@ -2069,7 +2076,34 @@ jump(int magic) /* 0=Physical, otherwise skill level */ set_wounded_legs(LEFT_SIDE, rn1(10, 11)); set_wounded_legs(RIGHT_SIDE, rn1(10, 11)); return ECMD_TIME; + default: + impossible("Jumping out of strange trap (%d)?", u.utraptype); + break; } + /* if we reach here, hero is no longer trapped */ + reset_utrap(TRUE); + } + /* jumping on hero's same spot doesn't use walk_path() and isn't + allowed when riding (handled above) */ + if (u_at(cc.x, cc.y)) { + struct trap *t; + + /* escaping from a trap takes precedence over jumping in place */ + if (wastrapped) { + morehungry(rnd(10)); + return ECMD_TIME; + } + /* jumping in place on a trap will trigger it */ + if ((t = t_at(cc.x, cc.y)) != 0) { + You("jump up and %s back down.", !Flying ? "come" : "fly"); + dotrap(t, FORCETRAP | TOOKPLUNGE); + return ECMD_TIME; + } + /* jumping in place takes no time and doesn't exercise anything */ + You("%s.", Hallucination ? "hop up and down a bit" + : "decide not to jump after all"); + return ECMD_OK; + } /* * Check the path from uc to cc, calling hurtle_step at each @@ -3262,15 +3296,15 @@ get_valid_polearm_position(coordxy x, coordxy y) } static void -display_polearm_positions(int state) +display_polearm_positions(boolean on_off) { - if (state == 0) { - tmp_at(DISP_BEAM, cmap_to_glyph(S_goodpos)); - } else if (state == 1) { - coordxy x, y, dx, dy; + coordxy x, y, dx, dy; - for (dx = -4; dx <= 4; dx++) - for (dy = -4; dy <= 4; dy++) { + if (on_off) { + /* on */ + tmp_at(DISP_BEAM, cmap_to_glyph(S_goodpos)); + for (dx = -3; dx <= 3; dx++) + for (dy = -3; dy <= 3; dy++) { x = dx + (int) u.ux; y = dy + (int) u.uy; if (get_valid_polearm_position(x, y)) { @@ -3278,6 +3312,7 @@ display_polearm_positions(int state) } } } else { + /* off */ tmp_at(DISP_END, 0); } } @@ -3571,6 +3606,28 @@ can_grapple_location(coordxy x, coordxy y) return (isok(x, y) && cansee(x, y) && distu(x, y) <= grapple_range()); } +static void +display_grapple_positions(boolean on_off) +{ + coordxy x, y, dx, dy; + + if (on_off) { + /* on */ + tmp_at(DISP_BEAM, cmap_to_glyph(S_goodpos)); + for (dx = -3; dx <= 3; dx++) + for (dy = -3; dy <= 3; dy++) { + x = dx + (int) u.ux; + y = dy + (int) u.uy; + if (can_grapple_location(x, y) && !u_at(x, y)) { + tmp_at(x, y); + } + } + } else { + /* off */ + tmp_at(DISP_END, 0); + } +} + static int use_grapple(struct obj *obj) { @@ -3586,6 +3643,7 @@ use_grapple(struct obj *obj) return ECMD_OK; } if (obj != uwep) { + /* "cast": grappling hook evolved from slash'em's fishing pole */ if (wield_tool(obj, "cast")) { cmdq_add_ec(CQ_CANNED, doapply); cmdq_add_key(CQ_CANNED, obj->invlet); @@ -3599,7 +3657,7 @@ use_grapple(struct obj *obj) pline(where_to_hit); cc.x = u.ux; cc.y = u.uy; - getpos_sethilite(NULL, can_grapple_location); + getpos_sethilite(display_grapple_positions, can_grapple_location); if (getpos(&cc, TRUE, "the spot to hit") < 0) /* ESC; uses turn iff grapnel became wielded */ return (res | ECMD_CANCEL); diff --git a/src/do_name.c b/src/do_name.c index 00e6ca570..872384457 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do_name.c $NHDT-Date: 1708124164 2024/02/16 22:56:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.306 $ */ +/* NetHack 3.7 do_name.c $NHDT-Date: 1708126536 2024/02/16 23:35:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.307 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -47,7 +47,7 @@ nextmbuf(void) /* function for getpos() to highlight desired map locations. * parameter value 0 = initialize, 1 = highlight, 2 = done */ -static void (*getpos_hilitefunc)(int) = (void (*)(int)) 0; +static void (*getpos_hilitefunc)(boolean) = (void (*)(boolean)) 0; static boolean (*getpos_getvalid)(coordxy, coordxy) = (boolean (*)(coordxy, coordxy)) 0; enum getposHiliteState { @@ -61,7 +61,7 @@ static enum getposHiliteState void getpos_sethilite( - void (*gp_hilitef)(int), + void (*gp_hilitef)(boolean), boolean (*gp_getvalidf)(coordxy, coordxy)) { boolean (*old_getvalid)(coordxy, coordxy) = getpos_getvalid; @@ -96,7 +96,7 @@ getpos_toggle_hilite_state(void) /* getpos_hilitefunc isn't Null */ if (getpos_hilite_state == HiliteGoodposSymbol) { /* currently on, finish */ - (*getpos_hilitefunc)(2); /* tmp_at(DISP_END) */ + (*getpos_hilitefunc)(FALSE); /* tmp_at(DISP_END) */ } getpos_hilite_state = (getpos_hilite_state + 1) @@ -108,8 +108,7 @@ getpos_toggle_hilite_state(void) if (getpos_hilite_state == HiliteGoodposSymbol) { /* now on, begin */ - (*getpos_hilitefunc)(0); /* tmp_at(DISP_start) */ - (*getpos_hilitefunc)(1); /* update appropriate spots w/ S_goodpos */ + (*getpos_hilitefunc)(TRUE); } } @@ -769,7 +768,7 @@ static void getpos_refresh(void) { if (getpos_hilitefunc && getpos_hilite_state == HiliteGoodposSymbol) { - (*getpos_hilitefunc)(2); /* tmp_at(DISP_END) */ + (*getpos_hilitefunc)(FALSE); /* tmp_at(DISP_END) */ getpos_hilite_state = defaultHiliteState; } diff --git a/src/read.c b/src/read.c index 05a4eef79..7def83c06 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 read.c $NHDT-Date: 1654931501 2022/06/11 07:11:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.257 $ */ +/* NetHack 3.7 read.c $NHDT-Date: 1708126537 2024/02/16 23:35:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.300 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -19,7 +19,7 @@ static void p_glow2(struct obj *, const char *); static void forget(int); static int maybe_tame(struct monst *, struct obj *); static boolean can_center_cloud(coordxy, coordxy); -static void display_stinking_cloud_positions(int); +static void display_stinking_cloud_positions(boolean); static void seffect_enchant_armor(struct obj **); static void seffect_destroy_armor(struct obj **); static void seffect_confuse_monster(struct obj **); @@ -1066,22 +1066,28 @@ can_center_cloud(coordxy x, coordxy y) } static void -display_stinking_cloud_positions(int state) +display_stinking_cloud_positions(boolean on_off) { - if (state == 0) { - tmp_at(DISP_BEAM, cmap_to_glyph(S_goodpos)); - } else if (state == 1) { - coordxy x, y, dx, dy; - int dist = 6; + coordxy x, y, dx, dy; + int dist = 6; + if (on_off) { + /* on */ + tmp_at(DISP_BEAM, cmap_to_glyph(S_goodpos)); for (dx = -dist; dx <= dist; dx++) for (dy = -dist; dy <= dist; dy++) { x = u.ux + dx; y = u.uy + dy; - if (can_center_cloud(x,y)) + /* hero's location is allowed but highlighting the hero's + spot makes map harder to read (if using '$' rather than + by changing background color) */ + if (u_at(x, y)) + continue; + if (can_center_cloud(x, y)) tmp_at(x, y); } } else { + /* off */ tmp_at(DISP_END, 0); } } diff --git a/src/spell.c b/src/spell.c index 8ff0e856b..b04bb2400 100644 --- a/src/spell.c +++ b/src/spell.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 spell.c $NHDT-Date: 1702023273 2023/12/08 08:14:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.157 $ */ +/* NetHack 3.7 spell.c $NHDT-Date: 1708126538 2024/02/16 23:35:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.163 $ */ /* Copyright (c) M. Stephenson 1988 */ /* NetHack may be freely redistributed. See license for details. */ @@ -46,6 +46,7 @@ static void spell_backfire(int); static boolean spelleffects_check(int, int *, int *); static const char *spelltypemnemonic(int); static boolean can_center_spell_location(coordxy, coordxy); +static void display_spell_target_positions(boolean); static boolean spell_aim_step(genericptr_t, coordxy, coordxy); /* The roles[] table lists the role-specific values for tuning @@ -1556,6 +1557,33 @@ can_center_spell_location(coordxy x, coordxy y) return (isok(x, y) && cansee(x, y) && !(IS_STWALL(levl[x][y].typ))); } +static void +display_spell_target_positions(boolean on_off) +{ + coordxy x, y, dx, dy; + int dist = 10; + + if (on_off) { + /* on */ + tmp_at(DISP_BEAM, cmap_to_glyph(S_goodpos)); + for (dx = -dist; dx <= dist; dx++) + for (dy = -dist; dy <= dist; dy++) { + x = u.ux + dx; + y = u.uy + dy; + /* hero's location is allowed but highlighting the hero's + spot makes map harder to read (if using '$' rather than + by changing background color) */ + if (u_at(x, y)) + continue; + if (can_center_spell_location(x, y)) + tmp_at(x, y); + } + } else { + /* off */ + tmp_at(DISP_END, 0); + } +} + /* Choose location where spell takes effect. */ static int throwspell(void) @@ -1574,7 +1602,8 @@ throwspell(void) pline("Where do you want to cast the spell?"); cc.x = u.ux; cc.y = u.uy; - getpos_sethilite(NULL, can_center_spell_location); + getpos_sethilite(display_spell_target_positions, + can_center_spell_location); if (getpos(&cc, TRUE, "the desired position") < 0) return 0; /* user pressed ESC */ clear_nhwindow(WIN_MESSAGE); /* discard any autodescribe feedback */