• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

appearing xe units

Status
Not open for further replies.
Level 3
Joined
Jun 9, 2012
Messages
25
hi,
i'm using vexorian's xe system, especially the xefx part.
When i spam some spells using xefx there appear xedummies after several casts.
Can anyone tell me why that is?
Would be glad to hear the reason.
 
Level 3
Joined
Jun 9, 2012
Messages
25
The trigger is quite heavy, that's why i didn't post it. I'm destroying the fx directly after i create it so there is no problem with indexing i think. But maybe the immediate destroying is the problem.

Here's the trigger:
JASS:
scope FuriousFire initializer init 

    globals
        private constant integer SPELL_ID                               = 'A00F'
        private constant integer DUMMY_SPELL_ID                         = 'A00E'
        private constant integer HIDE_ABILITY                           = 'A00G'
        private constant integer HIDE_DUMMY                             = 'A00H'
        
        private constant integer ANIM_INDEX                             = 5
        private constant integer FX_COUNT                               = 5
        
        private constant real RANGE                                     = 500
        private constant real RADIUS                                    = 100
        private constant real RANGE_BOOST                               = 500
        private constant real RADIUS_BOOST                              = 100
        private constant real GAP                                       = 125
        
        private constant real CHANNEL_TIME                              = 3
        private constant real WAIT                                      = 0.1
        private constant real DURATION                                  = 0.25
        
        private constant real TIM_PERIODIC                              = 0.04
        
        private constant string FX_PATH                                 = "war3mapImported\\Firaga.mdx"
        private constant string FX_PATH2                                = "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl"
        private constant string CHARGE_PATH                             = "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl"
        private constant string ATTACH_PATH                             = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
        
        private constant real SPEED                                     = (RANGE/FX_COUNT)
        
        private Table a
    endglobals
    
    
    private struct Spell
        unit c
        real x
        real y
        effect attach 
        xedamage d
        xefx chargefx
        real scale
        group hit
        real angle
        real range
        real radius
        real speed
        real dist
        real chargeBuff
        real fxScale
        integer fxCount
        xefx fx
        xefx fx2
        
        
        static method boom takes nothing returns nothing
            local timer tim = GetExpiredTimer()
            local Spell this = GetTimerData(tim)
            local unit t
            
            set .x = .x + .speed*Cos(angle)
            set .y = .y + .speed*Sin(angle)
            set .dist = .dist + .speed
            
            if .dist > .fxCount*GAP then
                set fx = xefx.create(x,y,0)
                set fx.fxpath = FX_PATH
                set fx.scale = .fxScale
                set fx.z = 0
                call fx.destroy()
                
                set fx2 = xefx.create(x,y,0)
                set fx2.fxpath = FX_PATH2
                set fx2.scale = .fxScale-0.3
                set fx2.z = 0
                call fx2.destroy()
                
                set .fxCount = .fxCount + 1
            endif
            
            call GroupClear(ENUM_GROUP)
            call GroupEnumUnitsInRange(ENUM_GROUP,x,y,.radius,null)
                loop
                    set t = FirstOfGroup(ENUM_GROUP)
                    exitwhen t == null
                    
                    if not IsUnitInGroup(t,hit) and IsUnitEnemy(t,GetOwningPlayer(.c)) then
                        call d.damageTarget(.c,t,200)
                        call GroupAddUnit(hit,t)
                    endif
                    
                    call GroupRemoveUnit(ENUM_GROUP,t)
                endloop
                
            if .dist >= .range then
                call ReleaseTimer(tim)
                call ReleaseGroup(hit)
                call .deallocate()
            endif
            
            set tim = null
            
        endmethod
        
        static method wait takes nothing returns nothing
            local timer tim = GetExpiredTimer()
            local Spell this = GetTimerData(tim)
            
            call DestroyEffect(.attach)
            
            set .chargeBuff = .chargeBuff/(CHANNEL_TIME/TIM_PERIODIC)
            set .radius = RADIUS+(RADIUS_BOOST*.chargeBuff)
            set .range = RANGE+(RANGE_BOOST*.chargeBuff)-.radius
            set .speed = (.range/DURATION)*TIM_PERIODIC
            set .fxScale = (.radius/125)
            
            call TimerStart(NewTimerEx(this),TIM_PERIODIC,true,function Spell.boom)
            
            call ReleaseTimer(tim)
            set tim = null
            
        endmethod
            
        
        static method charge takes nothing returns nothing
            local timer tim = GetExpiredTimer()
            local Spell this = GetTimerData(tim)
            
            set .scale = .scale + (1/CHANNEL_TIME)*TIM_PERIODIC
            set .chargefx.scale = .scale
            
            if a[GetHandleId(.c)] == 0 then
                call ReleaseTimer(tim)
                call SetUnitAnimationByIndex(.c,ANIM_INDEX)
                call QueueUnitAnimation(.c,"stand")
                
                call chargefx.hiddenDestroy()
                set .attach = AddSpecialEffectTarget(ATTACH_PATH,.c,"right hand")
                
                set .hit = NewGroup()
                call TimerStart(NewTimerEx(this),WAIT,false,function Spell.wait)
            else
                set .chargeBuff = .chargeBuff + 1
            endif
            
            set tim = null
        endmethod
        
        static method create takes unit c, real angle returns Spell
            local Spell this = Spell.allocate()
            local real x = GetUnitX(c)
            local real y = GetUnitY(c)
            local real angleFX = angle-(80*bj_DEGTORAD)
            
            local xecast caster = xecast.createBasicA('A00I',OrderId("ensnare"),Player(0))
            call caster.castOnTarget(c)
            
            set .c = c
            set .x = x
            set .y = y
            set .d = xedamage.create()
            set .angle = angle
            set .dist = 0
            set .chargeBuff = 0
            set .fxCount = 1
            
            set .chargefx = xefx.create(x+50*Cos(angleFX),y+50*Sin(angleFX),angle)
            set .scale = 0
            set .chargefx.scale = .scale
            set .chargefx.z = 100
            set .chargefx.fxpath = CHARGE_PATH
            
            set d.dtype = DAMAGE_TYPE_FIRE
            set d.wtype = WEAPON_TYPE_WHOKNOWS
            set d.atype = ATTACK_TYPE_MAGIC
            
            call TimerStart(NewTimerEx(this),TIM_PERIODIC,true,function Spell.charge)
            
            return this
        endmethod
        
    endstruct
    
    private function cond takes nothing returns boolean
        local unit c = GetTriggerUnit()
        local real tx = GetSpellTargetX()
        local real ty = GetSpellTargetY()
        local real x = GetUnitX(c)
        local real y = GetUnitY(c)
        local real angle
        local integer unitId = GetHandleId(c)
        local timer tim

        if GetSpellAbilityId() == DUMMY_SPELL_ID and a[unitId] == 0 then
            set angle = Atan2(ty-y,tx-x)
            call UnitAddAbility(c,HIDE_ABILITY)
            call UnitAddAbility(c,SPELL_ID)
            
            call IssueImmediateOrderById(c,OrderId("flare"))
            call SetUnitFacing(c,angle*bj_RADTODEG)
            
            set a[unitId] = 1
            call Spell.create(c,angle)
        endif
        
        set c = null
        
        return true
    endfunction
    
    private function cleanUp takes nothing returns boolean
        local unit c = GetTriggerUnit()
        local integer unitId = GetHandleId(c)
        
        if GetSpellAbilityId() == SPELL_ID and a[unitId] != 0 then
            call UnitRemoveAbility(c,SPELL_ID)
            call UnitRemoveAbility(c,HIDE_ABILITY)
            call UnitAddAbility(c,DUMMY_SPELL_ID)
            
            call IssueImmediateOrder(c,"stop")
            
            set a[unitId] = 0
        endif
        
        return true
    endfunction
    
    
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local trigger t2 = CreateTrigger()
        set a = Table.create()
        
        call SetPlayerAbilityAvailable(Player(0),HIDE_DUMMY,false)
        call SetPlayerAbilityAvailable(Player(0),HIDE_ABILITY,false)
        
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t,Condition(function cond))
        
        call TriggerRegisterAnyUnitEventBJ(t2,EVENT_PLAYER_UNIT_SPELL_ENDCAST)
        call TriggerAddCondition(t2,Condition(function cleanUp))
        
        set t = null
        set t2 = null
    endfunction
    
