• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJASS] Walkable Walls Rework

Status
Not open for further replies.
Level 11
Joined
Mar 31, 2016
Messages
657
So with the help of @Wietlol and a few others on Hive chat, I successfully re-implemented @MassiveMaster 's Castle Defense map's walkable wall system and construction system. I'm very excited to re-introduce them to Hive as a legit melee map that I'm currently working on. However, the wall system has a few of limitations and bugs that I'd like to fix before releasing the alpha map.

The wall system's pathing allows for units to walk on it like a real castle wall (great for archers too). Gates and towers can be built inbetween and next to walls - they spawn door attachments when next to walls so that units can walk through them (example unit walks from one side of gate to the other side passing through each side's door). This feature only worked for initially built structures in the original map - not for newly constructed structures. The door's do spawn in appropriate locations however units are unable to walk through them, so I believe the pathing destructible isn't spawning or something (this intensive wall vJASS script uses destructibles with custom pathing to achieve walkable walls).

Another feature of this system is that it spawns stairs and ladders nearby for units to climb up onto the wall. This is done via wall's ability and works fine however I'd like for workers to be able to build ladders and stairs instead of spawning them from the wall. I tried this and the ladders + stairs built had no walkable pathing (again the destructibles aren't spawning properly). Also I want to change the model and pathing of stairs because they are a bit tight so that they fit more units. I already have the new model and pathing however idk what to change in the trigger.

Ladder carriers use an ability to drop their ladder onto a wall so enemies can easily scale the wall. This works fine in the original castle defense via enemy invaders - however the player never used the ability. Idk if reimplementing it messed it up or that perhaps the ability is a dummy and that it was all done via a different trigger that I didn't implement which controlled the enemy invaders. Also there's an error message saying this isn't the correct type of wall.

The standard gates work, however there is a Big Gate that has no pathing at all so units can just walk through. The weird thing is that the I checked the pathing map and it looked fine... I think this might be another instance where the destructible pathing isn't spawning.

Appreciate any help and advice. Also let me know if I should post the triggers and screenshots of what's going on.
 
Level 23
Joined
Jan 1, 2009
Messages
1,608
What is your question? You assume a destructable isn't spawning, what were your steps to try make it spawn?

Of course we need to see the code. Do you think we can guess how the pathing system works?

I suspect there to be some sort of "register" function that creates the necessary invisible platforms, unless it's hardcoded for the static objects.
 
Level 11
Joined
Mar 31, 2016
Messages
657
JASS:
//TESH.scrollpos=3104
//TESH.alwaysfold=0
/*-------------------------------------------------------------
//Version number:
1.04

//Description:
This system provides all the triggers for buildable, walkable and partly destructable fortification buildings.
All fortification buildings have slots for adjoining buildings so it's possible to build connected wall segments with towers, gates, stairs, etc.
Fortifications can have different adjoining types (like straight, outer edge, inner edge walls) which are automatically fitted to adjoining fortifications at the start of construction.
With "udg_TerrainDeformation = true" the terrain under fortification buildings gets adjusted so that all adjoining fortifications are on the same hight. Only activate if you don't have many doodads (destructables are ok) on your map as every terrain adjustment causes lag spikes if a lot of doodads get adjusted.

It is written to perfectly work together with the "BuildingSiteSystem".

Values in the parts under "CUSTOMIZABLE PART" have to be adjusted.

//Public variables:
public boolean udg_InitFinished = false

//Public functions:
public function AdjustConstructingFortification takes unit Building returns boolean
public function AddBuildingUnderConstruction takes unit Building returns nothing
public function RemoveBuildingUnderConstruction takes unit Building returns nothing
public function AdjustReplacedBuilding takes unit Building returns nothing

//Changelog:
-1.01:
Inital remade version

-1.02
Fixed initial movement disabling
Smart orders only on walkable buildings instead of all fortifications
Workers are no longer smart ordered

-1.03
"GetFortificationAdditionInfo" now also requires the target ID
Added the "AddLadders" function that replaces the palisade instantly with the version with attached ladders when casted
udg_AttackingCivilianID is added to ladder carriers after deploying the ladder to enable attacks

-1.04
Used "SetUnitPropWindow" to immobilize units instead of using an ensnare ability
Renamed building sites
Moved init functions ("CreateInitWalls", "DisableMovementInit") to "INITIALISATION" section
Added GetConstructionPathDestructableID to allow pathing differences between free standing building and building under construction
Replaced private Id list with the use of the global IdSystem
Added protection to "Round" for errors by dividing with zero
-------------------------------------------------------------*/
library libWal initializer Init_WallSystem requires libId, libUnitDat
    //------------------
    //CUSTOMIZABLE PART:
    //------------------
   
    globals
        private constant integer udg_SystemSlot = libUnitDat_udg_SystemNumber_WallSystem
        private constant integer udg_CountPlayers = 12 //Highest player slot in use
        private constant integer udg_RepositionOnlyFortifications = 1 //1=False, 2=True(Initialisation=False), 3=True. May cause wrong building heights with udg_TerrainDeformation = true but prevents order terminations on buildings during adjustments
        private constant boolean udg_TerrainDeformation = false //Makes adjoining walls to be on the same hight but may cause lag spikes depending on total amount of doodads (not destructables) * amount of changed terrain
        private constant real udg_HeightAdjustSmooth = 0.66 //1.00=Sharp/NoHeightDifferences ... 0.00=Smooth/BiggestHeightDifferences
        private constant integer udg_MaxWalkBuildings = udg_CountPlayers * 500 //Maximal allowed walkable buildings at the same time (Shouldn't be higher than 8191)
        private constant real udg_MaxLadderRadius = 384.00 //Maximal radius computer controlled ladder carriers will look out for a wall
        private constant real udg_AutoUseSiegeLadderRate = 3.00 //Rate at which computer controlled ladder carriers will look out for a wall
    endglobals
   
    //Returns if the given building type is part of this system:
    private function IsFortificationBuilding takes integer BuildingID returns boolean
        if (BuildingID == libId_udg_WallUn) then //Wall (Undamaged)
            return true
        elseif (BuildingID == libId_udg_WallDa) then //Wall (Damaged)
            return true
        elseif (BuildingID == libId_udg_WallDe) then //Wall (Destroyed)
            return true
        elseif (BuildingID == libId_udg_WallOEUn) then //Wall (Outer Edge) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_WallOEDa) then //Wall (Outer Edge) (Damaged)
            return true
        elseif (BuildingID == libId_udg_WallOEDe) then //Wall (Outer Edge) (Destroyed)
            return true
        elseif (BuildingID == libId_udg_WallIEUn) then //Wall (Inner Edge) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_WallIEDa) then //Wall (Inner Edge) (Damaged)
            return true
        elseif (BuildingID == libId_udg_WallIEDe) then //Wall (Inner Edge) (Destroyed)
            return true
        elseif (BuildingID == libId_udg_PalisadeUn) then //Palisade (Undamaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeDa) then //Palisade (Damaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeDe) then //Palisade (Destroyed)
            return true
        elseif (BuildingID == libId_udg_PalisadeOEUn) then //Palisade (Outer Edge) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeOEDa) then //Palisade (Outer Edge) (Damaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeOEDe) then //Palisade (Outer Edge) (Destroyed)
            return true
        elseif (BuildingID == libId_udg_PalisadeIEUn) then //Palisade (Inner Edge) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeIEDa) then //Palisade (Inner Edge) (Damaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeIEDe) then //Palisade (Inner Edge) (Destroyed)
            return true
        elseif (BuildingID == libId_udg_PalisadeLadderUn) then //Palisade (Ladder) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (Ladder) (Damaged)
            return true
        elseif (BuildingID == libId_udg_GateCl) then //Gate (Closed)
            return true
        elseif (BuildingID == libId_udg_GateOp) then //Gate (Opened)
            return true
        elseif (BuildingID == libId_udg_GateDa) then //Gate (Damaged)
            return true
        elseif (BuildingID == libId_udg_BigGateCl) then //Big gate (Closed)
            return true
        elseif (BuildingID == libId_udg_BigGateOp) then //Big gate (Opened)
            return true
        elseif (BuildingID == libId_udg_BigGateDa) then //Big gate (Damaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeGateCl) then //Palisade gate (Closed)
            return true
        elseif (BuildingID == libId_udg_PalisadeGateOp) then //Palisade gate (Opened)
            return true
        elseif (BuildingID == libId_udg_PalisadeGateDa) then //Palisade gate (Damaged)
            return true
        elseif (BuildingID == libId_udg_TowerUn) then //Tower (Undamaged)
            return true
        elseif (BuildingID == libId_udg_TowerDa) then //Tower (Damaged)
            return true
        elseif (BuildingID == libId_udg_TowerDe) then //Tower (Destroyed)
            return true
        elseif (BuildingID == libId_udg_TowerOEUn) then //Tower (Outer Edge) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_TowerOEDa) then //Tower (Outer Edge) (Damaged)
            return true
        elseif (BuildingID == libId_udg_TowerOEDe) then //Tower (Outer Edge) (Destroyed)
            return true
        elseif (BuildingID == libId_udg_TowerIEDa) then //Tower (Inner  Edge) (Damaged)
            return true
        elseif (BuildingID == libId_udg_TowerIEDe) then //Tower (Inner  Edge) (Destroyed)
            return true
        elseif (BuildingID == libId_udg_TowerIEUn) then //Tower (Inner  Edge) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_BigTowerUn) then //Big tower (Undamaged)
            return true
        elseif (BuildingID == libId_udg_BigTowerDa) then //Big tower (Damaged)
            return true
        elseif (BuildingID == libId_udg_BigTowerDe) then //Big tower (Destroyed)
            return true
        elseif (BuildingID == libId_udg_BigTowerOEUn) then //Big tower (Outer Edge) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_BigTowerOEDa) then //Big tower (Outer Edge) (Damaged)
            return true
        elseif (BuildingID == libId_udg_BigTowerOEDe) then //Big tower (Outer Edge) (Destroyed)
            return true
        elseif (BuildingID == libId_udg_BigTowerIEUn) then //Big tower (Inner Edge) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_BigTowerIEDa) then //Big tower (Inner Edge) (Damaged)
            return true
        elseif (BuildingID == libId_udg_BigTowerIEDe) then //Big tower (Inner Edge) (Destroyed)
            return true
        elseif (BuildingID == libId_udg_DrumTowerUn) then //Drum tower (Undamaged)
            return true
        elseif (BuildingID == libId_udg_DrumTowerDa) then //Drum tower (Damaged)
            return true
        elseif (BuildingID == libId_udg_DrumTowerDe) then //Drum tower (Destroyed)
            return true
        elseif (BuildingID == libId_udg_DrumTowerOEUn) then //Drum tower (Outer Edge) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_DrumTowerOEDa) then //Drum tower (Outer Edge) (Damaged)
            return true
        elseif (BuildingID == libId_udg_DrumTowerOEDe) then //Drum tower (Outer Edge) (Destroyed)
            return true
        elseif (BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (Inner Edge) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_DrumTowerIEDa) then //Drum tower (Inner Edge) (Damaged)
            return true
        elseif (BuildingID == libId_udg_DrumTowerIEDe) then //Drum tower (Inner Edge) (Destroyed)
            return true
        elseif (BuildingID == libId_udg_Stairs) then //Stairs
            return true
        elseif (BuildingID == libId_udg_LadderWall) then //Ladder (Wall)
            return true
        elseif (BuildingID == libId_udg_LadderPalisade) then //Ladder (Palisade)
            return true
        endif
        return false
    endfunction
   
    //Returns if the given building type can be taken by ladders:
    private function IsLadderTakeableBuilding takes integer BuildingID returns boolean
        if (BuildingID == libId_udg_WallUn) then //Wall (Undamaged)
            return true
        elseif (BuildingID == libId_udg_WallDa) then //Wall (Damaged)
            return true
        elseif (BuildingID == libId_udg_WallOEUn) then //Wall (Outer Edge) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_WallOEDa) then //Wall (Outer Edge) (Damaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeUn) then //Palisade (Undamaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeDa) then //Palisade (Damaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeOEUn) then //Palisade (Outer Edge) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeOEDa) then //Palisade (Outer Edge) (Damaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeLadderUn) then //Palisade (Ladder) (Undamaged)
            return true
        elseif (BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (Ladder) (Damaged)
            return true
        endif
        return false
    endfunction

    //Returns the destruction time ("Grafic - Death time") in seconds of the building type (just for walkable buildings or buildings with a destructed version of the building type / should actually be a bit shorter to produce fluid animations):
    private function GetDestructionTime takes integer BuildingID returns real
        if (BuildingID == libId_udg_WallUn) then //Wall (Undamaged)
            return 3.90
        elseif (BuildingID == libId_udg_WallDa) then //Wall (Damaged)
            return 3.90
        elseif (BuildingID == libId_udg_WallOEUn) then //Wall (Outer Edge) (Undamaged)
            return 3.90
        elseif (BuildingID == libId_udg_WallOEDa) then //Wall (Outer Edge) (Damaged)
            return 3.90
        elseif (BuildingID == libId_udg_WallIEUn) then //Wall (Inner Edge) (Undamaged)
            return 3.90
        elseif (BuildingID == libId_udg_WallIEDa) then //Wall (Inner Edge) (Damaged)
            return 3.90
        elseif (BuildingID == libId_udg_PalisadeUn) then //Palisade (Undamaged)
            return 3.90
        elseif (BuildingID == libId_udg_PalisadeDa) then //Palisade (Damaged)
            return 3.90
        elseif (BuildingID == libId_udg_PalisadeOEUn) then //Palisade (Outer Edge) (Undamaged)
            return 3.90
        elseif (BuildingID == libId_udg_PalisadeOEDa) then //Palisade (Outer Edge) (Damaged)
            return 3.90
        elseif (BuildingID == libId_udg_PalisadeIEUn) then //Palisade (Inner Edge) (Undamaged)
            return 3.90
        elseif (BuildingID == libId_udg_PalisadeIEDa) then //Palisade (Inner Edge) (Damaged)
            return 3.90
        elseif (BuildingID == libId_udg_PalisadeLadderUn) then //Palisade (Ladder) (Undamaged)
            return 3.90
        elseif (BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (Ladder) (Damaged)
            return 3.90
        elseif (BuildingID == libId_udg_GateCl) then //Gate (Closed)
            return 3.90
        elseif (BuildingID == libId_udg_GateOp) then //Gate (Opened)
            return 3.90
        elseif (BuildingID == libId_udg_BigGateCl) then //Big gate (Closed)
            return 3.90
        elseif (BuildingID == libId_udg_BigGateOp) then //Big gate (Opened)
            return 3.90
        elseif (BuildingID == libId_udg_PalisadeGateCl) then //Palisade gate (Closed)
            return 0.90
        elseif (BuildingID == libId_udg_PalisadeGateOp) then //Palisade gate (Opened)
            return 0.90
        elseif (BuildingID == libId_udg_TowerUn) then //Tower (Undamaged)
            return 4.90
        elseif (BuildingID == libId_udg_TowerDa) then //Tower (Damaged)
            return 4.90
        elseif (BuildingID == libId_udg_TowerOEUn) then //Tower (Outer Edge) (Undamaged)
            return 4.90
        elseif (BuildingID == libId_udg_TowerOEDa) then //Tower (Outer Edge) (Damaged)
            return 4.90
        elseif (BuildingID == libId_udg_TowerIEUn) then //Tower (Inner  Edge) (Undamaged)
            return 4.90
        elseif (BuildingID == libId_udg_TowerIEDa) then //Tower (Inner  Edge) (Damaged)
            return 4.90
        elseif (BuildingID == libId_udg_BigTowerUn) then //Big tower (Undamaged)
            return 4.90
        elseif (BuildingID == libId_udg_BigTowerDa) then //Big tower (Damaged)
            return 4.90
        elseif (BuildingID == libId_udg_BigTowerOEUn) then //Big tower (Outer Edge) (Undamaged)
            return 4.90
        elseif (BuildingID == libId_udg_BigTowerOEDa) then //Big tower (Outer Edge) (Damaged)
            return 4.90
        elseif (BuildingID == libId_udg_BigTowerIEUn) then //Big tower (Inner Edge) (Undamaged)
            return 4.90
        elseif (BuildingID == libId_udg_BigTowerIEDa) then //Big tower (Inner Edge) (Damaged)
            return 4.90
        elseif (BuildingID == libId_udg_DrumTowerUn) then //Drum tower (Undamaged)
            return 4.90
        elseif (BuildingID == libId_udg_DrumTowerDa) then //Drum tower (Damaged)
            return 4.90
        elseif (BuildingID == libId_udg_DrumTowerOEUn) then //Drum tower (Outer Edge) (Undamaged)
            return 4.90
        elseif (BuildingID == libId_udg_DrumTowerOEDa) then //Drum tower (Outer Edge) (Damaged)
            return 4.90
        elseif (BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (Inner Edge) (Undamaged)
            return 4.90
        elseif (BuildingID == libId_udg_DrumTowerIEDa) then //Drum tower (Inner Edge) (Damaged)
            return 4.90
        elseif (BuildingID == libId_udg_Stairs) then //Stairs
            return 3.90
        elseif (BuildingID == libId_udg_LadderWall) then //Ladder (Wall)
            return 1.90
        elseif (BuildingID == libId_udg_LadderPalisade) then //Ladder (Palisade)
            return 1.90
        endif
        return 0.00
    endfunction
   
    //Returns the destructed building version of the building type (just for buildings with a destructed version of the building type):
    private function GetDestructedBuildingID takes integer BuildingID returns integer
        if (BuildingID == libId_udg_WallUn) then //Wall (Undamaged)
            return libId_udg_WallDa //Wall (Damaged)
        elseif (BuildingID == libId_udg_WallDa) then //Wall (Damaged)
            return libId_udg_WallDe //Wall (Destroyed)
        elseif (BuildingID == libId_udg_WallOEUn) then //Wall (Outer Edge) (Undamaged)
            return libId_udg_WallOEDa //Wall (Outer Edge) (Damaged)
        elseif (BuildingID == libId_udg_WallOEDa) then //Wall (Outer Edge) (Damaged)
            return libId_udg_WallOEDe //Wall (Outer Edge) (Destroyed)
        elseif (BuildingID == libId_udg_WallIEUn) then //Wall (Inner Edge) (Undamaged)
            return libId_udg_WallIEDa //Wall (Inner Edge) (Damaged)
        elseif (BuildingID == libId_udg_WallIEDa) then //Wall (Inner Edge) (Damaged)
            return libId_udg_WallIEDe //Wall (Inner Edge) (Destroyed)
        elseif (BuildingID == libId_udg_PalisadeUn) then //Palisade (Undamaged)
            return libId_udg_PalisadeDa //Palisade (Damaged)
        elseif (BuildingID == libId_udg_PalisadeDa) then //Palisade (Damaged)
            return libId_udg_PalisadeDe //Palisade (Destroyed)
        elseif (BuildingID == libId_udg_PalisadeOEUn) then //Palisade (Outer Edge) (Undamaged)
            return libId_udg_PalisadeOEDa //Palisade (Outer Edge) (Damaged)
        elseif (BuildingID == libId_udg_PalisadeOEDa) then //Palisade (Outer Edge) (Damaged)
            return libId_udg_PalisadeOEDe //Palisade (Outer Edge) (Destroyed)
        elseif (BuildingID == libId_udg_PalisadeIEUn) then //Palisade (Inner Edge) (Undamaged)
            return libId_udg_PalisadeIEDa //Palisade (Inner Edge) (Damaged)
        elseif (BuildingID == libId_udg_PalisadeIEDa) then //Palisade (Inner Edge) (Damaged)
            return libId_udg_PalisadeIEDe //Palisade (Inner Edge) (Destroyed)
        elseif (BuildingID == libId_udg_PalisadeLadderUn) then //Palisade (Ladder) (Undamaged)
            return libId_udg_PalisadeLadderDa //Palisade (Ladder) (Damaged)
        elseif (BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (Ladder) (Damaged)
            return libId_udg_PalisadeDe //Palisade (Destroyed)
        elseif (BuildingID == libId_udg_GateCl) then //Gate (Closed)
            return libId_udg_GateDa //Gate (Damaged)
        elseif (BuildingID == libId_udg_GateOp) then //Gate (Opened)
            return libId_udg_GateDa //Gate (Damaged)
        elseif (BuildingID == libId_udg_BigGateCl) then //Big gate (Closed)
            return libId_udg_BigGateDa //Big gate (Damaged)
        elseif (BuildingID == libId_udg_BigGateOp) then //Big gate (Opened)
            return libId_udg_BigGateDa //Big gate (Damaged)
        elseif (BuildingID == libId_udg_PalisadeGateCl) then //Palisade gate (Closed)
            return libId_udg_PalisadeGateDa //Palisade gate (Damaged)
        elseif (BuildingID == libId_udg_PalisadeGateOp) then //Palisade gate (Opened)
            return libId_udg_PalisadeGateDa //Palisade gate (Damaged)
        elseif (BuildingID == libId_udg_TowerUn) then //Tower (Undamaged)
            return libId_udg_TowerDa //Tower (Damaged)
        elseif (BuildingID == libId_udg_TowerDa) then //Tower (Damaged)
            return libId_udg_TowerDe //Tower (Destroyed)
        elseif (BuildingID == libId_udg_TowerOEUn) then //Tower (Outer Edge) (Undamaged)
            return libId_udg_TowerOEDa //Tower (Outer Edge) (Damaged)
        elseif (BuildingID == libId_udg_TowerOEDa) then //Tower (Outer Edge) (Damaged)
            return libId_udg_TowerOEDe //Tower (Outer Edge) (Destroyed)
        elseif (BuildingID == libId_udg_TowerIEUn) then //Tower (Inner  Edge) (Undamaged)
            return libId_udg_TowerIEDa //Tower (Inner  Edge) (Damaged)
        elseif (BuildingID == libId_udg_TowerIEDa) then //Tower (Inner  Edge) (Damaged)
            return libId_udg_TowerIEDe //Tower (Inner  Edge) (Destroyed)
        elseif (BuildingID == libId_udg_BigTowerUn) then //Big tower (Undamaged)
            return libId_udg_BigTowerDa //Big tower (Damaged)
        elseif (BuildingID == libId_udg_BigTowerDa) then //Big tower (Damaged)
            return libId_udg_BigTowerDe //Big tower (Destroyed)
        elseif (BuildingID == libId_udg_BigTowerOEUn) then //Big tower (Outer Edge) (Undamaged)
            return libId_udg_BigTowerOEDa //Big tower (Outer Edge) (Damaged)
        elseif (BuildingID == libId_udg_BigTowerOEDa) then //Big tower (Outer Edge) (Damaged)
            return libId_udg_BigTowerOEDe //Big tower (Outer Edge) (Destroyed)
        elseif (BuildingID == libId_udg_BigTowerIEUn) then //Big tower (Inner Edge) (Undamaged)
            return libId_udg_BigTowerIEDa //Big tower (Inner Edge) (Damaged)
        elseif (BuildingID == libId_udg_BigTowerIEDa) then //Big tower (Inner Edge) (Damaged)
            return libId_udg_BigTowerIEDe //Big tower (Inner Edge) (Destroyed)
        elseif (BuildingID == libId_udg_DrumTowerUn) then //Drum tower (Undamaged)
            return libId_udg_DrumTowerDa //Drum tower (Damaged)
        elseif (BuildingID == libId_udg_DrumTowerDa) then //Drum tower (Damaged)
            return libId_udg_DrumTowerDe //Drum tower (Destroyed)
        elseif (BuildingID == libId_udg_DrumTowerOEUn) then //Drum tower (Outer Edge) (Undamaged)
            return libId_udg_DrumTowerOEDa //Drum tower (Outer Edge) (Damaged)
        elseif (BuildingID == libId_udg_DrumTowerOEDa) then //Drum tower (Outer Edge) (Damaged)
            return libId_udg_DrumTowerOEDe //Drum tower (Outer Edge) (Destroyed)
        elseif (BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (Inner Edge) (Undamaged)
            return libId_udg_DrumTowerIEDa //Drum tower (Inner Edge) (Damaged)
        elseif (BuildingID == libId_udg_DrumTowerIEDa) then //Drum tower (Inner Edge) (Damaged)
            return libId_udg_DrumTowerIEDe //Drum tower (Inner Edge) (Destroyed)
        endif
        return 0
    endfunction
   
    //Returns the repaired building version of the building type (just for destructed versions of a building type):
    private function GetRepairedBuildingID takes integer BuildingID returns integer
        if (BuildingID == libId_udg_WallDa) then //Wall (Damaged)
            return libId_udg_WallUn //Wall (Undamaged)
        elseif (BuildingID == libId_udg_WallDe) then //Wall (Destroyed)
            return libId_udg_WallUn //Wall (Undamaged)
        elseif (BuildingID == libId_udg_WallOEDa) then //Wall (Outer Edge) (Damaged)
            return libId_udg_WallOEUn //Wall (Outer Edge) (Undamaged)
        elseif (BuildingID == libId_udg_WallOEDe) then //Wall (Outer Edge) (Destroyed)
            return libId_udg_WallOEDa //Wall (Outer Edge) (Damaged)
        elseif (BuildingID == libId_udg_WallIEDa) then //Wall (Inner Edge) (Damaged)
            return libId_udg_WallIEUn //Wall (Inner Edge) (Undamaged)
        elseif (BuildingID == libId_udg_WallIEDe) then //Wall (Inner Edge) (Destroyed)
            return libId_udg_WallIEUn //Wall (Inner Edge) (Undamaged)
        elseif (BuildingID == libId_udg_PalisadeDa) then //Palisade (Damaged)
            return libId_udg_PalisadeUn //Palisade (Undamaged)
        elseif (BuildingID == libId_udg_PalisadeDe) then //Palisade (Destroyed)
            return libId_udg_PalisadeUn //Palisade (Undamaged)
        elseif (BuildingID == libId_udg_PalisadeOEDa) then //Palisade (Outer Edge) (Damaged)
            return libId_udg_PalisadeOEUn //Palisade (Outer Edge) (Undamaged)
        elseif (BuildingID == libId_udg_PalisadeOEDe) then //Palisade (Outer Edge) (Destroyed)
            return libId_udg_PalisadeOEDa //Palisade (Outer Edge) (Damaged)
        elseif (BuildingID == libId_udg_PalisadeIEDa) then //Palisade (Inner Edge) (Damaged)
            return libId_udg_PalisadeIEUn //Palisade (Inner Edge) (Undamaged)
        elseif (BuildingID == libId_udg_PalisadeIEDe) then //Palisade (Inner Edge) (Destroyed)
            return libId_udg_PalisadeIEUn //Palisade (Inner Edge) (Undamaged)
        elseif (BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (Ladder) (Damaged)
            return libId_udg_PalisadeLadderUn //Palisade (Ladder) (Undamaged)
        elseif (BuildingID == libId_udg_GateDa) then //Gate (Damaged)
            return libId_udg_GateCl //Gate (Closed)
        elseif (BuildingID == libId_udg_BigGateDa) then //Big gate (Damaged)
            return libId_udg_BigGateCl //Big gate (Closed)
        elseif (BuildingID == libId_udg_PalisadeGateDa) then //Palisade gate (Damaged)
            return libId_udg_PalisadeGateCl //Palisade gate (Closed)
        elseif (BuildingID == libId_udg_TowerDa) then //Tower (Damaged)
            return libId_udg_TowerUn //Tower (Undamaged)
        elseif (BuildingID == libId_udg_TowerDe) then //Tower (Destroyed)
            return libId_udg_TowerUn //Tower (Undamaged)
        elseif (BuildingID == libId_udg_TowerOEDa) then //Tower (Outer Edge) (Damaged)
            return libId_udg_TowerOEUn //Tower (Outer Edge) (Undamaged)
        elseif (BuildingID == libId_udg_TowerOEDe) then //Tower (Outer Edge) (Destroyed)
            return libId_udg_TowerOEUn //Tower (Outer Edge) (Undamaged)
        elseif (BuildingID == libId_udg_TowerIEDa) then //Tower (Inner  Edge) (Damaged)
            return libId_udg_TowerIEUn //Tower (Inner  Edge) (Undamaged)
        elseif (BuildingID == libId_udg_TowerIEDe) then //Tower (Inner  Edge) (Destroyed)
            return libId_udg_TowerIEUn //Tower (Inner  Edge) (Undamaged)
        elseif (BuildingID == libId_udg_BigTowerDa) then //Big tower (Damaged)
            return libId_udg_BigTowerUn //Big tower (Undamaged)
        elseif (BuildingID == libId_udg_BigTowerDe) then //Big tower (Destroyed)
            return libId_udg_BigTowerUn //Big tower (Undamaged)
        elseif (BuildingID == libId_udg_BigTowerOEDa) then //Big tower (Outer Edge) (Damaged)
            return libId_udg_BigTowerOEUn //Big tower (Outer Edge) (Undamaged)
        elseif (BuildingID == libId_udg_BigTowerOEDe) then //Big tower (Outer Edge) (Destroyed)
            return libId_udg_BigTowerOEUn //Big tower (Outer Edge) (Undamaged)
        elseif (BuildingID == libId_udg_BigTowerIEDa) then //Big tower (Inner Edge) (Damaged)
            return libId_udg_BigTowerIEUn //Big tower (Inner Edge) (Undamaged)
        elseif (BuildingID == libId_udg_BigTowerIEDe) then //Big tower (Inner Edge) (Destroyed)
            return libId_udg_BigTowerIEUn //Big tower (Inner Edge) (Undamaged)
        elseif (BuildingID == libId_udg_DrumTowerDa) then //Drum tower (Damaged)
            return libId_udg_DrumTowerUn //Drum tower (Undamaged)
        elseif (BuildingID == libId_udg_DrumTowerDe) then //Drum tower (Destroyed)
            return libId_udg_DrumTowerUn //Drum tower (Undamaged)
        elseif (BuildingID == libId_udg_DrumTowerOEDa) then //Drum tower (Outer Edge) (Damaged)
            return libId_udg_DrumTowerOEUn //Drum tower (Outer Edge) (Undamaged)
        elseif (BuildingID == libId_udg_DrumTowerOEDe) then //Drum tower (Outer Edge) (Destroyed)
            return libId_udg_DrumTowerOEUn //Drum tower (Outer Edge) (Undamaged)
        elseif (BuildingID == libId_udg_DrumTowerIEDa) then //Drum tower (Inner Edge) (Damaged)
            return libId_udg_DrumTowerIEUn //Drum tower (Inner Edge) (Undamaged)
        elseif (BuildingID == libId_udg_DrumTowerIEDe) then //Drum tower (Inner Edge) (Destroyed)
            return libId_udg_DrumTowerIEUn //Drum tower (Inner Edge) (Undamaged)
        endif
        return 0
    endfunction
   
    //Returns the building type that replaces the matching initial building type:
    private function GetReplacingInitBuildingID takes integer BuildingID returns integer
        if (BuildingID == libId_udg_WallIP) then //Wall (Init Placement)
            return libId_udg_WallUn //Wall (Undamaged)
        elseif (BuildingID == libId_udg_WallDaIP) then //Wall (Damaged) (Init Placement)
            return libId_udg_WallDa //Wall (Damaged)
        elseif (BuildingID == libId_udg_WallDeIP) then //Wall (Destroyed) (Init Placement)
            return libId_udg_WallDe //Wall (Destroyed)
        elseif (BuildingID == libId_udg_WallOEIP) then //Wall (Outer Edge) (Init Placement)
            return libId_udg_WallOEUn //Wall (Outer Edge) (Undamaged)
        elseif (BuildingID == libId_udg_WallIEIP) then //Wall (Inner Edge) (Init Placement)
            return libId_udg_WallIEUn //Wall (Inner Edge) (Undamaged)
        elseif (BuildingID == libId_udg_PalisadeIP) then //Palisade (Init Placement)
            return libId_udg_PalisadeUn //Palisade (Undamaged)
        elseif (BuildingID == libId_udg_PalisadeLadderIP) then //Palisade (Ladder) (Init Placement)
            return libId_udg_PalisadeLadderUn //Palisade (Ladder) (Undamaged)
        elseif (BuildingID == libId_udg_PalisadeOEIP) then //Palisade (Outer Edge) (Init Placement)
            return libId_udg_PalisadeOEUn //Palisade (Outer Edge) (Undamaged)
        elseif (BuildingID == libId_udg_TowerOEIP) then //Tower (Outer Edge) (Init Placement)
            return libId_udg_TowerOEUn //Tower (Outer Edge) (Undamaged)
        elseif (BuildingID == libId_udg_TowerIP) then //Tower (Init Placement)
            return libId_udg_TowerUn //Tower (Undamaged)
        elseif (BuildingID == libId_udg_GateClIP) then //Gate (Closed) (Init Placement)
            return libId_udg_GateCl //Gate (Closed)
        elseif (BuildingID == libId_udg_BigGateOpIP) then //Big gate (Opened) (Init Placement)
            return libId_udg_BigGateOp //Big gate (Opened)
        elseif (BuildingID == libId_udg_PalisadeGateOpIP) then //Palisade gate (Opened) (Init Placement)
            return libId_udg_PalisadeGateOp //Palisade gate (Opened)
        elseif (BuildingID == libId_udg_BigTowerIP) then //Big tower (Init Placement)
            return libId_udg_BigTowerUn //Big tower (Undamaged)
        elseif (BuildingID == libId_udg_BigTowerOEDaIP) then //Big tower (Outer Edge) (Damaged) (Init Placement)
            return libId_udg_BigTowerOEDa //Big tower (Outer Edge) (Damaged)
        elseif (BuildingID == libId_udg_DrumTowerOEIP) then //Drum tower (Outer Edge) (Init Placement)
            return libId_udg_DrumTowerOEUn //Drum tower (Outer Edge)
        elseif (BuildingID == libId_udg_StairsIP) then //Stairs (Init Placement)
            return libId_udg_Stairs //Stairs
        elseif (BuildingID == libId_udg_LadderWallIP) then //Ladder (Init Placement) (Wall)
            return libId_udg_LadderWall //Ladder (Wall)
        elseif (BuildingID == libId_udg_LadderPalisadeIP) then //Ladder (Init Placement) (Palisade)
            return libId_udg_LadderPalisade //Ladder (Palisade)
        endif
        return 0
    endfunction
   
    //Returns the amount of adjoining slots from the given building type (BuildingID):
    private function GetFortificationBuildingAdjoiningSlots takes integer BuildingID returns integer
        if (BuildingID == libId_udg_WallUn or BuildingID == libId_udg_WallDa or BuildingID == libId_udg_WallDe) then //Wall (no Edge)
            return 4
        elseif (BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallOEDa or BuildingID == libId_udg_WallOEDe) then //Wall (Outer Edge)
            return 3
        elseif (BuildingID == libId_udg_WallIEUn or BuildingID == libId_udg_WallIEDa or BuildingID == libId_udg_WallIEDe) then //Wall (Inner Edge)
            return 2
        elseif (BuildingID == libId_udg_PalisadeUn or BuildingID == libId_udg_PalisadeDa or BuildingID == libId_udg_PalisadeDe or BuildingID == libId_udg_PalisadeLadderUn or BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (no Edge)
            return 3
        elseif (BuildingID == libId_udg_PalisadeOEUn or BuildingID == libId_udg_PalisadeOEDa or BuildingID == libId_udg_PalisadeOEDe) then //Palisade (Outer Edge)
            return 3
        elseif (BuildingID == libId_udg_PalisadeIEUn or BuildingID == libId_udg_PalisadeIEDa or BuildingID == libId_udg_PalisadeIEDe) then //Palisade (Inner Edge)
            return 2
        elseif (BuildingID == libId_udg_TowerUn or BuildingID == libId_udg_TowerDa or BuildingID == libId_udg_TowerDe) then //Tower (no Edge)
            return 2
        elseif (BuildingID == libId_udg_TowerOEUn or BuildingID == libId_udg_TowerOEDa or BuildingID == libId_udg_TowerOEDe) then //Tower (Outer Edge)
            return 2
        elseif (BuildingID == libId_udg_TowerIEUn or BuildingID == libId_udg_TowerIEDa or BuildingID == libId_udg_TowerIEDe) then //Tower (Inner Edge)
            return 2
        elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerDa or BuildingID == libId_udg_BigTowerDe) then //Big tower (no Edge)
            return 2
        elseif (BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerOEDa or BuildingID == libId_udg_BigTowerOEDe) then //Big tower (Outer Edge)
            return 2
        elseif (BuildingID == libId_udg_BigTowerIEUn or BuildingID == libId_udg_BigTowerIEDa or BuildingID == libId_udg_BigTowerIEDe) then //Big tower (Inner Edge)
            return 2
        elseif (BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerDa or BuildingID == libId_udg_DrumTowerDe) then //Drum tower (no Edge)
            return 2
        elseif (BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerOEDa or BuildingID == libId_udg_DrumTowerOEDe) then //Drum tower (Outer Edge)
            return 2
        elseif (BuildingID == libId_udg_DrumTowerIEUn or BuildingID == libId_udg_DrumTowerIEDa or BuildingID == libId_udg_DrumTowerIEDe) then //Drum tower (Inner Edge)
            return 2
        elseif (BuildingID == libId_udg_Stairs) then //Stairs
            return 1
        elseif (BuildingID == libId_udg_LadderWall) then //Ladder (Wall)
            return 1
        elseif (BuildingID == libId_udg_LadderPalisade) then //Ladder (Palisade)
            return 1
        elseif (BuildingID == libId_udg_GateCl or BuildingID == libId_udg_GateDa or BuildingID == libId_udg_GateOp) then //Gate
            return 2
        elseif (BuildingID == libId_udg_BigGateCl or BuildingID == libId_udg_BigGateOp or BuildingID == libId_udg_BigGateDa) then //Big gate
            return 2
        endif
        return 0
    endfunction
   
    //Returns the Wall walk destructable type of the given building type with the given opened/closed sides:
    private function GetWalkDestructableID takes integer BuildingID, integer Type returns integer
        if (BuildingID == libId_udg_WallUn or BuildingID == libId_udg_WallDa) then //Wall (No edge)
            if (Type == 0) then
                return libId_udg_WallWalkOp //Wall Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_WallWalkCl1 //Wall Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_WallWalkCl2 //Wall Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_WallWalkCl12 //Wall Walk (Closed 1&2)
            elseif (Type == 4) then
                return libId_udg_WallWalkCl3 //Wall Walk (Closed 3)
            elseif (Type == 5) then
                return libId_udg_WallWalkCl13 //Wall Walk (Closed 1&3)
            elseif (Type == 6) then
                return libId_udg_WallWalkCl23 //Wall Walk (Closed 2&3)
            elseif (Type == 7) then
                return libId_udg_WallWalkCl123 //Wall Walk (Closed 1&2&3)
            elseif (Type == 8) then
                return libId_udg_WallWalkCl4 //Wall Walk (Closed 4)
            elseif (Type == 9) then
                return libId_udg_WallWalkCl14 //Wall Walk (Closed 1&4)
            elseif (Type == 10) then
                return libId_udg_WallWalkCl23 //Wall Walk (Closed 2&4)
            elseif (Type == 11) then
                return libId_udg_WallWalkCl124 //Wall Walk (Closed 1&2&4)
            elseif (Type == 12) then
                return libId_udg_WallWalkCl34 //Wall Walk (Closed 3&4)
            elseif (Type == 13) then
                return libId_udg_WallWalkCl134 //Wall Walk (Closed 1&3&4)
            elseif (Type == 14) then
                return libId_udg_WallWalkCl234 //Wall Walk (Closed 2&3&4)
            elseif (Type == 15) then
                return libId_udg_WallWalkCl1234 //Wall Walk (Closed 1&2&3&4)
            endif
        elseif (BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallOEDa) then //Wall (Outer Edge)
            if (Type == 0) then
                return libId_udg_WallOEWalkOp //Wall Outer Edge Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_WallOEWalkCl1 //Wall Outer Edge Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_WallOEWalkCl2 //Wall Outer Edge Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_WallOEWalkCl12 //Wall Outer Edge Walk (Closed 1&2)
            elseif (Type == 4) then
                return libId_udg_WallOEWalkCl3 //Wall Outer Edge Walk (Closed 3)
            elseif (Type == 5) then
                return libId_udg_WallOEWalkCl13 //Wall Outer Edge Walk (Closed 1&3)
            elseif (Type == 6) then
                return libId_udg_WallOEWalkCl23 //Wall Outer Edge Walk (Closed 2&3)
            elseif (Type == 7) then
                return libId_udg_WallOEWalkCl123 //Wall Outer Edge Walk (Closed 1&2&3)
            endif
        elseif (BuildingID == libId_udg_WallIEUn or BuildingID == libId_udg_WallIEDa) then //Wall (Inner Edge)
            if (Type == 0) then
                return libId_udg_WallIEWalkOp //Wall Inner Edge Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_WallIEWalkCl1 //Wall Inner Edge Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_WallIEWalkCl2 //Wall Inner Edge Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_WallIEWalkCl12 //Wall Inner Edge Walk (Closed 1&2)
            endif
        elseif (BuildingID == libId_udg_PalisadeUn or BuildingID == libId_udg_PalisadeDa) then //Palisade (No edge)
            if (Type == 0) then
                return libId_udg_PalisadeWalkCl3 //Palisade Walk (Closed 3)
            elseif (Type == 1) then
                return libId_udg_PalisadeWalkCl13 //Palisade Walk (Closed 1&3)
            elseif (Type == 2) then
                return libId_udg_PalisadeWalkCl23 //Palisade Walk (Closed 2&3)
            elseif (Type == 3) then
                return libId_udg_PalisadeWalkCl123 //Palisade Walk (Closed 1&2&3)
            elseif (Type == 4) then
                return libId_udg_PalisadeWalkCl34 //Palisade Walk (Closed 3&4)
            elseif (Type == 5) then
                return libId_udg_PalisadeWalkCl134 //Palisade Walk (Closed 1&3&4)
            elseif (Type == 6) then
                return libId_udg_PalisadeWalkCl234 //Palisade Walk (Closed 2&3&4)
            elseif (Type == 7) then
                return libId_udg_PalisadeWalkCl1234 //Palisade Walk (Closed 1&2&3&4)
            endif
        elseif (BuildingID == libId_udg_PalisadeOEUn or BuildingID == libId_udg_PalisadeOEDa) then //Palisade (Outer Edge)
            if (Type == 0) then
                return libId_udg_PalisadeOEWalkOp //Palisade Outer Edge Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_PalisadeOEWalkCl1 //Palisade Outer Edge Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_PalisadeOEWalkCl2 //Palisade Outer Edge Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_PalisadeOEWalkCl12 //Palisade Outer Edge Walk (Closed 1&2)
            elseif (Type == 4) then
                return libId_udg_PalisadeOEWalkCl3 //Palisade Outer Edge Walk (Closed 3)
            elseif (Type == 5) then
                return libId_udg_PalisadeOEWalkCl13 //Palisade Outer Edge Walk (Closed 1&3)
            elseif (Type == 6) then
                return libId_udg_PalisadeOEWalkCl23 //Palisade Outer Edge Walk (Closed 2&3)
            elseif (Type == 7) then
                return libId_udg_PalisadeOEWalkCl123 //Palisade Outer Edge Walk (Closed 1&2&3)
            endif
        elseif (BuildingID == libId_udg_PalisadeIEUn or BuildingID == libId_udg_PalisadeIEDa) then //Palisade (Inner Edge)
            if (Type == 0) then
                return libId_udg_PalisadeIEWalkOp //Palisade Inner Edge Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_PalisadeIEWalkCl1 //Palisade Inner Edge Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_PalisadeIEWalkCl2 //Palisade Inner Edge Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_PalisadeIEWalkCl12 //Palisade Inner Edge Walk (Closed 1&2)
            endif
        elseif (BuildingID == libId_udg_PalisadeLadderUn or BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (Ladder) (No edge)
            if (Type == 0) then
                return libId_udg_PalisadeWalkOp //Palisade Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_PalisadeWalkCl1 //Palisade Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_PalisadeWalkCl2 //Palisade Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_PalisadeWalkCl12 //Palisade Walk (Closed 1&2)
            elseif (Type == 4) then
                return libId_udg_PalisadeWalkCl4 //Palisade Walk (Closed 4)
            elseif (Type == 5) then
                return libId_udg_PalisadeWalkCl14 //Palisade Walk (Closed 1&4)
            elseif (Type == 6) then
                return libId_udg_PalisadeWalkCl24 //Palisade Walk (Closed 2&4)
            elseif (Type == 7) then
                return libId_udg_PalisadeWalkCl124 //Palisade Walk (Closed 1&2&4)
            endif
        elseif (BuildingID == libId_udg_TowerUn or BuildingID == libId_udg_TowerDa) then //Tower (No edge)
            if (Type == 0) then
                return libId_udg_TowerWalkOp //Tower Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_TowerWalkCl1 //Tower Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_TowerWalkCl2 //Tower Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_TowerWalkCl12 //Tower Walk (Closed 1&2)
            endif
        elseif (BuildingID == libId_udg_TowerOEUn or BuildingID == libId_udg_TowerOEDa) then //Tower (Outer Edge)
            if (Type == 0) then
                return libId_udg_TowerOEWalkOp //Tower Outer Edge Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_TowerOEWalkCl1 //Tower Outer Edge Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_TowerOEWalkCl2 //Tower Outer Edge Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_TowerOEWalkCl12 //Tower Outer Edge Walk (Closed 1&2)
            endif
        elseif (BuildingID == libId_udg_TowerIEUn or BuildingID == libId_udg_TowerIEDa) then //Tower (Inner  Edge)
            if (Type == 0) then
                return libId_udg_TowerIEWalkOp //Tower Inner Edge Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_TowerIEWalkCl1 //Tower Inner Edge Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_TowerIEWalkCl2 //Tower Inner Edge Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_TowerIEWalkCl12 //Tower Inner Edge Walk (Closed 1&2)
            endif
        elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerDa) then //Big tower (No edge)
            if (Type == 0) then
                return libId_udg_BigTowerWalkOp //Big Tower Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_BigTowerWalkCl1 //Big Tower Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_BigTowerWalkCl2 //Big Tower Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_BigTowerWalkCl12 //Big Tower Walk (Closed 1&2)
            endif
        elseif (BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerOEDa) then //Big tower (Outer Edge)
            if (Type == 0) then
                return libId_udg_BigTowerOEWalkOp //Big Tower Outer Edge Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_BigTowerOEWalkCl1 //Big Tower Outer Edge Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_BigTowerOEWalkCl2 //Big Tower Outer Edge Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_BigTowerOEWalkCl12 //Big Tower Outer Edge Walk (Closed 1&2)
            endif
        elseif (BuildingID == libId_udg_BigTowerIEUn or BuildingID == libId_udg_BigTowerIEDa) then //Big tower (Inner Edge)
            if (Type == 0) then
                return libId_udg_BigTowerIEWalkOp //Big Tower Inner Edge Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_BigTowerIEWalkCl1 //Big Tower Inner Edge Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_BigTowerIEWalkCl2 //Big Tower Inner Edge Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_BigTowerIEWalkCl12 //Big Tower Inner Edge Walk (Closed 1&2)
            endif
        elseif (BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerDa) then //Drum tower (No edge)
            if (Type == 0) then
                return libId_udg_DrumTowerWalkOp //Drum Tower Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_DrumTowerWalkCl1 //Drum Tower Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_DrumTowerWalkCl2 //Drum Tower Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_DrumTowerWalkCl12 //Drum Tower Walk (Closed 1&2)
            endif
        elseif (BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerOEDa) then //Drum tower (Outer Edge)
            if (Type == 0) then
                return libId_udg_DrumTowerOEWalkOp //Drum Tower Outer Edge Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_DrumTowerOEWalkCl1 //Drum Tower Outer Edge Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_DrumTowerOEWalkCl2 //Drum Tower Outer Edge Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_DrumTowerOEWalkCl12 //Drum Tower Outer Edge Walk (Closed 1&2)
            endif
        elseif (BuildingID == libId_udg_DrumTowerIEUn or BuildingID == libId_udg_DrumTowerIEDa) then //Drum tower (Inner Edge)
            if (Type == 0) then
                return libId_udg_DrumTowerIEWalkOp //Drum Tower Inner Edge Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_DrumTowerIEWalkCl1 //Drum Tower Inner Edge Walk (Closed 1)
            elseif (Type == 2) then
                return libId_udg_DrumTowerIEWalkCl2 //Drum Tower Inner Edge Walk (Closed 2)
            elseif (Type == 3) then
                return libId_udg_DrumTowerIEWalkCl12 //Drum Tower Inner Edge Walk (Closed 1&2)
            endif
        elseif (BuildingID == libId_udg_Stairs) then //Stairs
            if (Type == 0) then
                return libId_udg_StairsWalkOp //Stairs Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_StairsWalkCl1 //Stairs Walk (Closed 1)
            endif
        elseif (BuildingID == libId_udg_LadderWall) then //Ladder (Wall)
            if (Type == 0) then
                return libId_udg_LadderWalkOp //Ladder Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_LadderWalkCl1 //Ladder Walk (Closed 1)
            endif
        elseif (BuildingID == libId_udg_LadderPalisade) then //Ladder (Palisade)
            if (Type == 0) then
                return libId_udg_LadderWalkSmallOp //Ladder Walk Small (Opened)
            elseif (Type == 1) then
                return libId_udg_LadderWalkSmallCl1 //Ladder Walk Small (Closed 1)
            endif
        endif
        return 0
    endfunction

    //Returns the pathing destructable type of the given building type during the death animation, if the destructed version isn't walkable:
    private function GetDyingPathDestructableID takes integer BuildingID returns integer
        if (BuildingID == libId_udg_WallDa or BuildingID == libId_udg_WallOEDa or BuildingID == libId_udg_WallIEDa or BuildingID == libId_udg_TowerDa or BuildingID == libId_udg_TowerOEDa or BuildingID == libId_udg_TowerIEDa) then //Wall (all Damaged), Tower (all Damaged)
            return libId_udg_PathingBlockerTiny //Pathing Blocker (tiny)
        elseif (BuildingID == libId_udg_PalisadeDa or BuildingID == libId_udg_PalisadeOEDa or BuildingID == libId_udg_PalisadeIEDa) then //Palisade (all Damaged)
            return libId_udg_PathingBlockerTiny //Pathing Blocker (tiny)
        elseif (BuildingID == libId_udg_BigTowerDa or BuildingID == libId_udg_BigTowerOEDa or BuildingID == libId_udg_BigTowerIEDa) then //Big tower (all Damaged)
            return libId_udg_PathingBlockerLittle //Pathing Blocker (little)
        elseif (BuildingID == libId_udg_DrumTowerDa or BuildingID == libId_udg_DrumTowerOEDa or BuildingID == libId_udg_DrumTowerIEDa) then //Drum tower (all Damaged)
            return libId_udg_PathingBlockerLittle //Pathing Blocker (little)
        elseif (BuildingID == libId_udg_GateCl or BuildingID == libId_udg_GateOp) then //Gate (not Damaged)
            return libId_udg_PathingBlockerGate //Pathing Blocker (Gate)
        elseif (BuildingID == libId_udg_BigGateCl or BuildingID == libId_udg_BigGateOp) then //Big gate (not Damaged)
            return libId_udg_PathingBlockerBigGate //Pathing Blocker (Big gate)
        elseif (BuildingID == libId_udg_PalisadeGateCl or BuildingID == libId_udg_PalisadeGateOp) then //Palisade gate (not Damaged)
            return libId_udg_PathingBlockerPalisadeGate //Pathing Blocker (Palisade gate)
        endif
        return 0
    endfunction
   
    //Returns the pathing destructable type of the given building type during the construction animation:
    private function GetConstructionPathDestructableID takes integer BuildingID returns integer
        local integer IntTemp1 = 1
        local integer IntTemp2
        if (BuildingID == libId_udg_TowerUn or BuildingID == libId_udg_TowerDa) then //Tower (No edge)
            return libId_udg_TowerOEWalkCl12 //Tower Outer Edge Walk (Closed 1&2)
        elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerDa) then //Big tower (No edge)
            return libId_udg_BigTowerOEWalkCl12 //Big Tower Outer Edge Walk (Closed 1&2)
        elseif (BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerDa) then //Drum tower (No edge)
            return libId_udg_DrumTowerOEWalkCl12 //Drum Tower Outer Edge Walk (Closed 1&2)
        endif
        //Loop instead of "Pow" (faster):
        set IntTemp2 = GetFortificationBuildingAdjoiningSlots(IntTemp1)
        loop
            exitwhen IntTemp2 <= 0
            set IntTemp1 = IntTemp1 * 2
            set IntTemp2 = IntTemp2 - 1
        endloop
        set IntTemp1 = IntTemp1 - 1
        return GetWalkDestructableID(BuildingID, IntTemp1)
    endfunction
   
    //Returns the base type of the given walk building sub type:
    private function GetBaseWalkBuildingID takes integer BuildingID returns integer
        if (BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallIEUn) then //Wall (Edge) (Undamaged)
            return libId_udg_WallUn //Wall (Undamaged)
        elseif (BuildingID == libId_udg_PalisadeOEUn or BuildingID == libId_udg_PalisadeIEUn) then //Palisade (Edge) (Undamaged)
            return libId_udg_PalisadeUn //Palisade (Undamaged)
        elseif (BuildingID == libId_udg_TowerOEUn or BuildingID == libId_udg_TowerIEUn) then //Tower (Edge) (Undamaged)
            return libId_udg_TowerUn //Tower (Undamaged)
        elseif (BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerIEUn) then //Big tower (Edge) (Undamaged)
            return libId_udg_BigTowerUn //Big tower (Undamaged)
        elseif (BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (Edge) (Undamaged)
            return libId_udg_DrumTowerUn //Drum tower (Undamaged)
        endif
        return BuildingID
    endfunction
   
    //Returns the sub type of the given walk building type:
    private function GetSubWalkBuildingID takes integer BuildingID, integer SubNumber returns integer
        if (BuildingID == libId_udg_WallUn) then //Wall (Undamaged)
            if (SubNumber == 1) then
                return BuildingID
            elseif (SubNumber == 2) then
                return libId_udg_WallOEUn //Wall (Outer Edge) (Undamaged)
            elseif (SubNumber == 3) then
                return libId_udg_WallIEUn //Wall (Inner Edge) (Undamaged)
            endif
        elseif (BuildingID == libId_udg_PalisadeUn) then //Palisade (Undamaged)
            if (SubNumber == 1) then
                return BuildingID
            elseif (SubNumber == 2) then
                return libId_udg_PalisadeOEUn //Palisade (Outer Edge) (Undamaged)
            elseif (SubNumber == 3) then
                return libId_udg_PalisadeIEUn //Palisade (Inner Edge) (Undamaged)
            endif
        elseif (BuildingID == libId_udg_TowerUn) then //Tower (Undamaged)
            if (SubNumber == 1) then
                return BuildingID
            elseif (SubNumber == 2) then
                return libId_udg_TowerOEUn //Tower (Outer Edge) (Undamaged)
            elseif (SubNumber == 3) then
                return libId_udg_TowerIEUn //Tower (Inner Edge) (Undamaged)
            endif
        elseif (BuildingID == libId_udg_BigTowerUn) then //Big tower (Undamaged)
            if (SubNumber == 1) then
                return BuildingID
            elseif (SubNumber == 2) then
                return libId_udg_BigTowerOEUn //Big tower (Outer Edge) (Undamaged)
            elseif (SubNumber == 3) then
                return libId_udg_BigTowerIEUn //Big tower (Inner Edge) (Undamaged)
            endif
        elseif (BuildingID == libId_udg_DrumTowerUn) then //Drum tower (Undamaged)
            if (SubNumber == 1) then
                return BuildingID
            elseif (SubNumber == 2) then
                return libId_udg_DrumTowerOEUn //Drum tower (Outer Edge) (Undamaged)
            elseif (SubNumber == 3) then
                return libId_udg_DrumTowerIEUn //Drum tower (Inner Edge) (Undamaged)
            endif
        endif
        return 0
    endfunction
   
    //Checks if the given building (Adjoining) is an adjoining building (Slot, Number) to a building with the given data (BuildingID, Facing):
    private function IsFortificationBuildingAdjoining_Function1 takes real Input returns boolean
        local real MaxResidual = 0.001
        return ((Input <= MaxResidual and Input >= (-1) * MaxResidual) or (360.00 - Input <= MaxResidual and 360.00 - Input >= (-1) * MaxResidual) or (-360.00 - Input <= MaxResidual and -360.00 - Input >= (-1) * MaxResidual))
    endfunction
    private function IsFortificationBuildingAdjoining takes integer BuildingID, integer Slot, integer Number, real Facing, unit Adjoining returns boolean
        local integer AdjoiningID = GetUnitTypeId(Adjoining)
        local real FacingOffset = GetUnitFacing(Adjoining) - Facing
        if (BuildingID == libId_udg_WallUn or BuildingID == libId_udg_WallDa or BuildingID == libId_udg_WallDe) then //Wall (no Edge)
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa or AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa or AdjoiningID == libId_udg_WallDe or AdjoiningID == libId_udg_WallOEDe or AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa or AdjoiningID == libId_udg_WallIEDe or AdjoiningID == libId_udg_TowerUn or AdjoiningID == libId_udg_TowerDa or AdjoiningID == libId_udg_TowerOEUn or AdjoiningID == libId_udg_TowerOEDa or AdjoiningID == libId_udg_TowerDe or AdjoiningID == libId_udg_TowerOEDe or AdjoiningID == libId_udg_GateCl or AdjoiningID == libId_udg_GateDa or AdjoiningID == libId_udg_GateOp) //Wall, Tower, Gate
                    endif
                elseif (Number == 2) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_BigTowerUn or AdjoiningID == libId_udg_BigTowerDa or AdjoiningID == libId_udg_BigTowerDe or AdjoiningID == libId_udg_BigTowerOEUn or AdjoiningID == libId_udg_BigTowerOEDa or AdjoiningID == libId_udg_BigTowerOEDe or AdjoiningID == libId_udg_BigTowerIEUn or AdjoiningID == libId_udg_BigTowerIEDa or AdjoiningID == libId_udg_BigTowerIEDe or AdjoiningID == libId_udg_DrumTowerUn or AdjoiningID == libId_udg_DrumTowerDa or AdjoiningID == libId_udg_DrumTowerDe or AdjoiningID == libId_udg_DrumTowerOEUn or AdjoiningID == libId_udg_DrumTowerOEDa or AdjoiningID == libId_udg_DrumTowerOEDe or AdjoiningID == libId_udg_DrumTowerIEUn or AdjoiningID == libId_udg_DrumTowerIEDa or AdjoiningID == libId_udg_DrumTowerIEDe or AdjoiningID == libId_udg_BigGateCl or AdjoiningID == libId_udg_BigGateOp or AdjoiningID == libId_udg_BigGateDa) //Big tower, Drum tower, Big gate
                    endif
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa or AdjoiningID == libId_udg_WallDe or AdjoiningID == libId_udg_TowerUn or AdjoiningID == libId_udg_TowerDa or AdjoiningID == libId_udg_TowerDe or AdjoiningID == libId_udg_GateCl or AdjoiningID == libId_udg_GateDa or AdjoiningID == libId_udg_GateOp) //Wall (no Edge), Tower (no Edge), Gate
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa or AdjoiningID == libId_udg_WallOEDe or AdjoiningID == libId_udg_TowerOEUn or AdjoiningID == libId_udg_TowerOEDa or AdjoiningID == libId_udg_TowerOEDe) //Wall (Outer Edge), Tower (Outer Edge)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa or AdjoiningID == libId_udg_WallIEDe or AdjoiningID == libId_udg_TowerIEUn or AdjoiningID == libId_udg_TowerIEDa or AdjoiningID == libId_udg_TowerIEDe) //Wall (Inner Edge), Tower (Inner Edge)
                    endif
                elseif (Number == 2) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_BigTowerUn or AdjoiningID == libId_udg_BigTowerDa or AdjoiningID == libId_udg_BigTowerDe or AdjoiningID == libId_udg_DrumTowerUn or AdjoiningID == libId_udg_DrumTowerDa or AdjoiningID == libId_udg_DrumTowerDe or AdjoiningID == libId_udg_BigGateCl or AdjoiningID == libId_udg_BigGateOp or AdjoiningID == libId_udg_BigGateDa) //Big tower (no Edge), Drum tower (no Edge), Big gate
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_BigTowerOEUn or AdjoiningID == libId_udg_BigTowerOEDa or AdjoiningID == libId_udg_BigTowerOEDe or AdjoiningID == libId_udg_DrumTowerOEUn or AdjoiningID == libId_udg_DrumTowerOEDa or AdjoiningID == libId_udg_DrumTowerOEDe) //Big tower (Outer Edge), Drum tower (Outer Edge)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_BigTowerIEUn or AdjoiningID == libId_udg_BigTowerIEDa or AdjoiningID == libId_udg_BigTowerIEDe or AdjoiningID == libId_udg_DrumTowerIEUn or AdjoiningID == libId_udg_DrumTowerIEDa or AdjoiningID == libId_udg_DrumTowerIEDe) //Big tower (Inner Edge), Drum tower (Inner Edge)
                    endif
                endif
            elseif (Slot == 3) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_Stairs) //Stairs
                    endif
                endif
            elseif (Slot == 4) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_LadderWall) //Ladder (Wall)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallOEDa or BuildingID == libId_udg_WallOEDe) then //Wall (Outer Edge)
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa or AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa or AdjoiningID == libId_udg_WallDe or AdjoiningID == libId_udg_WallOEDe or AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa or AdjoiningID == libId_udg_WallIEDe or AdjoiningID == libId_udg_TowerUn or AdjoiningID == libId_udg_TowerDa or AdjoiningID == libId_udg_TowerOEUn or AdjoiningID == libId_udg_TowerOEDa or AdjoiningID == libId_udg_TowerDe or AdjoiningID == libId_udg_TowerOEDe or AdjoiningID == libId_udg_GateCl or AdjoiningID == libId_udg_GateDa or AdjoiningID == libId_udg_GateOp) //Wall, Tower, Gate
                    endif
                elseif (Number == 2) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_BigTowerUn or AdjoiningID == libId_udg_BigTowerDa or AdjoiningID == libId_udg_BigTowerDe or AdjoiningID == libId_udg_BigTowerOEUn or AdjoiningID == libId_udg_BigTowerOEDa or AdjoiningID == libId_udg_BigTowerOEDe or AdjoiningID == libId_udg_BigTowerIEUn or AdjoiningID == libId_udg_BigTowerIEDa or AdjoiningID == libId_udg_BigTowerIEDe or AdjoiningID == libId_udg_DrumTowerUn or AdjoiningID == libId_udg_DrumTowerDa or AdjoiningID == libId_udg_DrumTowerDe or AdjoiningID == libId_udg_DrumTowerOEUn or AdjoiningID == libId_udg_DrumTowerOEDa or AdjoiningID == libId_udg_DrumTowerOEDe or AdjoiningID == libId_udg_DrumTowerIEUn or AdjoiningID == libId_udg_DrumTowerIEDa or AdjoiningID == libId_udg_DrumTowerIEDe or AdjoiningID == libId_udg_BigGateCl or AdjoiningID == libId_udg_BigGateOp or AdjoiningID == libId_udg_BigGateDa) //Big tower, Drum tower, Big gate
                    endif
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa or AdjoiningID == libId_udg_WallDe or AdjoiningID == libId_udg_TowerUn or AdjoiningID == libId_udg_TowerDa or AdjoiningID == libId_udg_TowerDe or AdjoiningID == libId_udg_GateCl or AdjoiningID == libId_udg_GateDa or AdjoiningID == libId_udg_GateOp) //Wall (no Edge), Tower (no Edge), Gate
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa or AdjoiningID == libId_udg_WallOEDe or AdjoiningID == libId_udg_TowerOEUn or AdjoiningID == libId_udg_TowerOEDa or AdjoiningID == libId_udg_TowerOEDe) //Wall (Outer Edge), Tower (Outer Edge)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa or AdjoiningID == libId_udg_WallIEDe or AdjoiningID == libId_udg_TowerIEUn or AdjoiningID == libId_udg_TowerIEDa or AdjoiningID == libId_udg_TowerIEDe) //Wall (Inner Edge), Tower (Inner Edge)
                    endif
                elseif (Number == 2) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_BigTowerUn or AdjoiningID == libId_udg_BigTowerDa or AdjoiningID == libId_udg_BigTowerDe or AdjoiningID == libId_udg_DrumTowerUn or AdjoiningID == libId_udg_DrumTowerDa or AdjoiningID == libId_udg_DrumTowerDe or AdjoiningID == libId_udg_BigGateCl or AdjoiningID == libId_udg_BigGateOp or AdjoiningID == libId_udg_BigGateDa) //Big tower (no Edge), Drum tower (no Edge), Big gate
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_BigTowerOEUn or AdjoiningID == libId_udg_BigTowerOEDa or AdjoiningID == libId_udg_BigTowerOEDe or AdjoiningID == libId_udg_DrumTowerOEUn or AdjoiningID == libId_udg_DrumTowerOEDa or AdjoiningID == libId_udg_DrumTowerOEDe) //Big tower (Outer Edge), Drum tower (Outer Edge)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_BigTowerIEUn or AdjoiningID == libId_udg_BigTowerIEDa or AdjoiningID == libId_udg_BigTowerIEDe or AdjoiningID == libId_udg_DrumTowerIEUn or AdjoiningID == libId_udg_DrumTowerIEDa or AdjoiningID == libId_udg_DrumTowerIEDe) //Big tower (Inner Edge), Drum tower (Inner Edge)
                    endif
                endif
            elseif (Slot == 3) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_LadderWall) //Ladder (Wall)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_WallIEUn or BuildingID == libId_udg_WallIEDa or BuildingID == libId_udg_WallIEDe) then //Wall (Inner Edge)
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa or AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa or AdjoiningID == libId_udg_WallDe or AdjoiningID == libId_udg_WallOEDe or AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa or AdjoiningID == libId_udg_WallIEDe or AdjoiningID == libId_udg_TowerUn or AdjoiningID == libId_udg_TowerDa or AdjoiningID == libId_udg_TowerOEUn or AdjoiningID == libId_udg_TowerOEDa or AdjoiningID == libId_udg_TowerDe or AdjoiningID == libId_udg_TowerOEDe or AdjoiningID == libId_udg_GateCl or AdjoiningID == libId_udg_GateDa or AdjoiningID == libId_udg_GateOp) //Wall, Tower, Gate
                    endif
                elseif (Number == 2) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_BigTowerUn or AdjoiningID == libId_udg_BigTowerDa or AdjoiningID == libId_udg_BigTowerDe or AdjoiningID == libId_udg_BigTowerOEUn or AdjoiningID == libId_udg_BigTowerOEDa or AdjoiningID == libId_udg_BigTowerOEDe or AdjoiningID == libId_udg_BigTowerIEUn or AdjoiningID == libId_udg_BigTowerIEDa or AdjoiningID == libId_udg_BigTowerIEDe or AdjoiningID == libId_udg_DrumTowerUn or AdjoiningID == libId_udg_DrumTowerDa or AdjoiningID == libId_udg_DrumTowerDe or AdjoiningID == libId_udg_DrumTowerOEUn or AdjoiningID == libId_udg_DrumTowerOEDa or AdjoiningID == libId_udg_DrumTowerOEDe or AdjoiningID == libId_udg_DrumTowerIEUn or AdjoiningID == libId_udg_DrumTowerIEDa or AdjoiningID == libId_udg_DrumTowerIEDe or AdjoiningID == libId_udg_BigGateCl or AdjoiningID == libId_udg_BigGateOp or AdjoiningID == libId_udg_BigGateDa) //Big tower, Drum tower, Big gate
                    endif
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa or AdjoiningID == libId_udg_WallDe or AdjoiningID == libId_udg_TowerUn or AdjoiningID == libId_udg_TowerDa or AdjoiningID == libId_udg_TowerDe or AdjoiningID == libId_udg_GateCl or AdjoiningID == libId_udg_GateDa or AdjoiningID == libId_udg_GateOp) //Wall (no Edge), Tower (no Edge), Gate
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa or AdjoiningID == libId_udg_WallOEDe or AdjoiningID == libId_udg_TowerOEUn or AdjoiningID == libId_udg_TowerOEDa or AdjoiningID == libId_udg_TowerOEDe) //Wall (Outer Edge), Tower (Outer Edge)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa or AdjoiningID == libId_udg_WallIEDe or AdjoiningID == libId_udg_TowerIEUn or AdjoiningID == libId_udg_TowerIEDa or AdjoiningID == libId_udg_TowerIEDe) //Wall (Inner Edge), Tower (Inner Edge)
                    endif
                elseif (Number == 2) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_BigTowerUn or AdjoiningID == libId_udg_BigTowerDa or AdjoiningID == libId_udg_BigTowerDe or AdjoiningID == libId_udg_DrumTowerUn or AdjoiningID == libId_udg_DrumTowerDa or AdjoiningID == libId_udg_DrumTowerDe or AdjoiningID == libId_udg_BigGateCl or AdjoiningID == libId_udg_BigGateOp or AdjoiningID == libId_udg_BigGateDa) //Big tower (no Edge), Drum tower (no Edge), Big gate
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_BigTowerOEUn or AdjoiningID == libId_udg_BigTowerOEDa or AdjoiningID == libId_udg_BigTowerOEDe or AdjoiningID == libId_udg_DrumTowerOEUn or AdjoiningID == libId_udg_DrumTowerOEDa or AdjoiningID == libId_udg_DrumTowerOEDe) //Big tower (Outer Edge), Drum tower (Outer Edge)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_BigTowerIEUn or AdjoiningID == libId_udg_BigTowerIEDa or AdjoiningID == libId_udg_BigTowerIEDe or AdjoiningID == libId_udg_DrumTowerIEUn or AdjoiningID == libId_udg_DrumTowerIEDa or AdjoiningID == libId_udg_DrumTowerIEDe) //Big tower (Inner Edge), Drum tower (Inner Edge)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_PalisadeUn or BuildingID == libId_udg_PalisadeDa or BuildingID == libId_udg_PalisadeDe or BuildingID == libId_udg_PalisadeLadderUn or BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (no Edge)
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_PalisadeUn or AdjoiningID == libId_udg_PalisadeDa or AdjoiningID == libId_udg_PalisadeOEUn or AdjoiningID == libId_udg_PalisadeOEDa or AdjoiningID == libId_udg_PalisadeDe or AdjoiningID == libId_udg_PalisadeOEDe or AdjoiningID == libId_udg_PalisadeIEUn or AdjoiningID == libId_udg_PalisadeIEDa or AdjoiningID == libId_udg_PalisadeIEDe or AdjoiningID == libId_udg_PalisadeLadderUn or AdjoiningID == libId_udg_PalisadeLadderDa) //Palisade
                    endif
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_PalisadeUn or AdjoiningID == libId_udg_PalisadeDa or AdjoiningID == libId_udg_PalisadeDe or AdjoiningID == libId_udg_PalisadeLadderUn or AdjoiningID == libId_udg_PalisadeLadderDa) //Palisade (no Edge)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_PalisadeOEUn or AdjoiningID == libId_udg_PalisadeOEDa or AdjoiningID == libId_udg_PalisadeOEDe) //Palisade (Outer Edge)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_PalisadeIEUn or AdjoiningID == libId_udg_PalisadeIEDa or AdjoiningID == libId_udg_PalisadeIEDe) //Palisade (Inner Edge)
                    endif
                endif
            elseif (Slot == 3) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_LadderPalisade) //Ladder (Palisade)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_PalisadeOEUn or BuildingID == libId_udg_PalisadeOEDa or BuildingID == libId_udg_PalisadeOEDe) then //Palisade (Outer Edge)
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_PalisadeUn or AdjoiningID == libId_udg_PalisadeDa or AdjoiningID == libId_udg_PalisadeOEUn or AdjoiningID == libId_udg_PalisadeOEDa or AdjoiningID == libId_udg_PalisadeDe or AdjoiningID == libId_udg_PalisadeOEDe or AdjoiningID == libId_udg_PalisadeIEUn or AdjoiningID == libId_udg_PalisadeIEDa or AdjoiningID == libId_udg_PalisadeIEDe or AdjoiningID == libId_udg_PalisadeLadderUn or AdjoiningID == libId_udg_PalisadeLadderDa) //Palisade
                    endif
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_PalisadeUn or AdjoiningID == libId_udg_PalisadeDa or AdjoiningID == libId_udg_PalisadeDe or AdjoiningID == libId_udg_PalisadeLadderUn or AdjoiningID == libId_udg_PalisadeLadderDa) //Palisade (no Edge)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_PalisadeOEUn or AdjoiningID == libId_udg_PalisadeOEDa or AdjoiningID == libId_udg_PalisadeOEDe) //Palisade (Outer Edge)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_PalisadeIEUn or AdjoiningID == libId_udg_PalisadeIEDa or AdjoiningID == libId_udg_PalisadeIEDe) //Palisade (Inner Edge)
                    endif
                endif
            elseif (Slot == 3) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_LadderPalisade) //Ladder (Palisade)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_PalisadeIEUn or BuildingID == libId_udg_PalisadeIEDa or BuildingID == libId_udg_PalisadeIEDe) then //Palisade (Inner Edge)
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_PalisadeUn or AdjoiningID == libId_udg_PalisadeDa or AdjoiningID == libId_udg_PalisadeOEUn or AdjoiningID == libId_udg_PalisadeOEDa or AdjoiningID == libId_udg_PalisadeDe or AdjoiningID == libId_udg_PalisadeOEDe or AdjoiningID == libId_udg_PalisadeIEUn or AdjoiningID == libId_udg_PalisadeIEDa or AdjoiningID == libId_udg_PalisadeIEDe or AdjoiningID == libId_udg_PalisadeLadderUn or AdjoiningID == libId_udg_PalisadeLadderDa) //Palisade
                    endif
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_PalisadeUn or AdjoiningID == libId_udg_PalisadeDa or AdjoiningID == libId_udg_PalisadeDe or AdjoiningID == libId_udg_PalisadeLadderUn or AdjoiningID == libId_udg_PalisadeLadderDa) //Palisade (no Edge)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_PalisadeOEUn or AdjoiningID == libId_udg_PalisadeOEDa or AdjoiningID == libId_udg_PalisadeOEDe) //Palisade (Outer Edge)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_PalisadeIEUn or AdjoiningID == libId_udg_PalisadeIEDa or AdjoiningID == libId_udg_PalisadeIEDe) //Palisade (Inner Edge)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_TowerUn or BuildingID == libId_udg_TowerDa or BuildingID == libId_udg_TowerDe or BuildingID == libId_udg_GateCl or BuildingID == libId_udg_GateDa or BuildingID == libId_udg_GateOp) then //Tower (no Edge), Gate
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa or AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa or AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa) //Wall (no Destroyed)
                    endif
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa) //Wall (no Edge, no Destroyed)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa) //Wall (Outer Edge, no Destroyed)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa) //Wall (Inner Edge, no Destroyed)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_TowerOEUn or BuildingID == libId_udg_TowerOEDa or BuildingID == libId_udg_TowerOEDe) then //Tower (Outer Edge)
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa or AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa or AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa) //Wall (no Destroyed)
                    endif
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa) //Wall (no Edge, no Destroyed)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa) //Wall (Outer Edge, no Destroyed)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa) //Wall (Inner Edge, no Destroyed)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_TowerIEUn or BuildingID == libId_udg_TowerIEDa or BuildingID == libId_udg_TowerIEDe) then //Tower (Inner Edge)
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa or AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa or AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa) //Wall (no Destroyed)
                    endif
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa) //Wall (no Edge, no Destroyed)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa) //Wall (Outer Edge, no Destroyed)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa) //Wall (Inner Edge, no Destroyed)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerDa or BuildingID == libId_udg_BigTowerDe or BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerDa or BuildingID == libId_udg_DrumTowerDe or BuildingID == libId_udg_BigGateCl or BuildingID == libId_udg_BigGateOp or BuildingID == libId_udg_BigGateDa) then //Big tower (no Edge), Drum tower (no Edge), Big gate
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa or AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa or AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa) //Wall (no Destroyed)
                    endif
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa) //Wall (no Edge, no Destroyed)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa) //Wall (Outer Edge, no Destroyed)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa) //Wall (Inner Edge, no Destroyed)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerOEDa or BuildingID == libId_udg_BigTowerOEDe or BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerOEDa or BuildingID == libId_udg_DrumTowerOEDe) then //Big tower (Outer Edge), Drum tower (Outer Edge)
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa or AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa or AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa) //Wall (no Destroyed)
                    endif
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa) //Wall (no Edge, no Destroyed)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa) //Wall (Outer Edge, no Destroyed)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa) //Wall (Inner Edge, no Destroyed)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_BigTowerIEUn or BuildingID == libId_udg_BigTowerIEDa or BuildingID == libId_udg_BigTowerIEDe or BuildingID == libId_udg_DrumTowerIEUn or BuildingID == libId_udg_DrumTowerIEDa or BuildingID == libId_udg_DrumTowerIEDe) then //Big tower (Inner Edge), Drum tower (Inner Edge)
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa or AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa or AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa) //Wall (no Destroyed)
                    endif
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa) //Wall (no Edge, no Destroyed)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset - 90.00)) then
                        return (AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa) //Wall (Outer Edge, no Destroyed)
                    elseif (IsFortificationBuildingAdjoining_Function1(FacingOffset + 90.00)) then
                        return (AdjoiningID == libId_udg_WallIEUn or AdjoiningID == libId_udg_WallIEDa) //Wall (Inner Edge, no Destroyed)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_Stairs) then //Stairs
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa) //Wall (no Edge, no Destroyed)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_LadderWall) then //Ladder (Wall)
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_WallUn or AdjoiningID == libId_udg_WallDa or AdjoiningID == libId_udg_WallOEUn or AdjoiningID == libId_udg_WallOEDa) //Wall (no Edge, no Destroyed), Wall (Outer Edge, no Destroyed)
                    endif
                endif
            endif
        elseif (BuildingID == libId_udg_LadderPalisade) then //Ladder (Palisade)
            if (Slot == 1) then
                if (Number == 1) then
                    if (IsFortificationBuildingAdjoining_Function1(FacingOffset)) then
                        return (AdjoiningID == libId_udg_PalisadeUn or AdjoiningID == libId_udg_PalisadeDa or AdjoiningID == libId_udg_PalisadeOEUn or AdjoiningID == libId_udg_PalisadeOEDa or AdjoiningID == libId_udg_PalisadeLadderUn or AdjoiningID == libId_udg_PalisadeLadderDa) //Palisade (no Edge, no Destroyed), Palisade (Outer Edge, no Destroyed)
                    endif
                endif
            endif
        endif
        return false
    endfunction
   
    //Returns a rect of an adjoining building (Slot, Number) from a building with the given data (BuildingID, PosX, PosY, Facing):
    private function GetFortificationBuildingAdjoiningRect takes integer BuildingID, real PosX, real PosY, real Facing, integer Slot, integer Number returns rect
        local real RealTemp1
        local real RealTemp2
        local real Distance = 0.00
        local real Angle = 0.00
        local real HalfRectSizeX = 0.00
        local real HalfRectSizeY = 0.00
        if (BuildingID == libId_udg_WallUn or BuildingID == libId_udg_WallDa or BuildingID == libId_udg_WallDe) then //Wall (no Edge)
            if (Slot == 0) then
                set HalfRectSizeX = 64.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = -90.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                elseif (Number == 2) then
                    set Angle = -78.69
                    set Distance = 163.169
                    set HalfRectSizeX = 96.00
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    set Angle = 90.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                elseif (Number == 2) then
                    set Angle = 78.69
                    set Distance = 163.169
                    set HalfRectSizeX = 96.00
                endif
            elseif (Slot == 3) then
                if (Number == 1) then
                    set Angle = -161.565
                    set Distance = 101.193
                    set HalfRectSizeX = 96.00
                endif
            elseif (Slot == 4) then
                if (Number == 1) then
                    set Angle = 0.00
                    set Distance = 96.00
                    set HalfRectSizeX = 64.00
                endif
            endif
        elseif (BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallOEDa or BuildingID == libId_udg_WallOEDe) then //Wall (Outer Edge)
            if (Slot == 0) then
                set HalfRectSizeX = 64.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = 180.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                elseif (Number == 2) then
                    set Angle = -168.690
                    set Distance = 163.169
                    set HalfRectSizeX = 96.00
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    set Angle = 90.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                elseif (Number == 2) then
                    set Angle = 78.69
                    set Distance = 163.169
                    set HalfRectSizeX = 96.00
                endif
            elseif (Slot == 3) then
                if (Number == 1) then
                    set Angle = 0.00
                    set Distance = 96.00
                    set HalfRectSizeX = 64.00
                endif
            endif
        elseif (BuildingID == libId_udg_WallIEUn or BuildingID == libId_udg_WallIEDa or BuildingID == libId_udg_WallIEDe) then //Wall (Inner Edge)
            if (Slot == 0) then
                set HalfRectSizeX = 64.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = 0.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                elseif (Number == 2) then
                    set Angle = 11.31
                    set Distance = 163.169
                    set HalfRectSizeX = 96.00
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    set Angle = 90.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                elseif (Number == 2) then
                    set Angle = 78.69
                    set Distance = 163.169
                    set HalfRectSizeX = 96.00
                endif
            endif
        elseif (BuildingID == libId_udg_PalisadeUn or BuildingID == libId_udg_PalisadeDa or BuildingID == libId_udg_PalisadeDe or BuildingID == libId_udg_PalisadeLadderUn or BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (no Edge)
            if (Slot == 0) then
                set HalfRectSizeX = 64.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = -90.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    set Angle = 90.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                endif
            elseif (Slot == 3) then
                if (Number == 1) then
                    set Angle = 0.00
                    set Distance = 96.00
                    set HalfRectSizeX = 64.00
                endif
            endif
        elseif (BuildingID == libId_udg_PalisadeOEUn or BuildingID == libId_udg_PalisadeOEDa or BuildingID == libId_udg_PalisadeOEDe) then //Palisade (Outer Edge)
            if (Slot == 0) then
                set HalfRectSizeX = 64.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = 180.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    set Angle = 90.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                endif
            elseif (Slot == 3) then
                if (Number == 1) then
                    set Angle = 0.00
                    set Distance = 96.00
                    set HalfRectSizeX = 64.00
                endif
            endif
        elseif (BuildingID == libId_udg_PalisadeIEUn or BuildingID == libId_udg_PalisadeIEDa or BuildingID == libId_udg_PalisadeIEDe) then //Palisade (Inner Edge)
            if (Slot == 0) then
                set HalfRectSizeX = 64.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = 0.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    set Angle = 90.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                endif
            endif
        elseif (BuildingID == libId_udg_TowerUn or BuildingID == libId_udg_TowerDa or BuildingID == libId_udg_TowerDe or BuildingID == libId_udg_GateCl or BuildingID == libId_udg_GateDa or BuildingID == libId_udg_GateOp) then //Tower (no Edge), Gate
            if (Slot == 0) then
                set HalfRectSizeX = 64.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = -90.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    set Angle = 90.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                endif
            endif
        elseif (BuildingID == libId_udg_TowerOEUn or BuildingID == libId_udg_TowerOEDa or BuildingID == libId_udg_TowerOEDe) then //Tower (Outer Edge)
            if (Slot == 0) then
                set HalfRectSizeX = 64.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = 180.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    set Angle = 90.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                endif
            endif
        elseif (BuildingID == libId_udg_TowerIEUn or BuildingID == libId_udg_TowerIEDa or BuildingID == libId_udg_TowerIEDe) then //Tower (Inner Edge)
            if (Slot == 0) then
                set HalfRectSizeX = 64.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = 0.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    set Angle = 90.00
                    set Distance = 128.00
                    set HalfRectSizeX = 64.00
                endif
            endif
        elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerDa or BuildingID == libId_udg_BigTowerDe or BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerDa or BuildingID == libId_udg_DrumTowerDe or BuildingID == libId_udg_BigGateCl or BuildingID == libId_udg_BigGateOp or BuildingID == libId_udg_BigGateDa) then //Big tower (no Edge), Drum tower (no Edge), Big gate
            if (Slot == 0) then
                set HalfRectSizeX = 96.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = -101.31
                    set Distance = 163.169
                    set HalfRectSizeX = 64.00
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    set Angle = 101.31
                    set Distance = 163.169
                    set HalfRectSizeX = 64.00
                endif
            endif
        elseif (BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerOEDa or BuildingID == libId_udg_BigTowerOEDe or BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerOEDa or BuildingID == libId_udg_DrumTowerOEDe) then //Big tower (Outer Edge), Drum tower (Outer Edge)
            if (Slot == 0) then
                set HalfRectSizeX = 96.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = 168.690
                    set Distance = 163.169
                    set HalfRectSizeX = 64.00
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    set Angle = 101.31
                    set Distance = 163.169
                    set HalfRectSizeX = 64.00
                endif
            endif
        elseif (BuildingID == libId_udg_BigTowerIEUn or BuildingID == libId_udg_BigTowerIEDa or BuildingID == libId_udg_BigTowerIEDe or BuildingID == libId_udg_DrumTowerIEUn or BuildingID == libId_udg_DrumTowerIEDa or BuildingID == libId_udg_DrumTowerIEDe) then //Big tower (Inner Edge), Drum tower (Inner Edge)
            if (Slot == 0) then
                set HalfRectSizeX = 96.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = -11.31
                    set Distance = 163.169
                    set HalfRectSizeX = 64.00
                endif
            elseif (Slot == 2) then
                if (Number == 1) then
                    set Angle = 101.31
                    set Distance = 163.169
                    set HalfRectSizeX = 64.00
                endif
            endif
        elseif (BuildingID == libId_udg_Stairs) then //Stairs
            if (Slot == 0) then
                set HalfRectSizeX = 32.00
                set HalfRectSizeY = 96.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = 18.435
                    set Distance = 101.193
                    set HalfRectSizeX = 64.00
                endif
            endif
        elseif (BuildingID == libId_udg_LadderWall) then //Ladder (Wall)
            if (Slot == 0) then
                set HalfRectSizeX = 32.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = 180.00
                    set Distance = 96.00
                    set HalfRectSizeX = 64.00
                endif
            endif
        elseif (BuildingID == libId_udg_LadderPalisade) then //Ladder (Palisade)
            if (Slot == 0) then
                set HalfRectSizeX = 32.00
            elseif (Slot == 1) then
                if (Number == 1) then
                    set Angle = 180.00
                    set Distance = 96.00
                    set HalfRectSizeX = 64.00
                endif
            endif
        endif
        //Process data to rect:
        if (HalfRectSizeX == 0.00) then
            return null
        elseif (HalfRectSizeY == 0.00) then
            set HalfRectSizeY = HalfRectSizeX
        endif
        set RealTemp1 = Facing + Angle
        if (RealTemp1 >= 360.00) then
            set RealTemp1 = RealTemp1 - 360.00
        elseif (RealTemp1 < 0.00) then
            set RealTemp1 = RealTemp1 + 360.00
        endif
        if (RealTemp1 == 90.00 or RealTemp1 == 270.00) then
            set RealTemp2 = HalfRectSizeX
            set HalfRectSizeX = HalfRectSizeY
            set HalfRectSizeY = RealTemp2
        endif
        set RealTemp2 = PosY + Distance * Sin(RealTemp1 * bj_DEGTORAD)
        set RealTemp1 = PosX + Distance * Cos(RealTemp1 * bj_DEGTORAD)
        //Check if target rect is in world bounds:
        if(GetRectMinX(bj_mapInitialPlayableArea) > RealTemp1 - HalfRectSizeX or GetRectMinY(bj_mapInitialPlayableArea) > RealTemp2 - HalfRectSizeY or GetRectMaxX(bj_mapInitialPlayableArea) < RealTemp1 + HalfRectSizeX or GetRectMaxY(bj_mapInitialPlayableArea) < RealTemp2 + HalfRectSizeY) then
            return null
        endif
        return Rect(RealTemp1 - HalfRectSizeX, RealTemp2 - HalfRectSizeY, RealTemp1 + HalfRectSizeX, RealTemp2 + HalfRectSizeY)
    endfunction
   
    //Returns if the building type has a small pathing (smaller than 4 pixels in one direction):
    private function HasSmallPathing takes integer BuildingID returns boolean
        if (BuildingID == libId_udg_Stairs) then //Stairs
            return true
        elseif (BuildingID == libId_udg_BuildingSiteStairs) then //Building site (Stairs)
            return true
        elseif (BuildingID == libId_udg_LadderWall) then //Ladder (Wall)
            return true
        elseif (BuildingID == libId_udg_LadderPalisade) then //Ladder (Palisade)
            return true
        elseif (BuildingID == libId_udg_BuildingSiteLadder) then //Building site (Ladder)
            return true
        elseif (BuildingID == libId_udg_Barricade) then //Barricade
            return true
        elseif (BuildingID == libId_udg_BuildingSiteTiny) then //Building site (tiny)
            return true
        endif
        return false
    endfunction
   
    //Returns the opened/closed building type or opening/closing duration of the given gate dummy unit:
    private function GetGateInfo takes integer BuildingID, integer Number returns integer
        if (BuildingID == libId_udg_GateClDu) then //Gate (Closed) (Dummy)
            if (Number == 1) then
                return libId_udg_GateCl //Gate (Closed)
            elseif (Number == 2) then
                return 8 //Gate closing duration
            endif
        elseif (BuildingID == libId_udg_GateOpDu) then //Gate (Opened) (Dummy)
            if (Number == 1) then
                return libId_udg_GateOp //Gate (Opened)
            elseif (Number == 2) then
                return 8 //Gate opening duration
            endif
        elseif (BuildingID == libId_udg_BigGateClDu) then //Big gate (Closed) (Dummy)
            if (Number == 1) then
                return libId_udg_BigGateCl //Big gate (Closed)
            elseif (Number == 2) then
                return 12 //Gate closing duration
            endif
        elseif (BuildingID == libId_udg_BigGateOpDu) then //Big gate (Opened) (Dummy)
            if (Number == 1) then
                return libId_udg_BigGateOp //Big gate (Opened)
            elseif (Number == 2) then
                return 12 //Gate opening duration
            endif
        elseif (BuildingID == libId_udg_PalisadeGateClDu) then //Palisade gate (Opened) (Dummy)
            if (Number == 1) then
                return libId_udg_PalisadeGateCl //Palisade gate (Closed)
            elseif (Number == 2) then
                return 4 //Gate closing duration
            endif
        elseif (BuildingID == libId_udg_PalisadeGateOpDu) then //Palisade gate (Opened) (Dummy)
            if (Number == 1) then
                return libId_udg_PalisadeGateOp //Palisade gate (Opened)
            elseif (Number == 2) then
                return 4 //Gate opening duration
            endif
        endif
        return 0
    endfunction
   
    //Returns info to an addition (Number) of the given addition starter (CasterID):
    private function GetFortificationAdditionInfo takes integer CasterID, integer TargetID, integer Number returns integer
        if (CasterID == libId_udg_WallUn or CasterID == libId_udg_WallDa) then
            if (Number == 1) then
                return libId_udg_BuildingSiteStairs //Building site (Stairs)
            elseif (Number == 2) then
                return libId_udg_Stairs //Stairs
            endif
        elseif (CasterID == libId_udg_Peon) then //Peon
            if (Number == 1) then
                return libId_udg_BuildingSiteLadder //Building site (Ladder)
            elseif (Number == 2) then
                if (TargetID == libId_udg_WallUn or TargetID == libId_udg_WallDa or TargetID == libId_udg_WallOEUn or TargetID == libId_udg_WallOEDa) then //Wall (no Edge), Wall (Outer Edge)
                    return libId_udg_LadderWall //Ladder (Wall)
                elseif (TargetID == libId_udg_PalisadeUn or TargetID == libId_udg_PalisadeDa or TargetID == libId_udg_PalisadeOEUn or TargetID == libId_udg_PalisadeOEDa or TargetID == libId_udg_PalisadeLadderUn or TargetID == libId_udg_PalisadeLadderDa) then //Palisade (no Edge), Palisade (Outer Edge)
                    return libId_udg_LadderPalisade //Ladder (Palisade)
                endif
            elseif (Number == 3) then
                return libId_udg_SiegeLadderAttachment //Siege Ladder (Attachment)
            endif
        elseif (CasterID == libId_udg_PalisadeUn) then
            if (Number == 2) then
                return libId_udg_PalisadeLadderUn //Palisade (Ladder) (Undamaged)
            endif
        elseif (CasterID == libId_udg_PalisadeDa) then
            if (Number == 2) then
                return libId_udg_PalisadeLadderDa //Palisade (Ladder) (Damaged)
            endif
        endif
        return 0
    endfunction
   
    //Returns the addition path checker position (Number, ReturnX) to a building with the given data (BuildingID, PosX, PosY, Facing):
    private function GetFortificationAdditionPathCheckerPos takes integer BuildingSiteID, real PosX, real PosY, real Facing, integer Number, boolean ReturnX returns real
        local real RealTemp1 = PosY
        if (ReturnX) then
            set RealTemp1 = PosX
        endif
        if (BuildingSiteID == libId_udg_BuildingSiteStairs) then //Building site (Stairs)
            if (Number == 1) then
                if (ReturnX and (Facing == 90.00 or Facing == 270.00)) then
                    return RealTemp1 + 64.00
                elseif (ReturnX == false and (Facing == 0.00 or Facing == 180.00)) then
                    return RealTemp1 + 64.00
                endif
                return RealTemp1
            elseif (Number == 2) then
                return RealTemp1
            elseif (Number == 3) then
                if (ReturnX and (Facing == 90.00 or Facing == 270.00)) then
                    return RealTemp1 - 64.00
                elseif (ReturnX == false and (Facing == 0.00 or Facing == 180.00)) then
                    return RealTemp1 - 64.00
                endif
                return RealTemp1
            endif
        elseif (BuildingSiteID == libId_udg_BuildingSiteLadder) then //Building site (Ladder)
            if (Number == 1) then
                if (ReturnX and (Facing == 90.00 or Facing == 270.00)) then
                    return RealTemp1 + 32.00
                elseif (ReturnX == false and (Facing == 0.00 or Facing == 180.00)) then
                    return RealTemp1 + 32.00
                endif
                return RealTemp1
            elseif (Number == 2) then
                if (ReturnX and (Facing == 90.00 or Facing == 270.00)) then
                    return RealTemp1 - 32.00
                elseif (ReturnX == false and (Facing == 0.00 or Facing == 180.00)) then
                    return RealTemp1 - 32.00
                endif
                return RealTemp1
            endif
        endif
        return 99999.99
    endfunction
   
    //Checks if the given unit is allowed to move:
    private function IsUnitWithoutMovement takes integer UnitID returns boolean
        if (UnitID == libId_udg_Ballista) then //Ballista
            return true
        endif
        return false
    endfunction
   
    //-------------
    //PRIVATE PART:
    //-------------
   
    //Rounds (up or down) in the direction of minimal deviation:
    private function Round takes real Dividend, real Divisor returns real
        local real RealTemp1 = 0.00
        if (Divisor > 0.00) then
            set RealTemp1 = I2R(R2I(Dividend / Divisor)) * Divisor
            if (Dividend - RealTemp1 > 0.5 * Divisor) then
                return RealTemp1 + Divisor
            elseif (Dividend - RealTemp1 < (-0.5) * Divisor) then
                return RealTemp1 - Divisor
            endif
        endif
        return RealTemp1
    endfunction

    private function AdjustOrthogonalAngle 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
        elseif (450.00 - Input <= MaxResidual and 450.00 - Input >= (-1) * MaxResidual) then
            return 90.00
        elseif (540.00 - Input <= MaxResidual and 540.00 - Input >= (-1) * MaxResidual) then
            return 180.00
        elseif (630.00 - Input <= MaxResidual and 630.00 - Input >= (-1) * MaxResidual) then
            return 270.00
        elseif (720.00 - Input <= MaxResidual and 720.00 - Input >= (-1) * MaxResidual) then
            return 0.00
        endif
        return Input
    endfunction
   
    //------------
    //PUBLIC PART:
    //------------
   
    globals
        public boolean udg_InitFinished = false
    endglobals

    //-----------------
    //DECLARATION PART:
    //-----------------
   
    globals
        private constant integer udg_MaxWalkBuildingsP = udg_MaxWalkBuildings + 1
        private constant integer udg_CountPlayersP = udg_CountPlayers + 1
    endglobals
   
    private struct WalkBuilding
        public integer BuildingObjectNumber = 0
        public destructable Destructable = null
        public boolean UnderConstruction = false
       
        public method remove takes nothing returns nothing
            call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, 0)
            set this.BuildingObjectNumber = 0
            call RemoveDestructable(this.Destructable)
            set this.Destructable = null
            set this.UnderConstruction = false
            call this.destroy()
        endmethod

        //--------------
        //OTHER METHODS:
        //--------------
       
        public method New takes unit Building, integer WalkBuildingNumber returns nothing
            set this.BuildingObjectNumber = libUnitDat_GetObjectNumber(Building, true)
            call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, WalkBuildingNumber)
            set this.Destructable = CreateDestructable(GetWalkDestructableID(GetUnitTypeId(Building), 0), GetUnitX(Building), GetUnitY(Building), AdjustOrthogonalAngle(GetUnitFacing(Building)), 1.00, 0)
            set this.UnderConstruction = false
        endmethod
       
        public method AdjustSystemNumber takes integer NewSystemNumber returns nothing
            call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, NewSystemNumber)
        endmethod
    endstruct
   
    globals
        private integer udg_WalkBuildingsCount = 0
        private WalkBuilding array udg_WalkBuildings [udg_MaxWalkBuildingsP]
        private boolean udg_RepositionAllBuildingsRunning = false
        private boolean udg_RepositionAllBuildingsRestart = false
        private integer udg_AdjustPathingForWalkBuildingGroup_Counter = 0
        private constant trigger gg_trg_GateClosingOrOpeningStarts = CreateTrigger()
        private constant trigger gg_trg_FortificationDies = CreateTrigger()
        private constant trigger gg_trg_FortificationBuildsFinish = CreateTrigger()
        private constant trigger gg_trg_AddStairs = CreateTrigger()
        private constant trigger gg_trg_AddLadders = CreateTrigger()
        private constant trigger gg_trg_UseSiegeLadder = CreateTrigger()
        private constant trigger gg_trg_AutoUseSiegeLadder = CreateTrigger()
        private constant trigger gg_trg_SmallPathingBuildsStart = CreateTrigger()
        private constant trigger gg_trg_DisableMovementFinish = CreateTrigger()
        private constant trigger gg_trg_SmartOrderOnWalkableBuilding = CreateTrigger()
    endglobals
   
    //-------------
    //PRIVATE PART:
    //-------------
   
    private function AddWalkBuilding takes unit Building returns nothing
        set udg_WalkBuildingsCount = udg_WalkBuildingsCount + 1
        set udg_WalkBuildings[udg_WalkBuildingsCount] = WalkBuilding.create()
        if (udg_WalkBuildings[udg_WalkBuildingsCount] == 0) then
            call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: WalkBuilding struct cap exceeded")
            return
        endif
        call udg_WalkBuildings[udg_WalkBuildingsCount].New(Building, udg_WalkBuildingsCount)
    endfunction
   
    private function RemoveWalkBuilding takes unit Building returns nothing
        local integer WalkBuildingNumber = libUnitDat_GetSystemNumberOfUnit(Building, udg_SystemSlot)
        if (WalkBuildingNumber > 0) then
            call udg_WalkBuildings[WalkBuildingNumber].remove()
            set udg_WalkBuildings[WalkBuildingNumber] = udg_WalkBuildings[udg_WalkBuildingsCount]
            call udg_WalkBuildings[WalkBuildingNumber].AdjustSystemNumber(WalkBuildingNumber)
            set udg_WalkBuildings[udg_WalkBuildingsCount] = 0
            set udg_WalkBuildingsCount = udg_WalkBuildingsCount - 1
        endif
    endfunction

    private function GetAdjoiningFortificationBuildings_Filter1 takes nothing returns boolean
        return (IsFortificationBuilding(GetUnitTypeId(GetFilterUnit())))
    endfunction
    private function GetAdjoiningFortificationBuildings takes unit Building returns group
        local rect RectTemp1
        local boolexpr Filter1 = null
        local unit UnitTemp1
        local unit UnitTemp2
        local group GroupTemp1 = CreateGroup()
        local group UncheckedUnits = CreateGroup()
        local group ReturnGroup = CreateGroup()
        local integer IntTemp1
        local integer IntTemp2
        local integer IntLoop1
        local integer IntLoop2
        local real RealTemp1
        local real RealTemp2
        local real RealTemp3
        call GroupAddUnit(UncheckedUnits, Building)
        call GroupAddUnit(ReturnGroup, Building)
        loop
            set UnitTemp1 = FirstOfGroup(UncheckedUnits)
            exitwhen UnitTemp1 == null
            call GroupRemoveUnit(UncheckedUnits, UnitTemp1)
            set IntTemp1 = GetUnitTypeId(UnitTemp1)
            set IntTemp2 = GetFortificationBuildingAdjoiningSlots(IntTemp1)
            set RealTemp1 = GetUnitX(UnitTemp1)
            set RealTemp2 = GetUnitY(UnitTemp1)
            set RealTemp3 = AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1))
            set IntLoop2 = 1
            loop
                exitwhen IntLoop2 > IntTemp2
                set IntLoop1 = 1
                loop
                    set RectTemp1 = GetFortificationBuildingAdjoiningRect(IntTemp1, RealTemp1, RealTemp2, RealTemp3, IntLoop2, IntLoop1)
                    exitwhen RectTemp1 == null
                    call GroupClear(GroupTemp1)
                    if (Filter1 == null) then
                        set Filter1 = Condition(function GetAdjoiningFortificationBuildings_Filter1)
                    endif
                    call GroupEnumUnitsInRect(GroupTemp1, RectTemp1, Filter1)
                    call RemoveRect(RectTemp1)
                    call GroupRemoveUnit(GroupTemp1, UnitTemp1)
                    loop
                        set UnitTemp2 = FirstOfGroup(GroupTemp1)
                        exitwhen UnitTemp2 == null
                        if (GetUnitState(UnitTemp2, UNIT_STATE_LIFE) >= 1.00) then
                            exitwhen IsFortificationBuildingAdjoining(IntTemp1, IntLoop2, IntLoop1, RealTemp3, UnitTemp2)
                        endif
                        call GroupRemoveUnit(GroupTemp1, UnitTemp2)
                    endloop
                    exitwhen UnitTemp2 != null
                    set IntLoop1 = IntLoop1 + 1
                endloop
                if (UnitTemp2 != null and IsUnitInGroup(UnitTemp2, ReturnGroup) == false) then
                    call GroupAddUnit(UncheckedUnits, UnitTemp2)
                    call GroupAddUnit(ReturnGroup, UnitTemp2)
                endif
                set IntLoop2 = IntLoop2 + 1
            endloop
        endloop
        //Anti-Memory-Leak:
        call DestroyGroup(GroupTemp1)
        set GroupTemp1 = null
        call DestroyGroup(UncheckedUnits)
        set UncheckedUnits = null
        if (Filter1 != null) then
            call DestroyBoolExpr(Filter1)
            set Filter1 = null
        endif
        set RectTemp1 = null
        set UnitTemp1 = null
        set UnitTemp2 = null
        //-----------------
        return ReturnGroup
    endfunction
   
    private function GetDirectAdjoiningFortificationBuildings_Filter1 takes nothing returns boolean
        return (IsFortificationBuilding(GetUnitTypeId(GetFilterUnit())))
    endfunction
    private function GetDirectAdjoiningFortificationBuildings takes unit Building, boolean IncludeGivenBuilding returns group
        local rect RectTemp1
        local boolexpr Filter1 = null
        local group GroupTemp1 = CreateGroup()
        local group GroupTemp2 = CreateGroup()
        local unit UnitTemp1
        local real PosX = GetUnitX(Building)
        local real PosY = GetUnitY(Building)
        local real Facing = AdjustOrthogonalAngle(GetUnitFacing(Building))
        local integer BuildingID = GetUnitTypeId(Building)
        local integer IntTemp1 = GetFortificationBuildingAdjoiningSlots(BuildingID)
        local integer IntLoop1 = 1
        local integer IntLoop2
        loop
            exitwhen IntLoop1 > IntTemp1
            set IntLoop2 = 1
            loop
                set RectTemp1 = GetFortificationBuildingAdjoiningRect(BuildingID, PosX, PosY, Facing, IntLoop1, IntLoop2)
                exitwhen RectTemp1 == null
                call GroupClear(GroupTemp1)
                if (Filter1 == null) then
                    set Filter1 = Condition(function GetDirectAdjoiningFortificationBuildings_Filter1)
                endif
                call GroupEnumUnitsInRect(GroupTemp1, RectTemp1, Filter1)
                call RemoveRect(RectTemp1)
                loop
                    set UnitTemp1 = FirstOfGroup(GroupTemp1)
                    exitwhen UnitTemp1 == null
                    if (GetUnitState(UnitTemp1, UNIT_STATE_LIFE) >= 1.00) then
                        exitwhen IsFortificationBuildingAdjoining(BuildingID, IntLoop1, IntLoop2, Facing, UnitTemp1)
                    endif
                    call GroupRemoveUnit(GroupTemp1, UnitTemp1)
                endloop
                exitwhen UnitTemp1 != null
                set IntLoop2 = IntLoop2 + 1
            endloop
            call GroupAddUnit(GroupTemp2, UnitTemp1)
            set IntLoop1 = IntLoop1 + 1
        endloop
        if (IncludeGivenBuilding) then
            call GroupAddUnit(GroupTemp2, Building)
        endif
        //Anti-Memory-Leak:
        call DestroyGroup(GroupTemp1)
        set GroupTemp1 = null
        if (Filter1 != null) then
            call DestroyBoolExpr(Filter1)
            set Filter1 = null
        endif
        call RemoveRect(RectTemp1)
        set RectTemp1 = null
        set UnitTemp1 = null
        //-----------------
        return GroupTemp2
    endfunction

    private function GetAdjoiningFortificationBuildingBySlot takes integer BuildingID, real PosX, real PosY, real Facing, integer Slot, integer CounterAddition returns unit
        local rect RectTemp1
        local group GroupTemp1 = CreateGroup()
        local unit ReturnUnit
        local integer IntLoop1 = 1
        loop
            set RectTemp1 = GetFortificationBuildingAdjoiningRect(BuildingID, PosX, PosY, Facing, Slot, IntLoop1)
            set udg_AdjustPathingForWalkBuildingGroup_Counter = udg_AdjustPathingForWalkBuildingGroup_Counter + CounterAddition
            exitwhen RectTemp1 == null
            call GroupClear(GroupTemp1)
            call GroupEnumUnitsInRect(GroupTemp1, RectTemp1, null)
            call RemoveRect(RectTemp1)
            loop
                set ReturnUnit = FirstOfGroup(GroupTemp1)
                exitwhen ReturnUnit == null
                set udg_AdjustPathingForWalkBuildingGroup_Counter = udg_AdjustPathingForWalkBuildingGroup_Counter + CounterAddition
                if (IsFortificationBuilding(GetUnitTypeId(ReturnUnit)) and GetUnitState(ReturnUnit, UNIT_STATE_LIFE) >= 1.00) then
                    set udg_AdjustPathingForWalkBuildingGroup_Counter = udg_AdjustPathingForWalkBuildingGroup_Counter + CounterAddition
                    exitwhen IsFortificationBuildingAdjoining(BuildingID, Slot, IntLoop1, Facing, ReturnUnit)
                endif
                call GroupRemoveUnit(GroupTemp1, ReturnUnit)
            endloop
            exitwhen ReturnUnit != null
            set IntLoop1 = IntLoop1 + 1
        endloop
        //Anti-Memory-Leak:
        call DestroyGroup(GroupTemp1)
        set GroupTemp1 = null
        call RemoveRect(RectTemp1)
        set RectTemp1 = null
        //-----------------
        return ReturnUnit
    endfunction
   
    private function RepositionBuilding takes unit Building returns nothing
        local integer IntLoop1 = 1
        //Hide all walk destructables:
        loop
            exitwhen IntLoop1 > udg_WalkBuildingsCount
            call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, false)
            set IntLoop1 = IntLoop1 + 1
        endloop
        call ShowUnit(Building, false)
        call ShowUnit(Building, true)
        //Show all walk destructables:
        set IntLoop1 = 1
        loop
            exitwhen IntLoop1 > udg_WalkBuildingsCount
            call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, true)
            set IntLoop1 = IntLoop1 + 1
        endloop
    endfunction
   
    private function RepositionBuildings takes group Buildings returns nothing
        local unit UnitTemp1
        local integer IntLoop1 = 1
        //Hide all walk destructables:
        loop
            exitwhen IntLoop1 > udg_WalkBuildingsCount
            call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, false)
            set IntLoop1 = IntLoop1 + 1
        endloop
        //Reposition buildings:
        loop
            set UnitTemp1 = FirstOfGroup(Buildings)
            exitwhen UnitTemp1 == null
            call ShowUnit(UnitTemp1, false)
            call ShowUnit(UnitTemp1, true)
            call GroupRemoveUnit(Buildings, UnitTemp1)
        endloop
        call DestroyGroup(Buildings)
        //Show all walk destructables:
        set IntLoop1 = 1
        loop
            exitwhen IntLoop1 > udg_WalkBuildingsCount
            call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, true)
            set IntLoop1 = IntLoop1 + 1
        endloop
        //Anti-Memory-Leak:
        set UnitTemp1 = null
    endfunction
   
    private function RepositionAllBuildings_Filter1 takes nothing returns boolean
        return (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE))
    endfunction
    private function RepositionAllBuildings_Filter2 takes nothing returns boolean
        return (IsFortificationBuilding(GetUnitTypeId(GetFilterUnit())))
    endfunction
    private function RepositionAllBuildings takes nothing returns nothing
        local boolexpr Filter1
        local group GroupTemp1 = CreateGroup()
        local group GroupTemp2 = CreateGroup()
        local unit UnitTemp1
        local integer IntLoop1
        local integer IntLoop2 = 0
        if (udg_RepositionOnlyFortifications <= 2) then
            set Filter1 = Condition(function RepositionAllBuildings_Filter1)
        else
            set Filter1 = Condition(function RepositionAllBuildings_Filter2)
        endif
        set udg_RepositionAllBuildingsRunning = true
        loop
            set udg_RepositionAllBuildingsRestart = false
            call GroupClear(GroupTemp1)
            call GroupEnumUnitsInRect(GroupTemp1, bj_mapInitialPlayableArea, Filter1)
            //Hide all walk destructables:
            set IntLoop1 = 1
            loop
                exitwhen IntLoop1 > udg_WalkBuildingsCount
                call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, false)
                set IntLoop1 = IntLoop1 + 1
            endloop
            //Reposition buildings:
            call SyncSelections()
            set IntLoop1 = 1
            loop
                exitwhen IntLoop1 > udg_CountPlayers
                if (GetPlayerController(Player(IntLoop1 - 1)) == MAP_CONTROL_USER) then
                    call GroupClear(GroupTemp2)
                    call GroupEnumUnitsSelected(GroupTemp2, Player(IntLoop1 - 1), Filter1)
                    loop
                        set UnitTemp1 = FirstOfGroup(GroupTemp2)
                        exitwhen UnitTemp1 == null
                        call ShowUnit(UnitTemp1, false)
                        call ShowUnit(UnitTemp1, true)
                        call GroupRemoveUnit(GroupTemp1, UnitTemp1)
                        call GroupRemoveUnit(GroupTemp2, UnitTemp1)
                        if (GetLocalPlayer() == Player(IntLoop1 - 1)) then
                            // Use only local code (no net traffic) within this block to avoid desyncs.
                            call SelectUnit(UnitTemp1, true)
                        endif
                        set IntLoop2 = IntLoop2 + 1
                    endloop
                endif
                set IntLoop1 = IntLoop1 + 1
            endloop
            loop
                //Reposition buildings:
                loop
                    exitwhen udg_RepositionAllBuildingsRestart
                    set UnitTemp1 = FirstOfGroup(GroupTemp1)
                    exitwhen UnitTemp1 == null
                    call ShowUnit(UnitTemp1, false)
                    call ShowUnit(UnitTemp1, true)
                    call GroupRemoveUnit(GroupTemp1, UnitTemp1)
                    exitwhen IntLoop2 >= 40
                    set IntLoop2 = IntLoop2 + 1
                endloop
                set IntLoop2 = 0
                //Show all walk destructables:
                set IntLoop1 = 1
                loop
                    exitwhen IntLoop1 > udg_WalkBuildingsCount
                    call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, true)
                    set IntLoop1 = IntLoop1 + 1
                endloop
                exitwhen udg_RepositionAllBuildingsRestart
                exitwhen UnitTemp1 == null
                call TriggerSleepAction(0.01)
                //Hide all walk destructables:
                set IntLoop1 = 1
                loop
                    exitwhen IntLoop1 > udg_WalkBuildingsCount
                    call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, false)
                    set IntLoop1 = IntLoop1 + 1
                endloop
            endloop
            exitwhen udg_RepositionAllBuildingsRestart == false
            call TriggerSleepAction(0.01)
        endloop
        set udg_RepositionAllBuildingsRunning = false
        //Anti-Memory-Leak:
        call DestroyGroup(GroupTemp1)
        set GroupTemp1 = null
        call DestroyGroup(GroupTemp2)
        set GroupTemp2 = null
        call DestroyBoolExpr(Filter1)
        set Filter1 = null
        set UnitTemp1 = null
    endfunction
   
    private function RecreateWalkDestructables takes group Buildings returns nothing
        local unit UnitTemp1
        local integer array IntArrayTemp1
        local integer IntLoop1
        //Remove all walk destructables:
        set IntLoop1 = 1
        loop
            exitwhen IntLoop1 > udg_WalkBuildingsCount
            if (IsUnitInGroup(libUnitDat_GetUnit(udg_WalkBuildings[IntLoop1].BuildingObjectNumber), Buildings)) then
                set IntArrayTemp1[IntLoop1] = GetDestructableTypeId(udg_WalkBuildings[IntLoop1].Destructable)
                call RemoveDestructable(udg_WalkBuildings[IntLoop1].Destructable)
            else
                set IntArrayTemp1[IntLoop1] = 0
            endif
            set IntLoop1 = IntLoop1 + 1
        endloop
        //Recreate all walk destructables:
        set IntLoop1 = 1
        loop
            exitwhen IntLoop1 > udg_WalkBuildingsCount
            if (IntArrayTemp1[IntLoop1] != 0) then
                set UnitTemp1 = libUnitDat_GetUnit(udg_WalkBuildings[IntLoop1].BuildingObjectNumber)
                set udg_WalkBuildings[IntLoop1].Destructable = CreateDestructable(IntArrayTemp1[IntLoop1], GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1)), 1.00, 0)
            endif
            set IntLoop1 = IntLoop1 + 1
        endloop
        //Anti-Memory-Leak:
        call DestroyGroup(Buildings)
        set UnitTemp1 = null
    endfunction
   
    private function RaiseBuildingsOnSameHeight_Function1 takes integer Number, integer Type, integer ReturnValue returns real
        if (Type == 1) then
            if (Number == 1) then
                if (ReturnValue == 3) then
                    return 1.00
                endif
            elseif (Number == 2) then
                if (ReturnValue == 1) then
                    return 128.00
                elseif (ReturnValue == 3) then
                    return udg_HeightAdjustSmooth
                endif
            elseif (Number == 3) then
                if (ReturnValue == 2) then
                    return 128.00
                elseif (ReturnValue == 3) then
                    return udg_HeightAdjustSmooth
                endif
            elseif (Number == 4) then
                if (ReturnValue == 1) then
                    return -128.00
                elseif (ReturnValue == 3) then
                    return udg_HeightAdjustSmooth
                endif
            elseif (Number == 5) then
                if (ReturnValue == 2) then
                    return -128.00
                elseif (ReturnValue == 3) then
                    return udg_HeightAdjustSmooth
                endif
            endif
        elseif (Type == 2) then
            if (Number == 1) then
                if (ReturnValue == 2) then
                    return 64.00
                elseif (ReturnValue == 3) then
                    return 1.00
                endif
            elseif (Number == 2) then
                if (ReturnValue == 2) then
                    return -64.00
                elseif (ReturnValue == 3) then
                    return 1.00
                endif
            elseif (Number == 3) then
                if (ReturnValue == 1) then
                    return 128.00
                elseif (ReturnValue == 2) then
                    return 64.00
                elseif (ReturnValue == 3) then
                    return udg_HeightAdjustSmooth
                endif
            elseif (Number == 4) then
                if (ReturnValue == 1) then
                    return -128.00
                elseif (ReturnValue == 2) then
                    return 64.00
                elseif (ReturnValue == 3) then
                    return udg_HeightAdjustSmooth
                endif
            elseif (Number == 5) then
                if (ReturnValue == 1) then
                    return 128.00
                elseif (ReturnValue == 2) then
                    return -64.00
                elseif (ReturnValue == 3) then
                    return udg_HeightAdjustSmooth
                endif
            elseif (Number == 6) then
                if (ReturnValue == 1) then
                    return -128.00
                elseif (ReturnValue == 2) then
                    return -64.00
                elseif (ReturnValue == 3) then
                    return udg_HeightAdjustSmooth
                endif
            endif
        elseif (Type == 3) then
            if (Number == 1) then
                if (ReturnValue == 1) then
                    return 64.00
                elseif (ReturnValue == 3) then
                    return 1.00
                endif
            elseif (Number == 2) then
                if (ReturnValue == 1) then
                    return -64.00
                elseif (ReturnValue == 3) then
                    return 1.00
                endif
            elseif (Number == 3) then
                if (ReturnValue == 1) then
                    return 64.00
                elseif (ReturnValue == 2) then
                    return 128.00
                elseif (ReturnValue == 3) then
                    return udg_HeightAdjustSmooth
                endif
            elseif (Number == 4) then
                if (ReturnValue == 1) then
                    return 64.00
                elseif (ReturnValue == 2) then
                    return -128.00
                elseif (ReturnValue == 3) then
                    return udg_HeightAdjustSmooth
                endif
            elseif (Number == 5) then
                if (ReturnValue == 1) then
                    return -64.00
                elseif (ReturnValue == 2) then
                    return 128.00
                elseif (ReturnValue == 3) then
                    return udg_HeightAdjustSmooth
                endif
            elseif (Number == 6) then
                if (ReturnValue == 1) then
                    return -64.00
                elseif (ReturnValue == 2) then
                    return -128.00
                elseif (ReturnValue == 3) then
                    return udg_HeightAdjustSmooth
                endif
            endif
        elseif (Type == 4) then
            if (Number == 1) then
                if (ReturnValue == 1) then
                    return 64.00
                elseif (ReturnValue == 2) then
                    return 64.00
                elseif (ReturnValue == 3) then
                    return 1.00
                endif
            elseif (Number == 2) then
                if (ReturnValue == 1) then
                    return -64.00
                elseif (ReturnValue == 2) then
                    return 64.00
                elseif (ReturnValue == 3) then
                    return 1.00
                endif
            elseif (Number == 3) then
                if (ReturnValue == 1) then
                    return 64.00
                elseif (ReturnValue == 2) then
                    return -64.00
                elseif (ReturnValue == 3) then
                    return 1.00
                endif
            elseif (Number == 4) then
                if (ReturnValue == 1) then
                    return -64.00
                elseif (ReturnValue == 2) then
                    return -64.00
                elseif (ReturnValue == 3) then
                    return 1.00
                endif
            endif
        endif
        return 0.00
    endfunction
    private function RaiseBuildingsOnSameHeight takes group Buildings returns boolean
        local real MaxResidual = 0.001
        local real AverageHeight = 0.00
        local real array PosXs
        local real array PosYs
        local real array Factors
        local integer UsedSlots = 0
        local real RealTemp1
        local real RealTemp2
        local real RealTemp3
        local real RealTemp4
        local real RealTemp5
        local unit UnitTemp1
        local location LocationTemp1 = null
        local group GroupTemp1 = null
        local group GroupTemp2 = null
        local group GroupTemp3 = null
        local terraindeformation TerraindeformationTemp1 = null
        local integer IntTemp1 = 0
        local integer IntTemp2
        local integer IntLoop1
        local integer IntLoop2 = 0
        local integer IntLoop3 = 0
        //Exit if group has not more than one unit:
        set UnitTemp1 = FirstOfGroup(Buildings)
        call GroupRemoveUnit(Buildings, UnitTemp1)
        if (FirstOfGroup(Buildings) == null) then
            //Anti-Memory-Leak:
            set UnitTemp1 = null
            //-----------------
            return false
        endif
        call GroupAddUnit(Buildings, UnitTemp1)
        //Hide all walk destructables:
        set IntLoop1 = 1
        loop
            exitwhen IntLoop1 > udg_WalkBuildingsCount
            call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, false)
            set IntLoop1 = IntLoop1 + 1
        endloop
        //Get building heights:
        set GroupTemp1 = CreateGroup()
        set GroupTemp2 = CreateGroup()
        set GroupTemp3 = CreateGroup()
        loop
            set UnitTemp1 = FirstOfGroup(Buildings)
            exitwhen UnitTemp1 == null
            call GroupRemoveUnit(Buildings, UnitTemp1)
            call GroupAddUnit(GroupTemp1, UnitTemp1)
            call GroupAddUnit(GroupTemp2, UnitTemp1)
            call GroupAddUnit(GroupTemp3, UnitTemp1)
            set LocationTemp1 = Location(GetUnitX(UnitTemp1), GetUnitY(UnitTemp1))
            set RealTemp1 = GetLocationZ(LocationTemp1)
            call RemoveLocation(LocationTemp1)
            if (IntTemp1 == 0) then
                //Check if all buildings are on the same hight:
                if (AverageHeight == 0.00) then
                    set RealTemp2 = RealTemp1
                elseif (RealTemp1 >= RealTemp2 + MaxResidual or RealTemp1 <= RealTemp2 - MaxResidual) then
                    set IntTemp1 = 1
                endif
            endif
            set AverageHeight = AverageHeight + RealTemp1
            set IntLoop2 = IntLoop2 + 1
        endloop
        if (IntLoop2 > 0) then
            set AverageHeight = AverageHeight / IntLoop2
        endif
        //Show all walk destructables:
        set IntLoop1 = 1
        loop
            exitwhen IntLoop1 > udg_WalkBuildingsCount
            call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, true)
            set IntLoop1 = IntLoop1 + 1
        endloop
        call TriggerSleepAction(0.01)
        //Exit if no buildings have to be adjusted:
        if (IntTemp1 == 0) then
            //Anti-Memory-Leak:
            call DestroyGroup(GroupTemp1)
            set GroupTemp1 = null
            call DestroyGroup(GroupTemp2)
            set GroupTemp2 = null
            call DestroyGroup(GroupTemp3)
            set GroupTemp3 = null
            call DestroyGroup(Buildings)
            set Buildings = null
            set UnitTemp1 = null
            set LocationTemp1 = null
            //-----------------
            return false
        endif
        //Get positions that have to be adjusted:
        set IntTemp2 = 30
        loop
            set UnitTemp1 = FirstOfGroup(GroupTemp1)
            exitwhen UnitTemp1 == null
            call GroupRemoveUnit(GroupTemp1, UnitTemp1)
            set RealTemp1 = I2R(R2I(GetUnitX(UnitTemp1) / 64.00)) * 64.00
            set RealTemp2 = I2R(R2I(GetUnitY(UnitTemp1) / 64.00)) * 64.00
            if (RealTemp1 - I2R(R2I(RealTemp1 / 128.00)) * 128.00 == 0.00) then
                if (RealTemp2 - I2R(R2I(RealTemp2 / 128.00)) * 128.00 == 0.00) then
                    set IntTemp1 = 1
                else
                    set IntTemp1 = 2
                endif
            else
                if (RealTemp2 - I2R(R2I(RealTemp2 / 128.00)) * 128.00 == 0.00) then
                    set IntTemp1 = 3
                else
                    set IntTemp1 = 4
                endif
            endif
            set IntLoop2 = 1
            loop
                set RealTemp5 = RaiseBuildingsOnSameHeight_Function1(IntLoop2, IntTemp1, 3)
                exitwhen RealTemp5 == 0.00
                set RealTemp3 = RealTemp1 + RaiseBuildingsOnSameHeight_Function1(IntLoop2, IntTemp1, 1)
                set RealTemp4 = RealTemp2 + RaiseBuildingsOnSameHeight_Function1(IntLoop2, IntTemp1, 2)
                set IntLoop1 = 1
                loop
                    exitwhen IntLoop1 > UsedSlots
                    exitwhen (PosXs[IntLoop1] == RealTemp3 and PosYs[IntLoop1] == RealTemp4)
                    set IntLoop1 = IntLoop1 + 1
                endloop
                if (IntLoop1 > UsedSlots) then
                    set UsedSlots = UsedSlots + 1
                    set PosXs[UsedSlots] = RealTemp3
                    set PosYs[UsedSlots] = RealTemp4
                    set Factors[UsedSlots] = RealTemp5
                elseif (Factors[IntLoop1] < RealTemp5) then
                    set Factors[IntLoop1] = RealTemp5
                endif
                set IntLoop2 = IntLoop2 + 1
            endloop
            set IntLoop3 = IntLoop3 + 1
            if (IntLoop3 >= IntTemp2) then
                set IntTemp2 = 4 + R2I(IntTemp2 * 0.5)
                set IntLoop3 = 0
                call TriggerSleepAction(0.01)
            endif
        endloop
        call TriggerSleepAction(0.01)
        //Hide all walk destructables:
        set IntLoop1 = 1
        loop
            exitwhen IntLoop1 > udg_WalkBuildingsCount
            call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, false)
            set IntLoop1 = IntLoop1 + 1
        endloop
        //Adjust heights of the positions:
        set IntLoop1 = 1
        loop
            exitwhen IntLoop1 > UsedSlots
            set LocationTemp1 = Location(PosXs[IntLoop1], PosYs[IntLoop1])
            set RealTemp1 = (GetLocationZ(LocationTemp1) - AverageHeight) * Factors[IntLoop1]
            call RemoveLocation(LocationTemp1)
            if (RealTemp1 >= MaxResidual or RealTemp1 <= (-1) * MaxResidual) then
                set TerraindeformationTemp1 = TerrainDeformCrater(PosXs[IntLoop1], PosYs[IntLoop1], 1.00, RealTemp1, 10, true)
            endif
            set IntLoop1 = IntLoop1 + 1
        endloop
        //Show all walk destructables:
        set IntLoop1 = 1
        loop
            exitwhen IntLoop1 > udg_WalkBuildingsCount
            call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, true)
            set IntLoop1 = IntLoop1 + 1
        endloop
        call TriggerSleepAction(0.01)
        call RecreateWalkDestructables(GroupTemp2)
        call RepositionBuildings(GroupTemp3)
        //Anti-Memory-Leak:
        call DestroyGroup(GroupTemp1)
        set GroupTemp1 = null
        set GroupTemp2 = null
        set GroupTemp3 = null
        call DestroyGroup(Buildings)
        set UnitTemp1 = null
        set LocationTemp1 = null
        set TerraindeformationTemp1 = null
        //-----------------
        return true
    endfunction

    private function AdjustPathingForWalkBuildingGroup takes group BuildingGroup, boolean WaitsNotAllowed returns nothing
        local group GroupTemp1 = BuildingGroup
        local unit UnitTemp1
        local integer IntTemp1
        local integer IntTemp2
        local integer IntTemp3
        local integer IntTemp4
        local integer IntTemp5
        local integer IntLoop1
        local real RealTemp1
        local real RealTemp2
        local real RealTemp3
        set udg_AdjustPathingForWalkBuildingGroup_Counter = 0
        loop
            set UnitTemp1 = FirstOfGroup(GroupTemp1)
            exitwhen UnitTemp1 == null
            call GroupRemoveUnit(GroupTemp1, UnitTemp1)
            set IntTemp1 = GetUnitTypeId(UnitTemp1)
            if (GetWalkDestructableID(IntTemp1, 0) != 0 and GetUnitState(UnitTemp1, UNIT_STATE_LIFE) >= 1.00) then
                set IntTemp2 = libUnitDat_GetSystemNumberOfUnit(UnitTemp1, udg_SystemSlot)
                if (IntTemp2 > 0) then
                    set RealTemp1 = GetUnitX(UnitTemp1)
                    set RealTemp2 = GetUnitY(UnitTemp1)
                    set RealTemp3 = AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1))
                    if (udg_WalkBuildings[IntTemp2].UnderConstruction and GetRepairedBuildingID(IntTemp1) == 0) then
                        set IntTemp5 = GetConstructionPathDestructableID(IntTemp1)
                    else
                        set IntTemp4 = GetFortificationBuildingAdjoiningSlots(IntTemp1)
                        set IntTemp3 = 0
                        set IntTemp5 = 0
                        //Get needed walk destructable type:
                        set IntLoop1 = 1
                        loop
                            exitwhen IntLoop1 > IntTemp4
                            set UnitTemp1 = GetAdjoiningFortificationBuildingBySlot(IntTemp1, RealTemp1, RealTemp2, RealTemp3, IntLoop1, 1)
                            if (IntLoop1 == 3) then
                                set IntTemp3 = IntTemp3 + 1
                            elseif (IntLoop1 == 4) then
                                set IntTemp3 = IntTemp3 + 3
                            endif
                            if (UnitTemp1 == null) then
                                set IntTemp5 = IntTemp5 + IntLoop1 + IntTemp3
                            endif
                            set IntLoop1 = IntLoop1 + 1
                        endloop
                        set IntTemp5 = GetWalkDestructableID(IntTemp1, IntTemp5)
                    endif
                    set udg_AdjustPathingForWalkBuildingGroup_Counter = udg_AdjustPathingForWalkBuildingGroup_Counter + 1
                    //Replace walk destructable if needed:
                    if (GetDestructableTypeId(udg_WalkBuildings[IntTemp2].Destructable) != IntTemp5) then
                        call RemoveDestructable(udg_WalkBuildings[IntTemp2].Destructable)
                        set udg_WalkBuildings[IntTemp2].Destructable = CreateDestructable(IntTemp5, RealTemp1, RealTemp2, RealTemp3, 1.00, 0)
                    endif
                    if (udg_AdjustPathingForWalkBuildingGroup_Counter >= 1000) then
                        set udg_AdjustPathingForWalkBuildingGroup_Counter = 0
                        if (WaitsNotAllowed) then
                            call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Too many units to adjust at once")
                        endif
                        call TriggerSleepAction(0.01)
                    endif
                endif
            endif
        endloop
        //Anti-Memory-Leak:
        call DestroyGroup(GroupTemp1)
        set GroupTemp1 = null
        set UnitTemp1 = null
    endfunction
   
    private function AdjustWalkBuildingsAtPos_Filter1 takes nothing returns boolean
        return (GetWalkDestructableID(GetUnitTypeId(GetFilterUnit()), 0) != 0)
    endfunction
    private function AdjustWalkBuildingsAtPos takes real PosX, real PosY returns nothing
        local real HalfRectSize = 384.00
        local rect RectTemp1
        local boolexpr Filter1 = Condition(function AdjustWalkBuildingsAtPos_Filter1)
        local group GroupTemp1 = CreateGroup()
        //Check if target rect is in world bounds:
        if(GetRectMinX(bj_mapInitialPlayableArea) <= PosX - HalfRectSize and GetRectMinY(bj_mapInitialPlayableArea) <= PosY - HalfRectSize and GetRectMaxX(bj_mapInitialPlayableArea) >= PosX + HalfRectSize and GetRectMaxY(bj_mapInitialPlayableArea) >= PosY + HalfRectSize) then
            set RectTemp1 = Rect(PosX - HalfRectSize, PosY - HalfRectSize, PosX + HalfRectSize, PosY + HalfRectSize)
            call GroupEnumUnitsInRect(GroupTemp1, RectTemp1, Filter1)
            call RemoveRect(RectTemp1)
            call AdjustPathingForWalkBuildingGroup(GroupTemp1, true)
        endif
        //Anti-Memory-Leak:
        set GroupTemp1 = null
        call DestroyBoolExpr(Filter1)
        set Filter1 = null
        set RectTemp1 = null
    endfunction

    private function PlaceFortificationAddition_Filter1 takes nothing returns boolean
        return (IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND) and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false)
    endfunction
    private function PlaceFortificationAddition takes rect TargetRect, player Owner, integer BuildingSiteID, real Facing returns unit
        local unit BuildingSite = null
        local real PosX = Round(GetRectCenterX(TargetRect), 1)
        local real PosY = Round(GetRectCenterY(TargetRect), 1)
        local boolexpr Filter1 = Condition(function PlaceFortificationAddition_Filter1)
        local group GroupTemp1 = CreateGroup()
        local group GroupTemp2 = CreateGroup()
        local unit UnitTemp1
        local real RealTemp1
        local real RealTemp2
        local integer IntLoop1 = 1
        //Hide ground units in the way:
        call GroupEnumUnitsInRect(GroupTemp1, TargetRect, Filter1)
        call RemoveRect(TargetRect)
        loop
            set UnitTemp1 = FirstOfGroup(GroupTemp1)
            exitwhen UnitTemp1 == null
            call ShowUnit(UnitTemp1, false)
            call GroupAddUnit(GroupTemp2, UnitTemp1)
            call GroupRemoveUnit(GroupTemp1, UnitTemp1)
        endloop
        //Check if target position is free:
        loop
            set RealTemp1 = GetFortificationAdditionPathCheckerPos(BuildingSiteID, PosX, PosY, Facing, IntLoop1, true)
            exitwhen RealTemp1 == 99999.99
            set RealTemp2 = GetFortificationAdditionPathCheckerPos(BuildingSiteID, PosX, PosY, Facing, IntLoop1, false)
            set UnitTemp1 = CreateUnit(Owner, libId_udg_PathingCheckDummy, RealTemp1, RealTemp2, Facing)
            exitwhen (GetUnitX(UnitTemp1) != RealTemp1 or GetUnitY(UnitTemp1) != RealTemp2)
            call RemoveUnit(UnitTemp1)
            set IntLoop1 = IntLoop1 + 1
        endloop
        //Create building site if target position is free:
        if (RealTemp1 == 99999.99) then
            set BuildingSite = CreateUnit(Owner, BuildingSiteID, PosX, PosY, Facing)
            call SetUnitX(BuildingSite, PosX)
            call SetUnitY(BuildingSite, PosY)
        else
            call RemoveUnit(UnitTemp1)
        endif
        //Show ground units in the way:
        loop
            set UnitTemp1 = FirstOfGroup(GroupTemp2)
            exitwhen UnitTemp1 == null
            call ShowUnit(UnitTemp1, true)
            call GroupRemoveUnit(GroupTemp2, UnitTemp1)
        endloop
        //Anti-Memory-Leak:
        call DestroyBoolExpr(Filter1)
        set Filter1 = null
        call DestroyGroup(GroupTemp1)
        set GroupTemp1 = null
        call DestroyGroup(GroupTemp2)
        set GroupTemp2 = null
        set UnitTemp1 = null
        //-----------------
        return BuildingSite
    endfunction
   
    //------------
    //PUBLIC PART:
    //------------
   
    public function AdjustConstructingFortification takes unit Building returns boolean
        local unit UnitTemp1 = null
        local integer IntTemp1 = GetUnitTypeId(Building)
        local integer IntTemp2
        local integer IntTemp3
        local integer IntTemp4 = 0
        local integer IntTemp5
        local integer IntTemp6
        local integer IntLoop1 = 0
        local integer IntLoop2
        local integer IntLoop3
        local real RealTemp1
        local real RealTemp2
        local real RealTemp3
        local real RealTemp4
        if (IsFortificationBuilding(IntTemp1)) then
            set RealTemp1 = GetUnitX(Building)
            set RealTemp2 = GetUnitY(Building)
            //Get base walk building type:
            set IntTemp1 = GetBaseWalkBuildingID(IntTemp1)
            //Get adjusted facing and walk building type:
            loop
                set RealTemp3 = AdjustOrthogonalAngle(GetUnitFacing(Building) + IntLoop1 * 90.00)
                exitwhen IntLoop1 >= 4
                set IntLoop2 = 1
                loop
                    set IntTemp2 = GetSubWalkBuildingID(IntTemp1, IntLoop2)
                    exitwhen IntTemp2 == 0
                    set IntTemp3 = 0
                    set IntTemp6 = GetFortificationBuildingAdjoiningSlots(IntTemp2)
                    set IntLoop3 = 1
                    loop
                        exitwhen IntLoop3 > IntTemp6
                        set UnitTemp1 = GetAdjoiningFortificationBuildingBySlot(IntTemp2, RealTemp1, RealTemp2, RealTemp3, IntLoop3, 0)
                        if (UnitTemp1 != null) then
                            set IntTemp3 = IntTemp3 + 1
                        endif
                        set IntLoop3 = IntLoop3 + 1
                    endloop
                    if (IntTemp3 > IntTemp4) then
                        set IntTemp4 = IntTemp3
                        set IntTemp5 = IntTemp2
                        set RealTemp4 = RealTemp3
                    endif
                    set IntLoop2 = IntLoop2 + 1
                endloop
                exitwhen IntLoop2 <= 1
                set IntLoop1 = IntLoop1 + 1
            endloop
            //Change building, if adjustment is different to the stats of the given building:
            if (IntTemp4 > 0 and (GetUnitTypeId(Building) != IntTemp5 or RealTemp4 != AdjustOrthogonalAngle(GetUnitFacing(Building)))) then
                call ShowUnit(Building, false)
                call libUnitDat_ChangeUnit(Building, CreateUnit(GetOwningPlayer(Building), IntTemp5, RealTemp1, RealTemp2, RealTemp4))
                call RemoveUnit(Building)
                set IntTemp1 = 0
            endif
        endif
        //Anti-Memory-Leak:
        set UnitTemp1 = null
        //-----------------
        return (IntTemp1 == 0)
    endfunction
   
    public function AddBuildingUnderConstruction takes unit Building returns nothing
        local integer BuildingID = GetUnitTypeId(Building)
        local integer IntTemp1
        if (GetWalkDestructableID(BuildingID, 0) != 0) then
            //Add walk destructable if needed and adjust:
            set IntTemp1 = libUnitDat_GetSystemNumberOfUnit(Building, udg_SystemSlot)
            if (IntTemp1 == 0) then
                set udg_WalkBuildingsCount = udg_WalkBuildingsCount + 1
                set IntTemp1 = udg_WalkBuildingsCount
                set udg_WalkBuildings[IntTemp1] = WalkBuilding.create()
                if (udg_WalkBuildings[IntTemp1] == 0) then
                    call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: WalkBuilding struct cap exceeded")
                    return
                endif
                call udg_WalkBuildings[IntTemp1].New(Building, IntTemp1)
            endif
            set udg_WalkBuildings[IntTemp1].UnderConstruction = true
            call AdjustPathingForWalkBuildingGroup(GetDirectAdjoiningFortificationBuildings(Building, true), true)
        endif
        call RepositionBuilding(Building)
    endfunction 
   
    public function RemoveBuildingUnderConstruction takes unit Building returns nothing
        if (libUnitDat_GetSystemNumberOfUnit(Building, udg_SystemSlot) > 0) then
            call RemoveWalkBuilding(Building)
        endif
        call AdjustWalkBuildingsAtPos(GetUnitX(Building), GetUnitY(Building))
    endfunction
   
    public function AdjustReplacedBuilding takes unit Building returns nothing
        if (HasSmallPathing(GetUnitTypeId(Building))) then
            call RepositionBuilding(Building)
        endif
    endfunction

    //---------------------
    //EVENT-TRIGGERED PART:
    //---------------------
   
    private function GateClosingOrOpeningStarts_Conditions takes nothing returns boolean
        return (GetGateInfo(GetUnitTypeId(GetTriggerUnit()), 1) != 0)
    endfunction
    private function GateClosingOrOpeningStarts takes nothing returns nothing
        local real CheckInterval = 0.5
        local unit UnitTemp1 = GetTriggerUnit()
        local unit UnitTemp2
        local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
        local integer IntTemp2 = libUnitDat_SetNoRecyclingOfUnit(UnitTemp1, true)
        local real RealTemp1 = I2R(GetGateInfo(IntTemp1, 2)) * 0.7
        loop
            exitwhen RealTemp1 <= 0.00
            if (RealTemp1 > CheckInterval) then
                call TriggerSleepAction(CheckInterval)
            else
                call TriggerSleepAction(RealTemp1)
            endif
            set RealTemp1 = RealTemp1 - CheckInterval
            set UnitTemp1 = libUnitDat_GetUnit(IntTemp2)
            //Check if gate is dead or the closing/opening aborted:
            exitwhen (UnitTemp1 == null or GetGateInfo(GetUnitTypeId(UnitTemp1), 1) == 0)
        endloop
        call libUnitDat_SetNoRecycling(IntTemp2, false)
        if (UnitTemp1 == null) then
            //Recycle object of dead gate:
            call libUnitDat_RemoveObject(IntTemp2)
        elseif (GetGateInfo(GetUnitTypeId(UnitTemp1), 1) != 0) then
            //Change gate to closed/opened:
            call ShowUnit(UnitTemp1, false)
            set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), GetGateInfo(IntTemp1, 1), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1))
            call libUnitDat_ChangeUnit(UnitTemp1, UnitTemp2)
            call RemoveUnit(UnitTemp1)
        endif
        //Anti-Memory-Leak:
        set UnitTemp1 = null
        set UnitTemp2 = null
    endfunction
   
    private function FortificationDies_Conditions takes nothing returns boolean
        return (IsFortificationBuilding(GetUnitTypeId(GetDyingUnit())))
    endfunction
    private function FortificationDies_Filter1 takes nothing returns boolean
        return (IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND) and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false)
    endfunction
    private function FortificationDies takes nothing returns nothing
        local unit UnitTemp1 = GetDyingUnit()
        local unit UnitTemp2
        local group GroupTemp1
        local boolexpr Filter1
        local rect RectTemp1
        local destructable DestructableTemp1
        local integer IntLoop1 = 1
        local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
        local integer IntTemp2 = GetDestructedBuildingID(IntTemp1)
        local real RealTemp1 = GetDestructionTime(IntTemp1)
        local boolean IsOldWalkBuilding = (GetWalkDestructableID(IntTemp1, 0) != 0)
        local boolean IsNewWalkBuilding = (GetWalkDestructableID(IntTemp2, 0) != 0)
        if (IsOldWalkBuilding and GetRepairedBuildingID(IntTemp1) == 0) then
            if (udg_WalkBuildings[libUnitDat_GetSystemNumberOfUnit(UnitTemp1, udg_SystemSlot)].UnderConstruction) then
                set IntTemp2 = 0
                set RealTemp1 = -1.00
                set IsNewWalkBuilding = false
            endif
        endif
        if (IsOldWalkBuilding) then
            if (IsNewWalkBuilding == false) then
                //Kill units on destroyed walkable building:
                set GroupTemp1 = CreateGroup()
                set RectTemp1 = GetFortificationBuildingAdjoiningRect(IntTemp1, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1)), 0, 0)
                set Filter1 = Condition(function FortificationDies_Filter1)
                call GroupEnumUnitsInRect(GroupTemp1, RectTemp1, Filter1)
                loop
                    set UnitTemp2 = FirstOfGroup(GroupTemp1)
                    exitwhen UnitTemp2 == null
                    call GroupRemoveUnit(GroupTemp1, UnitTemp2)
                    call KillUnit(UnitTemp2)
                endloop
                call DestroyGroup(GroupTemp1)
                call DestroyBoolExpr(Filter1)
                call RemoveRect(RectTemp1)
            endif
            call RemoveWalkBuilding(UnitTemp1)
        endif
        call AdjustPathingForWalkBuildingGroup(GetDirectAdjoiningFortificationBuildings(UnitTemp1, false), true)
        if (IsNewWalkBuilding) then
            //Create destructed version and hide it:
            call ShowUnit(UnitTemp1, false)
            set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), IntTemp2, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1))
            call AddWalkBuilding(UnitTemp2)
            call AdjustPathingForWalkBuildingGroup(GetDirectAdjoiningFortificationBuildings(UnitTemp2, true), true)
            call ShowUnit(UnitTemp2, false)
            call ShowUnit(UnitTemp1, true)
            call RepositionBuilding(UnitTemp1)
        elseif (IntTemp2 != 0) then
            //Create pathing destructable of dying building:
            set DestructableTemp1 = CreateDestructable(GetDyingPathDestructableID(IntTemp1), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1)), 1.00, 0)
        endif
        if (RealTemp1 > 0.00) then
            call TriggerSleepAction(RealTemp1)
        endif
        if (IntTemp2 != 0) then
            call ShowUnit(UnitTemp1, false)
            if (IsNewWalkBuilding) then
                call ShowUnit(UnitTemp2, true)
            else
                call RemoveDestructable(DestructableTemp1)
                set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), IntTemp2, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1))
                call libUnitDat_ChangeUnit(UnitTemp1, UnitTemp2)
            endif
            call RepositionBuilding(UnitTemp2)
            call libUnitDat_RemoveObjectUnit(UnitTemp1)
        elseif (RealTemp1 == -1.00) then
            call libUnitDat_RemoveObjectUnit(UnitTemp1)
        endif
        //Anti-Memory-Leak:
        set UnitTemp1 = null
        set UnitTemp2 = null
        set GroupTemp1 = null
        set Filter1 = null
        set RectTemp1 = null
        set DestructableTemp1 = null
    endfunction
   
    private function FortificationBuildsFinish_Conditions takes nothing returns boolean
        return (IsFortificationBuilding(GetUnitTypeId(GetTriggerUnit())))
    endfunction
    private function FortificationBuildsFinish takes nothing returns nothing
        local unit UnitTemp1 = GetTriggerUnit()
        local unit UnitTemp2
        local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
        local boolean IsOldWalkBuilding = (GetWalkDestructableID(IntTemp1, 0) != 0)
        local boolean IsNewWalkBuilding = IsOldWalkBuilding
        set IntTemp1 = GetRepairedBuildingID(IntTemp1)
        if (IntTemp1 != 0) then
            set IsNewWalkBuilding = (GetWalkDestructableID(IntTemp1, 0) != 0)
        endif
        call TriggerSleepAction(0.01)
        if (IsOldWalkBuilding and IsNewWalkBuilding == false) then
            call RemoveWalkBuilding(UnitTemp1)
        endif
        //Change building, if it was rebuilt:
        if (IntTemp1 != 0) then
            call ShowUnit(UnitTemp1, false)
            set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), IntTemp1, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1))
            call libUnitDat_ChangeUnit(UnitTemp1, UnitTemp2)
            call RemoveUnit(UnitTemp1)
            call RepositionBuilding(UnitTemp2)
            set UnitTemp1 = UnitTemp2
        endif
        if (IsNewWalkBuilding) then
            if (IsOldWalkBuilding) then
                set udg_WalkBuildings[libUnitDat_GetSystemNumberOfUnit(UnitTemp1, udg_SystemSlot)].UnderConstruction = false
            else
                call AddWalkBuilding(UnitTemp1)
            endif
        endif
        call AdjustPathingForWalkBuildingGroup(GetDirectAdjoiningFortificationBuildings(UnitTemp1, true), true)
        if (IsNewWalkBuilding and udg_TerrainDeformation) then
            if (RaiseBuildingsOnSameHeight(GetAdjoiningFortificationBuildings(UnitTemp1)) and udg_RepositionOnlyFortifications <= 1) then
                //Reposition all buildings:
                if (udg_RepositionAllBuildingsRunning) then
                    set udg_RepositionAllBuildingsRestart = true
                else
                    call TriggerSleepAction(0.01)
                    call RepositionAllBuildings()
                endif
            endif
        endif
        //Anti-Memory-Leak:
        set UnitTemp1 = null
        set UnitTemp2 = null
    endfunction

    private function AddStairs_Conditions takes nothing returns boolean
        return (GetSpellAbilityId() == libId_udg_AddStairs)
    endfunction
    private function AddStairs takes nothing returns nothing
        local unit UnitTemp1 = GetSpellAbilityUnit()
        local player PlayerTemp1 = GetOwningPlayer(UnitTemp1)
        local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
        local real RealTemp1 = AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1))
        local real RealTemp2 = GetUnitX(UnitTemp1)
        local real RealTemp3 = GetUnitY(UnitTemp1)
        local rect RectTemp1 = GetFortificationBuildingAdjoiningRect(IntTemp1, RealTemp2, RealTemp3, RealTemp1, 3, 1)
        set UnitTemp1 = PlaceFortificationAddition(RectTemp1, PlayerTemp1, GetFortificationAdditionInfo(IntTemp1, 0, 1), RealTemp1)
        if (UnitTemp1 != null) then
            if (GetLocalPlayer() == PlayerTemp1) then
                // Use only local code (no net traffic) within this block to avoid desyncs.
                call ClearSelection()
                call SelectUnit(UnitTemp1, true)
            endif
            call IssueImmediateOrderById(UnitTemp1, GetFortificationAdditionInfo(IntTemp1, 0, 2))
        else
            call DisplayTextToPlayer(PlayerTemp1, 0, 0, "No place for stairs here.")
        endif
        //Anti-Memory-Leak:
        set RectTemp1 = null
        set UnitTemp1 = null
        set PlayerTemp1 = null
    endfunction
   
    private function AddLadders_Conditions takes nothing returns boolean
        return (GetSpellAbilityId() == libId_udg_AddLadders)
    endfunction
    private function AddLadders takes nothing returns nothing
        local unit UnitTemp1 = GetSpellAbilityUnit()
        local unit UnitTemp2
        call ShowUnit(UnitTemp1, false)
        set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), GetFortificationAdditionInfo(GetUnitTypeId(UnitTemp1), 0, 2), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1)))
        call libUnitDat_ChangeUnit(UnitTemp1, UnitTemp2)
        call RemoveUnit(UnitTemp1)
        call AdjustPathingForWalkBuildingGroup(GetDirectAdjoiningFortificationBuildings(UnitTemp2, true), true)
        call RepositionBuilding(UnitTemp2)
        if (GetLocalPlayer() == GetOwningPlayer(UnitTemp2)) then
            // Use only local code (no net traffic) within this block to avoid desyncs.
            call ClearSelection()
            call SelectUnit(UnitTemp2, true)
        endif
        //Anti-Memory-Leak:
        set UnitTemp1 = null
        set UnitTemp2 = null
    endfunction
   
    private function UseSiegeLadder_Conditions takes nothing returns boolean
        return (GetSpellAbilityId() == libId_udg_UseSiegeLadder and IsLadderTakeableBuilding(GetUnitTypeId(GetSpellTargetUnit())))
    endfunction
    private function UseSiegeLadder takes nothing returns nothing
        local unit UnitTemp1 = GetSpellTargetUnit()
        local unit UnitTemp2 = GetSpellAbilityUnit()
        local player PlayerTemp1 = GetOwningPlayer(UnitTemp2)
        local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
        local integer IntTemp2 = GetUnitTypeId(UnitTemp2)
        local real RealTemp1 = AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1))
        local real RealTemp2 = GetUnitX(UnitTemp1)
        local real RealTemp3 = GetUnitY(UnitTemp1)
        local rect RectTemp1 = GetFortificationBuildingAdjoiningRect(IntTemp1, RealTemp2, RealTemp3, RealTemp1, 4, 1)
        if (RectTemp1 == null) then
            set RectTemp1 = GetFortificationBuildingAdjoiningRect(IntTemp1, RealTemp2, RealTemp3, RealTemp1, 3, 1)
        endif
        set UnitTemp1 = PlaceFortificationAddition(RectTemp1, PlayerTemp1, GetFortificationAdditionInfo(IntTemp2, IntTemp1, 1), RealTemp1)
        if (UnitTemp1 != null) then
            call IssueImmediateOrder(UnitTemp2, "stop")
            call UnitRemoveAbility(UnitTemp2, libId_udg_UseSiegeLadder)
            call UnitAddAbility(UnitTemp2, libId_udg_AttackingCivilian)
            call UnitRemoveAbility(UnitTemp2, GetFortificationAdditionInfo(IntTemp2, IntTemp1, 3))
            call IssueImmediateOrderById(UnitTemp1, GetFortificationAdditionInfo(IntTemp2, IntTemp1, 2))
            if (GetLocalPlayer() == PlayerTemp1) then
                // Use only local code (no net traffic) within this block to avoid desyncs.
                call ClearSelection()
                call SelectUnit(UnitTemp2, true)
            endif
        else
            call DisplayTextToPlayer(PlayerTemp1, 0, 0, "No place for a ladder here.")
        endif
        //Anti-Memory-Leak:
        set RectTemp1 = null
        set UnitTemp1 = null
        set UnitTemp2 = null
        set PlayerTemp1 = null
    endfunction
   
    private function AutoUseSiegeLadder_Filter1 takes nothing returns boolean
        return (GetUnitAbilityLevel(GetFilterUnit(), libId_udg_UseSiegeLadder) > 0 and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) >= 1.00)
    endfunction
    private function AutoUseSiegeLadder_Filter2 takes nothing returns boolean
        return (IsLadderTakeableBuilding(GetUnitTypeId(GetFilterUnit())))
    endfunction
    private function AutoUseSiegeLadder_Filter3 takes nothing returns boolean
        return (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE))
    endfunction
    private function AutoUseSiegeLadder takes nothing returns nothing
        local boolexpr Filter1 = Condition(function AutoUseSiegeLadder_Filter1)
        local boolexpr Filter2 = Condition(function AutoUseSiegeLadder_Filter2)
        local boolexpr Filter3 = Condition(function AutoUseSiegeLadder_Filter3)
        local group GroupTemp1 = CreateGroup()
        local group GroupTemp2 = CreateGroup()
        local group GroupTemp3 = CreateGroup()
        local group GroupTemp4 = CreateGroup()
        local unit UnitTemp1
        local unit UnitTemp2
        local unit UnitTemp3
        local rect RectTemp1
        local integer IntLoop1 = 1
        loop
            exitwhen IntLoop1 > 16
            if (GetPlayerController(Player(IntLoop1 - 1)) == MAP_CONTROL_COMPUTER) then
                call GroupEnumUnitsOfPlayer(GroupTemp1, Player(IntLoop1 - 1), Filter1)
                loop
                    set UnitTemp1 = FirstOfGroup(GroupTemp1)
                    exitwhen UnitTemp1 == null
                    call GroupRemoveUnit(GroupTemp1, UnitTemp1)
                    call GroupEnumUnitsInRange(GroupTemp2, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), udg_MaxLadderRadius, Filter2)
                    loop
                        set UnitTemp2 = FirstOfGroup(GroupTemp2)
                        exitwhen UnitTemp2 == null
                        call GroupRemoveUnit(GroupTemp2, UnitTemp2)
                        //Check if Wall isn't already a target and that it is from an enemy:
                        if (IsUnitInGroup(UnitTemp2, GroupTemp4) == false and GetPlayerAlliance(Player(IntLoop1 - 1), GetOwningPlayer(UnitTemp2), ALLIANCE_PASSIVE) == false) then
                            //Check if a structure is in the way:
                            set RectTemp1 = GetFortificationBuildingAdjoiningRect(GetUnitTypeId(UnitTemp2), GetUnitX(UnitTemp2), GetUnitY(UnitTemp2), AdjustOrthogonalAngle(GetUnitFacing(UnitTemp2)), 4, 1)
                            if (RectTemp1 == null) then
                                set RectTemp1 = GetFortificationBuildingAdjoiningRect(GetUnitTypeId(UnitTemp2), GetUnitX(UnitTemp2), GetUnitY(UnitTemp2), AdjustOrthogonalAngle(GetUnitFacing(UnitTemp2)), 3, 1)
                            endif
                            if (RectTemp1 != null) then
                                call GroupEnumUnitsInRect(GroupTemp3, RectTemp1, Filter3)
                                call RemoveRect(RectTemp1)
                                call GroupRemoveUnit(GroupTemp3, UnitTemp2)
                                set UnitTemp3 = FirstOfGroup(GroupTemp3)
                                call GroupClear(GroupTemp3)
                                if (UnitTemp3 == null) then
                                    call IssueTargetOrder(UnitTemp1, "thunderbolt", UnitTemp2)
                                    call GroupAddUnit(GroupTemp4, UnitTemp2)
                                    exitwhen true
                                endif
                            endif
                        endif
                    endloop
                    call GroupClear(GroupTemp2)
                endloop
            endif
            set IntLoop1 = IntLoop1 + 1
        endloop
        //Anti-Memory-Leak:
        call DestroyGroup(GroupTemp1)
        set GroupTemp1 = null
        call DestroyGroup(GroupTemp2)
        set GroupTemp2 = null
        call DestroyGroup(GroupTemp3)
        set GroupTemp3 = null
        call DestroyGroup(GroupTemp4)
        set GroupTemp4 = null
        call DestroyBoolExpr(Filter1)
        set Filter1 = null
        call DestroyBoolExpr(Filter2)
        set Filter2 = null
        call DestroyBoolExpr(Filter3)
        set Filter3 = null
        set UnitTemp1 = null
        set UnitTemp2 = null
        set UnitTemp3 = null
        set RectTemp1 = null
    endfunction
   
    private function SmallPathingBuildsStart_Conditions takes nothing returns boolean
        return (HasSmallPathing(GetUnitTypeId(GetConstructingStructure())) or HasSmallPathing(GetUnitTypeId(GetTriggerUnit())))
    endfunction
    private function SmallPathingBuildsStart takes nothing returns nothing
        local unit UnitTemp1 = GetConstructingStructure()
        if (UnitTemp1 == null) then
            set UnitTemp1 = GetTriggerUnit()
        endif
        call RepositionBuilding(UnitTemp1)
        //Anti-Memory-Leak:
        set UnitTemp1 = null
    endfunction
   
    private function DisableMovementFinish_Conditions takes nothing returns boolean
        return (IsUnitWithoutMovement(GetUnitTypeId(GetConstructedStructure())) or IsUnitWithoutMovement(GetUnitTypeId(GetTriggerUnit())))
    endfunction
    private function DisableMovementFinish takes nothing returns nothing
        local unit UnitTemp1 = GetConstructedStructure()
        if (UnitTemp1 == null) then
            set UnitTemp1 = GetTriggerUnit()
        endif
        call SetUnitPropWindow(UnitTemp1, 0)
        //Anti-Memory-Leak:
        set UnitTemp1 = null
    endfunction
    //original "private" function changed to "public" for 'CustomResourceSystem' compatibility:
    public function SmartOrderOnWalkableBuilding_Conditions takes nothing returns boolean
        return (OrderId2String(GetIssuedOrderId()) == "smart" and GetWalkDestructableID(GetUnitTypeId(GetOrderTargetUnit()), 0) != 0 and IsUnitType(GetOrderedUnit(), UNIT_TYPE_PEON) == false)
    endfunction
    private function SmartOrderOnWalkableBuilding takes nothing returns nothing
        local unit OrderedUnit = GetOrderedUnit()
        local unit Fortification = GetOrderTargetUnit()
        call IssuePointOrder(OrderedUnit, "move", GetUnitX(Fortification), GetUnitY(Fortification))
        //Anti-Memory-Leak:
        set OrderedUnit = null
        set Fortification = null
    endfunction

    //---------------
    //INITIALISATION:
    //---------------
   
    private function CreateInitWalls_Filter1 takes nothing returns boolean
        return (GetReplacingInitBuildingID(GetUnitTypeId(GetFilterUnit())) != 0)
    endfunction
    private function CreateInitWalls_Filter2 takes nothing returns boolean
        return (IsFortificationBuilding(GetUnitTypeId(GetFilterUnit())))
    endfunction
    private function CreateInitWalls takes nothing returns nothing
        local group GroupTemp1 = CreateGroup()
        local group GroupTemp2 = CreateGroup()
        local group GroupTemp3
        local boolexpr Filter1 = Condition(function CreateInitWalls_Filter1)
        local boolexpr Filter2
        local unit UnitTemp1
        local unit UnitTemp2
        local integer IntTemp1
        local integer IntLoop1 = 1
        //Replace init units:
        call GroupEnumUnitsInRect(GroupTemp1, bj_mapInitialPlayableArea, Filter1)
        loop
            set UnitTemp1 = FirstOfGroup(GroupTemp1)
            exitwhen UnitTemp1 == null
            call GroupRemoveUnit(GroupTemp1, UnitTemp1)
            call ShowUnit(UnitTemp1, false)
            set IntTemp1 = GetReplacingInitBuildingID(GetUnitTypeId(UnitTemp1))
            set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), IntTemp1, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1))
            if (GetWalkDestructableID(IntTemp1, 0) != 0) then
                call AddWalkBuilding(UnitTemp2)
                call GroupAddUnit(GroupTemp2, UnitTemp2)
            endif
            call RemoveUnit(UnitTemp1)
            set IntLoop1 = IntLoop1 + 1
            if (IntLoop1 >= 200) then
                set IntLoop1 = 0
                call TriggerSleepAction(0.01)
            endif
        endloop
        call TriggerSleepAction(0.01)
        call RepositionAllBuildings()
        call TriggerSleepAction(0.01)
        //Adjust replaced units:
        call DestroyGroup(GroupTemp1)
        call AdjustPathingForWalkBuildingGroup(GroupTemp2, false)
        //Adjust building heights:
        if (udg_TerrainDeformation) then
            call TriggerSleepAction(0.01)
            set Filter2 = Condition(function CreateInitWalls_Filter2)
            set GroupTemp2 = CreateGroup()
            call GroupEnumUnitsInRect(GroupTemp2, bj_mapInitialPlayableArea, Filter2)
            call DestroyBoolExpr(Filter2)
            set GroupTemp1 = CreateGroup()
            loop
                set UnitTemp1 = FirstOfGroup(GroupTemp2)
                exitwhen UnitTemp1 == null
                call GroupClear(GroupTemp1)
                set GroupTemp3 = GroupTemp1
                set GroupTemp1 = GetAdjoiningFortificationBuildings(UnitTemp1)
                loop
                    set UnitTemp1 = FirstOfGroup(GroupTemp1)
                    exitwhen UnitTemp1 == null
                    call GroupRemoveUnit(GroupTemp1, UnitTemp1)
                    call GroupRemoveUnit(GroupTemp2, UnitTemp1)
                    call GroupAddUnit(GroupTemp3, UnitTemp1)
                endloop
                //Raise adjoining buildings on same height:
                call RaiseBuildingsOnSameHeight(GroupTemp3)
            endloop
            call DestroyGroup(GroupTemp1)
            if (udg_RepositionOnlyFortifications <= 2) then
                //Reposition all buildings:
                if (udg_RepositionAllBuildingsRunning) then
                    set udg_RepositionAllBuildingsRestart = true
                else
                    call TriggerSleepAction(0.01)
                    call RepositionAllBuildings()
                endif
            endif
        endif
        call DestroyGroup(GroupTemp2)
        set udg_InitFinished = true
        //Anti-Memory-Leak:
        set GroupTemp1 = null
        set GroupTemp2 = null
        set GroupTemp3 = null
        call DestroyBoolExpr(Filter1)
        set Filter1 = null
        set Filter2 = null
        set UnitTemp1 = null
        set UnitTemp2 = null
    endfunction
   
    private function DisableMovementInit_Filter1 takes nothing returns boolean
        return (IsUnitWithoutMovement(GetUnitTypeId(GetFilterUnit())))
    endfunction
    private function DisableMovementInit takes nothing returns nothing
        local boolexpr Filter1 = Condition(function DisableMovementInit_Filter1)
        local group GroupTemp1 = CreateGroup()
        local unit UnitTemp1
        call TriggerSleepAction(0.01)
        call GroupEnumUnitsInRect(GroupTemp1, bj_mapInitialPlayableArea, Filter1)
        loop
            set UnitTemp1 = FirstOfGroup(GroupTemp1)
            exitwhen UnitTemp1 == null
            call GroupRemoveUnit(GroupTemp1, UnitTemp1)
            call SetUnitPropWindow(UnitTemp1, 0)
        endloop
        //Anti-Memory-Leak:
        call DestroyBoolExpr(Filter1)
        set Filter1 = null
        call DestroyGroup(GroupTemp1)
        set GroupTemp1 = null
        set UnitTemp1 = null
    endfunction
   
    private function Init_WallSystem takes nothing returns nothing
        local integer IntLoop1 = 1
        //Triggers and variables:
        call TriggerRegisterTimerEvent(gg_trg_AutoUseSiegeLadder, udg_AutoUseSiegeLadderRate, true)
        loop
            exitwhen IntLoop1 > udg_CountPlayers
            call TriggerRegisterPlayerUnitEvent(gg_trg_GateClosingOrOpeningStarts, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_START, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_FortificationDies, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_DEATH, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_FortificationBuildsFinish, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_FINISH, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_AddStairs, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_AddLadders, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_UseSiegeLadder, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_SmallPathingBuildsStart, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_CONSTRUCT_START, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_SmallPathingBuildsStart, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_START, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_DisableMovementFinish, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_FINISH, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_DisableMovementFinish, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_CONSTRUCT_FINISH, null)
            call TriggerRegisterPlayerUnitEvent(gg_trg_SmartOrderOnWalkableBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
            set IntLoop1 = IntLoop1 + 1
        endloop
        //Conditions:
        call TriggerAddCondition(gg_trg_GateClosingOrOpeningStarts, Condition(function GateClosingOrOpeningStarts_Conditions))
        call TriggerAddCondition(gg_trg_FortificationDies, Condition(function FortificationDies_Conditions))
        call TriggerAddCondition(gg_trg_FortificationBuildsFinish, Condition(function FortificationBuildsFinish_Conditions))
        call TriggerAddCondition(gg_trg_AddStairs, Condition(function AddStairs_Conditions))
        call TriggerAddCondition(gg_trg_AddLadders, Condition(function AddLadders_Conditions))
        call TriggerAddCondition(gg_trg_UseSiegeLadder, Condition(function UseSiegeLadder_Conditions))
        call TriggerAddCondition(gg_trg_SmallPathingBuildsStart, Condition(function SmallPathingBuildsStart_Conditions))
        call TriggerAddCondition(gg_trg_DisableMovementFinish, Condition(function DisableMovementFinish_Conditions))
        call TriggerAddCondition(gg_trg_SmartOrderOnWalkableBuilding, Condition(function SmartOrderOnWalkableBuilding_Conditions))
        //Actions:
        call TriggerAddAction(gg_trg_GateClosingOrOpeningStarts, function GateClosingOrOpeningStarts)
        call TriggerAddAction(gg_trg_FortificationDies, function FortificationDies)
        call TriggerAddAction(gg_trg_FortificationBuildsFinish, function FortificationBuildsFinish)
        call TriggerAddAction(gg_trg_AddStairs, function AddStairs)
        call TriggerAddAction(gg_trg_AddLadders, function AddLadders)
        call TriggerAddAction(gg_trg_UseSiegeLadder, function UseSiegeLadder)
        call TriggerAddAction(gg_trg_AutoUseSiegeLadder, function AutoUseSiegeLadder)
        call TriggerAddAction(gg_trg_SmallPathingBuildsStart, function SmallPathingBuildsStart)
        call TriggerAddAction(gg_trg_DisableMovementFinish, function DisableMovementFinish)
        call TriggerAddAction(gg_trg_SmartOrderOnWalkableBuilding, function SmartOrderOnWalkableBuilding)
        //Init functions:
        call CreateInitWalls()
        call DisableMovementInit()
    endfunction
endlibrary
 
Level 11
Joined
Mar 31, 2016
Messages
657
What is your question? You assume a destructable isn't spawning, what were your steps to try make it spawn?

Of course we need to see the code. Do you think we can guess how the pathing system works?

I suspect there to be some sort of "register" function that creates the necessary invisible platforms, unless it's hardcoded for the static objects.

My question is: Can you help me alter the code and or fix some bugs?
Well, the destructibles aren't selectable and invisible pathing, so when the building has no pathing - I assume the destructible has not spawned or something else isn't matching up in the trigger so that the destructible isn't spawning.

Thanks for the feedback.

Also if you need me to send you the map file to see the trigger in action, let me know.
 
Level 11
Joined
Mar 31, 2016
Messages
657
How are you using the system?

I imported the triggers and object editor data for my own RTS map.
This system works for a multi-stage destruction system of certain buildings (which I might delete and takes up most of the room) and for custom pathing of constructed and prebuilt (initial) buildings; mostly walkable walls, stairs, and ladders + a door system for gates and towers built along the wall so units can walk through them (although the door system doesn't work for built structures, only initially placed structures).
 
Level 11
Joined
Mar 31, 2016
Messages
657
You still didn't show how you are using the system.
Just importing it into your map won't suffice. The only reason initial placed objects are being converted is because of "CreateInitWalls".
Just look at the bottom of the script you pasted.

Idk what you mean by 'show' - what exactly are you looking to see?
Ok, thanks for spotting that out. Will do.

Also here's my map so far if you wanna see it in action. Build some 'Building Plot - Fortification's to make wall or gate. Assign 2-4+ workers and for some buildings, an architect for building construction (see multiboard for construction info). Check out the pathing issues as I described above for yourself. Also units have trouble moving onto walls unless they are completely enclosed or built next to a structure or destructible. Walls have an ability to build ladder or stairs on the inner edge of walls + 'Engineer's can build ladders from 'Building Plot - Siege' that work on the outer side of walls.

And most hotkeys use a grid QWER ASDF ZCXV format (not all hotkeys are set yet)
Use the units in the center of the map for testing constructed buildings.
 
Level 11
Joined
Mar 31, 2016
Messages
657
Read the description of the system, it tells you where you have to customize things.
Upload a map with just that system and the error youre getting etc.
Indeed it tells you most things and has lots of descriptive comments however its still quite complicated and I'm not sure what to change or edit for most of my issues.

Here's the map. Use units in the center of the map to build and test.
https://www.hiveworkshop.com/pastebin/1a8e40fdaf765a9e2deba002f12617d711652/

Build some 'Building Plot - Fortification's to make wall or gate. Rotate plot as needed, then upgrade those to walls or gates except the corner wall. The corner wall pieces autodetect so they must be done after the main wall segments. Assign 2-4+ workers and for some buildings, an architect for building construction (see multiboard for construction info). Check out the pathing issues I described for yourself. Also units have trouble moving onto walls unless they are completely enclosed or built next to a structure or destructible (if you have any ideas how to fix any pathing bugs, let me know!). Walls have an ability to build ladder or stairs on the inner edge of walls + 'Engineer's can build ladders and stairs from 'Building Plot - Siege' that work on the outer side of walls.

The errors I previously described:
1) Gates and towers can be built inbetween and next to walls - they spawn door attachments when next to walls so that units can walk through them (example unit walks from one side of gate to the other side passing through each side's door). This feature only worked for initially built structures in the original map - not for newly constructed structures. The door's do spawn in appropriate locations however units are unable to walk through them.
2) Walls have an ability to spawns stairs and ladders nearby for units to climb up onto the wall. This works fine however I'd like for workers to be able to build ladders and stairs instead of spawning them from the wall. I tried this and the ladders + stairs built had no walkable pathing (ladders only work on outer side of the wall). Also I want to change the model and pathing of stairs because the pathing detection is buggy and too tight (I want to swap the old stairs for a wider straight stairs so that they fit more units and better pathing detection). I already have the new model and pathing however idk what to change in the trigger.
I think the lines to change stair pathing are at line: 766 .
JASS:
        elseif (BuildingID == libId_udg_Stairs) then //Stairs
            if (Type == 0) then
                return libId_udg_StairsWalkOp //Stairs Walk (Opened)
            elseif (Type == 1) then
                return libId_udg_StairsWalkCl1 //Stairs Walk (Closed 1)
            endif
        elseif (BuildingID ==
StairsWalkOp and StairsWalkCl1 are destructibles with custom pathing. Is this all I have to change? Along with the pathing used in destructibles + models.
3) The standard gates work, however there is a Big Gate that has no pathing at all so units can just walk through. The weird thing is that the I checked the pathing map and it looked fine... I think this might be an instance where the destructible pathing isn't spawning.
4) Ladder carriers use an ability to drop their ladder onto a wall so enemies can easily scale the wall. This works fine in the original castle defense via enemy invaders - however the player never used the ability. Idk if re-implementing it messed it up or that perhaps the ability is a dummy and that it was all done via a different trigger that I didn't implement which controlled the enemy invaders. Also there's an error message saying this isn't the correct type of wall.
 
Last edited:
Status
Not open for further replies.
Top