HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

xecast or i dont know?

05-10-2009, 08:36 AM#1
Sinnergy
i made an upgrade that will give the heal (autocast) ability to a unit that will continuously spawn for every 1 minute, and will be spawned for each lane (i have 3 lanes), and made a trigger that each time the heal ability is casted (tested, spell_finish, spell_effect, spell_cast), i will create a dummy unit and cast healing wave to the healed unit via xecast 0.6, and reorder the unit to its second last order (IssueSecondLastOrder function by LastOrder system) to make the casting unit attack back to where it should attack, i did this, because i cant control them, the only way the units will cast healing wave is via autocast, detecting the autocast, and cast healing wave

the problem is, sometimes xecast wont create a unit and cast healing wave to the target, and sometimes the dummy runs to another point, i can see that the dummy is running because the lightning effect from healing wave moves from the caster to another random point

theres no problem with the "ordering the unit to its second last order", i think xecast is the problem

the code
Collapse JASS:
scope ChainHeal initializer init

globals
    private constant integer spell = 'A018'
    private constant integer spekk = 'A019'
    private constant string order = "healingwave"
endglobals

private struct data
    unit c
endstruct

private function con takes nothing returns boolean
    return GetSpellAbilityId() == spell
endfunction

private function callBack takes nothing returns boolean
    local timer t = GetExpiredTimer()
    local data d = GetTimerData(t)
    call IssueSecondLastOrder(d.c)
    call ReleaseTimer(t)
    call d.destroy()
    set t = null
    return true
endfunction

private function act takes nothing returns nothing
    local xecast xe = xecast.createA()
    local data d = data.create()
    local timer t = NewTimer()
    local unit cast = GetTriggerUnit()
    local unit targ = GetSpellTargetUnit()
    local real x = GetUnitX(cast)
    local real y = GetUnitY(cast)
    set xe.abilityid = spekk
    set xe.orderstring = order
    set xe.owningplayer = GetOwningPlayer(cast)
    set xe.recycledelay = 5.0
    set d.c = cast
    call xe.setSourcePoint(x,y,0.0)
    call xe.castOnTarget(targ)
    call TimerStart(t,1.5,false,function callBack)
    call SetTimerData(t,d)
    set t = null
    set cast = null
    set targ = null
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_CAST)
    call TriggerAddCondition(t, Condition(function con))
    call TriggerAddAction(t, function act)
endfunction

endscope
05-10-2009, 04:58 PM#2
0zyx0
It is probably not the cause of the problem, but you shouldn't set a timer variable to null, because it is bugged. Use a global timer variable instead.

Now for your problem; You have to destroy the xecast object after you are finished with it. Try to do it (everywhere in the map), and see if it solves your problem.
05-10-2009, 06:06 PM#3
Djinnx
Also a local xecast is not the most performant solution , rather use a private global for your spell instances (coz creating dummy units all time is not as good as having one for ever )

see a example out of my map

Collapse JASS:
scope Skyslash initializer Init

globals
    private xecast day
    private xecast night
    private constant integer id='A005'
    private constant integer ds1='s004'
    private constant integer ds2='s005'
endglobals

private function SetItUp takes xecast d, xecast n returns nothing
    set d.abilityid = ds1
    set d.orderid = OrderId("thunderbolt")
    
    set n.abilityid = ds2
    set n.orderid = OrderId("manaburn")
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId()==id
endfunction

private function Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local unit t = GetSpellTargetUnit()
    local real x
    local real y 
    
    if Gametime_IsNight() then
        set night.owningplayer = GetOwningPlayer(u)
        set night.level = GetUnitAbilityLevel(u, id)
        call night.castOnTarget(t)
    else
        set day.owningplayer = GetOwningPlayer(u)
        set day.level = GetUnitAbilityLevel(u, id)
        call day.castOnTarget(t)
    endif

    set x = GetUnitX(t)
    set y = GetUnitY(t)
    call SetUnitX(u, x)
    call SetUnitY(u, y)
    call IssueTargetOrder(u, "attack" ,t)
    
    set u = null
    set t = null
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition(t, Condition( function Conditions ) )
    call TriggerAddAction( t, function Actions )
    set t = null

    set day = xecast.create()
    set night = xecast.create()
    call SetItUp(day, night)
    call XE_PreloadAbility(id)
    call XE_PreloadAbility(ds1)
    call XE_PreloadAbility(ds2)
endfunction
endscope 
05-10-2009, 06:11 PM#4
Djinnx
Hmm my previous post was removed so i do it again

a local xecast is not best solution rather use a private global xecast

quick example :

Collapse JASS:
scope Skyslash initializer Init

globals
    private xecast day
    private xecast night
    private constant integer id='A005'
    private constant integer ds1='s004'
    private constant integer ds2='s005'
endglobals

private function SetItUp takes xecast d, xecast n returns nothing
    set d.abilityid = ds1
    set d.orderid = OrderId("thunderbolt")
    
    set n.abilityid = ds2
    set n.orderid = OrderId("manaburn")
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId()==id
endfunction

