• 🏆 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!

Dummy unit recycleing question

Status
Not open for further replies.
Level 17
Joined
Nov 13, 2006
Messages
1,814
somebody can translate this to me?

what this do? if missile isnt used anymore hide and destroy effet on him?
and when needed a new projectile then its check if have free projectile, if yes then show and move to target else create a new projectile dummy unit and linked list him?
missile is linked listed then why there the group then?
also this system really improve the speed with god amount? coz if stay on map 200 dummy unit, even hided that takes memeroy no?


Source from http://www.wc3c.net/showthread.php?t=101150
JASS:
//TESH.scrollpos=0
//TESH.alwaysfold=0
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
 
Status
Not open for further replies.
Top