endscope
 
Level 3
Joined
Jun 9, 2012
Messages
25
I don't think that's the problem because the way xefx works is that it creates a unit and then attaches the effect to it. So "destroying the effect" actually kills the unit.
Tested and the death animation is not the problem.
 
Level 3
Joined
Jun 9, 2012
Messages
25
Why does thistype help me here? I'm not using a module or something.
The xe system is quite complex.But it basically creates a unit and attaches the fxpath effect to it.
Yeah i know the code is quite ugly but i don't think thats the problem.
The units appear usually when i use more different spells and not just one so the problem is maybe not in the trigger.

Maybe it would be most useful if there is someone who uses xe and knows about the problem but thanks for your help!
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
if u post the xe system its not hard to understand what systems do. but i cant see what they do if i dont see them. How do u expect to get help if u dont show everything that ppl need to help u ?

also thistype keyword helps everywhere.

ur struct is called Spell so everywhere else u can and should use thistype. that way if u change the struct name to Spells it will still work without having to change everything.
 
Level 3
Joined
Jun 9, 2012
Messages
25
Xefx:
JASS:
library xefx initializer init requires xebasic, optional xedummy
//**************************************************
// xefx 0.9
// --------
//  Recommended: ARGB (adds ARGBrecolor method)
//  For your movable fx needs
//
//**************************************************

