shiFt
Member
- Reaction score
- 8
Would you not have to check pderiodically if ENDCAST has occured?
Nope, just do your destroy/cleanup on a trigger with that event and the condition that it is the correct ability.
You should save the data so that it's retrievable with only the information about the casting unit...after all, a unit can't be channeling the same spell more than once at a time, so it's OK to attach the spell data to the caster. That's one reason I like making channeled spells; it's so easy, especially if you're using a unit indexing system.
emjlr3's spell is a little different because he lets you re-target it by casting it again, while maintaining the same duration. Plain channeled spells like Aerial Shackles or Starfall just have a distinct start, end, and the spell effects that happen meanwhile.
it just so happens that successional casts trigger just about every PLAYER_UNIT_SPELL_XXXX there is
to my suprise learning an ability fires a unit event, and each ability has a unique learn id
I discovered that learning an ability produces a unique orderid, specific to that ability.
Yes and that order id is equal to the ability's id. Normal cast orders lie in the 852k area. The raw ids of objects from object editor (learning abilities, training/building/upgrading to units, researching, selling items) are much higher.
This is what I wrote
JASS:library CHANNEL requires T32 globals private constant integer SPELL_ID = 039;A09R039; private integer i endglobals private struct Data unit cs real x real y integer tick private method onDestroy takes nothing returns nothing set .cs = null set i = 0 call .deallocate() endmethod static method Conditions takes nothing returns boolean if GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_EFFECT and GetSpellAbilityId()==SPELL_ID then set i = 1 call BJDebugMsg( "ok0") return true elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_ENDCAST then set i = 2 call BJDebugMsg( "ok1") return true endif return false endmethod private method periodic takes nothing returns nothing if .tick >= T32_Tick and i == 1 then call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl", .x,.y)) call BJDebugMsg( "ok3") if .tick == T32_Tick or i == 2 then call .stopPeriodic() call .destroy() endif endif endmethod implement T32x private static method act takes nothing returns boolean local thistype this = thistype.allocate() set .cs = GetTriggerUnit() set .x = GetUnitX(.cs) set .y = GetUnitY(.cs) set .tick = T32_Tick + R2I( 10. * T32_PERIOD) call BJDebugMsg( I2S(i)) if i == 1 then call .startPeriodic() endif if i == 2 then call .stopPeriodic() call .destroy() endif return false endmethod private static method onInit takes nothing returns nothing local trigger t = CreateTrigger() local integer i = 0 loop exitwhen i > 11 call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null) call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_ENDCAST, null) set i = i + 1 endloop call TriggerAddCondition( t, Condition( function thistype.Conditions ) ) call TriggerAddAction(t, function thistype.act) endmethod endstruct endlibrary
Fires "ok1"
And "1"
Then crashes game
library CHANNEL requires T32
globals
private constant integer SPELL_ID = 039;A09R039;
private integer i
endglobals
private struct Data
unit cs
real x
real y
integer tick
private method onDestroy takes nothing returns nothing
set .cs = null
set i = 0
call .deallocate()
endmethod
private static method Conditions takes nothing returns boolean
if GetSpellAbilityId()==SPELL_ID then
if GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_EFFECT then
set i = 1
call BJDebugMsg( "ok0")
return true
elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_ENDCAST then
set i = 2
call BJDebugMsg( "ok1")
return true
endif
endif
return false
endmethod
private method periodic takes nothing returns nothing
if .tick >= T32_Tick and i == 1 then
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl", .x,.y))
call BJDebugMsg( "ok3")
if .tick == T32_Tick or i == 2 then
call .stopPeriodic()
call .destroy()
endif
endif
endmethod
implement T32x
private static method act takes nothing returns nothing
local thistype this = thistype.allocate()
set .cs = GetTriggerUnit()
set .x = GetUnitX(.cs)
set .y = GetUnitY(.cs)
set .tick = T32_Tick + R2I( 10. / T32_PERIOD)
call BJDebugMsg( I2S(i))
if i == 1 then
call .startPeriodic()
endif
//if i == 2 then
// call .stopPeriodic()
// call .destroy()
//endif
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
exitwhen i > 11
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_ENDCAST, null)
set i = i + 1
endloop
call TriggerAddCondition( t, Condition( function thistype.Conditions ) )
call TriggerAddAction(t, function thistype.act)
endmethod
endstruct
endlibrary