diff --git a/include/display.h b/include/display.h index 1334be2cc..68251158f 100644 --- a/include/display.h +++ b/include/display.h @@ -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 */ diff --git a/include/extern.h b/include/extern.h index dbef64c22..7f5f80000 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 ### */ diff --git a/src/apply.c b/src/apply.c index dbde93fba..9372b95fe 100644 --- a/src/apply.c +++ b/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, diff --git a/src/cmd.c b/src/cmd.c index 04df10458..1f9191ad6 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -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); diff --git a/src/detect.c b/src/detect.c index e6c5778af..f89689742 100644 --- a/src/detect.c +++ b/src/detect.c @@ -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 */ diff --git a/src/dig.c b/src/dig.c index 29d0941d4..0702ad0c8 100644 --- a/src/dig.c +++ b/src/dig.c @@ -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; } diff --git a/src/dothrow.c b/src/dothrow.c index de1afca9c..3226ed0b8 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -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 */ diff --git a/src/hack.c b/src/hack.c index 0e3f3f6f2..734ced2d6 100644 --- a/src/hack.c +++ b/src/hack.c @@ -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; } diff --git a/src/invent.c b/src/invent.c index c28a2120d..58fcd8408 100644 --- a/src/invent.c +++ b/src/invent.c @@ -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); diff --git a/src/objnam.c b/src/objnam.c index 597a79249..6e365e737 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -3363,10 +3363,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 @@ -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 diff --git a/src/pager.c b/src/pager.c index 5b7f43c48..52d26339a 100644 --- a/src/pager.c +++ b/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) diff --git a/src/steed.c b/src/steed.c index feede89c5..081cb475f 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 965c9347e..f70a90c7c 100644 --- a/src/trap.c +++ b/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*/