Merge branch 'NetHack-3.6.2-beta01' into NetHack-3.6.2

This commit is contained in:
nhmall
2018-10-06 12:53:41 -04:00
42 changed files with 489 additions and 288 deletions
+2 -1
View File
@@ -2601,7 +2601,8 @@ exclude that alignment from being picked randomly.
Cannot be set with the `O' command. Persistent. Cannot be set with the `O' command. Persistent.
.lp autodescribe .lp autodescribe
Automatically describe the terrain under cursor when asked to get a location Automatically describe the terrain under cursor when asked to get a location
on the map. The on the map (default true).
The
.op whatis_coord .op whatis_coord
option controls whether the description includes map coordinates. option controls whether the description includes map coordinates.
.lp autodig .lp autodig
+2 -2
View File
@@ -3038,8 +3038,8 @@ Cannot be set with the `{\tt O}' command. Persistent.
%.lp %.lp
\item[\ib{autodescribe}] \item[\ib{autodescribe}]
Automatically describe the terrain under cursor when asked to get a location Automatically describe the terrain under cursor when asked to get a location
on the map. The on the map (default true).
{\it whatis\verb+_+coord\/} The {\it whatis\verb+_+coord\/}
option controls whether the description includes map coordinates. option controls whether the description includes map coordinates.
%.lp %.lp
\item[\ib{autodig}] \item[\ib{autodig}]
+7
View File
@@ -152,6 +152,12 @@ fix missing space in "would flyif you weren't levitating"
a wand of polymorph lost its magical ability for the turn just because the a wand of polymorph lost its magical ability for the turn just because the
player using it to engrave happened to be blind, which didn't make player using it to engrave happened to be blind, which didn't make
a much sense a much sense
floating eye is classified as a flyer but flying is blocked while levitating,
so don't set intrinsic flying if hero is polymorphed into one
being trapped (bear trap, web, molten or solidified lava, chained to buried
iron ball) blocks both levitation and flight (note: being stuck in a
pit ends when either of those starts so doesn't apply)
change default value for the 'autodescribe' option to 'on'
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
@@ -163,6 +169,7 @@ sortloot segfaulted when filtering a subset of items (seen with 'A' command)
orctown: prevent Bad fruit #0 and some minor tuning orctown: prevent Bad fruit #0 and some minor tuning
make long extended commands list be more navigable make long extended commands list be more navigable
simplify #wizidentify; don't rely on having bold menu entries simplify #wizidentify; don't rely on having bold menu entries
ensure tmp_at() structures are initialized for all code paths when swallowed
tty: turn off an optimization that is the suspected cause of Windows reported tty: turn off an optimization that is the suspected cause of Windows reported
partial status lines following level changes partial status lines following level changes
tty: ensure that current status fields are always copied to prior status tty: ensure that current status fields are always copied to prior status
+2
View File
@@ -2438,6 +2438,8 @@ E struct monst *FDECL(animate_statue,
(struct obj *, XCHAR_P, XCHAR_P, int, int *)); (struct obj *, XCHAR_P, XCHAR_P, int, int *));
E struct monst *FDECL(activate_statue_trap, E struct monst *FDECL(activate_statue_trap,
(struct trap *, XCHAR_P, XCHAR_P, BOOLEAN_P)); (struct trap *, XCHAR_P, XCHAR_P, BOOLEAN_P));
E void FDECL(set_utrap, (unsigned, unsigned));
E void FDECL(reset_utrap, (BOOLEAN_P));
E void FDECL(dotrap, (struct trap *, unsigned)); E void FDECL(dotrap, (struct trap *, unsigned));
E void FDECL(seetrap, (struct trap *)); E void FDECL(seetrap, (struct trap *));
E void FDECL(feeltrap, (struct trap *)); E void FDECL(feeltrap, (struct trap *));
+1
View File
@@ -333,6 +333,7 @@ typedef struct sortloot_item Loot;
#define RECURSIVETRAP 0x08 /* trap changed into another type this same turn */ #define RECURSIVETRAP 0x08 /* trap changed into another type this same turn */
#define TOOKPLUNGE 0x10 /* used '>' to enter pit below you */ #define TOOKPLUNGE 0x10 /* used '>' to enter pit below you */
#define VIASITTING 0x20 /* #sit while at trap location (affects message) */ #define VIASITTING 0x20 /* #sit while at trap location (affects message) */
#define FAILEDUNTRAP 0x40 /* trap activated by failed untrap attempt */
/* Flags to control test_move in hack.c */ /* Flags to control test_move in hack.c */
#define DO_MOVE 0 /* really doing the move */ #define DO_MOVE 0 /* really doing the move */
+7
View File
@@ -209,8 +209,12 @@
#define ETeleport_control u.uprops[TELEPORT_CONTROL].extrinsic #define ETeleport_control u.uprops[TELEPORT_CONTROL].extrinsic
#define Teleport_control (HTeleport_control || ETeleport_control) #define Teleport_control (HTeleport_control || ETeleport_control)
/* HLevitation has I_SPECIAL set if levitating due to blessed potion
which allows player to use the '>' command to end levitation early */
#define HLevitation u.uprops[LEVITATION].intrinsic #define HLevitation u.uprops[LEVITATION].intrinsic
#define ELevitation u.uprops[LEVITATION].extrinsic #define ELevitation u.uprops[LEVITATION].extrinsic
/* BLevitation has I_SPECIAL set if trapped in the floor,
FROMOUTSIDE set if inside solid rock (or in water on Plane of Water) */
#define BLevitation u.uprops[LEVITATION].blocked #define BLevitation u.uprops[LEVITATION].blocked
#define Levitation ((HLevitation || ELevitation) && !BLevitation) #define Levitation ((HLevitation || ELevitation) && !BLevitation)
/* Can't touch surface, can't go under water; overrides all others */ /* Can't touch surface, can't go under water; overrides all others */
@@ -219,8 +223,11 @@
&& (HLevitation & ~(I_SPECIAL | TIMEOUT)) == 0L \ && (HLevitation & ~(I_SPECIAL | TIMEOUT)) == 0L \
&& (ELevitation & ~W_ARTI) == 0L) && (ELevitation & ~W_ARTI) == 0L)
/* Flying is overridden by Levitation */
#define HFlying u.uprops[FLYING].intrinsic #define HFlying u.uprops[FLYING].intrinsic
#define EFlying u.uprops[FLYING].extrinsic #define EFlying u.uprops[FLYING].extrinsic
/* BFlying has I_SPECIAL set if levitating or trapped in the floor or both,
FROMOUTSIDE set if inside solid rock (or in water on Plane of Water) */
#define BFlying u.uprops[FLYING].blocked #define BFlying u.uprops[FLYING].blocked
#define Flying \ #define Flying \
((HFlying || EFlying || (u.usteed && is_flyer(u.usteed->data))) \ ((HFlying || EFlying || (u.usteed && is_flyer(u.usteed->data))) \
+28 -30
View File
@@ -793,44 +793,42 @@ enum earlyarg e_arg;
userea = &argv[i][1]; userea = &argv[i][1];
} }
match = match_optname(userea, earlyopts[idx].name, match = match_optname(userea, earlyopts[idx].name,
earlyopts[idx].minlength, earlyopts[idx].valallowed); earlyopts[idx].minlength,
earlyopts[idx].valallowed);
if (match) break; if (match) break;
} }
if (match) { if (match) {
const char *extended_opt = index(userea,':'); const char *extended_opt = index(userea, ':');
if (!extended_opt) if (!extended_opt)
extended_opt = index(userea, '='); extended_opt = index(userea, '=');
switch(e_arg) { switch(e_arg) {
case ARG_DEBUG: case ARG_DEBUG:
if (extended_opt) { if (extended_opt) {
extended_opt++; extended_opt++;
debug_fields(extended_opt); debug_fields(extended_opt);
}
return 1;
break;
case ARG_VERSION: {
boolean insert_into_pastebuf = FALSE;
if (extended_opt) {
extended_opt++;
if (match_optname(extended_opt, "paste",
5, FALSE)) {
insert_into_pastebuf = TRUE;
} else {
raw_printf(
"-%sversion can only be extended with -%sversion:paste.\n",
dashdash, dashdash);
return TRUE;
}
}
early_version_info(insert_into_pastebuf);
return 2;
break;
} }
default: return 1;
break; case ARG_VERSION: {
boolean insert_into_pastebuf = FALSE;
if (extended_opt) {
extended_opt++;
if (match_optname(extended_opt, "paste", 5, FALSE)) {
insert_into_pastebuf = TRUE;
} else {
raw_printf(
"-%sversion can only be extended with -%sversion:paste.\n",
dashdash, dashdash);
return TRUE;
}
}
early_version_info(insert_into_pastebuf);
return 2;
}
default:
break;
} }
}; };
return FALSE; return FALSE;
@@ -843,7 +841,7 @@ enum earlyarg e_arg;
* are documented is right here. No gameplay is altered. * are documented is right here. No gameplay is altered.
* *
* test - test whether this parser is working * test - test whether this parser is working
* ttystatus - TTY: * ttystatus - TTY:
* immediateflips - WIN32: turn off display performance * immediateflips - WIN32: turn off display performance
* optimization so that display output * optimization so that display output
* can be debugged without buffering. * can be debugged without buffering.
+2 -2
View File
@@ -1752,7 +1752,7 @@ int magic; /* 0=Physical, otherwise skill level */
break; break;
case TT_LAVA: case TT_LAVA:
You("pull yourself above the %s!", hliquid("lava")); You("pull yourself above the %s!", hliquid("lava"));
u.utrap = 0; reset_utrap(TRUE);
return 1; return 1;
case TT_BURIEDBALL: case TT_BURIEDBALL:
case TT_INFLOOR: case TT_INFLOOR:
@@ -2738,7 +2738,7 @@ struct obj *obj;
if (!mtmp || enexto(&cc, rx, ry, youmonst.data)) { if (!mtmp || enexto(&cc, rx, ry, youmonst.data)) {
You("yank yourself out of the pit!"); You("yank yourself out of the pit!");
teleds(cc.x, cc.y, TRUE); teleds(cc.x, cc.y, TRUE);
u.utrap = 0; reset_utrap(TRUE);
vision_full_recalc = 1; vision_full_recalc = 1;
} }
} else { } else {
+7 -7
View File
@@ -703,11 +703,12 @@ xchar x, y;
} }
if (x != u.ux || y != u.uy) { if (x != u.ux || y != u.uy) {
static const char *pullmsg = "The ball pulls you out of the %s!";
struct trap *t; struct trap *t;
const char *pullmsg = "The ball pulls you out of the %s!"; long side;
if (u.utrap && u.utraptype != TT_INFLOOR if (u.utrap
&& u.utraptype != TT_BURIEDBALL) { && u.utraptype != TT_INFLOOR && u.utraptype != TT_BURIEDBALL) {
switch (u.utraptype) { switch (u.utraptype) {
case TT_PIT: case TT_PIT:
pline(pullmsg, "pit"); pline(pullmsg, "pit");
@@ -720,8 +721,8 @@ xchar x, y;
case TT_LAVA: case TT_LAVA:
pline(pullmsg, hliquid("lava")); pline(pullmsg, hliquid("lava"));
break; break;
case TT_BEARTRAP: { case TT_BEARTRAP:
register long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE; side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
pline(pullmsg, "bear trap"); pline(pullmsg, "bear trap");
set_wounded_legs(side, rn1(1000, 500)); set_wounded_legs(side, rn1(1000, 500));
if (!u.usteed) { if (!u.usteed) {
@@ -734,8 +735,7 @@ xchar x, y;
} }
break; break;
} }
} reset_utrap(TRUE);
u.utrap = 0;
fill_pit(u.ux, u.uy); fill_pit(u.ux, u.uy);
} }
+2 -2
View File
@@ -799,7 +799,7 @@ boolean *valsetlist;
* all of the fields when context.botlx is set. The tty port in * all of the fields when context.botlx is set. The tty port in
* particular has a problem if that isn't done, since the core sets * particular has a problem if that isn't done, since the core sets
* context.botlx when a menu or text display obliterates the status * context.botlx when a menu or text display obliterates the status
* line. * line.
* *
* For those situations, to trigger the full update of every field * For those situations, to trigger the full update of every field
* whether changed or not, call status_update() with BL_RESET. * whether changed or not, call status_update() with BL_RESET.
@@ -817,7 +817,7 @@ boolean *valsetlist;
else if ((windowprocs.wincap2 & WC2_FLUSH_STATUS) != 0L) else if ((windowprocs.wincap2 & WC2_FLUSH_STATUS) != 0L)
status_update(BL_FLUSH, (genericptr_t) 0, 0, 0, status_update(BL_FLUSH, (genericptr_t) 0, 0, 0,
NO_COLOR, &cond_hilites[0]); NO_COLOR, &cond_hilites[0]);
context.botl = context.botlx = 0; context.botl = context.botlx = 0;
update_all = FALSE; update_all = FALSE;
} }
+31 -8
View File
@@ -803,6 +803,7 @@ wiz_makemap(VOID_ARGS)
ballrelease(FALSE); ballrelease(FALSE);
unplacebc(); unplacebc();
} }
reset_utrap(FALSE); /* also done by safe_teleds() for new level */
check_special_room(TRUE); check_special_room(TRUE);
dmonsfree(); dmonsfree();
savelev(-1, ledger_no(&u.uz), FREE_SAVE); savelev(-1, ledger_no(&u.uz), FREE_SAVE);
@@ -2458,9 +2459,19 @@ int final;
long save_BLev = BLevitation; long save_BLev = BLevitation;
BLevitation = 0L; BLevitation = 0L;
if (Levitation) if (Levitation) {
enl_msg(You_, "would levitate", "would have levitated", /* either trapped in the floor or inside solid rock
if_surroundings_permitted, ""); (or both if chained to buried iron ball and have
moved one step into solid rock somehow) */
boolean trapped = (save_BLev & I_SPECIAL) != 0L,
terrain = (save_BLev & FROMOUTSIDE) != 0L;
Sprintf(buf, "%s%s%s",
trapped ? " if not trapped" : "",
(trapped && terrain) ? " and" : "",
terrain ? if_surroundings_permitted : "");
enl_msg(You_, "would levitate", "would have levitated", buf, "");
}
BLevitation = save_BLev; BLevitation = save_BLev;
} }
/* actively flying handled earlier as a status condition */ /* actively flying handled earlier as a status condition */
@@ -2468,15 +2479,27 @@ int final;
long save_BFly = BFlying; long save_BFly = BFlying;
BFlying = 0L; BFlying = 0L;
if (Flying) if (Flying) {
enl_msg(You_, "would fly", "would have flown", enl_msg(You_, "would fly", "would have flown",
/* wording quibble: for past tense, "hadn't been"
would sound better than "weren't" (and
"had permitted" better than "permitted"), but
"weren't" and "permitted" are adequate so the
extra complexity to handle that isn't worth it */
Levitation Levitation
? " if you weren't levitating" ? " if you weren't levitating"
: (save_BFly == FROMOUTSIDE) : (save_BFly == I_SPECIAL)
? if_surroundings_permitted /* this is an oversimpliction; being trapped
/* both surroundings and [latent] levitation */ might also be blocking levitation so flight
: " if circumstances permitted", would still be blocked after escaping trap */
? " if you weren't trapped"
: (save_BFly == FROMOUTSIDE)
? if_surroundings_permitted
/* two or more of levitation, surroundings,
and being trapped in the floor */
: " if circumstances permitted",
""); "");
}
BFlying = save_BFly; BFlying = save_BFly;
} }
/* actively walking on water handled earlier as a status condition */ /* actively walking on water handled earlier as a status condition */
+7 -10
View File
@@ -339,8 +339,8 @@ dig(VOID_ARGS)
} else { } else {
You("destroy the bear trap with %s.", You("destroy the bear trap with %s.",
yobjnam(uwep, (const char *) 0)); yobjnam(uwep, (const char *) 0));
u.utrap = 0; /* release from trap */
deltrap(ttmp); deltrap(ttmp);
reset_utrap(TRUE); /* release from trap, maybe Lev or Fly */
} }
/* we haven't made any progress toward a pit yet */ /* we haven't made any progress toward a pit yet */
context.digging.effort = 0; context.digging.effort = 0;
@@ -557,7 +557,7 @@ int ttyp;
if (u.utraptype == TT_BURIEDBALL) if (u.utraptype == TT_BURIEDBALL)
buried_ball_to_punishment(); buried_ball_to_punishment();
else if (u.utraptype == TT_INFLOOR) else if (u.utraptype == TT_INFLOOR)
u.utrap = 0; reset_utrap(FALSE);
} }
/* these furniture checks were in dighole(), but wand /* these furniture checks were in dighole(), but wand
@@ -619,11 +619,10 @@ int ttyp;
if (at_u) { if (at_u) {
if (!wont_fall) { if (!wont_fall) {
u.utrap = rn1(4, 2); set_utrap(rn1(4, 2), TT_PIT);
u.utraptype = TT_PIT;
vision_full_recalc = 1; /* vision limits change */ vision_full_recalc = 1; /* vision limits change */
} else } else
u.utrap = 0; reset_utrap(TRUE);
if (oldobjs != newobjs) /* something unearthed */ if (oldobjs != newobjs) /* something unearthed */
(void) pickup(1); /* detects pit */ (void) pickup(1); /* detects pit */
} else if (mtmp) { } else if (mtmp) {
@@ -1103,7 +1102,7 @@ struct obj *obj;
pline("You clear some debris from between the pits."); pline("You clear some debris from between the pits.");
} }
} else if (u.utrap && u.utraptype == TT_PIT } else if (u.utrap && u.utraptype == TT_PIT
&& (trap_with_u = t_at(u.ux, u.uy))) { && (trap_with_u = t_at(u.ux, u.uy)) != 0) {
You("swing %s, but the rubble has no place to go.", You("swing %s, but the rubble has no place to go.",
yobjnam(obj, (char *) 0)); yobjnam(obj, (char *) 0));
} else { } else {
@@ -1775,8 +1774,7 @@ buried_ball_to_punishment()
(void) stop_timer(RUST_METAL, obj_to_any(ball)); (void) stop_timer(RUST_METAL, obj_to_any(ball));
#endif #endif
punish(ball); /* use ball as flag for unearthed buried ball */ punish(ball); /* use ball as flag for unearthed buried ball */
u.utrap = 0; reset_utrap(FALSE);
u.utraptype = 0;
del_engr_at(cc.x, cc.y); del_engr_at(cc.x, cc.y);
newsym(cc.x, cc.y); newsym(cc.x, cc.y);
} }
@@ -1800,8 +1798,7 @@ buried_ball_to_freedom()
#endif #endif
place_object(ball, cc.x, cc.y); place_object(ball, cc.x, cc.y);
stackobj(ball); stackobj(ball);
u.utrap = 0; reset_utrap(TRUE);
u.utraptype = 0;
del_engr_at(cc.x, cc.y); del_engr_at(cc.x, cc.y);
newsym(cc.x, cc.y); newsym(cc.x, cc.y);
} }
+2 -2
View File
@@ -171,7 +171,7 @@ const char *verb;
"squished under a boulder", NO_KILLER_PREFIX); "squished under a boulder", NO_KILLER_PREFIX);
return FALSE; /* player remains trapped */ return FALSE; /* player remains trapped */
} else } else
u.utrap = 0; reset_utrap(TRUE);
} }
} }
if (*verb) { if (*verb) {
@@ -1239,7 +1239,7 @@ boolean at_stairs, falling, portal;
check_special_room(TRUE); /* probably was a trap door */ check_special_room(TRUE); /* probably was a trap door */
if (Punished) if (Punished)
unplacebc(); unplacebc();
u.utrap = 0; /* needed in level_tele */ reset_utrap(FALSE); /* needed in level_tele */
fill_pit(u.ux, u.uy); fill_pit(u.ux, u.uy);
u.ustuck = 0; /* idem */ u.ustuck = 0; /* idem */
u.uinwater = 0; u.uinwater = 0;
+9 -12
View File
@@ -175,7 +175,7 @@ const char *goal;
} }
/* disgusting hack; the alternate selection characters work for any /* disgusting hack; the alternate selection characters work for any
getpos call, but only matter for dowhatis (and doquickwhatis) */ getpos call, but only matter for dowhatis (and doquickwhatis) */
doing_what_is = (goal == what_is_an_unknown_object); doing_what_is = (goal == what_is_an_unknown_object);
if (doing_what_is) { if (doing_what_is) {
Sprintf(kbuf, "'%s' or '%s' or '%s' or '%s'", Sprintf(kbuf, "'%s' or '%s' or '%s' or '%s'",
visctrl(Cmd.spkeys[NHKF_GETPOS_PICK]), visctrl(Cmd.spkeys[NHKF_GETPOS_PICK]),
@@ -2071,20 +2071,17 @@ char *
rndorcname(s) rndorcname(s)
char *s; char *s;
{ {
int i; static const char *v[] = { "a", "ai", "og", "u" };
const char *v[] = {"a", "ai", "og", "u"}; static const char *snd[] = { "gor", "gris", "un", "bane", "ruk",
const char *snd[] = {"gor", "gris", "un", "bane", "ruk", "oth","ul", "z", "thos","akh","hai" };
"oth","ul", "z", "thos","akh","hai"}; int i, iend = rn1(2, 3), vstart = rn2(2);
int vstart = rn2(2);
if (s) { if (s) {
*s = '\0'; *s = '\0';
for (i = 0; i < rn2(2) + 3; ++i) { for (i = 0; i < iend; ++i) {
vstart = 1 - vstart; /* 0 -> 1, 1 -> 0 */ vstart = 1 - vstart; /* 0 -> 1, 1 -> 0 */
if (!rn2(30) && i > 0) Sprintf(eos(s), "%s%s", (i > 0 && !rn2(30)) ? "-" : "",
(void) strcat(s, "-"); vstart ? v[rn2(SIZE(v))] : snd[rn2(SIZE(snd))]);
(void) sprintf(eos(s), "%s", vstart ? v[rn2(SIZE(v))] :
snd[rn2(SIZE(snd))]);
} }
} }
return s; return s;
+8 -6
View File
@@ -185,10 +185,11 @@ Boots_on(VOID_ARGS)
incr_itimeout(&HFumbling, rnd(20)); incr_itimeout(&HFumbling, rnd(20));
break; break;
case LEVITATION_BOOTS: case LEVITATION_BOOTS:
if (!oldprop && !HLevitation && !BLevitation) { if (!oldprop && !HLevitation && !(BLevitation & FROMOUTSIDE)) {
makeknown(uarmf->otyp); makeknown(uarmf->otyp);
float_up(); float_up();
spoteffects(FALSE); if (Levitation)
spoteffects(FALSE); /* for sink effect */
} else { } else {
float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */ float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */
} }
@@ -238,7 +239,7 @@ Boots_off(VOID_ARGS)
HFumbling = EFumbling = 0; HFumbling = EFumbling = 0;
break; break;
case LEVITATION_BOOTS: case LEVITATION_BOOTS:
if (!oldprop && !HLevitation && !BLevitation if (!oldprop && !HLevitation && !(BLevitation & FROMOUTSIDE)
&& !context.takeoff.cancelled_don) { && !context.takeoff.cancelled_don) {
(void) float_down(0L, 0L); (void) float_down(0L, 0L);
makeknown(otyp); makeknown(otyp);
@@ -902,10 +903,11 @@ register struct obj *obj;
} }
break; break;
case RIN_LEVITATION: case RIN_LEVITATION:
if (!oldprop && !HLevitation && !BLevitation) { if (!oldprop && !HLevitation && !(BLevitation & FROMOUTSIDE)) {
float_up(); float_up();
learnring(obj, TRUE); learnring(obj, TRUE);
spoteffects(FALSE); /* for sinks */ if (Levitation)
spoteffects(FALSE); /* for sinks */
} else { } else {
float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */ float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */
} }
@@ -1016,7 +1018,7 @@ boolean gone;
} }
break; break;
case RIN_LEVITATION: case RIN_LEVITATION:
if (!BLevitation) { if (!(BLevitation & FROMOUTSIDE)) {
(void) float_down(0L, 0L); (void) float_down(0L, 0L);
if (!Levitation) if (!Levitation)
learnring(obj, TRUE); learnring(obj, TRUE);
+1 -1
View File
@@ -412,7 +412,7 @@ boolean with_you;
if (migrating_objs) if (migrating_objs)
deliver_obj_to_mon(mtmp, 0, DF_ALL); deliver_obj_to_mon(mtmp, 0, DF_ALL);
} }
if (xlocale && wander) { if (xlocale && wander) {
/* monster moved a bit; pick a nearby location */ /* monster moved a bit; pick a nearby location */
/* mnearto() deals w/stone, et al */ /* mnearto() deals w/stone, et al */
+1 -1
View File
@@ -1694,7 +1694,7 @@ unsigned long deliverflags;
where = (int) (otmp->owornmask & 0x7fffL); /* destination code */ where = (int) (otmp->owornmask & 0x7fffL); /* destination code */
if ((where & MIGR_TO_SPECIES) == 0) if ((where & MIGR_TO_SPECIES) == 0)
continue; continue;
if ((mtmp->data->mflags2 & otmp->corpsenm) != 0) { if ((mtmp->data->mflags2 & otmp->corpsenm) != 0) {
obj_extract_self(otmp); obj_extract_self(otmp);
otmp->owornmask = 0L; otmp->owornmask = 0L;
+16 -6
View File
@@ -1134,6 +1134,8 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
mon = u.ustuck; mon = u.ustuck;
bhitpos.x = mon->mx; bhitpos.x = mon->mx;
bhitpos.y = mon->my; bhitpos.y = mon->my;
if (tethered_weapon)
tmp_at(DISP_TETHER, obj_to_glyph(obj));
} else if (u.dz) { } else if (u.dz) {
if (u.dz < 0 if (u.dz < 0
/* Mjollnir must we wielded to be thrown--caller verifies this; /* Mjollnir must we wielded to be thrown--caller verifies this;
@@ -1280,19 +1282,27 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
/* missile has already been handled */ /* missile has already been handled */
if (tethered_weapon) tmp_at(DISP_END, 0); if (tethered_weapon) tmp_at(DISP_END, 0);
} else if (u.uswallow) { } else if (u.uswallow) {
if (tethered_weapon) if (tethered_weapon) {
tmp_at(DISP_END, 0); tmp_at(DISP_END, 0);
/* ball is not picked up by monster */ pline("%s returns to your hand!", The(xname(thrownobj)));
if (obj != uball) thrownobj = addinv(thrownobj);
(void) mpickobj(u.ustuck, obj); (void) encumber_msg();
thrownobj = (struct obj *) 0; if (thrownobj->owornmask & W_QUIVER) /* in case addinv() autoquivered */
setuqwep((struct obj *) 0);
setuwep(thrownobj);
} else {
/* ball is not picked up by monster */
if (obj != uball)
(void) mpickobj(u.ustuck, obj);
thrownobj = (struct obj *) 0;
}
} else { } else {
/* Mjollnir must we wielded to be thrown--caller verifies this; /* Mjollnir must we wielded to be thrown--caller verifies this;
aklys must we wielded as primary to return when thrown */ aklys must we wielded as primary to return when thrown */
if ((obj->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE)) if ((obj->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE))
|| tethered_weapon) { || tethered_weapon) {
if (rn2(100)) { if (rn2(100)) {
if (tethered_weapon) if (tethered_weapon)
tmp_at(DISP_END, BACKTRACK); tmp_at(DISP_END, BACKTRACK);
else else
sho_obj_return_to_u(obj); /* display its flight */ sho_obj_return_to_u(obj); /* display its flight */
+5 -3
View File
@@ -3088,15 +3088,17 @@ int corpsecheck; /* 0, no check, 1, corpses, 2, tinnable corpses */
struct trap *ttmp = t_at(u.ux, u.uy); struct trap *ttmp = t_at(u.ux, u.uy);
if (ttmp && ttmp->tseen && ttmp->ttyp == BEAR_TRAP) { if (ttmp && ttmp->tseen && ttmp->ttyp == BEAR_TRAP) {
boolean u_in_beartrap = (u.utrap && u.utraptype == TT_BEARTRAP);
/* If not already stuck in the trap, perhaps there should /* If not already stuck in the trap, perhaps there should
be a chance to becoming trapped? Probably not, because be a chance to becoming trapped? Probably not, because
then the trap would just get eaten on the _next_ turn... */ then the trap would just get eaten on the _next_ turn... */
Sprintf(qbuf, "There is a bear trap here (%s); eat it?", Sprintf(qbuf, "There is a bear trap here (%s); eat it?",
(u.utrap && u.utraptype == TT_BEARTRAP) ? "holding you" u_in_beartrap ? "holding you" : "armed");
: "armed");
if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') { if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
u.utrap = u.utraptype = 0;
deltrap(ttmp); deltrap(ttmp);
if (u_in_beartrap)
reset_utrap(TRUE);
return mksobj(BEARTRAP, TRUE, FALSE); return mksobj(BEARTRAP, TRUE, FALSE);
} else if (c == 'q') { } else if (c == 'q') {
return (struct obj *) 0; return (struct obj *) 0;
+1 -1
View File
@@ -870,7 +870,7 @@ int how;
else else
multi = -1; multi = -1;
if (u.utrap && u.utraptype == TT_LAVA) if (u.utrap && u.utraptype == TT_LAVA)
u.utrap = 0; reset_utrap(FALSE);
context.botl = 1; context.botl = 1;
u.ugrave_arise = NON_PM; u.ugrave_arise = NON_PM;
HUnchanging = 0L; HUnchanging = 0L;
+1 -1
View File
@@ -690,7 +690,7 @@ doengrave()
xcrypt(blengr(), buf); xcrypt(blengr(), buf);
} }
dengr = TRUE; dengr = TRUE;
} }
break; break;
case WAN_NOTHING: case WAN_NOTHING:
case WAN_UNDEAD_TURNING: case WAN_UNDEAD_TURNING:
+17 -14
View File
@@ -666,7 +666,7 @@ void
really_close() really_close()
{ {
int fd; int fd;
if (lftrack.init) { if (lftrack.init) {
fd = lftrack.fd; fd = lftrack.fd;
@@ -2156,24 +2156,27 @@ char sep;
return (char *) 0; return (char *) 0;
while (*str) { while (*str) {
if (*str == sep) nsep++; if (*str == sep)
str++; nsep++;
str++;
} }
csep = rn2(nsep); csep = rn2(nsep);
str = begin; str = begin;
while ((csep > 0) && *str) { while ((csep > 0) && *str) {
str++; str++;
if (*str == sep) csep--; if (*str == sep)
csep--;
} }
if (*str) { if (*str) {
if (*str == sep) str++; if (*str == sep)
begin = str; str++;
while (*str && *str != sep) { begin = str;
str++; while (*str && *str != sep) {
len++; str++;
} len++;
*str = '\0'; }
if (len) *str = '\0';
if (len)
return begin; return begin;
} }
return (char *) 0; return (char *) 0;
@@ -3582,7 +3585,7 @@ const char *reason; /* explanation */
void void
testinglog(filenm, type, reason) testinglog(filenm, type, reason)
const char *filenm; /* ad hoc file name */ const char *filenm; /* ad hoc file name */
const char *type; const char *type;
const char *reason; /* explanation */ const char *reason; /* explanation */
{ {
FILE *lfile; FILE *lfile;
+31 -11
View File
@@ -539,11 +539,17 @@ dosinkfall()
int dmg; int dmg;
boolean lev_boots = (uarmf && uarmf->otyp == LEVITATION_BOOTS), boolean lev_boots = (uarmf && uarmf->otyp == LEVITATION_BOOTS),
innate_lev = ((HLevitation & (FROMOUTSIDE | FROMFORM)) != 0L), innate_lev = ((HLevitation & (FROMOUTSIDE | FROMFORM)) != 0L),
ufall = (!innate_lev && !(HFlying || EFlying)); /* BFlying */ /* to handle being chained to buried iron ball, trying to
levitate but being blocked, then moving onto adjacent sink;
no need to worry about being blocked by terrain because we
couldn't be over a sink at the same time */
blockd_lev = (BLevitation == I_SPECIAL),
ufall = (!innate_lev && !blockd_lev
&& !(HFlying || EFlying)); /* BFlying */
if (!ufall) { if (!ufall) {
You(innate_lev ? "wobble unsteadily for a moment." You((innate_lev || blockd_lev) ? "wobble unsteadily for a moment."
: "gain control of your flight."); : "gain control of your flight.");
} else { } else {
long save_ELev = ELevitation, save_HLev = HLevitation; long save_ELev = ELevitation, save_HLev = HLevitation;
@@ -1179,6 +1185,10 @@ struct trap *desttrap; /* nonnull if another trap at <x,y> */
if (!u.utrap) if (!u.utrap)
return TRUE; /* sanity check */ return TRUE; /* sanity check */
/*
* Note: caller should call reset_utrap() when we set u.utrap to 0.
*/
switch (u.utraptype) { switch (u.utraptype) {
case TT_BEARTRAP: case TT_BEARTRAP:
if (flags.verbose) { if (flags.verbose) {
@@ -1203,7 +1213,6 @@ struct trap *desttrap; /* nonnull if another trap at <x,y> */
break; break;
case TT_WEB: case TT_WEB:
if (uwep && uwep->oartifact == ART_STING) { if (uwep && uwep->oartifact == ART_STING) {
u.utrap = 0;
pline("Sting cuts through the web!"); pline("Sting cuts through the web!");
break; /* escape trap but don't move */ break; /* escape trap but don't move */
} }
@@ -1656,7 +1665,12 @@ domove()
return; return;
if (u.utrap) { if (u.utrap) {
if (!trapmove(x, y, trap)) boolean moved = trapmove(x, y, trap);
if (!u.utrap)
reset_utrap(TRUE); /* might resume levitation or flight */
/* might not have escaped, or did escape but remain in same spot */
if (!moved)
return; return;
} }
@@ -1927,13 +1941,15 @@ switch_terrain()
|| (Is_waterlevel(&u.uz) && lev->typ == WATER)); || (Is_waterlevel(&u.uz) && lev->typ == WATER));
if (blocklev) { if (blocklev) {
/* called from spoteffects(), skip float_down() */ /* called from spoteffects(), stop levitating but skip float_down() */
if (Levitation) if (Levitation)
You_cant("levitate in here."); You_cant("levitate in here.");
BLevitation |= FROMOUTSIDE; BLevitation |= FROMOUTSIDE;
} else if (BLevitation) { } else if (BLevitation) {
BLevitation &= ~FROMOUTSIDE; BLevitation &= ~FROMOUTSIDE;
if (Levitation) /* we're probably levitating now; if not, we must be chained
to a buried iron ball so get float_up() feedback for that */
if (Levitation || BLevitation)
float_up(); float_up();
} }
/* the same terrain that blocks levitation also blocks flight */ /* the same terrain that blocks levitation also blocks flight */
@@ -2042,7 +2058,7 @@ boolean pick;
struct monst *mtmp; struct monst *mtmp;
struct trap *trap = t_at(u.ux, u.uy); struct trap *trap = t_at(u.ux, u.uy);
int trapflag = iflags.failing_untrap ? FORCETRAP : 0; int trapflag = iflags.failing_untrap ? FAILEDUNTRAP : 0;
/* prevent recursion from affecting the hero all over again /* prevent recursion from affecting the hero all over again
[hero poly'd to iron golem enters water here, drown() inflicts [hero poly'd to iron golem enters water here, drown() inflicts
@@ -2058,7 +2074,7 @@ boolean pick;
spotterrain = levl[u.ux][u.uy].typ; spotterrain = levl[u.ux][u.uy].typ;
spotloc.x = u.ux, spotloc.y = u.uy; spotloc.x = u.ux, spotloc.y = u.uy;
/* moving onto different terrain might cause Levitation to toggle */ /* moving onto different terrain might cause Lev or Fly to toggle */
if (spotterrain != levl[u.ux0][u.uy0].typ || !on_level(&u.uz, &u.uz0)) if (spotterrain != levl[u.ux0][u.uy0].typ || !on_level(&u.uz, &u.uz0))
switch_terrain(); switch_terrain();
@@ -2890,7 +2906,7 @@ boolean k_format;
int int
weight_cap() weight_cap()
{ {
long carrcap, save_ELev = ELevitation; long carrcap, save_ELev = ELevitation, save_BLev = BLevitation;
/* boots take multiple turns to wear but any properties they /* boots take multiple turns to wear but any properties they
confer are enabled at the start rather than the end; that confer are enabled at the start rather than the end; that
@@ -2900,6 +2916,9 @@ weight_cap()
ELevitation &= ~W_ARMF; ELevitation &= ~W_ARMF;
float_vs_flight(); /* in case Levitation is blocking Flying */ float_vs_flight(); /* in case Levitation is blocking Flying */
} }
/* levitation is blocked by being trapped in the floor, but it still
functions enough in that situation to enhance carrying capacity */
BLevitation &= ~I_SPECIAL;
carrcap = 25 * (ACURRSTR + ACURR(A_CON)) + 50; carrcap = 25 * (ACURRSTR + ACURR(A_CON)) + 50;
if (Upolyd) { if (Upolyd) {
@@ -2930,8 +2949,9 @@ weight_cap()
carrcap = 0; carrcap = 0;
} }
if (ELevitation != save_ELev) { if (ELevitation != save_ELev || BLevitation != save_BLev) {
ELevitation = save_ELev; ELevitation = save_ELev;
BLevitation = save_BLev;
float_vs_flight(); float_vs_flight();
} }
+1 -1
View File
@@ -2592,7 +2592,7 @@ long *out_cnt;
int unid_cnt; int unid_cnt;
char prompt[QBUFSZ]; char prompt[QBUFSZ];
unid_cnt = count_unidentified(invent); unid_cnt = count_unidentified(invent);
Sprintf(prompt, "Debug Identify"); /* 'title' rather than 'prompt' */ Sprintf(prompt, "Debug Identify"); /* 'title' rather than 'prompt' */
if (unid_cnt) if (unid_cnt)
Sprintf(eos(prompt), Sprintf(eos(prompt),
+2 -2
View File
@@ -1391,8 +1391,8 @@ int mmflags;
} }
if (allow_minvent && migrating_objs) if (allow_minvent && migrating_objs)
deliver_obj_to_mon(mtmp, 1, DF_NONE); /* in case there's waiting items */ deliver_obj_to_mon(mtmp, 1, DF_NONE); /* in case of waiting items */
if (!in_mklev) if (!in_mklev)
newsym(mtmp->mx, mtmp->my); /* make sure the mon shows up */ newsym(mtmp->mx, mtmp->my); /* make sure the mon shows up */
+2 -2
View File
@@ -782,13 +782,13 @@ struct attack *mattk;
/* Kill off aggressor if it didn't die. */ /* Kill off aggressor if it didn't die. */
if (!(result & MM_AGR_DIED)) { if (!(result & MM_AGR_DIED)) {
boolean was_leashed = (magr->mleashed); boolean was_leashed = (magr->mleashed != 0);
mondead(magr); mondead(magr);
if (!DEADMONSTER(magr)) if (!DEADMONSTER(magr))
return result; /* life saved */ return result; /* life saved */
result |= MM_AGR_DIED; result |= MM_AGR_DIED;
/* mondead() -> m_detach() -> m_unleash() always suppresses /* mondead() -> m_detach() -> m_unleash() always suppresses
the m_unleash() slack message, so deliver it here instead */ the m_unleash() slack message, so deliver it here instead */
if (was_leashed) if (was_leashed)
+1 -1
View File
@@ -1774,7 +1774,7 @@ struct attack *mattk;
if (u.utrap) { if (u.utrap) {
You("are released from the %s!", You("are released from the %s!",
u.utraptype == TT_WEB ? "web" : "trap"); u.utraptype == TT_WEB ? "web" : "trap");
u.utrap = 0; reset_utrap(FALSE);
} }
i = number_leashed(); i = number_leashed();
+1 -1
View File
@@ -1683,9 +1683,9 @@ mkinvokearea()
/* any trap hero is stuck in will be going away now */ /* any trap hero is stuck in will be going away now */
if (u.utrap) { if (u.utrap) {
u.utrap = 0;
if (u.utraptype == TT_BURIEDBALL) if (u.utraptype == TT_BURIEDBALL)
buried_ball_to_punishment(); buried_ball_to_punishment();
reset_utrap(FALSE);
} }
mkinvpos(xmin, ymin, 0); /* middle, before placing stairs */ mkinvpos(xmin, ymin, 0); /* middle, before placing stairs */
+1 -2
View File
@@ -801,11 +801,10 @@ stolen_booty(VOID_ARGS)
mtyp = rn2((PM_ORC_SHAMAN - PM_ORC) + 1) + PM_ORC; mtyp = rn2((PM_ORC_SHAMAN - PM_ORC) + 1) + PM_ORC;
mtmp = makemon(&mons[mtyp], 0, 0, MM_NONAME); mtmp = makemon(&mons[mtyp], 0, 0, MM_NONAME);
if (mtmp) { if (mtmp) {
shiny_orc_stuff(mtmp); shiny_orc_stuff(mtmp);
migrate_orc(mtmp, 0UL); migrate_orc(mtmp, 0UL);
} }
} }
ransacked = 0; ransacked = 0;
} }
+1 -1
View File
@@ -462,7 +462,7 @@ unsigned corpseflags;
* underneath it, you could be told the corpse type of a * underneath it, you could be told the corpse type of a
* monster that you never knew was there without this. * monster that you never knew was there without this.
* The code in hitmu() substitutes the word "something" * The code in hitmu() substitutes the word "something"
* if the corpses obj->dknown is 0. * if the corpse's obj->dknown is 0.
*/ */
if (Blind && !sensemon(mtmp)) if (Blind && !sensemon(mtmp))
obj->dknown = 0; obj->dknown = 0;
+4 -6
View File
@@ -255,14 +255,12 @@ struct monst *mon;
} }
} }
#define flees_light(mon) ((mon)->data == &mons[PM_GREMLIN] && \ #define flees_light(mon) ((mon)->data == &mons[PM_GREMLIN] \
(uwep && artifact_light(uwep) && uwep->lamplit)) && (uwep && artifact_light(uwep) && uwep->lamplit))
/* we could include this in the above macro, but probably overkill/overhead */ /* we could include this in the above macro, but probably overkill/overhead */
/* (!((which_armor((mon), W_ARMC) != 0) && ((which_armor((mon), W_ARMH) != 0))) && */ /* && (!(which_armor((mon), W_ARMC) != 0 */
/* && which_armor((mon), W_ARMH) != 0)) */
/* monster begins fleeing for the specified time, 0 means untimed flee /* monster begins fleeing for the specified time, 0 means untimed flee
* if first, only adds fleetime if monster isn't already fleeing * if first, only adds fleetime if monster isn't already fleeing
* if fleemsg, prints a message about new flight, otherwise, caller should */ * if fleemsg, prints a message about new flight, otherwise, caller should */
+29 -18
View File
@@ -254,14 +254,10 @@ int force;
start_y = u.uy - (force * 2); start_y = u.uy - (force * 2);
end_x = u.ux + (force * 2); end_x = u.ux + (force * 2);
end_y = u.uy + (force * 2); end_y = u.uy + (force * 2);
if (start_x < 1) start_x = max(start_x, 1);
start_x = 1; start_y = max(start_y, 0);
if (start_y < 1) end_x = min(end_x, COLNO - 1);
start_y = 1; end_y = min(end_y, ROWNO - 1);
if (end_x >= COLNO)
end_x = COLNO - 1;
if (end_y >= ROWNO)
end_y = ROWNO - 1;
for (x = start_x; x <= end_x; x++) for (x = start_x; x <= end_x; x++)
for (y = start_y; y <= end_y; y++) { for (y = start_y; y <= end_y; y++) {
if ((mtmp = m_at(x, y)) != 0) { if ((mtmp = m_at(x, y)) != 0) {
@@ -311,6 +307,11 @@ int force;
break; /* no pit if portal at that location */ break; /* no pit if portal at that location */
chasm->tseen = 1; chasm->tseen = 1;
/* TODO:
* This ought to be split into a separate routine to
* reduce indentation and the consequent line-wraps.
*/
levl[x][y].doormask = 0; levl[x][y].doormask = 0;
/* /*
* Let liquid flow into the newly created chasm. * Let liquid flow into the newly created chasm.
@@ -328,8 +329,8 @@ int force;
if ((otmp = sobj_at(BOULDER, x, y)) != 0) { if ((otmp = sobj_at(BOULDER, x, y)) != 0) {
if (cansee(x, y)) if (cansee(x, y))
pline("KADOOM! The boulder falls into a chasm%s!", pline("KADOOM! The boulder falls into a chasm%s!",
((x == u.ux) && (y == u.uy)) ? " below you" (x == u.ux && y == u.uy) ? " below you"
: ""); : "");
if (mtmp) if (mtmp)
mtmp->mtrapped = 0; mtmp->mtrapped = 0;
obj_extract_self(otmp); obj_extract_self(otmp);
@@ -343,6 +344,7 @@ int force;
if (!is_flyer(mtmp->data) if (!is_flyer(mtmp->data)
&& !is_clinger(mtmp->data)) { && !is_clinger(mtmp->data)) {
boolean m_already_trapped = mtmp->mtrapped; boolean m_already_trapped = mtmp->mtrapped;
mtmp->mtrapped = 1; mtmp->mtrapped = 1;
if (!m_already_trapped) { /* suppress messages */ if (!m_already_trapped) { /* suppress messages */
if (cansee(x, y)) if (cansee(x, y))
@@ -375,6 +377,16 @@ int force;
} }
} }
} else if (x == u.ux && y == u.uy) { } else if (x == u.ux && y == u.uy) {
if (u.utrap && u.utraptype == TT_BURIEDBALL) {
/* Note: the chain should break if a pit gets
created at the buried ball's location, which
is not necessarily here. But if we don't do
things this way, entering the new pit below
will override current trap anyway, but too
late to get Lev and Fly handling. */
Your("chain breaks!");
reset_utrap(TRUE);
}
if (Levitation || Flying if (Levitation || Flying
|| is_clinger(youmonst.data)) { || is_clinger(youmonst.data)) {
if (!tu_pit) { /* no pit here previously */ if (!tu_pit) { /* no pit here previously */
@@ -384,10 +396,9 @@ int force;
} else if (!tu_pit || !u.utrap } else if (!tu_pit || !u.utrap
|| (u.utrap && u.utraptype != TT_PIT)) { || (u.utrap && u.utraptype != TT_PIT)) {
/* no pit here previously, or you were /* no pit here previously, or you were
not in it even it there was */ not in it even if there was */
You("fall into a chasm!"); You("fall into a chasm!");
u.utrap = rn1(6, 2); set_utrap(rn1(6, 2), TT_PIT);
u.utraptype = TT_PIT;
losehp(Maybe_Half_Phys(rnd(6)), losehp(Maybe_Half_Phys(rnd(6)),
"fell into a chasm", NO_KILLER_PREFIX); "fell into a chasm", NO_KILLER_PREFIX);
selftouch("Falling, you"); selftouch("Falling, you");
@@ -396,9 +407,9 @@ int force;
((Fumbling && !rn2(5)) ((Fumbling && !rn2(5))
|| (!rnl(Role_if(PM_ARCHEOLOGIST) ? 3 : 9)) || (!rnl(Role_if(PM_ARCHEOLOGIST) ? 3 : 9))
|| ((ACURR(A_DEX) > 7) && rn2(5))); || ((ACURR(A_DEX) > 7) && rn2(5)));
You("are jostled around violently!"); You("are jostled around violently!");
u.utrap = rn1(6, 2); set_utrap(rn1(6, 2), TT_PIT);
u.utraptype = TT_PIT; /* superfluous */
losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)), losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
"hurt in a chasm", NO_KILLER_PREFIX); "hurt in a chasm", NO_KILLER_PREFIX);
if (keepfooting) if (keepfooting)
@@ -587,7 +598,7 @@ struct obj *instr;
exercise(A_DEX, TRUE); exercise(A_DEX, TRUE);
break; break;
case DRUM_OF_EARTHQUAKE: /* create several pits */ case DRUM_OF_EARTHQUAKE: /* create several pits */
/* a drum of earthquake does cause not cause deafness /* a drum of earthquake does not cause deafness
while still magically functional, nor afterwards while still magically functional, nor afterwards
when it invokes the LEATHER_DRUM case instead and when it invokes the LEATHER_DRUM case instead and
mundane is flagged */ mundane is flagged */
@@ -605,8 +616,8 @@ struct obj *instr;
You("beat a deafening row!"); You("beat a deafening row!");
incr_itimeout(&HDeaf, rn1(20, 30)); incr_itimeout(&HDeaf, rn1(20, 30));
exercise(A_WIS, FALSE); exercise(A_WIS, FALSE);
} else } else
You("%s %s.", You("%s %s.",
rn2(2) ? "butcher" : rn2(2) ? "manage" : "pull off", rn2(2) ? "butcher" : rn2(2) ? "manage" : "pull off",
an(beats[rn2(SIZE(beats))])); an(beats[rn2(SIZE(beats))]));
awaken_monsters(u.ulevel * (mundane ? 5 : 40)); awaken_monsters(u.ulevel * (mundane ? 5 : 40));
+1 -1
View File
@@ -78,7 +78,7 @@ static struct Bool_Opt {
#else #else
{ "asksavedisk", (boolean *) 0, FALSE, SET_IN_FILE }, { "asksavedisk", (boolean *) 0, FALSE, SET_IN_FILE },
#endif #endif
{ "autodescribe", &iflags.autodescribe, FALSE, SET_IN_GAME }, { "autodescribe", &iflags.autodescribe, TRUE, SET_IN_GAME },
{ "autodig", &flags.autodig, FALSE, SET_IN_GAME }, { "autodig", &flags.autodig, FALSE, SET_IN_GAME },
{ "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 },
+3 -3
View File
@@ -1390,7 +1390,7 @@ boolean without_asking;
} }
display_nhwindow(datawin, FALSE); display_nhwindow(datawin, FALSE);
destroy_nhwindow(datawin), datawin = WIN_ERR; destroy_nhwindow(datawin), datawin = WIN_ERR;
} }
} }
} }
@@ -1470,7 +1470,7 @@ doidtrap()
commands: basic letters vs digits, 'g' vs 'G' for '5', phone commands: basic letters vs digits, 'g' vs 'G' for '5', phone
keypad vs normal layout of digits, and QWERTZ keyboard swap between keypad vs normal layout of digits, and QWERTZ keyboard swap between
y/Y/^Y/M-y/M-Y/M-^Y and z/Z/^Z/M-z/M-Z/M-^Z.) y/Y/^Y/M-y/M-Y/M-^Y and z/Z/^Z/M-z/M-Z/M-^Z.)
The interpretor understands The interpretor understands
'&#' for comment, '&#' for comment,
'&? option' for 'if' (also '&? !option' '&? option' for 'if' (also '&? !option'
@@ -1481,7 +1481,7 @@ doidtrap()
'&:' for 'else' (also '&: #comment'; '&:' for 'else' (also '&: #comment';
0 or 1 instance for a given 'if'), and 0 or 1 instance for a given 'if'), and
'&.' for 'endif' (also '&. #comment'; required for each 'if'). '&.' for 'endif' (also '&. #comment'; required for each 'if').
The option handling is a bit of a mess, with no generality for The option handling is a bit of a mess, with no generality for
which options to deal with and only a comma separated list of which options to deal with and only a comma separated list of
integer values for the '=value' part. number_pad is the only integer values for the '=value' part. number_pad is the only
+31 -15
View File
@@ -86,7 +86,10 @@ set_uasmon()
PROPSET(TELEPORT, can_teleport(mdat)); PROPSET(TELEPORT, can_teleport(mdat));
PROPSET(TELEPORT_CONTROL, control_teleport(mdat)); PROPSET(TELEPORT_CONTROL, control_teleport(mdat));
PROPSET(LEVITATION, is_floater(mdat)); PROPSET(LEVITATION, is_floater(mdat));
PROPSET(FLYING, is_flyer(mdat)); /* floating eye is the only 'floater'; it is also flagged as a 'flyer';
suppress flying for it so that enlightenment doesn't confusingly
show latent flight capability always blocked by levitation */
PROPSET(FLYING, (is_flyer(mdat) && !is_floater(mdat)));
PROPSET(SWIMMING, is_swimmer(mdat)); PROPSET(SWIMMING, is_swimmer(mdat));
/* [don't touch MAGICAL_BREATHING here; both Amphibious and Breathless /* [don't touch MAGICAL_BREATHING here; both Amphibious and Breathless
key off of it but include different monster forms...] */ key off of it but include different monster forms...] */
@@ -116,12 +119,21 @@ set_uasmon()
void void
float_vs_flight() float_vs_flight()
{ {
/* floating overrides flight; normally float_up() and float_down() boolean stuck_in_floor = (u.utrap && u.utraptype != TT_PIT);
handle this, but sometimes they're skipped */
if (HLevitation || ELevitation) /* floating overrides flight; so does being trapped in the floor */
if ((HLevitation || ELevitation)
|| ((HFlying || EFlying) && stuck_in_floor))
BFlying |= I_SPECIAL; BFlying |= I_SPECIAL;
else else
BFlying &= ~I_SPECIAL; BFlying &= ~I_SPECIAL;
/* being trapped on the ground (bear trap, web, molten lava survived
with fire resistance, former lava solidified via cold, tethered
to a buried iron ball) overrides floating--the floor is reachable */
if ((HLevitation || ELevitation) && stuck_in_floor)
BLevitation |= I_SPECIAL;
else
BLevitation &= ~I_SPECIAL;
context.botl = TRUE; context.botl = TRUE;
} }
@@ -207,8 +219,8 @@ const char *fmt, *arg;
if (u.twoweap && !could_twoweap(youmonst.data)) if (u.twoweap && !could_twoweap(youmonst.data))
untwoweapon(); untwoweapon();
if (u.utraptype == TT_PIT && u.utrap) { if (u.utrap && u.utraptype == TT_PIT) {
u.utrap = rn1(6, 2); /* time to escape resets */ set_utrap(rn1(6, 2), TT_PIT); /* time to escape resets */
} }
if (was_blind && !Blind) { /* reverting from eyeless */ if (was_blind && !Blind) { /* reverting from eyeless */
Blinded = 1L; Blinded = 1L;
@@ -725,8 +737,8 @@ int mntmp;
drop_weapon(1); drop_weapon(1);
(void) hideunder(&youmonst); (void) hideunder(&youmonst);
if (u.utraptype == TT_PIT && u.utrap) { if (u.utrap && u.utraptype == TT_PIT) {
u.utrap = rn1(6, 2); /* time to escape resets */ set_utrap(rn1(6, 2), TT_PIT); /* time to escape resets */
} }
if (was_blind && !Blind) { /* previous form was eyeless */ if (was_blind && !Blind) { /* previous form was eyeless */
Blinded = 1L; Blinded = 1L;
@@ -794,17 +806,17 @@ int mntmp;
spoteffects(TRUE); spoteffects(TRUE);
if (Passes_walls && u.utrap if (Passes_walls && u.utrap
&& (u.utraptype == TT_INFLOOR || u.utraptype == TT_BURIEDBALL)) { && (u.utraptype == TT_INFLOOR || u.utraptype == TT_BURIEDBALL)) {
u.utrap = 0; if (u.utraptype == TT_INFLOOR) {
if (u.utraptype == TT_INFLOOR)
pline_The("rock seems to no longer trap you."); pline_The("rock seems to no longer trap you.");
else { } else {
pline_The("buried ball is no longer bound to you."); pline_The("buried ball is no longer bound to you.");
buried_ball_to_freedom(); buried_ball_to_freedom();
} }
reset_utrap(TRUE);
} else if (likes_lava(youmonst.data) && u.utrap } else if (likes_lava(youmonst.data) && u.utrap
&& u.utraptype == TT_LAVA) { && u.utraptype == TT_LAVA) {
u.utrap = 0;
pline_The("%s now feels soothing.", hliquid("lava")); pline_The("%s now feels soothing.", hliquid("lava"));
reset_utrap(TRUE);
} }
if (amorphous(youmonst.data) || is_whirly(youmonst.data) if (amorphous(youmonst.data) || is_whirly(youmonst.data)
|| unsolid(youmonst.data)) { || unsolid(youmonst.data)) {
@@ -823,11 +835,11 @@ int mntmp;
You("are no longer stuck in the %s.", You("are no longer stuck in the %s.",
u.utraptype == TT_WEB ? "web" : "bear trap"); u.utraptype == TT_WEB ? "web" : "bear trap");
/* probably should burn webs too if PM_FIRE_ELEMENTAL */ /* probably should burn webs too if PM_FIRE_ELEMENTAL */
u.utrap = 0; reset_utrap(TRUE);
} }
if (webmaker(youmonst.data) && u.utrap && u.utraptype == TT_WEB) { if (webmaker(youmonst.data) && u.utrap && u.utraptype == TT_WEB) {
You("orient yourself on the web."); You("orient yourself on the web.");
u.utrap = 0; reset_utrap(TRUE);
} }
check_strangling(TRUE); /* maybe start strangling */ check_strangling(TRUE); /* maybe start strangling */
@@ -1018,6 +1030,8 @@ int alone;
void void
rehumanize() rehumanize()
{ {
boolean was_flying = (Flying != 0);
/* You can't revert back while unchanging */ /* You can't revert back while unchanging */
if (Unchanging) { if (Unchanging) {
if (u.mh < 1) { if (u.mh < 1) {
@@ -1048,7 +1062,9 @@ rehumanize()
context.botl = 1; context.botl = 1;
vision_full_recalc = 1; vision_full_recalc = 1;
(void) encumber_msg(); (void) encumber_msg();
if (was_flying && !Flying && u.usteed)
You("and %s return gently to the %s.",
mon_nam(u.usteed), surface(u.ux, u.uy));
retouch_equipment(2); retouch_equipment(2);
if (!uarmg) if (!uarmg)
selftouch(no_longer_petrify_resistant); selftouch(no_longer_petrify_resistant);
+1 -1
View File
@@ -355,7 +355,7 @@ int trouble;
You("are back on solid ground."); You("are back on solid ground.");
/* teleport should always succeed, but if not, just untrap them */ /* teleport should always succeed, but if not, just untrap them */
if (!safe_teleds(FALSE)) if (!safe_teleds(FALSE))
u.utrap = 0; reset_utrap(TRUE);
break; break;
case TROUBLE_STARVING: case TROUBLE_STARVING:
/* temporarily lost strength recovery now handled by init_uhunger() */ /* temporarily lost strength recovery now handled by init_uhunger() */
+2
View File
@@ -335,6 +335,8 @@ boolean force; /* Quietly force this animal */
/* Must have Lev_at_will at this point */ /* Must have Lev_at_will at this point */
pline("%s magically floats up!", Monnam(mtmp)); pline("%s magically floats up!", Monnam(mtmp));
You("mount %s.", mon_nam(mtmp)); You("mount %s.", mon_nam(mtmp));
if (Flying)
You("and %s take flight together.", mon_nam(mtmp));
} }
/* setuwep handles polearms differently when you're mounted */ /* setuwep handles polearms differently when you're mounted */
if (uwep && is_pole(uwep)) if (uwep && is_pole(uwep))
+1 -1
View File
@@ -289,7 +289,7 @@ boolean allow_drag;
} }
} }
} }
u.utrap = 0; reset_utrap(FALSE);
u.ustuck = 0; u.ustuck = 0;
u.ux0 = u.ux; u.ux0 = u.ux;
u.uy0 = u.uy; u.uy0 = u.uy;
+168 -65
View File
@@ -805,10 +805,12 @@ struct trap *trap;
{ {
boolean isyou = (mtmp == &youmonst); boolean isyou = (mtmp == &youmonst);
struct permonst *mptr = mtmp->data; struct permonst *mptr = mtmp->data;
if (amorphous(mptr) || is_whirly(mptr) || flaming(mptr) if (amorphous(mptr) || is_whirly(mptr) || flaming(mptr)
|| unsolid(mptr) || mptr == &mons[PM_GELATINOUS_CUBE]) { || unsolid(mptr) || mptr == &mons[PM_GELATINOUS_CUBE]) {
xchar x = trap->tx; xchar x = trap->tx;
xchar y = trap->ty; xchar y = trap->ty;
if (flaming(mptr) || acidic(mptr)) { if (flaming(mptr) || acidic(mptr)) {
if (domsg) { if (domsg) {
if (isyou) if (isyou)
@@ -825,9 +827,9 @@ struct trap *trap;
return TRUE; return TRUE;
} }
if (domsg) { if (domsg) {
if (isyou) if (isyou) {
You("flow through %s spider web.", a_your[trap->madeby_u]); You("flow through %s spider web.", a_your[trap->madeby_u]);
else { } else {
pline("%s flows through %s spider web.", Monnam(mtmp), pline("%s flows through %s spider web.", Monnam(mtmp),
a_your[trap->madeby_u]); a_your[trap->madeby_u]);
seetrap(trap); seetrap(trap);
@@ -853,6 +855,37 @@ struct trap *trap;
return otmp; return otmp;
} }
void
set_utrap(tim, typ)
unsigned tim, typ;
{
u.utrap = tim;
/* FIXME:
* utraptype==0 is bear trap rather than 'none'; we probably ought
* to change that but can't do so until save file compatability is
* able to be broken.
*/
u.utraptype = tim ? typ : 0;
float_vs_flight(); /* maybe block Lev and/or Fly */
}
void
reset_utrap(msg)
boolean msg;
{
boolean was_Lev = (Levitation != 0), was_Fly = (Flying != 0);
set_utrap(0, 0);
if (msg) {
if (!was_Lev && Levitation)
float_up();
if (!was_Fly && Flying)
You("can fly.");
}
}
void void
dotrap(trap, trflags) dotrap(trap, trflags)
register struct trap *trap; register struct trap *trap;
@@ -861,7 +894,8 @@ unsigned trflags;
register int ttype = trap->ttyp; register int ttype = trap->ttyp;
struct obj *otmp; struct obj *otmp;
boolean already_seen = trap->tseen, boolean already_seen = trap->tseen,
forcetrap = (trflags & FORCETRAP) != 0, forcetrap = ((trflags & FORCETRAP) != 0
|| (trflags & FAILEDUNTRAP) != 0),
webmsgok = (trflags & NOWEBMSG) == 0, webmsgok = (trflags & NOWEBMSG) == 0,
forcebungle = (trflags & FORCEBUNGLE) != 0, forcebungle = (trflags & FORCEBUNGLE) != 0,
plunged = (trflags & TOOKPLUNGE) != 0, plunged = (trflags & TOOKPLUNGE) != 0,
@@ -1042,13 +1076,12 @@ unsigned trflags;
A_Your[trap->madeby_u]); A_Your[trap->madeby_u]);
break; break;
} }
u.utrap = rn1(4, 4); set_utrap((unsigned) rn1(4, 4), TT_BEARTRAP);
u.utraptype = TT_BEARTRAP;
if (u.usteed) { if (u.usteed) {
pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u], pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u],
s_suffix(mon_nam(u.usteed)), mbodypart(u.usteed, FOOT)); s_suffix(mon_nam(u.usteed)), mbodypart(u.usteed, FOOT));
if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE)) if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE))
u.utrap = 0; /* steed died, hero not trapped */ reset_utrap(TRUE); /* steed died, hero not trapped */
} else { } else {
pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u], pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u],
body_part(FOOT)); body_part(FOOT));
@@ -1191,8 +1224,12 @@ unsigned trflags;
} else } else
You("%s %s!", conj_pit ? "step" : "land", predicament); You("%s %s!", conj_pit ? "step" : "land", predicament);
} }
u.utrap = rn1(6, 2); /* FIXME:
u.utraptype = TT_PIT; * if hero gets killed here, setting u.utrap in advance will
* show "you were trapped in a pit" during disclosure's display
* of enlightenment, but hero is dying *before* becoming trapped.
*/
set_utrap((unsigned) rn1(6, 2), TT_PIT);
if (!steedintrap(trap, (struct obj *) 0)) { if (!steedintrap(trap, (struct obj *) 0)) {
if (ttype == SPIKED_PIT) { if (ttype == SPIKED_PIT) {
oldumort = u.umortality; oldumort = u.umortality;
@@ -1286,11 +1323,13 @@ unsigned trflags;
} }
You("%s %s spider web!", verbbuf, a_your[trap->madeby_u]); You("%s %s spider web!", verbbuf, a_your[trap->madeby_u]);
} }
u.utraptype = TT_WEB;
/* time will be adjusted below */
set_utrap(1, TT_WEB);
/* Time stuck in the web depends on your/steed strength. */ /* Time stuck in the web depends on your/steed strength. */
{ {
register int str = ACURR(A_STR); int tim, str = ACURR(A_STR);
/* If mounted, the steed gets trapped. Use mintrap /* If mounted, the steed gets trapped. Use mintrap
* to do all the work. If mtrapped is set as a result, * to do all the work. If mtrapped is set as a result,
@@ -1312,32 +1351,34 @@ unsigned trflags;
if (strongmonst(u.usteed->data)) if (strongmonst(u.usteed->data))
str = 17; str = 17;
} else { } else {
reset_utrap(FALSE);
break; break;
} }
webmsgok = FALSE; /* mintrap printed the messages */ webmsgok = FALSE; /* mintrap printed the messages */
} }
if (str <= 3) if (str <= 3)
u.utrap = rn1(6, 6); tim = rn1(6, 6);
else if (str < 6) else if (str < 6)
u.utrap = rn1(6, 4); tim = rn1(6, 4);
else if (str < 9) else if (str < 9)
u.utrap = rn1(4, 4); tim = rn1(4, 4);
else if (str < 12) else if (str < 12)
u.utrap = rn1(4, 2); tim = rn1(4, 2);
else if (str < 15) else if (str < 15)
u.utrap = rn1(2, 2); tim = rn1(2, 2);
else if (str < 18) else if (str < 18)
u.utrap = rnd(2); tim = rnd(2);
else if (str < 69) else if (str < 69)
u.utrap = 1; tim = 1;
else { else {
u.utrap = 0; tim = 0;
if (webmsgok) if (webmsgok)
You("tear through %s web!", a_your[trap->madeby_u]); You("tear through %s web!", a_your[trap->madeby_u]);
deltrap(trap); deltrap(trap);
newsym(u.ux, u.uy); /* get rid of trap symbol */ newsym(u.ux, u.uy); /* get rid of trap symbol */
} }
set_utrap((unsigned) tim, TT_WEB);
} }
break; break;
@@ -2767,16 +2808,34 @@ float_up()
context.botl = TRUE; context.botl = TRUE;
if (u.utrap) { if (u.utrap) {
if (u.utraptype == TT_PIT) { if (u.utraptype == TT_PIT) {
u.utrap = 0; reset_utrap(FALSE);
You("float up, out of the pit!"); You("float up, out of the pit!");
vision_full_recalc = 1; /* vision limits change */ vision_full_recalc = 1; /* vision limits change */
fill_pit(u.ux, u.uy); fill_pit(u.ux, u.uy);
} else if (u.utraptype == TT_INFLOOR) { } else if (u.utraptype == TT_LAVA /* molten lava */
|| u.utraptype == TT_INFLOOR) { /* solidified lava */
Your("body pulls upward, but your %s are still stuck.", Your("body pulls upward, but your %s are still stuck.",
makeplural(body_part(LEG))); makeplural(body_part(LEG)));
} else { } else if (u.utraptype == TT_BURIEDBALL) { /* tethered */
You("float up, only your %s is still stuck.", body_part(LEG)); coord cc;
cc.x = u.ux, cc.y = u.uy;
/* caveat: this finds the first buried iron ball within
one step of the specified location, not necessarily the
buried [former] uball at the original anchor point */
(void) buried_ball(&cc);
/* being chained to the floor blocks levitation from floating
above that floor but not from enhancing carrying capacity */
You("feel lighter, but your %s is still chained to the %s.",
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.");
} else { /* bear trap */
You("float up slightly, but your %s is still stuck.",
body_part(LEG));
} }
/* when still trapped, float_vs_flight() below will block levitation */
#if 0 #if 0
} else if (Is_waterlevel(&u.uz)) { } else if (Is_waterlevel(&u.uz)) {
pline("It feels as though you've lost some weight."); pline("It feels as though you've lost some weight.");
@@ -2795,8 +2854,7 @@ float_up()
} else { } else {
You("start to float in the air!"); You("start to float in the air!");
} }
if (u.usteed && !is_floater(u.usteed->data) if (u.usteed && !is_floater(u.usteed->data) && !is_flyer(u.usteed->data)) {
&& !is_flyer(u.usteed->data)) {
if (Lev_at_will) { if (Lev_at_will) {
pline("%s magically floats up!", Monnam(u.usteed)); pline("%s magically floats up!", Monnam(u.usteed));
} else { } else {
@@ -2806,7 +2864,7 @@ float_up()
} }
if (Flying) if (Flying)
You("are no longer able to control your flight."); You("are no longer able to control your flight.");
BFlying |= I_SPECIAL; float_vs_flight(); /* set BFlying, also BLevitation if still trapped */
/* levitation gives maximum carrying capacity, so encumbrance /* levitation gives maximum carrying capacity, so encumbrance
state might be reduced */ state might be reduced */
(void) encumber_msg(); (void) encumber_msg();
@@ -2841,16 +2899,29 @@ long hmask, emask; /* might cancel timeout */
if (Levitation) if (Levitation)
return 0; /* maybe another ring/potion/boots */ return 0; /* maybe another ring/potion/boots */
if (BLevitation) { if (BLevitation) {
/* Levitation is blocked, so hero is not actually floating /* if blocked by terrain, we haven't actually been levitating so
hence shouldn't have float_down effects and feedback */ we don't give any end-of-levitation feedback or side-effects,
float_vs_flight(); /* before nomul() rather than after */ but if blocking is solely due to being trapped in/on floor,
do give some feedback but skip other float_down() effects */
boolean trapped = (BLevitation == I_SPECIAL);
float_vs_flight();
if (trapped && u.utrap) /* u.utrap => paranoia */
You("are no longer trying to float up from the %s.",
(u.utraptype == TT_BEARTRAP) ? "trap's jaws"
: (u.utraptype == TT_WEB) ? "web"
: (u.utraptype == TT_BURIEDBALL) ? "chain"
: (u.utraptype == TT_LAVA) ? "lava"
: "ground"); /* TT_INFLOOR */
(void) encumber_msg(); /* carrying capacity might have changed */
return 0; return 0;
} }
context.botl = TRUE; context.botl = TRUE;
nomul(0); /* stop running or resting */ nomul(0); /* stop running or resting */
if (BFlying) { if (BFlying) {
/* controlled flight no longer overridden by levitation */ /* controlled flight no longer overridden by levitation */
BFlying &= ~I_SPECIAL; float_vs_flight(); /* clears BFlying & I_SPECIAL
* unless hero is stuck in floor */
if (Flying) { if (Flying) {
You("have stopped levitating and are now flying."); You("have stopped levitating and are now flying.");
(void) encumber_msg(); /* carrying capacity might have changed */ (void) encumber_msg(); /* carrying capacity might have changed */
@@ -2981,7 +3052,7 @@ climb_pit()
if (Passes_walls) { if (Passes_walls) {
/* marked as trapped so they can pick things up */ /* marked as trapped so they can pick things up */
You("ascend from the pit."); You("ascend from the pit.");
u.utrap = 0; reset_utrap(FALSE);
fill_pit(u.ux, u.uy); fill_pit(u.ux, u.uy);
vision_full_recalc = 1; /* vision limits change */ vision_full_recalc = 1; /* vision limits change */
} else if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) { } else if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) {
@@ -2993,10 +3064,11 @@ climb_pit()
/* eg fell in pit, then poly'd to a flying monster; /* eg fell in pit, then poly'd to a flying monster;
or used '>' to deliberately enter it */ or used '>' to deliberately enter it */
You("%s from the pit.", Flying ? "fly" : "climb"); You("%s from the pit.", Flying ? "fly" : "climb");
u.utrap = 0; reset_utrap(FALSE);
fill_pit(u.ux, u.uy); fill_pit(u.ux, u.uy);
vision_full_recalc = 1; /* vision limits change */ vision_full_recalc = 1; /* vision limits change */
} else if (!(--u.utrap)) { } else if (!(--u.utrap)) {
reset_utrap(FALSE);
You("%s to the edge of the pit.", You("%s to the edge of the pit.",
(Sokoban && Levitation) (Sokoban && Levitation)
? "struggle against the air currents and float" ? "struggle against the air currents and float"
@@ -3887,7 +3959,7 @@ boolean bury_it;
} }
newsym(ttmp->tx, ttmp->ty); newsym(ttmp->tx, ttmp->ty);
if (u.utrap && ttmp->tx == u.ux && ttmp->ty == u.uy) if (u.utrap && ttmp->tx == u.ux && ttmp->ty == u.uy)
u.utrap = 0; reset_utrap(TRUE);
deltrap(ttmp); deltrap(ttmp);
} }
@@ -3918,7 +3990,7 @@ struct trap *ttmp;
there are objects covering this trap */ there are objects covering this trap */
ttmp->tseen = 0; /* hack for check_here() */ ttmp->tseen = 0; /* hack for check_here() */
/* trigger the trap */ /* trigger the trap */
iflags.failing_untrap++; /* spoteffects() -> dotrap(,FORCETRAP) */ iflags.failing_untrap++; /* spoteffects() -> dotrap(,FAILEDUNTRAP) */
spoteffects(TRUE); /* pickup() + dotrap() */ spoteffects(TRUE); /* pickup() + dotrap() */
iflags.failing_untrap--; iflags.failing_untrap--;
/* this should no longer be necessary; before the failing_untrap /* this should no longer be necessary; before the failing_untrap
@@ -4003,7 +4075,8 @@ boolean force_failure;
pline("%s remains entangled.", Monnam(mtmp)); pline("%s remains entangled.", Monnam(mtmp));
} }
} else if (under_u) { } else if (under_u) {
dotrap(ttmp, 0); /* [don't need the iflags.failing_untrap hack here] */
dotrap(ttmp, FAILEDUNTRAP);
} else { } else {
move_into_trap(ttmp); move_into_trap(ttmp);
} }
@@ -4506,51 +4579,80 @@ struct monst *mon;
boolean *noticed; /* set to true iff hero notices the effect; */ boolean *noticed; /* set to true iff hero notices the effect; */
{ /* otherwise left with its previous value intact */ { /* otherwise left with its previous value intact */
struct trap *t; struct trap *t;
char buf[BUFSZ]; char buf[BUFSZ], whichbuf[20];
const char *trapdescr, *which; const char *trapdescr = 0, *which = 0;
boolean ishero = (mon == &youmonst); boolean ishero = (mon == &youmonst);
if (!mon) if (!mon)
return FALSE; return FALSE;
if (mon == u.usteed) if (mon == u.usteed)
ishero = TRUE; ishero = TRUE;
t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
/* if no trap here or it's not a holding trap, we're done */
if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
return FALSE;
trapdescr = defsyms[trap_to_defsym(t->ttyp)].explanation; t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
which = t->tseen ? the_your[t->madeby_u]
: index(vowels, *trapdescr) ? "an" : "a"; if (ishero && u.utrap) { /* all u.utraptype values are holding traps */
which = "";
switch (u.utraptype) {
case TT_LAVA:
trapdescr = "molten lava";
break;
case TT_INFLOOR:
/* solidified lava, so not "floor" even if within a room */
trapdescr = "ground";
break;
case TT_BURIEDBALL:
trapdescr = "your anchor";
break;
case TT_BEARTRAP:
case TT_PIT:
case TT_WEB:
trapdescr = 0; /* use defsyms[].explanation */
break;
default:
/* lint suppression in case 't' is unexpectedly Null
or u.utraptype has new value we don't know about yet */
trapdescr = "trap";
break;
}
} else {
/* if no trap here or it's not a holding trap, we're done */
if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
return FALSE;
}
if (!trapdescr)
trapdescr = defsyms[trap_to_defsym(t->ttyp)].explanation;
if (!which)
which = t->tseen ? the_your[t->madeby_u]
: index(vowels, *trapdescr) ? "an" : "a";
if (*which)
which = strcat(strcpy(whichbuf, which), " ");
if (ishero) { if (ishero) {
if (!u.utrap) if (!u.utrap)
return FALSE; return FALSE;
u.utrap = 0; /* released regardless of type */
*noticed = TRUE; *noticed = TRUE;
/* give message only if trap was the expected type */ if (u.usteed)
if (u.utraptype == TT_BEARTRAP || u.utraptype == TT_WEB) { Sprintf(buf, "%s is", noit_Monnam(u.usteed));
if (u.usteed) else
Sprintf(buf, "%s is", noit_Monnam(u.usteed)); Strcpy(buf, "You are");
else pline("%s released from %s%s.", buf, which, trapdescr);
Strcpy(buf, "You are"); reset_utrap(TRUE);
pline("%s released from %s %s.", buf, which, trapdescr);
}
} else { } else {
if (!mon->mtrapped) if (!mon->mtrapped)
return FALSE; return FALSE;
mon->mtrapped = 0; mon->mtrapped = 0;
if (canspotmon(mon)) { if (canspotmon(mon)) {
*noticed = TRUE; *noticed = TRUE;
pline("%s is released from %s %s.", Monnam(mon), which, pline("%s is released from %s%s.", Monnam(mon), which,
trapdescr); trapdescr);
} else if (cansee(t->tx, t->ty) && t->tseen) { } else if (cansee(t->tx, t->ty) && t->tseen) {
*noticed = TRUE; *noticed = TRUE;
if (t->ttyp == WEB) if (t->ttyp == WEB)
pline("%s is released from %s %s.", Something, which, pline("%s is released from %s%s.", Something, which,
trapdescr); trapdescr);
else /* BEAR_TRAP */ else /* BEAR_TRAP */
pline("%s %s opens.", upstart(strcpy(buf, which)), trapdescr); pline("%s%s opens.", upstart(strcpy(buf, which)), trapdescr);
} }
/* might pacify monster if adjacent */ /* might pacify monster if adjacent */
if (rn2(2) && distu(mon->mx, mon->my) <= 2) if (rn2(2) && distu(mon->mx, mon->my) <= 2)
@@ -5002,8 +5104,8 @@ register struct trap *ttmp;
register struct monst *mtmp; register struct monst *mtmp;
if (ttmp->tx == u.ux && ttmp->ty == u.uy) { if (ttmp->tx == u.ux && ttmp->ty == u.uy) {
u.utrap = 0; if (u.utraptype != TT_BURIEDBALL)
u.utraptype = 0; reset_utrap(TRUE);
} else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) { } else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
mtmp->mtrapped = 0; mtmp->mtrapped = 0;
} }
@@ -5211,12 +5313,11 @@ lava_effects()
boil_away = !Fire_resistance; boil_away = !Fire_resistance;
/* if not fire resistant, sink_into_lava() will quickly be fatal; /* if not fire resistant, sink_into_lava() will quickly be fatal;
hero needs to escape immediately */ hero needs to escape immediately */
u.utrap = rn1(4, 4) + ((boil_away ? 2 : rn1(4, 12)) << 8); set_utrap((unsigned) (rn1(4, 4) + ((boil_away ? 2 : rn1(4, 12)) << 8)),
u.utraptype = TT_LAVA; TT_LAVA);
You("sink into the %s%s!", hliquid("lava"), You("sink into the %s%s!", hliquid("lava"),
!boil_away !boil_away ? ", but it only burns slightly"
? ", but it only burns slightly" : " and are about to be immolated");
: " and are about to be immolated");
if (u.uhp > 1) if (u.uhp > 1)
losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer, losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer,
KILLED_BY); /* lava damage */ KILLED_BY); /* lava damage */
@@ -5238,7 +5339,7 @@ sink_into_lava()
if (!u.utrap || u.utraptype != TT_LAVA) { if (!u.utrap || u.utraptype != TT_LAVA) {
; /* do nothing; this shouldn't happen */ ; /* do nothing; this shouldn't happen */
} else if (!is_lava(u.ux, u.uy)) { } else if (!is_lava(u.ux, u.uy)) {
u.utrap = 0; /* this shouldn't happen either */ reset_utrap(FALSE); /* this shouldn't happen either */
} else if (!u.uinvulnerable) { } else if (!u.uinvulnerable) {
/* ordinarily we'd have to be fire resistant to survive long /* ordinarily we'd have to be fire resistant to survive long
enough to become stuck in lava, but it can happen without enough to become stuck in lava, but it can happen without
@@ -5255,8 +5356,10 @@ sink_into_lava()
burn_away_slime(); /* add insult to injury? */ burn_away_slime(); /* add insult to injury? */
done(DISSOLVED); done(DISSOLVED);
/* can only get here via life-saving; try to get away from lava */ /* can only get here via life-saving; try to get away from lava */
u.utrap = 0; reset_utrap(TRUE);
(void) safe_teleds(TRUE); /* levitation or flight have become unblocked, otherwise Tport */
if (!Levitation && !Flying)
(void) safe_teleds(TRUE);
} else if (!u.umoved) { } else if (!u.umoved) {
/* can't fully turn into slime while in lava, but might not /* can't fully turn into slime while in lava, but might not
have it be burned away until you've come awfully close */ have it be burned away until you've come awfully close */
+1 -1
View File
@@ -57,7 +57,7 @@ char *buf;
Sprintf(eos(buf), " ("); Sprintf(eos(buf), " (");
#if defined(RUNTIME_PORT_ID) #if defined(RUNTIME_PORT_ID)
tmp = get_port_id(tmpbuf); tmp = get_port_id(tmpbuf);
if (tmp) if (tmp)
Sprintf(eos(buf), "%s%s", c++ ? "," : "", tmp); Sprintf(eos(buf), "%s%s", c++ ? "," : "", tmp);
#endif #endif
+2 -3
View File
@@ -4431,11 +4431,10 @@ short exploding_wand_typ;
vision_full_recalc = 1; vision_full_recalc = 1;
} else if (u.utrap && u.utraptype == TT_LAVA) { } else if (u.utrap && u.utraptype == TT_LAVA) {
if (Passes_walls) { if (Passes_walls) {
u.utrap = 0;
You("pass through the now-solid rock."); You("pass through the now-solid rock.");
reset_utrap(TRUE);
} else { } else {
u.utrap = rn1(50, 20); set_utrap(rn1(50, 20), TT_INFLOOR);
u.utraptype = TT_INFLOOR;
You("are firmly stuck in the cooling rock."); You("are firmly stuck in the cooling rock.");
} }
} }
+47 -44
View File
@@ -3,13 +3,15 @@
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* /*
* This source file is compiled twice: * This source file is compiled twice:
* once without TILETEXT defined to make tilemap.{o,obj}, * once without TILETEXT defined to make tilemap.{o,obj},
* then again with it defined to produce tiletxt.{o,obj}. * then again with it defined to produce tiletxt.{o,obj}.
*/ */
#include "hack.h" #include "hack.h"
#define Fprintf (void) fprintf
const char *FDECL(tilename, (int, int)); const char *FDECL(tilename, (int, int));
void NDECL(init_tilemap); void NDECL(init_tilemap);
void FDECL(process_substitutions, (FILE *)); void FDECL(process_substitutions, (FILE *));
@@ -40,7 +42,7 @@ struct conditionals {
int sequence, predecessor; int sequence, predecessor;
const char *name; const char *name;
} conditionals[] = { } conditionals[] = {
#ifndef CHARON /* not supported yet */ #ifndef CHARON /* not supported */
{ MON_GLYPH, PM_HELL_HOUND, "Cerberus" }, { MON_GLYPH, PM_HELL_HOUND, "Cerberus" },
#endif #endif
/* commented out in monst.c at present */ /* commented out in monst.c at present */
@@ -68,7 +70,8 @@ struct conditionals {
* don't know what a slime mold should look like when renamed anyway * don't know what a slime mold should look like when renamed anyway
*/ */
#ifndef MAIL #ifndef MAIL
{ OBJ_GLYPH, SCR_STINKING_CLOUD + EXTRA_SCROLL_DESCR_COUNT, "stamped / mail" }, { OBJ_GLYPH, SCR_STINKING_CLOUD + EXTRA_SCROLL_DESCR_COUNT,
"stamped / mail" },
#endif #endif
{ 0, 0, 0 } { 0, 0, 0 }
}; };
@@ -394,19 +397,20 @@ init_tilemap()
#endif #endif
} }
const char *prolog[] = { "", "", "void", "substitute_tiles(plev)", const char *prolog[] = { "", "void", "substitute_tiles(plev)",
"d_level *plev;", "{", "\tint i;", "" }; "d_level *plev;", "{", " int i;", "" };
const char *epilog[] = { "}" }; const char *epilog[] = { " return;", "}" };
/* write out the substitutions in an easily-used form. */ /* write out the substitutions in an easily-used form. */
void void
process_substitutions(ofp) process_substitutions(ofp)
FILE *ofp; FILE *ofp;
{ {
static const char Dent[] = " "; /* 4 space indentation */
int i, j, k, span, start; int i, j, k, span, start;
fprintf(ofp, "\n\n"); Fprintf(ofp, "\n");
j = 0; /* unnecessary */ j = 0; /* unnecessary */
span = -1; span = -1;
@@ -415,16 +419,16 @@ FILE *ofp;
|| substitutes[i].last_glyph != substitutes[j].last_glyph) { || substitutes[i].last_glyph != substitutes[j].last_glyph) {
j = i; j = i;
span++; span++;
fprintf(ofp, "short std_tiles%d[] = { ", span); Fprintf(ofp, "short std_tiles%d[] = { ", span);
for (k = substitutes[i].first_glyph; for (k = substitutes[i].first_glyph;
k < substitutes[i].last_glyph; k++) k < substitutes[i].last_glyph; k++)
fprintf(ofp, "%d, ", tilemap[k]); Fprintf(ofp, "%d, ", tilemap[k]);
fprintf(ofp, "%d };\n", tilemap[substitutes[i].last_glyph]); Fprintf(ofp, "%d };\n", tilemap[substitutes[i].last_glyph]);
} }
} }
for (i = 0; i < SIZE(prolog); i++) { for (i = 0; i < SIZE(prolog); i++) {
fprintf(ofp, "%s\n", prolog[i]); Fprintf(ofp, "%s\n", prolog[i]);
} }
j = -1; j = -1;
span = -1; span = -1;
@@ -433,43 +437,41 @@ FILE *ofp;
if (i == 0 || substitutes[i].first_glyph != substitutes[j].first_glyph if (i == 0 || substitutes[i].first_glyph != substitutes[j].first_glyph
|| substitutes[i].last_glyph != substitutes[j].last_glyph) { || substitutes[i].last_glyph != substitutes[j].last_glyph) {
if (i != 0) { /* finish previous span */ if (i != 0) { /* finish previous span */
fprintf(ofp, "\t} else {\n"); Fprintf(ofp, "%s} else {\n", Dent);
fprintf(ofp, "\t\tfor (i = %d; i <= %d; i++)\n", Fprintf(ofp, "%s%sfor (i = %d; i <= %d; i++)\n", Dent, Dent,
substitutes[j].first_glyph, substitutes[j].first_glyph, substitutes[j].last_glyph);
substitutes[j].last_glyph); Fprintf(ofp, "%s%s%sglyph2tile[i] = std_tiles%d[i - %d];\n",
fprintf(ofp, "\t\t\tglyph2tile[i] = std_tiles%d[i - %d];\n", Dent, Dent, Dent, span, substitutes[j].first_glyph);
span, substitutes[j].first_glyph); Fprintf(ofp, "%s}\n\n", Dent);
fprintf(ofp, "\t}\n\n");
} }
j = i; j = i;
span++; span++;
} }
if (i != j) Fprintf(ofp, "%s%sif (%s) {\n", Dent, (i == j) ? "" : "} else ",
fprintf(ofp, "\t} else "); substitutes[i].level_test);
fprintf(ofp, "\tif (%s) {\n", substitutes[i].level_test); Fprintf(ofp, "%s%sfor (i = %d; i <= %d; i++)\n", Dent, Dent,
fprintf(ofp, "\t\tfor (i = %d; i <= %d; i++)\n",
substitutes[i].first_glyph, substitutes[i].last_glyph); substitutes[i].first_glyph, substitutes[i].last_glyph);
fprintf(ofp, "\t\t\tglyph2tile[i] = %d + i - %d;\n", start, Fprintf(ofp, "%s%s%sglyph2tile[i] = %d + i - %d;\n",
substitutes[i].first_glyph); Dent, Dent, Dent, start, substitutes[i].first_glyph);
start += substitutes[i].last_glyph - substitutes[i].first_glyph + 1; start += substitutes[i].last_glyph - substitutes[i].first_glyph + 1;
} }
/* finish last span */ /* finish last span */
fprintf(ofp, "\t} else {\n"); Fprintf(ofp, "%s} else {\n", Dent);
fprintf(ofp, "\t\tfor (i = %d; i <= %d; i++)\n", Fprintf(ofp, "%s%sfor (i = %d; i <= %d; i++)\n", Dent, Dent,
substitutes[j].first_glyph, substitutes[j].last_glyph); substitutes[j].first_glyph, substitutes[j].last_glyph);
fprintf(ofp, "\t\t\tglyph2tile[i] = std_tiles%d[i - %d];\n", span, Fprintf(ofp, "%s%s%sglyph2tile[i] = std_tiles%d[i - %d];\n",
substitutes[j].first_glyph); Dent, Dent, Dent, span, substitutes[j].first_glyph);
fprintf(ofp, "\t}\n\n"); Fprintf(ofp, "%s}\n", Dent);
for (i = 0; i < SIZE(epilog); i++) { for (i = 0; i < SIZE(epilog); i++) {
fprintf(ofp, "%s\n", epilog[i]); Fprintf(ofp, "%s\n", epilog[i]);
} }
lastothtile = start - 1; lastothtile = start - 1;
#ifdef STATUES_LOOK_LIKE_MONSTERS #ifdef STATUES_LOOK_LIKE_MONSTERS
start = laststatuetile + 1; start = laststatuetile + 1;
#endif #endif
fprintf(ofp, "\nint total_tiles_used = %d;\n", start); Fprintf(ofp, "\nint total_tiles_used = %d;\n", start);
} }
int int
@@ -489,27 +491,27 @@ main()
perror(filename); perror(filename);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
fprintf(ofp, Fprintf(ofp,
"/* This file is automatically generated. Do not edit. */\n"); "/* This file is automatically generated. Do not edit. */\n");
fprintf(ofp, "\n#include \"hack.h\"\n\n"); Fprintf(ofp, "\n#include \"hack.h\"\n");
fprintf(ofp, "short glyph2tile[MAX_GLYPH] = {\n"); Fprintf(ofp, "\nshort glyph2tile[MAX_GLYPH] = {\n");
for (i = 0; i < MAX_GLYPH; i++) { for (i = 0; i < MAX_GLYPH; i++) {
fprintf(ofp, "%2d,%c", tilemap[i], (i % 12) ? ' ' : '\n'); Fprintf(ofp, "%2d,%c", tilemap[i], (i % 12) ? ' ' : '\n');
} }
fprintf(ofp, "%s};\n", (i % 12) ? "\n" : ""); Fprintf(ofp, "\n};\n");
process_substitutions(ofp); process_substitutions(ofp);
fprintf(ofp, "\n#define MAXMONTILE %d\n", lastmontile); Fprintf(ofp, "\n#define MAXMONTILE %d\n", lastmontile);
fprintf(ofp, "#define MAXOBJTILE %d\n", lastobjtile); Fprintf(ofp, "#define MAXOBJTILE %d\n", lastobjtile);
fprintf(ofp, "#define MAXOTHTILE %d\n", lastothtile); Fprintf(ofp, "#define MAXOTHTILE %d\n", lastothtile);
#ifdef STATUES_LOOK_LIKE_MONSTERS #ifdef STATUES_LOOK_LIKE_MONSTERS
fprintf(ofp, "/* #define MAXSTATUETILE %d */\n", laststatuetile); Fprintf(ofp, "/* #define MAXSTATUETILE %d */\n", laststatuetile);
#endif #endif
fprintf(ofp, "\n/*tile.c*/\n"); Fprintf(ofp, "\n/*tile.c*/\n");
fclose(ofp); (void) fclose(ofp);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
/*NOTREACHED*/ /*NOTREACHED*/
return 0; return 0;
@@ -634,3 +636,4 @@ const char *encountered, *expected;
return FALSE; return FALSE;
} }
/*tilemap.c*/