//==================================================
 globals
    private constant integer MAX_INSTANCES = 8190 //change accordingly.

    //Delay in order to show the death animation of the effect correctly when xefx is destroyed.
    //You may need to increase this if you are using effects with longer death animations.
    private constant real    MIN_RECYCLE_DELAY = 4.0

    //The delay does not need to be exact so we do cleanup in batches instead of individually.
    //This determines how often the recycler runs, should be less than MIN_RECYCLE_DELAY.
    private constant real    RECYCLE_INTERVAL = 0.5

    //if this is true and the xedummy library is present, units will be recycled instead of removed.
    private constant boolean RECYCLE_DUMMY_UNITS = true
    
    private timer    recycler
 endglobals

   private struct recyclebin
       unit u

       private recyclebin next=0
       private static recyclebin array list
       private static integer readindex=1
       private static integer writeindex=0
       private static integer count=0

       static method Recycle takes nothing returns nothing
            local recyclebin this = .list[readindex]
            loop
                exitwhen this==0
                static if RECYCLE_DUMMY_UNITS and LIBRARY_xedummy then
                    call XE_ReleaseDummyUnit(this.u)
                else
                    call RemoveUnit(this.u)
                endif
                set this.u=null
                set .count=.count-1
                call this.destroy()
                set this=this.next
            endloop
            set .list[readindex]=0
            set .writeindex=.readindex
            set .readindex=.readindex+1
            if .readindex>R2I(MIN_RECYCLE_DELAY/RECYCLE_INTERVAL+1.0) then
                set .readindex=0
            endif
            if count!=0 then
                call TimerStart(recycler, RECYCLE_INTERVAL, false, function recyclebin.Recycle)
            endif
       endmethod
       
       static method create takes unit u returns recyclebin
           local recyclebin this=recyclebin.allocate()
           if .count==0 then
                call TimerStart(recycler, RECYCLE_INTERVAL, false, function recyclebin.Recycle)
           endif
           set .count=.count+1
           set .u=u
           call SetUnitOwner(u,Player(15),false)
           set .next=.list[.writeindex]
           set .list[.writeindex]=this
           return this
       endmethod
   endstruct



   private function init takes nothing returns nothing
       set recycler=CreateTimer()
   endfunction

   struct xefx[MAX_INSTANCES]
       public integer tag=0
       private unit   dummy
       private effect fx=null
       private real   zang=0.0
       private integer r=255
       private integer g=255
       private integer b=255
       private integer a=255

       private integer abil=0

       static method create takes real x, real y, real facing returns xefx
        local xefx this=xefx.allocate()
           static if RECYCLE_DUMMY_UNITS and LIBRARY_xedummy then
               set this.dummy= XE_NewDummyUnit(Player(15), x,y, facing*bj_RADTODEG)
           else
               set this.dummy= CreateUnit(Player(15), XE_DUMMY_UNITID, x,y, facing*bj_RADTODEG)
               call UnitAddAbility(this.dummy,XE_HEIGHT_ENABLER)
               call UnitAddAbility(this.dummy,'Aloc')
               call UnitRemoveAbility(this.dummy,XE_HEIGHT_ENABLER)
               call SetUnitX(this.dummy,x)
               call SetUnitY(this.dummy,y)
           endif
        return this
       endmethod

       method operator owner takes nothing returns player
           return GetOwningPlayer(this.dummy)
       endmethod

       method operator owner= takes player p returns nothing
           call SetUnitOwner(this.dummy,p,false)
       endmethod

       method operator teamcolor= takes playercolor c returns nothing
           call SetUnitColor(this.dummy,c)
       endmethod

       method operator scale= takes real value returns nothing
           call SetUnitScale(this.dummy,value,value,value)
       endmethod

       //! textmacro XEFX_colorstuff takes colorname, colorvar
       method operator $colorname$ takes nothing returns integer
           return this.$colorvar$
       endmethod
       method operator $colorname$= takes integer value returns nothing
           set this.$colorvar$=value
           call SetUnitVertexColor(this.dummy,this.r,this.g,this.b,this.a)
       endmethod
       //! endtextmacro
       //! runtextmacro XEFX_colorstuff("red","r")
       //! runtextmacro XEFX_colorstuff("green","g")
       //! runtextmacro XEFX_colorstuff("blue","b")
       //! runtextmacro XEFX_colorstuff("alpha","a")

       method recolor takes integer r, integer g , integer b, integer a returns nothing
           set this.r=r
           set this.g=g
           set this.b=b
           set this.a=a
           call SetUnitVertexColor(this.dummy,this.r,this.g,this.b,this.a)
       endmethod

       implement optional ARGBrecolor

       method operator abilityid takes nothing returns integer
           return this.abil
       endmethod

       method operator abilityid= takes integer a returns nothing
           if(this.abil!=0) then
               call UnitRemoveAbility(this.dummy,this.abil)
           endif

           if(a!=0) then
               call UnitAddAbility(this.dummy,a)
           endif
           set this.abil=a
       endmethod
       
       method operator getUnit takes nothing returns unit 
           return this.dummy
       endmethod
       
       method operator abilityLevel takes nothing returns integer
           return GetUnitAbilityLevel( this.dummy, this.abil)
       endmethod
       
       method operator abilityLevel= takes integer newLevel returns nothing
           call SetUnitAbilityLevel(this.dummy, this.abil, newLevel)
       endmethod

       method flash takes string fx returns nothing
           call DestroyEffect(AddSpecialEffectTarget(fx,this.dummy,"origin"))
       endmethod

       method operator xyangle takes nothing returns real
           return GetUnitFacing(this.dummy)*bj_DEGTORAD
       endmethod
       method operator xyangle= takes real value returns nothing
           call SetUnitFacing(this.dummy,value*bj_RADTODEG)
       endmethod

       method operator zangle takes nothing returns real
           return this.zang
       endmethod

       method operator zangle= takes real value returns nothing
        local integer i=R2I(value*bj_RADTODEG+90.5)
           set this.zang=value
           if(i>=180) then
               set i=179
           elseif(i<0) then
               set i=0
           endif
               
           call SetUnitAnimationByIndex(this.dummy, i  )
       endmethod


       method operator x takes nothing returns real
           return GetUnitX(this.dummy)
       endmethod
       method operator y takes nothing returns real
           return GetUnitY(this.dummy)
       endmethod
       method operator z takes nothing returns real
           return GetUnitFlyHeight(this.dummy)
       endmethod

       method operator z= takes real value returns nothing
           call SetUnitFlyHeight(this.dummy,value,0)
       endmethod

       method operator x= takes real value returns nothing
           call SetUnitX(this.dummy,value)
       endmethod

       method operator y= takes real value returns nothing
           call SetUnitY(this.dummy,value)
       endmethod

       method operator fxpath= takes string newpath returns nothing
           if (this.fx!=null) then
               call DestroyEffect(this.fx)
           endif
           if (newpath=="") then
               set this.fx=null
           else
               set this.fx=AddSpecialEffectTarget(newpath,this.dummy,"origin")
           endif

       endmethod
       
       method hiddenReset takes string newfxpath, real newfacing returns nothing
        local real x = GetUnitX(this.dummy)
        local real y = GetUnitY(this.dummy)
        local real z = this.z
        local real za = this.zangle
        local integer level = this.abilityLevel
           set .fxpath=null
           static if RECYCLE_DUMMY_UNITS and LIBRARY_xedummy then
               if(this.abil!=0) then
                   call UnitRemoveAbility(this.dummy,this.abil)
               endif
               call recyclebin.create(this.dummy)
               set this.dummy=XE_NewDummyUnit(Player(15), x,y, newfacing*bj_RADTODEG)
           else
               call RemoveUnit(this.dummy)
               set this.dummy= CreateUnit(Player(15), XE_DUMMY_UNITID, x,y, newfacing*bj_RADTODEG)
               call UnitAddAbility(this.dummy,XE_HEIGHT_ENABLER)
               call UnitAddAbility(this.dummy,'Aloc')
               call UnitRemoveAbility(this.dummy,XE_HEIGHT_ENABLER)
               call SetUnitX(this.dummy,x)
               call SetUnitY(this.dummy,y)
           endif
           set .fxpath=newfxpath
           if(level != 0) then
               call UnitAddAbility(this.dummy, this.abil) 
               call SetUnitAbilityLevel(this.dummy, this.abil, level)
           endif
           set this.z = z
           set zangle = za
       endmethod


       method destroy takes nothing returns nothing
           if(this.abil!=0) then
               call UnitRemoveAbility(this.dummy,this.abil)
           endif
           if(this.fx!=null) then
               call DestroyEffect(this.fx)
               set this.fx=null
           endif
           call recyclebin.create(this.dummy)
           set this.dummy=null
           call this.deallocate()
       endmethod

       method hiddenDestroy takes nothing returns nothing           
           call ShowUnit(dummy,false)
           call destroy()
       endmethod
       
   endstruct

