From 2fb14b026dfa8457db9ace24636e96205314150c Mon Sep 17 00:00:00 2001 From: Lukas Werling Date: Sun, 26 Aug 2018 23:15:05 +0200 Subject: [PATCH] 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. --- src/script/C4Effect.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/script/C4Effect.cpp b/src/script/C4Effect.cpp index 392f98f23..5be6ab6b5 100644 --- a/src/script/C4Effect.cpp +++ b/src/script/C4Effect.cpp @@ -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)