Добавлен
Написал такой код:
раскрыть
library UnitRecycler requires UnitRevive



    globals

        private  constant  real            UNIT_CAMP_X                  =  0.0
        private  constant  real            UNIT_CAMP_Y                  =  0.0

        private  constant  group           stock                        =  CreateGroup( )
        private            unit            recycledUnit                 =  null

        private            integer         stockedRawCodesCount         =  0
        private            integer  array  stockedRawCodes

        private            integer  array  stockedUnitCount
        private            unit     array  stockedUnit[ 256 ] [ 1024 ]

    endglobals



    private constant function IsUnitAlive takes unit whichUnit returns boolean
        return not ( IsUnitType( whichUnit, UNIT_TYPE_DEAD ) or  ( GetUnitTypeId( whichUnit ) == 0 ) )
    endfunction



    private function RAW2S takes integer value returns string
        local  string   charMap         =  ".................................!.#$%&'()*+,-./0123456789:;<=>.@ABCDEFGHIJKLMNOPQRSTUVWXYZ[.]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................................................................................."
        local  string   result          =  ""
        local  integer  remainingValue  =  value
        local  integer  byteno          =  0
        local  integer  charValue

        loop
            set charValue = ModuloInteger(remainingValue, 256)
            set remainingValue = remainingValue / 256
            set result = SubString(charMap, charValue, charValue + 1) + result
     
            set byteno = byteno + 1
            exitwhen ( byteno == 4 )
        endloop

        return result
    endfunction



    private function GetUnitFromStock takes integer rawCode returns unit
        local  integer  i  =  0

        loop

            if ( stockedRawCodes[ i ] == rawCode ) and ( stockedUnitCount [ i ] > 0 ) then

                set  stockedUnitCount [ i ]                             =  stockedUnitCount [ i ] - 1
                set  recycledUnit                                       =  stockedUnit [ i ] [ stockedUnitCount [ i ] ]
                set  stockedUnit      [ i ] [ stockedUnitCount [ i ] ]  =  null
                exitwhen true
            endif

            if ( i == stockedRawCodesCount ) then

                debug call BJDebugMsg( "GetUnitFromStock(...) :    '" + RAW2S( rawCode ) + "' unittype stock is emty. New unit has been created." )
                set recycledUnit = CreateUnit( Player( 15 ), rawCode, UNIT_CAMP_X, UNIT_CAMP_Y, 0.0 )
                exitwhen true
            endif

            set i = i + 1
        endloop

        return recycledUnit
    endfunction



    private function AddUnitToStock takes unit whichUnit returns nothing
        local  integer rawCode  =  GetUnitTypeId( whichUnit )
        local  integer i        =  0

        loop
            exitwhen ( stockedRawCodes[ i ] == rawCode )

            if ( i == stockedRawCodesCount ) then
                set stockedRawCodes[ i ] = rawCode
                set stockedRawCodesCount = stockedRawCodesCount + 1
                exitwhen true
            endif

            set i = i + 1
        endloop


        set stockedUnit      [ i ] [ stockedUnitCount [ i ] ]  =  whichUnit
        set stockedUnitCount [ i ]                             =  stockedUnitCount [ i ] + 1
    endfunction



    function GetRecycledUnit takes player owner, integer rawCode, real x, real y, real facing returns unit
        set recycledUnit = GetUnitFromStock( rawCode )

        call GroupRemoveUnit    ( stock, recycledUnit )
        call SetUnitFacing      ( recycledUnit, facing )
        call PauseUnit          ( recycledUnit, false )
        call SetUnitOwner       ( recycledUnit, owner, true )
        call SetUnitPosition    ( recycledUnit, x, y )
        call SetUnitPathing     ( recycledUnit, true )
        call SetUnitInvulnerable( recycledUnit, false )
        call ShowUnit           ( recycledUnit, true )

        return recycledUnit
    endfunction



    function RecycleUnit takes unit whichUnit returns boolean
        if ( whichUnit == null ) then
            debug call BJDebugMsg( "RecycleUnit(...) :    Attempt to recycle a null unit." )
            return false

        elseif IsUnitAlive( whichUnit ) then
            debug call BJDebugMsg( "RecycleUnit(...) :    Attempt to recycle an alive unit." )
            return false

        elseif IsUnitInGroup( whichUnit, stock ) then
            debug call BJDebugMsg( "RecycleUnit(...) :    Attempt to recycle an already recycled unit." )
            return false

        elseif IsHeroUnitId( GetUnitTypeId( whichUnit ) ) then
            debug call BJDebugMsg( "RecycleUnit(...) :    Attempt to recycle a hero unit." )
            return false

        elseif ReviveUnit( whichUnit ) then
            call GroupAddUnit       ( stock, whichUnit )
            call PauseUnit          ( whichUnit, true )
            call SetUnitOwner       ( whichUnit, Player( 15 ), false )
            call SetUnitState       ( whichUnit, UNIT_STATE_LIFE, GetUnitState( whichUnit, UNIT_STATE_MAX_LIFE ) )
            call SetUnitState       ( whichUnit, UNIT_STATE_MANA, GetUnitState( whichUnit, UNIT_STATE_MAX_MANA ) )
            call SetUnitScale       ( whichUnit, 1.0, 0.0, 0.0 )
            call SetUnitVertexColor ( whichUnit, 255, 255, 255, 255 )
            call SetUnitFlyHeight   ( whichUnit, GetUnitDefaultFlyHeight( whichUnit ), 0.0 )
            call SetUnitPathing     ( whichUnit, false )
            call SetUnitInvulnerable( whichUnit, true )
