//***************************************************************************
//* Fiery Slash
//*
//* Created by: Ofel The Editor
//* Version: 1.2
//*
//* =========================================================================
//*
//* Credits :
//* - Tank-Commander: Basic indexing.
//*
//* =========================================================================
//*
//* Changelog :
//* - v1.0: Initial version.
//* - v1.1: More configurables, fixed some things.
//* - v1.2: Fixed more things.
//*
//***************************************************************************
//***************************************************************************
//*
//* Configuration
//*
//***************************************************************************
//---- Ability raw code (Ctrl + D on Object Editor to display) ----\\
constant function FS_AbilityID takes nothing returns integer
return 'A000'
endfunction
//---- Loop interval ----\\
constant function FS_Interval takes nothing returns real
return 0.03125
endfunction
//---- Travelling time to target (in second) ----\\
constant function FS_TravelTime takes nothing returns real
return 0.45
endfunction
//---- Animation index played when moving to target ----\\
constant function FS_AnimationIndex takes nothing returns integer
return 2
endfunction
//---- Minimum distance between caster and target ----\\
constant function FS_SlashDistance takes nothing returns real
return 100.00
endfunction
//---- Damage range when moving ----\\
constant function FS_Collision takes nothing returns real
return 75.00
endfunction
//---- Damage per second duration to unit that hitted by caster when moving ----\\
constant function FS_HitDPSDuration takes nothing returns real
return 5.00
endfunction
//---- Damage per second duration to target ----\\
constant function FS_SlashDPSDuration takes nothing returns real
return 8.00
endfunction
//---- Effect attached to caster when moving ----\\
constant function FS_WeaponSFX takes nothing returns string
return "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
endfunction
//---- Attachment point for FS_WeaponSFX ----\\
constant function FS_WeaponSFXAttach takes nothing returns string
return "weapon"
endfunction
//---- Effect attached to unit that hitted by caster when moving ----\\
constant function FS_HitSFX takes nothing returns string
return "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
endfunction
//---- Attachment point for FS_HitSFX ----\\
constant function FS_HitSFXAttach takes nothing returns string
return "chest"
endfunction
//---- Effect attached to target when slashed ----\\
constant function FS_SlashSFX takes nothing returns string
return "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"
endfunction
//---- Attachment point for FS_SlashSFX ----\\
constant function FS_SlashSFXAttach takes nothing returns string
return "origin"
endfunction
//---- Effect attached to burning unit ----\\
constant function FS_BurnSFX takes nothing returns string
return "Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl"
endfunction
//---- Attachment point for FS_BurnSFX ----\\
constant function FS_BurnSFXAttach takes nothing returns string
return "chest"
endfunction
//---- Attack-type ----\\
constant function FS_HitAttackType takes nothing returns attacktype
return ATTACK_TYPE_NORMAL
endfunction
//---- Damage-type ----\\
constant function FS_HitDamageType takes nothing returns damagetype
return DAMAGE_TYPE_FIRE
endfunction
//---- Attack-type ----\\
constant function FS_SlashAttackType takes nothing returns attacktype
return ATTACK_TYPE_NORMAL
endfunction
//---- Damage-type ----\\
constant function FS_SlashDamageType takes nothing returns damagetype
return DAMAGE_TYPE_FIRE
endfunction
//---- Attack-type ----\\
constant function FS_BurnAttackType takes nothing returns attacktype
return ATTACK_TYPE_NORMAL
endfunction
//---- Damage-type ----\\
constant function FS_BurnDamageType takes nothing returns damagetype
return DAMAGE_TYPE_FIRE
endfunction
//---- Damage dealt to unit hitted by caster when moving ----\\
function FS_HitDamage takes real level returns real
return level * 10 + 40
endfunction
//---- Damage per second dealt to unit hitted by caster when moving ----\\
function FS_HitDPS takes real level returns real
return level * 5
endfunction
//---- Damage dealt to target when slashed ----\\
function FS_SlashDamage takes real level returns real
return level * 25 + 75
endfunction
//---- Damage per second dealt to target when slashed ----\\
function FS_SlashDPS takes real level returns real
return level * 10
endfunction
//---- Checker to units that are going to be damaged if all the conditions are true ----\\
function FS_FilterUnit takes unit u, integer index returns boolean
if (IsUnitEnemy(u, udg_FS_Owner[index]) and IsUnitType(u, UNIT_TYPE_FLYING) == false and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) == false) then
return true
endif
return false
endfunction
//***************************************************************************
//*
//* End of Configuration
//*
//***************************************************************************
//***************************************************************************
//*
//* Periodic Function
//*
//***************************************************************************
function FS_Periodic takes nothing returns nothing
local real x
local real y
local real x2
local real y2
local real angle
local real dist
local real speed
local unit u
local integer index = 1
loop
exitwhen index > udg_FS_MaxIndex
if (udg_FS_Stage[index] == 1) then
if (GetWidgetLife(udg_FS_Unit[index]) > 0.405 and GetWidgetLife(udg_FS_Target[index]) > 0.405 and udg_FS_Active[index]) then
set x = GetUnitX(udg_FS_Unit[index])
set y = GetUnitY(udg_FS_Unit[index])
set x2 = GetUnitX(udg_FS_Target[index])
set y2 = GetUnitY(udg_FS_Target[index])
set angle = Atan2(y2 - y, x2 - x)
set x2 = x2 - FS_SlashDistance() * Cos(angle)
set y2 = y2 - FS_SlashDistance() * Sin(angle)
set dist = SquareRoot((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y))
set udg_FS_Counter[index] = udg_FS_Counter[index] - FS_Interval()
if (udg_FS_Counter[index] > 0.05) then
set speed = dist / (udg_FS_Counter[index] / FS_Interval())
set x = x + speed * Cos(angle)
set y = y + speed * Sin(angle)
call SetUnitX(udg_FS_Unit[index], x)
call SetUnitY(udg_FS_Unit[index], y)
call GroupEnumUnitsInRange(udg_FS_TempGroup, x, y, FS_Collision(), null)
loop
set u = FirstOfGroup(udg_FS_TempGroup)
exitwhen u == null
if (FS_FilterUnit(u, index) and IsUnitInGroup(u, udg_FS_DamagedGroup[index]) == false and u != udg_FS_Target[index]) then
call DestroyEffect(AddSpecialEffectTarget(FS_HitSFX(), u, FS_HitSFXAttach()))
call UnitDamageTarget(udg_FS_Unit[index], u, FS_HitDamage(udg_FS_Level[index]), true, false, FS_HitAttackType(), FS_HitDamageType(), null)
call GroupAddUnit(udg_FS_DamagedGroup[index], u)
if (GetWidgetLife(u) > 0.405) then
set udg_FS_MaxIndex = udg_FS_MaxIndex + 1
set udg_FS_Target[udg_FS_MaxIndex] = udg_FS_Unit[index]
set udg_FS_Unit[udg_FS_MaxIndex] = u
set udg_FS_Duration[udg_FS_MaxIndex] = FS_HitDPSDuration()
set udg_FS_DPS[udg_FS_MaxIndex] = FS_HitDPS(udg_FS_Level[index])
set udg_FS_Counter[udg_FS_MaxIndex] = 0
set udg_FS_ModelFX[udg_FS_MaxIndex] = AddSpecialEffectTarget(FS_BurnSFX(), udg_FS_Unit[udg_FS_MaxIndex], FS_BurnSFXAttach())
set udg_FS_Stage[udg_FS_MaxIndex] = 2
endif
endif
call GroupRemoveUnit(udg_FS_TempGroup, u)
endloop
call GroupClear(udg_FS_TempGroup)
else
call SetUnitX(udg_FS_Unit[index], x2)
call SetUnitY(udg_FS_Unit[index], y2)
call UnitDamageTarget(udg_FS_Unit[index], udg_FS_Target[index], FS_SlashDamage(udg_FS_Level[index]), true, false, FS_SlashAttackType(), FS_SlashDamageType(), null)
call DestroyEffect(AddSpecialEffectTarget(FS_SlashSFX(), udg_FS_Target[index], FS_SlashSFXAttach()))
set udg_FS_MaxIndex = udg_FS_MaxIndex + 1
set udg_FS_Target[udg_FS_MaxIndex] = udg_FS_Unit[index]
set udg_FS_Unit[udg_FS_MaxIndex] = udg_FS_Target[index]
set udg_FS_Duration[udg_FS_MaxIndex] = FS_SlashDPSDuration()
set udg_FS_DPS[udg_FS_MaxIndex] = FS_SlashDPS(udg_FS_Level[index])
set udg_FS_Counter[udg_FS_MaxIndex] = 0
set udg_FS_ModelFX[udg_FS_MaxIndex] = AddSpecialEffectTarget(FS_BurnSFX(), udg_FS_Unit[udg_FS_MaxIndex], FS_BurnSFXAttach())
set udg_FS_Stage[udg_FS_MaxIndex] = 2
set udg_FS_Active[index] = false
endif
else
call DestroyEffect(udg_FS_ModelFX[index])
call DestroyGroup(udg_FS_DamagedGroup[index])
set udg_FS_Stage[index] = 3
endif
endif
if (udg_FS_Stage[index] == 2) then
if (GetWidgetLife(udg_FS_Unit[index]) > 0.405 and udg_FS_Duration[index] > 0) then
set udg_FS_Counter[index] = udg_FS_Counter[index] + FS_Interval()
if (udg_FS_Counter[index] > 1) then
call UnitDamageTarget(udg_FS_Target[index], udg_FS_Unit[index], udg_FS_DPS[index], true, false, FS_BurnAttackType(), FS_BurnDamageType(), null)
set udg_FS_Counter[index] = 0
endif
set udg_FS_Duration[index] = udg_FS_Duration[index] - FS_Interval()
else
call DestroyEffect(udg_FS_ModelFX[index])
call DestroyGroup(udg_FS_DamagedGroup[index])
set udg_FS_Stage[index] = 3
endif
endif
if (udg_FS_Stage[index] == 3) then
set udg_FS_Active[index] = udg_FS_Active[udg_FS_MaxIndex]
set udg_FS_Counter[index] = udg_FS_Counter[udg_FS_MaxIndex]
set udg_FS_DamagedGroup[index] = udg_FS_DamagedGroup[udg_FS_MaxIndex]
set udg_FS_DPS[index] = udg_FS_DPS[udg_FS_MaxIndex]
set udg_FS_Duration[index] = udg_FS_Duration[udg_FS_MaxIndex]
set udg_FS_Level[index] = udg_FS_Level[udg_FS_MaxIndex]
set udg_FS_ModelFX[index] = udg_FS_ModelFX[udg_FS_MaxIndex]
set udg_FS_Owner[index] = udg_FS_Owner[udg_FS_MaxIndex]
set udg_FS_Stage[index] = udg_FS_Stage[udg_FS_MaxIndex]
set udg_FS_Target[index] = udg_FS_Target[udg_FS_MaxIndex]
set udg_FS_Unit[index] = udg_FS_Unit[udg_FS_MaxIndex]
set udg_FS_MaxIndex = udg_FS_MaxIndex - 1
if (udg_FS_MaxIndex == 0) then
call PauseTimer(udg_FS_Timer)
endif
set index = index - 1
endif
set index = index + 1
endloop
endfunction
//***************************************************************************
//*
//* Starter Function
//*
//***************************************************************************
function FS_Cast takes nothing returns boolean
if (GetSpellAbilityId() == FS_AbilityID()) then
set udg_FS_MaxIndex = udg_FS_MaxIndex + 1
set udg_FS_Unit[udg_FS_MaxIndex] = GetTriggerUnit()
set udg_FS_Target[udg_FS_MaxIndex] = GetSpellTargetUnit()
set udg_FS_Owner[udg_FS_MaxIndex] = GetTriggerPlayer()
set udg_FS_Level[udg_FS_MaxIndex] = I2R(GetUnitAbilityLevel(udg_FS_Unit[udg_FS_MaxIndex], FS_AbilityID()))
set udg_FS_Counter[udg_FS_MaxIndex] = FS_TravelTime()
set udg_FS_ModelFX[udg_FS_MaxIndex] = AddSpecialEffectTarget(FS_WeaponSFX(), udg_FS_Unit[udg_FS_MaxIndex], FS_WeaponSFXAttach())
set udg_FS_DamagedGroup[udg_FS_MaxIndex] = CreateGroup()
set udg_FS_Active[udg_FS_MaxIndex] = true
set udg_FS_Stage[udg_FS_MaxIndex] = 1
call SetUnitAnimationByIndex(udg_FS_Unit[udg_FS_MaxIndex], FS_AnimationIndex())
if (udg_FS_MaxIndex == 1) then
call TimerStart(udg_FS_Timer, FS_Interval(), true, function FS_Periodic)
endif
endif
return false
endfunction
//***************************************************************************
//*
//* Initializer Function
//*
//***************************************************************************
function InitTrig_Fiery_Slash takes nothing returns nothing
set gg_trg_Fiery_Slash = CreateTrigger()
if (udg_FS_Timer == null) then
set udg_FS_Timer = CreateTimer()
endif
set udg_FS_TempGroup = CreateGroup()
call TriggerRegisterAnyUnitEventBJ(gg_trg_Fiery_Slash, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(gg_trg_Fiery_Slash, Filter(function FS_Cast))
endfunction