endlibrary

Xedummy:
JASS:
library xedummy requires xebasic
//******************************************************************************
// xedummy 0.9
// ------
// For all your xe dummy recycling needs.
//
//******************************************************************************

//==============================================================================
    globals
        // The number of different angles at which the dummy units will be stored.
        private constant integer ANGLE_RESOLUTION = 12

        // The total number of xe dummy units that will be preloaded on map initialization.
        private constant integer INITIAL_DUMMY_COUNT  = 36
    
        // Don't allow to keep more than DUMMY_STACK_LIMIT inactive dummy units.
        private constant integer DUMMY_STACK_LIMIT    = 240
    endglobals

// END OF CALIBRATION SECTION
// ================================================================

    private keyword xedummy
    private struct recycleQueue extends array
        recycleQueue next
        recycleQueue prev

        real angle

        integer size
        xedummy first
        xedummy last
        static method onInit takes nothing returns nothing
            local integer i=0
            loop
                exitwhen i==ANGLE_RESOLUTION
                set i=i+1
                set recycleQueue(i).prev=recycleQueue(i-1)
                set recycleQueue(i).next=recycleQueue(i+1)
                set recycleQueue(i).angle=(i-0.5)*(360.0/ANGLE_RESOLUTION)
            endloop
            set recycleQueue(1).prev=recycleQueue(i)
            set recycleQueue(i).next=recycleQueue(1)
        endmethod

        static method get takes real angle returns recycleQueue
            return recycleQueue(R2I(angle/360.0*ANGLE_RESOLUTION)+1)
        endmethod
    endstruct

