diff --git a/msu/hooks/entity/tactical/actor.nut b/msu/hooks/entity/tactical/actor.nut index 52ad2f60..09105b7d 100644 --- a/msu/hooks/entity/tactical/actor.nut +++ b/msu/hooks/entity/tactical/actor.nut @@ -21,14 +21,7 @@ q.onMovementStep = @(__original) function( _tile, _levelDifference ) { - local ret = __original(_tile, _levelDifference); - - if (ret) - { - this.m.Skills.onMovementStep(_tile, _levelDifference); - } - - return ret; + return __original(_tile, _levelDifference) && this.m.Skills.onMovementStep(_tile, _levelDifference); } // VANILLAFIX: http://battlebrothersgame.com/forums/topic/oncombatstarted-is-not-called-for-ai-characters/ diff --git a/msu/hooks/skills/skill_container.nut b/msu/hooks/skills/skill_container.nut index a9895f98..91ab75f4 100644 --- a/msu/hooks/skills/skill_container.nut +++ b/msu/hooks/skills/skill_container.nut @@ -132,10 +132,56 @@ q.onMovementStep <- function( _tile, _levelDifference ) { - this.callSkillsFunction("onMovementStep", [ - _tile, - _levelDifference - ], false); + local wasUpdating = this.m.IsUpdating; + this.m.IsUpdating = true; + + local callback = null; + + local skill, skill_callback; // cache vars for foreach loop + foreach (s in this.m.Skills) + { + if (s.isGarbage()) + continue; + + skill_callback = s.onMovementStep(_tile, _levelDifference); + if (callback == null) + { + switch (skill_callback) + { + // null is for legacy support, because older versions didn't have a return + // for `onMovementStep` and weren't meant to be able to interrupt movement. + case null: + case true: + break; + + // skill_callback is either `false` or a function in this case. + // In this case the skill wants to interrupt the movement. + // We will only take skill_callback from the first skill that gives it, + // so SkillOrder is important. + // The skill_callback can be useful to do functionality after the interruption + // e.g. refunding AP or triggering an effect etc. + default: + callback = skill_callback; + skill = s; + break; + } + } + } + + this.m.IsUpdating = wasUpdating; + + // callback being null means no skill returned `false` or a function + // therefore no skill is interrupting this movement. So we return `true`. + if (callback == null) + return true; + + // If any skill returned `false` or a function it means it wants to + // stop the movement. So, we call the skill's provided callback (if any) + // and then return `false`. + if (callback != false) + callback.call(skill, _tile, _levelDifference); + + return false; } q.onAnySkillExecuted <- function( _skill, _targetTile, _targetEntity, _forFree )