//          call ShowUnit           ( whichUnit, false )
            call SetUnitPosition    ( whichUnit, UNIT_CAMP_X, UNIT_CAMP_Y )
            call AddUnitToStock     ( whichUnit )
            return true

        else
            debug call BJDebugMsg( "RecycleUnit(...) :    Cannot revive this unit." )
            return false
        endif

        return false
    endfunction



endlibrary
Вроде бы всё работает, но может быть есть тут, что не правильно? Я про функции GetUnitFromStock( ), AddUnitToStock( ), где использются двумерные массивы.

Принятый ответ

исправил некоторые недочёты, и всё же хотелось бы узнать, может еще есть какие-то недоработки тут?
раскрыть
library UnitRecycler requires UnitRevive



    globals

        private  constant  integer         MAX_STOCKED_RAWCODES         =  256
        private  constant  integer         MAX_STOCKED_UNITTYPES        =  1024

        private  constant  group           stock                        =  CreateGroup( )
        private            unit            recycledUnit                 =  null

        private            integer         stockedRawCodesCount         =  0
        private            integer  array  stockedRawCodes

        private            integer  array  stockedUnitCount
        private            unit     array  stockedUnit[ MAX_STOCKED_RAWCODES ] [ MAX_STOCKED_UNITTYPES ]

    endglobals



    private constant function IsUnitAlive takes unit whichUnit returns boolean
        return not ( IsUnitType( whichUnit, UNIT_TYPE_DEAD ) or  ( GetUnitTypeId( whichUnit ) == 0 ) )
    endfunction



    private function RAW2S takes integer value returns string
        local  string   charMap         =  ".................................!.#$%&'()*+,-./0123456789:;<=>.@ABCDEFGHIJKLMNOPQRSTUVWXYZ[.]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................................................................................."
        local  string   result          =  ""
        local  integer  remainingValue  =  value
        local  integer  byteno          =  0
        local  integer  charValue

        loop
            set charValue = ModuloInteger(remainingValue, 256)
            set remainingValue = remainingValue / 256
            set result = SubString(charMap, charValue, charValue + 1) + result
     
            set byteno = byteno + 1
            exitwhen ( byteno == 4 )
        endloop

        return result
    endfunction



    private function GetUnitFromStock takes integer rawCode returns unit
        local  integer  i  =  0

        loop

            if ( stockedRawCodes[ i ] == rawCode ) and ( stockedUnitCount [ i ] > 0 ) then

                set  stockedUnitCount [ i ]                             =  stockedUnitCount [ i ] - 1
                set  recycledUnit                                       =  stockedUnit [ i ] [ stockedUnitCount [ i ] ]
                set  stockedUnit      [ i ] [ stockedUnitCount [ i ] ]  =  null
                exitwhen true
            endif

            if ( i == stockedRawCodesCount ) then

                debug call BJDebugMsg( "GetUnitFromStock(...) :    '" + RAW2S( rawCode ) + "' unittype stock is emty. New unit has been created." )
                set recycledUnit = CreateUnit( Player( 15 ), rawCode, HIDDEN_X, HIDDEN_Y, 0.0 )
                exitwhen true
            endif

            set i = i + 1
        endloop

        return recycledUnit
    endfunction



    private function AddUnitToStock takes unit whichUnit returns nothing
        local  integer rawCode  =  GetUnitTypeId( whichUnit )
        local  integer i        =  0

        loop
            exitwhen ( stockedRawCodes[ i ] == rawCode )

            if ( i == stockedRawCodesCount ) and ( stockedRawCodesCount < MAX_STOCKED_RAWCODES ) then
                set stockedRawCodes[ i ] = rawCode
                set stockedRawCodesCount = stockedRawCodesCount + 1
                exitwhen true

            elseif ( stockedRawCodesCount == MAX_STOCKED_RAWCODES ) then
                debug call BJDebugMsg( "AddUnitToStock(...) :    Cannot add unit to stock, max rawcode count achieved. Unit has been removed." )
                call KillUnit( whichUnit )
                call ShowUnit( whichUnit, false )
            endif

            set i = i + 1
        endloop

        if ( stockedUnitCount [ i ] < MAX_STOCKED_UNITTYPES ) then
            set stockedUnit      [ i ] [ stockedUnitCount [ i ] ]  =  whichUnit
            set stockedUnitCount [ i ]                             =  stockedUnitCount [ i ] + 1

        else
            debug call BJDebugMsg( "AddUnitToStock(...) :    Cannot add unit to stock, max unittype count achieved. Unit has been removed." )
            call KillUnit( whichUnit )
            call ShowUnit( whichUnit, false )
        endif

    endfunction



    function GetRecycledUnit takes player owner, integer rawCode, real x, real y, real facing returns unit
        if IsHeroUnitId( rawCode ) then
            debug call BJDebugMsg( "GetRecycledUnit(...) :    Attempt to  get recycled hero unit." )

        else
            set recycledUnit = GetUnitFromStock( rawCode )
            call GroupRemoveUnit    ( stock, recycledUnit )
            call PauseUnit          ( recycledUnit, false )
            call SetUnitOwner       ( recycledUnit, owner, true )
            call SetUnitPosition    ( recycledUnit, x, y )
            call SetUnitFacing      ( recycledUnit, facing )
            call SetUnitPathing     ( recycledUnit, true )
            call SetUnitInvulnerable( recycledUnit, false )
            call ShowUnit           ( recycledUnit, true )

            return recycledUnit
        endif

        return null
    endfunction



    function RecycleUnit takes unit whichUnit returns boolean
        if ( whichUnit == null ) then
            debug call BJDebugMsg( "RecycleUnit(...) :    Attempt to recycle a null unit." )
            return false

        elseif IsUnitAlive( whichUnit ) then
            debug call BJDebugMsg( "RecycleUnit(...) :    Attempt to recycle an alive unit." )
            return false

        elseif IsUnitInGroup( whichUnit, stock ) then
            debug call BJDebugMsg( "RecycleUnit(...) :    Attempt to recycle an already recycled unit." )
            return false

        elseif IsHeroUnitId( GetUnitTypeId( whichUnit ) ) then
            debug call BJDebugMsg( "RecycleUnit(...) :    Attempt to recycle a hero unit." )
            return false

        elseif ReviveUnit( whichUnit ) then
            call GroupAddUnit       ( stock, whichUnit )
            call PauseUnit          ( whichUnit, true )
            call SetUnitOwner       ( whichUnit, Player( 15 ), false )
            call SetUnitState       ( whichUnit, UNIT_STATE_LIFE, GetUnitState( whichUnit, UNIT_STATE_MAX_LIFE ) )
            call SetUnitState       ( whichUnit, UNIT_STATE_MANA, GetUnitState( whichUnit, UNIT_STATE_MAX_MANA ) )
            call SetUnitScale       ( whichUnit, 1.0, 0.0, 0.0 )
            call SetUnitVertexColor ( whichUnit, 255, 255, 255, 255 )
            call SetUnitFlyHeight   ( whichUnit, GetUnitDefaultFlyHeight( whichUnit ), 0.0 )
            call SetUnitPathing     ( whichUnit, false )
            call SetUnitInvulnerable( whichUnit, true )
