Skip to content

Commit

Permalink
Fix and cleanup script timer execution
Browse files Browse the repository at this point in the history
ARX_SCRIPT_Timer_Check needlessly used floating point math where integer
division was enough.

Also, the condition in the assert was wrong as 'st->tim == arxtime'
is a valid postcondition.

Fixes crash report #251
  • Loading branch information
dscharrer committed May 24, 2012
1 parent 92d587c commit 03fb27f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 57 deletions.
1 change: 1 addition & 0 deletions src/scene/ChangeLevel.cpp
Expand Up @@ -2192,6 +2192,7 @@ static INTERACTIVE_OBJ * ARX_CHANGELEVEL_Pop_IO(const string & ident, long num)
scr_timer[num].msecs = ats->msecs;
scr_timer[num].name = toLowercase(safestring(ats->name));
scr_timer[num].pos = ats->pos;
// TODO if the script has changed since the last save, this position may be invalid

float tt = ARX_CHANGELEVEL_DesiredTime + ats->tim;
if(tt < 0) {
Expand Down
107 changes: 50 additions & 57 deletions src/script/Script.cpp
Expand Up @@ -2213,65 +2213,58 @@ long Manage_Specific_RAT_Timer(SCR_TIMER * st)
return 0;
}

void ARX_SCRIPT_Timer_Check()
{
if (ActiveTimers)
{
for (long i = 0; i < MAX_TIMER_SCRIPT; i++)
{
SCR_TIMER * st = &scr_timer[i];

if (st->exist)
{
if (st->flags & 1)
{
if (!(st->io->GameFlags & GFLAG_ISINTREATZONE))
{
if (st->tim + st->msecs < float(arxtime))
{
const float delta = float(arxtime) - st->tim;
const float i = floorf(delta / (float)st->msecs);
st->tim += st->msecs * i;
arx_assert(st->tim < float(arxtime) && st->tim + st->msecs > float(arxtime));
}

continue;
}
}

if (st->tim + st->msecs <= float(arxtime))
{
EERIE_SCRIPT * es = st->es;
INTERACTIVE_OBJ * io = st->io;
long pos = st->pos;

if(!es) {
if(st->name == "_r_a_t_") {
if (Manage_Specific_RAT_Timer(st)) continue;
}
}

if (st->times == 1)
{
ARX_SCRIPT_Timer_ClearByNum(i);
}
else
{
if (st->times != 0) st->times--;

st->tim += st->msecs;
}

if ((es)
&& (ValidIOAddress(io)))
{

ScriptEvent::send(es, SM_EXECUTELINE, "", io, "", pos);
}

}
void ARX_SCRIPT_Timer_Check() {

if(!ActiveTimers) {
return;
}

for(long i = 0; i < MAX_TIMER_SCRIPT; i++) {

SCR_TIMER * st = &scr_timer[i];
if(!st->exist) {
continue;
}

unsigned long now = static_cast<unsigned long>(arxtime);
unsigned long fire_time = st->tim + st->msecs;
if(fire_time > now) {
// Timer not ready to fire yet
continue;
}

// Skip heartbeat timer events for far away objects
if((st->flags & 1) && !(st->io->GameFlags & GFLAG_ISINTREATZONE)) {
long increment = (now - st->tim) / st->msecs;
st->tim += st->msecs * increment;
arx_assert_msg(st->tim <= now && st->tim + st->msecs > now,
"start=%lu wait=%ld now=%lu", st->tim, st->msecs, now);
continue;
}

EERIE_SCRIPT * es = st->es;
INTERACTIVE_OBJ * io = st->io;
long pos = st->pos;

if(!es && st->name == "_r_a_t_") {
if(Manage_Specific_RAT_Timer(st)) {
continue;
}
}

if(st->times == 1) {
ARX_SCRIPT_Timer_ClearByNum(i);
} else {
if(st->times != 0) {
st->times--;
}
st->tim += st->msecs;
}

if(es && ValidIOAddress(io)) {
ScriptEvent::send(es, SM_EXECUTELINE, "", io, "", pos);
}

}
}

Expand Down

0 comments on commit 03fb27f

Please sign in to comment.