diff --git a/include/display.h b/include/display.h index 4bece448b..2a2e56bae 100644 --- a/include/display.h +++ b/include/display.h @@ -149,25 +149,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(rng) rng(NUMMONS) #define random_object(rng) (rng(NUM_OBJECTS - 1) + 1) -#define random_trap(rng) (rng(TRAPNUM - 1) + 1) /* * what_obj() * what_mon() - * what_trap() * * If hallucinating, choose a random object/monster, otherwise, use the one * given. Use the given rng to handle hallucination. */ #define what_obj(obj, rng) (Hallucination ? random_object(rng) : obj) #define what_mon(mon, rng) (Hallucination ? random_monster(rng) : mon) -#define what_trap(trp, rng) (Hallucination ? random_trap(rng) : trp) /* * newsym_rn2 @@ -338,8 +334,8 @@ #define explosion_to_glyph(expltype, idx) \ ((((expltype) * MAXEXPCHARS) + ((idx) - S_explode1)) + GLYPH_EXPLODE_OFF) -#define trap_to_glyph(trap, rng) \ - cmap_to_glyph(trap_to_defsym(what_trap((trap)->ttyp, rng))) +#define trap_to_glyph(trap) \ + cmap_to_glyph(trap_to_defsym((trap)->ttyp)) /* Not affected by hallucination. Gives a generic body for CORPSE */ /* MRKR: ...and the generic statue */ diff --git a/include/extern.h b/include/extern.h index f8544f150..50db404bc 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2563,6 +2563,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 ### */ diff --git a/src/apply.c b/src/apply.c index 257c12f98..cd99d5d5b 100644 --- a/src/apply.c +++ b/src/apply.c @@ -2487,7 +2487,7 @@ struct obj *otmp; if (otmp == g.trapinfo.tobj && u.ux == g.trapinfo.tx && u.uy == g.trapinfo.ty) { You("resume setting %s%s.", shk_your(buf, otmp), - defsyms[trap_to_defsym(what_trap(ttyp, rn2))].explanation); + trapname(ttyp, FALSE)); set_occupation(set_trap, occutext, 0); return; } @@ -2512,7 +2512,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, rn2))] + the(trapname(ttyp, FALSE))); .explanation)); if (yn(buf) == 'y') { if (chance) { @@ -2523,9 +2523,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, rn2))] - .explanation)); + You("drop %s!", the(trapname(ttyp, FALSE))); dropx(otmp); return; } @@ -2535,8 +2533,7 @@ struct obj *otmp; return; } } - You("begin setting %s%s.", shk_your(buf, otmp), - defsyms[trap_to_defsym(what_trap(ttyp, rn2))].explanation); + You("begin setting %s%s.", shk_your(buf, otmp), trapname(ttyp, FALSE)); set_occupation(set_trap, occutext, 0); return; } @@ -2567,8 +2564,7 @@ set_trap() add_damage(u.ux, u.uy, 0L); /* schedule removal */ } if (!g.trapinfo.force_bungle) - You("finish arming %s.", - the(defsyms[trap_to_defsym(what_trap(ttyp, rn2))].explanation)); + You("finish arming %s.", the(trapname(ttyp, FALSE))); if (((otmp->cursed || Fumbling) && (rnl(10) > 5)) || g.trapinfo.force_bungle) dotrap(ttmp, diff --git a/src/cmd.c b/src/cmd.c index 5b164de2f..9f1315162 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -2421,7 +2421,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); diff --git a/src/detect.c b/src/detect.c index 4ceca787b..7c29ac208 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1606,7 +1606,6 @@ void find_trap(trap) struct trap *trap; { - int tt = what_trap(trap->ttyp, rn2); boolean cleared = FALSE; trap->tseen = 1; @@ -1626,7 +1625,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 */ diff --git a/src/dig.c b/src/dig.c index 6bd239195..90c44caa6 100644 --- a/src/dig.c +++ b/src/dig.c @@ -579,7 +579,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; } diff --git a/src/dothrow.c b/src/dothrow.c index 552c8e0fd..dacce7a87 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -756,8 +756,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 */ diff --git a/src/hack.c b/src/hack.c index 31cb56963..ee260b396 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1481,10 +1481,8 @@ domove_core() if (g.context.run >= 2) { if (iflags.mention_walls) { if (trap && trap->tseen) { - int tt = what_trap(trap->ttyp, rn2_on_display_rng); - 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")); @@ -2734,10 +2732,9 @@ 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, rn2_on_display_rng); You("stop in front of %s.", - an(defsyms[trap_to_defsym(tt)].explanation)); + an(trapname(trap->ttyp, FALSE))); } goto stop; } diff --git a/src/invent.c b/src/invent.c index 13132536e..6f1a4e1a5 100644 --- a/src/invent.c +++ b/src/invent.c @@ -3418,8 +3418,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 = g.level.objects[u.ux][u.uy]; dfeature = dfeature_at(u.ux, u.uy, fbuf2); diff --git a/src/objnam.c b/src/objnam.c index aef37c6fa..e91639d2a 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -3423,10 +3423,8 @@ struct obj *no_wish; goto typfnd; } else if (trapped == 1 || *zp != '\0') { /* "trapped " or " trap" (actually "*") */ - 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 @@ -3628,7 +3626,7 @@ struct obj *no_wish; 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 */ @@ -3636,7 +3634,7 @@ struct obj *no_wish; 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 diff --git a/src/pager.c b/src/pager.c index 8dac57eb4..5823e4287 100644 --- a/src/pager.c +++ b/src/pager.c @@ -298,8 +298,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))); t->tseen = 1; } } @@ -451,7 +450,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), rn2_on_display_rng); + int tnum = glyph_to_trap(glyph); /* Trap detection displays a bear trap at locations having * a trapped door or trapped container or both. @@ -463,7 +462,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); @@ -1521,9 +1520,8 @@ doidtrap() if (u.dz < 0 ? is_hole(tt) : tt == ROCKTRAP) break; } - tt = what_trap(tt, rn2_on_display_rng); pline("That is %s%s%s.", - an(defsyms[trap_to_defsym(tt)].explanation), + an(trapname(tt, FALSE)), !trap->madeby_u ? "" : (tt == WEB) diff --git a/src/steed.c b/src/steed.c index 942bab8ec..c303df2dd 100644 --- a/src/steed.c +++ b/src/steed.c @@ -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); } diff --git a/src/trap.c b/src/trap.c index 12313d191..42acfb4af 100644 --- a/src/trap.c +++ b/src/trap.c @@ -913,14 +913,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 @@ -931,7 +931,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; } } @@ -1280,7 +1280,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); @@ -2448,7 +2448,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] @@ -4032,8 +4032,7 @@ boolean force_failure; if ((g.invent && (inv_weight() + weight_cap() > 600)) || bigmonst(g.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; } } @@ -4042,8 +4041,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; } @@ -4083,7 +4081,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; @@ -4362,7 +4360,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? */ @@ -4622,7 +4620,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"; @@ -5419,4 +5417,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*/