digging in ice

If the spot in front of a closed drawbridge was ICE, digging there
had issues....
This commit is contained in:
PatR
2024-11-27 08:41:55 -08:00
parent c1c74db90c
commit 9c0e47785a
5 changed files with 64 additions and 33 deletions

View File

@@ -1481,6 +1481,8 @@ if eating a tin's contents caused the hero to choke to death or turn to stone,
when hero who is poly'd into metallivore form eats a tin, bypass "smells like
<monster>" feedback and the "Eat it?" prompt; just eat the contents
along with the tin without asking
digging in ice was handled inconsistently, particularly if done at the span
spot in front of closed drawbridge
Fixes to 3.7.0-x General Problems Exposed Via git Repository

View File

@@ -859,8 +859,9 @@ liquid_flow(
}
if (ttmp)
(void) delfloortrap(ttmp); /* will untrap monster is one is here */
(void) delfloortrap(ttmp); /* will untrap monster if one is here */
/* if any objects were frozen here, they're released now */
obj_ice_effects(x, y, TRUE);
unearth_objs(x, y);
if (fillmsg)
@@ -2081,7 +2082,8 @@ bury_objs(int x, int y)
}
}
/* move objects from buriedobjlist to fobj/nexthere lists */
/* move objects from buriedobjlist to fobj/nexthere lists; if caller
converts terrain from ice to something, it should call obj_ice_effects() */
void
unearth_objs(int x, int y)
{

View File

@@ -48,9 +48,9 @@ dodrop(void)
*/
boolean
boulder_hits_pool(
struct obj *otmp,
coordxy rx, coordxy ry,
boolean pushing)
struct obj *otmp, /* the object falling into a pool or water or lava */
coordxy rx, coordxy ry, /* coordinates of the pool */
boolean pushing) /* for a boulder, whether or not it is being pushed */
{
if (!otmp || otmp->otyp != BOULDER) {
impossible("Not a boulder?");
@@ -138,8 +138,9 @@ boulder_hits_pool(
losehp(Maybe_Half_Phys(dmg), /* lava damage */
"molten lava", KILLED_BY);
} else if (!fills_up && flags.verbose
&& (pushing ? !Blind : cansee(rx, ry)))
&& (pushing ? !Blind : cansee(rx, ry))) {
pline("It sinks without a trace!");
}
}
/* boulder is now gone */
@@ -157,7 +158,10 @@ boulder_hits_pool(
* away.
*/
boolean
flooreffects(struct obj *obj, coordxy x, coordxy y, const char *verb)
flooreffects(
struct obj *obj, /* the object landing on the floor */
coordxy x, coordxy y, /* map coordinates for spot where it is landing */
const char *verb) /* "fall", "drop", "land", &c */
{
struct trap *t;
struct monst *mtmp;
@@ -236,12 +240,10 @@ flooreffects(struct obj *obj, coordxy x, coordxy y, const char *verb)
You_hear("a CRASH! beneath you.");
} else if (!Blind && cansee(x, y)) {
pline_The("boulder %s%s.",
(ttyp == TRAPDOOR && !tseen)
? "triggers and " : "",
(ttyp == TRAPDOOR)
? "plugs a trap door"
: (ttyp == HOLE) ? "plugs a hole"
: "fills a pit");
(ttyp == TRAPDOOR && !tseen) ? "triggers and " : "",
(ttyp == TRAPDOOR) ? "plugs a trap door"
: (ttyp == HOLE) ? "plugs a hole"
: "fills a pit");
} else {
Soundeffect(se_boulder_drop, 100);
You_hear("a boulder %s.", verb);
@@ -252,10 +254,13 @@ flooreffects(struct obj *obj, coordxy x, coordxy y, const char *verb)
* || mondied) -> mondead -> m_detach -> fill_pit.
*/
deletedwithboulder:
if ((t = t_at(x, y)) != 0)
deltrap(t);
if (u.utrap && u_at(x, y))
reset_utrap(FALSE);
/* creating a pit in ice results in that ice being turned into
floor so we shouldn't need any special ice handing here */
if ((t = t_at(x, y)) != 0) {
(void) delfloortrap(t);
if (u.utrap && u_at(x, y))
reset_utrap(FALSE);
}
useupf(obj, 1L);
bury_objs(x, y);
newsym(x, y);

View File

