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

@@ -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;