//****************************************************************************************************
//Eclipse of Sanity Configuration
//****************************************************************************************************
constant function Eclipse_SpellID takes nothing returns integer
return 'A001' //The rawcode of the spell in your map, check hit CTRL + D to view it then fill it in here
endfunction
constant function Eclipse_NumSprites takes integer lvl returns integer
return lvl * 0 + 3
endfunction
constant function Eclipse_Damage takes integer lvl returns real
return (lvl + 1.0) * 15
endfunction
constant function Eclipse_AreaofEffect takes integer lvl returns real
return lvl * 0 + 650.0
endfunction
constant function Eclipse_FlySpeed takes nothing returns real
return 550.0
endfunction
constant function Eclipse_Timeout takes nothing returns real
return 0.05 //Setting this above 0.08 or so will cause it to look really jumpy and bad, while lower than
//0.02 may cause some slowdown. 0.05 is smooth and seems to be efficient enough for me
endfunction
constant function Eclipse_DetectionRange takes nothing returns real
return 90.0
endfunction
constant function Eclipse_Duration takes integer lvl returns real
return lvl * 0 + 20.0
endfunction
constant function Eclipse_UsesMissile takes nothing returns boolean
return true //This is used to dictate whether or not the units will fly towards the target
//or just sort of appear at it
endfunction
constant function Eclipse_ValidTargets takes nothing returns boolean
return (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) != 0.00) and (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_unit))) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) and (GetUnitTypeId(GetFilterUnit()) != DummyID()) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND))
//This is the filter that we apply to units who are nearby, it is also used periodically to make sure the target is still valid
endfunction
//****************************************************************************************************
//Spell Section
//****************************************************************************************************
function Eclipse_Cast_Cons takes nothing returns boolean
return GetSpellAbilityId() == Eclipse_SpellID()
endfunction
function Eclipse_Movement takes nothing returns nothing
local timer t=GetExpiredTimer()
local string s=GetAttachmentTable(t)
local unit cast=GetTableUnit(s, "shieldunit")
local unit missile=GetTableUnit(s, "shieldmissile")
local unit targ=GetTableUnit(s, "shieldtarg")
local real angle=GetTableReal(s, "shieldangle")
local integer lvl=GetTableInt(s, "lvl")
local string way=GetTableString(s, "way")
local real x=GetUnitX(missile)
local real y=GetUnitY(missile)
local real speedi=GetTableReal(s, "speedi")
local real x1
local real y1
local group g=CreateGroup()
local boolexpr cons=Condition(function Eclipse_ValidTargets)
set angle=angle + 10
//Outward bound movement
if (way == "outward") then
set x1=GetUnitX(targ)
set y1=GetUnitY(targ)
if ((x1-x)*(x1-x)+(y1-y)*(y1-y)) <= Pow(Eclipse_DetectionRange(), 2) or (GetUnitState(targ, UNIT_STATE_LIFE) <= 0.00) then
call UnitDamageTargetBJ(cast, targ, Eclipse_Damage(lvl), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
call DestroyEffect(AddSpecialEffectTarget(GetAbilityEffectById(Eclipse_SpellID(), EFFECT_TYPE_TARGET, 1), targ, "chest"))
set way="inward"
set targ=null
else
call SetUnitFacing(missile, bj_RADTODEG*Atan2(y1-y, x1-x))
set x=GetUnitX(missile)+speedi*Cos(GetUnitFacing(missile)*bj_DEGTORAD)
set y=GetUnitY(missile)+speedi*Sin(GetUnitFacing(missile)*bj_DEGTORAD)
call SetUnitPosition(missile, x, y)
endif
endif
//Inward bound movement
if (way == "inward") or (way == "missile") then
//The missiles are heading back to the cast, so we must approximate it's proper location and
//make it move towards THAT location
set x1=GetUnitX(cast)+speedi*Cos(angle*bj_DEGTORAD)
set y1=GetUnitY(cast)+speedi*Sin(angle*bj_DEGTORAD)
call SetUnitFacing(missile, bj_RADTODEG*Atan2(y1-y, x1-x))
if (((x-x1)*(x-x1)+(y-y1)*(y-y1)) <= 600) then
set way="norm"
else
set x=GetUnitX(missile)+speedi*Cos(GetUnitFacing(missile)*bj_DEGTORAD)
set y=GetUnitY(missile)+speedi*Sin(GetUnitFacing(missile)*bj_DEGTORAD)
call SetUnitPosition(missile, x, y)
endif
endif
//Regular movement
if (way == "norm") then
set x=(GetUnitX(cast)+85*Cos(angle*bj_DEGTORAD))
set y=(GetUnitY(cast)+85*Sin(angle*bj_DEGTORAD))
call SetUnitPosition(missile, x, y)
set udg_unit=missile
call GroupEnumUnitsInRange(g, x, y, Eclipse_AreaofEffect(lvl), cons)
if (CountUnitsInGroup(g) > 0) then
set targ=GroupPickRandomUnit(g)
set way="outward"
endif
endif
//Refresh some of the table objects
call SetTableString(s, "way", way)
call SetTableReal(s, "shieldangle", angle)
call SetTableObject(s, "shieldtarg", targ)
if (GetUnitState(missile, UNIT_STATE_LIFE) <= 0.00) or (GetUnitState(cast, UNIT_STATE_LIFE) <= 0.00) then
call RemoveUnit(missile)
call PauseTimer(t)
call TriggerSleepAction(.1)
call DestroyTimer(t)
call DestroyTable(s)
endif
//Cleanup
call DestroyBoolExpr(cons)
call DestroyGroup(g)
set cons=null
set missile=null
set targ=null
set t=null
set cast=null
set g=null
endfunction
function Eclipse_Cast takes nothing returns nothing
local timer t=null
local string s
local unit cast=GetSpellTargetUnit()
local unit caster=GetTriggerUnit()
local unit temp
local unit ttemp
local integer lvl=GetUnitAbilityLevel(GetTriggerUnit(), Eclipse_SpellID())
local integer c=Eclipse_NumSprites(lvl)
local integer i=Eclipse_NumSprites(lvl)
local real x1=GetUnitX(caster)
local real y1=GetUnitY(caster)
local real angle
local string way="norm"
local real speedi=(Eclipse_FlySpeed() / (1/Eclipse_Timeout()))
if (Eclipse_UsesMissile()) then
set way="missile"
endif
if (GetUnitAbilityLevel(cast, Shifting_Form_BuffID()) != 0) then //REMOVE THIS LINE IF USING WITHOUT THE SHIFTING FORM SPELL
set i=i*2 //REMOVE THIS LINE IF USING WITHOUT THE SHIFTING FORM SPELL
set c=c*2 //REMOVE THIS LINE IF USING WITHOUT THE SHIFTING FORM SPELL
endif //REMOVE THIS LINE IF USING WITHOUT THE SHIFTING FORM SPELL
loop
exitwhen c==0
set angle=(360 / i) * c
//Create units and whatever
set temp=CreateUnit(GetOwningPlayer(caster), DummyID(), x1,y1,bj_RADTODEG*Atan2(GetUnitY(cast)-y1, GetUnitX(cast)-x1))
call AddSpecialEffectTimed(temp, GetAbilityEffectById(Eclipse_SpellID(), EFFECT_TYPE_TARGET, 1), "chest", Eclipse_Duration(lvl) - .3)
set t=CreateTimer()
call UnitApplyTimedLife(temp, 'BTLF', Eclipse_Duration(lvl))
set s=GetAttachmentTable(t)
call SetTableObject(s, "shieldunit", cast)
call SetTableObject(s, "shieldmissile", temp)
call SetTableReal(s, "shieldangle", angle)
call SetTableInt(s,"lvl", lvl)
call SetTableString(s, "way", way)
call SetTableReal(s, "speedi", speedi)
call TimerStart(t, Eclipse_Timeout(), true, function Eclipse_Movement)
set t=null
set ttemp=null
set temp=null
set c=c-1
endloop
set cast=null
set caster=null
endfunction
//===========================================================================
function InitTrig_Eclipse_of_Sanity takes nothing returns nothing
set gg_trg_Eclipse_of_Sanity = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Eclipse_of_Sanity, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Eclipse_of_Sanity, Condition( function Eclipse_Cast_Cons ))
call TriggerAddAction( gg_trg_Eclipse_of_Sanity, function Eclipse_Cast )
endfunction