Skip to content

Commit

Permalink
Add paranoid:swim to prevent typoing into water or lava
Browse files Browse the repository at this point in the history
In the name of accessibility: Prevent moving into dangerous liquids.

Now with themed rooms, water and lava are more common, and it's
unreasonable to expect blind players to check every step for those.
With paranoid:swim, just prevent normal walking into those liquids,
unless you prefix the movement with 'm', or if the liquid would not
harm you.

Doesn't completely prevent an accidental dunking - for example
if the hero is impaired or couldn't see the liquid.

This comes from xNetHack by copperwater <aosdict@gmail.com>
with some changes to the code.
  • Loading branch information
paxed committed Feb 12, 2022
1 parent c862f2a commit 03c715f
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 1 deletion.
4 changes: 4 additions & 0 deletions doc/Guidebook.mn
Expand Up @@ -4054,6 +4054,8 @@ than immediately praying; on by default;
.PL Remove
require selection from inventory for \(oqR\(cq and \(oqT\(cq
commands even when wearing just one applicable item.
.PL swim
prevent walking into water or lava.
.PL all
turn on all of the above.
.PE
Expand Down Expand Up @@ -5508,6 +5510,8 @@ If this is the case, disable the
.op number_pad
option and use the traditional
Rogue-like commands.
.lp paranoid_confirmation:swim
Prevent walking into water or lava.
.lp autodescribe
Automatically describe the terrain under the cursor when targeting.
.lp mention_walls
Expand Down
5 changes: 5 additions & 0 deletions doc/Guidebook.tex
Expand Up @@ -4430,6 +4430,8 @@ \subsection*{Customization options}
\item[{\tt Remove~}] require selection from inventory for `{\tt R}'
and `{\tt T}'
commands even when wearing just one applicable item.
\item[{\tt swim~~~}]
prevent walking into water or lava.
\item[{\tt all~~~~}]
turn on all of the above.
\elist
Expand Down Expand Up @@ -6054,6 +6056,9 @@ \subsection*{Configuring {\it NetHack\/} for Play by the Blind}
If this is the case, disable the number\verb+_+pad option and use the
traditional Rogue-like commands.
%.lp
\item[\ib{paranoid\verb+_+confirmation:swim}]
Prevent walking into water or lava.
%.lp
\item[\ib{autodescribe}]
Automatically describe the terrain under the cursor when targeting.
%.lp
Expand Down
1 change: 1 addition & 0 deletions doc/fixes3-7-0.txt
Expand Up @@ -1410,6 +1410,7 @@ reading a blessed scroll of light has a chance to improve bless/curse state
of wielded Sunsword or worn gold dragon scales/mail similar to dipping
those into holy water; cursed scroll has chance to worsen the state
added a chronicle of major events, and optional live logging of those
paranoid:swim to prevent accidental dunking into dangerous liquids


Platform- and/or Interface-Specific New Features
Expand Down
1 change: 1 addition & 0 deletions include/context.h
Expand Up @@ -150,6 +150,7 @@ struct context_info {
boolean botlx; /* print an entirely new bottom line */
boolean door_opened; /* set to true if door was opened during test_move */
boolean enhance_tip; /* player is informed about #enhance */
boolean swim_tip; /* player was informed about walking into water */
struct dig_info digging;
struct victual_info victual;
struct engrave_info engraving;
Expand Down
3 changes: 3 additions & 0 deletions include/flag.h
Expand Up @@ -78,6 +78,7 @@ struct flag {
#define PARANOID_BREAKWAND 0x0080
#define PARANOID_WERECHANGE 0x0100
#define PARANOID_EATING 0x0200
#define PARANOID_SWIM 0x0400
int pickup_burden; /* maximum burden before prompt */
int pile_limit; /* controls feedback when walking over objects */
char discosort; /* order of dodiscovery/doclassdisco output: o,s,c,a */
Expand Down Expand Up @@ -466,6 +467,8 @@ enum runmode_types {
/* continue eating: prompt given _after_first_bite_ when eating something
while satiated */
#define ParanoidEating ((flags.paranoia_bits & PARANOID_EATING) != 0)
/* Prevent going into lava or water without explicitly forcing it */
#define ParanoidSwim ((flags.paranoia_bits & PARANOID_SWIM) != 0)

/* command parsing, mainly dealing with number_pad handling;
not saved and restored */
Expand Down
1 change: 1 addition & 0 deletions include/mondata.h
Expand Up @@ -38,6 +38,7 @@
#define is_floater(ptr) ((ptr)->mlet == S_EYE || (ptr)->mlet == S_LIGHT)
/* clinger: piercers, mimics, wumpus -- generally don't fall down holes */
#define is_clinger(ptr) (((ptr)->mflags1 & M1_CLING) != 0L)
#define grounded(ptr) (!is_flyer(ptr) && !is_floater(ptr) && !is_clinger(ptr))
#define is_swimmer(ptr) (((ptr)->mflags1 & M1_SWIM) != 0L)
#define breathless(ptr) (((ptr)->mflags1 & M1_BREATHLESS) != 0L)
#define amphibious(ptr) \
Expand Down
2 changes: 1 addition & 1 deletion include/patchlevel.h
Expand Up @@ -17,7 +17,7 @@
* Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files.
*/
#define EDITLEVEL 49
#define EDITLEVEL 50

/*
* Development status possibilities.
Expand Down
48 changes: 48 additions & 0 deletions src/hack.c
Expand Up @@ -13,6 +13,7 @@ static void dosinkfall(void);
static boolean findtravelpath(int);
static boolean trapmove(int, int, struct trap *);
static void check_buried_zombies(xchar, xchar);
static boolean swim_move_danger(xchar x, xchar y);
static void domove_core(void);
static void maybe_smudge_engr(int, int, int, int);
static struct monst *monstinroom(struct permonst *, int);
Expand Down Expand Up @@ -1519,6 +1520,46 @@ check_buried_zombies(xchar x, xchar y)
}
}

/* Is it dangerous for hero to move to x,y due to water or lava? */
static boolean
swim_move_danger(xchar x, xchar y)
{
if (!Levitation && !Flying && grounded(g.youmonst.data) && !Stunned
&& !Confusion && levl[x][y].seenv
&& ((is_pool(x, y) && !is_pool(u.ux, u.uy))
|| (is_lava(x, y) && !is_lava(u.ux, u.uy)))) {
boolean known_wwalking, known_lwalking;

known_wwalking = (uarmf && uarmf->otyp == WATER_WALKING_BOOTS
&& objects[WATER_WALKING_BOOTS].oc_name_known
&& !u.usteed);
known_lwalking = (known_wwalking && Fire_resistance &&
uarmf->oerodeproof && uarmf->rknown);
/* FIXME: This can be exploited to identify the ring of fire resistance
* if the player is wearing it unidentified and has identified
* fireproof boots of water walking and is walking over lava. However,
* this is such a marginal case that it may not be worth fixing. */
if ((is_pool(x, y) && !known_wwalking)
|| (is_lava(x, y) && !known_lwalking)) {
if (g.context.nopick) {
/* moving with m-prefix */
g.context.swim_tip = TRUE;
return FALSE;
} else if (ParanoidSwim) {
You("avoid stepping into the %s.",
waterbody_name(x, y));
if (!g.context.swim_tip) {
pline("(Use '%s' prefix to step in if you really want to.)",
visctrl(cmd_from_func(do_reqmenu)));
g.context.swim_tip = TRUE;
}
return TRUE;
}
}
}
return FALSE;
}

void
domove(void)
{
Expand Down Expand Up @@ -1946,6 +1987,13 @@ domove_core(void)
return;
}

/* Is it dangerous to swim in water or lava? */
if (swim_move_danger(x, y)) {
g.context.move = 0;
nomul(0);
return;
}

/* Move ball and chain. */
if (Punished)
if (!drag_ball(x, y, &bc_control, &ballx, &bally, &chainx, &chainy,
Expand Down
2 changes: 2 additions & 0 deletions src/options.c
Expand Up @@ -154,6 +154,8 @@ static const struct paranoia_opts {
"y to pray (supersedes old \"prayconfirm\" option)" },
{ PARANOID_REMOVE, "Remove", 1, "Takeoff", 1,
"always pick from inventory for Remove and Takeoff" },
{ PARANOID_SWIM, "swim", 1, 0, 0,
"avoid walking into lava or water" },
/* for config file parsing; interactive menu skips these */
{ 0, "none", 4, 0, 0, 0 }, /* require full word match */
{ ~0, "all", 3, 0, 0, 0 }, /* ditto */
Expand Down

0 comments on commit 03c715f

Please sign in to comment.