private function Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local unit t = GetSpellTargetUnit()
    local real x
    local real y 
    
    if Gametime_IsNight() then
        set night.owningplayer = GetOwningPlayer(u)
        set night.level = GetUnitAbilityLevel(u, id)
        call night.castOnTarget(t)
    else
        set day.owningplayer = GetOwningPlayer(u)
        set day.level = GetUnitAbilityLevel(u, id)
        call day.castOnTarget(t)
    endif

    set x = GetUnitX(t)
    set y = GetUnitY(t)
    call SetUnitX(u, x)
    call SetUnitY(u, y)
    call IssueTargetOrder(u, "attack" ,t)
    
    set u = null
    set t = null
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition(t, Condition( function Conditions ) )
    call TriggerAddAction( t, function Actions )
    set t = null

    set day = xecast.create()
    set night = xecast.create()
    call SetItUp(day, night)
    call XE_PreloadAbility(id)
    call XE_PreloadAbility(ds1)
    call XE_PreloadAbility(ds2)
endfunction
endscope 
05-10-2009, 11:38 PM#5
Sinnergy
yep i tried using xecast.createA()
which will automatically destroys the xecast object after every castOn... method call, but still doesnt work
05-11-2009, 12:00 AM#6
Feroc1ty
You should store all orders, and than making unit retreat to the last order, see if that works.
05-11-2009, 12:36 AM#7
MaD[Lion]
dummy unit usually works but dunno in some enviroments they go all bezerk and walks away... had problem in my mad balls arena on my physic system. it always working fine. but suddenly maybe cus the map was big the units started to walk. so i had to pause them all.

the reason it wont create can be cause of the unit recieve the walk order. else i dont know
05-11-2009, 02:46 AM#8
Sinnergy
Quote:
Originally Posted by Feroc1ty
You should store all orders, and than making unit retreat to the last order, see if that works.
no need to store all orders, lastorder system does the job already

im fine at the dummy units walking around, but why does sometimes the dummy wont cast healing wave? is this a problem with the heal autocast ability?
05-11-2009, 02:59 AM#9
MaD[Lion]
i think they cant do it when they walk...
05-11-2009, 06:25 AM#10
cosmicat
Correct. "Move" overrides autocasts. "Attack Move" doesn't, though, so you might try that. Just make it so the dummy caster isn't actually allowed to auto-attack anything (e.g. allow it to attack only "dead" units, which it will never auto-attack anyway).
05-11-2009, 08:52 AM#11
Sinnergy
my map has a system that shows ability names when an ability is casted, while the caster is walking and my hero goes near to it, the HEAL word goes out from the walking caster, but the dummy unit doesnt cast healing wave

move overrides autocast ability, which is a reason why the trigger doesnt work, but why did my system detect the spell when casted, while they have the same events?

another one, when the caster starts to do the spell animation, the heal word comes out, but the healing wave was not casted, thats why i added a timer to the trigger to test if ordering the unit to its second last order was really the problem, but its not, i doubt this is about xecast

Collapse JASS:
scope ShowAbilityNames initializer init

private function act takes nothing returns nothing
    local string s = GetObjectName(GetSpellAbilityId())
    local unit cast = GetTriggerUnit()
    call AddFadingTextTag(s, GetUnitX(cast), GetUnitY(cast), 128, 128, 255, 255)
    set cast = null
endfunction

private function con takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit()) != 'e000'
endfunction

//===========================================================================
private function init takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition(t, Condition(function con))
    call TriggerAddAction( t, function act )
endfunction

endscope

EDIT: tried just creating a dummy unit and cast healing wave manually without using xecast, it works fine, but still the dummy unit runs sometimes, but this is fine, i could always remove the unit's move speed

looks like the problem was all about xecast, better report this to vexorian

Collapse JASS:
scope ChainHeal initializer init

globals
    private constant integer spell = 'A018'
    private constant integer spekk = 'A019'
    private constant string order = "healingwave"
endglobals

private struct data
    unit c
endstruct

private function con takes nothing returns boolean
    return GetSpellAbilityId() == spell
endfunction

private function act takes nothing returns nothing
    local unit cast = GetTriggerUnit()
    local unit targ = GetSpellTargetUnit()
    local real x = GetUnitX(cast)
    local real y = GetUnitY(cast)
    local unit u = CreateUnit(GetOwningPlayer(cast),'h00T',x,y,0.0)
    call UnitApplyTimedLife(u,'BTLF',5.0)
    call UnitAddAbility(u,'Aloc')
    call UnitAddAbility(u,spekk)
    call IssueTargetOrder(u,order,targ)
    call IssueSecondLastOrder(cast)
    set cast = null
    set targ = null
    set u = null
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call XE_PreloadAbility(spekk)
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function con))
    call TriggerAddAction(t, function act)
endfunction

endscope
05-11-2009, 05:46 PM#12
MaD[Lion]
i dont think its cause of xecast... but who knows ^^ maybe upload ur map so we can try fix it
05-11-2009, 09:17 PM#13
Sinnergy
the new chain heal ability now working fine, thats why i doubt about xecast