• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Projectile collision stops rest of code.

Status
Not open for further replies.
Well, I'm making a simple system for use with a map I'm making.
My problem is that if I set a projectile to collide, it will never move. Here is my code so far:

JASS:
//========================PROJECTILE SYSTEM CORE=======================//

library PSCore

    globals
        private timer PSUpdate = CreateTimer()
        private integer PSCount = 0
        private projectile array PSArray
        private integer PSDummy = 'e000'
        constant real PSUpdateInterval = 0.04
        private real MAX_X
        private real MAX_Y
        private real MIN_X
        private real MIN_Y
        private boolexpr filter
    endglobals
    
    private function PSFilter takes nothing returns boolean
        return true
    endfunction
    
    private function PSMain takes nothing returns boolean
        local projectile p
        local integer i = 1
        local real cX
        local real cY
        local unit u
        local group g
        
        loop
            exitwhen i > PSCount
            set p = PSArray[ i ]
            
            if (p.x > MAX_X) or (p.y > MAX_Y) or (p.x < MIN_X) or (p.y < MIN_Y) then
                call p.destroy()
                return false
            endif
            
            if p.data.moves then // Movement
                set p.x = p.x + p.data.speed * Cos( p.data.dir ) //Already dealing with radians not degrees.
                set p.y = p.y + p.data.speed * Sin( p.data.dir )
                call SetUnitPosition( p.dummy, p.x, p.y )
            endif
            
            if p.data.collides then //Collision
                //Thanks to HINDYHat for this nice way of looping through a group.
                call GroupEnumUnitsInRange( g, p.x, p.y, p.data.radius, filter )
                call GroupRemoveUnit( g, p.dummy )
                call GroupRemoveUnit( g, p.owner )
                loop
                    set u = FirstOfGroup( g )
                    exitwhen u == null
                    call p.data.Collide( u )
                    call GroupRemoveUnit( g, u )
                endloop
                call DestroyGroup( g )
                set g = null
                set u = null
            endif
            
            call p.data.Think() //Thinking!
            
            set i = i + 1
        endloop
        return true
    endfunction
    
    interface pdata
        real radius = 0.0
        real speed = 0.0
        real dir = 0.0
        real height = 0.0
        string model = ""
        boolean moves = false
        boolean collides = false
        boolean bounces = false
        projectile parent
        
        method Think takes nothing returns nothing defaults nothing
        method Collide takes unit c returns nothing defaults nothing
        method Start takes nothing returns nothing defaults nothing
        method End takes nothing returns nothing defaults nothing
    endinterface
    
    struct projectile
        pdata data
        integer id
        real x
        real y
        unit dummy
        unit owner
        effect ef
        
        static method create takes pdata data, unit owner, real x, real y returns projectile
            local projectile p = projectile.allocate()
            set p.data = data
            set p.owner = owner
            set p.x = x
            set p.y = y
            set p.dummy = CreateUnit( GetOwningPlayer(owner), PSDummy, x, y, data.dir )
            set p.ef = AddSpecialEffectTarget( data.model, p.dummy, "origin" )
            call SetUnitFlyHeight( p.dummy, data.height, 1000 )
            
            set PSCount = PSCount + 1
            set p.id = PSCount
            set PSArray[PSCount] = p
            debug call BJDebugMsg( "Projectile created with model: " + data.model + "[" + I2S( PSCount ) + "]" )
            
            //Timer stuff
            if PSCount == 1 then
                call TimerStart( PSUpdate, PSUpdateInterval, true, function PSMain )
            endif
            
            return p
        endmethod
        
        method onDestroy takes nothing returns nothing
            local integer i = .id + 1
            call DestroyEffect( .ef )
            call RemoveUnit( .dummy )
            set .dummy = null
            set .ef = null
            call .data.destroy()
            
            //Updating the projectile stack.
            loop
                exitwhen i > PSCount
                set PSArray[ i ].id = i - 1
                set PSArray[ i-1 ] = PSArray[ i ]
                set i = i + 1
            endloop
            set PSCount = PSCount - 1
            if PSCount == 0 then
                call PauseTimer( PSUpdate )
            endif
            
        endmethod
        
    endstruct
    
    function InitTrig_PSCore takes nothing returns nothing
        set MAX_X = GetRectMaxX( bj_mapInitialPlayableArea ) - 10
        set MAX_Y = GetRectMaxY( bj_mapInitialPlayableArea ) - 10
        set MIN_X = GetRectMinX( bj_mapInitialPlayableArea ) + 10
        set MIN_Y = GetRectMinY( bj_mapInitialPlayableArea ) + 10
        set filter = Filter(function PSFilter)
    endfunction
    
endlibrary

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

JASS:
library PSTypes requires PSCore
    struct projectile_glaive extends pdata
        real radius = 64.0
        real speed = 20.0
        real height = 60.0
        string model = "Abilities\\Weapons\\SentinelMissile\\SentinelMissile.mdl"
        boolean moves = true
        boolean collides = false
        boolean bounces = true
        
        static method create takes nothing returns projectile_glaive
            return projectile_glaive.allocate()
        endmethod
        
        method Collide takes unit u returns nothing
            debug call BJDebugMsg( "Glaive collided with unit." )
        endmethod
    endstruct
endlibrary

Basically, when I set the 'collides' boolean in the projectile_glaive struct to false, it works fine but if i set it to true then movement stops and collision doesn't occur either. I get no errors with the collision code. Here it is (if you can't be bothered to look through all of that and find it) :
JASS:
if p.data.collides then //Collision
                //Thanks to HINDYHat for this nice way of looping through a group.
                call GroupEnumUnitsInRange( g, p.x, p.y, p.data.radius, filter )
                call GroupRemoveUnit( g, p.dummy )
                call GroupRemoveUnit( g, p.owner )
                loop
                    set u = FirstOfGroup( g )
                    exitwhen u == null
                    call p.data.Collide( u )
                    call GroupRemoveUnit( g, u )
                endloop
                call DestroyGroup( g )
                set g = null
                set u = null
            endif

Example map included in the thread. Try changing the collides boolean and you'll see what I mean.

Edit:
Fixed. Forgot to do set g = CreateGroup()
 

Attachments

  • Projectile System.w3x
    37.9 KB · Views: 32
Last edited:
Status
Not open for further replies.
Top