melting ice (trunk only)

add a new melt_ice_away timer for ice created via zapping
a wand/spell of cold.

Some follow-up adjustments to the length of time before
the ice melts may be necessary. Ideally, I'd like to
have it so that the shorter the length of time since
the ice was created, the lesser the chance that it will
melt out from under you.  Likewise, the longer it has
been, the more risky it will be to venture onto it.

At the moment, however, each spot of ice is just
getting a somewhat random time always greater
than 50, which is less than ideal.
This commit is contained in:
nethack.allison
2003-10-12 04:21:27 +00:00
parent f6425ee3c5
commit 6712fc1b04
6 changed files with 80 additions and 8 deletions

View File

@@ -1309,7 +1309,8 @@ static const ttable timeout_funcs[NUM_TIME_FUNCS] = {
TTAB(revive_mon, (timeout_proc)0, "revive_mon"),
TTAB(burn_object, cleanup_burn, "burn_object"),
TTAB(hatch_egg, (timeout_proc)0, "hatch_egg"),
TTAB(fig_transform, (timeout_proc)0, "fig_transform")
TTAB(fig_transform, (timeout_proc)0, "fig_transform"),
TTAB(melt_ice_away, (timeout_proc)0, "melt_ice_away")
};
#undef TTAB
@@ -1554,6 +1555,36 @@ obj_stop_timers(obj)
obj->timed = 0;
}
/*
* Stop all timers of index func_index at this spot.
*
*/
void
spot_stop_timers(x,y,func_index)
xchar x,y;
short func_index;
{
timer_element *curr, *prev, *next_timer=0;
long where = (((long)x << 16) | ((long)y));
for (prev = 0, curr = timer_base; curr; curr = next_timer) {
next_timer = curr->next;
if (curr->kind == TIMER_LEVEL &&
curr->func_index == func_index && curr->arg == (genericptr_t)where) {
if (prev)
prev->next = curr->next;
else
timer_base = curr->next;
if (timeout_funcs[curr->func_index].cleanup)
(*timeout_funcs[curr->func_index].cleanup)(curr->arg,
curr->timeout);
free((genericptr_t) curr);
} else {
prev = curr;
}
}
}
/* Insert timer into the global queue */
STATIC_OVL void

View File

@@ -1904,7 +1904,7 @@ glovecheck: target = which_armor(mtmp, W_ARMG);
!see_it && distu(mtmp->mx, mtmp->my) <= 3*3)
You("smell smoke.");
if (is_ice(mtmp->mx,mtmp->my))
melt_ice(mtmp->mx,mtmp->my);
melt_ice(mtmp->mx,mtmp->my, (char *)0);
if (see_it) seetrap(trap);
break;
@@ -2440,7 +2440,7 @@ struct obj *box; /* null for floor trap */
if (!box && burn_floor_paper(u.ux, u.uy, see_it, TRUE) && !see_it)
You("smell paper burning.");
if (is_ice(u.ux, u.uy))
melt_ice(u.ux, u.uy);
melt_ice(u.ux, u.uy, (char *)0);
}
STATIC_OVL void

View File

@@ -3479,12 +3479,14 @@ register int dx,dy;
}
void
melt_ice(x, y)
melt_ice(x, y, msg)
xchar x, y;
const char *msg;
{
struct rm *lev = &levl[x][y];
struct obj *otmp;
if (!msg) msg = "The ice crackles and melts.";
if (lev->typ == DRAWBRIDGE_UP)
lev->drawbridgemask &= ~DB_ICE; /* revert to DB_MOAT */
else { /* lev->typ == ICE */
@@ -3496,11 +3498,12 @@ xchar x, y;
#endif
lev->icedpool = 0;
}
spot_stop_timers(x, y, MELT_ICE_AWAY); /* no more ice to melt away */
obj_ice_effects(x, y, FALSE);
unearth_objs(x, y);
if (Underwater) vision_recalc(1);
newsym(x,y);
if (cansee(x,y)) Norep("The ice crackles and melts.");
if (cansee(x,y)) Norep(msg);
if ((otmp = sobj_at(BOULDER, x, y)) != 0) {
if (cansee(x,y)) pline("%s settles...", An(xname(otmp)));
do {
@@ -3515,6 +3518,38 @@ xchar x, y;
spoteffects(TRUE); /* possibly drown, notice objects */
}
/*
* Start a melt_ice timer.
*/
void
start_melt_ice_timeout(x,y)
xchar x,y;
{
long when, where;
short action = MELT_ICE_AWAY;
for (when = 50L; when < 2000L; when++)
if (!rn2(3)) break;
where = (((long)x << 16) | ((long)y));
(void) start_timer(when, TIMER_LEVEL, action, (genericptr_t)where);
}
/*
* Called when ice has melted completely away.
*/
void
melt_ice_away(arg, timeout)
genericptr_t arg;
long timeout; /* unused */
{
xchar x,y;
long where = (long)arg;
y = (xchar)(where & 0xFFFF);
x = (xchar)((where >> 16) & 0xFFFF);
/* melt_ice does newsym when appropriate */
melt_ice(x,y,"Some ice melts away.");
}
/* Burn floor scrolls, evaporate pools, etc... in a single square. Used
* both for normal bolts of fire, cold, etc... and for fireballs.
* Sets shopdamage to TRUE if a shop door is destroyed, and returns the
@@ -3541,7 +3576,7 @@ boolean *shopdamage;
if (cansee(x,y)) newsym(x,y);
}
if(is_ice(x, y)) {
melt_ice(x, y);
melt_ice(x, y, (char *)0);
} else if(is_pool(x,y)) {
const char *msgtxt = "You hear hissing gas.";
if(lev->typ != POOL) { /* MOAT or DRAWBRIDGE_UP */
@@ -3627,6 +3662,7 @@ boolean *shopdamage;
}
}
}
start_melt_ice_timeout(x,y);
obj_ice_effects(x,y,TRUE);
}
if(closed_door(x, y)) {