• 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.
  • It's time for the first HD Modeling Contest of 2025. Join the theme discussion for Hive's HD Modeling Contest #7! Click here to post your idea!

[Solved] HELP: How to Add Units to a Function

Status
Not open for further replies.
Level 11
Joined
Mar 31, 2016
Messages
657
Hello, I'm having trouble figuring out how to add more units to a function.
Specifically, I want to add additional worker units to each worker slot - about 10 to #1, 4 to #2.
So far I've tried a couple of methods unsuccessfully shown below.

Here is the part of the code I need help with.

JASS:
    //Returns the unit type of the given WorkerSlot:
    private function WorkerSlot2UnitID takes integer WorkerSlot returns integer
        if (WorkerSlot == 1) then
            return libId_udg_Worker //Worker
        elseif (WorkerSlot == 2) then
            return libId_udg_Architect //Architect
        endif
        return 0
    endfunction

I also tried

JASS:
    //Returns the unit type of the given WorkerSlot:
    private function WorkerSlot2UnitID takes integer WorkerSlot returns integer
        if (WorkerSlot == 1) then
            return libId_udg_Worker //Worker
        elseif (WorkerSlot == 1) then
            return libId_udg_Worker2 //Worker (2)
        elseif (WorkerSlot == 2) then
            return libId_udg_Architect //Architect
        elseif (WorkerSlot == 2) then
            return libId_udg_Architect2 //Architect (2)
        endif
        return 0
    endfunction

and

JASS:
    //Returns the unit type of the given WorkerSlot:
    private function WorkerSlot2UnitID takes integer WorkerSlot returns integer
        if (WorkerSlot == 1) then
            return libId_udg_Worker or libId_udg_Worker2 //Worker (1,2)
        elseif (WorkerSlot == 2) then
            return libId_udg_Architect or libId_udg_Architect2 //Architect (1,2)
        endif
        return 0
    endfunction