@@ -78,19 +78,22 @@ set_levltyp(coordxy x, coordxy y, schar newtyp)
if (isok(x, y) && newtyp >= STONE && newtyp < MAX_TYPE) {
if (CAN_OVERWRITE_TERRAIN(levl[x][y].typ)) {
schar oldtyp = levl[x][y].typ;
boolean was_ice = (levl[x][y].typ == ICE);
/* typ==ICE || (typ==DRAWBRIDGE_UP && drawbridgemask==DB_ICE) */
boolean was_ice = is_ice(x, y);
levl[x][y].typ = newtyp;
/* TODO?
* if oldtyp used flags or horizontal differently from
* from the way newtyp will use them, clear them.
* the way newtyp will use them, clear them.
*/
if (IS_LAVA(newtyp))
if (IS_LAVA(newtyp)) /* [what about IS_LAVA(oldtyp)=>.lit = 0?] */
levl[x][y].lit = 1;
if (was_ice && newtyp != ICE)
if (was_ice && newtyp != ICE) {
/* frozen corpses resume rotting, no more ice to melt away */
obj_ice_effects(x, y, TRUE);
spot_stop_timers(x, y, MELT_ICE_AWAY);
}
if ((IS_FOUNTAIN(oldtyp) != IS_FOUNTAIN(newtyp))
|| (IS_SINK(oldtyp) != IS_SINK(newtyp)))
count_level_features(); /* level.flags.nfountains,nsinks */

View File

@@ -455,7 +455,7 @@ struct trap *
maketrap(coordxy x, coordxy y, int typ)
{
static union vlaunchinfo zero_vl;
boolean oldplace;
boolean oldplace, was_ice, clear_flags;
struct trap *ttmp;
struct rm *lev = &levl[x][y];
@@ -473,10 +473,10 @@ maketrap(coordxy x, coordxy y, int typ)
|| (u.utraptype == TT_LAVA && !is_lava(x, y))))
reset_utrap(FALSE);
/* old <tx,ty> remain valid */
} else if (!CAN_OVERWRITE_TERRAIN(lev->typ)
|| (IS_FURNITURE(lev->typ)
&& (typ != PIT && typ != HOLE))
} else if (!CAN_OVERWRITE_TERRAIN(lev->typ) /* stairs */
|| is_pool_or_lava(x, y)
|| (IS_FURNITURE(lev->typ) && (typ != PIT && typ != HOLE))
|| (lev->typ == DRAWBRIDGE_UP && typ == MAGIC_PORTAL)
|| (IS_AIR(lev->typ) && typ != MAGIC_PORTAL)
|| (typ == LEVEL_TELEP && single_level_branch(&u.uz))) {
/* no trap on top of furniture (caller usually screens the
@@ -522,22 +522,41 @@ maketrap(coordxy x, coordxy y, int typ)
&& (is_hole(typ) || IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
add_damage(x, y, /* schedule repair */
((IS_DOOR(lev->typ) || IS_WALL(lev->typ))
&& !svc.context.mon_moving)
? SHOP_HOLE_COST
: 0L);
lev->doormask = 0; /* subsumes altarmask, icedpool... */
if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */
&& !svc.context.mon_moving) ? SHOP_HOLE_COST : 0L);
clear_flags = TRUE; /* assume lev->flags needs to be reset */
/* DRAWBRIDGE_UP passes the IS_ROOM() test so check it first;
it also needs to retain lev->drawbridgemask */
if (lev->typ == DRAWBRIDGE_UP) {
/* bridge is closed and we're putting a hole or pit at the span
spot; this trap will be deleted if/when the bridge is opened;
terrain becomes room floor even if it was moat, lava, or ice */
clear_flags = FALSE; /* keep lev->drawbridgemask */
was_ice = (lev->drawbridgemask & DB_UNDER) == DB_ICE;
lev->drawbridgemask &= ~DB_UNDER;
lev->drawbridgemask |= DB_FLOOR;
if (was_ice) {
/* subset of set_levltyp() after changing ice to floor;
frozen corpses resume rotting, no more ice to melt away */
obj_ice_effects(x, y, TRUE);
spot_stop_timers(x, y, MELT_ICE_AWAY);
}
} else if (IS_ROOM(lev->typ)) {
(void) set_levltyp(x, y, ROOM);
/*
* some cases which can happen when digging
* down while phazing thru solid areas
*/
else if (lev->typ == STONE || lev->typ == SCORR)
} else if (lev->typ == STONE || lev->typ == SCORR) {
(void) set_levltyp(x, y, CORR);
else if (IS_WALL(lev->typ) || lev->typ == SDOOR)
} else if (IS_WALL(lev->typ) || lev->typ == SDOOR) {
(void) set_levltyp(x, y, svl.level.flags.is_maze_lev ? ROOM
: svl.level.flags.is_cavernous_lev ? CORR
: DOOR);
}
if (clear_flags)
lev->flags = 0; /* set_levltyp doesn't take care of this [yet?] */
unearth_objs(x, y);
break;