provide core support for saving of messsage history in save file
the following actions can now be continued after save/restore: digging,
eating, studying, removing armor
+hero-created and monster-created ice will eventually melt away
Platform- and/or Interface-Specific New Features
E void FDECL(obj_move_timers, (struct obj *, struct obj *));
E void FDECL(obj_split_timers, (struct obj *, struct obj *));
E void FDECL(obj_stop_timers, (struct obj *));
+E void FDECL(spot_stop_timers, (XCHAR_P,XCHAR_P,SHORT_P));
E boolean FDECL(obj_is_local, (struct obj *));
E void FDECL(save_timers, (int,int,int));
E void FDECL(restore_timers, (int,int,BOOLEAN_P,long));
E struct monst *FDECL(boomhit, (int,int));
E int FDECL(burn_floor_paper, (int,int,BOOLEAN_P,BOOLEAN_P));
E void FDECL(buzz, (int,int,XCHAR_P,XCHAR_P,int,int));
-E void FDECL(melt_ice, (XCHAR_P,XCHAR_P));
+E void FDECL(melt_ice, (XCHAR_P,XCHAR_P,const char *));
+E void FDECL(start_melt_ice_timeout, (XCHAR_P,XCHAR_P));
+E void FDECL(melt_ice_away, (genericptr_t, long));
E int FDECL(zap_over_floor, (XCHAR_P,XCHAR_P,int,boolean *));
E void FDECL(fracture_rock, (struct obj *));
E boolean FDECL(break_statue, (struct obj *));
#define BURN_OBJECT 3
#define HATCH_EGG 4
#define FIG_TRANSFORM 5
-#define NUM_TIME_FUNCS 6
+#define MELT_ICE_AWAY 6
+#define NUM_TIME_FUNCS 7
/* used in timeout.c */
typedef struct fe {
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
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
!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;
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
}
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 */
#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 {
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
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 */
}
}
}
+ start_melt_ice_timeout(x,y);
obj_ice_effects(x,y,TRUE);
}
if(closed_door(x, y)) {