// ================================================================

    struct xedummy
        private static group g=CreateGroup()
        private unit u

        // ----------------------------------------------------------------

        private xedummy next
        
        private method queueInsert takes recycleQueue q returns nothing
            call SetUnitFacing(.u, q.angle)

            if q.size==0 then
                set q.first=this
            else
                set q.last.next=this
            endif
            set q.last=this
            set .next=0

            // Recursively check adajcent queues and migrate xedummies as needed.
            if q.size>q.next.size then
                set this=q.first
                set q.first=.next
                call .queueInsert(q.next)
            elseif q.size>q.prev.size then
                set this=q.first
                set q.first=.next
                call .queueInsert(q.prev)
            else
                set q.size=q.size+1
            endif
        endmethod
        
        private static method queueRemove takes recycleQueue q returns xedummy
            // Recursively check adajcent queues and migrate xedummies as needed.
            local xedummy this
            if q.size<q.next.size then
                set this=q.last
                set q.last=.queueRemove(q.next)
                set .next=q.last
                call SetUnitFacing(q.last.u, q.angle)
            elseif q.size<q.prev.size then
                set this=q.last
                set q.last=.queueRemove(q.prev)
                set .next=q.last
                call SetUnitFacing(q.last.u, q.angle)
            else
                set q.size=q.size-1
                if q.size==0 then
                    set q.last=0
                endif
            endif

            set this=q.first
            set q.first=.next
            set .next=0
            return this
        endmethod
    
        // ----------------------------------------------------------------

        private static method create takes unit u returns xedummy
            local xedummy this
            if GetUnitTypeId(u)!=XE_DUMMY_UNITID then
                debug call BJDebugMsg("ReleaseXEDummy error: Method called on a unit of an incorrect type.")
            elseif IsUnitInGroup(u, .g) then
                debug call BJDebugMsg("ReleaseXEDummy error: Method called on an already released unit.")
            else
                set this=.allocate()
                if integer(this)>DUMMY_STACK_LIMIT then
                    call RemoveUnit(u)
                    call .deallocate()
                    return 0
                endif
                set .u=u
                call GroupAddUnit(.g, u)
                call .queueInsert(recycleQueue.get(GetUnitFacing(u)))
                call SetUnitAnimationByIndex(u, 90)
                call SetUnitScale(u, 1, 0, 0)
                call SetUnitVertexColor(u, 255, 255, 255, 255)
                // call ShowUnit(u, false) // Do not hide the unit, it is rather costly and not needed.
                return this
            endif
            return 0
        endmethod

        private method destroy takes nothing returns nothing
            call GroupRemoveUnit(.g, .u)
            call ShowUnit(.u, true) // Show the unit in case it was hidden before being recycled.
            set .u=null
            call .deallocate()
        endmethod
        
        // ----------------------------------------------------------------

        private static unit dummy

        private static method onInit takes nothing returns nothing
            local integer i=INITIAL_DUMMY_COUNT
            local recycleQueue q=recycleQueue(1)
            if i>DUMMY_STACK_LIMIT then
                debug call BJDebugMsg("xedummy error: INITIAL_DUMMY_COUNT can not be larger than DUMMY_STACK_LIMIT.")
                set i=DUMMY_STACK_LIMIT
            endif
            loop
                exitwhen i==0
                set .dummy = CreateUnit(Player(15), XE_DUMMY_UNITID, 0.0,0.0,q.angle)
                call UnitAddAbility(.dummy,XE_HEIGHT_ENABLER)
                call UnitAddAbility(.dummy,'Aloc')
                call UnitRemoveAbility(.dummy,XE_HEIGHT_ENABLER)
                call .create(.dummy)
                set i=i-1
                set q=q.next
            endloop
        endmethod

        // ----------------------------------------------------------------

        static method new takes player p, real x, real y, real face returns unit
            local recycleQueue q
            local xedummy this
            loop
                exitwhen face>0.0
                set face=face+360.0
            endloop
            loop
                exitwhen face<360.0
                set face=face-360.0
            endloop
            set q=recycleQueue.get(face)
            if q.size==0 then
                set .dummy = CreateUnit(p, XE_DUMMY_UNITID, x,y,face)
                call UnitAddAbility(.dummy,XE_HEIGHT_ENABLER)
                call UnitAddAbility(.dummy,'Aloc')
                call UnitRemoveAbility(.dummy,XE_HEIGHT_ENABLER)
                call SetUnitX(.dummy, x)
                call SetUnitY(.dummy, y)
            else
                set this=.queueRemove(q)
                set .dummy=.u
                call .destroy()
                call SetUnitX(.dummy, x)
                call SetUnitY(.dummy, y)
                call SetUnitFacing(.dummy, face)
                call SetUnitOwner(.dummy, p, true)
            endif
            return .dummy
        endmethod

        static method release takes unit u returns nothing
            call .create(u)
        endmethod
    endstruct
    
