Projectile system bug

MasterOfRa

New Member
Reaction score
10
The library works perfectly, except for a slight problem. if I attach a effect with a ribbon effect to it, then the ribbon jumps to the new location when the dummy gets recycled. What can i do about this, other than not recycle them?

JASS:
library Projectile initializer init uses Recycler, TT
    // uses Cjass
    
    location TempLoc // Used for height calculations
    group dummyPool // Used for recycling
    
    function NewDummy takes real x, real y returns unit
        local unit u = FirstOfGroup(dummyPool) // Get first of group
        if u == null then
            // if group was empty, create a new one
            u = CreateUnit(Player(15), UID_DUMMY,x,y,0)
            DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,2,I2S(GetRandomInt(1,5)))
        else
            // otherwise, set location, and remove unit from group
            SetUnitX(u,x)
            SetUnitY(u,y)
            GroupRemoveUnit(dummyPool, u)
        endif
        return u
    endfunction
    
    function ReleaseDummy takes unit u returns nothing
        GroupAddUnit(dummyPool,u)
            // Add Dummy to Group
    endfunction
    
    struct Projectile
        implement PAM_Property
        //instance list
        readonly static integer num = 0
        readonly static Projectile array list
        readonly integer listIndex

        //unit
        readonly unit u = null // The Dummy
        readonly effect sfx = null // The Effect
        readonly real dx = 0 // MomentumX
        readonly real dy = 0 // MomentumY
        readonly real dz = 0 // MomentumX
        readonly real x  = 0 // CurrentX
        readonly real y  = 0 // CurrentY
        readonly real z  = 0 // CurrentZ
        ///Updates all Projectiles by one second
        public static method CatchTick takes nothing returns nothing
            integer i
            Projectile t

            //Apply Momentum
            loopForIntBelow(i, Projectile.num)
                t = Projectile.list<i>
                t.ApplyMomentum()
            endloop
            
        endmethod
        
        method ApplyMomentum takes nothing returns nothing
            .x+= .dx * TT_PERIOD// offset Location
            .y+= .dy * TT_PERIOD//
            .z+= .dz * TT_PERIOD//
            SetUnitX(.u,.x)// Move the unit
            SetUnitY(.u,.y)
            MoveLocation(TempLoc,.x,.y)
            if .z - GetLocationZ(TempLoc) &lt;= 0 then // Check for ground hit.
                .destroy()
            endif
            SetUnitFlyHeight(.u,.z - GetLocationZ(TempLoc),0) // Set Height
            SetUnitFacing(.u,Atan2(.dy,.dx)*bj_RADTODEG)      // Set facing
            
            real dxy = SquareRoot(.dx*.dx+.dy*.dy)
            integer angle = R2I(Atan2(dxy,.dz)*bj_RADTODEG)
            if angle &lt; 0 then
                angle *= -1
            endif
            angle = 180 - angle
            SetUnitAnimationByIndex(.u,angle+1) // Set AngleV
            
            .dz -= 10
        endmethod
            
        ///Creates a Projectile structure for a given unit
        public static method create takes string SFX ,\ // Attached Effect
                                          real scale ,\ // Size
                                          real x     ,\ // StartLocation
                                          real y     ,\
                                          real z     ,\
                                          real dx    ,\ // StartMomentum
                                          real dy    ,\
                                          real dz     \
                                          returns thistype
            
            Projectile this
            macro_AllocCheck(this, Projectile)
            .u = NewDummy(x,y) // Get a new dummy unit
            SetUnitScale(.u,scale,scale,scale) // Set Size
            .sfx = AddSpecialEffectTarget(SFX,.u,&quot;origin&quot;) // Attach the Effect
            .x = x // Set Stored Location
            .y = y
            .z = z
            .dx = dx // Set Momentum
            .dy = dy
            .dz = dz
            call UnitAddAbility(.u,AID_FLY)    // Enable HeightChange
            call UnitRemoveAbility(.u,AID_FLY)
            MoveLocation(TempLoc,x,y)
            SetUnitFlyHeight(.u,z-GetLocationZ(TempLoc),0) // Set Height
            SetUnitFacing(.u,Atan2(.dy,.dx)*bj_RADTODEG)
            
            real dxy = SquareRoot(dx*dx+dy*dy)
            integer angle = R2I(Atan2(dxy,dz)*bj_RADTODEG)
            if angle &lt; 0 then
                angle *= -1
            endif
            SetUnitAnimationByIndex(.u,angle+1) // Set AngleV
            

            
            .listIndex = Projectile.num
            Projectile.list[Projectile.num] = this
            Projectile.num += 1
            Projectile[.u] = this
            return this
        endmethod

        ///Cleans up properly
        private method onDestroy takes nothing returns nothing
            assert(this != 0)

            //remove from global array
            Projectile.num -= 1
            Projectile.list[Projectile.num].listIndex = .listIndex
            Projectile.list[.listIndex] = Projectile.list[Projectile.num]
            Projectile.list[Projectile.num] = 0

            //destroy other stuff
            Projectile.RemoveKey(.u)
            DestroyEffect(.sfx)
            schedule_unit(Action_unit.ReleaseDummy, 2.5, .u)
            .u = null
            
        endmethod
    endstruct
    private function test takes nothing returns nothing
            // This simply creates projectiles at the center of the map at random angles and speeds.
        real angle = GetRandomReal(0,2*bj_PI)
        real anglez = GetRandomReal(0.25*bj_PI,0.40*bj_PI)
        real speed = GetRandomReal(300,600)
        real SpeedX = speed*Cos(angle)*Cos(anglez)
        real SpeedY = speed*Sin(angle)*Cos(anglez)
        real SpeedZ = speed*Sin(anglez)
        real X = 0
        real Y = 0
        real Z
        MoveLocation(TempLoc,X,Y)
        Z = 10+GetLocationZ(TempLoc)
        Projectile.create(&quot;Abilities\\Weapons\\WaterElementalMissile\\WaterElementalMissile.mdl&quot;,GetRandomReal(.2,.8),X,Y,Z,SpeedX,SpeedY,SpeedZ)
    endfunction
    
    private function test2 takes nothing returns nothing
    integer z = 0
    loop
        test()
        z++
        exitwhen z &gt;= 30
    endloop
    endfunction
    
    private function init takes nothing returns nothing
        TempLoc = Location(0.0,0.0) // Create the Temp Location
        dummyPool = NewGroup()      // Create the dummyPool
        TriggerSleepAction(.01)
        macro_AddPeriodicHandler(TT_PERIOD, function Projectile.CatchTick) // Start a periodic timer
        macro_AddPeriodicHandler(2, function test2)// Start another one
    endfunction
endlibrary
</i>
 

Viikuna

No Marlo no game.
Reaction score
265
You should not add your dummy to stack or group or whatever in onDestroy, but wait X secs ( X being your attached effects death animation duration ) before recycling dummy.
 

MasterOfRa

New Member
Reaction score
10
You should not add your dummy to stack or group or whatever in onDestroy, but wait X secs ( X being your attached effects death animation duration ) before recycling dummy.

Doesnt work, same thing still happened.

Edit:

I thought the delay was 2.5 seconds, as in the viewer, the death animation was 2.33 sec long.
However, when i made it 20 seconds, it worked fine, +rep
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top