Add hallucinatory trap names
This adds many funny, realistic, and nonsensical traps to the game, to be shown when the player is hallucinating. Architecturally, the biggest change is merging the what_trap macro and the "defsyms[trap_to_defsym(ttyp)].explanation" pattern into a single function "trapname", which returns the name of the trap, handling the hallucination case. There is also a second parameter used for overriding hallucination in the occasional cases where the actual trap name should always be returned. In addition, the what_trap and random_trap macros are now obsolete and not used anywhere, so they are removed.
This commit is contained in:
@@ -142,25 +142,21 @@
|
||||
/*
|
||||
* random_monster()
|
||||
* random_object()
|
||||
* random_trap()
|
||||
*
|
||||
* Respectively return a random monster, object, or trap number.
|
||||
* Respectively return a random monster or object.
|
||||
*/
|
||||
#define random_monster() rn2(NUMMONS)
|
||||
#define random_object() rn1(NUM_OBJECTS - 1, 1)
|
||||
#define random_trap() rn1(TRAPNUM - 1, 1)
|
||||
|
||||
/*
|
||||
* what_obj()
|
||||
* what_mon()
|
||||
* what_trap()
|
||||
*
|
||||
* If hallucinating, choose a random object/monster, otherwise, use the one
|
||||
* given.
|
||||
*/
|
||||
#define what_obj(obj) (Hallucination ? random_object() : obj)
|
||||
#define what_mon(mon) (Hallucination ? random_monster() : mon)
|
||||
#define what_trap(trp) (Hallucination ? random_trap() : trp)
|
||||
|
||||
/*
|
||||
* covers_objects()
|
||||
@@ -319,7 +315,7 @@
|
||||
((((expltype) * MAXEXPCHARS) + ((idx) - S_explode1)) + GLYPH_EXPLODE_OFF)
|
||||
|
||||
#define trap_to_glyph(trap) \
|
||||
cmap_to_glyph(trap_to_defsym(what_trap((trap)->ttyp)))
|
||||
cmap_to_glyph(trap_to_defsym((trap)->ttyp))
|
||||
|
||||
/* Not affected by hallucination. Gives a generic body for CORPSE */
|
||||
/* MRKR: ...and the generic statue */
|
||||
|
||||
@@ -2499,6 +2499,7 @@ E boolean FDECL(uteetering_at_seen_pit, (struct trap *));
|
||||
E boolean NDECL(lava_effects);
|
||||
E void NDECL(sink_into_lava);
|
||||
E void NDECL(sokoban_guilt);
|
||||
E const char * FDECL(trapname, (int, BOOLEAN_P));
|
||||
|
||||
/* ### u_init.c ### */
|
||||
|
||||
|
||||
14
src/apply.c
14
src/apply.c
@@ -2501,7 +2501,7 @@ struct obj *otmp;
|
||||
ttyp = (otmp->otyp == LAND_MINE) ? LANDMINE : BEAR_TRAP;
|
||||
if (otmp == trapinfo.tobj && u.ux == trapinfo.tx && u.uy == trapinfo.ty) {
|
||||
You("resume setting %s%s.", shk_your(buf, otmp),
|
||||
defsyms[trap_to_defsym(what_trap(ttyp))].explanation);
|
||||
trapname(ttyp, FALSE));
|
||||
set_occupation(set_trap, occutext, 0);
|
||||
return;
|
||||
}
|
||||
@@ -2526,7 +2526,7 @@ struct obj *otmp;
|
||||
chance = (rnl(10) > 5);
|
||||
You("aren't very skilled at reaching from %s.", mon_nam(u.usteed));
|
||||
Sprintf(buf, "Continue your attempt to set %s?",
|
||||
the(defsyms[trap_to_defsym(what_trap(ttyp))].explanation));
|
||||
the(trapname(ttyp, FALSE)));
|
||||
if (yn(buf) == 'y') {
|
||||
if (chance) {
|
||||
switch (ttyp) {
|
||||
@@ -2536,9 +2536,7 @@ struct obj *otmp;
|
||||
break;
|
||||
case BEAR_TRAP: /* drop it without arming it */
|
||||
reset_trapset();
|
||||
You("drop %s!",
|
||||
the(defsyms[trap_to_defsym(what_trap(ttyp))]
|
||||
.explanation));
|
||||
You("drop %s!", the(trapname(ttyp, FALSE)));
|
||||
dropx(otmp);
|
||||
return;
|
||||
}
|
||||
@@ -2548,8 +2546,7 @@ struct obj *otmp;
|
||||
return;
|
||||
}
|
||||
}
|
||||
You("begin setting %s%s.", shk_your(buf, otmp),
|
||||
defsyms[trap_to_defsym(what_trap(ttyp))].explanation);
|
||||
You("begin setting %s%s.", shk_your(buf, otmp), trapname(ttyp, FALSE));
|
||||
set_occupation(set_trap, occutext, 0);
|
||||
return;
|
||||
}
|
||||
@@ -2581,8 +2578,7 @@ set_trap()
|
||||
add_damage(u.ux, u.uy, 0L); /* schedule removal */
|
||||
}
|
||||
if (!trapinfo.force_bungle)
|
||||
You("finish arming %s.",
|
||||
the(defsyms[trap_to_defsym(what_trap(ttyp))].explanation));
|
||||
You("finish arming %s.", the(trapname(ttyp, FALSE)));
|
||||
if (((otmp->cursed || Fumbling) && (rnl(10) > 5))
|
||||
|| trapinfo.force_bungle)
|
||||
dotrap(ttmp,
|
||||
|
||||
@@ -2293,7 +2293,7 @@ int final;
|
||||
Strcpy(predicament, "trapped");
|
||||
if ((t = t_at(u.ux, u.uy)) != 0)
|
||||
Sprintf(eos(predicament), " in %s",
|
||||
an(defsyms[trap_to_defsym(t->ttyp)].explanation));
|
||||
an(trapname(t->ttyp, FALSE)));
|
||||
}
|
||||
if (u.usteed) { /* not `Riding' here */
|
||||
Sprintf(buf, "%s%s ", anchored ? "you and " : "", steedname);
|
||||
|
||||
@@ -1591,7 +1591,6 @@ void
|
||||
find_trap(trap)
|
||||
struct trap *trap;
|
||||
{
|
||||
int tt = what_trap(trap->ttyp);
|
||||
boolean cleared = FALSE;
|
||||
|
||||
trap->tseen = 1;
|
||||
@@ -1606,7 +1605,7 @@ struct trap *trap;
|
||||
cleared = TRUE;
|
||||
}
|
||||
|
||||
You("find %s.", an(defsyms[trap_to_defsym(tt)].explanation));
|
||||
You("find %s.", an(trapname(trap->ttyp, FALSE)));
|
||||
|
||||
if (cleared) {
|
||||
display_nhwindow(WIN_MAP, TRUE); /* wait */
|
||||
|
||||
@@ -581,7 +581,7 @@ int ttyp;
|
||||
|
||||
if (ttyp != PIT && (!Can_dig_down(&u.uz) && !lev->candig)) {
|
||||
impossible("digactualhole: can't dig %s on this level.",
|
||||
defsyms[trap_to_defsym(ttyp)].explanation);
|
||||
trapname(ttyp, TRUE));
|
||||
ttyp = PIT;
|
||||
}
|
||||
|
||||
|
||||
@@ -755,8 +755,7 @@ int x, y;
|
||||
return TRUE;
|
||||
} else {
|
||||
if (ttmp->tseen)
|
||||
You("pass right over %s.",
|
||||
an(defsyms[trap_to_defsym(ttmp->ttyp)].explanation));
|
||||
You("pass right over %s.", an(trapname(ttmp->ttyp, FALSE)));
|
||||
}
|
||||
}
|
||||
if (--*range < 0) /* make sure our range never goes negative */
|
||||
|
||||
@@ -1453,10 +1453,8 @@ domove()
|
||||
if (context.run >= 2) {
|
||||
if (iflags.mention_walls) {
|
||||
if (trap && trap->tseen) {
|
||||
int tt = what_trap(trap->ttyp);
|
||||
|
||||
You("stop in front of %s.",
|
||||
an(defsyms[trap_to_defsym(tt)].explanation));
|
||||
an(trapname(trap->ttyp, FALSE)));
|
||||
} else if (is_pool_or_lava(x,y) && levl[x][y].seenv) {
|
||||
You("stop at the edge of the %s.",
|
||||
hliquid(is_pool(x,y) ? "water" : "lava"));
|
||||
@@ -2678,9 +2676,8 @@ lookaround()
|
||||
goto bcorr; /* if you must */
|
||||
if (x == u.ux + u.dx && y == u.uy + u.dy) {
|
||||
if (iflags.mention_walls) {
|
||||
int tt = what_trap(trap->ttyp);
|
||||
You("stop in front of %s.",
|
||||
an(defsyms[trap_to_defsym(tt)].explanation));
|
||||
an(trapname(trap->ttyp, FALSE)));
|
||||
}
|
||||
goto stop;
|
||||
}
|
||||
|
||||
@@ -3382,8 +3382,7 @@ boolean picked_some;
|
||||
return !!Blind;
|
||||
}
|
||||
if (!skip_objects && (trap = t_at(u.ux, u.uy)) && trap->tseen)
|
||||
There("is %s here.",
|
||||
an(defsyms[trap_to_defsym(trap->ttyp)].explanation));
|
||||
There("is %s here.", an(trapname(trap->ttyp, FALSE)));
|
||||
|
||||
otmp = level.objects[u.ux][u.uy];
|
||||
dfeature = dfeature_at(u.ux, u.uy, fbuf2);
|
||||
|
||||
@@ -3363,10 +3363,8 @@ struct obj *no_wish;
|
||||
goto typfnd;
|
||||
} else if (trapped == 1 || *zp != '\0') {
|
||||
/* "trapped <foo>" or "<foo> trap" (actually "<foo>*") */
|
||||
int idx = trap_to_defsym(beartrap ? BEAR_TRAP : LANDMINE);
|
||||
|
||||
/* use canonical trap spelling, skip object matching */
|
||||
Strcpy(bp, defsyms[idx].explanation);
|
||||
Strcpy(bp, trapname(beartrap ? BEAR_TRAP : LANDMINE, TRUE));
|
||||
goto wiztrap;
|
||||
}
|
||||
/* [no prefix or suffix; we're going to end up matching
|
||||
@@ -3568,7 +3566,7 @@ wiztrap:
|
||||
struct trap *t;
|
||||
const char *tname;
|
||||
|
||||
tname = defsyms[trap_to_defsym(trap)].explanation;
|
||||
tname = trapname(trap, TRUE);
|
||||
if (strncmpi(tname, bp, strlen(tname)))
|
||||
continue;
|
||||
/* found it; avoid stupid mistakes */
|
||||
@@ -3576,7 +3574,7 @@ wiztrap:
|
||||
trap = ROCKTRAP;
|
||||
if ((t = maketrap(x, y, trap)) != 0) {
|
||||
trap = t->ttyp;
|
||||
tname = defsyms[trap_to_defsym(trap)].explanation;
|
||||
tname = trapname(trap, TRUE);
|
||||
pline("%s%s.", An(tname),
|
||||
(trap != MAGIC_PORTAL) ? "" : " to nowhere");
|
||||
} else
|
||||
|
||||
10
src/pager.c
10
src/pager.c
@@ -285,8 +285,7 @@ int x, y;
|
||||
|
||||
/* newsym lets you know of the trap, so mention it here */
|
||||
if (tt == BEAR_TRAP || is_pit(tt) || tt == WEB)
|
||||
Sprintf(eos(buf), ", trapped in %s",
|
||||
an(defsyms[trap_to_defsym(tt)].explanation));
|
||||
Sprintf(eos(buf), ", trapped in %s", an(trapname(tt, FALSE)));
|
||||
}
|
||||
|
||||
/* we know the hero sees a monster at this location, but if it's shown
|
||||
@@ -435,7 +434,7 @@ char *buf, *monbuf;
|
||||
} else if (glyph_is_object(glyph)) {
|
||||
look_at_object(buf, x, y, glyph); /* fill in buf[] */
|
||||
} else if (glyph_is_trap(glyph)) {
|
||||
int tnum = what_trap(glyph_to_trap(glyph));
|
||||
int tnum = glyph_to_trap(glyph);
|
||||
|
||||
/* Trap detection displays a bear trap at locations having
|
||||
* a trapped door or trapped container or both.
|
||||
@@ -447,7 +446,7 @@ char *buf, *monbuf;
|
||||
else if (trapped_door_at(tnum, x, y))
|
||||
Strcpy(buf, "trapped door"); /* not "trap door"... */
|
||||
else
|
||||
Strcpy(buf, defsyms[trap_to_defsym(tnum)].explanation);
|
||||
Strcpy(buf, trapname(tnum, FALSE));
|
||||
} else if (glyph_is_warning(glyph)) {
|
||||
int warnindx = glyph_to_warning(glyph);
|
||||
|
||||
@@ -1487,9 +1486,8 @@ doidtrap()
|
||||
if (u.dz < 0 ? is_hole(tt) : tt == ROCKTRAP)
|
||||
break;
|
||||
}
|
||||
tt = what_trap(tt);
|
||||
pline("That is %s%s%s.",
|
||||
an(defsyms[trap_to_defsym(tt)].explanation),
|
||||
an(trapname(tt, FALSE)),
|
||||
!trap->madeby_u
|
||||
? ""
|
||||
: (tt == WEB)
|
||||
|
||||
@@ -285,7 +285,7 @@ boolean force; /* Quietly force this animal */
|
||||
struct trap *t = t_at(mtmp->mx, mtmp->my);
|
||||
|
||||
You_cant("mount %s while %s's trapped in %s.", mon_nam(mtmp),
|
||||
mhe(mtmp), an(defsyms[trap_to_defsym(t->ttyp)].explanation));
|
||||
mhe(mtmp), an(trapname(t->ttyp, FALSE)));
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
73
src/trap.c
73
src/trap.c
@@ -916,14 +916,14 @@ unsigned trflags;
|
||||
*/
|
||||
pline("Air currents pull you down into %s %s!",
|
||||
a_your[trap->madeby_u],
|
||||
defsyms[trap_to_defsym(ttype)].explanation);
|
||||
trapname(ttype, TRUE)); /* do force "pit" while hallucinating */
|
||||
/* then proceed to normal trap effect */
|
||||
} else if (already_seen && !forcetrap) {
|
||||
if ((Levitation || (Flying && !plunged))
|
||||
&& (is_pit(ttype) || ttype == HOLE || ttype == BEAR_TRAP)) {
|
||||
You("%s over %s %s.", Levitation ? "float" : "fly",
|
||||
a_your[trap->madeby_u],
|
||||
defsyms[trap_to_defsym(ttype)].explanation);
|
||||
trapname(ttype, FALSE));
|
||||
return;
|
||||
}
|
||||
if (!Fumbling && ttype != MAGIC_PORTAL && ttype != VIBRATING_SQUARE
|
||||
@@ -934,7 +934,7 @@ unsigned trflags;
|
||||
You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u)
|
||||
? "an"
|
||||
: a_your[trap->madeby_u],
|
||||
defsyms[trap_to_defsym(ttype)].explanation);
|
||||
trapname(ttype, FALSE));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1283,7 +1283,7 @@ unsigned trflags;
|
||||
if (!Can_fall_thru(&u.uz)) {
|
||||
seetrap(trap); /* normally done in fall_through */
|
||||
impossible("dotrap: %ss cannot exist on this level.",
|
||||
defsyms[trap_to_defsym(ttype)].explanation);
|
||||
trapname(ttype, TRUE));
|
||||
break; /* don't activate it after all */
|
||||
}
|
||||
fall_through(TRUE);
|
||||
@@ -2461,7 +2461,7 @@ register struct monst *mtmp;
|
||||
case TRAPDOOR:
|
||||
if (!Can_fall_thru(&u.uz)) {
|
||||
impossible("mintrap: %ss cannot exist on this level.",
|
||||
defsyms[trap_to_defsym(tt)].explanation);
|
||||
trapname(tt, TRUE));
|
||||
break; /* don't activate it after all */
|
||||
}
|
||||
if (is_flyer(mptr) || is_floater(mptr) || mptr == &mons[PM_WUMPUS]
|
||||
@@ -4053,8 +4053,7 @@ boolean force_failure;
|
||||
if ((invent && (inv_weight() + weight_cap() > 600))
|
||||
|| bigmonst(youmonst.data)) {
|
||||
/* don't allow untrap if they can't get thru to it */
|
||||
You("are unable to reach the %s!",
|
||||
defsyms[trap_to_defsym(ttype)].explanation);
|
||||
You("are unable to reach the %s!", trapname(ttype, FALSE));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -4063,8 +4062,7 @@ boolean force_failure;
|
||||
if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
|
||||
rider_cant_reach();
|
||||
else
|
||||
You("are unable to reach the %s!",
|
||||
defsyms[trap_to_defsym(ttype)].explanation);
|
||||
You("are unable to reach the %s!", trapname(ttype, FALSE));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4104,7 +4102,7 @@ boolean force_failure;
|
||||
} else {
|
||||
pline("%s %s is difficult to %s.",
|
||||
ttmp->madeby_u ? "Your" : under_u ? "This" : "That",
|
||||
defsyms[trap_to_defsym(ttype)].explanation,
|
||||
trapname(ttype, FALSE),
|
||||
(ttype == WEB) ? "remove" : "disarm");
|
||||
}
|
||||
return 1;
|
||||
@@ -4383,7 +4381,7 @@ boolean force;
|
||||
ttmp = t_at(x, y);
|
||||
if (ttmp && !ttmp->tseen)
|
||||
ttmp = 0;
|
||||
trapdescr = ttmp ? defsyms[trap_to_defsym(ttmp->ttyp)].explanation : 0;
|
||||
trapdescr = ttmp ? trapname(ttmp->ttyp, FALSE) : 0;
|
||||
here = (x == u.ux && y == u.uy); /* !u.dx && !u.dy */
|
||||
|
||||
if (here) /* are there are one or more containers here? */
|
||||
@@ -4642,7 +4640,7 @@ boolean *noticed; /* set to true iff hero notices the effect; */
|
||||
}
|
||||
|
||||
if (!trapdescr)
|
||||
trapdescr = defsyms[trap_to_defsym(t->ttyp)].explanation;
|
||||
trapdescr = trapname(t->ttyp, FALSE);
|
||||
if (!which)
|
||||
which = t->tseen ? the_your[t->madeby_u]
|
||||
: index(vowels, *trapdescr) ? "an" : "a";
|
||||
@@ -5438,4 +5436,55 @@ maybe_finish_sokoban()
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the string name of the trap type passed in, unless the player is
|
||||
* hallucinating, in which case return a random or hallucinatory trap name.
|
||||
* 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)
|
||||
int ttyp;
|
||||
boolean override;
|
||||
{
|
||||
const char * halu_trapnames[] = {
|
||||
/* riffs on actual nethack traps */
|
||||
"bottomless pit", "polymorphism trap", "devil teleporter",
|
||||
"falling boulder trap", "anti-anti-magic field", "weeping gas trap",
|
||||
"queasy board", "electrified web", "owlbear trap", "sand mine",
|
||||
/* some traps found in nethack variants */
|
||||
"death trap", "disintegration trap", "ice trap", "monochrome trap",
|
||||
/* plausible real-life traps */
|
||||
"axeblade trap", "pool of boiling oil", "pool of quicksand",
|
||||
"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",
|
||||
/* sci-fi */
|
||||
"negative space", "tensor field", "singularity", "imperial fleet",
|
||||
"black hole", "thermal detonator", "event horizon",
|
||||
"entoptic phenomenon",
|
||||
/* 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"
|
||||
};
|
||||
int total_names = TRAPNUM + SIZE(halu_trapnames);
|
||||
int nameidx = rn2(total_names);
|
||||
if (override || !Hallucination) {
|
||||
return defsyms[trap_to_defsym(ttyp)].explanation;
|
||||
}
|
||||
if (nameidx < TRAPNUM) {
|
||||
/* random but real trap name */
|
||||
return defsyms[trap_to_defsym(nameidx)].explanation;
|
||||
}
|
||||
else {
|
||||
nameidx -= TRAPNUM;
|
||||
return halu_trapnames[nameidx];
|
||||
}
|
||||
}
|
||||
|
||||
/*trap.c*/
|
||||
|
||||
Reference in New Issue
Block a user