1------------------------------------------------------------------------------[[ 2-- Description: This file contains the definitions of all weapon skills. 3-- Each attack skill has a unique integer identifier 4-- that is used as its key in the skills table below. Some skills are primarily 5-- intended for characters to use while others are intended for enemies to use. 6-- Normally, we do not want to share skills between characters and enemies as 7-- character skills animate the sprites while enemy skills do not. 8-- 9-- Skill IDs 1 through 10,000 are reserved for attack skills. 10-- 11-- Each skill entry requires the following data to be defined: 12-- {name}: Text that defines the name of the skill 13-- {description}: A brief (one sentence) description of the skill 14-- (This field is required only for character skills and is optional for enemy skills) 15-- {sp_required}: The number of skill points (SP) that are required to use the skill 16-- (Zero is a valid value for this field, but a negative number is not) 17-- {warmup_time}: The number of milliseconds that the actor using the skill must wait between 18-- selecting the skill and executing it (a value of zero is valid). 19-- {cooldown_time}: The number of milliseconds that the actor using the skill must wait after 20-- executing the skill before their stamina begins regenrating (zero is valid). 21-- {action_name}: The sprite action played before executing the battle scripted function. 22-- {target_type}: The type of target the skill affects, which may be an attack point, actor, or party. 23-- 24-- Each skill entry requires a function called {BattleExecute} to be defined. This function implements the 25-- execution of the skill in battle, dealing damage, causing status changes, playing sounds, and animating 26-- sprites. 27------------------------------------------------------------------------------]] 28 29function clampDuration(effect_duration) 30 local minimum_duration = 15000 31 return (effect_duration >= minimum_duration) and effect_duration or minimum_duration 32end 33 34-- common functions 35function trigger_potential_stun(user, target) 36 local target_actor = target:GetActor(); 37 local attack_point = target_actor:GetAttackPoint(target:GetAttackPoint()); 38 local chance_modifier = (user:GetTotalMagicalAttack(vt_global.GameGlobal.GLOBAL_ELEMENTAL_NEUTRAL) 39 - attack_point:GetTotalMagicalDefense(vt_global.GameGlobal.GLOBAL_ELEMENTAL_NEUTRAL)) * 3.0; 40 local chance = (vt_utils.RandomFloat() * 100.0); 41 --print( chance.. "/".. 50.0 + chance_modifier); 42 if (chance > (50.0 + chance_modifier)) then 43 return; 44 end 45 46 -- Compute an effect duration time based on the characters' stats 47 -- Divide stun effect length by 2 has it makes the game more usable 48 local effect_duration = clampDuration(user:GetMagAtk() - target_actor:GetMagDef()) 49 target_actor:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_PARALYSIS, 50 vt_global.GameGlobal.GLOBAL_INTENSITY_NEG_LESSER, 51 effect_duration); 52 local Battle = ModeManager:GetTop(); 53 Battle:TriggerBattleParticleEffect("data/visuals/particle_effects/stun_star.lua", target_actor:GetXLocation(), target_actor:GetYLocation()); 54end 55 56function trigger_potential_attack_lowering(user, target) 57 local target_actor = target:GetActor(); 58 local attack_point = target_actor:GetAttackPoint(target:GetAttackPoint()); 59 local chance_modifier = (user:GetTotalMagicalAttack(vt_global.GameGlobal.GLOBAL_ELEMENTAL_NEUTRAL) 60 - attack_point:GetTotalMagicalDefense(vt_global.GameGlobal.GLOBAL_ELEMENTAL_NEUTRAL)) * 3.0; 61 local chance = (vt_utils.RandomFloat() * 100.0); 62 --print( chance.. "/".. 50.0 + chance_modifier); 63 if (chance > (50.0 + chance_modifier)) then 64 return; 65 end 66 67 -- Compute an effect duration time based on the characters' stats 68 local effect_duration = clampDuration(user:GetMagAtk() - target_actor:GetMagDef()) 69 target_actor:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_PHYS_ATK, 70 vt_global.GameGlobal.GLOBAL_INTENSITY_NEG_MODERATE, 71 effect_duration); 72end 73 74-- All attack skills definitions are stored in this table 75if (skills == nil) then 76 skills = {} 77end 78 79-------------------------------------------------------------------------------- 80-- IDs 1 - 1,000 are reserved for character attack skills 81-------------------------------------------------------------------------------- 82 83skills[1] = { 84 name = vt_system.Translate("Sword Slash"), 85 description = vt_system.Translate("A textbook maneuver that deals an effective blow."), 86 sp_required = 0, 87 warmup_time = 1200, 88 cooldown_time = 200, 89 action_name = "attack", 90 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE, 91 92 BattleExecute = function(user, target) 93 local target_actor = target:GetActor(); 94 95 if (vt_battle.RndEvade(target_actor) == false) then 96 -- Normal +0 attack 97 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor), target); 98 AudioManager:PlaySound("data/sounds/swordslice1.wav"); 99 else 100 target_actor:RegisterMiss(true); 101 AudioManager:PlaySound("data/sounds/sword_swipe.wav"); 102 end 103 end, 104 105 animation_scripts = { 106 [BRONANN] = "data/battles/characters_animations/bronann_attack.lua", 107 [THANIS] = "data/battles/characters_animations/thanis_attack.lua" 108 } 109} 110 111skills[2] = { 112 name = vt_system.Translate("Forward Thrust"), 113 show_notice = true, 114 description = vt_system.Translate("A concentrated attack on an enemy."), 115 sp_required = 2, 116 warmup_time = 800, 117 cooldown_time = 200, 118 action_name = "attack", 119 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 120 121 BattleExecute = function(user, target) 122 local target_actor = target:GetActor(); 123 local attack_point = target:GetAttackPoint(); 124 125 if (vt_battle.RndEvade(target_actor, 0, 1.0, attack_point) == false) then 126 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 0, 1.30, attack_point), target); 127 else 128 target_actor:RegisterMiss(true); 129 AudioManager:PlaySound("data/sounds/sword_swipe.wav"); 130 end 131 132 end, 133 134 animation_scripts = { 135 [BRONANN] = "data/battles/characters_animations/bronann_attack_forward_thrust.lua", 136 [KALYA] = "data/battles/characters_animations/kalya_double_attack.lua", 137 [THANIS] = "data/battles/characters_animations/thanis_attack.lua" 138 } 139} 140 141skills[3] = { 142 name = vt_system.Translate("Stun Strike"), 143 show_notice = true, 144 description = vt_system.Translate("A blow which temporarily stun its target."), 145 sp_required = 4, 146 warmup_time = 1200, 147 cooldown_time = 200, 148 action_name = "attack", 149 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 150 151 BattleExecute = function(user, target) 152 local target_actor = target:GetActor(); 153 local atk_point = target:GetAttackPoint(); 154 155 if (vt_battle.RndEvade(target_actor, 5.5, 1.0, atk_point) == false) then 156 -- Calculate chance for paralysis effect and activate it 157 trigger_potential_stun(user, target); 158 159 -- The damages are applied after the potential effects, so that a potential target death handles the effect removal properly 160 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 0, 1.0, atk_point), target); 161 AudioManager:PlaySound("data/sounds/swordslice1.wav"); 162 else 163 target_actor:RegisterMiss(true); 164 AudioManager:PlaySound("data/sounds/sword_swipe.wav"); 165 end 166 end, 167 168 animation_scripts = { 169 [BRONANN] = "data/battles/characters_animations/bronann_attack.lua", 170 [KALYA] = "data/battles/characters_animations/kalya_attack.lua", 171 [THANIS] = "data/battles/characters_animations/thanis_attack.lua" 172 } 173} 174 175 176 177skills[4] = { 178 name = vt_system.Translate("X-Strike"), 179 show_notice = true, 180 description = vt_system.Translate("A strong and aggressive attack with a blade that deals significant damage."), 181 sp_required = 32, 182 warmup_time = 2500, 183 cooldown_time = 1000, 184 action_name = "attack", 185 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE, 186 187 BattleExecute = function(user, target) 188 local target_actor = target:GetActor(); 189 190 if (vt_battle.RndEvade(target_actor, 8.5) == false) then 191 local effect_duration = clampDuration(user:GetMagAtk()) 192 target_actor:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_STAMINA, 193 vt_global.GameGlobal.GLOBAL_INTENSITY_NEG_GREATER, 194 effect_duration); 195 196 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 20), target); 197 AudioManager:PlaySound("data/sounds/swordslice2.wav"); 198 else 199 target_actor:RegisterMiss(true); 200 AudioManager:PlaySound("data/sounds/sword_swipe.wav"); 201 end 202 end, 203 204 animation_scripts = { 205 [BRONANN] = "data/battles/characters_animations/bronann_attack.lua", 206 [THANIS] = "data/battles/characters_animations/thanis_blade_rush_attack.lua" 207 } 208} 209 210-- Kalya first attack 211skills[5] = { 212 name = vt_system.Translate("Single Shot"), 213 description = vt_system.Translate("A simple shot using an arbalest."), 214 sp_required = 0, 215 warmup_time = 2500, 216 cooldown_time = 200, 217 action_name = "attack", 218 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE, 219 220 BattleExecute = function(user, target) 221 local target_actor = target:GetActor(); 222 223 if (vt_battle.RndEvade(target_actor) == false) then 224 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 5), target); 225 AudioManager:PlaySound("data/sounds/crossbow.ogg"); 226 else 227 target_actor:RegisterMiss(true); 228 AudioManager:PlaySound("data/sounds/crossbow_miss.ogg"); 229 end 230 end, 231 232 animation_scripts = { 233 [KALYA] = "data/battles/characters_animations/kalya_attack.lua" 234 } 235} 236 237skills[6] = { 238 name = vt_system.Translate("Blade Rush"), 239 show_notice = true, 240 description = vt_system.Translate("A strong and aggressive attack with a blade that deals significant damage."), 241 sp_required = 100, 242 warmup_time = 5000, 243 cooldown_time = 3000, 244 action_name = "attack", 245 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE, 246 247 BattleExecute = function(user, target) 248 local target_actor = target:GetActor(); 249 250 if (vt_battle.RndEvade(target_actor, 8.5) == false) then 251 local effect_duration = clampDuration(user:GetMagAtk()) 252 target_actor:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_STAMINA, 253 vt_global.GameGlobal.GLOBAL_INTENSITY_NEG_GREATER, 254 effect_duration); 255 256 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 20), target); 257 AudioManager:PlaySound("data/sounds/swordslice2.wav"); 258 else 259 target_actor:RegisterMiss(true); 260 AudioManager:PlaySound("data/sounds/sword_swipe.wav"); 261 end 262 end, 263 264 animation_scripts = { 265 [BRONANN] = "data/battles/characters_animations/bronann_attack.lua", 266 [THANIS] = "data/battles/characters_animations/thanis_blade_rush_attack.lua" 267 } 268} 269 270-- Kalya's attacks 271skills[101] = { 272 name = vt_system.Translate("Incapacitating Shot"), 273 show_notice = true, 274 description = vt_system.Translate("A powerful shot aimed at lowering the enemy's ability to attack."), 275 sp_required = 14, 276 warmup_time = 2700, 277 cooldown_time = 600, 278 action_name = "attack", 279 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 280 281 BattleExecute = function(user, target) 282 local target_actor = target:GetActor(); 283 local atk_point = target:GetAttackPoint(); 284 285 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 286 -- Calculate chance for attack lowering effect and activate it 287 trigger_potential_attack_lowering(user, target); 288 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 15, 1.0, atk_point), target); 289 AudioManager:PlaySound("data/sounds/crossbow.ogg"); 290 else 291 target_actor:RegisterMiss(true); 292 AudioManager:PlaySound("data/sounds/crossbow_miss.ogg"); 293 end 294 end, 295 296 animation_scripts = { 297 [KALYA] = "data/battles/characters_animations/kalya_attack.lua" 298 } 299} 300 301skills[102] = { 302 name = vt_system.Translate("Rain of Arrows"), 303 show_notice = true, 304 description = vt_system.Translate("An attack striking all enemies."), 305 sp_required = 28, 306 warmup_time = 3500, 307 cooldown_time = 1000, 308 action_name = "attack", 309 target_type = vt_global.GameGlobal.GLOBAL_TARGET_ALL_FOES, 310 311 BattleExecute = function(user, target) 312 local index = 0; 313 while (target:GetPartyActor(index) ~= nil) do 314 local target_actor = target:GetPartyActor(index) 315 316 if (vt_battle.RndEvade(target_actor) == false) then 317 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 5), target); 318 AudioManager:PlaySound("data/sounds/crossbow.ogg"); 319 else 320 target_actor:RegisterMiss(true); 321 AudioManager:PlaySound("data/sounds/crossbow_miss.ogg"); 322 end 323 324 index = index + 1 325 end 326 end, 327 328 animation_scripts = { 329 [KALYA] = "data/battles/characters_animations/kalya_attack_party_target.lua" 330 } 331} 332 333-- Sylve first attack 334skills[200] = { 335 name = vt_system.Translate("Dagger Slash"), 336 description = vt_system.Translate("A simple but efficient dagger attack."), 337 sp_required = 0, 338 warmup_time = 1000, 339 cooldown_time = 200, 340 action_name = "attack", 341 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 342 343 BattleExecute = function(user, target) 344 local target_actor = target:GetActor(); 345 local atk_point = target:GetAttackPoint(); 346 347 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 348 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 5, 1.0, atk_point), target); 349 AudioManager:PlaySound("data/sounds/swordslice2.wav"); 350 else 351 target_actor:RegisterMiss(true); 352 AudioManager:PlaySound("data/sounds/missed_target.wav"); 353 end 354 end 355} 356 357skills[201] = { 358 name = vt_system.Translate("Poison Slash"), 359 show_notice = true, 360 description = vt_system.Translate("A dagger attack, poisoning the enemy."), 361 sp_required = 5, 362 warmup_time = 1000, 363 cooldown_time = 200, 364 action_name = "attack", 365 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 366 367 BattleExecute = function(user, target) 368 local target_actor = target:GetActor(); 369 local atk_point = target:GetAttackPoint(); 370 371 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 372 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 5, 1.0, atk_point), target); 373 -- TODO: Add poison damage 374 AudioManager:PlaySound("data/sounds/swordslice2.wav"); 375 else 376 target_actor:RegisterMiss(true); 377 AudioManager:PlaySound("data/sounds/missed_target.wav"); 378 end 379 end 380} 381 382skills[202] = { 383 name = vt_system.Translate("High Strike"), 384 show_notice = true, 385 description = vt_system.Translate("A strike from above, stunning the enemy and breaking its magical defense."), 386 sp_required = 10, 387 warmup_time = 1000, 388 cooldown_time = 200, 389 action_name = "attack", 390 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 391 392 BattleExecute = function(user, target) 393 local target_actor = target:GetActor(); 394 local atk_point = target:GetAttackPoint(); 395--TODO 396 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 397 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 5, 1.0, atk_point), target); 398 -- TODO: Add poison damage 399 AudioManager:PlaySound("data/sounds/swordslice2.wav"); 400 else 401 target_actor:RegisterMiss(true); 402 AudioManager:PlaySound("data/sounds/missed_target.wav"); 403 end 404 end 405} 406 407skills[203] = { 408 name = vt_system.Translate("Sonic Wind"), 409 show_notice = true, 410 description = vt_system.Translate("Deals high wind damage to all enemies, stunning them along the way."), 411 sp_required = 100, 412 warmup_time = 3000, 413 cooldown_time = 1200, 414 action_name = "attack", 415 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 416 417 BattleExecute = function(user, target) 418 local target_actor = target:GetActor(); 419 local atk_point = target:GetAttackPoint(); 420--TODO 421 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 422 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 5, 1.0, atk_point), target); 423 AudioManager:PlaySound("data/sounds/swordslice2.wav"); 424 else 425 target_actor:RegisterMiss(true); 426 AudioManager:PlaySound("data/sounds/missed_target.wav"); 427 end 428 end 429} 430 431-- Thanis attacks 432skills[300] = { 433 name = vt_system.Translate("Sword Breaker"), 434 show_notice = true, 435 description = vt_system.Translate("An attack that breaks the enemy's own attack power."), 436 sp_required = 6, 437 warmup_time = 2000, 438 cooldown_time = 500, 439 action_name = "attack", 440 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 441 442 BattleExecute = function(user, target) 443 local target_actor = target:GetActor(); 444 local atk_point = target:GetAttackPoint(); 445--TODO 446 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 447 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 5, 1.0, atk_point), target); 448 AudioManager:PlaySound("data/sounds/swordslice2.wav"); 449 else 450 target_actor:RegisterMiss(true); 451 AudioManager:PlaySound("data/sounds/missed_target.wav"); 452 end 453 end, 454 455 animation_scripts = { 456 [THANIS] = "data/battles/characters_animations/thanis_attack.lua" 457 } 458} 459 460skills[301] = { 461 name = vt_system.Translate("Execution"), 462 show_notice = true, 463 description = vt_system.Translate("Attacks an enemy with a chance of causing death to catch its soul."), 464 sp_required = 48, 465 warmup_time = 4000, 466 cooldown_time = 1500, 467 action_name = "attack", 468 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 469 470 BattleExecute = function(user, target) 471 local target_actor = target:GetActor(); 472 local atk_point = target:GetAttackPoint(); 473--TODO 474 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 475 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 5, 1.0, atk_point), target); 476 AudioManager:PlaySound("data/sounds/swordslice2.wav"); 477 else 478 target_actor:RegisterMiss(true); 479 AudioManager:PlaySound("data/sounds/missed_target.wav"); 480 end 481 end, 482} 483 484-------------------------------------------------------------------------------- 485-- IDs 1,001 - 10,000 are reserved for enemy attack skills 486-------------------------------------------------------------------------------- 487 488skills[1001] = { 489 name = "Slime Attack", 490 sp_required = 0, 491 warmup_time = 1100, 492 cooldown_time = 500, 493 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 494 495 animation_scripts = { 496 -- N.B.: [1] is the enemy ID. 497 [1] = "data/battles/enemies_animations/standard_enemy_attack.lua", 498 [6] = "data/battles/enemies_animations/standard_enemy_attack.lua", 499 }, 500 501 BattleExecute = function(user, target) 502 local target_actor = target:GetActor(); 503 local atk_point = target:GetAttackPoint(); 504 505 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 506 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 10, 1.0, atk_point), target); 507 AudioManager:PlaySound("data/sounds/slime_attack.wav"); 508 else 509 target_actor:RegisterMiss(true); 510 AudioManager:PlaySound("data/sounds/missed_target.wav"); 511 end 512 end 513} 514 515skills[1002] = { 516 name = "Spider Bite", 517 sp_required = 0, 518 warmup_time = 1400, 519 cooldown_time = 0, 520 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 521 522 animation_scripts = { 523 -- N.B.: [2] is the enemy ID. 524 [2] = "data/battles/enemies_animations/standard_enemy_attack.lua", 525 }, 526 527 BattleExecute = function(user, target) 528 local target_actor = target:GetActor(); 529 local atk_point = target:GetAttackPoint(); 530 531 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 532 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 13, 1.0, atk_point), target); 533 AudioManager:PlaySound("data/sounds/spider_attack.wav"); 534 else 535 target_actor:RegisterMiss(true); 536 AudioManager:PlaySound("data/sounds/missed_target.wav"); 537 end 538 end 539} 540 541skills[1003] = { 542 name = "Snake Bite", 543 sp_required = 0, 544 warmup_time = 900, 545 cooldown_time = 0, 546 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 547 548 animation_scripts = { 549 -- N.B.: [4] is the enemy ID. 550 [4] = "data/battles/enemies_animations/standard_enemy_attack.lua", 551 }, 552 553 BattleExecute = function(user, target) 554 local target_actor = target:GetActor(); 555 local atk_point = target:GetAttackPoint(); 556 557 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 558 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 14, 1.0, atk_point), target); 559 AudioManager:PlaySound("data/sounds/snake_attack.wav"); 560 else 561 target_actor:RegisterMiss(true); 562 AudioManager:PlaySound("data/sounds/missed_target.wav"); 563 end 564 end 565} 566 567skills[1004] = { 568 name = vt_system.Translate("Stun Bite"), 569 icon = "data/skills/monster_attacks/animal-fangs.png", 570 show_notice = true, 571 sp_required = 1, 572 warmup_time = 3000, 573 cooldown_time = 1000, 574 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 575 576 animation_scripts = { 577 -- N.B.: [4] is the enemy ID. 578 [4] = "data/battles/enemies_animations/standard_enemy_attack.lua", 579 }, 580 581 BattleExecute = function(user, target) 582 local target_actor = target:GetActor(); 583 local atk_point = target:GetAttackPoint(); 584 585 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 586 -- Calculate chance for paralysis effect and activate it 587 trigger_potential_stun(user, target); 588 589 -- The damages are applied after the potential effects, so that a potential target death handles the effect removal properly 590 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 14, 1.0, atk_point), target); 591 AudioManager:PlaySound("data/sounds/snake_attack.wav"); 592 else 593 target_actor:RegisterMiss(true); 594 AudioManager:PlaySound("data/sounds/missed_target.wav"); 595 end 596 end 597} 598 599skills[1005] = { 600 -- Snake Dampening Bite 601 name = vt_system.Translate("Dampening Bite"), 602 icon = "data/skills/monster_attacks/animal-fangs.png", 603 show_notice = true, 604 sp_required = 2, 605 warmup_time = 5000, 606 cooldown_time = 2000, 607 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 608 609 animation_scripts = { 610 -- N.B.: [4] is the enemy ID. 611 [4] = "data/battles/enemies_animations/snake_dampen_attack.lua", 612 [12] = "data/battles/enemies_animations/snake_dampen_attack.lua", 613 }, 614 615 BattleExecute = function(user, target) 616 local target_actor = target:GetActor(); 617 local atk_point = target:GetAttackPoint(); 618 619 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 620 local effect_duration = clampDuration(user:GetMagAtk()) 621 target_actor:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_STAMINA, 622 vt_global.GameGlobal.GLOBAL_INTENSITY_NEG_LESSER, 623 effect_duration); 624 625 -- The damages are applied after the potential effects, so that a potential target death handles the effect removal properly 626 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 6, 1.0, atk_point), target); 627 AudioManager:PlaySound("data/sounds/bite_01.ogg"); 628 else 629 target_actor:RegisterMiss(true); 630 AudioManager:PlaySound("data/sounds/missed_target.wav"); 631 end 632 end 633} 634 635skills[1006] = { 636 name = "Skeleton Sword Attack", 637 sp_required = 0, 638 warmup_time = 1400, 639 cooldown_time = 0, 640 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 641 642 BattleExecute = function(user, target) 643 local target_actor = target:GetActor(); 644 local atk_point = target:GetAttackPoint(); 645 646 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 647 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 20, 1.0, atk_point), target); 648 AudioManager:PlaySound("data/sounds/skeleton_attack.wav"); 649 else 650 target_actor:RegisterMiss(true); 651 AudioManager:PlaySound("data/sounds/missed_target.wav"); 652 end 653 end 654} 655 656skills[1007] = { 657 name = vt_system.Translate("HP Drain"), 658 icon = "data/skills/monster_attacks/animal-fangs.png", 659 show_notice = true, 660 sp_required = 2, 661 warmup_time = 5000, 662 cooldown_time = 2000, 663 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 664 665 animation_scripts = { 666 -- N.B.: [6] is the enemy ID. 667 [6] = "data/battles/enemies_animations/bat_drain_attack.lua", 668 [11] = "data/battles/enemies_animations/bat_drain_attack.lua", 669 [12] = "data/battles/enemies_animations/bat_drain_attack.lua", 670 }, 671 672 BattleExecute = function(user, target) 673 local target_actor = target:GetActor(); 674 local atk_point = target:GetAttackPoint(); 675 676 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 677 local hp_drain = vt_battle.RndPhysicalDamage(user, target_actor, 8, 1.0, atk_point); 678 target_actor:RegisterDamage(hp_drain, target); 679 -- If the damage dealt was 1, don't recover any HP from the attack 680 if (hp_drain > 0) then 681 user:RegisterHealing(hp_drain, true); 682 end 683 AudioManager:PlaySound("data/sounds/bite_01.ogg") 684 else 685 target_actor:RegisterMiss(true); 686 AudioManager:PlaySound("data/sounds/missed_target.wav") 687 end 688 end 689} 690 691skills[1008] = { 692 name = "Fenrir Attack", 693 sp_required = 0, 694 warmup_time = 1200, 695 cooldown_time = 300, 696 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 697 698 animation_scripts = { 699 -- N.B.: [3] is the enemy ID. 700 [3] = "data/battles/enemies_animations/wolf_claw_attack.lua", 701 [7] = "data/battles/enemies_animations/wolf_claw_attack.lua", 702 [8] = "data/battles/enemies_animations/wolf_claw_attack.lua", 703 }, 704 705 BattleExecute = function(user, target) 706 local target_actor = target:GetActor(); 707 local atk_point = target:GetAttackPoint(); 708 709 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 710 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 20, 1.0, atk_point), target); 711 AudioManager:PlaySound("data/sounds/bite_01.ogg") 712 else 713 target_actor:RegisterMiss(true); 714 AudioManager:PlaySound("data/sounds/missed_target.wav") 715 end 716 end 717} 718 719skills[1009] = { 720 -- Fenrir Multiple Attack 721 name = vt_system.Translate("Multiple Attack"), 722 icon = "data/skills/monster_attacks/animal-fangs.png", 723 show_notice = true, 724 sp_required = 1, 725 warmup_time = 1600, 726 cooldown_time = 500, 727 target_type = vt_global.GameGlobal.GLOBAL_TARGET_ALL_FOES, 728 729 animation_scripts = { 730 -- N.B.: [3] is the enemy ID. 731 [3] = "data/battles/enemies_animations/wolf_fangs_party_attack.lua", 732 [7] = "data/battles/enemies_animations/wolf_fangs_party_attack.lua", 733 [8] = "data/battles/enemies_animations/wolf_fangs_party_attack.lua", 734 }, 735 736 BattleExecute = function(user, target) 737 local index = 0; 738 while true do 739 local target_actor = target:GetPartyActor(index); 740 if (target_actor == nil) then 741 break; 742 end 743 744 if (target_actor:IsAlive() == true and vt_battle.RndEvade(target_actor) == false) then 745 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 40)); 746 AudioManager:PlaySound("data/sounds/bite_02.ogg") 747 else 748 target_actor:RegisterMiss(true); 749 end 750 751 index = index + 1; 752 end 753 end 754} 755 756skills[1010] = { 757 name = "Rat Poison Bite", 758 sp_required = 5, 759 warmup_time = 900, 760 cooldown_time = 100, 761 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 762 763 animation_scripts = { 764 -- N.B.: [X] is the enemy ID. 765 [16] = "data/battles/enemies_animations/rat_poison_bite_attack.lua", 766 }, 767 768 BattleExecute = function(user, target) 769 local target_actor = target:GetActor(); 770 local atk_point = target:GetAttackPoint(); 771 772 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 773 local intensity = target_actor:GetActiveStatusEffectIntensity(vt_global.GameGlobal.GLOBAL_STATUS_HP); 774 775 -- Only apply up to a moderate poison 776 if (intensity > vt_global.GameGlobal.GLOBAL_INTENSITY_NEG_MODERATE) then 777 local effect_duration = clampDuration(user:GetMagAtk()) 778 target_actor:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_HP, 779 vt_global.GameGlobal.GLOBAL_INTENSITY_NEG_LESSER, 780 effect_duration); 781 end 782 783 -- The damages are applied after the potential effects, so that a potential target death handles the effect removal properly 784 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 6, 1.0, atk_point), target); 785 else 786 target_actor:RegisterMiss(true); 787 AudioManager:PlaySound("data/sounds/missed_target.wav") 788 end 789 end 790} 791 792skills[1011] = { 793 -- Skeleton Frenzy Attack 794 name = vt_system.Translate("Frenzy Attack"), 795 show_notice = true, 796 sp_required = 10, 797 warmup_time = 2400, 798 cooldown_time = 500, 799 target_type = vt_global.GameGlobal.GLOBAL_TARGET_ALL_FOES, 800 801 animation_scripts = { 802 -- N.B.: [19] is the enemy ID. 803 [19] = "data/battles/enemies_animations/skeleton_frenzy_attack.lua", 804 }, 805 806 BattleExecute = function(user, target) 807 local index = 0; 808 while true do 809 local target_actor = target:GetPartyActor(index); 810 if (target_actor == nil) then 811 break; 812 end 813 814 if (target_actor:IsAlive() == true and vt_battle.RndEvade(target_actor) == false) then 815 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 25), target); 816 AudioManager:PlaySound("data/sounds/skeleton_attack.wav"); 817 else 818 target_actor:RegisterMiss(true); 819 AudioManager:PlaySound("data/sounds/missed_target.wav"); 820 end 821 822 index = index + 1; 823 end 824 end 825} 826 827skills[1012] = { 828 name = vt_system.Translate("Stamina Steal"), 829 show_notice = true, 830 sp_required = 12, 831 warmup_time = 2400, 832 cooldown_time = 500, 833 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE, 834 835 animation_scripts = { 836 -- N.B.: [X] is the enemy ID. 837 [15] = "data/battles/enemies_animations/slime_water_spray_attack.lua", -- Beetle 838 }, 839 840 BattleExecute = function(user, target) 841 local target_actor = target:GetActor(); 842 843 if (vt_battle.RndEvade(target_actor) == false) then 844 local effect_duration = clampDuration(user:GetMagAtk()) 845 target_actor:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_STAMINA, 846 vt_global.GameGlobal.GLOBAL_INTENSITY_NEG_MODERATE, 847 effect_duration); 848 user:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_STAMINA, 849 vt_global.GameGlobal.GLOBAL_INTENSITY_POS_MODERATE, 850 effect_duration); 851 852 -- The damages are applied after the potential effects, so that a potential target death handles the effect removal properly 853 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 6), target); 854 AudioManager:PlaySound("data/sounds/spider_attack.wav"); 855 else 856 target_actor:RegisterMiss(true); 857 AudioManager:PlaySound("data/sounds/missed_target.wav"); 858 end 859 end 860} 861 862skills[1013] = { 863 name = "Dorver Frenzy", 864 sp_required = 10, 865 warmup_time = 2900, 866 cooldown_time = 1000, 867 target_type = vt_global.GameGlobal.GLOBAL_TARGET_SELF, 868 869 BattleExecute = function(user, target) -- target is self, we'll use user... 870 -- Add phys_atk & stamina, but decrease defense 871 local effect_duration = clampDuration(user:GetMagAtk()) 872 user:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_PHYS_ATK, 873 vt_global.GameGlobal.GLOBAL_INTENSITY_POS_MODERATE, 874 effect_duration); 875 user:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_STAMINA, 876 vt_global.GameGlobal.GLOBAL_INTENSITY_POS_MODERATE, 877 effect_duration); 878 user:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_PHYS_DEF, 879 vt_global.GameGlobal.GLOBAL_INTENSITY_NEG_MODERATE, 880 effect_duration); 881 882 AudioManager:PlaySound("data/sounds/defense1_spell.ogg"); 883 end 884} 885 886skills[1014] = { 887 name = "Andromalius Ground Hit", 888 sp_required = 0, 889 warmup_time = 1900, 890 cooldown_time = 1000, 891 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE, 892 893 BattleExecute = function(user, target) 894 local target_actor = target:GetActor(); 895 896 if (vt_battle.RndEvade(target_actor) == false) then 897 local effect_duration = clampDuration(user:GetMagAtk()) 898 target_actor:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_STAMINA, 899 vt_global.GameGlobal.GLOBAL_INTENSITY_NEG_MODERATE, 900 effect_duration); 901 902 -- The damages are applied after the potential effects, so that a potential target death handles the effect removal properly 903 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 6), target); 904 AudioManager:PlaySound("data/sounds/cave-in.ogg"); 905 else 906 target_actor:RegisterMiss(true); 907 end 908 end 909} 910 911skills[1015] = { 912 name = vt_system.Translate("Water Spray"), 913 icon = "data/skills/monster_attacks/waterspray.png", 914 show_notice = true, 915 sp_required = 0, 916 warmup_time = 1100, 917 cooldown_time = 500, 918 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 919 920 animation_scripts = { 921 -- N.B.: [1] is the slime enemy ID. 922 [1] = "data/battles/enemies_animations/slime_water_spray_attack.lua", 923 }, 924 925 BattleExecute = function(user, target) 926 local target_actor = target:GetActor(); 927 local atk_point = target:GetAttackPoint(); 928 929 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 930 local effect_duration = clampDuration(user:GetMagAtk()) 931 target_actor:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_EVADE, 932 vt_global.GameGlobal.GLOBAL_INTENSITY_NEG_LESSER, 933 effect_duration); 934 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 10, 1.0, atk_point), target); 935 936 local Battle = ModeManager:GetTop(); 937 Battle:TriggerBattleParticleEffect("data/visuals/particle_effects/waterspray_skill.lua", 938 target_actor:GetXLocation(), target_actor:GetYLocation()); 939 else 940 target_actor:RegisterMiss(true); 941 end 942 -- Play the sound in any case 943 AudioManager:PlaySound("data/sounds/watersplash.wav"); 944 end 945} 946 947skills[1016] = { 948 name = vt_system.Translate("Spider Web"), 949 icon = "data/skills/monster_attacks/web.png", 950 show_notice = true, 951 sp_required = 0, 952 warmup_time = 1100, 953 cooldown_time = 500, 954 target_type = vt_global.GameGlobal.GLOBAL_TARGET_FOE_POINT, 955 956 animation_scripts = { 957 -- N.B.: [2] is the spider enemy ID. 958 [2] = "data/battles/enemies_animations/spider_web_attack.lua", 959 }, 960 961 BattleExecute = function(user, target) 962 local target_actor = target:GetActor(); 963 local atk_point = target:GetAttackPoint(); 964 965 if (vt_battle.RndEvade(target_actor, 0.0, 1.0, atk_point) == false) then 966 local effect_duration = clampDuration(user:GetMagAtk()) 967 target_actor:ApplyActiveStatusEffect(vt_global.GameGlobal.GLOBAL_STATUS_STAMINA, 968 vt_global.GameGlobal.GLOBAL_INTENSITY_NEG_MODERATE, 969 effect_duration); 970 target_actor:RegisterDamage(vt_battle.RndPhysicalDamage(user, target_actor, 13, 1.0, atk_point), target); 971 else 972 target_actor:RegisterMiss(true); 973 end 974 -- Play the sound in any case 975 AudioManager:PlaySound("data/sounds/missed_target.wav"); 976 end 977} 978