mirror of
https://codeberg.org/noisytoot/notnotdnethack.git
synced 2025-07-27 07:52:25 +01:00
Fix how timers are paused
Do not remove from global list! Doing so makes it invisible. Instead, put paused & migrating timers on back end of procchain, not executable.
This commit is contained in:
parent
70903321ed
commit
d8b483ef65
6 changed files with 106 additions and 21 deletions
|
@ -2885,8 +2885,12 @@ E void FDECL(desummon_obj, (genericptr_t, long));
|
|||
E void FDECL(summoner_gone, (struct monst *, boolean));
|
||||
E void FDECL(stop_corpse_timers, (struct obj *));
|
||||
E boolean FDECL(start_timer, (long, SHORT_P, SHORT_P, genericptr_t));
|
||||
E void FDECL(pause_timer, (timer_element *));
|
||||
E void FDECL(resume_timer, (timer_element *));
|
||||
E void FDECL(pause_timers, (timer_element *));
|
||||
E void FDECL(resume_timers, (timer_element *));
|
||||
E void FDECL(migrate_timers, (timer_element *));
|
||||
E void FDECL(receive_timers, (timer_element *));
|
||||
E long FDECL(stop_timer, (SHORT_P, timer_element *));
|
||||
E void FDECL(stop_all_timers, (timer_element *));
|
||||
E void NDECL(run_timers);
|
||||
|
|
|
@ -49,13 +49,16 @@ typedef void FDECL((*timeout_proc), (genericptr_t, long));
|
|||
|
||||
/* used in timeout.c */
|
||||
typedef struct timer {
|
||||
struct timer *next; /* next item in PROCESSING chain */
|
||||
struct timer *tnxt; /* next item in LOCAL chain */
|
||||
long timeout; /* when we time out */
|
||||
unsigned long tid; /* timer ID */
|
||||
short kind; /* kind of use */
|
||||
short func_index; /* what to call when we time out */
|
||||
genericptr_t arg; /* pointer to timeout argument */
|
||||
struct timer *next; /* next item in PROCESSING chain */
|
||||
struct timer *tnxt; /* next item in LOCAL chain */
|
||||
long timeout; /* when we time out */
|
||||
unsigned long tid; /* timer ID */
|
||||
short kind; /* kind of use */
|
||||
short func_index; /* what to call when we time out */
|
||||
genericptr_t arg; /* pointer to timeout argument */
|
||||
int timerflags; /* flags for the timer */
|
||||
} timer_element;
|
||||
#define TIMERFLAG_PAUSED 0x01 /* pause progression of timer -- 'timeout' is how many turns were remaining when paused, instead of end-turn*/
|
||||
#define TIMERFLAG_MIGRATING 0x10 /* progress but do not execute timer, as 'arg' is migrating */
|
||||
|
||||
#endif /* TIMEOUT_H */
|
||||
|
|
|
@ -547,7 +547,7 @@ boolean with_you;
|
|||
}
|
||||
}
|
||||
/* now that it's placed, we can resume timers (which may kill mtmp) */
|
||||
resume_timers(mtmp->timed);
|
||||
receive_timers(mtmp->timed);
|
||||
}
|
||||
|
||||
/* heal monster for time spent elsewhere */
|
||||
|
@ -921,7 +921,7 @@ migrate_to_level(mtmp, tolev, xyloc, cc)
|
|||
summoner_gone(mtmp, TRUE);
|
||||
|
||||
/* timers pause processing while mon is migrating */
|
||||
pause_timers(mtmp->timed);
|
||||
migrate_timers(mtmp->timed);
|
||||
|
||||
relmon(mtmp);
|
||||
mtmp->nmon = migrating_mons;
|
||||
|
|
|
@ -1845,7 +1845,7 @@ obj_delivery()
|
|||
otmp->ox = otmp->oy = 0;
|
||||
rloco(otmp);
|
||||
}
|
||||
resume_timers(otmp->timed);
|
||||
receive_timers(otmp->timed);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3486,7 +3486,7 @@ add_to_migration(obj)
|
|||
if (obj->where != OBJ_FREE)
|
||||
panic("add_to_migration: obj not free");
|
||||
|
||||
pause_timers(obj->timed);
|
||||
migrate_timers(obj->timed);
|
||||
obj->where = OBJ_MIGRATING;
|
||||
obj->nobj = migrating_objs;
|
||||
migrating_objs = obj;
|
||||
|
|
|
@ -2692,7 +2692,9 @@ STATIC_DCL void FDECL(rem_procchain_tm, (timer_element *));
|
|||
STATIC_DCL void FDECL(rem_locchain_tm, (timer_element *, timer_element **));
|
||||
|
||||
/* ordered timer list */
|
||||
static timer_element *timer_base; /* "active" */
|
||||
static timer_element *timer_base; /* head of timer procchain */
|
||||
static timer_element *timer_paused; /* helper pointer to first paused/migrating timer in procchain */
|
||||
static timer_element *timer_last; /* last timer in procchain */
|
||||
static unsigned long timer_id = 1;
|
||||
|
||||
|
||||
|
@ -2879,16 +2881,32 @@ timer_element * tm;
|
|||
return;
|
||||
}
|
||||
}
|
||||
/* insert in ordered place in processing loop */
|
||||
for (prev = 0, curr = timer_base; curr; prev = curr, curr = curr->next)
|
||||
|
||||
/* insert into procchain */
|
||||
if (tm->timerflags & (TIMERFLAG_PAUSED | TIMERFLAG_MIGRATING)) {
|
||||
/* timer is not executable, goes on very end, order independent */
|
||||
prev = timer_last;
|
||||
curr = (timer_element *)0;
|
||||
if (!timer_paused)
|
||||
timer_paused = tm;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (curr->timeout >= tm->timeout) break;
|
||||
/* insert in ordered place in processing loop */
|
||||
for (prev = 0, curr = timer_base; curr && curr != timer_paused; prev = curr, curr = curr->next)
|
||||
{
|
||||
if (curr->timeout >= tm->timeout) break;
|
||||
}
|
||||
}
|
||||
tm->next = curr;
|
||||
|
||||
if (prev)
|
||||
prev->next = tm;
|
||||
prev->next = tm;
|
||||
else
|
||||
timer_base = tm;
|
||||
timer_base = tm;
|
||||
|
||||
if (!curr)
|
||||
timer_last = tm;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2902,16 +2920,32 @@ timer_element * tm;
|
|||
|
||||
if (timer_base == tm) {
|
||||
timer_base = tm->next;
|
||||
if (timer_paused == tm)
|
||||
timer_paused = tm->next;
|
||||
if (!tm->next)
|
||||
timer_last = timer_base;
|
||||
return;
|
||||
}
|
||||
else for (tmtmp = timer_base; tmtmp; tmtmp = tmtmp->next) {
|
||||
if (tmtmp->next == tm) {
|
||||
tmtmp->next = tm->next;
|
||||
if (timer_paused == tm)
|
||||
timer_paused = tm->next;
|
||||
if (!tm->next)
|
||||
timer_last = tmtmp;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* removes and readds a timer from the procchain, so that it is in the correct place */
|
||||
void
|
||||
adj_procchain_tm(tm)
|
||||
timer_element * tm;
|
||||
{
|
||||
rem_procchain_tm(tm);
|
||||
add_procchain_tm(tm);
|
||||
}
|
||||
|
||||
/* removes a timer from a local chain */
|
||||
void
|
||||
|
@ -3037,6 +3071,26 @@ timer_element * tm;
|
|||
}
|
||||
}
|
||||
|
||||
/* temporarily pause processing of a single timer */
|
||||
void
|
||||
pause_timer(tm)
|
||||
timer_element * tm;
|
||||
{
|
||||
tm->timeout = tm->timeout - monstermoves;
|
||||
tm->timerflags |= TIMERFLAG_PAUSED;
|
||||
adj_procchain_tm(tm);
|
||||
}
|
||||
/* resume processing of a single timer */
|
||||
void
|
||||
resume_timer(tm)
|
||||
timer_element * tm;
|
||||
{
|
||||
tm->timeout = tm->timeout + monstermoves;
|
||||
tm->timerflags &= ~TIMERFLAG_PAUSED;
|
||||
adj_procchain_tm(tm);
|
||||
flags.run_timers = TRUE;
|
||||
}
|
||||
|
||||
/* temporarily pause processing of all timers on chain until it they are resumed */
|
||||
void
|
||||
pause_timers(tm)
|
||||
|
@ -3044,7 +3098,7 @@ timer_element * tm;
|
|||
{
|
||||
timer_element *curr;
|
||||
for (curr = tm; curr; curr = tm->tnxt)
|
||||
rem_procchain_tm(curr);
|
||||
pause_timer(curr);
|
||||
}
|
||||
|
||||
/* resume processing of all timers on chain */
|
||||
|
@ -3054,9 +3108,33 @@ timer_element * tm;
|
|||
{
|
||||
timer_element *curr;
|
||||
for (curr = tm; curr; curr = tm->tnxt)
|
||||
add_procchain_tm(curr);
|
||||
/* catch up with lost time */
|
||||
run_timers();
|
||||
resume_timer(curr);
|
||||
}
|
||||
|
||||
/* set all timers on chain as migrating (do not execute) */
|
||||
void
|
||||
migrate_timers(tm)
|
||||
timer_element * tm;
|
||||
{
|
||||
timer_element *curr;
|
||||
for (curr = tm; curr; curr = tm->tnxt)
|
||||
{
|
||||
curr->timerflags |= TIMERFLAG_MIGRATING;
|
||||
adj_procchain_tm(curr);
|
||||
}
|
||||
}
|
||||
/* resume handling of migrating timers on chain */
|
||||
void
|
||||
receive_timers(tm)
|
||||
timer_element * tm;
|
||||
{
|
||||
timer_element *curr;
|
||||
for (curr = tm; curr; curr = tm->tnxt)
|
||||
{
|
||||
curr->timerflags &= ~TIMERFLAG_MIGRATING;
|
||||
adj_procchain_tm(curr);
|
||||
}
|
||||
flags.run_timers = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue