Port the autounlock feature, hallucinatory trap names from UnNetHack
This adds a boolean option, autounlock, defaulting to true. When this is set to TRUE, messages stating that some door or container is locked are automatically followed by a prompt asking if you would like to unlock it, if you are carrying an unlocking tool (key, lock pick, or credit card). Architecturally, this extends the pick_lock function to take three additional arguments (door coordinates or a box on the ground you are autounlocking). The code that selects an unlocking tool will always look first for a skeleton key, then a lock pick, then a credit card. Since curses, rust, and other attributes don't really have an effect on the viability of the unlocking device, it didn't seem to warrant making a more complex function for that. 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. reinstate anti-rng abuse bit on hallucination updates to hallucinatory trap names and fixes37.0 entry
This commit is contained in:
@@ -48,6 +48,7 @@ Platform- and/or Interface-Specific New Features
|
|||||||
|
|
||||||
NetHack Community Patches (or Variation) Included
|
NetHack Community Patches (or Variation) Included
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
hallucinatory trap names from github pull request #174
|
||||||
|
|
||||||
|
|
||||||
Code Cleanup and Reorganization
|
Code Cleanup and Reorganization
|
||||||
|
|||||||
+2
-6
@@ -149,25 +149,21 @@
|
|||||||
/*
|
/*
|
||||||
* random_monster()
|
* random_monster()
|
||||||
* random_object()
|
* 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_monster(rng) rng(NUMMONS)
|
||||||
#define random_object(rng) (rng(NUM_OBJECTS - 1) + 1)
|
#define random_object(rng) (rng(NUM_OBJECTS - 1) + 1)
|
||||||
#define random_trap(rng) (rng(TRAPNUM - 1) + 1)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* what_obj()
|
* what_obj()
|
||||||
* what_mon()
|
* what_mon()
|
||||||
* what_trap()
|
|
||||||
*
|
*
|
||||||
* If hallucinating, choose a random object/monster, otherwise, use the one
|
* If hallucinating, choose a random object/monster, otherwise, use the one
|
||||||
* given. Use the given rng to handle hallucination.
|
* given. Use the given rng to handle hallucination.
|
||||||
*/
|
*/
|
||||||
#define what_obj(obj, rng) (Hallucination ? random_object(rng) : obj)
|
#define what_obj(obj, rng) (Hallucination ? random_object(rng) : obj)
|
||||||
#define what_mon(mon, rng) (Hallucination ? random_monster(rng) : mon)
|
#define what_mon(mon, rng) (Hallucination ? random_monster(rng) : mon)
|
||||||
#define what_trap(trp, rng) (Hallucination ? random_trap(rng) : trp)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* newsym_rn2
|
* newsym_rn2
|
||||||
@@ -339,7 +335,7 @@
|
|||||||
((((expltype) * MAXEXPCHARS) + ((idx) - S_explode1)) + GLYPH_EXPLODE_OFF)
|
((((expltype) * MAXEXPCHARS) + ((idx) - S_explode1)) + GLYPH_EXPLODE_OFF)
|
||||||
|
|
||||||
#define trap_to_glyph(trap, rng) \
|
#define trap_to_glyph(trap, rng) \
|
||||||
cmap_to_glyph(trap_to_defsym(what_trap((trap)->ttyp, rng)))
|
cmap_to_glyph(trap_to_defsym((trap)->ttyp))
|
||||||
|
|
||||||
/* Not affected by hallucination. Gives a generic body for CORPSE */
|
/* Not affected by hallucination. Gives a generic body for CORPSE */
|
||||||
/* MRKR: ...and the generic statue */
|
/* MRKR: ...and the generic statue */
|
||||||
|
|||||||
+2
-1
@@ -1117,7 +1117,7 @@ E boolean FDECL(picking_at, (int, int));
|
|||||||
E void FDECL(breakchestlock, (struct obj *, BOOLEAN_P));
|
E void FDECL(breakchestlock, (struct obj *, BOOLEAN_P));
|
||||||
E void NDECL(reset_pick);
|
E void NDECL(reset_pick);
|
||||||
E void FDECL(maybe_reset_pick, (struct obj *));
|
E void FDECL(maybe_reset_pick, (struct obj *));
|
||||||
E int FDECL(pick_lock, (struct obj *));
|
E int FDECL(pick_lock, (struct obj *, xchar, xchar, struct obj *));
|
||||||
E int NDECL(doforce);
|
E int NDECL(doforce);
|
||||||
E boolean FDECL(boxlock, (struct obj *, struct obj *));
|
E boolean FDECL(boxlock, (struct obj *, struct obj *));
|
||||||
E boolean FDECL(doorlock, (struct obj *, int, int));
|
E boolean FDECL(doorlock, (struct obj *, int, int));
|
||||||
@@ -2653,6 +2653,7 @@ E boolean FDECL(uescaped_shaft, (struct trap *));
|
|||||||
E boolean NDECL(lava_effects);
|
E boolean NDECL(lava_effects);
|
||||||
E void NDECL(sink_into_lava);
|
E void NDECL(sink_into_lava);
|
||||||
E void NDECL(sokoban_guilt);
|
E void NDECL(sokoban_guilt);
|
||||||
|
E const char * FDECL(trapname, (int, BOOLEAN_P));
|
||||||
|
|
||||||
/* ### u_init.c ### */
|
/* ### u_init.c ### */
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ struct flag {
|
|||||||
boolean autodig; /* MRKR: Automatically dig */
|
boolean autodig; /* MRKR: Automatically dig */
|
||||||
boolean autoquiver; /* Automatically fill quiver */
|
boolean autoquiver; /* Automatically fill quiver */
|
||||||
boolean autoopen; /* open doors by walking into them */
|
boolean autoopen; /* open doors by walking into them */
|
||||||
|
boolean autounlock; /* automatically apply unlocking tools */
|
||||||
boolean beginner;
|
boolean beginner;
|
||||||
boolean biff; /* enable checking for mail */
|
boolean biff; /* enable checking for mail */
|
||||||
boolean bones; /* allow saving/loading bones */
|
boolean bones; /* allow saving/loading bones */
|
||||||
|
|||||||
+6
-11
@@ -2516,7 +2516,7 @@ struct obj *otmp;
|
|||||||
if (otmp == g.trapinfo.tobj && u.ux == g.trapinfo.tx
|
if (otmp == g.trapinfo.tobj && u.ux == g.trapinfo.tx
|
||||||
&& u.uy == g.trapinfo.ty) {
|
&& u.uy == g.trapinfo.ty) {
|
||||||
You("resume setting %s%s.", shk_your(buf, otmp),
|
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);
|
set_occupation(set_trap, occutext, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2541,8 +2541,7 @@ struct obj *otmp;
|
|||||||
chance = (rnl(10) > 5);
|
chance = (rnl(10) > 5);
|
||||||
You("aren't very skilled at reaching from %s.", mon_nam(u.usteed));
|
You("aren't very skilled at reaching from %s.", mon_nam(u.usteed));
|
||||||
Sprintf(buf, "Continue your attempt to set %s?",
|
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 (yn(buf) == 'y') {
|
||||||
if (chance) {
|
if (chance) {
|
||||||
switch (ttyp) {
|
switch (ttyp) {
|
||||||
@@ -2552,9 +2551,7 @@ struct obj *otmp;
|
|||||||
break;
|
break;
|
||||||
case BEAR_TRAP: /* drop it without arming it */
|
case BEAR_TRAP: /* drop it without arming it */
|
||||||
reset_trapset();
|
reset_trapset();
|
||||||
You("drop %s!",
|
You("drop %s!", the(trapname(ttyp, FALSE)));
|
||||||
the(defsyms[trap_to_defsym(what_trap(ttyp, rn2))]
|
|
||||||
.explanation));
|
|
||||||
dropx(otmp);
|
dropx(otmp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2564,8 +2561,7 @@ struct obj *otmp;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
You("begin setting %s%s.", shk_your(buf, otmp),
|
You("begin setting %s%s.", shk_your(buf, otmp), trapname(ttyp, FALSE));
|
||||||
defsyms[trap_to_defsym(what_trap(ttyp, rn2))].explanation);
|
|
||||||
set_occupation(set_trap, occutext, 0);
|
set_occupation(set_trap, occutext, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2596,8 +2592,7 @@ set_trap()
|
|||||||
add_damage(u.ux, u.uy, 0L); /* schedule removal */
|
add_damage(u.ux, u.uy, 0L); /* schedule removal */
|
||||||
}
|
}
|
||||||
if (!g.trapinfo.force_bungle)
|
if (!g.trapinfo.force_bungle)
|
||||||
You("finish arming %s.",
|
You("finish arming %s.", the(trapname(ttyp, FALSE)));
|
||||||
the(defsyms[trap_to_defsym(what_trap(ttyp, rn2))].explanation));
|
|
||||||
if (((otmp->cursed || Fumbling) && (rnl(10) > 5))
|
if (((otmp->cursed || Fumbling) && (rnl(10) > 5))
|
||||||
|| g.trapinfo.force_bungle)
|
|| g.trapinfo.force_bungle)
|
||||||
dotrap(ttmp,
|
dotrap(ttmp,
|
||||||
@@ -3609,7 +3604,7 @@ doapply()
|
|||||||
case LOCK_PICK:
|
case LOCK_PICK:
|
||||||
case CREDIT_CARD:
|
case CREDIT_CARD:
|
||||||
case SKELETON_KEY:
|
case SKELETON_KEY:
|
||||||
res = (pick_lock(obj) != 0);
|
res = (pick_lock(obj, 0, 0, NULL) != 0);
|
||||||
break;
|
break;
|
||||||
case PICK_AXE:
|
case PICK_AXE:
|
||||||
case DWARVISH_MATTOCK:
|
case DWARVISH_MATTOCK:
|
||||||
|
|||||||
@@ -2513,7 +2513,7 @@ int final;
|
|||||||
Strcpy(predicament, "trapped");
|
Strcpy(predicament, "trapped");
|
||||||
if ((t = t_at(u.ux, u.uy)) != 0)
|
if ((t = t_at(u.ux, u.uy)) != 0)
|
||||||
Sprintf(eos(predicament), " in %s",
|
Sprintf(eos(predicament), " in %s",
|
||||||
an(defsyms[trap_to_defsym(t->ttyp)].explanation));
|
an(trapname(t->ttyp, FALSE)));
|
||||||
}
|
}
|
||||||
if (u.usteed) { /* not `Riding' here */
|
if (u.usteed) { /* not `Riding' here */
|
||||||
Sprintf(buf, "%s%s ", anchored ? "you and " : "", steedname);
|
Sprintf(buf, "%s%s ", anchored ? "you and " : "", steedname);
|
||||||
|
|||||||
+3
-5
@@ -1612,7 +1612,6 @@ void
|
|||||||
find_trap(trap)
|
find_trap(trap)
|
||||||
struct trap *trap;
|
struct trap *trap;
|
||||||
{
|
{
|
||||||
int tt = what_trap(trap->ttyp, rn2);
|
|
||||||
boolean cleared = FALSE;
|
boolean cleared = FALSE;
|
||||||
|
|
||||||
trap->tseen = 1;
|
trap->tseen = 1;
|
||||||
@@ -1623,8 +1622,7 @@ struct trap *trap;
|
|||||||
behaviour might need a rework in the hallucination case
|
behaviour might need a rework in the hallucination case
|
||||||
(e.g. to not prompt if any trap glyph appears on the square). */
|
(e.g. to not prompt if any trap glyph appears on the square). */
|
||||||
if (Hallucination ||
|
if (Hallucination ||
|
||||||
levl[trap->tx][trap->ty].glyph !=
|
levl[trap->tx][trap->ty].glyph != trap_to_glyph(trap)) {
|
||||||
trap_to_glyph(trap, rn2_on_display_rng)) {
|
|
||||||
/* There's too much clutter to see your find otherwise */
|
/* There's too much clutter to see your find otherwise */
|
||||||
cls();
|
cls();
|
||||||
map_trap(trap, 1);
|
map_trap(trap, 1);
|
||||||
@@ -1632,7 +1630,7 @@ struct trap *trap;
|
|||||||
cleared = TRUE;
|
cleared = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
You("find %s.", an(defsyms[trap_to_defsym(tt)].explanation));
|
You("find %s.", an(trapname(trap->ttyp, FALSE)));
|
||||||
|
|
||||||
if (cleared) {
|
if (cleared) {
|
||||||
display_nhwindow(WIN_MAP, TRUE); /* wait */
|
display_nhwindow(WIN_MAP, TRUE); /* wait */
|
||||||
@@ -1871,7 +1869,7 @@ int default_glyph, which_subset;
|
|||||||
|| glyph_is_invisible(glyph))
|
|| glyph_is_invisible(glyph))
|
||||||
&& keep_traps && !covers_traps(x, y)) {
|
&& keep_traps && !covers_traps(x, y)) {
|
||||||
if ((t = t_at(x, y)) != 0 && t->tseen)
|
if ((t = t_at(x, y)) != 0 && t->tseen)
|
||||||
glyph = trap_to_glyph(t, rn2_on_display_rng);
|
glyph = trap_to_glyph(t);
|
||||||
}
|
}
|
||||||
if ((glyph_is_object(glyph) && !keep_objs)
|
if ((glyph_is_object(glyph) && !keep_objs)
|
||||||
|| (glyph_is_trap(glyph) && !keep_traps)
|
|| (glyph_is_trap(glyph) && !keep_traps)
|
||||||
|
|||||||
@@ -579,7 +579,7 @@ int ttyp;
|
|||||||
|
|
||||||
if (ttyp != PIT && (!Can_dig_down(&u.uz) && !lev->candig)) {
|
if (ttyp != PIT && (!Can_dig_down(&u.uz) && !lev->candig)) {
|
||||||
impossible("digactualhole: can't dig %s on this level.",
|
impossible("digactualhole: can't dig %s on this level.",
|
||||||
defsyms[trap_to_defsym(ttyp)].explanation);
|
trapname(ttyp, TRUE));
|
||||||
ttyp = PIT;
|
ttyp = PIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -229,7 +229,7 @@ register struct trap *trap;
|
|||||||
register int show;
|
register int show;
|
||||||
{
|
{
|
||||||
register int x = trap->tx, y = trap->ty;
|
register int x = trap->tx, y = trap->ty;
|
||||||
register int glyph = trap_to_glyph(trap, newsym_rn2);
|
register int glyph = trap_to_glyph(trap);
|
||||||
|
|
||||||
if (g.level.flags.hero_memory)
|
if (g.level.flags.hero_memory)
|
||||||
levl[x][y].glyph = glyph;
|
levl[x][y].glyph = glyph;
|
||||||
|
|||||||
+1
-2
@@ -756,8 +756,7 @@ int x, y;
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
} else {
|
} else {
|
||||||
if (ttmp->tseen)
|
if (ttmp->tseen)
|
||||||
You("pass right over %s.",
|
You("pass right over %s.", an(trapname(ttmp->ttyp, FALSE)));
|
||||||
an(defsyms[trap_to_defsym(ttmp->ttyp)].explanation));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (--*range < 0) /* make sure our range never goes negative */
|
if (--*range < 0) /* make sure our range never goes negative */
|
||||||
|
|||||||
+2
-5
@@ -1499,10 +1499,8 @@ domove_core()
|
|||||||
if (g.context.run >= 2) {
|
if (g.context.run >= 2) {
|
||||||
if (iflags.mention_walls) {
|
if (iflags.mention_walls) {
|
||||||
if (trap && trap->tseen) {
|
if (trap && trap->tseen) {
|
||||||
int tt = what_trap(trap->ttyp, rn2_on_display_rng);
|
|
||||||
|
|
||||||
You("stop in front of %s.",
|
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) {
|
} else if (is_pool_or_lava(x,y) && levl[x][y].seenv) {
|
||||||
You("stop at the edge of the %s.",
|
You("stop at the edge of the %s.",
|
||||||
hliquid(is_pool(x,y) ? "water" : "lava"));
|
hliquid(is_pool(x,y) ? "water" : "lava"));
|
||||||
@@ -2758,10 +2756,9 @@ lookaround()
|
|||||||
goto bcorr; /* if you must */
|
goto bcorr; /* if you must */
|
||||||
if (x == u.ux + u.dx && y == u.uy + u.dy) {
|
if (x == u.ux + u.dx && y == u.uy + u.dy) {
|
||||||
if (iflags.mention_walls) {
|
if (iflags.mention_walls) {
|
||||||
int tt = what_trap(trap->ttyp, rn2_on_display_rng);
|
|
||||||
|
|
||||||
You("stop in front of %s.",
|
You("stop in front of %s.",
|
||||||
an(defsyms[trap_to_defsym(tt)].explanation));
|
an(trapname(trap->ttyp, FALSE)));
|
||||||
}
|
}
|
||||||
goto stop;
|
goto stop;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -3422,8 +3422,7 @@ boolean picked_some;
|
|||||||
return !!Blind;
|
return !!Blind;
|
||||||
}
|
}
|
||||||
if (!skip_objects && (trap = t_at(u.ux, u.uy)) && trap->tseen)
|
if (!skip_objects && (trap = t_at(u.ux, u.uy)) && trap->tseen)
|
||||||
There("is %s here.",
|
There("is %s here.", an(trapname(trap->ttyp, FALSE)));
|
||||||
an(defsyms[trap_to_defsym(trap->ttyp)].explanation));
|
|
||||||
|
|
||||||
otmp = g.level.objects[u.ux][u.uy];
|
otmp = g.level.objects[u.ux][u.uy];
|
||||||
dfeature = dfeature_at(u.ux, u.uy, fbuf2);
|
dfeature = dfeature_at(u.ux, u.uy, fbuf2);
|
||||||
|
|||||||
+44
-15
@@ -294,14 +294,18 @@ struct obj *container; /* passed from obfree() */
|
|||||||
|
|
||||||
/* player is applying a key, lock pick, or credit card */
|
/* player is applying a key, lock pick, or credit card */
|
||||||
int
|
int
|
||||||
pick_lock(pick)
|
pick_lock(pick, rx, ry, container)
|
||||||
struct obj *pick;
|
struct obj *pick;
|
||||||
|
xchar rx, ry; /* coordinates of doors/container, for autounlock: does not
|
||||||
|
prompt for direction if these are set */
|
||||||
|
struct obj *container; /* container, for autounlock */
|
||||||
{
|
{
|
||||||
int picktyp, c, ch;
|
int picktyp, c, ch;
|
||||||
coord cc;
|
coord cc;
|
||||||
struct rm *door;
|
struct rm *door;
|
||||||
struct obj *otmp;
|
struct obj *otmp;
|
||||||
char qbuf[QBUFSZ];
|
char qbuf[QBUFSZ];
|
||||||
|
boolean autounlock = (rx != 0 && ry != 0) || (container != NULL);
|
||||||
|
|
||||||
picktyp = pick->otyp;
|
picktyp = pick->otyp;
|
||||||
|
|
||||||
@@ -348,8 +352,13 @@ struct obj *pick;
|
|||||||
}
|
}
|
||||||
ch = 0; /* lint suppression */
|
ch = 0; /* lint suppression */
|
||||||
|
|
||||||
if (!get_adjacent_loc((char *) 0, "Invalid location!", u.ux, u.uy, &cc))
|
if (rx != 0 && ry != 0) { /* autounlock; caller has provided coordinates */
|
||||||
|
cc.x = rx;
|
||||||
|
cc.y = ry;
|
||||||
|
}
|
||||||
|
else if (!get_adjacent_loc((char *) 0, "Invalid location!", u.ux, u.uy, &cc)) {
|
||||||
return PICKLOCK_DID_NOTHING;
|
return PICKLOCK_DID_NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
if (cc.x == u.ux && cc.y == u.uy) { /* pick lock on a container */
|
if (cc.x == u.ux && cc.y == u.uy) { /* pick lock on a container */
|
||||||
const char *verb;
|
const char *verb;
|
||||||
@@ -372,7 +381,9 @@ struct obj *pick;
|
|||||||
count = 0;
|
count = 0;
|
||||||
c = 'n'; /* in case there are no boxes here */
|
c = 'n'; /* in case there are no boxes here */
|
||||||
for (otmp = g.level.objects[cc.x][cc.y]; otmp; otmp = otmp->nexthere)
|
for (otmp = g.level.objects[cc.x][cc.y]; otmp; otmp = otmp->nexthere)
|
||||||
if (Is_box(otmp)) {
|
/* autounlock on boxes: only the one that just informed you it was
|
||||||
|
* locked. Don't include any other boxes which might be here. */
|
||||||
|
if ((!autounlock && Is_box(otmp)) || (otmp == container)) {
|
||||||
++count;
|
++count;
|
||||||
if (!can_reach_floor(TRUE)) {
|
if (!can_reach_floor(TRUE)) {
|
||||||
You_cant("reach %s from up here.", the(xname(otmp)));
|
You_cant("reach %s from up here.", the(xname(otmp)));
|
||||||
@@ -388,17 +399,24 @@ struct obj *pick;
|
|||||||
else
|
else
|
||||||
verb = "pick";
|
verb = "pick";
|
||||||
|
|
||||||
/* "There is <a box> here; <verb> <it|its lock>?" */
|
if (autounlock) {
|
||||||
Sprintf(qsfx, " here; %s %s?", verb, it ? "it" : "its lock");
|
Sprintf(qbuf, "Unlock it with %s?", yname(pick));
|
||||||
(void) safe_qbuf(qbuf, "There is ", qsfx, otmp, doname,
|
c = yn(qbuf);
|
||||||
ansimpleoname, "a box");
|
if (c == 'n')
|
||||||
otmp->lknown = 1;
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* "There is <a box> here; <verb> <it|its lock>?" */
|
||||||
|
Sprintf(qsfx, " here; %s %s?", verb, it ? "it" : "its lock");
|
||||||
|
(void) safe_qbuf(qbuf, "There is ", qsfx, otmp, doname,
|
||||||
|
ansimpleoname, "a box");
|
||||||
|
otmp->lknown = 1;
|
||||||
|
|
||||||
c = ynq(qbuf);
|
c = ynq(qbuf);
|
||||||
if (c == 'q')
|
if (c == 'q')
|
||||||
return 0;
|
return 0;
|
||||||
if (c == 'n')
|
if (c == 'n')
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (otmp->obroken) {
|
if (otmp->obroken) {
|
||||||
You_cant("fix its broken lock with %s.", doname(pick));
|
You_cant("fix its broken lock with %s.", doname(pick));
|
||||||
@@ -484,8 +502,10 @@ struct obj *pick;
|
|||||||
return PICKLOCK_LEARNED_SOMETHING;
|
return PICKLOCK_LEARNED_SOMETHING;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sprintf(qbuf, "%s it?",
|
Sprintf(qbuf, "%s it%s%s?",
|
||||||
(door->doormask & D_LOCKED) ? "Unlock" : "Lock");
|
(door->doormask & D_LOCKED) ? "Unlock" : "Lock",
|
||||||
|
autounlock ? " with " : "",
|
||||||
|
autounlock ? yname(pick) : "");
|
||||||
|
|
||||||
c = yn(qbuf);
|
c = yn(qbuf);
|
||||||
if (c == 'n')
|
if (c == 'n')
|
||||||
@@ -685,6 +705,8 @@ int x, y;
|
|||||||
|
|
||||||
if (!(door->doormask & D_CLOSED)) {
|
if (!(door->doormask & D_CLOSED)) {
|
||||||
const char *mesg;
|
const char *mesg;
|
||||||
|
boolean locked = FALSE;
|
||||||
|
struct obj* unlocktool;
|
||||||
|
|
||||||
switch (door->doormask) {
|
switch (door->doormask) {
|
||||||
case D_BROKEN:
|
case D_BROKEN:
|
||||||
@@ -698,9 +720,16 @@ int x, y;
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mesg = " is locked";
|
mesg = " is locked";
|
||||||
|
locked = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pline("This door%s.", mesg);
|
pline("This door%s.", mesg);
|
||||||
|
if (locked && flags.autounlock &&
|
||||||
|
((unlocktool = carrying(SKELETON_KEY)) ||
|
||||||
|
(unlocktool = carrying(LOCK_PICK)) ||
|
||||||
|
(unlocktool = carrying(CREDIT_CARD)))) {
|
||||||
|
pick_lock(unlocktool, cc.x, cc.y, (struct obj *) 0);
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-5
@@ -3484,10 +3484,8 @@ struct obj *no_wish;
|
|||||||
goto typfnd;
|
goto typfnd;
|
||||||
} else if (trapped == 1 || *zp != '\0') {
|
} else if (trapped == 1 || *zp != '\0') {
|
||||||
/* "trapped <foo>" or "<foo> trap" (actually "<foo>*") */
|
/* "trapped <foo>" or "<foo> trap" (actually "<foo>*") */
|
||||||
int idx = trap_to_defsym(beartrap ? BEAR_TRAP : LANDMINE);
|
|
||||||
|
|
||||||
/* use canonical trap spelling, skip object matching */
|
/* use canonical trap spelling, skip object matching */
|
||||||
Strcpy(bp, defsyms[idx].explanation);
|
Strcpy(bp, trapname(beartrap ? BEAR_TRAP : LANDMINE, TRUE));
|
||||||
goto wiztrap;
|
goto wiztrap;
|
||||||
}
|
}
|
||||||
/* [no prefix or suffix; we're going to end up matching
|
/* [no prefix or suffix; we're going to end up matching
|
||||||
@@ -3692,7 +3690,7 @@ struct obj *no_wish;
|
|||||||
struct trap *t;
|
struct trap *t;
|
||||||
const char *tname;
|
const char *tname;
|
||||||
|
|
||||||
tname = defsyms[trap_to_defsym(trap)].explanation;
|
tname = trapname(trap, TRUE);
|
||||||
if (strncmpi(tname, bp, strlen(tname)))
|
if (strncmpi(tname, bp, strlen(tname)))
|
||||||
continue;
|
continue;
|
||||||
/* found it; avoid stupid mistakes */
|
/* found it; avoid stupid mistakes */
|
||||||
@@ -3700,7 +3698,7 @@ struct obj *no_wish;
|
|||||||
trap = ROCKTRAP;
|
trap = ROCKTRAP;
|
||||||
if ((t = maketrap(x, y, trap)) != 0) {
|
if ((t = maketrap(x, y, trap)) != 0) {
|
||||||
trap = t->ttyp;
|
trap = t->ttyp;
|
||||||
tname = defsyms[trap_to_defsym(trap)].explanation;
|
tname = trapname(trap, TRUE);
|
||||||
pline("%s%s.", An(tname),
|
pline("%s%s.", An(tname),
|
||||||
(trap != MAGIC_PORTAL) ? "" : " to nowhere");
|
(trap != MAGIC_PORTAL) ? "" : " to nowhere");
|
||||||
} else
|
} else
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ static const struct Bool_Opt {
|
|||||||
{ "autoopen", &flags.autoopen, TRUE, SET_IN_GAME },
|
{ "autoopen", &flags.autoopen, TRUE, SET_IN_GAME },
|
||||||
{ "autopickup", &flags.pickup, TRUE, SET_IN_GAME },
|
{ "autopickup", &flags.pickup, TRUE, SET_IN_GAME },
|
||||||
{ "autoquiver", &flags.autoquiver, FALSE, SET_IN_GAME },
|
{ "autoquiver", &flags.autoquiver, FALSE, SET_IN_GAME },
|
||||||
|
{ "autounlock", &flags.autounlock, TRUE, SET_IN_GAME },
|
||||||
#if defined(MICRO) && !defined(AMIGA)
|
#if defined(MICRO) && !defined(AMIGA)
|
||||||
{ "BIOS", &iflags.BIOS, FALSE, SET_IN_FILE },
|
{ "BIOS", &iflags.BIOS, FALSE, SET_IN_FILE },
|
||||||
#else
|
#else
|
||||||
|
|||||||
+4
-6
@@ -305,8 +305,7 @@ int x, y;
|
|||||||
|
|
||||||
/* newsym lets you know of the trap, so mention it here */
|
/* newsym lets you know of the trap, so mention it here */
|
||||||
if (tt == BEAR_TRAP || is_pit(tt) || tt == WEB) {
|
if (tt == BEAR_TRAP || is_pit(tt) || tt == WEB) {
|
||||||
Sprintf(eos(buf), ", trapped in %s",
|
Sprintf(eos(buf), ", trapped in %s", an(trapname(tt, FALSE)));
|
||||||
an(defsyms[trap_to_defsym(tt)].explanation));
|
|
||||||
t->tseen = 1;
|
t->tseen = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -458,7 +457,7 @@ char *buf, *monbuf;
|
|||||||
} else if (glyph_is_object(glyph)) {
|
} else if (glyph_is_object(glyph)) {
|
||||||
look_at_object(buf, x, y, glyph); /* fill in buf[] */
|
look_at_object(buf, x, y, glyph); /* fill in buf[] */
|
||||||
} else if (glyph_is_trap(glyph)) {
|
} 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
|
/* Trap detection displays a bear trap at locations having
|
||||||
* a trapped door or trapped container or both.
|
* a trapped door or trapped container or both.
|
||||||
@@ -470,7 +469,7 @@ char *buf, *monbuf;
|
|||||||
else if (trapped_door_at(tnum, x, y))
|
else if (trapped_door_at(tnum, x, y))
|
||||||
Strcpy(buf, "trapped door"); /* not "trap door"... */
|
Strcpy(buf, "trapped door"); /* not "trap door"... */
|
||||||
else
|
else
|
||||||
Strcpy(buf, defsyms[trap_to_defsym(tnum)].explanation);
|
Strcpy(buf, trapname(tnum, FALSE));
|
||||||
} else if (glyph_is_warning(glyph)) {
|
} else if (glyph_is_warning(glyph)) {
|
||||||
int warnindx = glyph_to_warning(glyph);
|
int warnindx = glyph_to_warning(glyph);
|
||||||
|
|
||||||
@@ -1570,9 +1569,8 @@ doidtrap()
|
|||||||
if (u.dz < 0 ? is_hole(tt) : tt == ROCKTRAP)
|
if (u.dz < 0 ? is_hole(tt) : tt == ROCKTRAP)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tt = what_trap(tt, rn2_on_display_rng);
|
|
||||||
pline("That is %s%s%s.",
|
pline("That is %s%s%s.",
|
||||||
an(defsyms[trap_to_defsym(tt)].explanation),
|
an(trapname(tt, FALSE)),
|
||||||
!trap->madeby_u
|
!trap->madeby_u
|
||||||
? ""
|
? ""
|
||||||
: (tt == WEB)
|
: (tt == WEB)
|
||||||
|
|||||||
@@ -1714,6 +1714,7 @@ int cindex, ccount; /* index of this container (1..N), number of them (N) */
|
|||||||
if (!cobj)
|
if (!cobj)
|
||||||
return 0;
|
return 0;
|
||||||
if (cobj->olocked) {
|
if (cobj->olocked) {
|
||||||
|
struct obj *unlocktool;
|
||||||
if (ccount < 2)
|
if (ccount < 2)
|
||||||
pline("%s locked.",
|
pline("%s locked.",
|
||||||
cobj->lknown ? "It is" : "Hmmm, it turns out to be");
|
cobj->lknown ? "It is" : "Hmmm, it turns out to be");
|
||||||
@@ -1722,6 +1723,14 @@ int cindex, ccount; /* index of this container (1..N), number of them (N) */
|
|||||||
else
|
else
|
||||||
pline("Hmmm, %s turns out to be locked.", the(xname(cobj)));
|
pline("Hmmm, %s turns out to be locked.", the(xname(cobj)));
|
||||||
cobj->lknown = 1;
|
cobj->lknown = 1;
|
||||||
|
|
||||||
|
if (flags.autounlock &&
|
||||||
|
((unlocktool = carrying(SKELETON_KEY)) ||
|
||||||
|
(unlocktool = carrying(LOCK_PICK)) ||
|
||||||
|
(unlocktool = carrying(CREDIT_CARD)))) {
|
||||||
|
/* pass ox and oy to avoid direction prompt */
|
||||||
|
pick_lock(unlocktool, cobj->ox, cobj->oy, cobj);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
cobj->lknown = 1; /* floor container, so no need for update_inventory() */
|
cobj->lknown = 1; /* floor container, so no need for update_inventory() */
|
||||||
|
|||||||
+1
-1
@@ -285,7 +285,7 @@ boolean force; /* Quietly force this animal */
|
|||||||
struct trap *t = t_at(mtmp->mx, mtmp->my);
|
struct trap *t = t_at(mtmp->mx, mtmp->my);
|
||||||
|
|
||||||
You_cant("mount %s while %s's trapped in %s.", mon_nam(mtmp),
|
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);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+61
-12
@@ -923,14 +923,14 @@ unsigned trflags;
|
|||||||
*/
|
*/
|
||||||
pline("Air currents pull you down into %s %s!",
|
pline("Air currents pull you down into %s %s!",
|
||||||
a_your[trap->madeby_u],
|
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 */
|
/* then proceed to normal trap effect */
|
||||||
} else if (already_seen && !forcetrap) {
|
} else if (already_seen && !forcetrap) {
|
||||||
if ((Levitation || (Flying && !plunged))
|
if ((Levitation || (Flying && !plunged))
|
||||||
&& (is_pit(ttype) || ttype == HOLE || ttype == BEAR_TRAP)) {
|
&& (is_pit(ttype) || ttype == HOLE || ttype == BEAR_TRAP)) {
|
||||||
You("%s over %s %s.", Levitation ? "float" : "fly",
|
You("%s over %s %s.", Levitation ? "float" : "fly",
|
||||||
a_your[trap->madeby_u],
|
a_your[trap->madeby_u],
|
||||||
defsyms[trap_to_defsym(ttype)].explanation);
|
trapname(ttype, FALSE));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Fumbling && ttype != MAGIC_PORTAL && ttype != VIBRATING_SQUARE
|
if (!Fumbling && ttype != MAGIC_PORTAL && ttype != VIBRATING_SQUARE
|
||||||
@@ -941,7 +941,7 @@ unsigned trflags;
|
|||||||
You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u)
|
You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u)
|
||||||
? "an"
|
? "an"
|
||||||
: a_your[trap->madeby_u],
|
: a_your[trap->madeby_u],
|
||||||
defsyms[trap_to_defsym(ttype)].explanation);
|
trapname(ttype, FALSE));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1290,7 +1290,7 @@ unsigned trflags;
|
|||||||
if (!Can_fall_thru(&u.uz)) {
|
if (!Can_fall_thru(&u.uz)) {
|
||||||
seetrap(trap); /* normally done in fall_through */
|
seetrap(trap); /* normally done in fall_through */
|
||||||
impossible("dotrap: %ss cannot exist on this level.",
|
impossible("dotrap: %ss cannot exist on this level.",
|
||||||
defsyms[trap_to_defsym(ttype)].explanation);
|
trapname(ttype, TRUE));
|
||||||
break; /* don't activate it after all */
|
break; /* don't activate it after all */
|
||||||
}
|
}
|
||||||
fall_through(TRUE, (trflags & TOOKPLUNGE));
|
fall_through(TRUE, (trflags & TOOKPLUNGE));
|
||||||
@@ -2465,7 +2465,7 @@ register struct monst *mtmp;
|
|||||||
case TRAPDOOR:
|
case TRAPDOOR:
|
||||||
if (!Can_fall_thru(&u.uz)) {
|
if (!Can_fall_thru(&u.uz)) {
|
||||||
impossible("mintrap: %ss cannot exist on this level.",
|
impossible("mintrap: %ss cannot exist on this level.",
|
||||||
defsyms[trap_to_defsym(tt)].explanation);
|
trapname(tt, TRUE));
|
||||||
break; /* don't activate it after all */
|
break; /* don't activate it after all */
|
||||||
}
|
}
|
||||||
if (is_flyer(mptr) || is_floater(mptr) || mptr == &mons[PM_WUMPUS]
|
if (is_flyer(mptr) || is_floater(mptr) || mptr == &mons[PM_WUMPUS]
|
||||||
@@ -4051,8 +4051,7 @@ boolean force_failure;
|
|||||||
if ((g.invent && (inv_weight() + weight_cap() > 600))
|
if ((g.invent && (inv_weight() + weight_cap() > 600))
|
||||||
|| bigmonst(g.youmonst.data)) {
|
|| bigmonst(g.youmonst.data)) {
|
||||||
/* don't allow untrap if they can't get thru to it */
|
/* don't allow untrap if they can't get thru to it */
|
||||||
You("are unable to reach the %s!",
|
You("are unable to reach the %s!", trapname(ttype, FALSE));
|
||||||
defsyms[trap_to_defsym(ttype)].explanation);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4061,8 +4060,7 @@ boolean force_failure;
|
|||||||
if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
|
if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
|
||||||
rider_cant_reach();
|
rider_cant_reach();
|
||||||
else
|
else
|
||||||
You("are unable to reach the %s!",
|
You("are unable to reach the %s!", trapname(ttype, FALSE));
|
||||||
defsyms[trap_to_defsym(ttype)].explanation);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4102,7 +4100,7 @@ boolean force_failure;
|
|||||||
} else {
|
} else {
|
||||||
pline("%s %s is difficult to %s.",
|
pline("%s %s is difficult to %s.",
|
||||||
ttmp->madeby_u ? "Your" : under_u ? "This" : "That",
|
ttmp->madeby_u ? "Your" : under_u ? "This" : "That",
|
||||||
defsyms[trap_to_defsym(ttype)].explanation,
|
trapname(ttype, FALSE),
|
||||||
(ttype == WEB) ? "remove" : "disarm");
|
(ttype == WEB) ? "remove" : "disarm");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@@ -4381,7 +4379,7 @@ boolean force;
|
|||||||
ttmp = t_at(x, y);
|
ttmp = t_at(x, y);
|
||||||
if (ttmp && !ttmp->tseen)
|
if (ttmp && !ttmp->tseen)
|
||||||
ttmp = 0;
|
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 */
|
here = (x == u.ux && y == u.uy); /* !u.dx && !u.dy */
|
||||||
|
|
||||||
if (here) /* are there are one or more containers here? */
|
if (here) /* are there are one or more containers here? */
|
||||||
@@ -4641,7 +4639,7 @@ boolean *noticed; /* set to true iff hero notices the effect; */
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!trapdescr)
|
if (!trapdescr)
|
||||||
trapdescr = defsyms[trap_to_defsym(t->ttyp)].explanation;
|
trapdescr = trapname(t->ttyp, FALSE);
|
||||||
if (!which)
|
if (!which)
|
||||||
which = t->tseen ? the_your[t->madeby_u]
|
which = t->tseen ? the_your[t->madeby_u]
|
||||||
: index(vowels, *trapdescr) ? "an" : "a";
|
: index(vowels, *trapdescr) ? "an" : "a";
|
||||||
@@ -5452,4 +5450,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_on_display_rng(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*/
|
/*trap.c*/
|
||||||
|
|||||||
Reference in New Issue
Block a user