fix #K105 - earthquake chasms

Drum of earthquake can try to destroy fountains, thrones, altars,
sinks, and graves but it wouldn't do so because maketrap() had been
changed to prevent clobbering furniture with traps.  So you might get
"the throne falls into a chasm" but the throne would remain intact.

Change furniture to be floor before trying to create a pit.  The gist
of the patch is the 'if' after 'do_pit:' and also some changes to the
revealing of hidden monsters.  The rest is reformatting.
This commit is contained in:
PatR
2020-01-05 01:20:15 -08:00
parent 4b2ba5acc7
commit 5292ab5de0
2 changed files with 173 additions and 161 deletions
+4 -1
View File
@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.49 $ $NHDT-Date: 1578190894 2020/01/05 02:21:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.50 $ $NHDT-Date: 1578216006 2020/01/05 09:20:06 $
General Fixes and Modified Features General Fixes and Modified Features
----------------------------------- -----------------------------------
@@ -28,6 +28,9 @@ monster wielding Stormbringer or healer's Staff against another monster would
heal the hero instead of the wielding monster when draining life heal the hero instead of the wielding monster when draining life
change twoweapon feedback from "not a weapon" to "not a suitable weapon" change twoweapon feedback from "not a weapon" to "not a suitable weapon"
don't allow twoweapon combat if either weapon is a bow, crossbow, or sling don't allow twoweapon combat if either weapon is a bow, crossbow, or sling
drum of earthquake feedback reported various things (fountains, thrones, &c)
falling into a chasm but they remained intact because trap creation
had been changed to not clobber such things (so couldn't make pits)
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
+57 -48
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 music.c $NHDT-Date: 1573063606 2019/11/06 18:06:46 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.60 $ */ /* NetHack 3.6 music.c $NHDT-Date: 1578216006 2020/01/05 09:20:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.66 $ */
/* Copyright (c) 1989 by Jean-Christophe Collet */ /* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -224,16 +224,20 @@ static void
do_earthquake(force) do_earthquake(force)
int force; int force;
{ {
static const char into_a_chasm[] = " into a chasm";
register int x, y; register int x, y;
struct monst *mtmp; struct monst *mtmp;
struct obj *otmp; struct obj *otmp;
struct trap *chasm, *trap_at_u = t_at(u.ux, u.uy); struct trap *chasm, *trap_at_u = t_at(u.ux, u.uy);
int start_x, start_y, end_x, end_y; int start_x, start_y, end_x, end_y, amsk;
aligntyp algn;
schar filltype; schar filltype;
unsigned tu_pit = 0; unsigned tu_pit = 0;
if (trap_at_u) if (trap_at_u)
tu_pit = is_pit(trap_at_u->ttyp); tu_pit = is_pit(trap_at_u->ttyp);
if (force > 13) /* sanity precaution; maximum used is actually 10 */
force = 13;
start_x = u.ux - (force * 2); start_x = u.ux - (force * 2);
start_y = u.uy - (force * 2); start_y = u.uy - (force * 2);
end_x = u.ux + (force * 2); end_x = u.ux + (force * 2);
@@ -246,94 +250,101 @@ int force;
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) {
wakeup(mtmp, TRUE); /* peaceful monster will become hostile */ wakeup(mtmp, TRUE); /* peaceful monster will become hostile */
if (mtmp->mundetected && is_hider(mtmp->data)) { if (mtmp->mundetected) {
mtmp->mundetected = 0; mtmp->mundetected = 0;
newsym(x, y);
if (ceiling_hider(mtmp->data)) {
if (cansee(x, y)) if (cansee(x, y))
pline("%s is shaken loose from the ceiling!", pline("%s is shaken loose from the ceiling!",
Amonnam(mtmp)); Amonnam(mtmp));
else else if (!is_flyer(mtmp->data))
You_hear("a thumping sound."); You_hear("a thump.");
if (x == u.ux && y == u.uy)
You("easily dodge the falling %s.", mon_nam(mtmp));
newsym(x, y);
} }
} }
if (!rn2(14 - force)) if (M_AP_TYPE(mtmp) != M_AP_NOTHING
&& M_AP_TYPE(mtmp) != M_AP_MONSTER)
seemimic(mtmp);
}
if (rn2(14 - force))
continue;
switch (levl[x][y].typ) { switch (levl[x][y].typ) {
case FOUNTAIN: /* Make the fountain disappear */ case FOUNTAIN: /* make the fountain disappear */
if (cansee(x, y)) if (cansee(x, y))
pline_The("fountain falls into a chasm."); pline_The("fountain falls%s.", into_a_chasm);
goto do_pit; goto do_pit;
case SINK: case SINK:
if (cansee(x, y)) if (cansee(x, y))
pline_The("kitchen sink falls into a chasm."); pline_The("kitchen sink falls%s.", into_a_chasm);
goto do_pit; goto do_pit;
case ALTAR: case ALTAR:
if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)) if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz))
break; break;
/* no need to check for high altar here; we've just
excluded those */
amsk = altarmask_at(x, y);
algn = Amask2align(amsk & AM_MASK);
if (cansee(x, y)) if (cansee(x, y))
pline_The("altar falls into a chasm."); pline_The("%s altar falls%s.",
align_str(algn), into_a_chasm);
goto do_pit; goto do_pit;
case GRAVE: case GRAVE:
if (cansee(x, y)) if (cansee(x, y))
pline_The("headstone topples into a chasm."); pline_The("headstone topples%s.", into_a_chasm);
goto do_pit; goto do_pit;
case THRONE: case THRONE:
if (cansee(x, y)) if (cansee(x, y))
pline_The("throne falls into a chasm."); pline_The("throne falls%s.", into_a_chasm);
/*FALLTHRU*/ /*FALLTHRU*/
case ROOM: case ROOM:
case CORR: /* Try to make a pit */ case CORR: /* Try to make a pit */
do_pit: do_pit:
/* maketrap() won't replace furniture with a trap,
so remove the furniture first */
if (levl[x][y].typ != CORR) {
if (levl[x][y].typ != DOOR)
levl[x][y].typ = ROOM;
levl[x][y].flags = 0; /* clear doormask (D_NODOOR) or
* altarmask or looted throne */
levl[x][y].horizontal = 0; /* clear blessed fountain,
* disturbed grave */
}
chasm = maketrap(x, y, PIT); chasm = maketrap(x, y, PIT);
if (!chasm) if (!chasm)
break; /* no pit if portal at that location */ break; /* no pit if portal at that location */
chasm->tseen = 1; chasm->tseen = 1;
/* TODO: /* Let liquid flow into the newly created chasm.
* This ought to be split into a separate routine to Adjust corresponding code in apply.c for exploding
* reduce indentation and the consequent line-wraps. wand of digging if you alter this sequence. */
*/
levl[x][y].doormask = 0;
/*
* Let liquid flow into the newly created chasm.
* Adjust corresponding code in apply.c for
* exploding wand of digging if you alter this sequence.
*/
filltype = fillholetyp(x, y, FALSE); filltype = fillholetyp(x, y, FALSE);
if (filltype != ROOM) { if (filltype != ROOM) {
levl[x][y].typ = filltype; /* flags set via doormask */ levl[x][y].typ = filltype; /* flags set via doormask */
liquid_flow(x, y, filltype, chasm, (char *) 0); liquid_flow(x, y, filltype, chasm, (char *) 0);
} }
mtmp = m_at(x, y); mtmp = m_at(x, y); /* (redundant?) */
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);
(void) flooreffects(otmp, x, y, ""); (void) flooreffects(otmp, x, y, "");
break; break; /* from switch, not loop */
} }
/* We have to check whether monsters or player /* We have to check whether monsters or player
falls in a chasm... */ falls in a chasm... */
if (mtmp) { if (mtmp) {
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))
pline("%s falls into a chasm!", pline("%s falls into a chasm!", Monnam(mtmp));
Monnam(mtmp));
else if (humanoid(mtmp->data)) else if (humanoid(mtmp->data))
You_hear("a scream!"); You_hear("a scream!");
} }
@@ -348,11 +359,9 @@ int force;
} else { } else {
You("destroy %s!", You("destroy %s!",
mtmp->mtame mtmp->mtame
? x_monnam(mtmp, ARTICLE_THE, ? x_monnam(mtmp, ARTICLE_THE, "poor",
"poor",
has_mname(mtmp) has_mname(mtmp)
? SUPPRESS_SADDLE ? SUPPRESS_SADDLE : 0,
: 0,
FALSE) FALSE)
: mon_nam(mtmp)); : mon_nam(mtmp));
} }
@@ -371,14 +380,12 @@ int force;
Your("chain breaks!"); Your("chain breaks!");
reset_utrap(TRUE); reset_utrap(TRUE);
} }
if (Levitation || Flying if (Levitation || Flying || is_clinger(g.youmonst.data)) {
|| is_clinger(g.youmonst.data)) {
if (!tu_pit) { /* no pit here previously */ if (!tu_pit) { /* no pit here previously */
pline("A chasm opens up under you!"); pline("A chasm opens up under you!");
You("don't fall in!"); You("don't fall in!");
} }
} else if (!tu_pit || !u.utrap } else if (!tu_pit || !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 if there was */ not in it even if there was */
You("fall into a chasm!"); You("fall into a chasm!");
@@ -399,18 +406,20 @@ int force;
if (keepfooting) if (keepfooting)
exercise(A_DEX, TRUE); exercise(A_DEX, TRUE);
else else
selftouch( selftouch((Upolyd && (slithy(g.youmonst.data)
(Upolyd && (slithy(g.youmonst.data)
|| nolimbs(g.youmonst.data))) || nolimbs(g.youmonst.data)))
? "Shaken, you" ? "Shaken, you"
: "Falling down, you"); : "Falling down, you");
} }
} else } else {
newsym(x, y); newsym(x, y);
}
break; break;
case DOOR: /* Make the door collapse */ case DOOR: /* make the door collapse */
if (levl[x][y].doormask == D_NODOOR) if (levl[x][y].doormask == D_NODOOR)
goto do_pit; goto do_pit;
/* TODO: if door is trapped, the trap should explode;
forcing D_NODOOR just makes trap silently go away */
if (cansee(x, y)) if (cansee(x, y))
pline_The("door collapses."); pline_The("door collapses.");
if (*in_rooms(x, y, SHOPBASE)) if (*in_rooms(x, y, SHOPBASE))