• 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.

[vJASS] HELP: Missing Endblock Error

Status
Not open for further replies.
Level 11
Joined
Mar 31, 2016
Messages
657
I was editing a trigger for my map and encountered an error with jass helper - missing endblock?

Not sure how to diagnose the issue... Anybody know how to diagnose or go about fixing?

Here is the code I was editing as well as the original code.

Thanks, appreciate any help and advice.

EDITED VERSION
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_FirePit) then //Fire Pit
            return 20.00
        elseif (BuildingID == libId_udg_LightP1) then //Light Post (1)
            return 25.00
        elseif (BuildingID == libId_udg_LightP2) then //Light Post (2)
            return 25.00
        elseif (BuildingID == libId_udg_Banner1) then //Banner (1)
            return 10.00
        elseif (BuildingID == libId_udg_Banner2) then //Banner (2)
            return 15.00
        elseif (BuildingID == libId_udg_Statue1) then //Statue (1)
            return 50.00
        elseif (BuildingID == libId_udg_Statue2) then //Statue (2)
            return 50.00
        elseif (BuildingID == libId_udg_Well1) then //Well (1)
            return 25.00
        elseif (BuildingID == libId_udg_Well2) then //Well (2)
            return 20.00
        elseif (BuildingID == libId_udg_Well3) then //Well (3)
            return 30.00
        elseif (BuildingID == libId_udg_Fountain1) then //Fountain (1)
            return 40.00
        elseif (BuildingID == libId_udg_Fountain2) then //Fountain (2)
            return 50.00
        elseif (BuildingID == libId_udg_Stash1) then //Stash (1)
            return 20.00
        elseif (BuildingID == libId_udg_Stash2) then //Stash (2)
            return 30.00
        //Building Site - Misc:
        elseif (BuildingID == libId_udg_Barricade) then //Barricade
            return 10.00
        elseif (BuildingID == libId_udg_TrainD1) then //Training Dummy (1)
            return 15.00
        elseif (BuildingID == libId_udg_TrainD2) then //Training Dummy (2)
            return 20.00
        elseif (BuildingID == libId_udg_TrainD3) then //Training Dummy (3)
            return 30.00
        elseif (BuildingID == libId_udg_Target1) then //Archery Target (1)
            return 15.00
        elseif (BuildingID == libId_udg_Target2) then //Archery Target (2)
            return 20.00
        //Building Site - Small:
        elseif (BuildingID == libId_udg_House1) then //House (1)
            return 40.00
        elseif (BuildingID == libId_udg_House2) then //House (2)
            return 30.00
        elseif (BuildingID == libId_udg_House3) then //House (3)
            return 30.00
        elseif (BuildingID == libId_udg_House4) then //House (4)
            return 60.00
        elseif (BuildingID == libId_udg_Tent1) then //Tent (1)
            return 20.00
        elseif (BuildingID == libId_udg_Tent2) then //Tent (2)
            return 30.00
        elseif (BuildingID == libId_udg_Tent3) then //Tent (3)
            return 40.00
        elseif (BuildingID == libId_udg_Path1) then //Path (1)
            return 10.00
        elseif (BuildingID == libId_udg_Path2) then //Path (2)
            return 20.00
        elseif (BuildingID == libId_udg_Path3) then //Path (3)
            return 30.00
        //Building Site - Fortification:
        elseif (BuildingID == libId_udg_Tower1) then //Tower (1)
            return 70.00
        elseif (BuildingID == libId_udg_Tower2) then //Tower (2)
            return 60.00
        elseif (BuildingID == libId_udg_Tower3) then //Tower (3)
            return 80.00
        elseif (BuildingID == libId_udg_Tower4) then //Tower (4)
            return 80.00
        elseif (BuildingID == libId_udg_TowerB1) then //Bell Tower (1)
            return 75.00
        elseif (BuildingID == libId_udg_TowerB2) then //Bell Tower (2)
            return 90.00
        elseif (BuildingID == libId_udg_TowerR) then //TowerR
            return 125.00
        elseif (BuildingID == libId_udg_TowerRB) then //TowerRB
            return 25.00
        elseif (BuildingID == libId_udg_TowerBC) then //TowerRC
            return 25.00
        elseif (BuildingID == libId_udg_TowerS) then //TowerS
            return 125.00
        elseif (BuildingID == libId_udg_TowerSB) then //TowerSB
            return 25.00
        elseif (BuildingID == libId_udg_TowerSC) then //TowerSC
            return 25.00
        elseif (BuildingID == libId_udg_GateCl) then //Gate (Closed)
            return 100.00
        elseif (BuildingID == libId_udg_PalisadeGateCl) then //Palisade gate (Closed)
            return 50.00
        elseif (BuildingID == libId_udg_WallUn or BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallIEUn) then //Wall (all Undamaged)
            return 90.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 140.00
        elseif (BuildingID == libId_udg_BigGateCl) then //Big gate (Closed)
            return 150.00
        elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerIEUn) then //Big tower (all Undamaged)
            return 170.00
        elseif (BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (all Undamaged)
            return 200.00
        //Building Site - Wide:
        elseif (BuildingID == libId_udg_LongHall1) then //Long Hall (1)
            return 70.00
        elseif (BuildingID == libId_udg_LongHall2) then //Long Hall (2)
            return 100.00
        elseif (BuildingID == libId_udg_LongHall3) then //Long Hall (3)
            return 100.00
        elseif (BuildingID == libId_udg_LongHall4) then //Long Hall (4)
            return 150.00
        elseif (BuildingID == libId_udg_Manor1) then //Manor (1)
            return 125.00
        elseif (BuildingID == libId_udg_Manor2) then //Manor (2)
            return 100.00
        elseif (BuildingID == libId_udg_Manor3) then //Manor (3)
            return 150.00
        elseif (BuildingID == libId_udg_Tavern1) then //Tavern (1)
            return 140.00
        elseif (BuildingID == libId_udg_Tavern2) then //Tavern (2)
            return 110.00
        elseif (BuildingID == libId_udg_Tavern3) then //Tavern (3)
            return 175.00
        elseif (BuildingID == libId_udg_Barn1) then //Barn (1)
            return 90.00
        elseif (BuildingID == libId_udg_Barn2) then //Barn (2)
            return 100.00
        elseif (BuildingID == libId_udg_Barn3) then //Barn (3)
            return 140.00
        elseif (BuildingID == libId_udg_Forge1) then //Forge (1)
            return 60.00
        elseif (BuildingID == libId_udg_Forge2) then //Forge (2)
            return 80.00
        elseif (BuildingID == libId_udg_Forge3) then //Forge (3)
            return 100.00
        elseif (BuildingID == libId_udg_Forge4) then //Forge (4)
            return 125.00
        elseif (BuildingID == libId_udg_LumberMill1) then //Lumber Mill (1)
            return 50.00
        elseif (BuildingID == libId_udg_LumberMill2) then //Lumber Mill (2)
            return 70.00
        elseif (BuildingID == libId_udg_LumberMill3) then //Lumber Mill (3)
            return 90.00
        elseif (BuildingID == libId_udg_LumberMill4) then //Lumber Mill (4)
            return 125.00
        elseif (BuildingID == libId_udg_StoneMill1) then //Stone Mill (1)
            return 50.00
        elseif (BuildingID == libId_udg_StoneMill2) then //Stone Mill (2)
            return 70.00
        elseif (BuildingID == libId_udg_StoneMill3) then //Stone Mill (3)
            return 90.00
        elseif (BuildingID == libId_udg_StoneMill4) then //Stone Mill (4)
            return 125.00
        //Building Site - Medium:
        elseif (BuildingID == libId_udg_GreatHall1) then //Great Hall (1)
            return 175.00
        elseif (BuildingID == libId_udg_GreatHall2) then //Great Hall (2)
            return 150.00
        elseif (BuildingID == libId_udg_GreatHall3) then //Great Hall (3)
            return 250.00
        elseif (BuildingID == libId_udg_University1) then //University (1)
            return 200.00
        elseif (BuildingID == libId_udg_University2) then //University (2)
            return 75.00
        elseif (BuildingID == libId_udg_Warehouse1) then //Warehouse (1)
            return 125.00
        elseif (BuildingID == libId_udg_Warehouse2) then //Warehouse (2)
            return 100.00
        elseif (BuildingID == libId_udg_Warehouse3) then //Warehouse (3)
            return 160.00
        elseif (BuildingID == libId_udg_WaterMill1) then //Water Mill (1)
            return 175.00
        elseif (BuildingID == libId_udg_WaterMill2) then //Water Mill (2)
            return 100.00
        elseif (BuildingID == libId_udg_WaterMill3) then //Water Mill (3)
            return 150.00
        elseif (BuildingID == libId_udg_Altar1) then //Altar (1)
            return 75.00
        elseif (BuildingID == libId_udg_Altar2) then //Altar (2)
            return 125.00
        elseif (BuildingID == libId_udg_TrainG1) then //Training Grounds (1)
            return 60.00
        elseif (BuildingID == libId_udg_TrainG2) then //Training Grounds (2)
            return 40.00
        //Building Site - Large:
        elseif (BuildingID == libId_udg_Barracks1) then //Barracks (1)
            return 150.00
        elseif (BuildingID == libId_udg_Barracks2) then //Barracks (2)
            return 100.00
        elseif (BuildingID == libId_udg_Barracks3) then //Barracks (3)
            return 175.00
        elseif (BuildingID == libId_udg_Barracks4) then //Barracks (4)
            return 200.00
        elseif (BuildingID == libId_udg_ArcheryR1) then //Archery Range (1)
            return 150.00
        elseif (BuildingID == libId_udg_ArcheryR2) then //Archery Range (2)
            return 125.00
        elseif (BuildingID == libId_udg_ArcheryR3) then //Archery Range (3)
            return 200.00
        elseif (BuildingID == libId_udg_Stables1) then //Stables (1)
            return 125.00
        elseif (BuildingID == libId_udg_Stables2) then //Stables (2)
            return 100.00
        elseif (BuildingID == libId_udg_Stables3) then //Stables (3)
            return 150.00
        elseif (BuildingID == libId_udg_Workshop1) then //Workshop (1)
            return 175.00
        elseif (BuildingID == libId_udg_Workshop2) then //Workshop (2)
            return 150.00
        elseif (BuildingID == libId_udg_Workshop3) then //Workshop (3)
            return 200.00
        elseif (BuildingID == libId_udg_Docks1) then //Docks (1)
            return 150.00
        elseif (BuildingID == libId_udg_Docks2) then //Docks (2)
            return 125.00
        elseif (BuildingID == libId_udg_Docks3) then //Docks (3)
            return 200.00
        elseif (BuildingID == libId_udg_VillageSquare) then //Village Square
            return 75.00
        //Building Site - Huge:
        elseif (BuildingID == libId_udg_Stronghold) then //Stronghold
            return 500.00
        elseif (BuildingID == libId_udg_Cathedral1) then //Cathedral (1)
            return 175.00
        elseif (BuildingID == libId_udg_Cathedral2) then //Cathedral (2)
            return 225.00
        elseif (BuildingID == libId_udg_Cathedral3) then //Cathedral (3)
            return 250.00       
        elseif (BuildingID == libId_udg_Market1) then //Market (1)
            return 100.00
        elseif (BuildingID == libId_udg_Market2) then //Market (2)
            return 90.00
        elseif (BuildingID == libId_udg_Market3) then //Market (3)
            return 110.00
        elseif (BuildingID == libId_udg_Market4) then //Market (4)
            return 140.00
        //Building site (special):
        elseif (BuildingID == libId_udg_Stairs) then //Stairs
            return 50.00
        elseif (BuildingID == libId_udg_LadderWall) then //Ladder (Wall)
            return 10.00
        elseif (BuildingID == libId_udg_LadderPalisade) then //Ladder (Palisade)
            return 10.00
        elseif (BuildingID == libId_udg_WallDa or BuildingID == libId_udg_WallOEDa or BuildingID == libId_udg_WallIEDa) then //Wall (all Damaged)
            return 40.00
        elseif (BuildingID == libId_udg_WallDe or BuildingID == libId_udg_WallOEDe or BuildingID == libId_udg_WallIEDe) then //Wall (all Destroyed)
            return 70.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 15.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 50.00
        elseif (BuildingID == libId_udg_PalisadeGateDa) then //Palisade gate (Damaged)
            return 30.00
        elseif (BuildingID == libId_udg_BigGateDa) then //Big gate (Damaged)
            return 70.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 90.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 150.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
        //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.25
        elseif (BuildingID == libId_udg_Barracks2) then //Barracks (2)
            return 2.25
        elseif (BuildingID == libId_udg_Barracks3) then //Barracks (3)
            return 2.25
        elseif (BuildingID == libId_udg_Barracks4) then //Barracks (4)
            return 2.25
        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 - Misc:
        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_TrainD1 or BuildingID == libId_udg_TrainD2 or BuildingID == libId_udg_TrainD3) then //Training Dummy (1,2,3)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 4
                endif
            endif  
        elseif (BuildingID == libId_udg_Target1 or BuildingID == libId_udg_Target2) then //Archery Target (1,2)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 4
                endif
            endif
        //Building Site - Tiny:
        elseif (BuildingID == libId_udg_FirePit) then //Fire Pit
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_LightP1 or BuildingID == libId_udg_LightP2) then //Light Post (1,2)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_Banner1 or BuildingID == libId_udg_Banner2) then //Banner (1,2)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_Statue1 or BuildingID == libId_udg_Statue2) then //Statue (1,2)
            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
        elseif (BuildingID == libId_udg_Well1 or BuildingID == libId_udg_Well2 or BuildingID == libId_udg_Well3) then //Well (1,2,3)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_Fountain1 or BuildingID == libId_udg_Fountain2) then //Fountain (1,2)
            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_Stash1 or BuildingID == libId_udg_Stash2) then //Stash (1,2)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 4
                endif
            endif
       //Building Site - Small:
          elseif (BuildingID == libId_udg_House1 or BuildingID == libId_udg_House2 or BuildingID == libId_udg_House3 or BuildingID == libId_udg_House4) then //House (1,2,3,4)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 6
                endif
            endif
        elseif (BuildingID == libId_udg_Tent1 or BuildingID == libId_udg_Tent2 or BuildingID == libId_udg_Tent3) then //Tent (1,2,3)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_Path1 or BuildingID == libId_udg_Path2 or BuildingID == libId_udg_Path3) then //Path (1,2,3)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 4
                endif
            endif
      //Building Site - Fortification:
       elseif (BuildingID == libId_udg_Tower1 or BuildingID == libId_udg_Tower2 or BuildingID == libId_udg_Tower3 or BuildingID == libId_udg_Tower4) then //Tower (1,2,3,4)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 8
                endif
            endif 
        elseif (BuildingID == libId_udg_TowerR or BuildingID == libId_udg_TowerRB or BuildingID == libId_udg_TowerRC) then //Tower Round
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 8
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 3
                endif
            endif
        elseif (BuildingID == libId_udg_TowerS or BuildingID == libId_udg_TowerSB or BuildingID == libId_udg_TowerSC) then //Tower Square
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 8
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 3
                endif
            endif
        elseif (BuildingID == libId_udg_TowerB1 or BuildingID == libId_udg_TowerB2) then //Bell Tower (1,2)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 6
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_GateCl) then //Gate (Closed)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 6
                endif
            endif
        elseif (BuildingID == libId_udg_PalisadeGateCl) then //Palisade gate (Closed)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 5
                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 5
                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 4
                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 3
                else
                    return 8
                endif
            endif
        elseif (BuildingID == libId_udg_BigGateCl) then //Big gate (Closed)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 8
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 3
                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 3
                else
                    return 8
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 3
                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 8
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 2
                else
                    return 4
                endif
            endif
        //Building Site - Wide:
        elseif (BuildingID == libId_udg_LongHall1) then //Long Hall (1)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 6
                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
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_Manor1 or BuildingID == libId_udg_Manor2 or BuildingID == libId_udg_Manor3) then //Manor (1,2,3)
            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
        elseif (BuildingID == libId_udg_Tavern1 or BuildingID == libId_udg_Tavern2 or BuildingID == libId_udg_Tavern3) then //Tavern (1,2,3)
            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
        elseif (BuildingID == libId_udg_Forge1 or BuildingID == libId_udg_Forge2 or BuildingID == libId_udg_Forge3 or BuildingID == libId_udg_Forge4) then //Forge (1,2,3,4)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 6
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif  
        elseif (BuildingID == libId_udg_LumberMill1) then //Lumber Mill (1)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 5
                endif
            endif
        elseif (BuildingID == libId_udg_LumberMill2 or BuildingID == libId_udg_LumberMill3 or BuildingID == libId_udg_LumberMill4) then //Lumber Mill (2,3,4)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 8
                endif
            endif
        elseif (BuildingID == libId_udg_StoneMill1) then //Stone Mill (1)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 5
                endif
            endif
        elseif (BuildingID == libId_udg_StoneMill2 or BuildingID == libId_udg_StoneMill3 or BuildingID == libId_udg_StoneMill4) then //Stone Mill (2,3,4)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 8
                endif
            endif
        //Building Site - Medium:
        elseif (BuildingID == libId_udg_GreatHall1 or BuildingID == libId_udg_GreatHall2 or BuildingID == libId_udg_GreatHall3) then //Great Hall (1,2,3)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 4
                else
                    return 10
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 2
                else
                    return 5
                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 2
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_Warehouse1 or BuildingID == libId_udg_Warehouse2 or BuildingID == libId_udg_Warehouse3) then //Warehouse (1,2,3)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 8
                endif
            endif
        elseif (BuildingID == libId_udg_WaterMill1 or BuildingID == libId_udg_WaterMill2 or BuildingID == libId_udg_WaterMill3) then //Water Mill (1,2,3)
            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
        elseif (BuildingID == libId_udg_Altar1 or BuildingID == libId_udg_Altar2) then //Altar (1,2)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 6
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_TrainG1 or BuildingID == libId_udg_TrainG2) then //Training Grounds (1,2)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 8
                endif
            endif
        //Building Site - Large:
        elseif (BuildingID == libId_udg_Barracks1 or BuildingID == libId_udg_Barracks2 or BuildingID == libId_udg_Barracks3 or BuildingID == libId_udg_Barracks4) then //Barracks (1,2,3,4)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 4
                else
                    return 10
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 2
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_ArcheryR1 or BuildingID == libId_udg_ArcheryR2 or BuildingID == libId_udg_ArcheryR3) then //Archery Range (1,2,3)
            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
        elseif (BuildingID == libId_udg_Stables1 or BuildingID == libId_udg_Stables2 or BuildingID == libId_udg_Stables3) then //Stables (1,2,3)
            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
        elseif (BuildingID == libId_udg_Workshop1 or BuildingID == libId_udg_Workshop2 or BuildingID == libId_udg_Workshop3) then //Workshop (1,2,3)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 4
                else
                    return 10
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 2
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_Docks1 or BuildingID == libId_udg_Docks2 or BuildingID == libId_udg_Docks3) then //Docks (1,2,3)
            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
        elseif (BuildingID == libId_udg_VillageSquare) then //Village Square
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 6
                endif
            endif
        //Building Site - Huge:
        elseif (BuildingID == libId_udg_Stronghold) then //Stronghold
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 10
                else
                    return 25
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 4
                else
                    return 10
                endif
            endif
        elseif (BuildingID == libId_udg_Cathedral1 or BuildingID == libId_udg_Cathedral2 or BuildingID == libId_udg_Cathedral3) then //Cathedral (1,2,3)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 5
                else
                    return 12
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 3
                else
                    return 7
                endif
            endif
        elseif (BuildingID == libId_udg_Market1 or BuildingID == libId_udg_Market2 or BuildingID == libId_udg_Market3 or BuildingID == libId_udg_Market4) then //Market (1,2,3,4)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 10
                endif
            endif
        //Building site (special):
        elseif (BuildingID == libId_udg_Stairs) then //Stairs
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_GateDa) then //Gate (Damaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_PalisadeGateDa) then //Palisade gate (Damaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_BigGateDa) then //Big gate (Damaged)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 4
                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 4
                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 1
                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_BuildingSiteFort //Building Site - Fortification
        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_BuildingSiteFort //Building Site - Fortification
        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_BuildingSiteFort //Building Site - Fortification
        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_BuildingSiteFort //Building Site - Fortification
        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_BuildingSiteFort //Building Site - Fortification
        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
  
    // ADDED BY WIETLOL
    private function UnitTypeIdIsInWorkerSlot takes integer unitTypeId, integer workerSlot returns boolean
        if (workerSlot == 1) then
            return unitTypeId == libId_udg_Worker or unitTypeId == libId_udg_Worker1b or unitTypeId == libId_udg_Worker2a or unitTypeId == libId_udg_Worker2b or unitTypeId == libId_udg_Worker3a or unitTypeId == libId_udg_Worker3b or unitTypeId == libId_udg_Worker4a or unitTypeId == libId_udg_Worker4b
        elseif (workerSlot == 2) then
            return unitTypeId == libId_udg_Architect or unitTypeId == libId_udg_Architect2 or unitTypeId == libId_udg_Architect3 or unitTypeId == libId_udg_Worker1e or unitTypeId == libId_udg_Worker2e
        endif
            return false
    endfunction
    // END BY WIETLOL
  
    //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 == 1) then
            return libId_udg_Worker2a //Worker (2)
        elseif (WorkerSlot == 1) then
            return libId_udg_Worker2b //Worker (2)
        elseif (WorkerSlot == 1) then
            return libId_udg_Worker3a //Worker (3)
        elseif (WorkerSlot == 1) then
            return libId_udg_Worker3b //Worker (3)
        elseif (WorkerSlot == 1) then
            return libId_udg_Worker4a //Worker (4)
        elseif (WorkerSlot == 1) then
            return libId_udg_Worker4b //Worker (4)
        elseif (WorkerSlot == 2) then
            return libId_udg_Architect //Architect
        elseif (WorkerSlot == 2) then
            return libId_udg_Architect2 //Architect (2)
        elseif (WorkerSlot == 2) then
            return libId_udg_Architect3 //Architect (3)
        elseif (WorkerSlot == 2) then
            return libId_udg_Worker1e //Engineer (1)
        elseif (WorkerSlot == 2) then
            return libId_udg_Worker2e //Engineer (2)          
        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_BuildingSiteMisc) then //Building Site - Misc
            return 64.00
        elseif (BuildingID == libId_udg_BuildingSiteSmall) then //Building site - Small
            return 128.00
        elseif (BuildingID == libId_udg_BuildingSiteFort) then //Building Site - Fortification
            return 128.00
        elseif (BuildingID == libId_udg_BuildingSiteWide) then //Building Site - Wide
            return 192.00
        elseif (BuildingID == libId_udg_BuildingSiteMedium) then //Building Site - Medium
            return 192.00
        elseif (BuildingID == libId_udg_BuildingSiteLarge) then //Building Site - Large
            return 320.00
        elseif (BuildingID == libId_udg_BuildingSiteHuge) then //Building Site - Huge
            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
                // ADDED BY WIETLOL
                exitwhen UnitTypeIdIsInWorkerSlot(PersonID, IntLoop1)
                // REMOVED BY WIETLOL
                //exitwhen WorkerSlot2UnitID(IntLoop1) == PersonID
                // END BY WIETLOL
                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
                // ADDED BY WIETLOL
                exitwhen UnitTypeIdIsInWorkerSlot(PersonID, IntLoop1)
                // REMOVED BY WIETLOL
                //exitwhen WorkerSlot2UnitID(IntLoop1) == PersonID
                // END BY WIETLOL
                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
            // REMOVED BY WIETLOL
            //set IntTemp1 = WorkerSlot2UnitID(IntLoop1)
            // END BY WIETLOL
            loop
                set UnitTemp1 = FirstOfGroup(GroupTemp1)
                exitwhen UnitTemp1 == null
                call GroupRemoveUnit(GroupTemp1, UnitTemp1)
                // ADDED BY WIETLOL
                if (UnitTypeIdIsInWorkerSlot(GetUnitTypeId(UnitTemp1), IntLoop1)) then
                // REMOVED BY WIETLOL
                //if (GetUnitTypeId(UnitTemp1) == IntTemp1) then
                // END BY WIETLOL
                    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)) // TODO replace this function
                    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) // TODO replace this function
            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