//          call ShowUnit           ( whichUnit, false )
            call SetUnitPosition    ( whichUnit, HIDDEN_X, HIDDEN_Y )
            call AddUnitToStock     ( whichUnit )
            return true

        else
            debug call BJDebugMsg( "RecycleUnit(...) :    Cannot revive this unit." )
            return false
        endif

        return false
    endfunction



endlibrary
0
21
6 лет назад
0
исправил некоторые недочёты, и всё же хотелось бы узнать, может еще есть какие-то недоработки тут?
раскрыть
library UnitRecycler requires UnitRevive



    globals

        private  constant  integer         MAX_STOCKED_RAWCODES         =  256
        private  constant  integer         MAX_STOCKED_UNITTYPES        =  1024

        private  constant  group           stock                        =  CreateGroup( )
        private            unit            recycledUnit                 =  null

        private            integer         stockedRawCodesCount         =  0
        private            integer  array  stockedRawCodes

        private            integer  array  stockedUnitCount
        private            unit     array  stockedUnit[ MAX_STOCKED_RAWCODES ] [ MAX_STOCKED_UNITTYPES ]

    endglobals



    private constant function IsUnitAlive takes unit whichUnit returns boolean
        return not ( IsUnitType( whichUnit, UNIT_TYPE_DEAD ) or  ( GetUnitTypeId( whichUnit ) == 0 ) )
    endfunction



    private function RAW2S takes integer value returns string
        local  string   charMap         =  ".................................!.#$%&'()*+,-./0123456789:;<=>.@ABCDEFGHIJKLMNOPQRSTUVWXYZ[.]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................................................................................."
        local  string   result          =  ""
        local  integer  remainingValue  =  value
        local  integer  byteno          =  0
        local  integer  charValue

        loop
            set charValue = ModuloInteger(remainingValue, 256)
            set remainingValue = remainingValue / 256
            set result = SubString(charMap, charValue, charValue + 1) + result
     
            set byteno = byteno + 1
            exitwhen ( byteno == 4 )
        endloop

        return result
    endfunction



    private function GetUnitFromStock takes integer rawCode returns unit
        local  integer  i  =  0

        loop

            if ( stockedRawCodes[ i ] == rawCode ) and ( stockedUnitCount [ i ] > 0 ) then

                set  stockedUnitCount [ i ]                             =  stockedUnitCount [ i ] - 1
                set  recycledUnit                                       =  stockedUnit [ i ] [ stockedUnitCount [ i ] ]
                set  stockedUnit      [ i ] [ stockedUnitCount [ i ] ]  =  null
                exitwhen true
            endif

            if ( i == stockedRawCodesCount ) then

                debug call BJDebugMsg( "GetUnitFromStock(...) :    '" + RAW2S( rawCode ) + "' unittype stock is emty. New unit has been created." )
                set recycledUnit = CreateUnit( Player( 15 ), rawCode, HIDDEN_X, HIDDEN_Y, 0.0 )
                exitwhen true
            endif

            set i = i + 1
        endloop

        return recycledUnit
    endfunction



    private function AddUnitToStock takes unit whichUnit returns nothing
        local  integer rawCode  =  GetUnitTypeId( whichUnit )
        local  integer i        =  0

        loop
            exitwhen ( stockedRawCodes[ i ] == rawCode )

            if ( i == stockedRawCodesCount ) and ( stockedRawCodesCount < MAX_STOCKED_RAWCODES ) then
                set stockedRawCodes[ i ] = rawCode
                set stockedRawCodesCount = stockedRawCodesCount + 1
                exitwhen true

            elseif ( stockedRawCodesCount == MAX_STOCKED_RAWCODES ) then
                debug call BJDebugMsg( "AddUnitToStock(...) :    Cannot add unit to stock, max rawcode count achieved. Unit has been removed." )
                call KillUnit( whichUnit )
                call ShowUnit( whichUnit, false )
            endif

            set i = i + 1
        endloop

        if ( stockedUnitCount [ i ] < MAX_STOCKED_UNITTYPES ) then
            set stockedUnit      [ i ] [ stockedUnitCount [ i ] ]  =  whichUnit
            set stockedUnitCount [ i ]                             =  stockedUnitCount [ i ] + 1

        else
            debug call BJDebugMsg( "AddUnitToStock(...) :    Cannot add unit to stock, max unittype count achieved. Unit has been removed." )
            call KillUnit( whichUnit )
            call ShowUnit( whichUnit, false )
        endif

    endfunction



    function GetRecycledUnit takes player owner, integer rawCode, real x, real y, real facing returns unit
        if IsHeroUnitId( rawCode ) then
            debug call BJDebugMsg( "GetRecycledUnit(...) :    Attempt to  get recycled hero unit." )

        else
            set recycledUnit = GetUnitFromStock( rawCode )
            call GroupRemoveUnit    ( stock, recycledUnit )
            call PauseUnit          ( recycledUnit, false )
            call SetUnitOwner       ( recycledUnit, owner, true )
            call SetUnitPosition    ( recycledUnit, x, y )
            call SetUnitFacing      ( recycledUnit, facing )
            call SetUnitPathing     ( recycledUnit, true )
            call SetUnitInvulnerable( recycledUnit, false )
            call ShowUnit           ( recycledUnit, true )

            return recycledUnit
        endif

        return null
    endfunction



    function RecycleUnit takes unit whichUnit returns boolean
        if ( whichUnit == null ) then
            debug call BJDebugMsg( "RecycleUnit(...) :    Attempt to recycle a null unit." )
            return false

        elseif IsUnitAlive( whichUnit ) then
            debug call BJDebugMsg( "RecycleUnit(...) :    Attempt to recycle an alive unit." )
            return false

        elseif IsUnitInGroup( whichUnit, stock ) then
            debug call BJDebugMsg( "RecycleUnit(...) :    Attempt to recycle an already recycled unit." )
            return false

        elseif IsHeroUnitId( GetUnitTypeId( whichUnit ) ) then
            debug call BJDebugMsg( "RecycleUnit(...) :    Attempt to recycle a hero unit." )
            return false

        elseif ReviveUnit( whichUnit ) then
            call GroupAddUnit       ( stock, whichUnit )
            call PauseUnit          ( whichUnit, true )
            call SetUnitOwner       ( whichUnit, Player( 15 ), false )
            call SetUnitState       ( whichUnit, UNIT_STATE_LIFE, GetUnitState( whichUnit, UNIT_STATE_MAX_LIFE ) )
            call SetUnitState       ( whichUnit, UNIT_STATE_MANA, GetUnitState( whichUnit, UNIT_STATE_MAX_MANA ) )
            call SetUnitScale       ( whichUnit, 1.0, 0.0, 0.0 )
            call SetUnitVertexColor ( whichUnit, 255, 255, 255, 255 )
            call SetUnitFlyHeight   ( whichUnit, GetUnitDefaultFlyHeight( whichUnit ), 0.0 )
            call SetUnitPathing     ( whichUnit, false )
            call SetUnitInvulnerable( whichUnit, true )
//          call ShowUnit           ( whichUnit, false )
            call SetUnitPosition    ( whichUnit, HIDDEN_X, HIDDEN_Y )
            call AddUnitToStock     ( whichUnit )
            return true

        else
            debug call BJDebugMsg( "RecycleUnit(...) :    Cannot revive this unit." )
            return false
        endif

        return false
    endfunction



endlibrary
Принятый ответ
Чтобы оставить комментарий, пожалуйста, войдите на сайт.