scope FireForm initializer onInit
globals
private constant integer SPELL_ID = 'A000'
private constant integer DUMMY_ID = 'h000'
// OFFSET is distance travelled per cycle
// KT_PERIOD is the period you use for KT_Add
//Manaperunit is the mana per unit moved.
private constant real OFFSET = 20
private constant real KT_PERIOD = 00.03
private constant real Manaperunit = .25
endglobals
// I'm assuming that the struct declared
// below is for the sole use of FireForm
// so I made it private. The members are
// public by default, you don't need to
// declare them as such.
private struct casterObject
unit caster
unit dummy
real offsetX
real offsetY
real direction
real distDelta
real distTarget
endstruct
private function userFunc takes nothing returns boolean
local casterObject obj = casterObject(KT_GetData())
local boolean stop = (obj.distDelta >= obj.distTarget)
// If the distance travelled is equivalent or more than the
// target distance then stop repeating
if stop then
// 1. Show the caster.
// 2. Select the caster. (It gets unselected when hidden.)
// 3. Move it to the position of the dummy.
call ShowUnit(obj.caster, true)
call SelectUnit(obj.caster, true)
call SetUnitX(obj.caster, GetUnitX(obj.dummy))
call SetUnitY(obj.caster, GetUnitY(obj.dummy))
// 4. Cleanup.
call RemoveUnit(obj.dummy)
set obj.caster = null
set obj.dummy = null
call obj.destroy()
else
// 1. Move the dummy unit.
// This works because the increase in the offsets is sequential.
// There is no need to call cos and sin repeatedly.
// Nobody believes me though.
//2. Removing mana equal to the offset * .25
if ( GetUnitState(obj.caster, UNIT_STATE_MANA) < 1) then
set obj.distDelta = obj.distTarget
else
call SetUnitX(obj.dummy, GetUnitX(obj.dummy) + obj.offsetX)
call SetUnitY(obj.dummy, GetUnitY(obj.dummy) + obj.offsetY)
call SetUnitState(obj.caster, UNIT_STATE_MANA, RMaxBJ(0, GetUnitState(obj.caster, UNIT_STATE_MANA) - (OFFSET * Manaperunit)))
// 2. Update distDelta so it correctly holds the distance travelled
// by the dummy unit.
set obj.distDelta = obj.distDelta + OFFSET
endif
endif
return stop
endfunction
private function onEffect takes nothing returns boolean
local casterObject obj = casterObject(0)
local real x = 0
local real y = 0
local real angle = 0
local boolean cond = (GetSpellAbilityId() == SPELL_ID)
// If the spell detected was SPELL_ID then the actions below
// would be executed, else it would just exit, returning false.
if cond then
// 1. Prepare the needed data.
set x = GetUnitX(GetTriggerUnit())
set y = GetUnitY(GetTriggerUnit())
set angle = Atan2(GetSpellTargetY() - y, GetSpellTargetX() - x)
// Atan2 returns angle in radians, no conversion required.
// 2. Instantiate.
set obj = casterObject.create()
set obj.caster = GetTriggerUnit()
set obj.dummy = CreateUnit(GetOwningPlayer(obj.caster), DUMMY_ID, x, y, angle*bj_RADTODEG)
// angle*bj_RADTODEG makes the dummy looks toward the cast point.
// 3. Determine the offsets of both x and y coordinates.
// The angle is constant so the offset increase per iteration
// will be constant.
set obj.offsetX = OFFSET*Cos(angle)
set obj.offsetY = OFFSET*Sin(angle)
set x = GetSpellTargetX() - x
set y = GetSpellTargetY() - y
// 4. Determine the required distance to traverse. Store the
// distance travelled.
set obj.distDelta = 0
set obj.distTarget = SquareRoot(x*x+y*y)
// ============= Debug messages ============
debug call BJDebugMsg("====================")
debug call BJDebugMsg("caster:"+GetUnitName(obj.caster))
debug call BJDebugMsg("dummy:"+GetUnitName(obj.dummy))
debug call BJDebugMsg("x offset:"+R2S(obj.offsetX))
debug call BJDebugMsg("y offset:"+R2S(obj.offsetY))
debug call BJDebugMsg("distance delta:"+R2S(obj.distDelta))
debug call BJDebugMsg("distance required:"+R2S(obj.distTarget))
debug call BJDebugMsg("====================")
// =========================================
// 5. Hide the casting unit.
call ShowUnit(obj.caster, false)
call PauseUnit(obj.dummy, true)
call KT_Add(function userFunc, obj, KT_PERIOD)
endif
return false
endfunction
private function onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t,Condition(function onEffect))
endfunction
endscope