// ================================================================

    function XE_NewDummyUnit takes player p, real x, real y, real face returns unit
        return xedummy.new( p,x,y,face )
    endfunction

    function XE_ReleaseDummyUnit takes unit u returns nothing
        call xedummy.release( u )
    endfunction

endlibrary
 
Level 3
Joined
Jun 9, 2012
Messages
25
sorry, the name is not rly well chosen. HIDE_DUMMY just represents an ability id. I'm using the engineering upgrade because within the spell, the hero ability gets replaced.So i'm not hiding any unit. Though the problem seems to be that the dummy loses the locust ability.
If you're interested, you can read the part about "Aneg" on the link you posted.
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
sorry, the name is not rly well chosen. HIDE_DUMMY just represents an ability id. I'm using the engineering upgrade because within the spell, the hero ability gets replaced.So i'm not hiding any unit. Though the problem seems to be that the dummy loses the locust ability.
If you're interested, you can read the part about "Aneg" on the link you posted.

Nah I read it quite a lot of times already =D

I can only find one thing related to hiding units in your code here

JASS:
                call chargefx.hiddenDestroy()

which is linked to

JASS:
       method hiddenDestroy takes nothing returns nothing           
           call ShowUnit(dummy,false)
           call destroy()
       endmethod

and because you have xedummy