Here is the whole trigger...
JASS:
library libBuilSite initializer Init_BuildingSiteSystem requires libId, libUnitDat, libDum, libWal
    //------------------
    //CUSTOMIZABLE PART:
    //------------------
   
    globals
        private constant integer udg_SystemSlot = libUnitDat_udg_SystemNumber_BuildingSiteSystem
        private constant integer udg_CountPlayers = 12 //Highest player slot in use
        private constant integer udg_MaxBuildingSites = 50 * udg_CountPlayers //Maximal allowed building sites at the same time
        private constant integer udg_MaxWorkerTypes = 2 //Maximal used different worker types
        private constant real udg_BuildingRate = 0.05 //Higher rate for smoother building but worse performence
        private constant real udg_MaxAutoBuildRange = 1024.00 //Range in which workers automatically look for another suitable building site after finishing one
    endglobals
   
    //Returns the amount of work required to complete the given building type:
    private function GetBuildingValue takes integer BuildingID returns real
        //Building site (tiny):
        if (BuildingID == libId_udg_Barricade) then //Barricade
            return 10.00
        elseif (BuildingID == libId_udg_Ballista) then //Ballista
            return 48.00
        //Building site (little):
        elseif (BuildingID == libId_udg_GateCl) then //Gate (Closed)
            return 90.00
        elseif (BuildingID == libId_udg_PalisadeGateCl) then //Palisade gate (Closed)
            return 45.00
        elseif (BuildingID == libId_udg_WallUn or BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallIEUn) then //Wall (all Undamaged)
            return 60.00
        elseif (BuildingID == libId_udg_PalisadeUn or BuildingID == libId_udg_PalisadeOEUn or BuildingID == libId_udg_PalisadeIEUn) then //Palisade (all Undamaged)
            return 30.00
        elseif (BuildingID == libId_udg_TowerUn or BuildingID == libId_udg_TowerOEUn or BuildingID == libId_udg_TowerIEUn) then //Tower (all Undamaged)
            return 120.00
        //Building site (small):
        elseif (BuildingID == libId_udg_BigGateCl) then //Big gate (Closed)
            return 120.00
        elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerIEUn) then //Big tower (all Undamaged)
            return 180.00
        elseif (BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (all Undamaged)
            return 240.00
        //Building site (big):
        elseif (BuildingID == libId_udg_LongHall1) then //Long Hall (1)
            return 90.00
        elseif (BuildingID == libId_udg_LongHall2) then //Long Hall (2)
            return 60.00
        elseif (BuildingID == libId_udg_LongHall3) then //Long Hall (3)
            return 60.00
        elseif (BuildingID == libId_udg_LongHall4) then //Long Hall (4)
            return 60.00
        elseif (BuildingID == libId_udg_GreatHall1) then //Great Hall (1)
            return 120.00
        elseif (BuildingID == libId_udg_GreatHall2) then //Great Hall (2)
            return 80.00
        elseif (BuildingID == libId_udg_GreatHall3) then //Great Hall (3)
            return 80.00
        elseif (BuildingID == libId_udg_University1) then //University (1)
            return 80.00
        elseif (BuildingID == libId_udg_University2) then //University (2)
            return 80.00
        elseif (BuildingID == libId_udg_Barracks1) then //Barracks (1)
            return 120.00
        elseif (BuildingID == libId_udg_Barracks2) then //Barracks (2)
            return 80.00
        elseif (BuildingID == libId_udg_Barracks3) then //Barracks (3)
            return 80.00
        elseif (BuildingID == libId_udg_Barracks4) then //Barracks (4)
            return 80.00
        //Building site (very large):
        elseif (BuildingID == libId_udg_Tavern1) then //Tavern (1)
            return 180.00
        elseif (BuildingID == libId_udg_Tavern2) then //Tavern (2)
            return 120.00
        elseif (BuildingID == libId_udg_Tavern3) then //Tavern (3)
            return 120.00
        //Building site (special):
        elseif (BuildingID == libId_udg_Stairs) then //Stairs
            return 40.00
        elseif (BuildingID == libId_udg_LadderWall) then //Ladder (Wall)
            return -3.00
        elseif (BuildingID == libId_udg_LadderPalisade) then //Ladder (Palisade)
            return -3.00
        elseif (BuildingID == libId_udg_WallDa or BuildingID == libId_udg_WallOEDa or BuildingID == libId_udg_WallIEDa) then //Wall (all Damaged)
            return 20.00
        elseif (BuildingID == libId_udg_WallDe or BuildingID == libId_udg_WallOEDe or BuildingID == libId_udg_WallIEDe) then //Wall (all Destroyed)
            return 50.00
        elseif (BuildingID == libId_udg_PalisadeDa or BuildingID == libId_udg_PalisadeOEDa or BuildingID == libId_udg_PalisadeIEDa or BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (all Damaged)
            return 10.00
        elseif (BuildingID == libId_udg_PalisadeDe or BuildingID == libId_udg_PalisadeOEDe or BuildingID == libId_udg_PalisadeIEDe) then //Palisade (all Destroyed)
            return 25.00
        elseif (BuildingID == libId_udg_GateDa) then //Gate (Damaged)
            return 40.00
        elseif (BuildingID == libId_udg_PalisadeGateDa) then //Palisade gate (Damaged)
            return 20.00
        elseif (BuildingID == libId_udg_BigGateDa) then //Big gate (Damaged)
            return 60.00
        elseif (BuildingID == libId_udg_TowerDa or BuildingID == libId_udg_TowerOEDa or BuildingID == libId_udg_TowerIEDa) then //Tower (all Damaged)
            return 40.00
        elseif (BuildingID == libId_udg_TowerDe or BuildingID == libId_udg_TowerOEDe or BuildingID == libId_udg_TowerIEDe) then //Tower (all Destroyed)
            return 100.00
        elseif (BuildingID == libId_udg_BigTowerDa or BuildingID == libId_udg_BigTowerOEDa or BuildingID == libId_udg_BigTowerIEDa) then //Big tower (all Damaged)
            return 140.00
        elseif (BuildingID == libId_udg_BigTowerDe or BuildingID == libId_udg_BigTowerOEDe or BuildingID == libId_udg_BigTowerIEDe) then //Big tower (all Destroyed)
            return 30.00
        endif
        return 0.00
    endfunction
   
    //Returns the building size ("Grafic - Scaling value") of the building type:
    private function GetBuildingSize takes integer BuildingID returns real
        //Building site (tiny):
        if (BuildingID == libId_udg_Barricade) then //Barricade
            return 0.60
        elseif (BuildingID == libId_udg_Ballista) then //Ballista
            return 0.60
        //Building site (big):
        elseif (BuildingID == libId_udg_LongHall1) then //Long Hall (1)
            return 1.80
        elseif (BuildingID == libId_udg_LongHall2) then //Long Hall (2)
            return 1.80
        elseif (BuildingID == libId_udg_LongHall3) then //Long Hall (3)
            return 1.80
        elseif (BuildingID == libId_udg_LongHall4) then //Long Hall (4)
            return 1.80
        elseif (BuildingID == libId_udg_GreatHall1) then //Great Hall (1)
            return 1.55
        elseif (BuildingID == libId_udg_GreatHall2) then //Great Hall (2)
            return 1.55
        elseif (BuildingID == libId_udg_GreatHall3) then //Great Hall (3)
            return 1.55
        elseif (BuildingID == libId_udg_University1) then //University (1)
            return 1.70
        elseif (BuildingID == libId_udg_University2) then //University (2)
            return 1.70
        elseif (BuildingID == libId_udg_Barracks1) then //Barracks (1)
            return 2.30
        elseif (BuildingID == libId_udg_Barracks2) then //Barracks (2)
            return 2.30
        elseif (BuildingID == libId_udg_Barracks3) then //Barracks (3)
            return 2.30
        elseif (BuildingID == libId_udg_Barracks4) then //Barracks (4)
            return 2.30
        endif
        return 1.00
    endfunction

    //Returns the minimal/maximal number of required/allowed workers of the given type number for the given building type:
    private function GetNeededWorkers takes integer BuildingID, integer WorkerSlot, boolean ReturnMin returns integer
        //Building site (tiny):
        if (BuildingID == libId_udg_Barricade) then //Barricade
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_Ballista) then //Ballista
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 3
                endif
            endif
        //Building site (little):
        elseif (BuildingID == libId_udg_GateCl) then //Gate (Closed)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_PalisadeGateCl) then //Palisade gate (Closed)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_WallUn or BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallIEUn) then //Wall (all Undamaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_PalisadeUn or BuildingID == libId_udg_PalisadeOEUn or BuildingID == libId_udg_PalisadeIEUn) then //Palisade (all Undamaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_TowerUn or BuildingID == libId_udg_TowerOEUn or BuildingID == libId_udg_TowerIEUn) then //Tower (all Undamaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 4
                endif
            endif
        //Building site (small):
        elseif (BuildingID == libId_udg_BigGateCl) then //Big gate (Closed)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 5
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 1
                endif
            endif
        elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerIEUn) then //Big tower (all Undamaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 5
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 1
                endif
            endif
        elseif (BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (all Undamaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 6
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        //Building site (big):
        elseif (BuildingID == libId_udg_LongHall1) then //Long Hall (1)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 8
                endif
            endif
        elseif (BuildingID == libId_udg_LongHall2 or BuildingID == libId_udg_LongHall3 or BuildingID == libId_udg_LongHall4) then //Long Hall (2,3,4)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 8
                endif
            endif
        elseif (BuildingID == libId_udg_GreatHall1) then //Great Hall (1)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 4
                else
                    return 10
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_GreatHall2 or BuildingID == libId_udg_GreatHall3) then //Great Hall (2,3)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 4
                else
                    return 10
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_University1 or BuildingID == libId_udg_University2) then //University (1,2)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 4
                else
                    return 10
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_Barracks1) then //Barracks (1)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 4
                else
                    return 10
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_Barracks2 or BuildingID == libId_udg_Barracks3 or BuildingID == libId_udg_Barracks4) then //Barracks (2,3,4)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 4
                else
                    return 10
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        //Building site (very large):
        elseif (BuildingID == libId_udg_Tavern1) then //Tavern (1)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 8
                endif
            endif
        elseif (BuildingID == libId_udg_Tavern2 or BuildingID == libId_udg_Tavern3) then //Tavern (2,3)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 8
                endif
            endif
        //Building site (special):
        elseif (BuildingID == libId_udg_Stairs) then //Stairs
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 3
                endif
            endif
        elseif (BuildingID == libId_udg_GateDa) then //Gate (Damaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_PalisadeGateDa) then //Palisade gate (Damaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_BigGateDa) then //Big gate (Damaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_WallDa or BuildingID == libId_udg_WallOEDa or BuildingID == libId_udg_WallIEDa) then //Wall (all Damaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_WallDe or BuildingID == libId_udg_WallOEDe or BuildingID == libId_udg_WallIEDe) then //Wall (all Destroyed)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_PalisadeDa or BuildingID == libId_udg_PalisadeOEDa or BuildingID == libId_udg_PalisadeIEDa or BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (all Damaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_PalisadeDe or BuildingID == libId_udg_PalisadeOEDe or BuildingID == libId_udg_PalisadeIEDe) then //Palisade (all Destroyed)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_TowerDa or BuildingID == libId_udg_TowerOEDa or BuildingID == libId_udg_TowerIEDa) then //Tower (all Damaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_TowerDe or BuildingID == libId_udg_TowerOEDe or BuildingID == libId_udg_TowerIEDe) then //Tower (all Destroyed)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_BigTowerDa or BuildingID == libId_udg_BigTowerOEDa or BuildingID == libId_udg_BigTowerIEDa) then //Big tower (all Damaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 3
                endif
            endif
        elseif (BuildingID == libId_udg_BigTowerDe or BuildingID == libId_udg_BigTowerOEDe or BuildingID == libId_udg_BigTowerIEDe) then //Big tower (all Destroyed)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 5
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 1
                endif
            endif
        elseif (BuildingID == libId_udg_DrumTowerDa or BuildingID == libId_udg_DrumTowerOEDa or BuildingID == libId_udg_DrumTowerIEDa) then //Drum tower (all Damaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 3
                endif
            endif
        elseif (BuildingID == libId_udg_DrumTowerDe or BuildingID == libId_udg_DrumTowerOEDe or BuildingID == libId_udg_DrumTowerIEDe) then //Drum tower (all Destroyed)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 8
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        endif
        return 0
    endfunction
   
    //Returns the building site for the given building type (only required for multi-edge fortifications):
    private function GetBuildingSiteID takes integer BuildingID returns integer
        if (BuildingID == libId_udg_WallUn) then //Wall (Undamaged)
            return libId_udg_BuildingSiteLittle //Building site (little)
        elseif (BuildingID == libId_udg_WallOEUn) then //Wall (Outer Edge) (Undamaged)
            return libId_udg_BuildingSiteEdge //Building site (Edge)
        elseif (BuildingID == libId_udg_WallIEUn) then //Wall (Inner Edge) (Undamaged)
            return libId_udg_BuildingSiteEdge //Building site (Edge)
        elseif (BuildingID == libId_udg_PalisadeUn) then //Palisade (Undamaged)
            return libId_udg_BuildingSiteLittle //Building site (little)
        elseif (BuildingID == libId_udg_PalisadeOEUn) then //Palisade (Outer Edge) (Undamaged)
            return libId_udg_BuildingSiteEdge //Building site (Edge)
        elseif (BuildingID == libId_udg_PalisadeIEUn) then //Palisade (Inner Edge) (Undamaged)
            return libId_udg_BuildingSiteEdge //Building site (Edge)
        elseif (BuildingID == libId_udg_TowerUn) then //Tower (Undamaged)
            return libId_udg_BuildingSiteLittle //Building site (little)
        elseif (BuildingID == libId_udg_TowerOEUn) then //Tower (Outer Edge) (Undamaged)
            return libId_udg_BuildingSiteEdge //Building site (Edge)
        elseif (BuildingID == libId_udg_TowerIEUn) then //Tower (Inner Edge) (Undamaged)
            return libId_udg_BuildingSiteEdge //Building site (Edge)
        elseif (BuildingID == libId_udg_BigTowerUn) then //Big tower (Undamaged)
            return libId_udg_BuildingSiteSmall //Building site (small)
        elseif (BuildingID == libId_udg_BigTowerOEUn) then //Big tower (Outer Edge) (Undamaged)
            return libId_udg_BuildingSiteEdge //Building site (Edge)
        elseif (BuildingID == libId_udg_BigTowerIEUn) then //Big tower (Inner Edge) (Undamaged)
            return libId_udg_BuildingSiteEdge //Building site (Edge)
        elseif (BuildingID == libId_udg_DrumTowerUn) then //Drum tower (Undamaged)
            return libId_udg_BuildingSiteSmall //Building site (small)
        elseif (BuildingID == libId_udg_DrumTowerOEUn) then //Drum tower (Outer Edge) (Undamaged)
            return libId_udg_BuildingSiteEdge //Building site (Edge)
        elseif (BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (Inner Edge) (Undamaged)
            return libId_udg_BuildingSiteEdge //Building site (Edge)
        endif
        return 0
    endfunction
   
    //Returns the unit type of the given WorkerSlot:
    private function WorkerSlot2UnitID takes integer WorkerSlot returns integer
        if (WorkerSlot == 1) then
            return libId_udg_Worker //Worker
        elseif (WorkerSlot == 1) then
            return libId_udg_Worker1b //Worker (1)
        elseif (WorkerSlot == 2) then
            return libId_udg_Architect //Architect
        endif
        return 0
    endfunction
   
    //Returns the square size of the given building site type:
    private function GetBuildingSiteSquareSize takes integer BuildingID returns real
        if (BuildingID == libId_udg_BuildingSiteTiny) then //Building site (tiny)
            return 64.00
        elseif (BuildingID == libId_udg_BuildingSiteLittle) then //Building site (little)
            return 128.00
        elseif (BuildingID == libId_udg_BuildingSiteSmall) then //Building site (small)
            return 192.00
        elseif (BuildingID == libId_udg_BuildingSiteBig) then //Building site (big)
            return 320.00
        elseif (BuildingID == libId_udg_BuildingSiteVeryLarge) then //Building site (very large)
            return 512.00
        elseif (BuildingID == libId_udg_BuildingSiteStairs) then //Building site (Stairs)
            return 192.00
        elseif (BuildingID == libId_udg_BuildingSiteLadder) then //Building site (Ladder)
            return 128.00
        endif
        return 0.00
    endfunction
   
    //Returns the work power per second:
    private function GetWorkPower takes integer UnitID returns real
        if (UnitID == libId_udg_Worker) then //Worker
            return 1.00
        elseif (UnitID == libId_udg_Worker2a) then //Worker (2)
            return 1.10
        elseif (UnitID == libId_udg_Worker3a) then //Worker (3)
            return 1.20
        elseif (UnitID == libId_udg_Worker4a) then //Worker (4)
            return 1.30
        elseif (UnitID == libId_udg_Worker1b) then //Worker (1)
            return 1.00
        elseif (UnitID == libId_udg_Worker2b) then //Worker (2)
            return 1.10
        elseif (UnitID == libId_udg_Worker3b) then //Worker (3)
            return 1.20
        elseif (UnitID == libId_udg_Worker4b) then //Worker (4)
            return 1.30
        elseif (UnitID == libId_udg_Worker1e) then //Engineer (1)
            return 2.00
        elseif (UnitID == libId_udg_Worker2e) then //Engineer (2)
            return 2.50
        elseif (UnitID == libId_udg_Architect) then //Architect
            return 1.50
        elseif (UnitID == libId_udg_Architect2) then //Architect (2)
            return 1.70
        elseif (UnitID == libId_udg_Architect3) then //Architect (3)
            return 1.90
        endif
        return 0.00
    endfunction

    //-----------------
    //DECLARATION PART:
    //-----------------
   
    globals
        private constant real udg_AntiSingularityAddition = 0.000001
        private constant integer udg_MaxBuildingSitesP = udg_MaxBuildingSites + 1
        private constant integer udg_MaxWorkerTypesP = udg_MaxWorkerTypes + 1
    endglobals
   
    private struct BuildingSite
        private integer BuildingObjectNumber = 0
        private integer WorkersClusterNumber = 0
        private real Progress = 0.00
        private real Workpower = 0.00
        private integer array WorkerCounts [udg_MaxWorkerTypesP]
        private boolean EnoughWorker = false
       
        public method remove takes nothing returns nothing
            local group GroupTemp1 = libUnitDat_GetGroup(this.WorkersClusterNumber)
            local unit UnitTemp1
            local integer IntLoop1 = 1
            call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, 0)
            set this.BuildingObjectNumber = 0
            call libUnitDat_SetClusterSystemNumbers(this.WorkersClusterNumber, udg_SystemSlot, 0)
            loop
                set UnitTemp1 = FirstOfGroup(GroupTemp1)
                exitwhen UnitTemp1 == null
                call GroupRemoveUnit(GroupTemp1, UnitTemp1)
                call UnitRemoveAbility(UnitTemp1, libId_udg_ConstructingBuff)
                call SetUnitAnimation(UnitTemp1, "stand")
            endloop
            call libUnitDat_RemoveCluster(this.WorkersClusterNumber)
            set this.WorkersClusterNumber = 0
            set this.Progress = 0.00
            set this.Workpower = 0.00
            loop
                exitwhen IntLoop1 > udg_MaxWorkerTypes
                set this.WorkerCounts[IntLoop1] = 0
                set IntLoop1 = IntLoop1 + 1
            endloop
            set this.EnoughWorker = false
            call this.destroy()
            //Anti-Memory-Leak:
            call DestroyGroup(GroupTemp1)
            set GroupTemp1 = null
            set UnitTemp1 = null
        endmethod

        //------------
        //GET METHODS:
        //------------
       
        public method GetBuilding takes nothing returns unit
            return libUnitDat_GetUnit(this.BuildingObjectNumber)
        endmethod
       
        public method GetWorkers takes nothing returns group
            return libUnitDat_GetGroup(this.WorkersClusterNumber)
        endmethod
       
        public method GetProgress takes nothing returns real
            return this.Progress
        endmethod

        public method GetWorkerCounts takes integer WorkerSlot returns integer
            return this.WorkerCounts[WorkerSlot]
        endmethod
       
        //------------
        //SET METHODS:
        //------------
       
        public method SetBuilding takes unit Building returns nothing
            set this.BuildingObjectNumber = libUnitDat_GetObjectNumber(Building, true)
        endmethod
       
        //--------------
        //OTHER METHODS:
        //--------------
       
        public method New takes unit Building, integer BuildingSiteNumber returns nothing
            local integer IntLoop1 = 1
            set this.BuildingObjectNumber = libUnitDat_GetObjectNumber(Building, true)
            call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, BuildingSiteNumber)
            set this.WorkersClusterNumber = libUnitDat_CreateCluster()
            set this.Progress = GetBuildingValue(GetUnitTypeId(Building))
            set this.Workpower = 0.00
            loop
                exitwhen IntLoop1 > udg_MaxWorkerTypes
                set this.WorkerCounts[IntLoop1] = 0
                set IntLoop1 = IntLoop1 + 1
            endloop
            set this.EnoughWorker = false
        endmethod
       
        public method IsWorker takes unit Person returns boolean
            return (libUnitDat_GetSystemNumber(libUnitDat_GetObjectNumber(Person, false), udg_SystemSlot) == libUnitDat_GetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot))
        endmethod
       
        public method CheckWorkerCount takes nothing returns nothing
            local integer BuildingID = GetUnitTypeId(libUnitDat_GetUnit(this.BuildingObjectNumber))
            local boolean EnoughWorkerOld = this.EnoughWorker
            local group GroupTemp1
            local unit UnitTemp1
            local integer IntLoop1 = 1
            set this.EnoughWorker = true
            loop
                exitwhen IntLoop1 > udg_MaxWorkerTypes
                if (this.EnoughWorker and this.WorkerCounts[IntLoop1] < GetNeededWorkers(BuildingID, IntLoop1, true)) then
                    set this.EnoughWorker = false
                    exitwhen true
                endif
                set IntLoop1 = IntLoop1 + 1
            endloop
            if (EnoughWorkerOld == false and this.EnoughWorker) then
                set GroupTemp1 = libUnitDat_GetGroup(this.WorkersClusterNumber)
                loop
                    set UnitTemp1 = FirstOfGroup(GroupTemp1)
                    exitwhen UnitTemp1 == null
                    call GroupRemoveUnit(GroupTemp1, UnitTemp1)
                    call SetUnitAnimation(UnitTemp1, "work")
                endloop
                call DestroyGroup(GroupTemp1)
            elseif (EnoughWorkerOld and this.EnoughWorker == false) then
                set GroupTemp1 = libUnitDat_GetGroup(this.WorkersClusterNumber)
                loop
                    set UnitTemp1 = FirstOfGroup(GroupTemp1)
                    exitwhen UnitTemp1 == null
                    call GroupRemoveUnit(GroupTemp1, UnitTemp1)
                    call SetUnitAnimation(UnitTemp1, "stand")
                endloop
                call DestroyGroup(GroupTemp1)
            endif
            //Anti-Memory-Leak:
            set GroupTemp1 = null
            set UnitTemp1 = null
        endmethod
       
        public method AddWorker takes unit Person returns nothing
            local integer PersonObjectNumber
            local integer PersonID = GetUnitTypeId(Person)
            local integer IntLoop1 = 1
            loop
                exitwhen IntLoop1 > udg_MaxWorkerTypes
                exitwhen WorkerSlot2UnitID(IntLoop1) == PersonID
                set IntLoop1 = IntLoop1 + 1
            endloop
            if (IntLoop1 > udg_MaxWorkerTypes) then
                call DisplayTextToPlayer(GetOwningPlayer(Person), 0, 0, "This builder can't work at this type of building.")
            elseif (this.WorkerCounts[IntLoop1] >= GetNeededWorkers(GetUnitTypeId(libUnitDat_GetUnit(this.BuildingObjectNumber)), IntLoop1, false)) then
                call DisplayTextToPlayer(GetOwningPlayer(Person), 0, 0, "The worker limit for this building site has already been reached.")
            else
                set this.WorkerCounts[IntLoop1] = this.WorkerCounts[IntLoop1] + 1
                set PersonObjectNumber = libUnitDat_SetSystemNumberOfUnit(Person, udg_SystemSlot, libUnitDat_GetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot))
                call libUnitDat_ClusterChangeObject(this.WorkersClusterNumber, PersonObjectNumber, true)
                set this.Workpower = this.Workpower + GetWorkPower(PersonID)
                call libDum_CastOnTarget(libId_udg_AddConstructionBuff, 1, "innerfire", Person, Player(PLAYER_NEUTRAL_PASSIVE))
                if (this.EnoughWorker == false) then
                    call TriggerSleepAction(0.01)
                    call this.CheckWorkerCount()
                else
                    call TriggerSleepAction(0.01)
                    call SetUnitAnimation(Person, "work")
                endif
            endif
        endmethod
       
        public method RemoveWorker takes unit Person returns nothing
            local integer PersonObjectNumber
            local integer PersonID = GetUnitTypeId(Person)
            local integer IntLoop1 = 1
            loop
                exitwhen IntLoop1 > udg_MaxWorkerTypes
                exitwhen WorkerSlot2UnitID(IntLoop1) == PersonID
                set IntLoop1 = IntLoop1 + 1
            endloop
            if (IntLoop1 > udg_MaxWorkerTypes or this.WorkerCounts[IntLoop1] <= 0) then
                call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Can't remove more builders of this type")
                return
            else
                set this.WorkerCounts[IntLoop1] = this.WorkerCounts[IntLoop1] - 1
                set PersonObjectNumber = libUnitDat_SetSystemNumberOfUnit(Person, udg_SystemSlot, 0)
                call libUnitDat_ClusterChangeObject(this.WorkersClusterNumber, PersonObjectNumber, false)
                call SetUnitAnimation(Person, "stand")
                set this.Workpower = this.Workpower - GetWorkPower(PersonID)
                call UnitRemoveAbility(Person, libId_udg_ConstructingBuff)
                if (this.EnoughWorker) then
                    call this.CheckWorkerCount()
                endif
            endif
        endmethod
       
        public method ReduceBuildingTime takes nothing returns nothing
            local unit Building = libUnitDat_GetUnit(this.BuildingObjectNumber)
            local integer BuildingID
            local integer IntTemp1
            if (this.Progress > 0.00) then
                set BuildingID = GetUnitTypeId(Building)
                if (this.EnoughWorker) then
                    set this.Progress = this.Progress - this.Workpower * udg_BuildingRate
                endif
                set IntTemp1 = R2I(100.00 - 100.00 * this.Progress / (GetBuildingValue(BuildingID) + udg_AntiSingularityAddition))
                if (IntTemp1 >= 100 and this.Progress > 0.00) then
                    set IntTemp1 = 99
                elseif (IntTemp1 <= 0) then
                    set IntTemp1 = 1
                endif
                call UnitSetUpgradeProgress(Building, IntTemp1)
            elseif (this.Progress == 0.00) then
                call UnitSetUpgradeProgress(Building, 1)
            endif
            //Anit-Memory-Leak:
            set Building = null
        endmethod
       
        public method AdjustSystemNumber takes integer NewSystemNumber returns nothing
            call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, NewSystemNumber)
            call libUnitDat_SetClusterSystemNumbers(this.WorkersClusterNumber, udg_SystemSlot, NewSystemNumber)
        endmethod
    endstruct
   
    globals
        private BuildingSite array udg_BuildingSites [udg_MaxBuildingSitesP]
        private integer udg_CountBuildingSites = 0
        private constant trigger gg_trg_AdjustBuildingTime = CreateTrigger()
        private constant trigger gg_trg_TurnBuilding = CreateTrigger()
        private constant trigger gg_trg_RemoveBuilding = CreateTrigger()
        private constant trigger gg_trg_StartBuilding = CreateTrigger()
        private constant trigger gg_trg_FinishBuilding = CreateTrigger()
        private constant trigger gg_trg_AbortBuilding = CreateTrigger()
        private constant trigger gg_trg_BuildingDies = CreateTrigger()
        private constant trigger gg_trg_DuplicateBuildingSite = CreateTrigger()
        private constant trigger gg_trg_SmartOrderOnBuildingSite = CreateTrigger()
        private constant trigger gg_trg_LeaveBuildingSite = CreateTrigger()
        private constant trigger gg_trg_Construct = CreateTrigger()
    endglobals
   
    //-------------
    //PRIVATE PART:
    //-------------
   
    private function GetAdjustedAngle takes real Input returns real
        local real MaxResidual = 0.001
        if (0.00 - Input <= MaxResidual and 0.00 - Input >= (-1) * MaxResidual) then
            return 0.00
        elseif (90.00 - Input <= MaxResidual and 90.00 - Input >= (-1) * MaxResidual) then
            return 90.00
        elseif (180.00 - Input <= MaxResidual and 180.00 - Input >= (-1) * MaxResidual) then
            return 180.00
        elseif (270.00 - Input <= MaxResidual and 270.00 - Input >= (-1) * MaxResidual) then
            return 270.00
        elseif (360.00 - Input <= MaxResidual and 360.00 - Input >= (-1) * MaxResidual) then
            return 0.00
        endif
        return Input
    endfunction
   
    private function FindBuildingSitesForWorkers_Filter1 takes nothing returns boolean
        return (GetBuildingValue(GetUnitTypeId(GetFilterUnit())) != 0.00 and libUnitDat_GetSystemNumberOfUnit(GetFilterUnit(), udg_SystemSlot) > 0)
    endfunction
    private function FindBuildingSitesForWorkers takes group Workers, real PosX, real PosY returns nothing
        local player Owner = GetOwningPlayer(FirstOfGroup(Workers))
        local unit array StackBuildings
        local real array StackDistances
        local integer StackSize = 0
        local group array WorkerGroups
        local boolexpr Filter1 = Condition(function FindBuildingSitesForWorkers_Filter1)
        local group GroupTemp1 = CreateGroup()
        local unit UnitTemp1
        local real RealTemp1
        local real RealTemp2
        local integer IntTemp1
        local integer IntTemp2
        local integer IntTemp3
        local integer IntLoop1
        local integer IntLoop2
        //Sort nearby building sites after the their distance:
        call GroupEnumUnitsInRange(GroupTemp1, PosX, PosY, udg_MaxAutoBuildRange, Filter1)
        loop
            set UnitTemp1 = FirstOfGroup(GroupTemp1)
            exitwhen UnitTemp1 == null
            call GroupRemoveUnit(GroupTemp1, UnitTemp1)
            if (Owner == GetOwningPlayer(UnitTemp1)) then
                set RealTemp1 = GetUnitX(UnitTemp1) - PosX
                set RealTemp2 = GetUnitY(UnitTemp1) - PosY
                set RealTemp1 = SquareRoot(RealTemp1 * RealTemp1 + RealTemp2 * RealTemp2)
                set IntLoop1 = StackSize
                set StackSize = StackSize + 1
                loop
                    exitwhen IntLoop1 <= 0
                    exitwhen StackDistances[IntLoop1] <= RealTemp1
                    set StackBuildings[IntLoop1 + 1] = StackBuildings[IntLoop1]
                    set StackDistances[IntLoop1 + 1] = StackDistances[IntLoop1]
                    set IntLoop1 = IntLoop1 - 1
                endloop
                set StackBuildings[IntLoop1 + 1] = UnitTemp1
                set StackDistances[IntLoop1 + 1] = RealTemp1
            endif
        endloop
        call DestroyGroup(GroupTemp1)
        //Sort workers after their worker type slot:
        set IntLoop1 = 1
        set WorkerGroups[IntLoop1] = Workers
        loop
            exitwhen IntLoop1 > udg_MaxWorkerTypes
            set GroupTemp1 = WorkerGroups[IntLoop1]
            set WorkerGroups[IntLoop1] = CreateGroup()
            if (IntLoop1 + 1 <= udg_MaxWorkerTypes) then
                set WorkerGroups[IntLoop1 + 1] = CreateGroup()
            endif
            set IntTemp1 = WorkerSlot2UnitID(IntLoop1)
            loop
                set UnitTemp1 = FirstOfGroup(GroupTemp1)
                exitwhen UnitTemp1 == null
                call GroupRemoveUnit(GroupTemp1, UnitTemp1)
                if (GetUnitTypeId(UnitTemp1) == IntTemp1) then
                    call GroupAddUnit(WorkerGroups[IntLoop1], UnitTemp1)
                elseif (IntLoop1 + 1 <= udg_MaxWorkerTypes) then
                    call GroupAddUnit(WorkerGroups[IntLoop1 + 1], UnitTemp1)
                endif
            endloop
            call DestroyGroup(GroupTemp1)
            set IntLoop1 = IntLoop1 + 1
        endloop
        //Distribute workers to building sites:
        set IntLoop1 = 1
        loop
            exitwhen IntLoop1 > StackSize
            set IntTemp1 = libUnitDat_GetSystemNumberOfUnit(StackBuildings[IntLoop1], udg_SystemSlot)
            set IntTemp2 = GetUnitTypeId(StackBuildings[IntLoop1])
            set IntTemp3 = -1
            set IntLoop2 = 1
            loop
                exitwhen IntLoop2 > udg_MaxWorkerTypes
                if (WorkerGroups[IntLoop2] != null) then
                    set IntTemp3 = GetNeededWorkers(IntTemp2, IntLoop2, false)
                    if (IntTemp3 > 0) then
                        set IntTemp3 = IntTemp3 - udg_BuildingSites[IntTemp1].GetWorkerCounts(IntLoop2)
                        loop
                            exitwhen IntTemp3 <= 0
                            set UnitTemp1 = FirstOfGroup(WorkerGroups[IntLoop2])
                            if (UnitTemp1 == null) then
                                call DestroyGroup(WorkerGroups[IntLoop2])
                                set WorkerGroups[IntLoop2] = null
                                exitwhen true
                            endif
                            call GroupRemoveUnit(WorkerGroups[IntLoop2], UnitTemp1)
                            call IssueTargetOrder(UnitTemp1, "thunderbolt", StackBuildings[IntLoop1])
                            set IntTemp3 = IntTemp3 - 1
                        endloop
                    endif
                endif
                set IntLoop2 = IntLoop2 + 1
            endloop
            set StackBuildings[IntLoop1] = null
            set IntLoop1 = IntLoop1 + 1
            exitwhen IntTemp3 == -1
        endloop
        //Anti-Memory-Leak:
        if (IntLoop1 > StackSize) then
            set IntLoop1 = 1
            loop
                exitwhen IntLoop1 > udg_MaxWorkerTypes
                if (WorkerGroups[IntLoop1] != null) then
                    call DestroyGroup(WorkerGroups[IntLoop1])
                    set WorkerGroups[IntLoop1] = null
                endif
                set IntLoop1 = IntLoop1 + 1
            endloop
        else
            loop
                exitwhen IntLoop1 > StackSize
                set StackBuildings[IntLoop1] = null
                set IntLoop1 = IntLoop1 + 1
            endloop
        endif
        set GroupTemp1 = null
        call DestroyBoolExpr(Filter1)
        set Filter1 = null
        set UnitTemp1 = null
    endfunction

    //------------
    //PUBLIC PART:
    //------------
   
    public function GetBuildingSiteNumber takes unit Building returns integer
        return (libUnitDat_GetSystemNumberOfUnit(Building, udg_SystemSlot))
    endfunction

    public function GetBuildingSiteInfo takes integer BuildingSiteNumber, integer InfoNumber, integer SubNumber returns integer
        local integer ReturnValue = 0
        local real RealTemp1 = 0.00
        local real RealTemp2
        local integer IntTemp1
        local integer IntTemp2
        local integer IntLoop1 = 1
        if (InfoNumber == 1) then //Left building time
            set RealTemp2 = udg_BuildingSites[BuildingSiteNumber].GetProgress()
            if (RealTemp2 == 0.00) then
                set ReturnValue = -2000
            elseif (RealTemp2 < 0.00) then
                set ReturnValue = R2I(RealTemp2)
            else
                set IntTemp1 = GetUnitTypeId(udg_BuildingSites[BuildingSiteNumber].GetBuilding())
                loop
                    exitwhen IntLoop1 > udg_MaxWorkerTypes
                    set IntTemp2 = udg_BuildingSites[BuildingSiteNumber].GetWorkerCounts(IntLoop1)
                    if (IntTemp2 < GetNeededWorkers(IntTemp1, IntLoop1, true)) then
                        set ReturnValue = -1000
                        exitwhen true
                    endif
                    set RealTemp1 = RealTemp1 + IntTemp2 * GetWorkPower(WorkerSlot2UnitID(IntLoop1))
                    set IntLoop1 = IntLoop1 + 1
                endloop
                if (ReturnValue == 0) then
                    set ReturnValue = R2I(RealTemp2 / (RealTemp1 + udg_AntiSingularityAddition))
                endif
            endif
        elseif (InfoNumber == 2) then //Employed worker ID of type number
            if (SubNumber > udg_MaxWorkerTypes) then
                set ReturnValue = -1
            else
                set ReturnValue = WorkerSlot2UnitID(SubNumber)
            endif
        elseif (InfoNumber == 3) then //Employed worker count of type number
            set ReturnValue = udg_BuildingSites[BuildingSiteNumber].GetWorkerCounts(SubNumber)
        elseif (InfoNumber == 4) then //Minimal required worker count of type number
            set ReturnValue = GetNeededWorkers(GetUnitTypeId(udg_BuildingSites[BuildingSiteNumber].GetBuilding()), SubNumber, true)
        elseif (InfoNumber == 5) then //Maximal allowed worker count of type number
            set ReturnValue = GetNeededWorkers(GetUnitTypeId(udg_BuildingSites[BuildingSiteNumber].GetBuilding()), SubNumber, false)
        endif
        return ReturnValue
    endfunction

    public function GetWorkerGroup takes integer BuildingSiteNumber returns group
        return udg_BuildingSites[BuildingSiteNumber].GetWorkers()
    endfunction
   
    //---------------------
    //EVENT-TRIGGERED PART:
    //---------------------
   
    private function TurnBuilding_Conditions takes nothing returns boolean
        return (GetSpellAbilityId() == libId_udg_TurnBuilding)
    endfunction
    private function TurnBuilding takes nothing returns nothing
        local group GroupTemp1 = CreateGroup()
        local unit UnitTemp1 = GetSpellAbilityUnit()
        local unit UnitTemp2
        local real RealTemp1
        call SyncSelections()
        call GroupEnumUnitsSelected(GroupTemp1, GetOwningPlayer(UnitTemp1), null)
        loop
            set UnitTemp1 = FirstOfGroup(GroupTemp1)
            exitwhen UnitTemp1 == null
            call GroupRemoveUnit(GroupTemp1, UnitTemp1)
            if (GetUnitAbilityLevel(UnitTemp1, libId_udg_TurnBuilding) != 0) then
                set RealTemp1 = GetAdjustedAngle(GetUnitFacing(UnitTemp1)) + 90.00
                if (RealTemp1 >= 360.00) then
                    set RealTemp1 = RealTemp1 - 360.00
                endif
                call ShowUnit(UnitTemp1, false)
                set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), GetUnitTypeId(UnitTemp1), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), RealTemp1)
                call libUnitDat_ChangeUnit(UnitTemp1, UnitTemp2)
                call RemoveUnit(UnitTemp1)
                if (RealTemp1 == 90.00) then
                    call UnitRemoveAbility(UnitTemp2, libId_udg_BuildingFacingDown)
                    call UnitAddAbility(UnitTemp2, libId_udg_BuildingFacingUp)
                elseif (RealTemp1 == 180.00) then
                    call UnitRemoveAbility(UnitTemp2, libId_udg_BuildingFacingDown)
                    call UnitAddAbility(UnitTemp2, libId_udg_BuildingFacingLeft)
                elseif (RealTemp1 == 0.00) then
                    call UnitRemoveAbility(UnitTemp2, libId_udg_BuildingFacingDown)
                    call UnitAddAbility(UnitTemp2, libId_udg_BuildingFacingRight)
                endif
                call libWal_AdjustReplacedBuilding(UnitTemp2)
                if (GetLocalPlayer() == GetOwningPlayer(UnitTemp2)) then
                    // Use only local code (no net traffic) within this block to avoid desyncs.
                    call SelectUnit(UnitTemp2, true)
                endif
            endif
        endloop
        //Anti-Memory-Leak:
        call DestroyGroup(GroupTemp1)
         set GroupTemp1 = null
        set UnitTemp1 = null
        set UnitTemp2 = null
    endfunction
   
    private function RemoveBuilding_Conditions takes nothing returns boolean
        return (GetSpellAbilityId() == libId_udg_RemoveBuilding)
    endfunction
    private function RemoveBuilding takes nothing returns nothing
        local unit UnitTemp1 = GetSpellAbilityUnit()
        call KillUnit(UnitTemp1)
        call ShowUnit(UnitTemp1, false)
        call TriggerSleepAction(1.00)
        call RemoveUnit(UnitTemp1)
        //Anti-Memory-Leak:
        set UnitTemp1 = null
    endfunction
   
    private function StartBuilding_Conditions takes nothing returns boolean
        local unit UnitTemp1 = GetTriggerUnit()
        local integer IntTemp1 = 1
        if (GetBuildingValue(GetUnitTypeId(UnitTemp1)) != 0.00) then
            set IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
        endif
        //Anti-Memory-Leak:
        set UnitTemp1 = null
        //-----------------
        return (IntTemp1 == 0)
    endfunction
    private function StartBuilding takes nothing returns nothing
        local unit UnitTemp1 = GetTriggerUnit()
        local real RealTemp1
        local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
        set udg_CountBuildingSites = udg_CountBuildingSites + 1
        set udg_BuildingSites[udg_CountBuildingSites] = BuildingSite.create()
        if (udg_BuildingSites[udg_CountBuildingSites] == 0) then
            call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: BuildingSite struct cap exceeded")
            return
        endif
        call udg_BuildingSites[udg_CountBuildingSites].New(UnitTemp1, udg_CountBuildingSites)
        set RealTemp1 = GetBuildingSize(IntTemp1)
        call SetUnitScale(UnitTemp1, RealTemp1, RealTemp1, RealTemp1)
        if (libWal_AdjustConstructingFortification(UnitTemp1)) then
            set UnitTemp1 = udg_BuildingSites[udg_CountBuildingSites].GetBuilding()
            call ShowUnit(UnitTemp1, false)
            set IntTemp1 = GetUnitTypeId(UnitTemp1)
            call libUnitDat_ChangeUnit(UnitTemp1, CreateUnit(GetOwningPlayer(UnitTemp1), GetBuildingSiteID(IntTemp1), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1)))
            call RemoveUnit(UnitTemp1)
            set UnitTemp1 = udg_BuildingSites[udg_CountBuildingSites].GetBuilding()
            call IssueImmediateOrderById(UnitTemp1, IntTemp1)
            set RealTemp1 = GetBuildingSize(IntTemp1)
            call SetUnitScale(UnitTemp1, RealTemp1, RealTemp1, RealTemp1)
        endif
        call libWal_AddBuildingUnderConstruction(UnitTemp1)
        if (GetLocalPlayer() == GetOwningPlayer(UnitTemp1)) then
            // Use only local code (no net traffic) within this block to avoid desyncs.
            call SelectUnit(UnitTemp1, true)
        endif
        //Anti-Memory-Leak:
        set UnitTemp1 = null
    endfunction
   
    private function FinishBuilding_Conditions takes nothing returns boolean
        return (GetBuildingValue(GetUnitTypeId(GetTriggerUnit())) != 0.00)
    endfunction
    private function FinishBuilding takes nothing returns nothing
        local unit UnitTemp1 = GetTriggerUnit()
        local group GroupTemp1
        local integer IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
        if (IntTemp1 <= udg_CountBuildingSites and IntTemp1 > 0) then
            set GroupTemp1 = udg_BuildingSites[IntTemp1].GetWorkers()
            call udg_BuildingSites[IntTemp1].remove()
            if (udg_CountBuildingSites != IntTemp1) then
                set udg_BuildingSites[IntTemp1] = udg_BuildingSites[udg_CountBuildingSites]
                call udg_BuildingSites[IntTemp1].AdjustSystemNumber(IntTemp1)
            endif
            set udg_BuildingSites[udg_CountBuildingSites] = 0
            set udg_CountBuildingSites = udg_CountBuildingSites - 1
            call FindBuildingSitesForWorkers(GroupTemp1, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1))
        endif
        //Anti-Memory-Leak:
        set UnitTemp1 = null
        set GroupTemp1 = null
    endfunction
   
    private function AbortBuilding_Conditions takes nothing returns boolean
        return (GetBuildingSiteNumber(GetTriggerUnit()) > 0)
    endfunction
    private function AbortBuilding takes nothing returns nothing
        local unit UnitTemp1 = GetTriggerUnit()
        local integer IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
        if (IntTemp1 <= udg_CountBuildingSites) then
            call udg_BuildingSites[IntTemp1].remove()
            if (udg_CountBuildingSites != IntTemp1) then
                set udg_BuildingSites[IntTemp1] = udg_BuildingSites[udg_CountBuildingSites]
                call udg_BuildingSites[IntTemp1].AdjustSystemNumber(IntTemp1)
            endif
            set udg_BuildingSites[udg_CountBuildingSites] = 0
            set udg_CountBuildingSites = udg_CountBuildingSites - 1
            if (GetUnitAbilityLevel(UnitTemp1, libId_udg_RemoveBuilding) > 0) then
                call libWal_RemoveBuildingUnderConstruction(UnitTemp1)
                call libUnitDat_RemoveObjectUnit(UnitTemp1)
            endif
        endif
        //Anti-Memory-Leak:
        set UnitTemp1 = null
    endfunction
   
    private function BuildingDies_Conditions takes nothing returns boolean
        local unit UnitTemp1 = GetDyingUnit()
        local integer IntTemp1 = 0
        if (GetBuildingValue(GetUnitTypeId(UnitTemp1)) != 0.00) then
            set IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
        endif
        //Anti-Memory-Leak:
        set UnitTemp1 = null
        //-----------------
        return (IntTemp1 != 0)
    endfunction
    private function BuildingDies takes nothing returns nothing
        local unit UnitTemp1 = GetDyingUnit()
        local integer IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
        if (IntTemp1 <= udg_CountBuildingSites) then
            call udg_BuildingSites[IntTemp1].remove()
            if (udg_CountBuildingSites != IntTemp1) then
                set udg_BuildingSites[IntTemp1] = udg_BuildingSites[udg_CountBuildingSites]
                call udg_BuildingSites[IntTemp1].AdjustSystemNumber(IntTemp1)
            endif
            set udg_BuildingSites[udg_CountBuildingSites] = 0
            set udg_CountBuildingSites = udg_CountBuildingSites - 1
        endif
        //Anti-Memory-Leak:
        set UnitTemp1 = null
    endfunction
   
    private function AdjustBuildingTime takes nothing returns nothing
        local integer IntLoop1 = 1
        loop
            exitwhen IntLoop1 > udg_CountBuildingSites
            call udg_BuildingSites[IntLoop1].ReduceBuildingTime()
            set IntLoop1 = IntLoop1 + 1
        endloop
    endfunction

    private function Construct_Conditions takes nothing returns boolean
        return (GetSpellAbilityId() == libId_udg_Construct)
    endfunction
    private function Construct takes nothing returns nothing
        local unit Worker = GetSpellAbilityUnit()
        local unit Building = GetSpellTargetUnit()
        local integer BuildingSiteNumber = GetBuildingSiteNumber(Building)
        if (BuildingSiteNumber > 0) then
            call TriggerSleepAction(0.01)
            call udg_BuildingSites[BuildingSiteNumber].AddWorker(Worker)
        endif
        //Anti-Memory-Leak:
        set Worker = null
        set Building = null
    endfunction
   
    private function LeaveBuildingSite_Conditions takes nothing returns boolean
        return (GetWorkPower(GetUnitTypeId(GetTriggerUnit())) > 0.00)
    endfunction
    private function LeaveBuildingSite takes nothing returns nothing
        local unit Worker = GetTriggerUnit()
        local integer BuildingSiteNumber = GetBuildingSiteNumber(Worker)
        if (BuildingSiteNumber > 0) then
            call udg_BuildingSites[BuildingSiteNumber].RemoveWorker(Worker)
        endif
        //Anti-Memory-Leak:
        set Worker = null
    endfunction

    private function DuplicateBuildingSite_Conditions takes nothing returns boolean
        return (GetSpellAbilityId() == libId_udg_Duplicate)
    endfunction
    private function DuplicateBuildingSite takes nothing returns nothing
        local unit Building = GetSpellAbilityUnit()
        local unit Duplicate
        local integer BuildingID = GetUnitTypeId(Building)
        local real Facing = GetAdjustedAngle(GetUnitFacing(Building))
        local real PosX = GetUnitX(Building)
        local real PosY = GetUnitY(Building)
        if (Facing == 0.00) then
            set PosY = PosY - GetBuildingSiteSquareSize(BuildingID)
        elseif (Facing == 90.00) then
            set PosX = PosX + GetBuildingSiteSquareSize(BuildingID)
        elseif (Facing == 180.00) then
            set PosY = PosY + GetBuildingSiteSquareSize(BuildingID)
        elseif (Facing == 270.00) then
            set PosX = PosX - GetBuildingSiteSquareSize(BuildingID)
        endif
        if (GetRectMinX(bj_mapInitialPlayableArea) <= PosX and PosX <= GetRectMaxX(bj_mapInitialPlayableArea) and GetRectMinY(bj_mapInitialPlayableArea) <= PosY and PosY <= GetRectMaxY(bj_mapInitialPlayableArea) and IsVisibleToPlayer(PosX, PosY, GetOwningPlayer(Building))) then
            set Duplicate = CreateUnit(GetOwningPlayer(Building), BuildingID, PosX, PosY, Facing)
            if (Facing == 90.00) then
                call UnitRemoveAbility(Duplicate, libId_udg_BuildingFacingDown)
                call UnitAddAbility(Duplicate, libId_udg_BuildingFacingUp)
            elseif (Facing == 180.00) then
                call UnitRemoveAbility(Duplicate, libId_udg_BuildingFacingDown)
                call UnitAddAbility(Duplicate, libId_udg_BuildingFacingLeft)
            elseif (Facing == 0.00) then
                call UnitRemoveAbility(Duplicate, libId_udg_BuildingFacingDown)
                call UnitAddAbility(Duplicate, libId_udg_BuildingFacingRight)
            endif
            if (GetLocalPlayer() == GetOwningPlayer(Duplicate)) then
                // Use only local code (no net traffic) within this block to avoid desyncs.
                call ClearSelection()
                call SelectUnit(Duplicate, true)
            endif
        endif
        //Anti-Memory-Leak:
        set Building = null
        set Duplicate = null
    endfunction
   
    private function SmartOrderOnBuildingSite_Conditions takes nothing returns boolean
        return (OrderId2String(GetIssuedOrderId()) == "smart" and GetUnitState(GetOrderTargetUnit(), UNIT_STATE_LIFE) == GetUnitState(GetOrderTargetUnit(), UNIT_STATE_MAX_LIFE) and GetBuildingSiteNumber(GetOrderTargetUnit()) > 0 and GetWorkPower(GetUnitTypeId(GetOrderedUnit())) > 0.00)
    endfunction
    private function SmartOrderOnBuildingSite takes nothing returns nothing
        local unit Worker = GetOrderedUnit()
        local unit Building = GetOrderTargetUnit()
        call IssueTargetOrder(Worker, "thunderbolt", Building)
        //Anti-Memory-Leak:
        set Worker = null
        set Building = null
    endfunction

    //---------------
    //INITIALISATION:
    //---------------
   
    private function Init_BuildingSiteSystem takes nothing returns nothing
        local integer IntLoop1 = 1
        //Triggers:
        call TriggerRegisterTimerEvent(gg_trg_AdjustBuildingTime, udg_BuildingRate, true)
        loop
            exitwhen IntLoop1 > udg_CountPlayers
            call TriggerRegisterPlayerUnitEvent(gg_trg_TurnBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_RemoveBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_StartBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_START, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_FinishBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_FINISH, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_AbortBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_CANCEL, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_BuildingDies, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_DEATH, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_DuplicateBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_SmartOrderOnBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_UNIT_ORDER, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ATTACKED, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_Construct, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
            set IntLoop1 = IntLoop1 + 1
        endloop
        //Conditions:
        call TriggerAddCondition(gg_trg_TurnBuilding, Condition(function TurnBuilding_Conditions))
        call TriggerAddCondition(gg_trg_RemoveBuilding, Condition(function RemoveBuilding_Conditions))
        call TriggerAddCondition(gg_trg_StartBuilding, Condition(function StartBuilding_Conditions))
        call TriggerAddCondition(gg_trg_FinishBuilding, Condition(function FinishBuilding_Conditions))
        call TriggerAddCondition(gg_trg_AbortBuilding, Condition(function AbortBuilding_Conditions))
        call TriggerAddCondition(gg_trg_BuildingDies, Condition(function BuildingDies_Conditions))
        call TriggerAddCondition(gg_trg_DuplicateBuildingSite, Condition(function DuplicateBuildingSite_Conditions))
        call TriggerAddCondition(gg_trg_SmartOrderOnBuildingSite, Condition(function SmartOrderOnBuildingSite_Conditions))
        call TriggerAddCondition(gg_trg_LeaveBuildingSite, Condition(function LeaveBuildingSite_Conditions))
        call TriggerAddCondition(gg_trg_Construct, Condition(function Construct_Conditions))
        //Actions:
        call TriggerAddAction(gg_trg_AdjustBuildingTime, function AdjustBuildingTime)
        call TriggerAddAction(gg_trg_TurnBuilding, function TurnBuilding)
        call TriggerAddAction(gg_trg_RemoveBuilding, function RemoveBuilding)
        call TriggerAddAction(gg_trg_StartBuilding, function StartBuilding)
        call TriggerAddAction(gg_trg_FinishBuilding, function FinishBuilding)
        call TriggerAddAction(gg_trg_AbortBuilding, function AbortBuilding)
        call TriggerAddAction(gg_trg_BuildingDies, function BuildingDies)
        call TriggerAddAction(gg_trg_DuplicateBuildingSite, function DuplicateBuildingSite)
        call TriggerAddAction(gg_trg_SmartOrderOnBuildingSite, function SmartOrderOnBuildingSite)
        call TriggerAddAction(gg_trg_LeaveBuildingSite, function LeaveBuildingSite)
        call TriggerAddAction(gg_trg_Construct, function Construct)
    endfunction
endlibrary

Thanks, appreciate any help and advice.
 
Hello, I'm having trouble figuring out how to add more units to a function.
^Can you re-phrase "adding units to a function"? I'm having issues to understand.
Specifically, I want to add additional worker units to each worker slot - about 10 to #1, 4 to #2.
^I don't understand, this, too.

JASS:
//Returns the unit type of the given WorkerSlot:
    private function WorkerSlot2UnitID takes integer WorkerSlot returns integer
        if (WorkerSlot == 1) then
            return libId_udg_Worker //Worker
        elseif (WorkerSlot == 2) then
            return libId_udg_Architect //Architect
        endif
        return 0
    endfunction
^What does not work? And are you sure "libId_udg_Architect" is the correct name? It's a weird mix of globals and the udg_ prefix, which is/should be used only for GUI variables.
 
Level 11
Joined
Mar 31, 2016
Messages
657
^Can you re-phrase "adding units to a function"? I'm having issues to understand.

^I don't understand, this, too.

JASS:
//Returns the unit type of the given WorkerSlot:
    private function WorkerSlot2UnitID takes integer WorkerSlot returns integer
        if (WorkerSlot == 1) then
            return libId_udg_Worker //Worker
        elseif (WorkerSlot == 2) then
            return libId_udg_Architect //Architect
        endif
        return 0
    endfunction
^What does not work? And are you sure "libId_udg_Architect" is the correct name? It's a weird mix of globals and the udg_ prefix, which is/should be used only for GUI variables.


Not sure if I can phrase it any other way so I'll explain the trigger itself and then go into what I want to change.

The trigger used two different worker slots for an advanced construction system. Each worker slot is used by one specific type of worker via unit id - however I want to add more workers to each worker slot. I want to add 7 workers via unit id to worker slot #1, then I want to add 4 to #2.

Basically, when I try to add new workers via unit id, nothing happens or I get errors.
 
Status
Not open for further replies.
Top