- Joined
- Jul 26, 2008
- Messages
- 1,009
Alright so a long time ago watermelon1234 showed me an example on how to do Activatables, as they're a rather complex thing from what I can tell.
Well, what I've been using is far from perfect, and has a lot of issues. (This set-up has been giving me headaches forever. When Silenced the spell deactivates without the icon deactivating. If you try to level the spell up when active, it doesn't level up. Fortunately those are the two issues where it's been narrowed down to.)
Perhaps someone can give me a better way, or help me fix this current version.
Uses Table.
Well, what I've been using is far from perfect, and has a lot of issues. (This set-up has been giving me headaches forever. When Silenced the spell deactivates without the icon deactivating. If you try to level the spell up when active, it doesn't level up. Fortunately those are the two issues where it's been narrowed down to.)
Perhaps someone can give me a better way, or help me fix this current version.
Uses Table.
JASS:
scope Euphoria initializer Init
globals
private constant integer SPELLID = 'Euph'
private constant string TurnOn = "immolation"
private constant string TurnOff = "unimmolation"
private constant real tick = 0.1
private HandleTable info
private unit TEMP
endglobals
private struct Data
unit c
boolean deactivate = false
timer tim
static method GroupEm takes nothing returns boolean
local integer lvl = GetUnitAbilityLevel(TEMP, SPELLID)
if IsUnitAlly(GetFilterUnit(), GetOwningPlayer(TEMP)) and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) != true and IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD) != true then
call SetWidgetLife(GetFilterUnit(), GetWidgetLife(GetFilterUnit())+((GetHeroInt(TEMP,true)*lvl*0.07+(0.3+0.8*lvl)+1.5)*tick))
call DestroyEffect(AddSpecialEffectTarget(GetAbilityEffectById(SPELLID, EFFECT_TYPE_TARGET, 0), GetFilterUnit(), "origin"))
endif
return false
endmethod
static method onLoop takes nothing returns nothing
local group g = NewGroup()
local Data D = Data(GetTimerData(GetExpiredTimer()))
if not(IsUnitType(D.c,UNIT_TYPE_DEAD)) and not(D.deactivate) and GetUnitState(D.c, UNIT_STATE_MANA) >= 10 then
//Start timer
set TEMP = D.c
call GroupEnumUnitsInArea(g, GetUnitX(D.c), GetUnitY(D.c), 300, Filter(function Data.GroupEm))
call SetUnitState(D.c, UNIT_STATE_MANA, GetUnitState(D.c, UNIT_STATE_MANA) - (0.3 + 0.1 * GetHeroInt(D.c, true)*tick))
call ReleaseGroup(g)
else
//Cleanup
call IssueImmediateOrder(D.c, TurnOff)
call info.flush(D.c)
set D.c = null
call ReleaseTimer(D.tim)
set D.tim = null
call D.destroy()
endif
endmethod
static method create takes unit caster returns Data
local Data D = Data.allocate()
set D.c = caster
//Timer
set D.tim = NewTimer()
call SetTimerData(D.tim,D)
call TimerStart(D.tim, tick, true, function Data.onLoop)
set info[D.c] = D
return D
endmethod
endstruct
private function Deactivate takes nothing returns boolean
local Data D
if GetIssuedOrderId() == OrderId(TurnOff) and info.exists(GetTriggerUnit()) then
set D = info[GetTriggerUnit()]
set D.deactivate = true
endif
return false
endfunction
private function Activation takes nothing returns boolean
if GetIssuedOrderId() == OrderId(TurnOn) and GetUnitAbilityLevel(GetTriggerUnit(), SPELLID) > 0 then
call Data.create(GetTriggerUnit())
endif
return false
endfunction
//===========================================================================
public function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerAddCondition(t, function Activation )
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerAddCondition( t, function Deactivate )
set info = HandleTable.create()
call XE_PreloadAbility(SPELLID)
endfunction
endscope