Name | Type | is_array | initial_value |
FireBolts | group | No | |
group | group | No | |
p | location | Yes | |
Targets | group | No |
//TESH.scrollpos=0
//TESH.alwaysfold=0
library FireBall
globals // Globals of the Fire Balls and the spell.
private constant integer AbilityID = 'A001'
private constant integer DummyID = 'u000'
private constant real SpeedPerSecond = 900.00
// Amount of range the fire ball moves per second.
private real LifeSpam
// 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 = 100.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 recomment using this effect for the fire ball.
private group FBs = CreateGroup()
private group Targets = CreateGroup()
private unit passable
endglobals
private keyword data
globals
private data array DATAS
private integer total = 0
endglobals
private struct data
unit StructUnit
real lifespam
real speed
real damage
real ar
real tr
integer i
endstruct
private function AttachStruct takes unit ToWhich returns data
local data dat = data.create()
set dat.StructUnit = ToWhich
set dat.i = total
set DATAS[total] = dat
set total = total + 1
return dat
endfunction
private function GetStruct takes unit FromWhich returns data
local integer i = 0
local data toReturn = 0
loop
exitwhen i >= total
if DATAS[i].StructUnit == FromWhich then
set toReturn = DATAS[i]
endif
set i = i + 1
endloop
return toReturn
endfunction
private function DestroyStruct takes unit WhichUnits returns nothing
local data dat = GetStruct(WhichUnits)
set total = total - 1
set DATAS[dat.i] = DATAS[total]
set DATAS[dat.i].i = dat.i
call dat.destroy()
endfunction
//======================================================================================================================================================
//======================================================================================================================================================
//======================================================================================================================================================
//~~~~~~ Start of creation
//===========================================================================
private function Conditions takes nothing returns boolean
return (GetSpellAbilityId() == AbilityID)
endfunction
private function Create takes nothing returns nothing
local real ox = GetUnitX(GetTriggerUnit())
local real oy = GetUnitY(GetTriggerUnit())
local real px = GetLocationX(GetSpellTargetLoc())
local real py = GetLocationY(GetSpellTargetLoc())
local real angle = bj_RADTODEG * Atan2(py - oy, px - ox)
local real x = ox + 15 * Cos(angle * bj_DEGTORAD)
local real y = oy + 15 * Sin(angle * bj_DEGTORAD)
local unit u = CreateUnit( GetOwningPlayer(GetTriggerUnit()), DummyID, x, y, angle)
local data dat = AttachStruct(u)
set dat.lifespam = GetRandomReal(1.00, 2.00)
set dat.speed = GetRandomReal(SpeedPerSecond - 200.00, SpeedPerSecond + 200.00)
set dat.damage = ( GetHeroInt(GetSpellAbilityUnit(), true) * GetUnitAbilityLevel(GetSpellAbilityUnit(), AbilityID) )
set dat.ar = GetRandomReal(AcquireTargetsRange - 20.00, AcquireTargetsRange + 20.00)
set dat.tr = GetRandomReal(DamageSplashRadius - 25.00, DamageSplashRadius + 25.00)
call GroupAddUnit( FBs, u )
set u = null
endfunction
private constant function AntiLeak takes nothing returns boolean
return true
endfunction
//===========================================================================
//~~~~~~ End of creation
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~ Start of movement
//===========================================================================
private function Filtru takes nothing returns boolean
return (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > .405) and (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetEnumUnit())) == true)
endfunction
private function ITE takes nothing returns boolean
local data dat = GetStruct(GetEnumUnit())
call ForGroup(Targets, function CountUnitsInGroupEnum)
if ( bj_groupCountUnits >= 1 ) then
return true
endif
if ( dat.lifespam <= 0.00 ) then
return true
endif
return false
endfunction
private function Damage takes nothing returns nothing
local unit u = GetEnumUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real dump
local data dat = GetStruct( passable )
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 ) 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
endif
call UnitDamageTarget( passable, u, dat.damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS )
set dat.damage = dump
set u = null
endfunction
private function Move takes nothing returns nothing
local unit u = GetEnumUnit()
local data dat = GetStruct( u )
local real angle = GetUnitFacing( u )
local real dist = dat.speed / 100
local real x = GetUnitX(u) + dist * Cos(angle * bj_DEGTORAD)
local real y = GetUnitY(u) + dist * Sin(angle * bj_DEGTORAD)
//Done with setup.
set dat.lifespam = (dat.lifespam - 0.01)
call SetUnitPosition( u, x, y )
call GroupEnumUnitsInRangeOfLoc(Targets, Location(x, y), dat.ar, Condition(function Filtru))
call DestroyBoolExpr( Condition( function Filtru ) )
if ( ITE() ) then
set passable = u
call GroupEnumUnitsInRangeOfLoc(Targets, Location(x, y), dat.tr, Condition(function Filtru))
call DestroyBoolExpr( Condition( function Filtru ) )
call ForGroup( Targets, function Damage )
call DestroyEffect( AddSpecialEffect( sfxpath, x, y ) )
call DestroyStruct( u )
call RemoveUnit( u )
endif
set bj_groupCountUnits = 0
call GroupClear(Targets)
set u = null
endfunction
private function Pick takes nothing returns nothing
call ForGroup( FBs, function Move )
endfunction
function InitTrig_Fire_Ball takes nothing returns nothing
local trigger t = CreateTrigger()
local filterfunc f = Filter(function AntiLeak)
local integer i = 0
local trigger trg = CreateTrigger( )
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 Create )
call DestroyFilter(f)
set f = null
call TriggerRegisterTimerEvent( trg, 0.01, true )
call TriggerAddAction( trg, function Pick )
endfunction
//===========================================================================
//~~~~~~ End of movement
endlibrary