melting ice timeout issues

Reported directly to devteam by entrez via email:
>
> I noticed some potential issues with (melting) ice:
>
>   * Digging down into ice, or setting a land mine on the ice and
>   triggering it, doesn't remove the melt_ice timeout, so it can result
>   in a sequence like dig down -> pit fills with water -> freeze water
>   -> freezing water tries to set melt_ice timeout -> duplicate timeout
>   impossible.  Or if you don't freeze the water again, melt_ice will
>   run on a non-ice surface, which might at least produce strange
>   messages.
>
>   * Setting a land mine on ice: melting ice doesn't do anything with
>   the trap, so there is still a land mine which you can trigger by
>   flying over the water (the land mine's trigger is also still
>   described as being 'in a pile of soil', despite being underwater at
>   this point).  Similar thing happens with bear traps.
>
>   * Not really related to _melting_ ice, but an exploding land mine
>   doesn't reset the typ from ICE to FLOOR (like normal digging does),
>   so it will result in a square with a pit that is also an ice square,
>   where the ice can melt under the pit and produce a combination
>   pit/moat.  If you then freeze the moat, the pit reappears on top of
>   the ice.
This commit is contained in:
nhmall
2021-10-16 22:22:33 -04:00
parent 91b4e4570d
commit 17165e3b92
7 changed files with 94 additions and 42 deletions
+33 -40
View File
@@ -767,9 +767,9 @@ dighole(boolean pit_only, boolean by_magic, coord *cc)
register struct trap *ttmp;
struct rm *lev;
struct obj *boulder_here;
schar typ;
schar typ, old_typ;
xchar dig_x, dig_y;
boolean nohole;
boolean nohole, retval = TRUE;
if (!cc) {
dig_x = u.ux;
@@ -784,10 +784,11 @@ dighole(boolean pit_only, boolean by_magic, coord *cc)
ttmp = t_at(dig_x, dig_y);
lev = &levl[dig_x][dig_y];
nohole = (!Can_dig_down(&u.uz) && !lev->candig);
old_typ = lev->typ;
if ((ttmp && (ttmp->ttyp == MAGIC_PORTAL
|| ttmp->ttyp == VIBRATING_SQUARE || nohole))
|| (IS_ROCK(lev->typ) && lev->typ != SDOOR
|| (IS_ROCK(old_typ) && old_typ != SDOOR
&& (lev->wall_info & W_NONDIGGABLE) != 0)) {
pline_The("%s %shere is too hard to dig in.", surface(dig_x, dig_y),
(dig_x != u.ux || dig_y != u.uy) ? "t" : "");
@@ -797,20 +798,19 @@ dighole(boolean pit_only, boolean by_magic, coord *cc)
hliquid(is_lava(dig_x, dig_y) ? "lava" : "water"));
wake_nearby(); /* splashing */
} else if (lev->typ == DRAWBRIDGE_DOWN
} else if (old_typ == DRAWBRIDGE_DOWN
|| (is_drawbridge_wall(dig_x, dig_y) >= 0)) {
/* drawbridge_down is the platform crossing the moat when the
bridge is extended; drawbridge_wall is the open "doorway" or
closed "door" where the portcullis/mechanism is located */
if (pit_only) {
pline_The("drawbridge seems too hard to dig through.");
return FALSE;
retval = FALSE;
} else {
int x = dig_x, y = dig_y;
/* if under the portcullis, the bridge is adjacent */
(void) find_drawbridge(&x, &y);
destroy_drawbridge(x, y);
return TRUE;
}
} else if ((boulder_here = sobj_at(BOULDER, dig_x, dig_y)) != 0) {
@@ -828,13 +828,10 @@ dighole(boolean pit_only, boolean by_magic, coord *cc)
(void) delfloortrap(ttmp);
}
delobj(boulder_here);
return TRUE;
} else if (IS_GRAVE(lev->typ)) {
} else if (IS_GRAVE(old_typ)) {
digactualhole(dig_x, dig_y, BY_YOU, PIT);
dig_up_grave(cc);
return TRUE;
} else if (lev->typ == DRAWBRIDGE_UP) {
} else if (old_typ == DRAWBRIDGE_UP) {
/* must be floor or ice, other cases handled above */
/* dig "pit" and let fluid flow in (if possible) */
typ = fillholetyp(dig_x, dig_y, FALSE);
@@ -847,20 +844,19 @@ dighole(boolean pit_only, boolean by_magic, coord *cc)
pline_The("%s %shere is too hard to dig in.",
surface(dig_x, dig_y),
(dig_x != u.ux || dig_y != u.uy) ? "t" : "");
return FALSE;
retval = FALSE;
} else {
lev->drawbridgemask &= ~DB_UNDER;
lev->drawbridgemask |= (typ == LAVAPOOL) ? DB_LAVA : DB_MOAT;
liquid_flow(dig_x, dig_y, typ, ttmp,
"As you dig, the hole fills with %s!");
}
lev->drawbridgemask &= ~DB_UNDER;
lev->drawbridgemask |= (typ == LAVAPOOL) ? DB_LAVA : DB_MOAT;
liquid_flow(dig_x, dig_y, typ, ttmp,
"As you dig, the hole fills with %s!");
return TRUE;
/* the following two are here for the wand of digging */
} else if (IS_THRONE(lev->typ)) {
} else if (IS_THRONE(old_typ)) {
pline_The("throne is too hard to break apart.");
} else if (IS_ALTAR(lev->typ)) {
} else if (IS_ALTAR(old_typ)) {
pline_The("altar is too hard to break apart.");
} else {
@@ -873,28 +869,25 @@ dighole(boolean pit_only, boolean by_magic, coord *cc)
liquid_flow(dig_x, dig_y, typ, ttmp,
"As you dig, the hole fills with %s!");
}
return TRUE;
} else {
/* magical digging disarms settable traps */
if (by_magic && ttmp
&& (ttmp->ttyp == LANDMINE || ttmp->ttyp == BEAR_TRAP)) {
int otyp = (ttmp->ttyp == LANDMINE) ? LAND_MINE : BEARTRAP;
/* convert trap into buried object (deletes trap) */
cnv_trap_obj(otyp, 1, ttmp, TRUE);
}
/* finally we get to make a hole */
if (nohole || pit_only)
digactualhole(dig_x, dig_y, BY_YOU, PIT);
else
digactualhole(dig_x, dig_y, BY_YOU, HOLE);
}
/* magical digging disarms settable traps */
if (by_magic && ttmp
&& (ttmp->ttyp == LANDMINE || ttmp->ttyp == BEAR_TRAP)) {
int otyp = (ttmp->ttyp == LANDMINE) ? LAND_MINE : BEARTRAP;
/* convert trap into buried object (deletes trap) */
cnv_trap_obj(otyp, 1, ttmp, TRUE);
}
/* finally we get to make a hole */
if (nohole || pit_only)
digactualhole(dig_x, dig_y, BY_YOU, PIT);
else
digactualhole(dig_x, dig_y, BY_YOU, HOLE);
return TRUE;
}
return FALSE;
spot_checks(dig_x, dig_y, old_typ);
return retval;
}
static void