[/spoilers]

[spoilers]
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_ThatchedCottages1) then //Thatched cottages (Level1)
            return 90.00
        elseif (BuildingID == libId_udg_ThatchedCottages2) then //Thatched cottages (Level2)
            return 60.00
        elseif (BuildingID == libId_udg_ThatchedCottages3) then //Thatched cottages (Level3)
            return 60.00
        elseif (BuildingID == libId_udg_ThatchedCottages4) then //Thatched cottages (Level4)
            return 60.00
        elseif (BuildingID == libId_udg_VillageHouse1) then //Village house (Level1)
            return 120.00
        elseif (BuildingID == libId_udg_VillageHouse2) then //Village house (Level2)
            return 80.00
        elseif (BuildingID == libId_udg_VillageHouse3) then //Village house (Level3)
            return 80.00
        elseif (BuildingID == libId_udg_VillageHouse4) then //Village house (Level4)
            return 80.00
        elseif (BuildingID == libId_udg_VillageHouse5) then //Village house (Level5)
            return 80.00
        elseif (BuildingID == libId_udg_Barracks) then //Barracks
            return 120.00
        //Building site (very large):
        elseif (BuildingID == libId_udg_MotteAndBailey) then //Motte-and-bailey
            return 180.00
        elseif (BuildingID == libId_udg_SmallCastle) then //Small castle
            return 120.00
        elseif (BuildingID == libId_udg_BigCastle) then //Big castle
            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_ThatchedCottages1) then //Thatched cottages (Level1)
            return 0.62
        elseif (BuildingID == libId_udg_ThatchedCottages2) then //Thatched cottages (Level2)
            return 0.62
        elseif (BuildingID == libId_udg_ThatchedCottages3) then //Thatched cottages (Level3)
            return 0.62
        elseif (BuildingID == libId_udg_ThatchedCottages4) then //Thatched cottages (Level4)
            return 0.62
        elseif (BuildingID == libId_udg_VillageHouse1) then //Village house (Level1)
            return 1.45
        elseif (BuildingID == libId_udg_VillageHouse2) then //Village house (Level2)
            return 1.45
        elseif (BuildingID == libId_udg_VillageHouse3) then //Village house (Level3)
            return 1.45
        elseif (BuildingID == libId_udg_VillageHouse4) then //Village house (Level4)
            return 1.45
        elseif (BuildingID == libId_udg_VillageHouse5) then //Village house (Level5)
            return 1.45
        elseif (BuildingID == libId_udg_Barracks) then //Barracks
            return 1.45
        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 1
                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_ThatchedCottages1) then //Thatched cottages (Level1)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 4
                else
                    return 8
                endif
            endif
        elseif (BuildingID == libId_udg_ThatchedCottages2 or BuildingID == libId_udg_ThatchedCottages3 or BuildingID == libId_udg_ThatchedCottages4) then //Thatched cottages (Level2,3,4)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 4
                endif
            endif
        elseif (BuildingID == libId_udg_VillageHouse1) then //Village house (Level1)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 7
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 1
                endif
            endif
        elseif (BuildingID == libId_udg_VillageHouse2 or BuildingID == libId_udg_VillageHouse3 or BuildingID == libId_udg_VillageHouse4 or BuildingID == libId_udg_VillageHouse5) then //Village house (Level2,3,4,5)
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 1
                else
                    return 3
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 1
                endif
            endif
        elseif (BuildingID == libId_udg_Barracks) then //Barracks
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 7
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 1
                endif
            endif
        //Building site (very large):
        elseif (BuildingID == libId_udg_MotteAndBailey) then //Motte-and-bailey
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 3
                else
                    return 7
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 2
                else
                    return 3
                endif
            endif
        elseif (BuildingID == libId_udg_SmallCastle) then //Small castle
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 4
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                endif
            endif
        elseif (BuildingID == libId_udg_BigCastle) then //Big castle
            if (WorkerSlot == 1) then
                if (ReturnMin) then
                    return 2
                else
                    return 4
                endif
            elseif (WorkerSlot == 2) then
                if (ReturnMin) then
                    return 1
                else
                    return 2
                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 6
                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 == 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_Architect) then //Architect
            return 1.50
        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
 
Status
Not open for further replies.
Top