1-- This file is scripting Bronann's attack animation, called by attack skills. 2-- The initialize() function is called once, followed by calls to the update function. 3-- When the update function returns true, the attack is finished. 4 5-- Set the namespace 6local ns = {}; 7setmetatable(ns, {__index = _G}); 8bronann_attack_forward_thrust = ns; 9setfenv(1, ns); 10 11-- local references 12local character = nil 13local target = nil 14local target_actor = nil 15local skill = nil 16 17local character_pos_x = 0.0; 18local character_pos_y = 0.0; 19 20local a_coeff = 0.0; 21local distance_moved_x = 0.0; 22local distance_moved_y = 0.0; 23 24local enemy_pos_x = 0.0; 25local enemy_pos_y = 0.0; 26 27local attack_step = 0; 28local attack_time = 0.0; 29 30local damage_triggered = false; 31 32local Battle = nil 33local sword_slash = nil 34local slash_effect_time = 0 35local slash_effect_started = false 36 37-- Used to trigger dust 38local move_time = 0 39-- Used to set up the Forward thrust counter force 40local forward_thrust_counter_force = 0.0; 41 42-- character, the BattleActor attacking (here Bronann) 43-- target, the BattleEnemy target 44-- The skill id used on target 45function Initialize(_character, _target, _skill) 46 -- Keep the reference in memory 47 character = _character; 48 target = _target; 49 target_actor = _target:GetActor(); 50 skill = _skill; 51 52 -- Don't attack if the character isn't alive 53 if (character:IsAlive() == false) then 54 return; 55 end 56 57 -- Get the current characters' positions 58 character_pos_x = character:GetXLocation(); 59 character_pos_y = character:GetYLocation(); 60 61 enemy_pos_x = target_actor:GetXLocation() - (character:GetSpriteWidth() / 2.0); 62 enemy_pos_y = target_actor:GetYLocation() - 5.0; -- Makes Bronann placed behind the enemy. 63 64 attack_step = 0; 65 attack_time = 0; 66 67 damage_triggered = false; 68 69 distance_moved_x = SystemManager:GetUpdateTime() / vt_map.MapMode.NORMAL_SPEED * 170.0; 70 local x_diff = enemy_pos_x - character_pos_x; 71 local y_diff = character_pos_y - enemy_pos_y; 72 if (y_diff == 0.0) then 73 a_coeff = 0.0; 74 distance_moved_y = 0.0; 75 elseif (x_diff == 0.0) then 76 a_coeff = 0.0; 77 distance_moved_y = distance_moved_x; 78 distance_moved_x = 0.0; 79 else 80 a_coeff = y_diff / x_diff; 81 if (a_coeff < 0) then a_coeff = -a_coeff; end 82 distance_moved_y = a_coeff * distance_moved_x; 83 end 84 85 --print("distance x: ", enemy_pos_x - character_pos_x) 86 --print("distance y: ", character_pos_y - enemy_pos_y) 87 --print (distance_moved_x, a_coeff, distance_moved_y); 88 89 Battle = ModeManager:GetTop(); 90 -- A sword slash animation 91 sword_slash = Battle:CreateBattleAnimation("data/entities/battle/effects/sword_forward_slash.lua"); 92 slash_effect_time = 0; 93 slash_effect_started = false; 94 move_time = 0; 95 forward_thrust_counter_force = 0; 96end 97 98 99function Update() 100 -- The update time can vary, so update the distance on each update as well. 101 distance_moved_x = SystemManager:GetUpdateTime() / vt_map.MapMode.NORMAL_SPEED * 170.0; 102 if (a_coeff ~= 0.0) then 103 distance_moved_y = a_coeff * distance_moved_x; 104 end 105 106 -- Make the speed the same whatever the angle between the character and the enemy is. 107 -- We deal only with a coefficients > 1.0 for simplification purpose. 108 if (a_coeff > 1.0 and distance_moved_x ~= 0.0 and distance_moved_y ~= 0.0) then 109 distance_moved_x = distance_moved_x * (distance_moved_x / distance_moved_y); 110 if (a_coeff ~= 0.0) then 111 distance_moved_y = a_coeff * distance_moved_x; 112 end 113 --print ("new_ratio: ", a_coeff, distance_moved_x / distance_moved_y) 114 end 115 116 -- Start to run towards the enemy 117 if (attack_step == 0) then 118 character:ChangeSpriteAnimation("jump_forward") 119 AudioManager:PlaySound("data/sounds/footstep_grass1.wav") 120 Battle:TriggerBattleParticleEffect("data/visuals/particle_effects/dust.lua", character_pos_x, character_pos_y); 121 122 attack_step = 1 123 end 124 -- Make the player move till it reaches the enemy 125 if (attack_step == 1) then 126 if (character_pos_x > enemy_pos_x) then 127 character_pos_x = character_pos_x - distance_moved_x; 128 if character_pos_x < enemy_pos_x then character_pos_x = enemy_pos_x end 129 end 130 if (character_pos_x < enemy_pos_x) then 131 character_pos_x = character_pos_x + distance_moved_x; 132 if character_pos_x > enemy_pos_x then character_pos_x = enemy_pos_x end 133 end 134 if (character_pos_y > enemy_pos_y) then 135 character_pos_y = character_pos_y - distance_moved_y; 136 if character_pos_y < enemy_pos_y then character_pos_y = enemy_pos_y end 137 end 138 if (character_pos_y < enemy_pos_y) then 139 character_pos_y = character_pos_y + distance_moved_y; 140 if character_pos_y > enemy_pos_y then character_pos_y = enemy_pos_y end 141 end 142 143 character:SetXLocation(character_pos_x); 144 character:SetYLocation(character_pos_y); 145 146 -- Attack when reaching the enemy 147 if (character_pos_x >= enemy_pos_x and character_pos_y == enemy_pos_y) then 148 attack_step = 2; 149 end 150 end 151 152 -- triggers the attack animation 153 if (attack_step == 2) then 154 AudioManager:PlaySound("data/sounds/footstep_grass2.wav") 155 Battle:TriggerBattleParticleEffect("data/visuals/particle_effects/dust.lua", character_pos_x, character_pos_y); 156 character:ChangeSpriteAnimation("attack_forward_thrust") 157 158 -- Trigger damage a first time 159 skill:ExecuteBattleFunction(character, target) 160 AudioManager:PlaySound("data/sounds/swordslice1.wav") 161 162 -- Init the slash effect life time 163 slash_effect_time = 0; 164 slash_effect_started = false; 165 166 move_time = 0; 167 168 attack_step = 3; 169 end 170 171 -- Wait for it to finish 172 if (attack_step == 3) then 173 attack_time = attack_time + SystemManager:GetUpdateTime(); 174 175 if (attack_time > 410) then 176 slash_effect_time = slash_effect_time + SystemManager:GetUpdateTime(); 177 if (slash_effect_started == false) then 178 slash_effect_started = true 179 180 sword_slash:SetXLocation(target_actor:GetXLocation()); 181 sword_slash:SetYLocation(target_actor:GetYLocation() + 2.0); 182 sword_slash:SetVisible(true); 183 sword_slash:Reset(); 184 end 185 end 186 187 if (sword_slash ~= nil and slash_effect_time > 75 * 4) then -- 300, 410 + 300 = 710 (< 730). 188 sword_slash:SetVisible(false); 189 sword_slash:Remove(); 190 -- The Remove() call will make the engine delete the object, so we set it to nil 191 -- to avoid using it again. 192 sword_slash = nil; 193 end 194 195 -- Triggers the damage a second time in the middle of the attack animation 196 if (damage_triggered == false and attack_time > 505.0) then 197 skill:ExecuteBattleFunction(character, target) 198 AudioManager:PlaySound("data/sounds/swordslice1.wav") 199 -- Remove the skill points at the end of attack 200 character:SubtractSkillPoints(skill:GetSPRequired()) 201 damage_triggered = true; 202 end 203 204 -- Makes the character go through the enemy for the second blow. 205 if (attack_time > 390) then 206 character_pos_x = character_pos_x + distance_moved_x - forward_thrust_counter_force; 207 character:SetXLocation(character_pos_x); 208 forward_thrust_counter_force = forward_thrust_counter_force + (2.0 * SystemManager:GetUpdateTime() / 30.0); 209 210 -- Adds some dust every 15ms 211 move_time = move_time + SystemManager:GetUpdateTime(); 212 if (move_time > 15) then 213 Battle:TriggerBattleParticleEffect("data/visuals/particle_effects/dust.lua", character_pos_x, character_pos_y); 214 move_time = 0 215 end 216 end 217 218 if (attack_time > 730.0) then 219 character:ChangeSpriteAnimation("jump_backward") 220 Battle:TriggerBattleParticleEffect("data/visuals/particle_effects/dust.lua", character_pos_x, character_pos_y); 221 AudioManager:PlaySound("data/sounds/footstep_grass1.wav") 222 223 -- Recompute the a coefficient using the character origin position as the angle has changed. 224 distance_moved_x = SystemManager:GetUpdateTime() / vt_map.MapMode.NORMAL_SPEED * 170.0; 225 local x_diff = character:GetXLocation() - character:GetXOrigin(); 226 local y_diff = character:GetYOrigin() - character:GetYLocation(); 227 if (y_diff == 0.0) then 228 a_coeff = 0.0; 229 distance_moved_y = 0.0; 230 elseif (x_diff == 0.0) then 231 a_coeff = 0.0; 232 distance_moved_y = distance_moved_x; 233 distance_moved_x = 0.0; 234 else 235 a_coeff = y_diff / x_diff; 236 if (a_coeff < 0) then a_coeff = -a_coeff; end 237 distance_moved_y = a_coeff * distance_moved_x; 238 end 239 240 attack_step = 4; 241 end 242 end 243 244 -- triggers skill 245 if (attack_step == 4) then 246 -- Make the character jump back to its place 247 if (character_pos_x > character:GetXOrigin()) then 248 character_pos_x = character_pos_x - distance_moved_x; 249 if character_pos_x < character:GetXOrigin() then character_pos_x = character:GetXOrigin() end 250 end 251 if (character_pos_x < character:GetXOrigin()) then 252 character_pos_x = character_pos_x + distance_moved_x; 253 if character_pos_x > character:GetXOrigin() then character_pos_x = character:GetXOrigin() end 254 end 255 if (character_pos_y > character:GetYOrigin()) then 256 character_pos_y = character_pos_y - distance_moved_y; 257 if character_pos_y < character:GetYOrigin() then character_pos_y = character:GetYOrigin() end 258 end 259 if (character_pos_y < character:GetYOrigin()) then 260 character_pos_y = character_pos_y + distance_moved_y; 261 if character_pos_y > character:GetYOrigin() then character_pos_y = character:GetYOrigin() end 262 end 263 264 character:SetXLocation(character_pos_x); 265 character:SetYLocation(character_pos_y); 266 267 -- Attack when reaching the enemy 268 if (character_pos_x == character:GetXOrigin() and character_pos_y == character:GetYOrigin()) then 269 attack_step = 5; 270 end 271 end 272 273 if (attack_step == 5) then 274 character:ChangeSpriteAnimation("idle") 275 Battle:TriggerBattleParticleEffect("data/visuals/particle_effects/dust.lua", character_pos_x, character_pos_y) 276 AudioManager:PlaySound("data/sounds/footstep_grass2.wav") 277 return true; 278 end 279 return false; 280end 281