randomized trap names

Use trapname() in several more places.  I wasn't systematic about it.

trapname() could generate a random value of 0 and attempt to use
"real trap #0" but 0 is NO_TRAP.  So it ended up with "water" from
the preceding block of entries in defsyms[].  Treat 0 as an extra
chance for the actual trap instead of an hallucinatory one.

Add a couple more hallucinatory traps.  "Roach Motel" is trademarked
but like Spam and Band-Aid, general usage has trampled over it.  I
included "(tm)" anyway.  Also, sometimes generate "<role> trap" or
"<rank> trap" on the fly.  Why should tourists get all the fun?
This commit is contained in:
PatR
2020-01-09 18:45:06 -08:00
parent 3ed51c2718
commit f6c547f376
2 changed files with 52 additions and 25 deletions

View File

@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ $NHDT-Date: 1578400811 2020/01/07 12:40:11 $
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.58 $ $NHDT-Date: 1578624299 2020/01/10 02:44:59 $
General Fixes and Modified Features
-----------------------------------
@@ -55,6 +55,7 @@ autounlock picked Rogue's artifact key over lock-pick or credit card (or
ordinary key depending upon invent order) even for non-rogues who
would be blasted when touching it
wielded aklys had its "(tethered weapon...)" description scrambled
randomized trap name could pick trap #0 which isn't a trap and yielded "water"
Platform- and/or Interface-Specific Fixes

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 trap.c $NHDT-Date: 1577759854 2019/12/31 02:37:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.348 $ */
/* NetHack 3.6 trap.c $NHDT-Date: 1578624299 2020/01/10 02:44:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.349 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
@@ -954,6 +954,14 @@ unsigned trflags;
steed_article = ARTICLE_NONE;
}
/*
* Note:
* Most references to trap types here don't use trapname() for
* hallucination. This could be considered to be a bug but doing
* that would hide the actual trap situation from the player which
* would be somewhat harsh for what's usually a minor impairment.
*/
switch (ttype) {
case ARROW_TRAP:
if (trap->once && trap->tseen && !rn2(15)) {
@@ -2831,7 +2839,7 @@ float_up()
if (u.utrap) {
if (u.utraptype == TT_PIT) {
reset_utrap(FALSE);
You("float up, out of the pit!");
You("float up, out of the %s!", trapname(PIT, FALSE));
g.vision_full_recalc = 1; /* vision limits change */
fill_pit(u.ux, u.uy);
} else if (u.utraptype == TT_LAVA /* molten lava */
@@ -2852,7 +2860,8 @@ float_up()
body_part(LEG),
IS_ROOM(levl[cc.x][cc.y].typ) ? "floor" : "ground");
} else if (u.utraptype == WEB) {
You("float up slightly, but you are still stuck in the web.");
You("float up slightly, but you are still stuck in the %s.",
trapname(WEB, FALSE));
} else { /* bear trap */
You("float up slightly, but your %s is still stuck.",
body_part(LEG));
@@ -3068,12 +3077,15 @@ long hmask, emask; /* might cancel timeout */
void
climb_pit()
{
const char *pitname;
if (!u.utrap || u.utraptype != TT_PIT)
return;
pitname = trapname(PIT, FALSE);
if (Passes_walls) {
/* marked as trapped so they can pick things up */
You("ascend from the pit.");
You("ascend from the %s.", pitname);
reset_utrap(FALSE);
fill_pit(u.ux, u.uy);
g.vision_full_recalc = 1; /* vision limits change */
@@ -3085,19 +3097,24 @@ climb_pit()
} else if ((Flying || is_clinger(g.youmonst.data)) && !Sokoban) {
/* eg fell in pit, then poly'd to a flying monster;
or used '>' to deliberately enter it */
You("%s from the pit.", Flying ? "fly" : "climb");
You("%s from the %s.", Flying ? "fly" : "climb", pitname);
reset_utrap(FALSE);
fill_pit(u.ux, u.uy);
g.vision_full_recalc = 1; /* vision limits change */
} else if (!(--u.utrap)) {
reset_utrap(FALSE);
You("%s to the edge of the pit.",
You("%s to the edge of the %s.",
(Sokoban && Levitation)
? "struggle against the air currents and float"
: u.usteed ? "ride" : "crawl");
: u.usteed ? "ride" : "crawl",
pitname);
fill_pit(u.ux, u.uy);
g.vision_full_recalc = 1; /* vision limits change */
} else if (u.dz || flags.verbose) {
/* these should use 'pitname' rather than "pit" for hallucination
but that would nullify Norep (this message can be repeated
many times without further user intervention by using a run
attempt to keep retrying to escape from the pit) */
if (u.usteed)
Norep("%s is still in a pit.", upstart(y_monnam(u.usteed)));
else
@@ -5455,9 +5472,6 @@ maybe_finish_sokoban()
* If the second argument is true, return the correct trap name even when
* hallucinating (for things like wizard mode wishing for traps and impossible
* calls).
* Originally I had intended for messages like "You begin setting the bear trap"
* to override as well, but the context in those bits of code indicated that it
* was meant to take a random name if the hero was hallucinating.
*/
const char *
trapname(ttyp, override)
@@ -5469,6 +5483,7 @@ boolean override;
"bottomless pit", "polymorphism trap", "devil teleporter",
"falling boulder trap", "anti-anti-magic field", "weeping gas trap",
"queasy board", "electrified web", "owlbear trap", "sand mine",
"vacillating triangle",
/* some traps found in nethack variants */
"death trap", "disintegration trap", "ice trap", "monochrome trap",
/* plausible real-life traps */
@@ -5476,7 +5491,7 @@ boolean override;
"field of caltrops", "buzzsaw trap", "spiked floor", "revolving wall",
"uneven floor", "finger trap", "jack-in-a-box", "yellow snow",
"booby trap", "rat trap", "poisoned nail", "snare", "whirlpool",
"trip wire",
"trip wire", "roach motel (tm)",
/* sci-fi */
"negative space", "tensor field", "singularity", "imperial fleet",
"black hole", "thermal detonator", "event horizon",
@@ -5484,22 +5499,33 @@ boolean override;
/* miscellaneous suggestions */
"sweet-smelling gas vent", "phone booth", "exploding runes",
"never-ending elevator", "slime pit", "warp zone", "illusory floor",
"pile of poo", "honey trap", "tourist trap"
"pile of poo", "honey trap", "tourist trap",
};
int total_names, nameidx;
static char roletrap[33]; /* [17 + 5 + 1] should suffice */
if (override || !Hallucination) {
return defsyms[trap_to_defsym(ttyp)].explanation;
}
total_names = TRAPNUM + SIZE(halu_trapnames);
nameidx = rn2_on_display_rng(total_names);
if (nameidx < TRAPNUM) {
/* random but real trap name */
return defsyms[trap_to_defsym(nameidx)].explanation;
} else {
nameidx -= TRAPNUM;
return halu_trapnames[nameidx];
if (Hallucination && !override) {
int total_names = TRAPNUM + SIZE(halu_trapnames),
nameidx = rn2_on_display_rng(total_names + 1);
if (nameidx == total_names) {
boolean fem = Upolyd ? u.mfemale : flags.female;
/* inspired by "tourist trap" */
copynchars(roletrap,
rn2(3) ? ((fem && g.urole.name.f) ? g.urole.name.f
: g.urole.name.m)
: rank_of(u.ulevel, Role_switch, fem),
(int) (sizeof roletrap - sizeof " trap"));
Strcat(roletrap, " trap");
return lcase(roletrap);
} else if (nameidx >= TRAPNUM) {
nameidx -= TRAPNUM;
return halu_trapnames[nameidx];
} /* else use an actual trap type */
if (nameidx != NO_TRAP)
ttyp = nameidx;
}
return defsyms[trap_to_defsym(ttyp)].explanation;
}
/*trap.c*/