Script: Remove effect after error in Timer

As the timer tends to run more than once, you'd also very likely get the
error more than once. The timer also often determines the effect
lifetime, making a broken effect live forever.

This was especially annoying with one-off Schedule() invokations
that wouldn't even stop throwing errors after finishing the
designated number of repeats. Although fixing just that script
function would have been possible, I believe that a more general
solution for all effects is useful.
master
Lukas Werling 2018-08-26 23:15:05 +02:00
parent f5988085a7
commit 2fb14b026d
1 changed files with 15 additions and 4 deletions

View File

@ -442,10 +442,21 @@ int C4Effect::CallStop(int reason, bool temporary)
}
int C4Effect::CallTimer(int time)
{
if (!GetCallbackScript())
return Call(P_Timer, &C4AulParSet(time)).getInt();
if (pFnTimer)
return pFnTimer->Exec(GetCallbackScript(), &C4AulParSet(Obj(Target), this, time)).getInt();
try
{
if (!GetCallbackScript())
return Call(P_Timer, &C4AulParSet(time), true).getInt();
if (pFnTimer)
return pFnTimer->Exec(GetCallbackScript(), &C4AulParSet(Obj(Target), this, time), true).getInt();
}
catch (C4AulError &e)
{
// Script error: remove the timer.
// TODO: The error message is printed after the stack trace. No way around that currently.
::ScriptEngine.GetErrorHandler()->OnError(e.what());
// => Removing effect { ... }
DebugLogF(" Removing %s", C4Value(this).GetDataString(3).getData());
}
return C4Fx_Execute_Kill;
}
void C4Effect::CallDamage(int32_t & damage, int damagetype, int plr)