JASS:
        private method destroy takes nothing returns nothing
            call GroupRemoveUnit(.g, .u)
            call ShowUnit(.u, true) // Show the unit in case it was hidden before being recycled.
            set .u=null
            call .deallocate()
        endmethod

Thus, I believe that is what is causing your problem. You can simply try an alternative method for removing chargefx and see what turns out.
 
Level 3
Joined
Jun 9, 2012
Messages
25
shouldnt this
JASS:
if GetSpellAbilityId() == SPELL_ID and a[unitId] != 0 then
have an or not an and ? this is in ur cleanUp method.
Maybe that's a little confusing. When the hero charges the ability, a[unitId] gets 1 so that checkes if the casted spell is the spell that ends the charge and if the unit is charging. Then the value changes again to 0 to indicate that the unit isn't charging anymore.

Nah I read it quite a lot of times already =D

I can only find one thing related to hiding units in your code here

JASS:
                call chargefx.hiddenDestroy()

which is linked to

JASS:
       method hiddenDestroy takes nothing returns nothing           
           call ShowUnit(dummy,false)
           call destroy()
       endmethod

and because you have xedummy

JASS:
        private method destroy takes nothing returns nothing
            call GroupRemoveUnit(.g, .u)
            call ShowUnit(.u, true) // Show the unit in case it was hidden before being recycled.
            set .u=null
            call .deallocate()
        endmethod

Thus, I believe that is what is causing your problem. You can simply try an alternative method for removing chargefx and see what turns out.


Wow, that seems to solve the problem.I'm wondering why Vex didn't fix that yet..
Thanks alot to both of you.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
Maybe that's a little confusing. When the hero charges the ability, a[unitId] gets 1 so that checkes if the casted spell is the spell that ends the charge and if the unit is charging. Then the value changes again to 0 to indicate that the unit isn't charging anymore.

Wow, that seems to solve the problem.I'm wondering why Vex didn't fix that yet..
Thanks alot to both of you.

ooo ok lol sry for the confusion.
 
Status
Not open for further replies.
Top