library FireBall initializer Init
globals // Globals of the Fire Balls and the spell.
private constant integer AbilityID = 'A001' //The Ability used to demonstrate the fireball.
private constant integer DummyID = 'u000' //A dummy unit to keep the effects.
private constant real Interval = 50 //How many times(frames) per second should the movement be executed?
private constant real SpeedPerSecond = 600.00
// Amount of range the fire ball moves per second.
private constant real LifeSpam = 2.00
// Amount of time the fire ball will fly.
private constant real AcquireTargetsRange = 60.00
// Enemy units in this range are considered targets; allow the fire ball to damage more than one unit.
private constant real DamageSplashRadius = 125.00
// Enemy units in this range get damaged
private constant real TextTagSize = 10.00
// The size of the text tags (floating texts) wich show the damage amount.
private constant real TextTagVelocity = 120.00
// The velocity of the text tags (floating texts)
private constant real TextTagFadePoint = 3.00
// At this point the text tag starts fading.
private constant real TextTagDeathPoint = 5.50
// At this point the text tag dies.
private constant real TextTagZoffset = 30.00
// Height of the text tag above the target.
private constant boolean TextTagVisible = true
// I guess you want it visible, don't you? SET TO "false" FOR NO TEXT TAGS
private constant string sfxpath = "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"
// This is the Special Effect created when the fire ball explodes.
// I strongly recommend using this effect for the fire ball.
private integer Total = 0
private timer Cycle = CreateTimer()
endglobals
private function Conditions takes nothing returns boolean
return (GetSpellAbilityId() == AbilityID)
endfunction
private constant function AntiLeak takes nothing returns boolean
return true
endfunction
private function Filtru takes nothing returns boolean
return (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > .405) and (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetEnumUnit())) == true)
endfunction
public struct Data
unit entity
real lifespam
real speed
real damage
real ar
real tr
integer i
string sfx
group Targets = CreateGroup()
method onDestroy takes nothing returns nothing
set .entity = null
endmethod
static method create takes real x, real y, real face, real end, real spd, real dmg, real ar, real tr, string sfxp returns Data
local Data dat = Data.allocate()
set dat.entity = CreateUnit( GetOwningPlayer(GetTriggerUnit()), DummyID, x, y, face)
set dat.lifespam = end
set dat.speed = spd
set dat.damage = dmg
set dat.ar = ar
set dat.tr = tr
set dat.sfx = sfxp
if Total <= 0 then
call TimerStart(Cycle, 1.00 / Interval, true, function Data.cycle)
endif
set Total = Total + 1
return dat
endmethod
private static method ITE takes nothing returns boolean
local Data dat
local integer i
call ForGroup(dat.Targets, function CountUnitsInGroupEnum)
set i = bj_groupCountUnits
if ( i >= 1 ) then
return true
endif
if ( dat.lifespam <= 0.00 ) then
return true
endif
return false
endmethod
private static method Damage takes nothing returns nothing
local Data dat
local unit u = GetEnumUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real dump = -2000000000
local texttag tt = CreateTextTag()
call SetTextTagVelocity(tt, 0, TextTagVelocity * 0.071 / 128 ) //The text will only go up. I used ' * 0.071 / 128' to avoid using a BJ.
call SetTextTagPermanent(tt, false )
call SetTextTagFadepoint(tt, TextTagFadePoint )
call SetTextTagLifespan(tt, TextTagDeathPoint )
call SetTextTagVisibility(tt, TextTagVisible )
call SetTextTagPosUnit(tt, u, TextTagZoffset)
if ( GetUnitAbilityLevel(u, 'Avul') == 0 ) and ( GetUnitAbilityLevel(u, 'Aloc') == 0 ) then
call SetTextTagText(tt, ( "Damage: " + ( I2S ( R2I (dat.damage) ) + " " ) ), TextTagSize * 0.023 / 10 )
call SetTextTagColor(tt, 230, 100, 150, 255 )
// R G B Alpha
elseif ( GetUnitAbilityLevel(u, 'Avul') == 1 ) then
call SetTextTagText(tt, "Damage: none", TextTagSize * 0.023 / 10 )
call SetTextTagColor(tt, 230, 200, 150, 255 )
// R G B Alpha
elseif ( GetUnitAbilityLevel(u, 'Aloc') == 1 ) and GetUnitTypeId(u) != DummyID then
call SetTextTagText(tt, "Missed", TextTagSize * 0.023 / 10 )
call SetTextTagColor(tt, 230, 200, 150, 255 )
// R G B Alpha
set dump = dat.damage
set dat.damage = 0
elseif GetUnitTypeId(u) == DummyID then
call SetTextTagText(tt, "Collided", TextTagSize * 0.023 / 10 )
call SetTextTagColor(tt, 150, 200, 230, 255 )
// R G B Alpha
endif
call UnitDamageTarget( dat.entity, u, dat.damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS )
if dump == -2000000000 then
set dat.damage = dump
endif
set u = null
endmethod
private static method cycle takes nothing returns nothing
local Data dat
local real angle = GetUnitFacing( dat.entity )
local real dist = dat.speed / Interval
local real x = GetUnitX(dat.entity) + dist * Cos(angle * bj_DEGTORAD)
local real y = GetUnitY(dat.entity) + dist * Sin(angle * bj_DEGTORAD)
//Done with setup.
set dat.lifespam = (dat.lifespam - (100 / Interval ) )
call SetUnitPosition( dat.entity, x, y )
call GroupEnumUnitsInRangeOfLoc(dat.Targets, Location(x, y), dat.ar, Condition(function Filtru))
call DestroyBoolExpr( Condition( function Filtru ) )
if ( dat.ITE() ) then
call GroupEnumUnitsInRangeOfLoc(dat.Targets, Location(x, y), dat.tr, Condition(function Filtru))
call DestroyBoolExpr( Condition( function Filtru ) )
call ForGroup( dat.Targets, function Data.Damage )
call DestroyEffect( AddSpecialEffect( dat.sfx, x, y ) )
call RemoveUnit( dat.entity )
call dat.destroy()
set Total = Total - 1
if Total <= 0 then
call PauseTimer(Cycle)
endif
endif
call GroupClear(dat.Targets)
set dat.entity = null
endmethod
endstruct
private function FBCreate takes nothing returns nothing
local integer damage = GetHeroInt(GetTriggerUnit(), true) * GetHeroLevel(GetTriggerUnit()) * GetUnitAbilityLevel(GetTriggerUnit(), AbilityID)
local Data dat = Data.create(GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), GetUnitFacing(GetTriggerUnit()), LifeSpam, SpeedPerSecond, damage, DamageSplashRadius, AcquireTargetsRange, sfxpath)
endfunction
function Init takes nothing returns nothing
local trigger t = CreateTrigger()
local filterfunc f = Filter(function AntiLeak)
local integer i = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, f)
set i = i + 1
exitwhen i >= 16
endloop
call TriggerAddCondition(t, Condition( function Conditions ) )
call TriggerAddAction(t, function FBCreate )
call DestroyFilter(f)
set f = null
endfunction
//===========================================================================
//~~~~~~ End of movement
endlibrary