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 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 <monster>" feedback and the "Eat it?" prompt; just eat the contents
along with the tin without asking 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 Fixes to 3.7.0-x General Problems Exposed Via git Repository

View File

@@ -859,8 +859,9 @@ liquid_flow(
} }
if (ttmp) 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 */ /* if any objects were frozen here, they're released now */
obj_ice_effects(x, y, TRUE);
unearth_objs(x, y); unearth_objs(x, y);
if (fillmsg) 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 void
unearth_objs(int x, int y) unearth_objs(int x, int y)
{ {

View File

@@ -48,9 +48,9 @@ dodrop(void)
*/ */
boolean boolean
boulder_hits_pool( boulder_hits_pool(
struct obj *otmp, struct obj *otmp, /* the object falling into a pool or water or lava */
coordxy rx, coordxy ry, coordxy rx, coordxy ry, /* coordinates of the pool */
boolean pushing) boolean pushing) /* for a boulder, whether or not it is being pushed */
{ {
if (!otmp || otmp->otyp != BOULDER) { if (!otmp || otmp->otyp != BOULDER) {
impossible("Not a boulder?"); impossible("Not a boulder?");
@@ -138,8 +138,9 @@ boulder_hits_pool(
losehp(Maybe_Half_Phys(dmg), /* lava damage */ losehp(Maybe_Half_Phys(dmg), /* lava damage */
"molten lava", KILLED_BY); "molten lava", KILLED_BY);
} else if (!fills_up && flags.verbose } else if (!fills_up && flags.verbose
&& (pushing ? !Blind : cansee(rx, ry))) && (pushing ? !Blind : cansee(rx, ry))) {
pline("It sinks without a trace!"); pline("It sinks without a trace!");
}
} }
/* boulder is now gone */ /* boulder is now gone */
@@ -157,7 +158,10 @@ boulder_hits_pool(
* away. * away.
*/ */
boolean 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 trap *t;
struct monst *mtmp; struct monst *mtmp;
@@ -236,12 +240,10 @@ flooreffects(struct obj *obj, coordxy x, coordxy y, const char *verb)
You_hear("a CRASH! beneath you."); You_hear("a CRASH! beneath you.");
} else if (!Blind && cansee(x, y)) { } else if (!Blind && cansee(x, y)) {
pline_The("boulder %s%s.", pline_The("boulder %s%s.",
(ttyp == TRAPDOOR && !tseen) (ttyp == TRAPDOOR && !tseen) ? "triggers and " : "",
? "triggers and " : "", (ttyp == TRAPDOOR) ? "plugs a trap door"
(ttyp == TRAPDOOR) : (ttyp == HOLE) ? "plugs a hole"
? "plugs a trap door" : "fills a pit");
: (ttyp == HOLE) ? "plugs a hole"
: "fills a pit");
} else { } else {
Soundeffect(se_boulder_drop, 100); Soundeffect(se_boulder_drop, 100);
You_hear("a boulder %s.", verb); 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. * || mondied) -> mondead -> m_detach -> fill_pit.
*/ */
deletedwithboulder: deletedwithboulder:
if ((t = t_at(x, y)) != 0) /* creating a pit in ice results in that ice being turned into
deltrap(t); floor so we shouldn't need any special ice handing here */
if (u.utrap && u_at(x, y)) if ((t = t_at(x, y)) != 0) {
reset_utrap(FALSE); (void) delfloortrap(t);
if (u.utrap && u_at(x, y))
reset_utrap(FALSE);
}
useupf(obj, 1L); useupf(obj, 1L);
bury_objs(x, y); bury_objs(x, y);
newsym(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 (isok(x, y) && newtyp >= STONE && newtyp < MAX_TYPE) {
if (CAN_OVERWRITE_TERRAIN(levl[x][y].typ)) { if (CAN_OVERWRITE_TERRAIN(levl[x][y].typ)) {
schar oldtyp = 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; levl[x][y].typ = newtyp;
/* TODO? /* TODO?
* if oldtyp used flags or horizontal differently from * 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; 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); spot_stop_timers(x, y, MELT_ICE_AWAY);
}
if ((IS_FOUNTAIN(oldtyp) != IS_FOUNTAIN(newtyp)) if ((IS_FOUNTAIN(oldtyp) != IS_FOUNTAIN(newtyp))
|| (IS_SINK(oldtyp) != IS_SINK(newtyp))) || (IS_SINK(oldtyp) != IS_SINK(newtyp)))
count_level_features(); /* level.flags.nfountains,nsinks */ count_level_features(); /* level.flags.nfountains,nsinks */

View File

@@ -455,7 +455,7 @@ struct trap *
maketrap(coordxy x, coordxy y, int typ) maketrap(coordxy x, coordxy y, int typ)
{ {
static union vlaunchinfo zero_vl; static union vlaunchinfo zero_vl;
boolean oldplace; boolean oldplace, was_ice, clear_flags;
struct trap *ttmp; struct trap *ttmp;
struct rm *lev = &levl[x][y]; 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)))) || (u.utraptype == TT_LAVA && !is_lava(x, y))))
reset_utrap(FALSE); reset_utrap(FALSE);
/* old <tx,ty> remain valid */ /* old <tx,ty> remain valid */
} else if (!CAN_OVERWRITE_TERRAIN(lev->typ) } else if (!CAN_OVERWRITE_TERRAIN(lev->typ) /* stairs */
|| (IS_FURNITURE(lev->typ)
&& (typ != PIT && typ != HOLE))
|| is_pool_or_lava(x, y) || 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) || (IS_AIR(lev->typ) && typ != MAGIC_PORTAL)
|| (typ == LEVEL_TELEP && single_level_branch(&u.uz))) { || (typ == LEVEL_TELEP && single_level_branch(&u.uz))) {
/* no trap on top of furniture (caller usually screens the /* 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))) && (is_hole(typ) || IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
add_damage(x, y, /* schedule repair */ add_damage(x, y, /* schedule repair */
((IS_DOOR(lev->typ) || IS_WALL(lev->typ)) ((IS_DOOR(lev->typ) || IS_WALL(lev->typ))
&& !svc.context.mon_moving) && !svc.context.mon_moving) ? SHOP_HOLE_COST : 0L);
? SHOP_HOLE_COST
: 0L); clear_flags = TRUE; /* assume lev->flags needs to be reset */
lev->doormask = 0; /* subsumes altarmask, icedpool... */ /* DRAWBRIDGE_UP passes the IS_ROOM() test so check it first;
if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */ 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); (void) set_levltyp(x, y, ROOM);
/* /*
* some cases which can happen when digging * some cases which can happen when digging
* down while phazing thru solid areas * 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); (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 (void) set_levltyp(x, y, svl.level.flags.is_maze_lev ? ROOM
: svl.level.flags.is_cavernous_lev ? CORR : svl.level.flags.is_cavernous_lev ? CORR
: DOOR); : DOOR);
}
if (clear_flags)
lev->flags = 0; /* set_levltyp doesn't take care of this [yet?] */
unearth_objs(x, y); unearth_objs(x, y);
break; break;