1-- Set the namespace 2local ns = {}; 3setmetatable(ns, {__index = _G}); 4wolf_fangs_party_attack = ns; 5setfenv(1, ns); 6 7-- local references 8local attacker = nil 9local target = nil 10local skill = nil 11 12local attacker_pos_x = 0.0; 13local attacker_pos_y = 0.0; 14 15local distance_moved = 0.0; 16local start_x_position = 0.0; 17local start_y_position = 0.0; 18local jump_end_x_position = 0.0; 19local diff_x = 0.0; 20local diff_y = 0.0; 21 22local targets = {} 23 24local attack_step = 0; 25 26local damage_triggered = false; 27 28local Battle = nil 29local claw_slash = nil 30local slash_effect_time = 0 31local slash_effect_started = false 32 33-- attacker, the BattleActor attacking 34-- target, the BattleActor target 35-- The skill id used on target 36function Initialize(_attacker, _target, _skill) 37 -- Keep the reference in memory 38 attacker = _attacker; 39 target = _target; 40 skill = _skill; 41 42 -- Don't attack if the attacker isn't alive 43 if (attacker:IsAlive() == false) then 44 return; 45 end 46 47 -- Get the current attackers' positions 48 attacker_pos_x = attacker:GetXLocation(); 49 attacker_pos_y = attacker:GetYLocation(); 50 51 attack_step = 0; 52 53 damage_triggered = false; 54 55 distance_moved = SystemManager:GetUpdateTime() / vt_map.MapMode.NORMAL_SPEED * 100.0; 56 start_x_position = attacker_pos_x; 57 jump_end_x_position = attacker_pos_x - 140 58 start_y_position = attacker_pos_y; 59 diff_x = attacker_pos_x - 70; 60 diff_y = attacker_pos_y - 50; 61 62 63 Battle = ModeManager:GetTop(); 64 slash_effect_time = 0; 65 slash_effect_started = false; 66 67 -- Register all the valid actors position in the table 68 local index = 0; 69 while (target:GetPartyActor(index) ~= nil) do 70 local actor = target:GetPartyActor(index) 71 if (actor:CanFight() == true) then 72 targets[index] = {}; 73 targets[index].actor = actor 74 targets[index].slash_anim = Battle:CreateBattleAnimation("data/entities/battle/effects/fangs_crush.lua"); 75 end 76 77 index = index + 1 78 end 79end 80 81 82function Update() 83 -- The update time can vary, so update the distance on each update as well. 84 distance_moved = SystemManager:GetUpdateTime() / vt_map.MapMode.NORMAL_SPEED * 100.0; 85 86 -- Start to jump slightly 87 if (attack_step == 0) then 88 attacker:ChangeSpriteAnimation("idle") 89 Battle:TriggerBattleParticleEffect("data/visuals/particle_effects/dust.lua", attacker_pos_x, attacker_pos_y) 90 AudioManager:PlaySound("data/sounds/growl1_IFartInUrGeneralDirection_freesound.wav") 91 92 attack_step = 1 93 end 94 -- Make the attacker jump 95 if (attack_step == 1) then 96 97 if (attacker_pos_x > diff_x) then 98 attacker_pos_x = attacker_pos_x - distance_moved; 99 if attacker_pos_x < diff_x then attacker_pos_x = diff_x end 100 end 101 if (attacker_pos_x < diff_x) then 102 attacker_pos_x = attacker_pos_x + distance_moved; 103 if attacker_pos_x > diff_x then attacker_pos_x = diff_x end 104 end 105 106 if (attacker_pos_y > diff_y) then 107 attacker_pos_y = attacker_pos_y - distance_moved; 108 if attacker_pos_y < diff_y then attacker_pos_y = diff_y end 109 end 110 if (attacker_pos_y < diff_y) then 111 attacker_pos_y = attacker_pos_y + distance_moved; 112 if attacker_pos_y > diff_y then attacker_pos_y = diff_y end 113 end 114 115 attacker:SetXLocation(attacker_pos_x); 116 attacker:SetYLocation(attacker_pos_y); 117 118 -- half-jump done 119 if (attacker_pos_x == diff_x and attacker_pos_y == diff_y) then 120 attack_step = 2; 121 end 122 end 123 124 -- Second half-jump 125 if (attack_step == 2) then 126 if (attacker_pos_x > jump_end_x_position) then 127 attacker_pos_x = attacker_pos_x - distance_moved; 128 if attacker_pos_x < jump_end_x_position then attacker_pos_x = jump_end_x_position end 129 end 130 if (attacker_pos_x < jump_end_x_position) then 131 attacker_pos_x = attacker_pos_x + distance_moved; 132 if attacker_pos_x > jump_end_x_position then attacker_pos_x = jump_end_x_position end 133 end 134 135 if (attacker_pos_y > start_y_position) then 136 attacker_pos_y = attacker_pos_y - distance_moved; 137 if attacker_pos_y < start_y_position then attacker_pos_y = start_y_position end 138 end 139 if (attacker_pos_y < start_y_position) then 140 attacker_pos_y = attacker_pos_y + distance_moved; 141 if attacker_pos_y > start_y_position then attacker_pos_y = start_y_position end 142 end 143 144 attacker:SetXLocation(attacker_pos_x); 145 attacker:SetYLocation(attacker_pos_y); 146 147 -- half-jump done 148 if (attacker_pos_y == start_y_position) then 149 Battle:TriggerBattleParticleEffect("data/visuals/particle_effects/dust.lua", attacker_pos_x, attacker_pos_y); 150 151 -- Init the slash effect life time 152 slash_effect_time = 0; 153 slash_effect_started = false; 154 155 attack_step = 3; 156 end 157 end 158 159 -- Wait for it to finish 160 if (attack_step == 3) then 161 slash_effect_time = slash_effect_time + SystemManager:GetUpdateTime() 162 if (slash_effect_started == false) then 163 slash_effect_started = true 164 165 for index, target_info in pairs(targets) do 166 target_info.slash_anim:SetXLocation(target_info.actor:GetXLocation()) 167 target_info.slash_anim:SetYLocation(target_info.actor:GetYLocation() + 0.1) -- To see the effect 168 target_info.slash_anim:SetVisible(true) 169 target_info.slash_anim:Reset() 170 end 171 172 -- Triggers the damage in the middle of the attack animation 173 skill:ExecuteBattleFunction(attacker, target) 174 -- Remove the skill points at the end of the attack 175 attacker:SubtractSkillPoints(skill:GetSPRequired()) 176 attack_step = 4 177 end 178 end 179 180 -- Return to start pos 181 if (attack_step == 4) then 182 slash_effect_time = slash_effect_time + SystemManager:GetUpdateTime(); 183 184 if (attacker_pos_x > start_x_position) then 185 attacker_pos_x = attacker_pos_x - distance_moved; 186 if attacker_pos_x < start_x_position then attacker_pos_x = start_x_position end 187 end 188 if (attacker_pos_x < start_x_position) then 189 attacker_pos_x = attacker_pos_x + distance_moved; 190 if attacker_pos_x > start_x_position then attacker_pos_x = start_x_position end 191 end 192 193 if (attacker_pos_y > start_y_position) then 194 attacker_pos_y = attacker_pos_y - distance_moved; 195 if attacker_pos_y < start_y_position then attacker_pos_y = start_y_position end 196 end 197 if (attacker_pos_y < start_y_position) then 198 attacker_pos_y = attacker_pos_y + distance_moved; 199 if attacker_pos_y > start_y_position then attacker_pos_y = start_y_position end 200 end 201 202 attacker:SetXLocation(attacker_pos_x); 203 attacker:SetYLocation(attacker_pos_y); 204 205 -- Stops once all the animations are done 206 if (slash_effect_time > 75 * 4) then -- 300, 410 + 300 = 710 (< 730). 207 208 local all_anim_are_done = true 209 for index, target_info in pairs(targets) do 210 if (target_info.slash_anim ~= nil) then 211 target_info.slash_anim:SetVisible(false) 212 target_info.slash_anim:Remove() 213 -- The Remove() call will make the engine delete the object, so we set it to nil 214 -- to avoid using it again. 215 target_info.slash_anim = nil 216 217 all_anim_are_done = false 218 end 219 end 220 221 if (all_anim_are_done == false) then 222 return true; 223 end 224 end 225 end 226 227 return false; 228end 229