The EVS_TakeTurn script runs when it's the actor's turn to attack. A typical attack follows this pattern: approach the target, check if the attack hits, deal damage, then return home.
Testing the target
Before dealing damage, use EnemyTestTarget to check if the attack will hit. This accounts for evasion badges and abilities.
Call(SetTargetActor,attackerID ACTOR_SELF,defenderID ACTOR_PLAYER)
Call(EnemyTestTarget,
actorID ACTOR_SELF,outResult LVar0,damageType 0,debuffType 0,
damageAmount 1,flagsModifier BS_FLAGS1_INCLUDE_POWER_UPS)
Switch(LVar0)
CaseOrEq(HIT_RESULT_MISS)
CaseOrEq(HIT_RESULT_LUCKY)
// play miss animation, then return home
Call(YieldTurn)
Return
EndCaseGroup
EndSwitchThe fifth argument (1 in this example) is the damage amount for display purposes.
Dealing damage
If the test passes, use EnemyDamageTarget to actually apply damage:
Call(SetGoalToTarget,actorID ACTOR_SELF)
Call(EnemyDamageTarget,
actorID ACTOR_SELF,outResult LVar0,damageType 0,suppressEventFlags 0,
debuffType 0,damageAmount 2,flagsModifier BS_FLAGS1_TRIGGER_EVENTS)The third argument is the damage type flags — use 0 for a normal attack, or combine flags for elemental and special behavior (see below). The sixth argument (2 here) is the actual damage dealt. The result in LVar0 tells you what happened:
| Result | Meaning |
|---|---|
HIT_RESULT_HIT | Normal hit |
HIT_RESULT_NO_DAMAGE | Hit but dealt 0 damage (e.g. high defense) |
Simple melee attack
Here's a basic melee attack that runs up to the player, hits, and retreats:
EvtScript EVS_TakeTurn = {
Call(UseIdleAnimation,actorID ACTOR_SELF,useIdle false)
Call(EnableIdleScript,actorID ACTOR_SELF,mode IDLE_SCRIPT_DISABLE)
Call(SetTargetActor,attackerID ACTOR_SELF,defenderID ACTOR_PLAYER)
Call(UseBattleCamPreset,presetIndex BTL_CAM_ENEMY_APPROACH)
Call(BattleCamTargetActor,actorID ACTOR_SELF)
// run towards the player
Call(SetAnimation,
actorID ACTOR_SELF,partIndex PRT_MAIN,animID ANIM_Goomba_Run)
Call(SetGoalToTarget,actorID ACTOR_SELF)
Call(AddGoalPos,actorID ACTOR_SELF,dx 50,dy 0,dz 0)
Call(SetActorSpeed,actorID ACTOR_SELF,moveSpeed Float(6.0))
Call(RunToGoal,actorID ACTOR_SELF,moveTime 0,moveArcAmplitude false)
// test if the attack hits
Call(EnemyTestTarget,
actorID ACTOR_SELF,outResult LVar0,damageType 0,debuffType 0,
damageAmount 2,flagsModifier BS_FLAGS1_INCLUDE_POWER_UPS)
Switch(LVar0)
CaseOrEq(HIT_RESULT_MISS)
CaseOrEq(HIT_RESULT_LUCKY)
// missed — return home
Call(UseBattleCamPreset,presetIndex BTL_CAM_DEFAULT)
Call(YieldTurn)
Call(SetAnimation,
actorID ACTOR_SELF,partIndex PRT_MAIN,animID ANIM_Goomba_Run)
Call(SetGoalToHome,actorID ACTOR_SELF)
Call(SetActorSpeed,actorID ACTOR_SELF,moveSpeed Float(8.0))
Call(RunToGoal,
actorID ACTOR_SELF,moveTime 0,moveArcAmplitude false)
Call(EnableIdleScript,actorID ACTOR_SELF,mode IDLE_SCRIPT_ENABLE)
Call(UseIdleAnimation,actorID ACTOR_SELF,useIdle true)
Return
EndCaseGroup
EndSwitch
// attack connects
Call(SetGoalToTarget,actorID ACTOR_SELF)
Call(EnemyDamageTarget,
actorID ACTOR_SELF,outResult LVar0,damageType 0,suppressEventFlags 0,
debuffType 0,damageAmount 2,flagsModifier BS_FLAGS1_TRIGGER_EVENTS)
// return home
Call(UseBattleCamPreset,presetIndex BTL_CAM_DEFAULT)
Wait(5)
Call(YieldTurn)
Call(SetAnimation,
actorID ACTOR_SELF,partIndex PRT_MAIN,animID ANIM_Goomba_Run)
Call(SetGoalToHome,actorID ACTOR_SELF)
Call(SetActorSpeed,actorID ACTOR_SELF,moveSpeed Float(8.0))
Call(RunToGoal,actorID ACTOR_SELF,moveTime 0,moveArcAmplitude false)
Call(EnableIdleScript,actorID ACTOR_SELF,mode IDLE_SCRIPT_ENABLE)
Call(UseIdleAnimation,actorID ACTOR_SELF,useIdle true)
Return
End
};For a jump attack with arc rotation, see src/battle/actor/gloomba.c. For a dive attack pattern, see src/battle/actor/paragoomba.c.
Damage type flags
The third argument to EnemyDamageTarget is a bitmask of DAMAGE_TYPE_ flags. Use exactly one elemental flag to set the attack's element, and optionally combine it with modifier flags:
| Flag | Effect |
|---|---|
DAMAGE_TYPE_NO_CONTACT | Ranged/projectile attack — won't trigger contact hazards like spikes or Zap Tap. |
DAMAGE_TYPE_IGNORE_DEFENSE | Bypasses the target's defense stat. |
DAMAGE_TYPE_UNBLOCKABLE | Cannot be blocked by the player. |
DAMAGE_TYPE_STATUS_ALWAYS_HITS | Status effects bypass immunity checks. |
Pass 0 for a normal contact attack with no special properties.