//TESH.scrollpos=0
//TESH.alwaysfold=0
Name | Type | is_array | initial_value |
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*
Requires:
-Jass NewGen Pack (can be found here: "http://www.wc3c.net/showthread.php?t=90999").
Helpful:
-Some crude knowledge with Jass, vJass or any other programming language (to be able to adjust the systems values to your need).
-Basic knowledge about the editor (importing models, creating stuff with the object editor).
-Basic knowledge about object Ids (First four letters when you press "Strg + D" in Object Editor, example: 'h001')
Note:
This pack of systems comes with its own unit indexer ("UnitDataSystem").
If you already use another unit indexer (or more precisely the "UnitUserData" fields) you have to change the "UnitDataSystem" to use a hashtable instead.
The "UnitInfoSystem" is optinal as it only visualizes data through a multiboard (like how many workers a building site requires and currently has).
Though if you don't set the values in "GetNeededWorkers" to 1 for every building it is recommended to use it and additionally you can easily make it to show other informations as well (see system header).
All used object Ids in this map have been altered to 'xZxx' (Standard are 'x0xx'), so if you don't use objects with altered Ids in your map there shouldn't be anymore problems with merging data.
Foreword:
The following instruction will tell you how to implement the fortification systems as as a whole into your map.
Implementation:
The easiest way to use this wall system is to use the blank map as start map and remove unneeded objects and scripts (just the "Fortification Systems" folder is required).
But if you want to implement the system into another map you have to port the needed objects (buildings/units, destructables and abilities) and scripts into that map.
First be sure to have a backup of your target map (in case anything goes wrong)!
Then copy the complete "Fortification Systems" folder into the target map.
After that export the data from this map with "Extensions" -> "Export Files" to your desktop.
Thereafter import the "Imports" folder with "Extensions" -> "Import Directory" into the target map.
Close, restart and reload the editor without additional saving (editor should automatically save map after importing).
Finally port all objects with "Extensions" -> "Merge Object Editor Data" into your map.
Close, restart and reload the editor again without additional saving.
Finished! You might then remove unneeded objects from your map (like the doodads, non fortification units and abilities, etc.).
What you can do, if you have Id collision:
If you have collisions there are two ways to remove these before merging the objects into the target map.
The first method is to change the Ids of the colliding objects by enabling "Grimoire" -> "Enable object editor hack" and then copy+pasting the objects, giving in new Ids and deleting the old, colliding objects.
The second method is to copy+paste every needed object one by one from this map into the target map and then adjusting the Ids at the top of "WallSystem" and "BuildingSiteSystem".
At last you can adjust the settings of the fortification systems by changing the values under the parts named "CUSTOMIZABLE PART".
If you want to add your own additional fortification buildings or remove some unwanted you have to look into the header descriptions of the individual fortification systems.
*/
//TESH.scrollpos=144
//TESH.alwaysfold=0
/*-------------------------------------------------------------
//Version number:
1.01
//Description:
This system contains all mayor object Ids used by systems in this map for easier adjustment.
Values in the parts under "PUBLIC/CUSTOMIZABLE PART" have to be adjusted.
//Changelog:
-1.01:
Initial version
-------------------------------------------------------------*/
library libId
//-------------------------
//PUBLIC/CUSTOMIZABLE PART:
//-------------------------
//Last used human Id: hZ3L
//Last used orc Id: oZ07
//Last used undead Id: uZ08
//Last used neutral Id: nZ03
globals
//Fortifications (Base):
public constant integer udg_WallUn = 'hZ0H' //Wall (Undamaged)
public constant integer udg_WallDa = 'hZ0S' //Wall (Damaged)
public constant integer udg_WallDe = 'hZ0N' //Wall (Destroyed)
public constant integer udg_WallOEUn = 'hZ1H' //Wall (Outer Edge) (Undamaged)
public constant integer udg_WallOEDa = 'hZ1I' //Wall (Outer Edge) (Damaged)
public constant integer udg_WallOEDe = 'hZ1J' //Wall (Outer Edge) (Destroyed)
public constant integer udg_WallIEUn = 'hZ1Y' //Wall (Inner Edge) (Undamaged)
public constant integer udg_WallIEDa = 'hZ1W' //Wall (Inner Edge) (Damaged)
public constant integer udg_WallIEDe = 'hZ1X' //Wall (Inner Edge) (Destroyed)
public constant integer udg_PalisadeUn = 'hZ22' //Palisade (Undamaged)
public constant integer udg_PalisadeDa = 'hZ26' //Palisade (Damaged)
public constant integer udg_PalisadeDe = 'hZ27' //Palisade (Destroyed)
public constant integer udg_PalisadeOEUn = 'hZ28' //Palisade (Outer Edge) (Undamaged)
public constant integer udg_PalisadeOEDa = 'hZ2A' //Palisade (Outer Edge) (Damaged)
public constant integer udg_PalisadeOEDe = 'hZ29' //Palisade (Outer Edge) (Destroyed)
public constant integer udg_PalisadeIEUn = 'hZ2B' //Palisade (Inner Edge) (Undamaged)
public constant integer udg_PalisadeIEDa = 'hZ2D' //Palisade (Inner Edge) (Damaged)
public constant integer udg_PalisadeIEDe = 'hZ2C' //Palisade (Inner Edge) (Destroyed)
public constant integer udg_PalisadeLadderUn = 'hZ2I' //Palisade (Ladder) (Undamaged)
public constant integer udg_PalisadeLadderDa = 'hZ2K' //Palisade (Ladder) (Damaged)
public constant integer udg_TowerUn = 'hZ01' //Tower (Undamaged)
public constant integer udg_TowerDa = 'hZ19' //Tower (Damaged)
public constant integer udg_TowerDe = 'hZ14' //Tower (Destroyed)
public constant integer udg_TowerOEUn = 'hZ07' //Tower (Outer Edge) (Undamaged)
public constant integer udg_TowerOEDa = 'hZ09' //Tower (Outer Edge) (Damaged)
public constant integer udg_TowerOEDe = 'hZ0A' //Tower (Outer Edge) (Destroyed)
public constant integer udg_TowerIEUn = 'hZ1V' //Tower (Inner Edge) (Undamaged)
public constant integer udg_TowerIEDa = 'hZ1T' //Tower (Inner Edge) (Damaged)
public constant integer udg_TowerIEDe = 'hZ1U' //Tower (Inner Edge) (Destroyed)
public constant integer udg_BigTowerUn = 'hZ0O' //Big tower (Undamaged)
public constant integer udg_BigTowerDa = 'hZ17' //Big tower (Damaged)
public constant integer udg_BigTowerDe = 'hZ16' //Big tower (Destroyed)
public constant integer udg_BigTowerOEUn = 'hZ18' //Big tower (Outer Edge) (Undamaged)
public constant integer udg_BigTowerOEDa = 'hZ1L' //Big tower (Outer Edge) (Damaged)
public constant integer udg_BigTowerOEDe = 'hZ1A' //Big tower (Outer Edge) (Destroyed)
public constant integer udg_BigTowerIEUn = 'hZ1S' //Big tower (Inner Edge) (Undamaged)
public constant integer udg_BigTowerIEDa = 'hZ1Q' //Big tower (Inner Edge) (Damaged)
public constant integer udg_BigTowerIEDe = 'hZ1R' //Big tower (Inner Edge) (Destroyed)
public constant integer udg_DrumTowerUn = 'hZ2R' //Drum tower (Undamaged)
public constant integer udg_DrumTowerDa = 'hZ33' //Drum tower (Damaged)
public constant integer udg_DrumTowerDe = 'hZ32' //Drum tower (Destroyed)
public constant integer udg_DrumTowerOEUn = 'hZ2V' //Drum tower (Outer Edge) (Undamaged)
public constant integer udg_DrumTowerOEDa = 'hZ2X' //Drum tower (Outer Edge) (Damaged)
public constant integer udg_DrumTowerOEDe = 'hZ2W' //Drum tower (Outer Edge) (Destroyed)
public constant integer udg_DrumTowerIEUn = 'hZ2Z' //Drum tower (Inner Edge) (Undamaged)
public constant integer udg_DrumTowerIEDa = 'hZ31' //Drum tower (Inner Edge) (Damaged)
public constant integer udg_DrumTowerIEDe = 'hZ30' //Drum tower (Inner Edge) (Destroyed)
public constant integer udg_GateCl = 'hZ02' //Gate (Closed)
public constant integer udg_GateOp = 'hZ03' //Gate (Opened)
public constant integer udg_GateDa = 'hZ04' //Gate (Damaged)
public constant integer udg_BigGateCl = 'hZ0E' //Big gate (Closed)
public constant integer udg_BigGateOp = 'hZ0C' //Big gate (Opened)
public constant integer udg_BigGateDa = 'hZ0D' //Big gate (Damaged)
public constant integer udg_PalisadeGateCl = 'hZ20' //Palisade gate (Closed)
public constant integer udg_PalisadeGateOp = 'hZ3H' //Palisade gate (Opened)
public constant integer udg_PalisadeGateDa = 'hZ3G' //Palisade gate (Damaged)
public constant integer udg_Stairs = 'hZ1C' //Stairs
public constant integer udg_LadderWall = 'hZ0W' //Ladder (Wall)
public constant integer udg_LadderPalisade = 'hZ2G' //Ladder (Palisade)
//Fortifications (Init):
public constant integer udg_WallIP = 'hZ08' //Wall (Init Placement)
public constant integer udg_WallDaIP = 'hZ0P' //Wall (Damaged) (Init Placement)
public constant integer udg_WallDeIP = 'hZ1E' //Wall (Destroyed) (Init Placement)
public constant integer udg_WallOEIP = 'hZ1K' //Wall (Outer Edge) (Init Placement)
public constant integer udg_WallIEIP = 'hZ1Z' //Wall (Inner Edge) (Init Placement)
public constant integer udg_PalisadeIP = 'hZ2E' //Palisade (Init Placement)
public constant integer udg_PalisadeLadderIP = 'hZ2J' //Palisade (Ladder) (Init Placement)
public constant integer udg_PalisadeOEIP = 'hZ2F' //Palisade (Outer Edge) (Init Placement)
public constant integer udg_TowerIP = 'hZ1N' //Tower (Init Placement)
public constant integer udg_TowerOEIP = 'hZ0X' //Tower (Outer Edge) (Init Placement)
public constant integer udg_GateClIP = 'hZ1B' //Gate (Closed) (Init Placement)
public constant integer udg_BigGateOpIP = 'hZ0M' //Big gate (Opened) (Init Placement)
public constant integer udg_PalisadeGateOpIP = 'hZ3J' //Palisade gate (Opened) (Init Placement)
public constant integer udg_BigTowerIP = 'hZ15' //Big tower (Init Placement)
public constant integer udg_BigTowerOEDaIP = 'hZ1M' //Big tower (Outer Edge) (Damaged) (Init Placement)
public constant integer udg_DrumTowerOEIP = 'hZ2U' //Drum tower (Outer Edge) (Init Placement)
public constant integer udg_StairsIP = 'hZ1D' //Stairs (Init Placement)
public constant integer udg_LadderWallIP = 'hZ0Y' //Ladder (Init Placement) (Wall)
public constant integer udg_LadderPalisadeIP = 'hZ2H' //Ladder (Init Placement) (Palisade)
//Fortifications (Other):
public constant integer udg_GateClDu = 'hZ0F' //Gate (Closed) (Dummy)
public constant integer udg_GateOpDu = 'hZ24' //Gate (Opened) (Dummy)
public constant integer udg_BigGateClDu = 'hZ0G' //Big gate (Closed) (Dummy)
public constant integer udg_BigGateOpDu = 'hZ23' //Big gate (Opened) (Dummy)
public constant integer udg_PalisadeGateClDu = 'hZ3I' //Palisade gate (Closed) (Dummy)
public constant integer udg_PalisadeGateOpDu = 'hZ3K' //Palisade gate (Opened) (Dummy)
//Building sites:
public constant integer udg_BuildingSiteTiny = 'hZ10' //Building site (tiny)
public constant integer udg_BuildingSiteLittle = 'hZ1F' //Building site (little)
public constant integer udg_BuildingSiteSmall = 'hZ0Q' //Building site (small)
public constant integer udg_BuildingSiteBig = 'hZ0I' //Building site (big)
public constant integer udg_BuildingSiteVeryLarge = 'hZ11' //Building site (very large)
public constant integer udg_BuildingSiteStairs = 'hZ05' //Building site (Stairs)
public constant integer udg_BuildingSiteLadder = 'hZ12' //Building site (Ladder)
public constant integer udg_BuildingSiteEdge = 'hZ21' //Building site (Edge)
//Buildings (Human):
public constant integer udg_Barricade = 'hZ0Z' //Barricade
public constant integer udg_ThatchedCottages1 = 'hZ3B' //Thatched cottages (Level1)
public constant integer udg_ThatchedCottages2 = 'hZ3C' //Thatched cottages (Level2)
public constant integer udg_ThatchedCottages3 = 'hZ3D' //Thatched cottages (Level3)
public constant integer udg_ThatchedCottages4 = 'hZ3E' //Thatched cottages (Level4)
public constant integer udg_VillageHouse1 = 'hZ0J' //Village house (Level1)
public constant integer udg_VillageHouse2 = 'hZ0K' //Village house (Level2)
public constant integer udg_VillageHouse3 = 'hZ2S' //Village house (Level3)
public constant integer udg_VillageHouse4 = 'hZ2T' //Village house (Level4)
public constant integer udg_VillageHouse5 = 'hZ3S' //Village house (Level5)
public constant integer udg_MotteAndBailey = 'hZ0L' //Motte-and-bailey
public constant integer udg_SmallCastle = 'hZ0R' //Small castle
public constant integer udg_BigCastle = 'hZ0U' //Big castle
public constant integer udg_Barracks = 'hZ2Q' //Barracks
public constant integer udg_VillageSquare = 'hZ2Y' //Village square
//Standard units (Human):
public constant integer udg_Worker = 'hZ00' //Worker
public constant integer udg_Architect = 'hZ38' //Architect
public constant integer udg_Ballista = 'hZ39' //Ballista
public constant integer udg_LadderCarrier = 'hZ2N' //Ladder Carrier
public constant integer udg_ArmouredSwordman = 'hZ13' //Armoured Swordman
public constant integer udg_Pikeman = 'hZ2L' //Pikeman
public constant integer udg_Knight = 'hZ0B' //Knight
public constant integer udg_MortarTeam = 'hZ2P' //Mortar Team
public constant integer udg_Priest = 'hZ0V' //Priest
public constant integer udg_Paladin = 'hZ25' //Paladin
public constant integer udg_Archer = 'hZ34' //Archer
public constant integer udg_Scout = 'hZ35' //Scout
public constant integer udg_AxeWarrior = 'hZ36' //Axe Warrior
public constant integer udg_SpearThrower = 'hZ37' //Spear Thrower
public constant integer udg_HumanTransportShip = 'hZ2M' //Transport Ship
public constant integer udg_HumanWarShip = 'hZ2O' //War-Ship
//Standard units (Heroes):
public constant integer udg_Commander = 'HZ3L' //Commander
//Special units (Human):
public constant integer udg_AvatarOfLight = 'hZ3F' //Avatar of Light
public constant integer udg_Militia = 'hZ1G' //Militia
public constant integer udg_Trap = 'hZ3A' //Trap
public constant integer udg_Sheep = 'hZ0T' //Sheep
public constant integer udg_FlyingSheep = 'hZ1O' //Flying Sheep
public constant integer udg_Mage = 'hZ06' //Mage
//Standard units (Orc):
public constant integer udg_Peon = 'oZ03' //Peon
public constant integer udg_Grunt = 'oZ00' //Grunt
public constant integer udg_Raider = 'oZ04' //Raider
public constant integer udg_TrollHeadhunter = 'oZ02' //Troll Headhunter
public constant integer udg_Devastor = 'oZ01' //Devastor
public constant integer udg_Shaman = 'oZ05' //Shaman
//Special units (Orc):
public constant integer udg_OrcTransportShip = 'oZ06' //Transport Ship
public constant integer udg_OrcWarShip = 'oZ07' //War-Ship
//Buildings (Undead):
public constant integer udg_Graveyard = 'uZ00' //Graveyard
//Standard units (Undead):
public constant integer udg_Ghul = 'uZ01' //Ghul
public constant integer udg_Abomination = 'uZ02' //Abomination
public constant integer udg_MeatWagon = 'uZ06' //Meat Wagon
public constant integer udg_SkeletonWarrior = 'uZ03' //Skeleton Warrior
public constant integer udg_SkeletonMage = 'uZ04' //Skeleton Mage
public constant integer udg_SkeletonDragon = 'uZ05' //Skeleton Dragon
public constant integer udg_Zombie = 'uZ07' //Zombie
public constant integer udg_SkeletonArcher = 'uZ08' //Skeleton Archer
//Buildings (Neutral):
public constant integer udg_Goldmine = 'nZ00' //Goldmine
//Special units (Neutral):
public constant integer udg_PathingCheckDummy = 'nZ04' //Pathing check dunmmy
public constant integer udg_Arrow = 'nZ01' //Arrow
public constant integer udg_Dummy = 'nZ02' //Dummy
public constant integer udg_SpawnPoint = 'nZ03' //Spawn point
endglobals
//Last used destructable Id: BZ36
globals
//Fortifications (Walk destructables):
public constant integer udg_WallWalkOp = 'BZ0C' //Wall Walk (Opened)
public constant integer udg_WallWalkCl1 = 'BZ0R' //Wall Walk (Closed 1)
public constant integer udg_WallWalkCl2 = 'BZ13' //Wall Walk (Closed 2)
public constant integer udg_WallWalkCl12 = 'BZ0O' //Wall Walk (Closed 1&2)
public constant integer udg_WallWalkCl3 = 'BZ1C' //Wall Walk (Closed 3)
public constant integer udg_WallWalkCl13 = 'BZ1D' //Wall Walk (Closed 1&3)
public constant integer udg_WallWalkCl23 = 'BZ1E' //Wall Walk (Closed 2&3)
public constant integer udg_WallWalkCl123 = 'BZ1F' //Wall Walk (Closed 1&2&3)
public constant integer udg_WallWalkCl4 = 'BZ02' //Wall Walk (Closed 4)
public constant integer udg_WallWalkCl14 = 'BZ04' //Wall Walk (Closed 1&4)
public constant integer udg_WallWalkCl24 = 'BZ05' //Wall Walk (Closed 2&4)
public constant integer udg_WallWalkCl124 = 'BZ08' //Wall Walk (Closed 1&2&4)
public constant integer udg_WallWalkCl34 = 'BZ06' //Wall Walk (Closed 3&4)
public constant integer udg_WallWalkCl134 = 'BZ09' //Wall Walk (Closed 1&3&4)
public constant integer udg_WallWalkCl234 = 'BZ0A' //Wall Walk (Closed 2&3&4)
public constant integer udg_WallWalkCl1234 = 'BZ07' //Wall Walk (Closed 1&2&3&4)
public constant integer udg_WallOEWalkOp = 'BZ1M' //Wall Outer Edge Walk (Opened)
public constant integer udg_WallOEWalkCl1 = 'BZ1L' //Wall Outer Edge Walk (Closed 1)
public constant integer udg_WallOEWalkCl2 = 'BZ1J' //Wall Outer Edge Walk (Closed 2)
public constant integer udg_WallOEWalkCl12 = 'BZ1K' //Wall Outer Edge Walk (Closed 1&2)
public constant integer udg_WallOEWalkCl3 = 'BZ0B' //Wall Outer Edge Walk (Closed 3)
public constant integer udg_WallOEWalkCl13 = 'BZ0G' //Wall Outer Edge Walk (Closed 1&3)
public constant integer udg_WallOEWalkCl23 = 'BZ0I' //Wall Outer Edge Walk (Closed 2&3)
public constant integer udg_WallOEWalkCl123 = 'BZ0E' //Wall Outer Edge Walk (Closed 1&2&3)
public constant integer udg_WallIEWalkOp = 'BZ1Q' //Wall Inner Edge Walk (Opened)
public constant integer udg_WallIEWalkCl1 = 'BZ14' //Wall Inner Edge Walk (Closed 1)
public constant integer udg_WallIEWalkCl2 = 'BZ1P' //Wall Inner Edge Walk (Closed 2)
public constant integer udg_WallIEWalkCl12 = 'BZ1O' //Wall Inner Edge Walk (Closed 1&2)
public constant integer udg_PalisadeWalkOp = 'BZ22' //Palisade Walk (Opened)
public constant integer udg_PalisadeWalkCl1 = 'BZ2B' //Palisade Walk (Closed 1)
public constant integer udg_PalisadeWalkCl2 = 'BZ26' //Palisade Walk (Closed 2)
public constant integer udg_PalisadeWalkCl12 = 'BZ2E' //Palisade Walk (Closed 1&2)
public constant integer udg_PalisadeWalkCl3 = 'BZ24' //Palisade Walk (Closed 3)
public constant integer udg_PalisadeWalkCl13 = 'BZ2U' //Palisade Walk (Closed 1&3)
public constant integer udg_PalisadeWalkCl23 = 'BZ29' //Palisade Walk (Closed 2&3)
public constant integer udg_PalisadeWalkCl123 = 'BZ2G' //Palisade Walk (Closed 1&2&3)
public constant integer udg_PalisadeWalkCl4 = 'BZ23' //Palisade Walk (Closed 4)
public constant integer udg_PalisadeWalkCl14 = 'BZ2C' //Palisade Walk (Closed 1&4)
public constant integer udg_PalisadeWalkCl24 = 'BZ28' //Palisade Walk (Closed 2&4)
public constant integer udg_PalisadeWalkCl124 = 'BZ2F' //Palisade Walk (Closed 1&2&4)
public constant integer udg_PalisadeWalkCl34 = 'BZ25' //Palisade Walk (Closed 3&4)
public constant integer udg_PalisadeWalkCl134 = 'BZ2D' //Palisade Walk (Closed 1&3&4)
public constant integer udg_PalisadeWalkCl234 = 'BZ2A' //Palisade Walk (Closed 2&3&4)
public constant integer udg_PalisadeWalkCl1234 = 'BZ2H' //Palisade Walk (Closed 1&2&3&4)
public constant integer udg_PalisadeOEWalkOp = 'BZ2I' //Palisade Outer Edge Walk (Opened)
public constant integer udg_PalisadeOEWalkCl1 = 'BZ2M' //Palisade Outer Edge Walk (Closed 1)
public constant integer udg_PalisadeOEWalkCl2 = 'BZ2K' //Palisade Outer Edge Walk (Closed 2)
public constant integer udg_PalisadeOEWalkCl12 = 'BZ2O' //Palisade Outer Edge Walk (Closed 1&2)
public constant integer udg_PalisadeOEWalkCl3 = 'BZ2J' //Palisade Outer Edge Walk (Closed 3)
public constant integer udg_PalisadeOEWalkCl13 = 'BZ2N' //Palisade Outer Edge Walk (Closed 1&3)
public constant integer udg_PalisadeOEWalkCl23 = 'BZ2L' //Palisade Outer Edge Walk (Closed 2&3)
public constant integer udg_PalisadeOEWalkCl123 = 'BZ2P' //Palisade Outer Edge Walk (Closed 1&2&3)
public constant integer udg_PalisadeIEWalkOp = 'BZ2Q' //Palisade Inner Edge Walk (Opened)
public constant integer udg_PalisadeIEWalkCl1 = 'BZ2S' //Palisade Inner Edge Walk (Closed 1)
public constant integer udg_PalisadeIEWalkCl2 = 'BZ2R' //Palisade Inner Edge Walk (Closed 2)
public constant integer udg_PalisadeIEWalkCl12 = 'BZ2T' //Palisade Inner Edge Walk (Closed 1&2)
public constant integer udg_TowerWalkOp = 'BZ16' //Tower Walk (Opened)
public constant integer udg_TowerWalkCl1 = 'BZ18' //Tower Walk (Closed 1)
public constant integer udg_TowerWalkCl2 = 'BZ17' //Tower Walk (Closed 2)
public constant integer udg_TowerWalkCl12 = 'BZ12' //Tower Walk (Closed 1&2)
public constant integer udg_TowerOEWalkOp = 'BZ19' //Tower Outer Edge Walk (Opened)
public constant integer udg_TowerOEWalkCl1 = 'BZ15' //Tower Outer Edge Walk (Closed 1)
public constant integer udg_TowerOEWalkCl2 = 'BZ1A' //Tower Outer Edge Walk (Closed 2)
public constant integer udg_TowerOEWalkCl12 = 'BZ1B' //Tower Outer Edge Walk (Closed 1&2)
public constant integer udg_TowerIEWalkOp = 'BZ1G' //Tower Inner Edge Walk (Opened)
public constant integer udg_TowerIEWalkCl1 = 'BZ1H' //Tower Inner Edge Walk (Closed 1)
public constant integer udg_TowerIEWalkCl2 = 'BZ1I' //Tower Inner Edge Walk (Closed 2)
public constant integer udg_TowerIEWalkCl12 = 'BZ11' //Tower Inner Edge Walk (Closed 1&2)
public constant integer udg_BigTowerWalkOp = 'BZ0J' //Big Tower Walk (Opened)
public constant integer udg_BigTowerWalkCl1 = 'BZ0L' //Big Tower Walk (Closed 1)
public constant integer udg_BigTowerWalkCl2 = 'BZ0K' //Big Tower Walk (Closed 2)
public constant integer udg_BigTowerWalkCl12 = 'BZ0M' //Big Tower Walk (Closed 1&2)
public constant integer udg_BigTowerOEWalkOp = 'BZ0N' //Big Tower Outer Edge Walk (Opened)
public constant integer udg_BigTowerOEWalkCl1 = 'BZ0T' //Big Tower Outer Edge Walk (Closed 1)
public constant integer udg_BigTowerOEWalkCl2 = 'BZ0U' //Big Tower Outer Edge Walk (Closed 2)
public constant integer udg_BigTowerOEWalkCl12 = 'BZ0Q' //Big Tower Outer Edge Walk (Closed 1&2)
public constant integer udg_BigTowerIEWalkOp = 'BZ10' //Big Tower Inner Edge Walk (Opened)
public constant integer udg_BigTowerIEWalkCl1 = 'BZ0Y' //Big Tower Inner Edge Walk (Closed 1)
public constant integer udg_BigTowerIEWalkCl2 = 'BZ0Z' //Big Tower Inner Edge Walk (Closed 2)
public constant integer udg_BigTowerIEWalkCl12 = 'BZ0X' //Big Tower Inner Edge Walk (Closed 1&2)
public constant integer udg_DrumTowerWalkOp = 'BZ35' //Drum Tower Walk (Opened)
public constant integer udg_DrumTowerWalkCl1 = 'BZ31' //Drum Tower Walk (Closed 1)
public constant integer udg_DrumTowerWalkCl2 = 'BZ2Z' //Drum Tower Walk (Closed 2)
public constant integer udg_DrumTowerWalkCl12 = 'BZ34' //Drum Tower Walk (Closed 1&2)
public constant integer udg_DrumTowerOEWalkOp = 'BZ33' //Drum Tower Outer Edge Walk (Opened)
public constant integer udg_DrumTowerOEWalkCl1 = 'BZ31' //Drum Tower Outer Edge Walk (Closed 1)
public constant integer udg_DrumTowerOEWalkCl2 = 'BZ32' //Drum Tower Outer Edge Walk (Closed 2)
public constant integer udg_DrumTowerOEWalkCl12 = 'BZ2Y' //Drum Tower Outer Edge Walk (Closed 1&2)
public constant integer udg_DrumTowerIEWalkOp = 'BZ2X' //Drum Tower Inner Edge Walk (Opened)
public constant integer udg_DrumTowerIEWalkCl1 = 'BZ2V' //Drum Tower Inner Edge Walk (Closed 1)
public constant integer udg_DrumTowerIEWalkCl2 = 'BZ2W' //Drum Tower Inner Edge Walk (Closed 2)
public constant integer udg_DrumTowerIEWalkCl12 = 'BZ27' //Drum Tower Inner Edge Walk (Closed 1&2)
public constant integer udg_StairsWalkOp = 'BZ0S' //Stairs Walk (Opened)
public constant integer udg_StairsWalkCl1 = 'BZ1N' //Stairs Walk (Closed 1)
public constant integer udg_LadderWalkOp = 'BZ00' //Ladder Walk (Opened)
public constant integer udg_LadderWalkCl1 = 'BZ01' //Ladder Walk (Closed 1)
public constant integer udg_LadderWalkSmallOp = 'BZ20' //Ladder Walk Small (Opened)
public constant integer udg_LadderWalkSmallCl1 = 'BZ21' //Ladder Walk Small (Closed 1)
//Fortifications (Pathing blockers):
public constant integer udg_PathingBlockerTiny = 'BZ1V' //Pathing Blocker (tiny)
public constant integer udg_PathingBlockerLittle = 'BZ1R' //Pathing Blocker (little)
public constant integer udg_PathingBlockerGate = 'BZ1W' //Pathing Blocker (Gate)
public constant integer udg_PathingBlockerBigGate = 'BZ1Z' //Pathing Blocker (Big gate)
public constant integer udg_PathingBlockerPalisadeGate = 'BZ30' //Pathing Blocker (Palisade gate)
endglobals
//Last used ability Id: AZ1V
//Last used buff Id: BZ0N
globals
//Fortification and BuildingSite System:
public constant integer udg_AddLadders = 'AZ1K' //Add ladders
public constant integer udg_AddStairs = 'AZ0U' //Add stairs
public constant integer udg_UseSiegeLadder = 'AZ09' //Use siege ladder
public constant integer udg_TurnBuilding = 'AZ0Q' //Turn building
public constant integer udg_BuildingFacingRight = 'AZ01' //Building facing (right)
public constant integer udg_BuildingFacingUp = 'AZ08' //Building facing (up)
public constant integer udg_BuildingFacingLeft = 'AZ05' //Building facing (left)
public constant integer udg_BuildingFacingDown = 'AZ0L' //Building facing (down)
public constant integer udg_RemoveBuilding = 'AZ07' //Remove building
public constant integer udg_Duplicate = 'AZ0N' //Duplicate
public constant integer udg_Construct = 'AZ0M' //Construct
public constant integer udg_AddConstructionBuff = 'AZ0P' //Add construction buff
//Unit abilities:
public constant integer udg_InfectionAttack = 'AZ16' //Infection attack
public constant integer udg_AddInfection = 'AZ0T' //Add infection
public constant integer udg_EnsnareRaider = 'AZ0V' //Ensnare (Raider)
public constant integer udg_AngleOfLight = 'AZ18' //Angle of Light
public constant integer udg_HolyLightAn = 'AZ1D' //Holy light (Angle of Light)
public constant integer udg_HolyLightAv = 'AZ1H' //Holy light (Avatar of Light)
public constant integer udg_PassiveInvisibleAbilities = 'AZ1I' //Passive invisible abilities
public constant integer udg_Dispel = 'AZ10' //Dispel
public constant integer udg_RaiseZombie = 'AZ0Z' //Raise zombie
public constant integer udg_AttackingCivilian = 'AZ1L' //Attacking civilian
//Attachments:
public constant integer udg_SiegeLadderAttachment = 'AZ0B' //Siege Ladder (Attachment)
//Buffs:
public constant integer udg_InvisibilityBuff = 'BZ0A' //Invisibility
public constant integer udg_InfectedBuff = 'BZ05' //Infected
public constant integer udg_ConstructingBuff = 'BZ06' //Constructing
endglobals
endlibrary
//TESH.scrollpos=51
//TESH.alwaysfold=0
/*-------------------------------------------------------------
//Version number:
1.02
//Description:
This system gives any unit that is added to it an unique ObjectNumber.
Its speciality is its feature to support easy, unproblematic unit type changing.
Use "ChangeUnit" whenever an added unit shall change it appearance (unit type).
Whenever you'd store a unit handle use the ObjectNumber instead. This way you always get the right unit handle when you load it with "GetUnit".
Clusters work the same way just for group handls. So you always get the right unit handles when you load a cluster with "GetGroup".
Use "RemoveObjectUnit" whenever you remove a unit. Don't use the normal "RemoveUnit" (only if you're absolutely sure it has no ObjectNumber).
To add simple additional attributes to an unit, add it to the textmacro "AddAttributes" und add an additional call of the textmacro "PublicAttributeFunctions" with proper attributes.
To add more complexe additional attributes and other stuff to an unit it is recommended to use subsystems. The corresponding slot number of such a subsystem can then be saved as SystemNumber for the unit in this system.
For more info look at the descriptions at the public functions.
This system uses the "UnitUserData" for getting the ObjectNumber of an unit (fastest), but can be changed through "udg_UseUnitUserData = false" to use a hashtable instead (slower) if it would conflict with another system you use.
Values in the part under "CUSTOMIZABLE PART" have to be adjusted.
//Customizable/Public functions:
public function ObjectAttributes_Get$ATTRIBUTE$ takes integer ObjectNumber returns $TYPE$
public function ObjectAttributes_Get$ATTRIBUTE$OfUnit takes unit Unit returns $TYPE$
public function ObjectAttributes_Set$ATTRIBUTE$ takes integer ObjectNumber, $TYPE$ $ATTRIBUTE$ returns nothing
public function ObjectAttributes_Set$ATTRIBUTE$OfUnit takes unit Unit, $TYPE$ $ATTRIBUTE$ returns nothing
//Public functions:
public function GetObjectNumber takes unit Unit, boolean AddMissing returns integer
public function GetSystemNumber takes integer ObjectNumber, integer SystemSlot returns integer
public function GetSystemNumberOfUnit takes unit Unit, integer SystemSlot returns integer
public function SetSystemNumber takes integer ObjectNumber, integer SystemSlot, integer Number returns nothing
public function SetSystemNumberOfUnit takes unit Unit, integer SystemSlot, integer Number returns integer
public function ChangeUnit takes unit OldUnit, unit NewUnit returns nothing
public function RemoveObject takes integer ObjectNumber returns nothing
public function RemoveObjectUnit takes unit Unit returns nothing
public function SetNoRecycling takes integer ObjectNumber, boolean NoRecycling returns nothing
public function SetNoRecyclingOfUnit takes unit Unit, boolean NoRecycling returns integer
public function GetUnit takes integer ObjectNumber returns unit
public function GetUnitType takes integer ObjectNumber returns integer
public function CreateCluster takes nothing returns integer
public function RemoveCluster takes integer ClusterNumber returns nothing
public function ClusterChangeObject takes integer ClusterNumber, integer ObjectNumber, boolean ObjectAdd returns nothing
public function ClusterChangeCluster takes integer SourceClusterNumber, integer TargetClusterNumber, boolean AddTargetCluster returns nothing
public function GetGroup takes integer ClusterNumber returns group
public function GetClusterSize takes integer ClusterNumber returns integer
public function IsObjectInCluster takes integer ClusterNumber, integer ObjectNumber returns boolean
public function GetClusterFirstObject takes integer ClusterNumber returns integer
public function SetClusterSystemNumbers takes integer ClusterNumber, integer SystemSlot, integer Number returns nothing
//Changelog:
-1.01:
Initial version
-1.02:
Added udg_HashtableLink and udg_UsedChildKey to be able to use an extern hashtable
Added an integer to Clusters to store their member count
Replaced SystemNumbers array with individual SystemNumber variables to avoid too big Object structs
Added public constant SystemNumbers for easier number assignment
All unused data slots get cleared and added to the unused stash instead of being removed
-------------------------------------------------------------*/
library libUnitDat initializer Init_UnitDataSystem
//------------------
//CUSTOMIZABLE PART:
//------------------
globals
private constant integer udg_CountPlayers = 16 //Highest player slot in use
private constant boolean udg_UseUnitUserData = true //Uses a slower hashtable for units instead when deactivated
private constant hashtable udg_HashtableLink = null //If udg_HashtableLink != null will use the linked hashtable instead of an own private hashtable
private constant integer udg_UsedChildKey = 0 //The child key that is used for storing the ObjectNumber (HandleId is parent key)
private constant integer udg_MaxObjects = udg_CountPlayers * 500
private constant integer udg_MaxSystemNumbers = 2
private constant integer udg_MaxClusters = udg_CountPlayers * 100
endglobals
//! textmacro AddAttributes
// public integer ExampleInteger = 0
//! endtextmacro
//! textmacro ClearAttributes
// set this.ExampleInteger = 0
//! endtextmacro
//-------------------------
//CUSTOMIZABLE/PUBLIC PART:
//-------------------------
globals
public constant integer udg_SystemNumber_WallSystem = 1
public constant integer udg_SystemNumber_BuildingSiteSystem = 2
endglobals
//-------------
//PRIVATE PART:
//-------------
globals
private integer udg_CountGroupSize_IntTemp1 = 0
endglobals
private function CountGroupSize takes nothing returns nothing
set udg_CountGroupSize_IntTemp1 = udg_CountGroupSize_IntTemp1 + 1
endfunction
//-----------------
//DECLARATION PART:
//-----------------
globals
private constant integer udg_MaxObjectsP = udg_MaxObjects + 1
private constant integer udg_MaxClustersP = udg_MaxClusters + 1
endglobals
private struct Object [8001] //udg_MaxObjectsP
unit Unit = null
boolean NoRecycling = false
integer SystemNumber01 = 0
integer SystemNumber02 = 0
//! runtextmacro AddAttributes()
method GetSystemNumberBySlot takes integer SlotNumber returns integer
if (SlotNumber == 1) then
return this.SystemNumber01
elseif (SlotNumber == 2) then
return this.SystemNumber02
endif
return 0
endmethod
method SetSystemNumberBySlot takes integer SlotNumber, integer SystemNumber returns nothing
if (SlotNumber == 1) then
set this.SystemNumber01 = SystemNumber
elseif (SlotNumber == 2) then
set this.SystemNumber02 = SystemNumber
endif
endmethod
method remove takes nothing returns nothing
local integer IntLoop1 = 1
set this.Unit = null
set this.NoRecycling = false
loop
exitwhen IntLoop1 > udg_MaxSystemNumbers
call this.SetSystemNumberBySlot(IntLoop1, 0)
set IntLoop1 = IntLoop1 + 1
endloop
//! runtextmacro ClearAttributes()
call this.destroy()
endmethod
method Clear takes nothing returns nothing
local integer IntLoop1 = 1
set this.Unit = null
set this.NoRecycling = false
loop
exitwhen IntLoop1 > udg_MaxSystemNumbers
call this.SetSystemNumberBySlot(IntLoop1, 0)
set IntLoop1 = IntLoop1 + 1
endloop
//! runtextmacro ClearAttributes()
endmethod
method New takes unit Unit returns nothing
local integer IntLoop1 = 1
set this.Unit = Unit
set this.NoRecycling = false
loop
exitwhen IntLoop1 > udg_MaxSystemNumbers
call this.SetSystemNumberBySlot(IntLoop1, 0)
set IntLoop1 = IntLoop1 + 1
endloop
//! runtextmacro ClearAttributes()
endmethod
endstruct
private struct Cluster [1601] //udg_MaxClustersP
group Group = null
integer Size = 0
method remove takes nothing returns nothing
call DestroyGroup(this.Group)
set this.Group = null
call this.destroy()
endmethod
method Clear takes nothing returns nothing
call GroupClear(this.Group)
set this.Size = 0
endmethod
method New takes nothing returns nothing
set this.Group = CreateGroup()
set this.Size = 0
endmethod
endstruct
globals
private Object array udg_Objects [udg_MaxObjectsP]
private integer udg_CountObjects = 0
private integer array udg_UnusedObjectNumbers [udg_MaxObjectsP]
private integer udg_CountUnusedObjectNumbers = 0
private Cluster array udg_Clusters [udg_MaxClustersP]
private integer udg_CountClusters = 0
private integer array udg_UnusedClusterNumbers [udg_MaxClustersP]
private integer udg_CountUnusedClusterNumbers = 0
private hashtable udg_Hashtable = udg_HashtableLink
private constant trigger gg_trg_UnitDies = CreateTrigger()
endglobals
//-------------
//PRIVATE PART:
//-------------
globals
private group udg_CreateCopiedGroup_GroupTemp1 = null
endglobals
private function CreateCopiedGroup_Function1 takes nothing returns nothing
call GroupAddUnit(udg_CreateCopiedGroup_GroupTemp1, GetEnumUnit())
endfunction
private function CreateCopiedGroup takes group InputGroup returns group
set udg_CreateCopiedGroup_GroupTemp1 = CreateGroup()
call ForGroup(InputGroup, function CreateCopiedGroup_Function1)
return udg_CreateCopiedGroup_GroupTemp1
endfunction
private function GetUnitObjectNumber takes unit Unit returns integer
if (udg_UseUnitUserData) then
return GetUnitUserData(Unit)
else
return LoadInteger(udg_Hashtable, GetHandleId(Unit), udg_UsedChildKey)
endif
endfunction
private function SetUnitObjectNumber takes unit Unit, integer ObjectNumber returns nothing
if (udg_UseUnitUserData) then
call SetUnitUserData(Unit, ObjectNumber)
else
call SaveInteger(udg_Hashtable, GetHandleId(Unit), udg_UsedChildKey, ObjectNumber)
endif
endfunction
private function AddObject takes unit Unit returns integer
local integer NewObjectNumber
if (udg_CountUnusedObjectNumbers > 0) then
set NewObjectNumber = udg_UnusedObjectNumbers[udg_CountUnusedObjectNumbers]
set udg_CountUnusedObjectNumbers = udg_CountUnusedObjectNumbers - 1
else
if (udg_CountObjects + 1 > udg_MaxObjects) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Too many objects")
return 0
endif
set udg_CountObjects = udg_CountObjects + 1
set udg_Objects[udg_CountObjects] = Object.create()
if (udg_Objects[udg_CountObjects] == 0) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Object struct cap exceeded")
return 0
endif
set NewObjectNumber = udg_CountObjects
endif
call udg_Objects[NewObjectNumber].New(Unit)
call SetUnitObjectNumber(Unit, NewObjectNumber)
return NewObjectNumber
endfunction
private function RecycleObject takes integer ObjectNumber returns nothing
local integer IntLoop1 = 1
if (ObjectNumber > 0) then
if (udg_Objects[ObjectNumber].Unit != null) then
//Remove unit from all clusters:
loop
exitwhen IntLoop1 > udg_CountClusters
if (IsUnitInGroup(udg_Objects[ObjectNumber].Unit, udg_Clusters[IntLoop1].Group)) then
call GroupRemoveUnit(udg_Clusters[IntLoop1].Group, udg_Objects[ObjectNumber].Unit)
set udg_Clusters[IntLoop1].Size = udg_Clusters[IntLoop1].Size - 1
endif
set IntLoop1 = IntLoop1 + 1
endloop
call SetUnitObjectNumber(udg_Objects[ObjectNumber].Unit, 0)
endif
call udg_Objects[ObjectNumber].Clear()
if (udg_CountUnusedObjectNumbers + 1 > udg_MaxObjects) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Too many unused objects")
return
endif
set udg_CountUnusedObjectNumbers = udg_CountUnusedObjectNumbers + 1
set udg_UnusedObjectNumbers[udg_CountUnusedObjectNumbers] = ObjectNumber
endif
endfunction
//---------------
//TEXTMACRO PART:
//---------------
//! textmacro PublicAttributeFunctions takes ATTRIBUTE, TYPE
public function Get$ATTRIBUTE$ takes integer ObjectNumber returns $TYPE$
return udg_Objects[ObjectNumber].$ATTRIBUTE$
endfunction
public function Get$ATTRIBUTE$OfUnit takes unit Unit returns $TYPE$
return udg_Objects[GetUnitObjectNumber(Unit)].$ATTRIBUTE$
endfunction
public function Set$ATTRIBUTE$ takes integer ObjectNumber, $TYPE$ $ATTRIBUTE$ returns nothing
set udg_Objects[ObjectNumber].$ATTRIBUTE$ = $ATTRIBUTE$
endfunction
public function Set$ATTRIBUTE$OfUnit takes unit Unit, $TYPE$ $ATTRIBUTE$ returns nothing
set udg_Objects[GetUnitObjectNumber(Unit)].$ATTRIBUTE$ = $ATTRIBUTE$
endfunction
//! endtextmacro
//-------------------------
//CUSTOMIZABLE/PUBLIC PART:
//-------------------------
// //! runtextmacro PublicAttributeFunctions("ExampleInteger", "integer")
//------------
//PUBLIC PART:
//------------
public function GetObjectNumber takes unit Unit, boolean AddMissing returns integer
local integer ObjectNumber = GetUnitObjectNumber(Unit)
if (AddMissing and ObjectNumber <= 0) then
set ObjectNumber = AddObject(Unit)
endif
return ObjectNumber
endfunction
public function GetSystemNumber takes integer ObjectNumber, integer SystemSlot returns integer
return udg_Objects[ObjectNumber].GetSystemNumberBySlot(SystemSlot)
endfunction
public function GetSystemNumberOfUnit takes unit Unit, integer SystemSlot returns integer
return udg_Objects[GetUnitObjectNumber(Unit)].GetSystemNumberBySlot(SystemSlot)
endfunction
public function SetSystemNumber takes integer ObjectNumber, integer SystemSlot, integer Number returns nothing
if (ObjectNumber > 0) then
call udg_Objects[ObjectNumber].SetSystemNumberBySlot(SystemSlot, Number)
endif
endfunction
public function SetSystemNumberOfUnit takes unit Unit, integer SystemSlot, integer Number returns integer
local integer ObjectNumber = GetUnitObjectNumber(Unit)
if (ObjectNumber == 0) then
set ObjectNumber = AddObject(Unit)
endif
call udg_Objects[ObjectNumber].SetSystemNumberBySlot(SystemSlot, Number)
return ObjectNumber
endfunction
public function ChangeUnit takes unit OldUnit, unit NewUnit returns nothing
local integer ObjectNumber = GetUnitObjectNumber(OldUnit)
local integer IntLoop1 = 1
if (ObjectNumber > 0) then
call SetUnitObjectNumber(OldUnit, 0)
set udg_Objects[ObjectNumber].Unit = NewUnit
call SetUnitObjectNumber(NewUnit, ObjectNumber)
loop
exitwhen IntLoop1 > udg_CountClusters
if (IsUnitInGroup(OldUnit, udg_Clusters[IntLoop1].Group)) then
call GroupRemoveUnit(udg_Clusters[IntLoop1].Group, OldUnit)
call GroupAddUnit(udg_Clusters[IntLoop1].Group, NewUnit)
endif
set IntLoop1 = IntLoop1 + 1
endloop
endif
endfunction
public function RemoveObject takes integer ObjectNumber returns nothing
local unit Unit
if (ObjectNumber != 0) then
set Unit = udg_Objects[ObjectNumber].Unit
if (Unit != null) then
if (GetUnitState(Unit, UNIT_STATE_LIFE) >= 1.00) then
call KillUnit(Unit)
endif
call ShowUnit(Unit, false)
call TriggerSleepAction(1.00)
call RemoveUnit(Unit)
elseif (udg_Objects[ObjectNumber].NoRecycling == false) then
call RecycleObject(ObjectNumber)
endif
endif
//Anti-Memory-Leak:
set Unit = null
endfunction
public function RemoveObjectUnit takes unit Unit returns nothing
local integer ObjectNumber = GetUnitObjectNumber(Unit)
if (ObjectNumber != 0) then
if (GetUnitState(Unit, UNIT_STATE_LIFE) >= 1.00) then
call KillUnit(Unit)
endif
call ShowUnit(Unit, false)
call TriggerSleepAction(1.00)
endif
call RemoveUnit(Unit)
endfunction
//Prevents that the given ObjectNumber is reused when it's removed or the unit dies:
public function SetNoRecycling takes integer ObjectNumber, boolean NoRecycling returns nothing
set udg_Objects[ObjectNumber].NoRecycling = NoRecycling
endfunction
//Prevents that the ObjectNumber of the given Unit is reused when it's removed or the unit dies:
public function SetNoRecyclingOfUnit takes unit Unit, boolean NoRecycling returns integer
local integer ObjectNumber = GetUnitObjectNumber(Unit)
if (ObjectNumber == 0) then
set ObjectNumber = AddObject(Unit)
endif
set udg_Objects[ObjectNumber].NoRecycling = NoRecycling
return ObjectNumber
endfunction
public function GetUnit takes integer ObjectNumber returns unit
return udg_Objects[ObjectNumber].Unit
endfunction
public function GetUnitType takes integer ObjectNumber returns integer
return GetUnitTypeId(udg_Objects[ObjectNumber].Unit)
endfunction
public function CreateCluster takes nothing returns integer
local integer NewClusterNumber
if (udg_CountUnusedClusterNumbers > 0) then
set NewClusterNumber = udg_UnusedClusterNumbers[udg_CountUnusedClusterNumbers]
set udg_CountUnusedClusterNumbers = udg_CountUnusedClusterNumbers - 1
else
if (udg_CountClusters + 1 > udg_MaxClusters) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Too many clusters")
return 0
endif
set udg_CountClusters = udg_CountClusters + 1
set udg_Clusters[udg_CountClusters] = Cluster.create()
if (udg_Clusters[udg_CountClusters] == 0) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Cluster struct cap exceeded")
return 0
endif
call udg_Clusters[udg_CountClusters].New()
set NewClusterNumber = udg_CountClusters
endif
return NewClusterNumber
endfunction
public function RemoveCluster takes integer ClusterNumber returns nothing
if (ClusterNumber > 0) then
call udg_Clusters[ClusterNumber].Clear()
if (udg_CountUnusedClusterNumbers + 1 > udg_MaxClusters) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Too many unused clusters")
return
endif
set udg_CountUnusedClusterNumbers = udg_CountUnusedClusterNumbers + 1
set udg_UnusedClusterNumbers[udg_CountUnusedClusterNumbers] = ClusterNumber
endif
endfunction
public function ClusterChangeObject takes integer ClusterNumber, integer ObjectNumber, boolean ObjectAdd returns nothing
if (ObjectAdd) then
if (IsUnitInGroup(udg_Objects[ObjectNumber].Unit, udg_Clusters[ClusterNumber].Group) == false) then
call GroupAddUnit(udg_Clusters[ClusterNumber].Group, udg_Objects[ObjectNumber].Unit)
set udg_Clusters[ClusterNumber].Size = udg_Clusters[ClusterNumber].Size + 1
endif
else
if (IsUnitInGroup(udg_Objects[ObjectNumber].Unit, udg_Clusters[ClusterNumber].Group) == true) then
call GroupRemoveUnit(udg_Clusters[ClusterNumber].Group, udg_Objects[ObjectNumber].Unit)
set udg_Clusters[ClusterNumber].Size = udg_Clusters[ClusterNumber].Size - 1
endif
endif
endfunction
public function ClusterChangeCluster takes integer SourceClusterNumber, integer TargetClusterNumber, boolean AddTargetCluster returns nothing
local group GroupTemp1 = CreateCopiedGroup(udg_Clusters[TargetClusterNumber].Group)
local unit UnitTemp1
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
if (AddTargetCluster) then
if (IsUnitInGroup(UnitTemp1, udg_Clusters[SourceClusterNumber].Group) == false) then
call GroupAddUnit(udg_Clusters[SourceClusterNumber].Group, UnitTemp1)
set udg_Clusters[SourceClusterNumber].Size = udg_Clusters[SourceClusterNumber].Size + 1
endif
else
if (IsUnitInGroup(UnitTemp1, udg_Clusters[SourceClusterNumber].Group) == true) then
call GroupRemoveUnit(udg_Clusters[SourceClusterNumber].Group, UnitTemp1)
set udg_Clusters[SourceClusterNumber].Size = udg_Clusters[SourceClusterNumber].Size - 1
endif
endif
endloop
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
endfunction
public function GetGroup takes integer ClusterNumber returns group
return CreateCopiedGroup(udg_Clusters[ClusterNumber].Group)
endfunction
public function GetClusterSize takes integer ClusterNumber returns integer
return udg_Clusters[ClusterNumber].Size
endfunction
public function IsObjectInCluster takes integer ClusterNumber, integer ObjectNumber returns boolean
return IsUnitInGroup(udg_Objects[ObjectNumber].Unit, udg_Clusters[ClusterNumber].Group)
endfunction
public function GetClusterFirstObject takes integer ClusterNumber returns integer
return GetUnitObjectNumber(FirstOfGroup(udg_Clusters[ClusterNumber].Group))
endfunction
public function SetClusterSystemNumbers takes integer ClusterNumber, integer SystemSlot, integer Number returns nothing
local group GroupTemp1 = CreateCopiedGroup(udg_Clusters[ClusterNumber].Group)
local unit UnitTemp1
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call SetSystemNumberOfUnit(UnitTemp1, SystemSlot, Number)
endloop
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
endfunction
//---------------------
//EVENT-TRIGGERED PART:
//---------------------
private function UnitDies_Conditions takes nothing returns boolean
return (GetUnitObjectNumber(GetDyingUnit()) != 0)
endfunction
private function UnitDies takes nothing returns nothing
local integer ObjectNumber = GetUnitObjectNumber(GetDyingUnit())
if (udg_Objects[ObjectNumber].NoRecycling) then
set udg_Objects[ObjectNumber].Unit = null
else
call TriggerSleepAction(0.01)
call RecycleObject(ObjectNumber)
endif
endfunction
//---------------
//INITIALISATION:
//---------------
private function Init_UnitDataSystem takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers:
loop
exitwhen IntLoop1 > udg_CountPlayers
call TriggerRegisterPlayerUnitEvent(gg_trg_UnitDies, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_DEATH, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Conditions:
call TriggerAddCondition(gg_trg_UnitDies, Condition(function UnitDies_Conditions))
//Actions:
call TriggerAddAction(gg_trg_UnitDies, function UnitDies)
//Variables:
set udg_Objects[0] = Object.create()
set udg_Clusters[0] = Cluster.create()
if (udg_UseUnitUserData == false and udg_HashtableLink == null) then
set udg_Hashtable = InitHashtable()
endif
endfunction
endlibrary
//TESH.scrollpos=12
//TESH.alwaysfold=0
/*-------------------------------------------------------------
//Version number:
1.01
//Description:
The "CastOnTarget" function allows to cast any desired ability from an unselectable dummy on a target unit.
After the ability (Has to be in "IsDummyAbility") is casted the dummy is automatically removed.
Values in the parts under "CUSTOMIZABLE PART" have to be adjusted.
Note: Dummies owned by a computer player may not execute cast orders. Use neutral passive player instead then if possible.
//Public functions:
public function CastOnTarget takes integer AbilityID, integer Level, string Order, unit Target, player CasterOwner returns nothing
public function CastOnTargetById takes integer AbilityID, integer Level, unit Target, player CasterOwner returns nothing
//Changelog:
-1.01:
Initial version
-------------------------------------------------------------*/
library libDum initializer Init_DummySystem requires libId
//------------------
//CUSTOMIZABLE PART:
//------------------
globals
private constant integer udg_CountPlayers = 16 //Highest player slot in use
endglobals
private function IsDummyAbility takes integer AbilityID returns boolean
if (AbilityID == libId_udg_AddConstructionBuff) then //Add construction buff
return true
elseif (AbilityID == libId_udg_AddInfection) then //Add infection
return true
elseif (AbilityID == libId_udg_HolyLightAn) then //Holy light (Angle of Light)
return true
elseif (AbilityID == libId_udg_RaiseZombie) then //Raise zombie
return true
endif
return false
endfunction
//-----------------
//DECLARATION PART:
//-----------------
globals
private constant trigger gg_trg_RemoveDummy = CreateTrigger()
endglobals
//------------
//PUBLIC PART:
//------------
public function CastOnTarget takes integer AbilityID, integer Level, string Order, unit Target, player CasterOwner returns nothing
local unit Dummy = CreateUnit(CasterOwner, libId_udg_Dummy, GetUnitX(Target), GetUnitY(Target), 0.00)
call UnitAddAbility(Dummy, 'Aloc') //Locust
call UnitRemoveAbility(Dummy, 'Aloc') //Locust
call UnitAddAbility(Dummy, AbilityID)
call SetUnitAbilityLevel(Dummy, AbilityID, Level)
call IssueTargetOrder(Dummy, Order, Target)
//Anit-Memory-Leak:
set Dummy = null
endfunction
public function CastOnTargetById takes integer AbilityID, integer Level, unit Target, player CasterOwner returns nothing
local unit Dummy = CreateUnit(CasterOwner, libId_udg_Dummy, GetUnitX(Target), GetUnitY(Target), 0.00)
call UnitAddAbility(Dummy, 'Aloc') //Locust
call UnitRemoveAbility(Dummy, 'Aloc') //Locust
call UnitAddAbility(Dummy, AbilityID)
call SetUnitAbilityLevel(Dummy, AbilityID, Level)
call IssueTargetOrderById(Dummy, AbilityID, Target)
//Anit-Memory-Leak:
set Dummy = null
endfunction
//---------------------
//EVENT-TRIGGERED PART:
//---------------------
private function RemoveDummy_Conditions takes nothing returns boolean
return (IsDummyAbility(GetSpellAbilityId()) and GetUnitTypeId(GetSpellAbilityUnit())== libId_udg_Dummy)
endfunction
private function RemoveDummy takes nothing returns nothing
local unit Dummy = GetSpellAbilityUnit()
call RemoveUnit(Dummy)
//Anti-Memory-Leak:
set Dummy = null
endfunction
//---------------
//INITIALISATION:
//---------------
private function Init_DummySystem takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers:
loop
exitwhen IntLoop1 > udg_CountPlayers
call TriggerRegisterPlayerUnitEvent(gg_trg_RemoveDummy, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_FINISH, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Conditions:
call TriggerAddCondition(gg_trg_RemoveDummy, Condition(function RemoveDummy_Conditions))
//Actions:
call TriggerAddAction(gg_trg_RemoveDummy, function RemoveDummy)
endfunction
endlibrary
//TESH.scrollpos=42
//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
private 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
//TESH.scrollpos=21
//TESH.alwaysfold=0
/*-------------------------------------------------------------
//Version number:
1.04
//Description:
Through this system buildings are turnable as they are upgraded out of turnable building sites with fitting pathing maps.
Also building types can require a specific minimum and allow a specific maximum amount of different workers each ("GetNeededWorkers").
The building time ("GetBuildingValue") is dynamically influenced by its actual amount of workers working on it.
It is modified/written to perfectly work together with the "WallSystem".
Values in the parts under "CUSTOMIZABLE PART" have to be adjusted.
//Public functions:
public function GetBuildingSiteNumber takes unit Building returns integer
public function GetBuildingSiteInfo takes integer BuildingSiteNumber, integer InfoNumber, integer SubNumber returns integer
public function GetWorkerGroup takes integer BuildingSiteNumber returns group
//Changelog:
-1.01:
Inital remade version
-1.02:
Renamed "Work on building" to "Construct"
-1.03:
Replaced the message "There are already too many workers of this type on this building site." with "The worker limit for this building site has already been reached."
-1.04
Incorporated DummySystem
Renamed building sites
Removed obsolete function NextBuildingSiteType
Fixed RemoveBuilding
Removed obsolet function IsBuildingSite (use GetBuildingSiteNumber > 0 instead)
Replaced private Id list with the use of the global IdSystem
Added udg_AntiSingularityAddition to avoid errors by dividing with zero
Removed obsolet TargetID input from BuildingSite.New
-------------------------------------------------------------*/
library libBuilSite initializer Init_BuildingSiteSystem requires libId, libUnitDat, libDum, libWal
//------------------
//CUSTOMIZABLE PART:
//------------------
globals
private constant integer udg_SystemSlot = libUnitDat_udg_SystemNumber_BuildingSiteSystem
private constant integer udg_CountPlayers = 12 //Highest player slot in use
private constant integer udg_MaxBuildingSites = 50 * udg_CountPlayers //Maximal allowed building sites at the same time
private constant integer udg_MaxWorkerTypes = 2 //Maximal used different worker types
private constant real udg_BuildingRate = 0.05 //Higher rate for smoother building but worse performence
private constant real udg_MaxAutoBuildRange = 1024.00 //Range in which workers automatically look for another suitable building site after finishing one
endglobals
//Returns the amount of work required to complete the given building type:
private function GetBuildingValue takes integer BuildingID returns real
//Building site (tiny):
if (BuildingID == libId_udg_Barricade) then //Barricade
return 10.00
elseif (BuildingID == libId_udg_Ballista) then //Ballista
return 48.00
//Building site (little):
elseif (BuildingID == libId_udg_GateCl) then //Gate (Closed)
return 90.00
elseif (BuildingID == libId_udg_PalisadeGateCl) then //Palisade gate (Closed)
return 45.00
elseif (BuildingID == libId_udg_WallUn or BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallIEUn) then //Wall (all Undamaged)
return 60.00
elseif (BuildingID == libId_udg_PalisadeUn or BuildingID == libId_udg_PalisadeOEUn or BuildingID == libId_udg_PalisadeIEUn) then //Palisade (all Undamaged)
return 30.00
elseif (BuildingID == libId_udg_TowerUn or BuildingID == libId_udg_TowerOEUn or BuildingID == libId_udg_TowerIEUn) then //Tower (all Undamaged)
return 120.00
//Building site (small):
elseif (BuildingID == libId_udg_BigGateCl) then //Big gate (Closed)
return 120.00
elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerIEUn) then //Big tower (all Undamaged)
return 180.00
elseif (BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (all Undamaged)
return 240.00
//Building site (big):
elseif (BuildingID == libId_udg_ThatchedCottages1) then //Thatched cottages (Level1)
return 90.00
elseif (BuildingID == libId_udg_ThatchedCottages2) then //Thatched cottages (Level2)
return 60.00
elseif (BuildingID == libId_udg_ThatchedCottages3) then //Thatched cottages (Level3)
return 60.00
elseif (BuildingID == libId_udg_ThatchedCottages4) then //Thatched cottages (Level4)
return 60.00
elseif (BuildingID == libId_udg_VillageHouse1) then //Village house (Level1)
return 120.00
elseif (BuildingID == libId_udg_VillageHouse2) then //Village house (Level2)
return 80.00
elseif (BuildingID == libId_udg_VillageHouse3) then //Village house (Level3)
return 80.00
elseif (BuildingID == libId_udg_VillageHouse4) then //Village house (Level4)
return 80.00
elseif (BuildingID == libId_udg_VillageHouse5) then //Village house (Level5)
return 80.00
elseif (BuildingID == libId_udg_Barracks) then //Barracks
return 120.00
//Building site (very large):
elseif (BuildingID == libId_udg_MotteAndBailey) then //Motte-and-bailey
return 180.00
elseif (BuildingID == libId_udg_SmallCastle) then //Small castle
return 120.00
elseif (BuildingID == libId_udg_BigCastle) then //Big castle
return 120.00
//Building site (special):
elseif (BuildingID == libId_udg_Stairs) then //Stairs
return 40.00
elseif (BuildingID == libId_udg_LadderWall) then //Ladder (Wall)
return -3.00
elseif (BuildingID == libId_udg_LadderPalisade) then //Ladder (Palisade)
return -3.00
elseif (BuildingID == libId_udg_WallDa or BuildingID == libId_udg_WallOEDa or BuildingID == libId_udg_WallIEDa) then //Wall (all Damaged)
return 20.00
elseif (BuildingID == libId_udg_WallDe or BuildingID == libId_udg_WallOEDe or BuildingID == libId_udg_WallIEDe) then //Wall (all Destroyed)
return 50.00
elseif (BuildingID == libId_udg_PalisadeDa or BuildingID == libId_udg_PalisadeOEDa or BuildingID == libId_udg_PalisadeIEDa or BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (all Damaged)
return 10.00
elseif (BuildingID == libId_udg_PalisadeDe or BuildingID == libId_udg_PalisadeOEDe or BuildingID == libId_udg_PalisadeIEDe) then //Palisade (all Destroyed)
return 25.00
elseif (BuildingID == libId_udg_GateDa) then //Gate (Damaged)
return 40.00
elseif (BuildingID == libId_udg_PalisadeGateDa) then //Palisade gate (Damaged)
return 20.00
elseif (BuildingID == libId_udg_BigGateDa) then //Big gate (Damaged)
return 60.00
elseif (BuildingID == libId_udg_TowerDa or BuildingID == libId_udg_TowerOEDa or BuildingID == libId_udg_TowerIEDa) then //Tower (all Damaged)
return 40.00
elseif (BuildingID == libId_udg_TowerDe or BuildingID == libId_udg_TowerOEDe or BuildingID == libId_udg_TowerIEDe) then //Tower (all Destroyed)
return 100.00
elseif (BuildingID == libId_udg_BigTowerDa or BuildingID == libId_udg_BigTowerOEDa or BuildingID == libId_udg_BigTowerIEDa) then //Big tower (all Damaged)
return 140.00
elseif (BuildingID == libId_udg_BigTowerDe or BuildingID == libId_udg_BigTowerOEDe or BuildingID == libId_udg_BigTowerIEDe) then //Big tower (all Destroyed)
return 30.00
endif
return 0.00
endfunction
//Returns the building size ("Grafic - Scaling value") of the building type:
private function GetBuildingSize takes integer BuildingID returns real
//Building site (tiny):
if (BuildingID == libId_udg_Barricade) then //Barricade
return 0.60
elseif (BuildingID == libId_udg_Ballista) then //Ballista
return 0.60
//Building site (big):
elseif (BuildingID == libId_udg_ThatchedCottages1) then //Thatched cottages (Level1)
return 0.62
elseif (BuildingID == libId_udg_ThatchedCottages2) then //Thatched cottages (Level2)
return 0.62
elseif (BuildingID == libId_udg_ThatchedCottages3) then //Thatched cottages (Level3)
return 0.62
elseif (BuildingID == libId_udg_ThatchedCottages4) then //Thatched cottages (Level4)
return 0.62
elseif (BuildingID == libId_udg_VillageHouse1) then //Village house (Level1)
return 1.45
elseif (BuildingID == libId_udg_VillageHouse2) then //Village house (Level2)
return 1.45
elseif (BuildingID == libId_udg_VillageHouse3) then //Village house (Level3)
return 1.45
elseif (BuildingID == libId_udg_VillageHouse4) then //Village house (Level4)
return 1.45
elseif (BuildingID == libId_udg_VillageHouse5) then //Village house (Level5)
return 1.45
elseif (BuildingID == libId_udg_Barracks) then //Barracks
return 1.45
endif
return 1.00
endfunction
//Returns the minimal/maximal number of required/allowed workers of the given type number for the given building type:
private function GetNeededWorkers takes integer BuildingID, integer WorkerSlot, boolean ReturnMin returns integer
//Building site (tiny):
if (BuildingID == libId_udg_Barricade) then //Barricade
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 1
endif
endif
elseif (BuildingID == libId_udg_Ballista) then //Ballista
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 3
endif
endif
//Building site (little):
elseif (BuildingID == libId_udg_GateCl) then //Gate (Closed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 4
endif
endif
elseif (BuildingID == libId_udg_PalisadeGateCl) then //Palisade gate (Closed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_WallUn or BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallIEUn) then //Wall (all Undamaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 4
endif
endif
elseif (BuildingID == libId_udg_PalisadeUn or BuildingID == libId_udg_PalisadeOEUn or BuildingID == libId_udg_PalisadeIEUn) then //Palisade (all Undamaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_TowerUn or BuildingID == libId_udg_TowerOEUn or BuildingID == libId_udg_TowerIEUn) then //Tower (all Undamaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 4
endif
endif
//Building site (small):
elseif (BuildingID == libId_udg_BigGateCl) then //Big gate (Closed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 5
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 1
endif
endif
elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerIEUn) then //Big tower (all Undamaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 5
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 1
endif
endif
elseif (BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (all Undamaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 6
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
//Building site (big):
elseif (BuildingID == libId_udg_ThatchedCottages1) then //Thatched cottages (Level1)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 4
else
return 8
endif
endif
elseif (BuildingID == libId_udg_ThatchedCottages2 or BuildingID == libId_udg_ThatchedCottages3 or BuildingID == libId_udg_ThatchedCottages4) then //Thatched cottages (Level2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 4
endif
endif
elseif (BuildingID == libId_udg_VillageHouse1) then //Village house (Level1)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 7
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 1
endif
endif
elseif (BuildingID == libId_udg_VillageHouse2 or BuildingID == libId_udg_VillageHouse3 or BuildingID == libId_udg_VillageHouse4 or BuildingID == libId_udg_VillageHouse5) then //Village house (Level2,3,4,5)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 3
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 1
endif
endif
elseif (BuildingID == libId_udg_Barracks) then //Barracks
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 7
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 1
endif
endif
//Building site (very large):
elseif (BuildingID == libId_udg_MotteAndBailey) then //Motte-and-bailey
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 7
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 2
else
return 3
endif
endif
elseif (BuildingID == libId_udg_SmallCastle) then //Small castle
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 4
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_BigCastle) then //Big castle
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 4
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
//Building site (special):
elseif (BuildingID == libId_udg_Stairs) then //Stairs
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 3
endif
endif
elseif (BuildingID == libId_udg_GateDa) then //Gate (Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_PalisadeGateDa) then //Palisade gate (Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_BigGateDa) then //Big gate (Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_WallDa or BuildingID == libId_udg_WallOEDa or BuildingID == libId_udg_WallIEDa) then //Wall (all Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_WallDe or BuildingID == libId_udg_WallOEDe or BuildingID == libId_udg_WallIEDe) then //Wall (all Destroyed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 4
endif
endif
elseif (BuildingID == libId_udg_PalisadeDa or BuildingID == libId_udg_PalisadeOEDa or BuildingID == libId_udg_PalisadeIEDa or BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (all Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_PalisadeDe or BuildingID == libId_udg_PalisadeOEDe or BuildingID == libId_udg_PalisadeIEDe) then //Palisade (all Destroyed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_TowerDa or BuildingID == libId_udg_TowerOEDa or BuildingID == libId_udg_TowerIEDa) then //Tower (all Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_TowerDe or BuildingID == libId_udg_TowerOEDe or BuildingID == libId_udg_TowerIEDe) then //Tower (all Destroyed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 4
endif
endif
elseif (BuildingID == libId_udg_BigTowerDa or BuildingID == libId_udg_BigTowerOEDa or BuildingID == libId_udg_BigTowerIEDa) then //Big tower (all Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 3
endif
endif
elseif (BuildingID == libId_udg_BigTowerDe or BuildingID == libId_udg_BigTowerOEDe or BuildingID == libId_udg_BigTowerIEDe) then //Big tower (all Destroyed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 5
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 1
endif
endif
elseif (BuildingID == libId_udg_DrumTowerDa or BuildingID == libId_udg_DrumTowerOEDa or BuildingID == libId_udg_DrumTowerIEDa) then //Drum tower (all Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 3
endif
endif
elseif (BuildingID == libId_udg_DrumTowerDe or BuildingID == libId_udg_DrumTowerOEDe or BuildingID == libId_udg_DrumTowerIEDe) then //Drum tower (all Destroyed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 6
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
endif
return 0
endfunction
//Returns the building site for the given building type (only required for multi-edge fortifications):
private function GetBuildingSiteID takes integer BuildingID returns integer
if (BuildingID == libId_udg_WallUn) then //Wall (Undamaged)
return libId_udg_BuildingSiteLittle //Building site (little)
elseif (BuildingID == libId_udg_WallOEUn) then //Wall (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_WallIEUn) then //Wall (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_PalisadeUn) then //Palisade (Undamaged)
return libId_udg_BuildingSiteLittle //Building site (little)
elseif (BuildingID == libId_udg_PalisadeOEUn) then //Palisade (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_PalisadeIEUn) then //Palisade (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_TowerUn) then //Tower (Undamaged)
return libId_udg_BuildingSiteLittle //Building site (little)
elseif (BuildingID == libId_udg_TowerOEUn) then //Tower (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_TowerIEUn) then //Tower (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_BigTowerUn) then //Big tower (Undamaged)
return libId_udg_BuildingSiteSmall //Building site (small)
elseif (BuildingID == libId_udg_BigTowerOEUn) then //Big tower (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_BigTowerIEUn) then //Big tower (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_DrumTowerUn) then //Drum tower (Undamaged)
return libId_udg_BuildingSiteSmall //Building site (small)
elseif (BuildingID == libId_udg_DrumTowerOEUn) then //Drum tower (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
endif
return 0
endfunction
//Returns the unit type of the given WorkerSlot:
private function WorkerSlot2UnitID takes integer WorkerSlot returns integer
if (WorkerSlot == 1) then
return libId_udg_Worker //Worker
elseif (WorkerSlot == 2) then
return libId_udg_Architect //Architect
endif
return 0
endfunction
//Returns the square size of the given building site type:
private function GetBuildingSiteSquareSize takes integer BuildingID returns real
if (BuildingID == libId_udg_BuildingSiteTiny) then //Building site (tiny)
return 64.00
elseif (BuildingID == libId_udg_BuildingSiteLittle) then //Building site (little)
return 128.00
elseif (BuildingID == libId_udg_BuildingSiteSmall) then //Building site (small)
return 192.00
elseif (BuildingID == libId_udg_BuildingSiteBig) then //Building site (big)
return 320.00
elseif (BuildingID == libId_udg_BuildingSiteVeryLarge) then //Building site (very large)
return 512.00
elseif (BuildingID == libId_udg_BuildingSiteStairs) then //Building site (Stairs)
return 192.00
elseif (BuildingID == libId_udg_BuildingSiteLadder) then //Building site (Ladder)
return 128.00
endif
return 0.00
endfunction
//Returns the work power per second:
private function GetWorkPower takes integer UnitID returns real
if (UnitID == libId_udg_Worker) then //Worker
return 1.00
elseif (UnitID == libId_udg_Architect) then //Architect
return 1.50
endif
return 0.00
endfunction
//-----------------
//DECLARATION PART:
//-----------------
globals
private constant real udg_AntiSingularityAddition = 0.000001
private constant integer udg_MaxBuildingSitesP = udg_MaxBuildingSites + 1
private constant integer udg_MaxWorkerTypesP = udg_MaxWorkerTypes + 1
endglobals
private struct BuildingSite
private integer BuildingObjectNumber = 0
private integer WorkersClusterNumber = 0
private real Progress = 0.00
private real Workpower = 0.00
private integer array WorkerCounts [udg_MaxWorkerTypesP]
private boolean EnoughWorker = false
public method remove takes nothing returns nothing
local group GroupTemp1 = libUnitDat_GetGroup(this.WorkersClusterNumber)
local unit UnitTemp1
local integer IntLoop1 = 1
call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, 0)
set this.BuildingObjectNumber = 0
call libUnitDat_SetClusterSystemNumbers(this.WorkersClusterNumber, udg_SystemSlot, 0)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call UnitRemoveAbility(UnitTemp1, libId_udg_ConstructingBuff)
call SetUnitAnimation(UnitTemp1, "stand")
endloop
call libUnitDat_RemoveCluster(this.WorkersClusterNumber)
set this.WorkersClusterNumber = 0
set this.Progress = 0.00
set this.Workpower = 0.00
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
set this.WorkerCounts[IntLoop1] = 0
set IntLoop1 = IntLoop1 + 1
endloop
set this.EnoughWorker = false
call this.destroy()
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
endmethod
//------------
//GET METHODS:
//------------
public method GetBuilding takes nothing returns unit
return libUnitDat_GetUnit(this.BuildingObjectNumber)
endmethod
public method GetWorkers takes nothing returns group
return libUnitDat_GetGroup(this.WorkersClusterNumber)
endmethod
public method GetProgress takes nothing returns real
return this.Progress
endmethod
public method GetWorkerCounts takes integer WorkerSlot returns integer
return this.WorkerCounts[WorkerSlot]
endmethod
//------------
//SET METHODS:
//------------
public method SetBuilding takes unit Building returns nothing
set this.BuildingObjectNumber = libUnitDat_GetObjectNumber(Building, true)
endmethod
//--------------
//OTHER METHODS:
//--------------
public method New takes unit Building, integer BuildingSiteNumber returns nothing
local integer IntLoop1 = 1
set this.BuildingObjectNumber = libUnitDat_GetObjectNumber(Building, true)
call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, BuildingSiteNumber)
set this.WorkersClusterNumber = libUnitDat_CreateCluster()
set this.Progress = GetBuildingValue(GetUnitTypeId(Building))
set this.Workpower = 0.00
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
set this.WorkerCounts[IntLoop1] = 0
set IntLoop1 = IntLoop1 + 1
endloop
set this.EnoughWorker = false
endmethod
public method IsWorker takes unit Person returns boolean
return (libUnitDat_GetSystemNumber(libUnitDat_GetObjectNumber(Person, false), udg_SystemSlot) == libUnitDat_GetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot))
endmethod
public method CheckWorkerCount takes nothing returns nothing
local integer BuildingID = GetUnitTypeId(libUnitDat_GetUnit(this.BuildingObjectNumber))
local boolean EnoughWorkerOld = this.EnoughWorker
local group GroupTemp1
local unit UnitTemp1
local integer IntLoop1 = 1
set this.EnoughWorker = true
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
if (this.EnoughWorker and this.WorkerCounts[IntLoop1] < GetNeededWorkers(BuildingID, IntLoop1, true)) then
set this.EnoughWorker = false
exitwhen true
endif
set IntLoop1 = IntLoop1 + 1
endloop
if (EnoughWorkerOld == false and this.EnoughWorker) then
set GroupTemp1 = libUnitDat_GetGroup(this.WorkersClusterNumber)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call SetUnitAnimation(UnitTemp1, "work")
endloop
call DestroyGroup(GroupTemp1)
elseif (EnoughWorkerOld and this.EnoughWorker == false) then
set GroupTemp1 = libUnitDat_GetGroup(this.WorkersClusterNumber)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call SetUnitAnimation(UnitTemp1, "stand")
endloop
call DestroyGroup(GroupTemp1)
endif
//Anti-Memory-Leak:
set GroupTemp1 = null
set UnitTemp1 = null
endmethod
public method AddWorker takes unit Person returns nothing
local integer PersonObjectNumber
local integer PersonID = GetUnitTypeId(Person)
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
exitwhen WorkerSlot2UnitID(IntLoop1) == PersonID
set IntLoop1 = IntLoop1 + 1
endloop
if (IntLoop1 > udg_MaxWorkerTypes) then
call DisplayTextToPlayer(GetOwningPlayer(Person), 0, 0, "This builder can't work at this type of building.")
elseif (this.WorkerCounts[IntLoop1] >= GetNeededWorkers(GetUnitTypeId(libUnitDat_GetUnit(this.BuildingObjectNumber)), IntLoop1, false)) then
call DisplayTextToPlayer(GetOwningPlayer(Person), 0, 0, "The worker limit for this building site has already been reached.")
else
set this.WorkerCounts[IntLoop1] = this.WorkerCounts[IntLoop1] + 1
set PersonObjectNumber = libUnitDat_SetSystemNumberOfUnit(Person, udg_SystemSlot, libUnitDat_GetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot))
call libUnitDat_ClusterChangeObject(this.WorkersClusterNumber, PersonObjectNumber, true)
set this.Workpower = this.Workpower + GetWorkPower(PersonID)
call libDum_CastOnTarget(libId_udg_AddConstructionBuff, 1, "innerfire", Person, Player(PLAYER_NEUTRAL_PASSIVE))
if (this.EnoughWorker == false) then
call TriggerSleepAction(0.01)
call this.CheckWorkerCount()
else
call TriggerSleepAction(0.01)
call SetUnitAnimation(Person, "work")
endif
endif
endmethod
public method RemoveWorker takes unit Person returns nothing
local integer PersonObjectNumber
local integer PersonID = GetUnitTypeId(Person)
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
exitwhen WorkerSlot2UnitID(IntLoop1) == PersonID
set IntLoop1 = IntLoop1 + 1
endloop
if (IntLoop1 > udg_MaxWorkerTypes or this.WorkerCounts[IntLoop1] <= 0) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Can't remove more builders of this type")
return
else
set this.WorkerCounts[IntLoop1] = this.WorkerCounts[IntLoop1] - 1
set PersonObjectNumber = libUnitDat_SetSystemNumberOfUnit(Person, udg_SystemSlot, 0)
call libUnitDat_ClusterChangeObject(this.WorkersClusterNumber, PersonObjectNumber, false)
call SetUnitAnimation(Person, "stand")
set this.Workpower = this.Workpower - GetWorkPower(PersonID)
call UnitRemoveAbility(Person, libId_udg_ConstructingBuff)
if (this.EnoughWorker) then
call this.CheckWorkerCount()
endif
endif
endmethod
public method ReduceBuildingTime takes nothing returns nothing
local unit Building = libUnitDat_GetUnit(this.BuildingObjectNumber)
local integer BuildingID
local integer IntTemp1
if (this.Progress > 0.00) then
set BuildingID = GetUnitTypeId(Building)
if (this.EnoughWorker) then
set this.Progress = this.Progress - this.Workpower * udg_BuildingRate
endif
set IntTemp1 = R2I(100.00 - 100.00 * this.Progress / (GetBuildingValue(BuildingID) + udg_AntiSingularityAddition))
if (IntTemp1 >= 100 and this.Progress > 0.00) then
set IntTemp1 = 99
elseif (IntTemp1 <= 0) then
set IntTemp1 = 1
endif
call UnitSetUpgradeProgress(Building, IntTemp1)
elseif (this.Progress == 0.00) then
call UnitSetUpgradeProgress(Building, 1)
endif
//Anit-Memory-Leak:
set Building = null
endmethod
public method AdjustSystemNumber takes integer NewSystemNumber returns nothing
call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, NewSystemNumber)
call libUnitDat_SetClusterSystemNumbers(this.WorkersClusterNumber, udg_SystemSlot, NewSystemNumber)
endmethod
endstruct
globals
private BuildingSite array udg_BuildingSites [udg_MaxBuildingSitesP]
private integer udg_CountBuildingSites = 0
private constant trigger gg_trg_AdjustBuildingTime = CreateTrigger()
private constant trigger gg_trg_TurnBuilding = CreateTrigger()
private constant trigger gg_trg_RemoveBuilding = CreateTrigger()
private constant trigger gg_trg_StartBuilding = CreateTrigger()
private constant trigger gg_trg_FinishBuilding = CreateTrigger()
private constant trigger gg_trg_AbortBuilding = CreateTrigger()
private constant trigger gg_trg_BuildingDies = CreateTrigger()
private constant trigger gg_trg_DuplicateBuildingSite = CreateTrigger()
private constant trigger gg_trg_SmartOrderOnBuildingSite = CreateTrigger()
private constant trigger gg_trg_LeaveBuildingSite = CreateTrigger()
private constant trigger gg_trg_Construct = CreateTrigger()
endglobals
//-------------
//PRIVATE PART:
//-------------
private function GetAdjustedAngle takes real Input returns real
local real MaxResidual = 0.001
if (0.00 - Input <= MaxResidual and 0.00 - Input >= (-1) * MaxResidual) then
return 0.00
elseif (90.00 - Input <= MaxResidual and 90.00 - Input >= (-1) * MaxResidual) then
return 90.00
elseif (180.00 - Input <= MaxResidual and 180.00 - Input >= (-1) * MaxResidual) then
return 180.00
elseif (270.00 - Input <= MaxResidual and 270.00 - Input >= (-1) * MaxResidual) then
return 270.00
elseif (360.00 - Input <= MaxResidual and 360.00 - Input >= (-1) * MaxResidual) then
return 0.00
endif
return Input
endfunction
private function FindBuildingSitesForWorkers_Filter1 takes nothing returns boolean
return (GetBuildingValue(GetUnitTypeId(GetFilterUnit())) != 0.00 and libUnitDat_GetSystemNumberOfUnit(GetFilterUnit(), udg_SystemSlot) > 0)
endfunction
private function FindBuildingSitesForWorkers takes group Workers, real PosX, real PosY returns nothing
local player Owner = GetOwningPlayer(FirstOfGroup(Workers))
local unit array StackBuildings
local real array StackDistances
local integer StackSize = 0
local group array WorkerGroups
local boolexpr Filter1 = Condition(function FindBuildingSitesForWorkers_Filter1)
local group GroupTemp1 = CreateGroup()
local unit UnitTemp1
local real RealTemp1
local real RealTemp2
local integer IntTemp1
local integer IntTemp2
local integer IntTemp3
local integer IntLoop1
local integer IntLoop2
//Sort nearby building sites after the their distance:
call GroupEnumUnitsInRange(GroupTemp1, PosX, PosY, udg_MaxAutoBuildRange, Filter1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
if (Owner == GetOwningPlayer(UnitTemp1)) then
set RealTemp1 = GetUnitX(UnitTemp1) - PosX
set RealTemp2 = GetUnitY(UnitTemp1) - PosY
set RealTemp1 = SquareRoot(RealTemp1 * RealTemp1 + RealTemp2 * RealTemp2)
set IntLoop1 = StackSize
set StackSize = StackSize + 1
loop
exitwhen IntLoop1 <= 0
exitwhen StackDistances[IntLoop1] <= RealTemp1
set StackBuildings[IntLoop1 + 1] = StackBuildings[IntLoop1]
set StackDistances[IntLoop1 + 1] = StackDistances[IntLoop1]
set IntLoop1 = IntLoop1 - 1
endloop
set StackBuildings[IntLoop1 + 1] = UnitTemp1
set StackDistances[IntLoop1 + 1] = RealTemp1
endif
endloop
call DestroyGroup(GroupTemp1)
//Sort workers after their worker type slot:
set IntLoop1 = 1
set WorkerGroups[IntLoop1] = Workers
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
set GroupTemp1 = WorkerGroups[IntLoop1]
set WorkerGroups[IntLoop1] = CreateGroup()
if (IntLoop1 + 1 <= udg_MaxWorkerTypes) then
set WorkerGroups[IntLoop1 + 1] = CreateGroup()
endif
set IntTemp1 = WorkerSlot2UnitID(IntLoop1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
if (GetUnitTypeId(UnitTemp1) == IntTemp1) then
call GroupAddUnit(WorkerGroups[IntLoop1], UnitTemp1)
elseif (IntLoop1 + 1 <= udg_MaxWorkerTypes) then
call GroupAddUnit(WorkerGroups[IntLoop1 + 1], UnitTemp1)
endif
endloop
call DestroyGroup(GroupTemp1)
set IntLoop1 = IntLoop1 + 1
endloop
//Distribute workers to building sites:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > StackSize
set IntTemp1 = libUnitDat_GetSystemNumberOfUnit(StackBuildings[IntLoop1], udg_SystemSlot)
set IntTemp2 = GetUnitTypeId(StackBuildings[IntLoop1])
set IntTemp3 = -1
set IntLoop2 = 1
loop
exitwhen IntLoop2 > udg_MaxWorkerTypes
if (WorkerGroups[IntLoop2] != null) then
set IntTemp3 = GetNeededWorkers(IntTemp2, IntLoop2, false)
if (IntTemp3 > 0) then
set IntTemp3 = IntTemp3 - udg_BuildingSites[IntTemp1].GetWorkerCounts(IntLoop2)
loop
exitwhen IntTemp3 <= 0
set UnitTemp1 = FirstOfGroup(WorkerGroups[IntLoop2])
if (UnitTemp1 == null) then
call DestroyGroup(WorkerGroups[IntLoop2])
set WorkerGroups[IntLoop2] = null
exitwhen true
endif
call GroupRemoveUnit(WorkerGroups[IntLoop2], UnitTemp1)
call IssueTargetOrder(UnitTemp1, "thunderbolt", StackBuildings[IntLoop1])
set IntTemp3 = IntTemp3 - 1
endloop
endif
endif
set IntLoop2 = IntLoop2 + 1
endloop
set StackBuildings[IntLoop1] = null
set IntLoop1 = IntLoop1 + 1
exitwhen IntTemp3 == -1
endloop
//Anti-Memory-Leak:
if (IntLoop1 > StackSize) then
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
if (WorkerGroups[IntLoop1] != null) then
call DestroyGroup(WorkerGroups[IntLoop1])
set WorkerGroups[IntLoop1] = null
endif
set IntLoop1 = IntLoop1 + 1
endloop
else
loop
exitwhen IntLoop1 > StackSize
set StackBuildings[IntLoop1] = null
set IntLoop1 = IntLoop1 + 1
endloop
endif
set GroupTemp1 = null
call DestroyBoolExpr(Filter1)
set Filter1 = null
set UnitTemp1 = null
endfunction
//------------
//PUBLIC PART:
//------------
public function GetBuildingSiteNumber takes unit Building returns integer
return (libUnitDat_GetSystemNumberOfUnit(Building, udg_SystemSlot))
endfunction
public function GetBuildingSiteInfo takes integer BuildingSiteNumber, integer InfoNumber, integer SubNumber returns integer
local integer ReturnValue = 0
local real RealTemp1 = 0.00
local real RealTemp2
local integer IntTemp1
local integer IntTemp2
local integer IntLoop1 = 1
if (InfoNumber == 1) then //Left building time
set RealTemp2 = udg_BuildingSites[BuildingSiteNumber].GetProgress()
if (RealTemp2 == 0.00) then
set ReturnValue = -2000
elseif (RealTemp2 < 0.00) then
set ReturnValue = R2I(RealTemp2)
else
set IntTemp1 = GetUnitTypeId(udg_BuildingSites[BuildingSiteNumber].GetBuilding())
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
set IntTemp2 = udg_BuildingSites[BuildingSiteNumber].GetWorkerCounts(IntLoop1)
if (IntTemp2 < GetNeededWorkers(IntTemp1, IntLoop1, true)) then
set ReturnValue = -1000
exitwhen true
endif
set RealTemp1 = RealTemp1 + IntTemp2 * GetWorkPower(WorkerSlot2UnitID(IntLoop1))
set IntLoop1 = IntLoop1 + 1
endloop
if (ReturnValue == 0) then
set ReturnValue = R2I(RealTemp2 / (RealTemp1 + udg_AntiSingularityAddition))
endif
endif
elseif (InfoNumber == 2) then //Employed worker ID of type number
if (SubNumber > udg_MaxWorkerTypes) then
set ReturnValue = -1
else
set ReturnValue = WorkerSlot2UnitID(SubNumber)
endif
elseif (InfoNumber == 3) then //Employed worker count of type number
set ReturnValue = udg_BuildingSites[BuildingSiteNumber].GetWorkerCounts(SubNumber)
elseif (InfoNumber == 4) then //Minimal required worker count of type number
set ReturnValue = GetNeededWorkers(GetUnitTypeId(udg_BuildingSites[BuildingSiteNumber].GetBuilding()), SubNumber, true)
elseif (InfoNumber == 5) then //Maximal allowed worker count of type number
set ReturnValue = GetNeededWorkers(GetUnitTypeId(udg_BuildingSites[BuildingSiteNumber].GetBuilding()), SubNumber, false)
endif
return ReturnValue
endfunction
public function GetWorkerGroup takes integer BuildingSiteNumber returns group
return udg_BuildingSites[BuildingSiteNumber].GetWorkers()
endfunction
//---------------------
//EVENT-TRIGGERED PART:
//---------------------
private function TurnBuilding_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_TurnBuilding)
endfunction
private function TurnBuilding takes nothing returns nothing
local group GroupTemp1 = CreateGroup()
local unit UnitTemp1 = GetSpellAbilityUnit()
local unit UnitTemp2
local real RealTemp1
call SyncSelections()
call GroupEnumUnitsSelected(GroupTemp1, GetOwningPlayer(UnitTemp1), null)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
if (GetUnitAbilityLevel(UnitTemp1, libId_udg_TurnBuilding) != 0) then
set RealTemp1 = GetAdjustedAngle(GetUnitFacing(UnitTemp1)) + 90.00
if (RealTemp1 >= 360.00) then
set RealTemp1 = RealTemp1 - 360.00
endif
call ShowUnit(UnitTemp1, false)
set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), GetUnitTypeId(UnitTemp1), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), RealTemp1)
call libUnitDat_ChangeUnit(UnitTemp1, UnitTemp2)
call RemoveUnit(UnitTemp1)
if (RealTemp1 == 90.00) then
call UnitRemoveAbility(UnitTemp2, libId_udg_BuildingFacingDown)
call UnitAddAbility(UnitTemp2, libId_udg_BuildingFacingUp)
elseif (RealTemp1 == 180.00) then
call UnitRemoveAbility(UnitTemp2, libId_udg_BuildingFacingDown)
call UnitAddAbility(UnitTemp2, libId_udg_BuildingFacingLeft)
elseif (RealTemp1 == 0.00) then
call UnitRemoveAbility(UnitTemp2, libId_udg_BuildingFacingDown)
call UnitAddAbility(UnitTemp2, libId_udg_BuildingFacingRight)
endif
call libWal_AdjustReplacedBuilding(UnitTemp2)
if (GetLocalPlayer() == GetOwningPlayer(UnitTemp2)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SelectUnit(UnitTemp2, true)
endif
endif
endloop
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
set UnitTemp2 = null
endfunction
private function RemoveBuilding_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_RemoveBuilding)
endfunction
private function RemoveBuilding takes nothing returns nothing
local unit UnitTemp1 = GetSpellAbilityUnit()
call KillUnit(UnitTemp1)
call ShowUnit(UnitTemp1, false)
call TriggerSleepAction(1.00)
call RemoveUnit(UnitTemp1)
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function StartBuilding_Conditions takes nothing returns boolean
local unit UnitTemp1 = GetTriggerUnit()
local integer IntTemp1 = 1
if (GetBuildingValue(GetUnitTypeId(UnitTemp1)) != 0.00) then
set IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
//-----------------
return (IntTemp1 == 0)
endfunction
private function StartBuilding takes nothing returns nothing
local unit UnitTemp1 = GetTriggerUnit()
local real RealTemp1
local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
set udg_CountBuildingSites = udg_CountBuildingSites + 1
set udg_BuildingSites[udg_CountBuildingSites] = BuildingSite.create()
if (udg_BuildingSites[udg_CountBuildingSites] == 0) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: BuildingSite struct cap exceeded")
return
endif
call udg_BuildingSites[udg_CountBuildingSites].New(UnitTemp1, udg_CountBuildingSites)
set RealTemp1 = GetBuildingSize(IntTemp1)
call SetUnitScale(UnitTemp1, RealTemp1, RealTemp1, RealTemp1)
if (libWal_AdjustConstructingFortification(UnitTemp1)) then
set UnitTemp1 = udg_BuildingSites[udg_CountBuildingSites].GetBuilding()
call ShowUnit(UnitTemp1, false)
set IntTemp1 = GetUnitTypeId(UnitTemp1)
call libUnitDat_ChangeUnit(UnitTemp1, CreateUnit(GetOwningPlayer(UnitTemp1), GetBuildingSiteID(IntTemp1), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1)))
call RemoveUnit(UnitTemp1)
set UnitTemp1 = udg_BuildingSites[udg_CountBuildingSites].GetBuilding()
call IssueImmediateOrderById(UnitTemp1, IntTemp1)
set RealTemp1 = GetBuildingSize(IntTemp1)
call SetUnitScale(UnitTemp1, RealTemp1, RealTemp1, RealTemp1)
endif
call libWal_AddBuildingUnderConstruction(UnitTemp1)
if (GetLocalPlayer() == GetOwningPlayer(UnitTemp1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SelectUnit(UnitTemp1, true)
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function FinishBuilding_Conditions takes nothing returns boolean
return (GetBuildingValue(GetUnitTypeId(GetTriggerUnit())) != 0.00)
endfunction
private function FinishBuilding takes nothing returns nothing
local unit UnitTemp1 = GetTriggerUnit()
local group GroupTemp1
local integer IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
if (IntTemp1 <= udg_CountBuildingSites and IntTemp1 > 0) then
set GroupTemp1 = udg_BuildingSites[IntTemp1].GetWorkers()
call udg_BuildingSites[IntTemp1].remove()
if (udg_CountBuildingSites != IntTemp1) then
set udg_BuildingSites[IntTemp1] = udg_BuildingSites[udg_CountBuildingSites]
call udg_BuildingSites[IntTemp1].AdjustSystemNumber(IntTemp1)
endif
set udg_BuildingSites[udg_CountBuildingSites] = 0
set udg_CountBuildingSites = udg_CountBuildingSites - 1
call FindBuildingSitesForWorkers(GroupTemp1, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1))
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
set GroupTemp1 = null
endfunction
private function AbortBuilding_Conditions takes nothing returns boolean
return (GetBuildingSiteNumber(GetTriggerUnit()) > 0)
endfunction
private function AbortBuilding takes nothing returns nothing
local unit UnitTemp1 = GetTriggerUnit()
local integer IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
if (IntTemp1 <= udg_CountBuildingSites) then
call udg_BuildingSites[IntTemp1].remove()
if (udg_CountBuildingSites != IntTemp1) then
set udg_BuildingSites[IntTemp1] = udg_BuildingSites[udg_CountBuildingSites]
call udg_BuildingSites[IntTemp1].AdjustSystemNumber(IntTemp1)
endif
set udg_BuildingSites[udg_CountBuildingSites] = 0
set udg_CountBuildingSites = udg_CountBuildingSites - 1
if (GetUnitAbilityLevel(UnitTemp1, libId_udg_RemoveBuilding) > 0) then
call libWal_RemoveBuildingUnderConstruction(UnitTemp1)
call libUnitDat_RemoveObjectUnit(UnitTemp1)
endif
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function BuildingDies_Conditions takes nothing returns boolean
local unit UnitTemp1 = GetDyingUnit()
local integer IntTemp1 = 0
if (GetBuildingValue(GetUnitTypeId(UnitTemp1)) != 0.00) then
set IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
//-----------------
return (IntTemp1 != 0)
endfunction
private function BuildingDies takes nothing returns nothing
local unit UnitTemp1 = GetDyingUnit()
local integer IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
if (IntTemp1 <= udg_CountBuildingSites) then
call udg_BuildingSites[IntTemp1].remove()
if (udg_CountBuildingSites != IntTemp1) then
set udg_BuildingSites[IntTemp1] = udg_BuildingSites[udg_CountBuildingSites]
call udg_BuildingSites[IntTemp1].AdjustSystemNumber(IntTemp1)
endif
set udg_BuildingSites[udg_CountBuildingSites] = 0
set udg_CountBuildingSites = udg_CountBuildingSites - 1
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function AdjustBuildingTime takes nothing returns nothing
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_CountBuildingSites
call udg_BuildingSites[IntLoop1].ReduceBuildingTime()
set IntLoop1 = IntLoop1 + 1
endloop
endfunction
private function Construct_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_Construct)
endfunction
private function Construct takes nothing returns nothing
local unit Worker = GetSpellAbilityUnit()
local unit Building = GetSpellTargetUnit()
local integer BuildingSiteNumber = GetBuildingSiteNumber(Building)
if (BuildingSiteNumber > 0) then
call TriggerSleepAction(0.01)
call udg_BuildingSites[BuildingSiteNumber].AddWorker(Worker)
endif
//Anti-Memory-Leak:
set Worker = null
set Building = null
endfunction
private function LeaveBuildingSite_Conditions takes nothing returns boolean
return (GetWorkPower(GetUnitTypeId(GetTriggerUnit())) > 0.00)
endfunction
private function LeaveBuildingSite takes nothing returns nothing
local unit Worker = GetTriggerUnit()
local integer BuildingSiteNumber = GetBuildingSiteNumber(Worker)
if (BuildingSiteNumber > 0) then
call udg_BuildingSites[BuildingSiteNumber].RemoveWorker(Worker)
endif
//Anti-Memory-Leak:
set Worker = null
endfunction
private function DuplicateBuildingSite_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_Duplicate)
endfunction
private function DuplicateBuildingSite takes nothing returns nothing
local unit Building = GetSpellAbilityUnit()
local unit Duplicate
local integer BuildingID = GetUnitTypeId(Building)
local real Facing = GetAdjustedAngle(GetUnitFacing(Building))
local real PosX = GetUnitX(Building)
local real PosY = GetUnitY(Building)
if (Facing == 0.00) then
set PosY = PosY - GetBuildingSiteSquareSize(BuildingID)
elseif (Facing == 90.00) then
set PosX = PosX + GetBuildingSiteSquareSize(BuildingID)
elseif (Facing == 180.00) then
set PosY = PosY + GetBuildingSiteSquareSize(BuildingID)
elseif (Facing == 270.00) then
set PosX = PosX - GetBuildingSiteSquareSize(BuildingID)
endif
if (GetRectMinX(bj_mapInitialPlayableArea) <= PosX and PosX <= GetRectMaxX(bj_mapInitialPlayableArea) and GetRectMinY(bj_mapInitialPlayableArea) <= PosY and PosY <= GetRectMaxY(bj_mapInitialPlayableArea) and IsVisibleToPlayer(PosX, PosY, GetOwningPlayer(Building))) then
set Duplicate = CreateUnit(GetOwningPlayer(Building), BuildingID, PosX, PosY, Facing)
if (Facing == 90.00) then
call UnitRemoveAbility(Duplicate, libId_udg_BuildingFacingDown)
call UnitAddAbility(Duplicate, libId_udg_BuildingFacingUp)
elseif (Facing == 180.00) then
call UnitRemoveAbility(Duplicate, libId_udg_BuildingFacingDown)
call UnitAddAbility(Duplicate, libId_udg_BuildingFacingLeft)
elseif (Facing == 0.00) then
call UnitRemoveAbility(Duplicate, libId_udg_BuildingFacingDown)
call UnitAddAbility(Duplicate, libId_udg_BuildingFacingRight)
endif
if (GetLocalPlayer() == GetOwningPlayer(Duplicate)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call ClearSelection()
call SelectUnit(Duplicate, true)
endif
endif
//Anti-Memory-Leak:
set Building = null
set Duplicate = null
endfunction
private function SmartOrderOnBuildingSite_Conditions takes nothing returns boolean
return (OrderId2String(GetIssuedOrderId()) == "smart" and GetUnitState(GetOrderTargetUnit(), UNIT_STATE_LIFE) == GetUnitState(GetOrderTargetUnit(), UNIT_STATE_MAX_LIFE) and GetBuildingSiteNumber(GetOrderTargetUnit()) > 0 and GetWorkPower(GetUnitTypeId(GetOrderedUnit())) > 0.00)
endfunction
private function SmartOrderOnBuildingSite takes nothing returns nothing
local unit Worker = GetOrderedUnit()
local unit Building = GetOrderTargetUnit()
call IssueTargetOrder(Worker, "thunderbolt", Building)
//Anti-Memory-Leak:
set Worker = null
set Building = null
endfunction
//---------------
//INITIALISATION:
//---------------
private function Init_BuildingSiteSystem takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers:
call TriggerRegisterTimerEvent(gg_trg_AdjustBuildingTime, udg_BuildingRate, true)
loop
exitwhen IntLoop1 > udg_CountPlayers
call TriggerRegisterPlayerUnitEvent(gg_trg_TurnBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_RemoveBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_StartBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_START, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_FinishBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_FINISH, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_AbortBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_CANCEL, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_BuildingDies, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_DuplicateBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_SmartOrderOnBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_UNIT_ORDER, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ATTACKED, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_Construct, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Conditions:
call TriggerAddCondition(gg_trg_TurnBuilding, Condition(function TurnBuilding_Conditions))
call TriggerAddCondition(gg_trg_RemoveBuilding, Condition(function RemoveBuilding_Conditions))
call TriggerAddCondition(gg_trg_StartBuilding, Condition(function StartBuilding_Conditions))
call TriggerAddCondition(gg_trg_FinishBuilding, Condition(function FinishBuilding_Conditions))
call TriggerAddCondition(gg_trg_AbortBuilding, Condition(function AbortBuilding_Conditions))
call TriggerAddCondition(gg_trg_BuildingDies, Condition(function BuildingDies_Conditions))
call TriggerAddCondition(gg_trg_DuplicateBuildingSite, Condition(function DuplicateBuildingSite_Conditions))
call TriggerAddCondition(gg_trg_SmartOrderOnBuildingSite, Condition(function SmartOrderOnBuildingSite_Conditions))
call TriggerAddCondition(gg_trg_LeaveBuildingSite, Condition(function LeaveBuildingSite_Conditions))
call TriggerAddCondition(gg_trg_Construct, Condition(function Construct_Conditions))
//Actions:
call TriggerAddAction(gg_trg_AdjustBuildingTime, function AdjustBuildingTime)
call TriggerAddAction(gg_trg_TurnBuilding, function TurnBuilding)
call TriggerAddAction(gg_trg_RemoveBuilding, function RemoveBuilding)
call TriggerAddAction(gg_trg_StartBuilding, function StartBuilding)
call TriggerAddAction(gg_trg_FinishBuilding, function FinishBuilding)
call TriggerAddAction(gg_trg_AbortBuilding, function AbortBuilding)
call TriggerAddAction(gg_trg_BuildingDies, function BuildingDies)
call TriggerAddAction(gg_trg_DuplicateBuildingSite, function DuplicateBuildingSite)
call TriggerAddAction(gg_trg_SmartOrderOnBuildingSite, function SmartOrderOnBuildingSite)
call TriggerAddAction(gg_trg_LeaveBuildingSite, function LeaveBuildingSite)
call TriggerAddAction(gg_trg_Construct, function Construct)
endfunction
endlibrary
//TESH.scrollpos=4
//TESH.alwaysfold=0
/*-------------------------------------------------------------
//Version number:
1.04
//Description:
This system shows each player informations about his currently selected unit in a multiboard and periodically refreshes these informations.
Add new lines with "AddMultiboardline" with a text and an icon input.
Add head/subhead lines by setting the icon path of a line to "UI\\Minimap\\MinimapIconCreepLoc2.blp"/"UI\\Minimap\\MinimapIconCreepLoc2.blp".
You can show different types of informations depending on the selected unit by adding if-then-else conditions, etc.
Use "AddArrow" to mark units that are linked in a way to the current selected unit.
Values in the parts under "CUSTOMIZABLE PART" have to be adjusted.
//Changelog:
-1.01:
Initial version
-1.02:
Improved ShowUnitInfo
Arrows are removed properly
-1.03:
Rewrote system to use a struct instead of several global variables
Optimized the multiboard adjustment
Multiboards are automatically maximized at initialisation
Arrows are now checked at every adjustment
Improved "EquateGroups"
-1.04:
Moved init functions ("InitMultiboards") to "INITIALISATION" section
-------------------------------------------------------------*/
library libUnitInf initializer Init_UnitInfoSystem requires libId, libBuilSite
//------------------
//CUSTOMIZABLE PART:
//------------------
globals
private constant integer udg_CountPlayers = 12 //Highest player slot in use
private constant integer udg_MaxArrows = udg_CountPlayers * 100
private constant real udg_AdjustingTime = 0.50
endglobals
private function GetUnitIconPath takes integer UnitID returns string
if (UnitID == libId_udg_Worker) then //Worker
return "ReplaceableTextures\\CommandButtons\\BTNPeasant.blp"
elseif (UnitID == libId_udg_Architect) then //Architect
return "ReplaceableTextures\\CommandButtons\\BTNBloodElfPeasant.blp"
elseif (UnitID == libId_udg_AxeWarrior) then //Axe warrior
return "ReplaceableTextures\\CommandButtons\\BTNBandit.blp"
elseif (UnitID == libId_udg_SpearThrower) then //Spear thrower
return "ReplaceableTextures\\CommandButtons\\BTNBanditSpearThrower.blp"
elseif (UnitID == libId_udg_Archer) then //Archer
return "ReplaceableTextures\\CommandButtons\\BTNHighElvenArcher.blp"
elseif (UnitID == libId_udg_Knight) then //Knight
return "ReplaceableTextures\\CommandButtons\\BTNKnight.blp"
elseif (UnitID == libId_udg_Priest) then //Priest
return "ReplaceableTextures\\CommandButtons\\BTNPriest.blp"
elseif (UnitID == libId_udg_ArmouredSwordman) then //Armoured swordman
return "ReplaceableTextures\\CommandButtons\\BTNFootman.blp"
elseif (UnitID == libId_udg_Paladin) then //Paladin
return "ReplaceableTextures\\CommandButtons\\BTNHeroMountainKing.blp"
elseif (UnitID == libId_udg_Scout) then //Scout
return "ReplaceableTextures\\CommandButtons\\BTNMedivh.blp"
elseif (UnitID == libId_udg_Pikeman) then //Pikeman
return "ReplaceableTextures\\CommandButtons\\BTNArthas.blp"
endif
return null
endfunction
private function GetBuildingArrowPosHight takes integer StructureID returns real
return 200.00
endfunction
//-------------
//PRIVATE PART:
//-------------
globals
private group udg_EquateGroups_GroupTemp1 = null
endglobals
private function EquateGroups_Function1 takes nothing returns nothing
call GroupAddUnit(udg_EquateGroups_GroupTemp1, GetEnumUnit())
endfunction
//Changes the given target group (DestGroup) to an exact copy of the given source group (SourceGroup):
private function EquateGroups takes group SourceGroup, group DestGroup returns nothing
if (udg_EquateGroups_GroupTemp1 == null) then
call GroupClear(DestGroup)
set udg_EquateGroups_GroupTemp1 = DestGroup
call ForGroup(SourceGroup, function EquateGroups_Function1)
set DestGroup = udg_EquateGroups_GroupTemp1
set udg_EquateGroups_GroupTemp1 = null
else
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Simultaneous use of EquateGroups")
endif
endfunction
//-----------------
//DECLARATION PART:
//-----------------
globals
private constant integer udg_CountPlayersP = udg_CountPlayers + 1
private constant integer udg_MaxArrowsP = udg_MaxArrows + 1
endglobals
private struct InfoBoard
private multiboard Multiboard = null
private integer UsedLines = 0
private group ArrowsUnits = null
private effect array ArrowsEffect [udg_MaxArrowsP]
private unit array ArrowsTarget [udg_MaxArrowsP]
private integer ArrowsCount = 0
private group ArrowsTargetGroup = null
private group ArrowsCheckGroup = null
public method remove takes nothing returns nothing
local integer IntLoop1 = 1
call DestroyMultiboard(this.Multiboard)
set this.Multiboard = null
set this.UsedLines = 0
loop
exitwhen IntLoop1 > this.ArrowsCount
call DestroyEffect(this.ArrowsEffect[IntLoop1])
set this.ArrowsEffect[IntLoop1] = null
set this.ArrowsTarget[IntLoop1] = null
set IntLoop1 = IntLoop1 + 1
endloop
set this.ArrowsCount = 0
call DestroyGroup(this.ArrowsUnits)
set this.ArrowsUnits = null
call DestroyGroup(this.ArrowsTargetGroup)
set this.ArrowsTargetGroup = null
call DestroyGroup(this.ArrowsCheckGroup)
set this.ArrowsCheckGroup = null
call this.destroy()
endmethod
//--------------
//OTHER METHODS:
//--------------
public method New takes boolean Init returns nothing
set this.Multiboard = CreateMultiboard()
call MultiboardSetTitleText(this.Multiboard, "Unit Informations")
call MultiboardSetColumnCount(this.Multiboard, 1)
if (Init) then
call MultiboardMinimize(this.Multiboard, false)
set this.ArrowsCount = 0
set this.ArrowsUnits = CreateGroup()
set this.ArrowsTargetGroup = CreateGroup()
set this.ArrowsCheckGroup = CreateGroup()
endif
call MultiboardDisplay(this.Multiboard, false)
set this.UsedLines = 0
endmethod
public method Recreate takes nothing returns nothing
call DestroyMultiboard(this.Multiboard)
call this.New(false)
endmethod
public method Display takes integer PlayerID, boolean Show returns nothing
if (GetLocalPlayer() == Player(PlayerID - 1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call MultiboardDisplay(this.Multiboard, Show)
endif
endmethod
public method AddItem takes nothing returns multiboarditem
set this.UsedLines = this.UsedLines + 1
call MultiboardSetRowCount(this.Multiboard, this.UsedLines)
return MultiboardGetItem(this.Multiboard, this.UsedLines - 1, 0)
endmethod
public method AddArrow takes unit TargetUnit, integer TypeNumber returns nothing
local unit UnitTemp1
if (IsUnitInGroup(TargetUnit, this.ArrowsCheckGroup)) then
call GroupRemoveUnit(this.ArrowsCheckGroup, TargetUnit)
elseif (IsUnitInGroup(TargetUnit, this.ArrowsTargetGroup) == false) then
call GroupAddUnit(this.ArrowsTargetGroup, TargetUnit)
if (IsUnitType(TargetUnit, UNIT_TYPE_STRUCTURE)) then
set UnitTemp1 = CreateUnit(GetOwningPlayer(TargetUnit), libId_udg_Arrow, GetUnitX(TargetUnit), GetUnitY(TargetUnit), 270.00)
call GroupAddUnit(this.ArrowsUnits, UnitTemp1)
call SetUnitFlyHeight(UnitTemp1, GetBuildingArrowPosHight(GetUnitTypeId(TargetUnit)), 0)
else
if (this.ArrowsCount >= udg_MaxArrows) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Too many arrows")
return
endif
set this.ArrowsCount = this.ArrowsCount + 1
set this.ArrowsTarget[this.ArrowsCount] = TargetUnit
if (TypeNumber == 1) then
set this.ArrowsEffect[this.ArrowsCount] = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Aneu\\AneuCaster.mdl", TargetUnit, "overhead")
elseif (TypeNumber == 2) then
set this.ArrowsEffect[this.ArrowsCount] = AddSpecialEffectTarget("Abilities\\Spells\\Other\\GeneralAuraTarget\\GeneralAuraTarget.mdl", TargetUnit, "origin")
endif
endif
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
endmethod
public method AdjustArrows takes nothing returns nothing
local unit UnitTemp1
local integer IntLoop1
//Remove no longer needed arrows:
loop
set UnitTemp1 = FirstOfGroup(this.ArrowsCheckGroup)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(this.ArrowsCheckGroup, UnitTemp1)
call GroupRemoveUnit(this.ArrowsTargetGroup, UnitTemp1)
if (IsUnitInGroup(UnitTemp1, this.ArrowsUnits)) then
call GroupRemoveUnit(this.ArrowsUnits, UnitTemp1)
call RemoveUnit(UnitTemp1)
else
set IntLoop1 = 1
loop
exitwhen IntLoop1 > this.ArrowsCount
exitwhen this.ArrowsTarget[IntLoop1] == UnitTemp1
set IntLoop1 = IntLoop1 + 1
endloop
if (IntLoop1 <= this.ArrowsCount) then
call DestroyEffect(this.ArrowsEffect[IntLoop1])
set this.ArrowsEffect[IntLoop1] = this.ArrowsEffect[this.ArrowsCount]
set this.ArrowsTarget[IntLoop1] = this.ArrowsTarget[this.ArrowsCount]
set this.ArrowsEffect[this.ArrowsCount] = null
set this.ArrowsTarget[this.ArrowsCount] = null
set this.ArrowsCount = this.ArrowsCount - 1
endif
endif
endloop
call EquateGroups(this.ArrowsTargetGroup, this.ArrowsCheckGroup)
//Anti-Memory-Leak:
set UnitTemp1 = null
endmethod
public method RemoveArrows takes nothing returns nothing
local unit UnitTemp1
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > this.ArrowsCount
call DestroyEffect(this.ArrowsEffect[IntLoop1])
set this.ArrowsEffect[IntLoop1] = null
set this.ArrowsTarget[IntLoop1] = null
set IntLoop1 = IntLoop1 + 1
endloop
set this.ArrowsCount = 0
loop
set UnitTemp1 = FirstOfGroup(this.ArrowsUnits)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(this.ArrowsUnits, UnitTemp1)
call RemoveUnit(UnitTemp1)
endloop
call GroupClear(this.ArrowsTargetGroup)
call GroupClear(this.ArrowsCheckGroup)
//Anti-Memory-Leak:
set UnitTemp1 = null
endmethod
endstruct
globals
private InfoBoard array udg_InfoBoards [udg_CountPlayersP]
private timer array udg_AdjustingTimer [udg_CountPlayersP]
private unit array udg_SelectedUnit [udg_CountPlayersP]
private constant trigger gg_trg_UnitIsSelected = CreateTrigger()
private constant trigger gg_trg_InitMultiboards = CreateTrigger()
endglobals
//-------------
//PRIVATE PART:
//-------------
private function AddMultiboardline takes string Text, string IconPath, integer PlayerID returns nothing
local multiboarditem MultiboardItem = udg_InfoBoards[PlayerID].AddItem()
call MultiboardSetItemValue(MultiboardItem, Text)
call MultiboardSetItemIcon(MultiboardItem, IconPath)
if (IconPath == "UI\\Minimap\\MinimapIconCreepLoc2.blp") then
call MultiboardSetItemValueColor(MultiboardItem, 255, 0, 0, 255)
elseif (IconPath == "UI\\Minimap\\MinimapIconCreepLoc.blp") then
call MultiboardSetItemValueColor(MultiboardItem, 255, 200, 0, 255)
endif
call MultiboardSetItemWidth(MultiboardItem, 0.15)
call MultiboardReleaseItem(MultiboardItem)
//Anti-Memory-Leak:
set MultiboardItem = null
endfunction
//------------------
//CUSTOMIZABLE PART:
//------------------
private function MultiboardInfos takes integer PlayerID, unit SelectedUnit returns boolean
local boolean NoInfo = true
local integer IntTemp1
local integer IntTemp2
local integer IntTemp3
local integer IntLoop1
local unit UnitTemp1
local group GroupTemp1
local integer array IntArrayTemp1
local integer array IntArrayTemp2
if (libBuilSite_GetBuildingSiteNumber(SelectedUnit) > 0 and GetOwningPlayer(SelectedUnit) == Player(PlayerID - 1)) then
set NoInfo = false
set IntTemp1 = libBuilSite_GetBuildingSiteNumber(SelectedUnit)
//Show building site infos:
call AddMultiboardline("Building site data:", "UI\\Minimap\\MinimapIconCreepLoc2.blp", PlayerID)
set IntLoop1 = 1
loop
set IntTemp2 = libBuilSite_GetBuildingSiteInfo(IntTemp1, 2, IntLoop1)
exitwhen IntTemp2 == -1
set IntTemp3 = libBuilSite_GetBuildingSiteInfo(IntTemp1, 4, IntLoop1)
if (IntTemp2 != 0 and IntTemp3 > 0) then
set UnitTemp1 = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), IntTemp2, 0.00, 0.00, 0.00)
call AddMultiboardline(GetUnitName(UnitTemp1) + ": " + I2S(libBuilSite_GetBuildingSiteInfo(IntTemp1, 3, IntLoop1)) + "/(" + I2S(IntTemp3) + "-" + I2S(libBuilSite_GetBuildingSiteInfo(IntTemp1, 5, IntLoop1)) + ")", GetUnitIconPath(IntTemp2), PlayerID)
call RemoveUnit(UnitTemp1)
endif
set IntLoop1 = IntLoop1 + 1
endloop
set IntTemp2 = libBuilSite_GetBuildingSiteInfo(IntTemp1, 1, 0)
if (IntTemp2 == -1000) then
call AddMultiboardline("Not enough worker available", "ReplaceableTextures\\CommandButtons\\PASBTNEngineeringUpgrade.blp", PlayerID)
elseif (IntTemp2 == -2000) then
call AddMultiboardline("Not enough bulding materials available", "ReplaceableTextures\\CommandButtons\\PASBTNEngineeringUpgrade.blp", PlayerID)
elseif (IntTemp2 < 0) then
call AddMultiboardline("Structure is self-building (" + I2S((-1) * IntTemp2) + "s)", "ReplaceableTextures\\CommandButtons\\PASBTNEngineeringUpgrade.blp", PlayerID)
else
call AddMultiboardline("Left building time: " + I2S(IntTemp2), "ReplaceableTextures\\CommandButtons\\PASBTNEngineeringUpgrade.blp", PlayerID)
endif
//Add arrows to units:
call udg_InfoBoards[PlayerID].AddArrow(SelectedUnit, 1)
set GroupTemp1 = libBuilSite_GetWorkerGroup(IntTemp1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call udg_InfoBoards[PlayerID].AddArrow(UnitTemp1, 1)
endloop
call DestroyGroup(GroupTemp1)
elseif (GetUnitTypeId(SelectedUnit) == 'h02Y' and GetOwningPlayer(SelectedUnit) == Player(PlayerID - 1)) then //Village square
set NoInfo = false
//Show civil infos:
call AddMultiboardline("Population (civil):", "UI\\Minimap\\MinimapIconCreepLoc2.blp", PlayerID)
set GroupTemp1 = CreateGroup()
call GroupEnumUnitsOfPlayer(GroupTemp1, Player(PlayerID - 1), null)
//Counted unit types:
set IntTemp1 = 1
set IntArrayTemp1[IntTemp1] = libId_udg_Worker //Worker
set IntArrayTemp2[IntTemp1] = 0
set IntTemp1 = IntTemp1 + 1
set IntArrayTemp1[IntTemp1] = libId_udg_Architect //Architect
set IntArrayTemp2[IntTemp1] = 0
set IntTemp1 = IntTemp1 + 1
set IntArrayTemp1[IntTemp1] = libId_udg_Scout //Scout
set IntArrayTemp2[IntTemp1] = 0
set IntTemp1 = IntTemp1 + 1
set IntArrayTemp1[IntTemp1] = 0
//Count different unit types:
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
if (GetUnitState(UnitTemp1, UNIT_STATE_LIFE) >= 1.00) then
set IntTemp1 = GetUnitTypeId(UnitTemp1)
set IntLoop1 = 1
loop
exitwhen IntArrayTemp1[IntLoop1] == 0
if (IntTemp1 == IntArrayTemp1[IntLoop1]) then
set IntArrayTemp2[IntLoop1] = IntArrayTemp2[IntLoop1] + 1
//Add arrow to unit:
call udg_InfoBoards[PlayerID].AddArrow(UnitTemp1, 2)
endif
set IntLoop1 = IntLoop1 + 1
endloop
endif
endloop
call DestroyGroup(GroupTemp1)
//Show population counts:
set IntLoop1 = 1
loop
exitwhen IntArrayTemp1[IntLoop1] == 0
if (IntArrayTemp2[IntLoop1] > 0) then
set UnitTemp1 = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), IntArrayTemp1[IntLoop1], 0.00, 0.00, 0.00)
call AddMultiboardline(GetUnitName(UnitTemp1) + ": " + I2S(IntArrayTemp2[IntLoop1]), GetUnitIconPath(IntArrayTemp1[IntLoop1]), PlayerID)
call RemoveUnit(UnitTemp1)
endif
set IntLoop1 = IntLoop1 + 1
endloop
//Add arrow to unit:
call udg_InfoBoards[PlayerID].AddArrow(SelectedUnit, 1)
elseif (IsUnitType(SelectedUnit, UNIT_TYPE_TOWNHALL) and GetOwningPlayer(SelectedUnit) == Player(PlayerID - 1)) then
set NoInfo = false
//Show military infos:
call AddMultiboardline("Population (military):", "UI\\Minimap\\MinimapIconCreepLoc2.blp", PlayerID)
set GroupTemp1 = CreateGroup()
call GroupEnumUnitsOfPlayer(GroupTemp1, Player(PlayerID - 1), null)
//Counted unit types:
set IntTemp1 = 1
set IntArrayTemp1[IntTemp1] = libId_udg_AxeWarrior //Axe warrior
set IntArrayTemp2[IntTemp1] = 0
set IntTemp1 = IntTemp1 + 1
set IntArrayTemp1[IntTemp1] = libId_udg_SpearThrower //Spear thrower
set IntArrayTemp2[IntTemp1] = 0
set IntTemp1 = IntTemp1 + 1
set IntArrayTemp1[IntTemp1] = libId_udg_ArmouredSwordman //Armoured swordman
set IntArrayTemp2[IntTemp1] = 0
set IntTemp1 = IntTemp1 + 1
set IntArrayTemp1[IntTemp1] = libId_udg_Archer //Archer
set IntArrayTemp2[IntTemp1] = 0
set IntTemp1 = IntTemp1 + 1
set IntArrayTemp1[IntTemp1] = libId_udg_Knight //Knight
set IntArrayTemp2[IntTemp1] = 0
set IntTemp1 = IntTemp1 + 1
set IntArrayTemp1[IntTemp1] = libId_udg_Priest //Priest
set IntArrayTemp2[IntTemp1] = 0
set IntTemp1 = IntTemp1 + 1
set IntArrayTemp1[IntTemp1] = libId_udg_Paladin //Paladin
set IntArrayTemp2[IntTemp1] = 0
set IntTemp1 = IntTemp1 + 1
set IntArrayTemp1[IntTemp1] = libId_udg_Pikeman //Pikeman
set IntArrayTemp2[IntTemp1] = 0
set IntTemp1 = IntTemp1 + 1
set IntArrayTemp1[IntTemp1] = 0
//Count different unit types:
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
if (GetUnitState(UnitTemp1, UNIT_STATE_LIFE) >= 1.00) then
set IntTemp1 = GetUnitTypeId(UnitTemp1)
set IntLoop1 = 1
loop
exitwhen IntArrayTemp1[IntLoop1] == 0
if (IntTemp1 == IntArrayTemp1[IntLoop1]) then
set IntArrayTemp2[IntLoop1] = IntArrayTemp2[IntLoop1] + 1
//Add arrow to unit:
call udg_InfoBoards[PlayerID].AddArrow(UnitTemp1, 2)
endif
set IntLoop1 = IntLoop1 + 1
endloop
endif
endloop
call DestroyGroup(GroupTemp1)
//Show population counts:
set IntLoop1 = 1
loop
exitwhen IntArrayTemp1[IntLoop1] == 0
if (IntArrayTemp2[IntLoop1] > 0) then
set UnitTemp1 = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), IntArrayTemp1[IntLoop1], 0.00, 0.00, 0.00)
call AddMultiboardline(GetUnitName(UnitTemp1) + ": " + I2S(IntArrayTemp2[IntLoop1]), GetUnitIconPath(IntArrayTemp1[IntLoop1]), PlayerID)
call RemoveUnit(UnitTemp1)
endif
set IntLoop1 = IntLoop1 + 1
endloop
//Add arrow to unit:
call udg_InfoBoards[PlayerID].AddArrow(SelectedUnit, 1)
endif
call udg_InfoBoards[PlayerID].AdjustArrows()
//Anti-Memory-Leaks:
set UnitTemp1 = null
set GroupTemp1 = null
//------------------
return NoInfo
endfunction
//-------------
//PRIVATE PART:
//-------------
private function ShowUnitInfo takes integer PlayerID returns nothing
//Check if unit is still selected:
if (IsUnitSelected(udg_SelectedUnit[PlayerID], Player(PlayerID - 1)) == false) then
//Hide multiboard:
call PauseTimer(udg_AdjustingTimer[PlayerID])
set udg_SelectedUnit[PlayerID] = null
call udg_InfoBoards[PlayerID].Display(PlayerID, false)
call udg_InfoBoards[PlayerID].RemoveArrows()
return
endif
//Recreate multiboard:
call udg_InfoBoards[PlayerID].Recreate()
//Get unit informations:
if (MultiboardInfos(PlayerID, udg_SelectedUnit[PlayerID])) then
//Hide multiboard:
call PauseTimer(udg_AdjustingTimer[PlayerID])
set udg_SelectedUnit[PlayerID] = null
call udg_InfoBoards[PlayerID].Display(PlayerID, false)
call udg_InfoBoards[PlayerID].RemoveArrows()
else
//Show multiboard:
call udg_InfoBoards[PlayerID].Display(PlayerID, true)
endif
endfunction
private function AdjustUnitInfo takes nothing returns nothing
local timer ExpiredTimer = GetExpiredTimer()
local integer IntLoop1 = 1
//Get player ID:
loop
exitwhen IntLoop1 > udg_CountPlayers
exitwhen udg_AdjustingTimer[IntLoop1] == ExpiredTimer
set IntLoop1 = IntLoop1 + 1
endloop
if (IntLoop1 > udg_CountPlayers) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Couldn't find timer")
return
endif
call ShowUnitInfo(IntLoop1)
//Anti-Memory-Leak:
set ExpiredTimer = null
endfunction
//---------------------
//EVENT-TRIGGERED PART:
//---------------------
private function UnitIsSelected takes nothing returns nothing
local integer PlayerID = GetPlayerId(GetTriggerPlayer()) + 1
//Remove old informations:
call PauseTimer(udg_AdjustingTimer[PlayerID])
call udg_InfoBoards[PlayerID].RemoveArrows()
//Get new unit informations:
set udg_SelectedUnit[PlayerID] = GetTriggerUnit()
if (udg_SelectedUnit[PlayerID] != null) then
call ShowUnitInfo(PlayerID)
call TimerStart(udg_AdjustingTimer[PlayerID], udg_AdjustingTime, true, function AdjustUnitInfo)
endif
endfunction
//---------------
//INITIALISATION:
//---------------
private function InitMultiboards takes nothing returns nothing
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_CountPlayers
call udg_InfoBoards[IntLoop1].New(true)
set IntLoop1 = IntLoop1 + 1
endloop
endfunction
private function Init_UnitInfoSystem takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers and arrays:
call TriggerRegisterTimerEvent(gg_trg_InitMultiboards, 0.01, false)
loop
exitwhen IntLoop1 > udg_CountPlayers
set udg_AdjustingTimer[IntLoop1] = CreateTimer()
set udg_InfoBoards[IntLoop1] = InfoBoard.create()
call TriggerRegisterPlayerUnitEvent(gg_trg_UnitIsSelected, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SELECTED, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Actions:
call TriggerAddAction(gg_trg_UnitIsSelected, function UnitIsSelected)
call TriggerAddAction(gg_trg_InitMultiboards, function InitMultiboards)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*-------------------------------------------------------------
//Version number:
1.01
//Description:
Values in the parts under "PUBLIC/CUSTOMIZABLE PART" and "CUSTOMIZABLE PART" have to be adjusted.
//Public variables:
public constant real udg_HourLength
public constant real udg_SunriseTime
public constant real udg_SunsetTime
public integer udg_Year
public integer udg_Month
public integer udg_Day
public integer udg_Monthday
public integer udg_Weekday
//Public functions:
public function GetCurrentSeason takes nothing returns integer
public function GetElapsedTime takes nothing returns real
public function ChangeCurrentTime takes real TimeAddition returns real
//Changelog:
-1.01:
Initial version
-------------------------------------------------------------*/
library libTim initializer Init_TimeSystem
//-------------------------
//PUBLIC/CUSTOMIZABLE PART:
//-------------------------
globals
public constant real udg_HourLength = 25.00 //Real seconds per ingame hour
public constant real udg_SunriseTime = 6.00
public constant real udg_SunsetTime = 18.00
public integer udg_Year = 1200
public integer udg_Month = 4
public integer udg_Day = 1
public integer udg_Monthday = 1
public integer udg_Weekday = 1
endglobals
//Returns the meteorological season:
public function GetCurrentSeason takes nothing returns integer
if (udg_Month <= 2 or udg_Month >= 12) then
return 4
elseif (udg_Month <= 5) then
return 1
elseif (udg_Month <= 8) then
return 2
elseif (udg_Month <= 11) then
return 3
endif
return 0
endfunction
//------------------
//CUSTOMIZABLE PART:
//------------------
globals
private constant integer udg_MonthsPerYear = 12
private constant integer udg_DaysPerWeek = 7
private constant real udg_InitTime = 6.01
endglobals
private function GetDaysOfMonth takes integer Month returns integer
if (Month == 1 or Month == 3 or Month == 5 or Month == 7 or Month == 8 or Month == 10 or Month == 12) then
return 31
elseif (Month == 4 or Month == 6 or Month == 9 or Month == 11) then
return 30
elseif (Month == 2) then
return 28
endif
return 0
endfunction
//-----------------
//DECLARATION PART:
//-----------------
globals
private constant trigger gg_trg_NewDay = CreateTrigger()
endglobals
//------------
//PUBLIC PART:
//------------
//Returns the elapsed real time seconds:
public function GetElapsedTime takes nothing returns real
return ((udg_Day * 24 + GetFloatGameState(GAME_STATE_TIME_OF_DAY) - udg_InitTime) * libTim_udg_HourLength)
endfunction
//Adds a given positive amount of time (TimeAddition) to the current time:
public function ChangeCurrentTime takes real TimeAddition returns real
local real NewHour
local integer DayAddition
local integer IntTemp1
if (TimeAddition <= 0.00) then
return udg_Day * 24 + GetFloatGameState(GAME_STATE_TIME_OF_DAY)
endif
set TimeAddition = TimeAddition + GetFloatGameState(GAME_STATE_TIME_OF_DAY)
set NewHour = TimeAddition - I2R(R2I(TimeAddition / 24)) * 24
if (NewHour < 0) then
set NewHour = NewHour + 24
endif
set DayAddition = R2I((TimeAddition - NewHour) / 24)
set udg_Day = udg_Day + DayAddition
//Adjust date:
set udg_Monthday = udg_Monthday + DayAddition
loop
set IntTemp1 = GetDaysOfMonth(udg_Month)
exitwhen udg_Monthday <= IntTemp1
set udg_Monthday = udg_Monthday - IntTemp1
set udg_Month = udg_Month + 1
if (udg_Month > udg_MonthsPerYear) then
set udg_Month = 1
set udg_Year = udg_Year + 1
endif
endloop
//Adjust week-day:
set udg_Weekday = udg_Weekday + DayAddition
set udg_Weekday = udg_Weekday - (udg_Weekday / udg_DaysPerWeek) * udg_DaysPerWeek
if (udg_Weekday <= 0) then
set udg_Weekday = udg_Weekday + udg_DaysPerWeek
endif
//Adjust day time:
call SetFloatGameState(GAME_STATE_TIME_OF_DAY, NewHour)
//Return new time:
return udg_Day * 24 + NewHour
endfunction
//---------------------
//EVENT TRIGGERED PART:
//---------------------
private function NewDay takes nothing returns nothing
set udg_Day = udg_Day + 1
//Adjust date:
set udg_Monthday = udg_Monthday + 1
if (udg_Monthday > GetDaysOfMonth(udg_Month)) then
set udg_Monthday = 1
set udg_Month = udg_Month + 1
if (udg_Month > udg_MonthsPerYear) then
set udg_Month = 1
set udg_Year = udg_Year + 1
endif
endif
//Adjust week-day:
set udg_Weekday = udg_Weekday + 1
if (udg_Weekday > udg_DaysPerWeek) then
set udg_Weekday = 1
endif
endfunction
//---------------
//INITIALISATION:
//---------------
private function InitTime takes nothing returns nothing
call SetFloatGameState(GAME_STATE_TIME_OF_DAY, udg_InitTime)
endfunction
private function Init_TimeSystem takes nothing returns nothing
//Triggers:
call TriggerRegisterGameStateEvent(gg_trg_NewDay, GAME_STATE_TIME_OF_DAY, EQUAL, 0.00)
//Actions:
call TriggerAddAction(gg_trg_NewDay, function NewDay)
//Init functions:
call InitTime()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*-------------------------------------------------------------
//Version number:
1.02
//Description:
This system allows time dependant ("GetTeamWaveStartTime") waves with varying group members ("GetTeamGroupMember").
Values in the part under "CUSTOMIZABLE PART" have to be adjusted.
//Public functions:
public function InitSpawnTeams takes nothing returns nothing
//Changelog:
-1.01:
Initial version
-1.02
Incorporated TimeSystem
Moved init functions ("InitSpawnTeams") to "INITIALISATION" section
Added "IsSpawnPointAllowedForTeam" function
InitSpawnTeams: StartTime is now current ingame time
-------------------------------------------------------------*/
library libWav initializer Init_WaveSystem requires libId, libTim
//------------------
//CUSTOMIZABLE PART:
//------------------
globals
private constant integer udg_MaxSpawnTeams = 3
private constant integer udg_MaxSpawnPoints = 10
private constant real udg_WaveStartTimeShift = -2.00
endglobals
private function GetTeamOwnerID takes integer TeamSlot returns integer
if (TeamSlot == 1) then //Orc raiders
return 6
elseif (TeamSlot == 2) then //Undead
return 4
elseif (TeamSlot == 3) then //Enemy Kingdom
return 3
endif
return 0
endfunction
//Returns the members of the given group type (maximal 12 units per group):
private function GetTeamGroupMember takes integer TeamSlot, integer GroupType, integer TypeNumber, boolean ReturnID returns integer
if (TeamSlot == 1) then //Orc raiders
/*------------------
Small groups:
1 = TrollHeadhunter
2 = Raider
3 = Peon
4 = Devastator
5 = Shaman
6 = Grunt
7 = MixedShaman
8 = MixedLadder
9 = MixedDevastor
Big groups:
10 = TrollHeadhunter
11 = Raider
12 = Peon
13 = Devastator
14 = Shaman
15 = Grunt
16 = MixedNoSiege
17 = MixedLadder
18 = MixedDevastor
------------------*/
if (GroupType == 1) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_TrollHeadhunter //Troll Headhunter
else
return 4
endif
endif
elseif (GroupType == 2) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Raider //Raider
else
return 4
endif
endif
elseif (GroupType == 3) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 1
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Peon //Peon
else
return 5
endif
endif
elseif (GroupType == 4) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 1
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_TrollHeadhunter //Troll Headhunter
else
return 3
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Devastor //Devastator
else
return 2
endif
endif
elseif (GroupType == 5) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Shaman //Shaman
else
return 4
endif
endif
elseif (GroupType == 6) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 6
endif
endif
elseif (GroupType == 7) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 3
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_TrollHeadhunter //Troll Headhunter
else
return 2
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Shaman //Shaman
else
return 1
endif
endif
elseif (GroupType == 8) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_TrollHeadhunter //Troll Headhunter
else
return 1
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Peon //Peon
else
return 3
endif
endif
elseif (GroupType == 9) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 3
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_TrollHeadhunter //Troll Headhunter
else
return 2
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Devastor //Devastator
else
return 1
endif
endif
elseif (GroupType == 10) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_TrollHeadhunter //Troll Headhunter
else
return 10
endif
endif
elseif (GroupType == 11) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 4
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Raider //Raider
else
return 8
endif
endif
elseif (GroupType == 12) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 1
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Peon //Peon
else
return 11
endif
endif
elseif (GroupType == 13) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_TrollHeadhunter //Troll Headhunter
else
return 4
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Devastor //Devastator
else
return 6
endif
endif
elseif (GroupType == 14) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 4
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Shaman //Shaman
else
return 8
endif
endif
elseif (GroupType == 15) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 12
endif
endif
elseif (GroupType == 16) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 5
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_TrollHeadhunter //Troll Headhunter
else
return 3
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Shaman //Shaman
else
return 2
endif
elseif (TypeNumber == 4) then
if (ReturnID) then
return libId_udg_Raider //Raider
else
return 2
endif
endif
elseif (GroupType == 17) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 3
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_TrollHeadhunter //Troll Headhunter
else
return 2
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Peon //Peon
else
return 7
endif
endif
elseif (GroupType == 18) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Grunt //Grunt
else
return 5
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_TrollHeadhunter //Troll Headhunter
else
return 3
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Devastor //Devastator
else
return 3
endif
elseif (TypeNumber == 4) then
if (ReturnID) then
return libId_udg_Shaman //Shaman
else
return 1
endif
endif
endif
elseif (TeamSlot == 2) then //Undead
/*------------------
Small groups:
1 = Zombie
2 = Abomination
3 = Ghul
4 = MeatWagon
5 = SkeletonWarrior
6 = SkeletonArcher
7 = SkeletonMage
8 = SkeletonDragon
9 = MixedSkeletonGround
10 = MixedSkeletonAir
11 = MixedAbomination
12 = MixedMeatWagon
Big groups:
13 = Zombie
14 = Abomination
15 = Ghul
16 = MeatWagon
17 = SkeletonWarrior
18 = SkeletonArcher
19 = SkeletonMage
20 = SkeletonDragon
21 = MixedSkeletonGround
22 = MixedSkeletonAir
23 = MixedAbomination
24 = MixedMeatWagon
------------------*/
if (GroupType == 1) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 6
endif
endif
elseif (GroupType == 2) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 4
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Abomination //Abomination
else
return 2
endif
endif
elseif (GroupType == 3) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Ghul //Ghul
else
return 4
endif
endif
elseif (GroupType == 4) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 3
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_MeatWagon //Meat wagon
else
return 3
endif
endif
elseif (GroupType == 5) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 1
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SkeletonWarrior //Skeleton warrior
else
return 5
endif
endif
elseif (GroupType == 6) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SkeletonArcher //Skeleton archer
else
return 4
endif
endif
elseif (GroupType == 7) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 3
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SkeletonMage //Skeleton mage
else
return 3
endif
endif
elseif (GroupType == 8) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 5
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SkeletonDragon //Skeleton dragon
else
return 1
endif
endif
elseif (GroupType == 9) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 1
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SkeletonWarrior //Skeleton warrior
else
return 2
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_SkeletonArcher //Skeleton archer
else
return 2
endif
elseif (TypeNumber == 4) then
if (ReturnID) then
return libId_udg_SkeletonMage //Skeleton mage
else
return 1
endif
endif
elseif (GroupType == 10) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 1
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SkeletonWarrior //Skeleton warrior
else
return 2
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_SkeletonArcher //Skeleton archer
else
return 1
endif
elseif (TypeNumber == 4) then
if (ReturnID) then
return libId_udg_SkeletonMage //Skeleton mage
else
return 1
endif
elseif (TypeNumber == 5) then
if (ReturnID) then
return libId_udg_SkeletonDragon //Skeleton dragon
else
return 1
endif
endif
elseif (GroupType == 11) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 3
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Ghul //Ghul
else
return 2
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Abomination //Abomination
else
return 1
endif
endif
elseif (GroupType == 12) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SkeletonMage //Skeleton mage
else
return 2
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_MeatWagon //Meat wagon
else
return 2
endif
endif
elseif (GroupType == 13) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 12
endif
endif
elseif (GroupType == 14) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 8
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Abomination //Abomination
else
return 4
endif
endif
elseif (GroupType == 15) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 4
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Ghul //Ghul
else
return 8
endif
endif
elseif (GroupType == 16) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 7
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_MeatWagon //Meat wagon
else
return 5
endif
endif
elseif (GroupType == 17) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 1
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SkeletonWarrior //Skeleton warrior
else
return 11
endif
endif
elseif (GroupType == 18) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 3
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SkeletonArcher //Skeleton archer
else
return 9
endif
endif
elseif (GroupType == 19) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 4
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SkeletonMage //Skeleton mage
else
return 8
endif
endif
elseif (GroupType == 20) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 9
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SkeletonDragon //Skeleton dragon
else
return 3
endif
endif
elseif (GroupType == 21) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 1
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SkeletonWarrior //Skeleton warrior
else
return 5
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_SkeletonArcher //Skeleton archer
else
return 3
endif
elseif (TypeNumber == 4) then
if (ReturnID) then
return libId_udg_SkeletonMage //Skeleton mage
else
return 2
endif
elseif (TypeNumber == 5) then
if (ReturnID) then
return libId_udg_MeatWagon //Meat wagon
else
return 1
endif
endif
elseif (GroupType == 22) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 1
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SkeletonWarrior //Skeleton warrior
else
return 5
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_SkeletonArcher //Skeleton archer
else
return 3
endif
elseif (TypeNumber == 4) then
if (ReturnID) then
return libId_udg_SkeletonMage //Skeleton mage
else
return 1
endif
elseif (TypeNumber == 5) then
if (ReturnID) then
return libId_udg_SkeletonDragon //Skeleton dragon
else
return 2
endif
endif
elseif (GroupType == 23) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 6
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Ghul //Ghul
else
return 4
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Abomination //Abomination
else
return 2
endif
endif
elseif (GroupType == 24) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Zombie //Zombie
else
return 5
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Abomination //Abomination
else
return 1
endif
elseif (TypeNumber == 4) then
if (ReturnID) then
return libId_udg_MeatWagon //Meat wagon
else
return 3
endif
elseif (TypeNumber == 5) then
if (ReturnID) then
return libId_udg_SkeletonMage //Skeleton mage
else
return 3
endif
endif
endif
elseif (TeamSlot == 3) then //Enemy Kingdom
/*------------------
Small groups:
1 = Archer
2 = Knight
3 = LadderCarrier
4 = SpearThrower
5 = Paladin
6 = Caster
7 = Pikeman
8 = MortarTeam
9 = MixedHoly
10 = MixedLadder
11 = MixedMortarTeam
12 = MixedRanged
Big groups:
13 = Archer
14 = Knight
15 = LadderCarrier
16 = SpearThrower
17 = Paladin
18 = Caster
19 = Pikeman
20 = MortarTeam
21 = MixedHoly
22 = MixedLadder
23 = MixedMortarTeam
24 = MixedRanged
------------------*/
if (GroupType == 1) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_AxeWarrior //Axe warrior
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Archer //Archer
else
return 4
endif
endif
elseif (GroupType == 2) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_ArmouredSwordman //Armoured swordman
else
return 3
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Knight //Knight
else
return 3
endif
endif
elseif (GroupType == 3) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_AxeWarrior //Axe warrior
else
return 1
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_LadderCarrier //Ladder carrier
else
return 5
endif
endif
elseif (GroupType == 4) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_AxeWarrior //Axe warrior
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SpearThrower //Spear thrower
else
return 4
endif
endif
elseif (GroupType == 5) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_ArmouredSwordman //Armoured swordman
else
return 3
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Paladin //Paladin
else
return 3
endif
endif
elseif (GroupType == 6) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_ArmouredSwordman //Armoured swordman
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Mage //Mage
else
return 2
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Priest //Priest
else
return 2
endif
endif
elseif (GroupType == 7) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_ArmouredSwordman //Armoured swordman
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Pikeman //Pikeman
else
return 4
endif
endif
elseif (GroupType == 8) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_AxeWarrior //Axe warrior
else
return 3
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_MortarTeam //Mortar team
else
return 3
endif
endif
elseif (GroupType == 9) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_ArmouredSwordman //Armoured swordman
else
return 1
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Priest //Priest
else
return 3
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Paladin //Paladin
else
return 2
endif
endif
elseif (GroupType == 10) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_AxeWarrior //Axe warrior
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_LadderCarrier //Ladder carrier
else
return 3
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_SpearThrower //Spear thrower
else
return 1
endif
endif
elseif (GroupType == 11) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_AxeWarrior //Axe warrior
else
return 3
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_MortarTeam //Mortar team
else
return 2
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_SpearThrower //Spear thrower
else
return 1
endif
endif
elseif (GroupType == 12) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Archer //Archer
else
return 3
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_MortarTeam //Mortar team
else
return 1
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_SpearThrower //Spear thrower
else
return 2
endif
endif
elseif (GroupType == 13) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_AxeWarrior //Axe warrior
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Archer //Archer
else
return 10
endif
endif
elseif (GroupType == 14) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_ArmouredSwordman //Armoured swordman
else
return 6
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Knight //Knight
else
return 6
endif
endif
elseif (GroupType == 15) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_AxeWarrior //Axe warrior
else
return 1
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_LadderCarrier //Ladder carrier
else
return 11
endif
endif
elseif (GroupType == 16) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_AxeWarrior //Axe warrior
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_SpearThrower //Spear thrower
else
return 10
endif
endif
elseif (GroupType == 17) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_ArmouredSwordman //Armoured swordman
else
return 6
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Paladin //Paladin
else
return 6
endif
endif
elseif (GroupType == 18) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_ArmouredSwordman //Armoured swordman
else
return 4
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Mage //Mage
else
return 4
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Priest //Priest
else
return 4
endif
endif
elseif (GroupType == 19) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_ArmouredSwordman //Armoured swordman
else
return 2
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Pikeman //Pikeman
else
return 10
endif
endif
elseif (GroupType == 20) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_AxeWarrior //Axe warrior
else
return 6
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_MortarTeam //Mortar team
else
return 6
endif
endif
elseif (GroupType == 21) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_ArmouredSwordman //Armoured swordman
else
return 3
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_Priest //Priest
else
return 5
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_Paladin //Paladin
else
return 4
endif
endif
elseif (GroupType == 22) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_AxeWarrior //Axe warrior
else
return 4
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_LadderCarrier //Ladder carrier
else
return 7
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_SpearThrower //Spear thrower
else
return 1
endif
endif
elseif (GroupType == 23) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_AxeWarrior //Axe warrior
else
return 4
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_MortarTeam //Mortar team
else
return 4
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_SpearThrower //Spear thrower
else
return 2
endif
elseif (TypeNumber == 4) then
if (ReturnID) then
return libId_udg_ArmouredSwordman //Armoured swordman
else
return 2
endif
endif
elseif (GroupType == 24) then
if (TypeNumber == 1) then
if (ReturnID) then
return libId_udg_Archer //Archer
else
return 5
endif
elseif (TypeNumber == 2) then
if (ReturnID) then
return libId_udg_MortarTeam //Mortar team
else
return 2
endif
elseif (TypeNumber == 3) then
if (ReturnID) then
return libId_udg_SpearThrower //Spear thrower
else
return 3
endif
elseif (TypeNumber == 4) then
if (ReturnID) then
return libId_udg_AxeWarrior //Axe warrior
else
return 2
endif
endif
endif
endif
return 0
endfunction
//Returns which group types are in the given wave (WaveNumber):
private function GetTeamWaveGroup takes integer TeamSlot, integer WaveNumber, integer GroupNumber returns integer
if (TeamSlot == 1) then //Orc raiders
if (WaveNumber == 1) then
if (GroupNumber == 1) then
return 8 //Small Group: MixedLadder
endif
elseif (WaveNumber == 2) then
if (GroupNumber == 1) then
return 7 //Small Group: MixedShaman
endif
elseif (WaveNumber == 3) then
if (GroupNumber == 1) then
return GetRandomInt(1,9) //Small Group: Random
endif
elseif (WaveNumber == 4) then
if (GroupNumber == 1) then
return 18 //Big Group: MixedDevastor
endif
elseif (WaveNumber == 5) then
if (GroupNumber == 1) then
return 6 //Small Group: Grunt
elseif (GroupNumber == 2) then
return 3 //Small Group: Peon
endif
elseif (WaveNumber == 6) then
if (GroupNumber == 1) then
return GetRandomInt(10,18) //Big Group: Random
endif
elseif (WaveNumber == 7) then
if (GroupNumber == 1) then
return GetRandomInt(1,9) //Small Group: Random
elseif (GroupNumber == 2) then
return GetRandomInt(1,9) //Small Group: Random
endif
elseif (WaveNumber == 8) then
if (GroupNumber == 1) then
return 16 //Big Group: MixedNoSiege
elseif (GroupNumber == 2) then
return 3 //Small Group: Peon
endif
elseif (WaveNumber == 9) then
if (GroupNumber == 1) then
return 2 //Small Group: Raider
elseif (GroupNumber == 2) then
return 4 //Small Group: Devastator
elseif (GroupNumber == 3) then
return 7 //Small Group: MixedShaman
endif
elseif (WaveNumber == 10) then
if (GroupNumber == 1) then
return 8 //Small Group: MixedLadder
elseif (GroupNumber == 2) then
return GetRandomInt(10,18) //Big Group: Random
endif
elseif (WaveNumber == 11) then
if (GroupNumber == 1) then
return 1 //Small Group: TrollHeadhunter
elseif (GroupNumber == 2) then
return 18 //Big Group: MixedDevastor
endif
elseif (WaveNumber == 12) then
if (GroupNumber == 1) then
return 15 //Big Group: Grunt
elseif (GroupNumber == 2) then
return 12 //Big Group: Peon
endif
elseif (WaveNumber == 13) then
if (GroupNumber == 1) then
return GetRandomInt(1,9) //Small Group: Random
elseif (GroupNumber == 2) then
return GetRandomInt(1,9) //Small Group: Random
elseif (GroupNumber == 3) then
return GetRandomInt(1,9) //Small Group: Random
endif
elseif (WaveNumber == 14) then
if (GroupNumber == 1) then
return 11 //Big Group: Raider
endif
elseif (WaveNumber == 15) then
if (GroupNumber == 1) then
return 10 //Big Group: TrollHeadhunter
elseif (GroupNumber == 2) then
return 4 //Small Group: Devastator
endif
elseif (WaveNumber == 16) then
if (GroupNumber == 1) then
return 16 //Big Group: MixedNoSiege
elseif (GroupNumber == 2) then
return 12 //Big Group: Peon
endif
elseif (WaveNumber == 17) then
if (GroupNumber == 1) then
return 18 //Big Group: MixedDevastor
endif
elseif (WaveNumber == 18) then
if (GroupNumber == 1) then
return GetRandomInt(10,18) //Big Group: Random
elseif (GroupNumber == 2) then
return GetRandomInt(10,18) //Big Group: Random
endif
elseif (WaveNumber == 19) then
if (GroupNumber == 1) then
return GetRandomInt(1,9) //Small Group: Random
elseif (GroupNumber == 2) then
return GetRandomInt(1,9) //Small Group: Random
elseif (GroupNumber == 3) then
return GetRandomInt(1,9) //Small Group: Random
elseif (GroupNumber == 4) then
return GetRandomInt(1,9) //Small Group: Random
endif
elseif (WaveNumber == 20) then
if (GroupNumber == 1) then
return 7 //Small Group: MixedShaman
elseif (GroupNumber == 2) then
return 4 //Small Group: Devastator
elseif (GroupNumber == 3) then
return 3 //Small Group: Peon
endif
elseif (WaveNumber == 21) then
if (GroupNumber == 1) then
return 16 //Big Group: MixedNoSiege
elseif (GroupNumber == 2) then
return 18 //Big Group: MixedDevastor
elseif (GroupNumber == 3) then
return 3 //Small Group: Peon
endif
elseif (WaveNumber == 22) then
if (GroupNumber == 1) then
return GetRandomInt(1,9) //Small Group: Random
elseif (GroupNumber == 2) then
return GetRandomInt(1,9) //Small Group: Random
elseif (GroupNumber == 3) then
return GetRandomInt(1,9) //Small Group: Random
elseif (GroupNumber == 4) then
return GetRandomInt(1,9) //Small Group: Random
elseif (GroupNumber == 5) then
return GetRandomInt(1,9) //Small Group: Random
endif
elseif (WaveNumber == 23) then
if (GroupNumber == 1) then
return 13 //Big Group: Devastator
elseif (GroupNumber == 2) then
return 6 //Small Group: Grunt
endif
elseif (WaveNumber == 24) then
if (GroupNumber == 1) then
return 14 //Big Group: Shaman
elseif (GroupNumber == 2) then
return 12 //Big Group: Peon
elseif (GroupNumber == 3) then
return 15 //Big Group: Grunt
endif
endif
elseif (TeamSlot == 2) then //Undead
if (WaveNumber == 1) then
if (GroupNumber == 1) then
return 2 //Small Group: Abomination
elseif (GroupNumber == 2) then
return 1 //Small Group: Zombie
endif
elseif (WaveNumber == 2) then
if (GroupNumber == 1) then
return 23 //Big Group: MixedAbomination
elseif (GroupNumber == 2) then
return 3 //Small Group: Ghul
endif
elseif (WaveNumber == 3) then
if (GroupNumber == 1) then
return 21 //Big Group: MixedSkeletonGround
elseif (GroupNumber == 2) then
return 6 //Small Group: SkeletonArcher
elseif (GroupNumber == 3) then
return 2 //Small Group: Abomination
endif
elseif (WaveNumber == 4) then
if (GroupNumber == 1) then
return 19 //Big Group: SkeletonMage
elseif (GroupNumber == 2) then
return 17 //Big Group: SkeletonWarrior
elseif (GroupNumber == 3) then
return 2 //Small Group: Abomination
endif
elseif (WaveNumber == 5) then
if (GroupNumber == 1) then
return 9 //Small Group: MixedSkeletonGround
elseif (GroupNumber == 2) then
return 11 //Small Group: MixedAbomination
elseif (GroupNumber == 3) then
return 10 //Small Group: MixedSkeletonAir
endif
elseif (WaveNumber == 6) then
if (GroupNumber == 1) then
return GetRandomInt(1,12) //Small Group: Random
elseif (GroupNumber == 2) then
return GetRandomInt(1,12) //Small Group: Random
endif
elseif (WaveNumber == 7) then
if (GroupNumber == 1) then
return 3 //Small Group: Ghul
elseif (GroupNumber == 2) then
return 23 //Big Group: MixedAbomination
endif
elseif (WaveNumber == 8) then
if (GroupNumber == 1) then
return 2 //Small Group: Abomination
elseif (GroupNumber == 2) then
return 21 //Big Group: MixedSkeletonGround
endif
elseif (WaveNumber == 9) then
if (GroupNumber == 1) then
return 22 //Big Group: MixedSkeletonAir
elseif (GroupNumber == 2) then
return 23 //Big Group: MixedAbomination
endif
elseif (WaveNumber == 10) then
if (GroupNumber == 1) then
return GetRandomInt(13,24) //Big Group: Random
elseif (GroupNumber == 2) then
return GetRandomInt(1,12) //Small Group: Random
endif
elseif (WaveNumber == 11) then
if (GroupNumber == 1) then
return 13//Big Group: Zombie
elseif (GroupNumber == 2) then
return 14 //Big Group: Abomination
endif
elseif (WaveNumber == 12) then
if (GroupNumber == 1) then
return 15//Big Group: Ghul
elseif (GroupNumber == 2) then
return 23 //Big Group: MixedAbomination
endif
elseif (WaveNumber == 13) then
if (GroupNumber == 1) then
return GetRandomInt(13,24) //Big Group: Random
elseif (GroupNumber == 2) then
return GetRandomInt(13,24) //Big Group: Random
endif
elseif (WaveNumber == 14) then
if (GroupNumber == 1) then
return 21 //Big Group: MixedSkeletonGround
elseif (GroupNumber == 2) then
return 11 //Small Group: MixedAbomination
elseif (GroupNumber == 3) then
return 22 //Big Group: MixedSkeletonAir
endif
elseif (WaveNumber == 15) then
if (GroupNumber == 1) then
return 13 //Big Group: Zombie
elseif (GroupNumber == 2) then
return 2 //Small Group: Abomination
elseif (GroupNumber == 3) then
return 13 //Big Group: Zombie
endif
elseif (WaveNumber == 16) then
if (GroupNumber == 1) then
return 21 //Big Group: MixedSkeletonGround
elseif (GroupNumber == 2) then
return 10 //Small Group: MixedSkeletonAir
elseif (GroupNumber == 3) then
return 22 //Big Group: MixedSkeletonAir
elseif (GroupNumber == 4) then
return 2 //Small Group: Abomination
endif
endif
elseif (TeamSlot == 3) then //Enemy Kingdom
if (WaveNumber == 1) then
if (GroupNumber == 1) then
return GetRandomInt(1,12) //Small Group: Random
endif
elseif (WaveNumber == 2) then
if (GroupNumber == 1) then
return GetRandomInt(1,12) //Small Group: Random
endif
elseif (WaveNumber == 3) then
if (GroupNumber == 1) then
return GetRandomInt(1,12) //Small Group: Random
endif
elseif (WaveNumber == 4) then
if (GroupNumber == 1) then
return GetRandomInt(1,12) //Small Group: Random
endif
elseif (WaveNumber == 5) then
if (GroupNumber == 1) then
return GetRandomInt(1,12) //Small Group: Random
endif
elseif (WaveNumber == 6) then
if (GroupNumber == 1) then
return GetRandomInt(13,24) //Big Group: Random
endif
elseif (WaveNumber == 7) then
if (GroupNumber == 1) then
return GetRandomInt(13,24) //Big Group: Random
endif
elseif (WaveNumber == 8) then
if (GroupNumber == 1) then
return GetRandomInt(13,24) //Big Group: Random
endif
elseif (WaveNumber == 9) then
if (GroupNumber == 1) then
return GetRandomInt(13,24) //Big Group: Random
endif
endif
endif
return 0
endfunction
//Returns the time at which the given wave (TeamSlot, WaveNumber) spawns:
private function GetTeamWaveStartTime_Function1 takes integer Day, real Hour returns real
return ((Day * 24.0 + Hour) * libTim_udg_HourLength)
endfunction
private function GetTeamWaveStartTime takes integer TeamSlot, integer WaveNumber returns real
if (TeamSlot == 1) then //Orc raiders
if (WaveNumber == 1) then
return GetTeamWaveStartTime_Function1(0, GetRandomReal(9, 12))
elseif (WaveNumber == 2) then
return GetTeamWaveStartTime_Function1(0, GetRandomReal(15, 18))
elseif (WaveNumber == 3) then
return GetTeamWaveStartTime_Function1(1, GetRandomReal(5, 8))
elseif (WaveNumber == 4) then
return GetTeamWaveStartTime_Function1(1, GetRandomReal(12, 15))
elseif (WaveNumber == 5) then
return GetTeamWaveStartTime_Function1(2, GetRandomReal(5, 8))
elseif (WaveNumber == 6) then
return GetTeamWaveStartTime_Function1(2, GetRandomReal(12, 15))
elseif (WaveNumber == 7) then
return GetTeamWaveStartTime_Function1(3, GetRandomReal(5, 8))
elseif (WaveNumber == 8) then
return GetTeamWaveStartTime_Function1(3, GetRandomReal(12, 15))
elseif (WaveNumber == 9) then
return GetTeamWaveStartTime_Function1(4, GetRandomReal(5, 8))
elseif (WaveNumber == 10) then
return GetTeamWaveStartTime_Function1(4, GetRandomReal(12, 15))
elseif (WaveNumber == 11) then
return GetTeamWaveStartTime_Function1(5, GetRandomReal(5, 8))
elseif (WaveNumber == 12) then
return GetTeamWaveStartTime_Function1(5, GetRandomReal(12, 15))
elseif (WaveNumber == 13) then
return GetTeamWaveStartTime_Function1(6, GetRandomReal(5, 7))
elseif (WaveNumber == 14) then
return GetTeamWaveStartTime_Function1(6, GetRandomReal(8.5, 10.5))
elseif (WaveNumber == 15) then
return GetTeamWaveStartTime_Function1(6, GetRandomReal(12, 14))
elseif (WaveNumber == 16) then
return GetTeamWaveStartTime_Function1(7, GetRandomReal(5, 7))
elseif (WaveNumber == 17) then
return GetTeamWaveStartTime_Function1(7, GetRandomReal(8.5, 10.5))
elseif (WaveNumber == 18) then
return GetTeamWaveStartTime_Function1(7, GetRandomReal(12, 14))
elseif (WaveNumber == 19) then
return GetTeamWaveStartTime_Function1(8, GetRandomReal(5, 7))
elseif (WaveNumber == 20) then
return GetTeamWaveStartTime_Function1(8, GetRandomReal(8.5, 10.5))
elseif (WaveNumber == 21) then
return GetTeamWaveStartTime_Function1(8, GetRandomReal(12, 14))
elseif (WaveNumber == 22) then
return GetTeamWaveStartTime_Function1(9, GetRandomReal(5, 7))
elseif (WaveNumber == 23) then
return GetTeamWaveStartTime_Function1(9, GetRandomReal(8.5, 10.5))
elseif (WaveNumber == 24) then
return GetTeamWaveStartTime_Function1(9, GetRandomReal(12, 14))
endif
elseif (TeamSlot == 2) then //Undead
if (WaveNumber == 1) then
return GetTeamWaveStartTime_Function1(0, GetRandomReal(22, 24))
elseif (WaveNumber == 2) then
return GetTeamWaveStartTime_Function1(1, GetRandomReal(22, 24))
elseif (WaveNumber == 3) then
return GetTeamWaveStartTime_Function1(2, GetRandomReal(22, 24))
elseif (WaveNumber == 4) then
return GetTeamWaveStartTime_Function1(3, GetRandomReal(22, 24))
elseif (WaveNumber == 5) then
return GetTeamWaveStartTime_Function1(4, GetRandomReal(22, 23))
elseif (WaveNumber == 6) then
return GetTeamWaveStartTime_Function1(5, GetRandomReal(1, 2))
elseif (WaveNumber == 7) then
return GetTeamWaveStartTime_Function1(5, GetRandomReal(22, 23))
elseif (WaveNumber == 8) then
return GetTeamWaveStartTime_Function1(6, GetRandomReal(1, 2))
elseif (WaveNumber == 9) then
return GetTeamWaveStartTime_Function1(6, GetRandomReal(22, 23))
elseif (WaveNumber == 10) then
return GetTeamWaveStartTime_Function1(7, GetRandomReal(1, 2))
elseif (WaveNumber == 11) then
return GetTeamWaveStartTime_Function1(7, GetRandomReal(22, 23))
elseif (WaveNumber == 12) then
return GetTeamWaveStartTime_Function1(8, GetRandomReal(1, 2))
elseif (WaveNumber == 13) then
return GetTeamWaveStartTime_Function1(8, GetRandomReal(22, 23))
elseif (WaveNumber == 14) then
return GetTeamWaveStartTime_Function1(9, GetRandomReal(1, 2))
elseif (WaveNumber == 15) then
return GetTeamWaveStartTime_Function1(9, GetRandomReal(22, 23))
elseif (WaveNumber == 16) then
return GetTeamWaveStartTime_Function1(10, GetRandomReal(1, 2))
endif
elseif (TeamSlot == 3) then //Enemy Kingdom
if (WaveNumber == 1) then
return GetTeamWaveStartTime_Function1(1, GetRandomReal(17, 20))
elseif (WaveNumber == 2) then
return GetTeamWaveStartTime_Function1(2, GetRandomReal(17, 20))
elseif (WaveNumber == 3) then
return GetTeamWaveStartTime_Function1(3, GetRandomReal(17, 20))
elseif (WaveNumber == 4) then
return GetTeamWaveStartTime_Function1(4, GetRandomReal(17, 20))
elseif (WaveNumber == 5) then
return GetTeamWaveStartTime_Function1(5, GetRandomReal(17, 20))
elseif (WaveNumber == 6) then
return GetTeamWaveStartTime_Function1(6, GetRandomReal(16, 20))
elseif (WaveNumber == 7) then
return GetTeamWaveStartTime_Function1(7, GetRandomReal(16, 20))
elseif (WaveNumber == 8) then
return GetTeamWaveStartTime_Function1(8, GetRandomReal(16, 20))
elseif (WaveNumber == 9) then
return GetTeamWaveStartTime_Function1(9, GetRandomReal(16, 20))
endif
endif
return 0.00
endfunction
private function GetTeamWaveTarget takes integer TeamSlot, integer WaveNumber, boolean ReturnX returns real
if (TeamSlot == 1) then //Orc raiders
if (ReturnX) then
return -2816.00
else
return 5632.00
endif
elseif (TeamSlot == 2) then //Undead
if (ReturnX) then
return -2816.00
else
return 5632.00
endif
elseif (TeamSlot == 3) then //Enemy Kingdom
if (ReturnX) then
return -2816.00
else
return 5632.00
endif
endif
return 0.00
endfunction
//Returns the spawn position of the given wave (TeamSlot, WaveNumber), 99999.99 means a random stored point:
private function GetTeamWaveSpawnPosition takes integer TeamSlot, integer WaveNumber, boolean ReturnX returns real
if (TeamSlot == 1) then //Orc raiders
if (WaveNumber == 1) then
if (ReturnX) then
return -256.00
else
return 512.00
endif
elseif (WaveNumber == 2) then
if (ReturnX) then
return -6912.00
else
return 8320.00
endif
endif
endif
return 99999.99
endfunction
//Returns if the given spawn points (SpawnPointNumber) are allowed as random spawn position for the given team (TeamSlot):
private function IsSpawnPointAllowedForTeam takes integer TeamSlot, integer SpawnPointNumber returns boolean
if (TeamSlot == 1) then //Orc raiders
if (SpawnPointNumber == 1) then
return true
elseif (SpawnPointNumber == 4) then
return true
endif
elseif (TeamSlot == 2) then //Undead
if (SpawnPointNumber == 2) then
return true
endif
elseif (TeamSlot == 3) then //Enemy Kingdom
if (SpawnPointNumber == 1) then
return true
elseif (SpawnPointNumber == 3) then
return true
endif
endif
return false
endfunction
//-----------------
//DECLARATION PART:
//-----------------
globals
private constant integer udg_MaxSpawnTeamsP = udg_MaxSpawnTeams + 1
private constant integer udg_MaxSpawnPointsP = udg_MaxSpawnPoints + 1
endglobals
private struct SpawnTeam
private integer PlayerID = 0
private integer CountPoints = 0
private real array PointX [udg_MaxSpawnPointsP]
private real array PointY [udg_MaxSpawnPointsP]
private timer WaveTimer = null
private integer WaveNumber = 0
//-----------
//IS METHODS:
//-----------
public method IsTimer takes timer Timer returns boolean
return (Timer == this.WaveTimer)
endmethod
//------------
//GET METHODS:
//------------
public method GetPlayerID takes nothing returns integer
return this.PlayerID
endmethod
public method GetWaveNumber takes nothing returns integer
return this.WaveNumber
endmethod
public method GetWaveTimer takes nothing returns timer
return this.WaveTimer
endmethod
public method GetSpawnPoint takes integer PointNumber, boolean ReturnX returns real
if (ReturnX) then
return this.PointX[PointNumber]
else
return this.PointY[PointNumber]
endif
endmethod
public method GetSpawnPointCount takes nothing returns integer
return this.CountPoints
endmethod
//------------
//SET METHODS:
//------------
public method SetWaveNumber takes integer WaveNumber returns nothing
set this.WaveNumber = WaveNumber
endmethod
//--------------
//OTHER METHODS:
//--------------
public method New takes integer PlayerID returns nothing
set this.PlayerID = PlayerID
set this.CountPoints = 0
set this.WaveTimer = CreateTimer()
set this.WaveNumber = 0
endmethod
public method AddSpawnPoint takes real PosX, real PosY returns nothing
set this.CountPoints = this.CountPoints + 1
set this.PointX[this.CountPoints] = PosX
set this.PointY[this.CountPoints] = PosY
endmethod
endstruct
globals
private SpawnTeam array udg_SpawnTeams [udg_MaxSpawnTeamsP]
private constant trigger gg_trg_SpawnWaves = CreateTrigger()
endglobals
//-------------
//PRIVATE PART:
//-------------
private function StartNextWaveTimer takes nothing returns nothing
local timer ExpiredTimer = GetExpiredTimer()
local player Owner
local group GroupTemp1 = CreateGroup()
local unit UnitTemp1
local real RealTemp1
local real RealTemp2
local real RealTemp3
local real RealTemp4
local integer IntTemp1
local integer IntTemp2
local integer IntTemp3
local integer IntLoop1 = 1
local integer IntLoop2 = 1
local integer IntLoop3
local integer IntLoop4
loop
exitwhen IntLoop1 > udg_MaxSpawnTeams
exitwhen udg_SpawnTeams[IntLoop1].IsTimer(ExpiredTimer)
set IntLoop1 = IntLoop1 + 1
endloop
if (IntLoop1 <= udg_MaxSpawnTeams) then
//Create wave:
set Owner = Player(udg_SpawnTeams[IntLoop1].GetPlayerID() - 1)
set IntTemp2 = udg_SpawnTeams[IntLoop1].GetWaveNumber()
set RealTemp1 = GetTeamWaveSpawnPosition(IntLoop1, IntTemp2, true)
if (RealTemp1 == 99999.99) then
set IntTemp1 = GetRandomInt(1, udg_SpawnTeams[IntLoop1].GetSpawnPointCount())
set RealTemp1 = udg_SpawnTeams[IntLoop1].GetSpawnPoint(IntTemp1, true)
set RealTemp2 = udg_SpawnTeams[IntLoop1].GetSpawnPoint(IntTemp1, false)
else
set RealTemp2 = GetTeamWaveSpawnPosition(IntLoop1, IntTemp2, false)
endif
set RealTemp3 = GetTeamWaveTarget(IntLoop1, IntTemp2, true)
set RealTemp4 = GetTeamWaveTarget(IntLoop1, IntTemp2, false)
loop
set IntTemp3 = GetTeamWaveGroup(IntLoop1, IntTemp2, IntLoop2)
exitwhen IntTemp3 == 0
//Create next group:
set IntLoop3 = 1
loop
set IntTemp1 = GetTeamGroupMember(IntLoop1, IntTemp3, IntLoop3, true)
exitwhen IntTemp1 == 0
set IntLoop4 = GetTeamGroupMember(IntLoop1, IntTemp3, IntLoop3, false)
loop
exitwhen IntLoop4 <= 0
set UnitTemp1 = CreateUnit(Owner, IntTemp1, RealTemp1, RealTemp2, GetRandomReal(0.00, 360.00))
call GroupAddUnit(GroupTemp1, UnitTemp1)
set IntLoop4 = IntLoop4 - 1
endloop
set IntLoop3 = IntLoop3 + 1
endloop
call GroupPointOrder(GroupTemp1, "attack", RealTemp3, RealTemp4)
call GroupClear(GroupTemp1)
set IntLoop2 = IntLoop2 + 1
endloop
//Start timer for next wave:
set RealTemp1 = GetTeamWaveStartTime(IntLoop1, IntTemp2 + 1) + udg_WaveStartTimeShift - libTim_GetElapsedTime()
if (RealTemp1 > 0.00) then
call udg_SpawnTeams[IntLoop1].SetWaveNumber(IntTemp2 + 1)
call TimerStart(ExpiredTimer, RealTemp1, false, function StartNextWaveTimer)
endif
endif
//Anti-Memory-Leak:
set ExpiredTimer = null
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
endfunction
//---------------
//INITIALISATION:
//---------------
private function InitSpawnTeams_Filter1 takes nothing returns boolean
return (GetUnitTypeId(GetFilterUnit()) == libId_udg_SpawnPoint)
endfunction
public function InitSpawnTeams takes nothing returns nothing
local real StartTime = GetFloatGameState(GAME_STATE_TIME_OF_DAY)
local boolexpr Filter1 = Condition(function InitSpawnTeams_Filter1)
local group GroupTemp1 = CreateGroup()
local unit UnitTemp1
local real RealTemp1
local integer IntTemp1
local integer IntLoop1 = 1
//Init spawn teams:
loop
exitwhen IntLoop1 > udg_MaxSpawnTeams
set udg_SpawnTeams[IntLoop1] = SpawnTeam.create()
call udg_SpawnTeams[IntLoop1].New(GetTeamOwnerID(IntLoop1))
set IntLoop1 = IntLoop1 + 1
endloop
//Init random spawn points:
call GroupEnumUnitsInRect(GroupTemp1, bj_mapInitialPlayableArea, Filter1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
set IntTemp1 = 100 - R2I(100 * GetUnitState(UnitTemp1, UNIT_STATE_LIFE) / GetUnitState(UnitTemp1, UNIT_STATE_MAX_LIFE))
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_MaxSpawnTeams
if (IsSpawnPointAllowedForTeam(IntLoop1, IntTemp1)) then
call udg_SpawnTeams[IntLoop1].AddSpawnPoint(GetUnitX(UnitTemp1), GetUnitY(UnitTemp1))
endif
set IntLoop1 = IntLoop1 + 1
endloop
call RemoveUnit(UnitTemp1)
endloop
//Start wave timers:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_MaxSpawnTeams
set RealTemp1 = GetTeamWaveStartTime(IntLoop1, 1) + udg_WaveStartTimeShift - StartTime * libTim_udg_HourLength
if (RealTemp1 > 0.00) then
call udg_SpawnTeams[IntLoop1].SetWaveNumber(1)
call TimerStart(udg_SpawnTeams[IntLoop1].GetWaveTimer(), RealTemp1, false, function StartNextWaveTimer)
endif
set IntLoop1 = IntLoop1 + 1
endloop
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
call DestroyBoolExpr(Filter1)
set Filter1 = null
endfunction
private function Init_WaveSystem takes nothing returns nothing
//
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*-------------------------------------------------------------
//Version number:
1.02
//Description:
Values in the parts under "CUSTOMIZABLE PART" have to be adjusted.
//Public functions:
public function ShowSpeakScene takes integer PlayerID, string Text, string Name, integer PortraitID, integer ColourID returns real
public function ShowSpeakSceneByUnit takes integer PlayerID, string Text, unit Speaker returns real
public function ApplyCameraTimed takes integer PlayerID, camerasetup Camera, real Time returns nothing
public function ApplyCameraTimedForForce takes force Force, camerasetup Camera, real Time returns nothing
public function SwitchCinematicMode takes integer PlayerID, boolean SwitchOn returns nothing
public function SwitchCameraLock takes integer PlayerID, unit Target, boolean SwitchOn returns nothing
public function IsCinematicSkipped takes integer PlayerID returns boolean
//Changelog:
-1.01:
Initial version
-1.02
Added a camera lock functionality
-------------------------------------------------------------*/
library libCin initializer Init_CinematicSystem requires libId
//------------------
//CUSTOMIZABLE PART:
//------------------
globals
private constant integer udg_CountPlayers = 12
private constant real udg_MinSpeechLength = 1.00
private constant real udg_SpeechTimePerLetter = 0.05
endglobals
//-----------------
//DECLARATION PART:
//-----------------
globals
private constant integer udg_CountPlayersP = udg_CountPlayers + 1
endglobals
private struct CinematicData
private boolean SwitchedOn = false
private integer PlayerID = 0
private fogmodifier Vision = null
private unit CameraLockDummy = null
private camerasetup CameraSetup = null
private boolean Skipped = false
//------------
//GET METHODS:
//------------
public method IsSkipped takes nothing returns boolean
return this.Skipped
endmethod
//--------------
//OTHER METHODS:
//--------------
public method New takes integer PlayerID returns nothing
set this.SwitchedOn = false
set this.PlayerID = PlayerID
set this.Vision = null
set this.CameraLockDummy = null
set this.CameraSetup = CreateCameraSetup()
set this.Skipped = false
endmethod
public method LockCamera takes unit Target, boolean LockOn returns nothing
if (LockOn) then
if (Target == null) then
if (this.CameraLockDummy == null) then
set this.CameraLockDummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), libId_udg_Dummy, 0.00, 0.00, 0.00)
call ShowUnit(this.CameraLockDummy, false)
endif
if (GetLocalPlayer() == Player(this.PlayerID - 1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SetCameraTargetController(this.CameraLockDummy, GetCameraTargetPositionX(), GetCameraTargetPositionY(), true)
endif
else
if (this.CameraLockDummy != null) then
call RemoveUnit(this.CameraLockDummy)
set this.CameraLockDummy = null
endif
if (GetLocalPlayer() == Player(this.PlayerID - 1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call PanCameraToTimed(GetUnitX(Target), GetUnitY(Target), 0.00)
call SetCameraTargetController(Target, 0.00, 0.00, true)
endif
endif
else
if (this.CameraLockDummy != null) then
call ShowUnit(this.CameraLockDummy, true)
call RemoveUnit(this.CameraLockDummy)
set this.CameraLockDummy = null
endif
call CameraSetupSetField(this.CameraSetup, CAMERA_FIELD_TARGET_DISTANCE, GetCameraField(CAMERA_FIELD_TARGET_DISTANCE), 0.00)
call CameraSetupSetField(this.CameraSetup, CAMERA_FIELD_FARZ, GetCameraField(CAMERA_FIELD_FARZ), 0.00)
call CameraSetupSetField(this.CameraSetup, CAMERA_FIELD_ZOFFSET, GetCameraField(CAMERA_FIELD_ZOFFSET), 0.00)
call CameraSetupSetField(this.CameraSetup, CAMERA_FIELD_ANGLE_OF_ATTACK, bj_RADTODEG * GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK), 0.00)
call CameraSetupSetField(this.CameraSetup, CAMERA_FIELD_FIELD_OF_VIEW, bj_RADTODEG * GetCameraField(CAMERA_FIELD_FIELD_OF_VIEW), 0.00)
call CameraSetupSetField(this.CameraSetup, CAMERA_FIELD_ROLL, bj_RADTODEG * GetCameraField(CAMERA_FIELD_ROLL), 0.00)
call CameraSetupSetField(this.CameraSetup, CAMERA_FIELD_ROTATION, bj_RADTODEG * GetCameraField(CAMERA_FIELD_ROTATION), 0.00)
call CameraSetupSetDestPosition(this.CameraSetup, GetCameraTargetPositionX(), GetCameraTargetPositionY(), 0.00)
if (GetLocalPlayer() == Player(this.PlayerID - 1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call ResetToGameCamera(0.00)
call CameraSetupApply(this.CameraSetup, false, false)
endif
endif
endmethod
public method Switch takes boolean SwitchOn returns nothing
if (SwitchOn == true and this.SwitchedOn == false) then
set this.SwitchedOn = true
set this.Skipped = false
set this.Vision = CreateFogModifierRect(Player(this.PlayerID - 1), FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea, false, false)
call FogModifierStart(this.Vision)
if (GetLocalPlayer() == Player(this.PlayerID - 1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call ShowInterface(false, 0.00)
call EnableUserControl(false)
call ClearTextMessages()
endif
call this.LockCamera(null, true)
elseif (SwitchOn == false and this.SwitchedOn == true) then
set this.SwitchedOn = false
call DestroyFogModifier(this.Vision)
set this.Vision = CreateFogModifierRect(Player(this.PlayerID - 1), FOG_OF_WAR_MASKED, bj_mapInitialPlayableArea, false, false)
call FogModifierStart(this.Vision)
call DestroyFogModifier(this.Vision)
if (GetLocalPlayer() == Player(this.PlayerID - 1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call ResetToGameCamera(2.00)
call ShowInterface(true, 2.00)
call EnableUserControl(true)
call ClearTextMessages()
endif
call this.LockCamera(null, false)
endif
endmethod
public method Skip takes nothing returns nothing
set this.Skipped = true
call this.Switch(false)
endmethod
endstruct
globals
private CinematicData array udg_CinematicDatas [udg_CountPlayersP]
private trigger gg_trg_CinematicSkipped = CreateTrigger()
endglobals
//------------
//PUBLIC PART:
//------------
public function ShowSpeakScene takes integer PlayerID, string Text, string Name, integer PortraitID, integer ColourID returns real
local real SpeechLength = StringLength(Text) * udg_SpeechTimePerLetter
if (SpeechLength < udg_MinSpeechLength) then
set SpeechLength = udg_MinSpeechLength
endif
set bj_cineModeSavedSeed = GetRandomInt(0, 1000000)
call SetRandomSeed(0)
if (GetLocalPlayer() == Player(PlayerID - 1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SetCinematicScene(PortraitID, GetPlayerColor(Player(ColourID - 1)), Name, Text, SpeechLength + bj_TRANSMISSION_PORT_HANGTIME, SpeechLength)
endif
call SetRandomSeed(bj_cineModeSavedSeed)
return SpeechLength
endfunction
public function ShowSpeakSceneByUnit takes integer PlayerID, string Text, unit Speaker returns real
local real SpeechLength = StringLength(Text) * udg_SpeechTimePerLetter
if (SpeechLength < udg_MinSpeechLength) then
set SpeechLength = udg_MinSpeechLength
endif
if (GetLocalPlayer() == Player(PlayerID - 1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SetCinematicScene(GetUnitTypeId(Speaker), GetPlayerColor(GetOwningPlayer(Speaker)), GetUnitName(Speaker), Text, SpeechLength + bj_TRANSMISSION_PORT_HANGTIME, SpeechLength)
endif
return SpeechLength
endfunction
public function ApplyCameraTimed takes integer PlayerID, camerasetup Camera, real Time returns nothing
if (GetLocalPlayer() == Player(PlayerID - 1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call PanCameraToTimed(CameraSetupGetDestPositionX(Camera), CameraSetupGetDestPositionY(Camera), Time)
call CameraSetupApplyForceDuration(Camera, false, Time)
endif
endfunction
public function ApplyCameraTimedForForce takes force Force, camerasetup Camera, real Time returns nothing
if (IsPlayerInForce(GetLocalPlayer(), Force)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call PanCameraToTimed(CameraSetupGetDestPositionX(Camera), CameraSetupGetDestPositionY(Camera), Time)
call CameraSetupApplyForceDuration(Camera, false, Time)
endif
endfunction
public function SwitchCinematicMode takes integer PlayerID, boolean SwitchOn returns nothing
call udg_CinematicDatas[PlayerID].Switch(SwitchOn)
endfunction
public function SwitchCameraLock takes integer PlayerID, unit Target, boolean SwitchOn returns nothing
call udg_CinematicDatas[PlayerID].LockCamera(Target, SwitchOn)
endfunction
public function IsCinematicSkipped takes integer PlayerID returns boolean
return udg_CinematicDatas[PlayerID].IsSkipped()
endfunction
//---------------------
//EVENT-TRIGGERED PART:
//---------------------
private function CinematicSkipped takes nothing returns nothing
local integer PlayerID = GetPlayerId(GetTriggerPlayer()) + 1
call udg_CinematicDatas[PlayerID].Skip()
endfunction
//----------------
//INITIALISATIONS:
//----------------
private function Init_CinematicSystem takes nothing returns nothing
local integer IntLoop1 = 1
//Arrays:
loop
exitwhen IntLoop1 > udg_CountPlayers
set udg_CinematicDatas[IntLoop1] = CinematicData.create()
if (udg_CinematicDatas[IntLoop1] == 0) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: CinematicData struct cap exceeded")
return
endif
call udg_CinematicDatas[IntLoop1].New(IntLoop1)
set IntLoop1 = IntLoop1 + 1
endloop
//Triggers:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_CountPlayers
call TriggerRegisterPlayerEvent(gg_trg_CinematicSkipped, Player(IntLoop1 - 1), EVENT_PLAYER_END_CINEMATIC)
set IntLoop1 = IntLoop1 + 1
endloop
//Actions:
call TriggerAddAction(gg_trg_CinematicSkipped, function CinematicSkipped)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*-------------------------------------------------------------
//Version number:
1.03
//Description:
Values in the parts under "CUSTOMIZABLE PART" and "PUBLIC/CUSTOMIZABLE PART" have to be adjusted.
//Public variables:
public string udg_CurrentWeather
public real udg_DistantVision
//Public functions:
public function SetCurrentWeather takes string WeatherType returns nothing
public function SetNextWeather takes string WeatherType returns nothing
//Changelog:
-1.01:
Initial version
-1.02:
Rearranged system structure and cleaned up everything
Added varying weather duration
Added weather transition
Remade date triggers
-1.03
Incorporated TimeSystem and removed shared variables
Rearranged fog adjustment triggers
Added udg_AntiSingularityAddition to avoid errors by dividing with zero
-------------------------------------------------------------*/
library libAdvWeath initializer Init_AdvancedWeatherSystem requires libTim
//------------------
//CUSTOMIZABLE PART:
//------------------
globals
private constant integer udg_FogSetting = 2 //1 = Old linear, 2 = New sinusoidal
private constant real udg_MinWeatherDuration = 75.00 //In real-time seconds
private constant real udg_MaxWeatherDuration = 150.00 //In real-time seconds
private constant real udg_WeatherTransitionDuration = 25.00 //In real-time seconds
private constant real udg_FogAdjustmentRate = 1.00
private constant real udg_FogIntensity = 0.50 //0.00 = No fog, 1.00 = Normal fog
endglobals
private function GetWeathereffectID takes string WeatherType returns integer
if (WeatherType == "Light sun") then
return 0
elseif (WeatherType == "Heavy sun") then
return 0
elseif (WeatherType == "Light mist") then
return 0
elseif (WeatherType == "Heavy mist") then
return 0
elseif (WeatherType == "Light wind") then
return 'WOlw'
elseif (WeatherType == "Heavy wind") then
return 'WOcw'
elseif (WeatherType == "Light snow") then
return 'SNls'
elseif (WeatherType == "Heavy snow") then
return 'SNhs'
elseif (WeatherType == "Light rain") then
return 'RLlr'
elseif (WeatherType == "Heavy rain") then
return 'RLhr'
endif
return 0
endfunction
private function GetSkyModelPath takes string WeatherType, real CurrentTime returns string
if (WeatherType == "Light sun") then
if (CurrentTime >= libTim_udg_SunriseTime and CurrentTime < libTim_udg_SunsetTime) then
return "Environment\\Sky\\LordaeronSummerSky\\LordaeronSummerSky.mdl"
else
return "Environment\\Sky\\FoggedSky\\FoggedSky.mdl"
endif
elseif (WeatherType == "Heavy sun") then
if (CurrentTime >= libTim_udg_SunriseTime and CurrentTime < libTim_udg_SunsetTime) then
return "Environment\\Sky\\LordaeronSummerSky\\LordaeronSummerSky.mdl"
else
return "Environment\\Sky\\FoggedSky\\FoggedSky.mdl"
endif
elseif (WeatherType == "Light mist") then
if (CurrentTime >= libTim_udg_SunriseTime and CurrentTime < libTim_udg_SunsetTime) then
return "Environment\\Sky\\BlizzardSky\\BlizzardSky.mdl"
else
return "Environment\\Sky\\FoggedSky\\FoggedSky.mdl"
endif
elseif (WeatherType == "Heavy mist") then
if (CurrentTime >= libTim_udg_SunriseTime and CurrentTime < libTim_udg_SunsetTime) then
return "Environment\\Sky\\BlizzardSky\\BlizzardSky.mdl"
else
return "Environment\\Sky\\FoggedSky\\FoggedSky.mdl"
endif
elseif (WeatherType == "Light wind") then
if (CurrentTime >= libTim_udg_SunriseTime and CurrentTime < libTim_udg_SunsetTime) then
return "Environment\\Sky\\LordaeronSummerSky\\LordaeronSummerSky.mdl"
else
return "Environment\\Sky\\FoggedSky\\FoggedSky.mdl"
endif
elseif (WeatherType == "Heavy wind") then
if (CurrentTime >= libTim_udg_SunriseTime and CurrentTime < libTim_udg_SunsetTime) then
return "Environment\\Sky\\LordaeronSummerSky\\LordaeronSummerSky.mdl"
else
return "Environment\\Sky\\FoggedSky\\FoggedSky.mdl"
endif
elseif (WeatherType == "Light snow") then
if (CurrentTime >= libTim_udg_SunriseTime and CurrentTime < libTim_udg_SunsetTime) then
return "Environment\\Sky\\BlizzardSky\\BlizzardSky.mdl"
else
return "Environment\\Sky\\FoggedSky\\FoggedSky.mdl"
endif
elseif (WeatherType == "Heavy snow") then
if (CurrentTime >= libTim_udg_SunriseTime and CurrentTime < libTim_udg_SunsetTime) then
return "Environment\\Sky\\BlizzardSky\\BlizzardSky.mdl"
else
return "Environment\\Sky\\FoggedSky\\FoggedSky.mdl"
endif
elseif (WeatherType == "Light rain") then
if (CurrentTime >= libTim_udg_SunriseTime and CurrentTime < libTim_udg_SunsetTime) then
return "Environment\\Sky\\LordaeronWinterSky\\LordaeronWinterSky.mdl"
else
return "Environment\\Sky\\FelwoodSky\\FelwoodSky.mdl"
endif
elseif (WeatherType == "Heavy rain") then
if (CurrentTime >= libTim_udg_SunriseTime and CurrentTime < libTim_udg_SunsetTime) then
return "Environment\\Sky\\LordaeronWinterSky\\LordaeronWinterSky.mdl"
else
return "Environment\\Sky\\FelwoodSky\\FelwoodSky.mdl"
endif
endif
return null
endfunction
private function GetFogValue takes string WeatherType, real TimeOfDay, real IntensityValue, integer ValueNumber returns real
local boolean IsDayTime = (TimeOfDay >= libTim_udg_SunriseTime and TimeOfDay < libTim_udg_SunsetTime)
//ValueNumber:
//1=Z-Start
//2=Z-End
//3=Density
//4=Red
//5=Green
//6=Blue
if (udg_FogSetting == 1) then
if (WeatherType == "Light sun") then
if (IsDayTime) then
if (ValueNumber == 1) then
return 0.80 * IntensityValue
elseif (ValueNumber == 2) then
return 1.00
elseif (ValueNumber == 3) then
return 0.80 * IntensityValue
elseif (ValueNumber == 4) then
return 0.80 * IntensityValue
elseif (ValueNumber == 5) then
return 0.40 * IntensityValue
endif
else
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.40 + 0.60 * IntensityValue
elseif (ValueNumber == 3) then
return 0.00
elseif (ValueNumber == 4) then
return 0.00
elseif (ValueNumber == 5) then
return 0.00
endif
endif
elseif (WeatherType == "Heavy sun") then
if (IsDayTime) then
if (ValueNumber == 1) then
return 0.80 * IntensityValue
elseif (ValueNumber == 2) then
return 1.00
elseif (ValueNumber == 3) then
return 1.00 * IntensityValue
elseif (ValueNumber == 4) then
return 1.00 * IntensityValue
elseif (ValueNumber == 5) then
return 0.50 * IntensityValue
endif
else
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.45 + 0.55 * IntensityValue
elseif (ValueNumber == 3) then
return 0.00
elseif (ValueNumber == 4) then
return 0.00
elseif (ValueNumber == 5) then
return 0.00
endif
endif
elseif (WeatherType == "Light mist") then
if (IsDayTime) then
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.50
elseif (ValueNumber == 3) then
return 0.40 + 0.40 * IntensityValue
elseif (ValueNumber == 4) then
return 0.40 + 0.40 * IntensityValue
elseif (ValueNumber == 5) then
return 0.50 + 0.50 * IntensityValue
endif
else
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.35 + 0.15 * IntensityValue
elseif (ValueNumber == 3) then
return 0.40 * IntensityValue
elseif (ValueNumber == 4) then
return 0.40 * IntensityValue
elseif (ValueNumber == 5) then
return 0.50 * IntensityValue
endif
endif
elseif (WeatherType == "Heavy mist") then
if (IsDayTime) then
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.25
elseif (ValueNumber == 3) then
return 0.40 + 0.40 * IntensityValue
elseif (ValueNumber == 4) then
return 0.40 + 0.40 * IntensityValue
elseif (ValueNumber == 5) then
return 0.50 + 0.50 * IntensityValue
endif
else
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.25
elseif (ValueNumber == 3) then
return 0.40 * IntensityValue
elseif (ValueNumber == 4) then
return 0.40 * IntensityValue
elseif (ValueNumber == 5) then
return 0.50 * IntensityValue
endif
endif
elseif (WeatherType == "Light wind") then
if (IsDayTime) then
if (ValueNumber == 1) then
return IntensityValue
elseif (ValueNumber == 2) then
return 1.00
elseif (ValueNumber == 3) then
return 1.00 * IntensityValue
elseif (ValueNumber == 4) then
return 1.00 * IntensityValue
elseif (ValueNumber == 5) then
return 1.00 * IntensityValue
endif
else
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.40 + 0.60 * IntensityValue
elseif (ValueNumber == 3) then
return 0.00
elseif (ValueNumber == 4) then
return 0.00
elseif (ValueNumber == 5) then
return 0.00
endif
endif
elseif (WeatherType == "Heavy wind") then
if (IsDayTime) then
if (ValueNumber == 1) then
return IntensityValue
elseif (ValueNumber == 2) then
return 1.00
elseif (ValueNumber == 3) then
return 1.00 * IntensityValue
elseif (ValueNumber == 4) then
return 1.00 * IntensityValue
elseif (ValueNumber == 5) then
return 1.00 * IntensityValue
endif
else
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.40 + 0.60 * IntensityValue
elseif (ValueNumber == 3) then
return 0.00
elseif (ValueNumber == 4) then
return 0.00
elseif (ValueNumber == 5) then
return 0.00
endif
endif
elseif (WeatherType == "Light snow") then
if (IsDayTime) then
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 1.00 + IntensityValue
elseif (ValueNumber == 3) then
return 1.00 * IntensityValue
elseif (ValueNumber == 4) then
return 1.00 * IntensityValue
elseif (ValueNumber == 5) then
return 1.00 * IntensityValue
endif
else
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.40 + 0.60 * IntensityValue
elseif (ValueNumber == 3) then
return 0.00
elseif (ValueNumber == 4) then
return 0.00
elseif (ValueNumber == 5) then
return 0.00
endif
endif
elseif (WeatherType == "Heavy snow") then
if (IsDayTime) then
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 1.00
elseif (ValueNumber == 3) then
return 1.00 * IntensityValue
elseif (ValueNumber == 4) then
return 1.00 * IntensityValue
elseif (ValueNumber == 5) then
return 1.00 * IntensityValue
endif
else
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.40 + 0.60 * IntensityValue
elseif (ValueNumber == 3) then
return 0.00
elseif (ValueNumber == 4) then
return 0.00
elseif (ValueNumber == 5) then
return 0.00
endif
endif
elseif (WeatherType == "Light rain") then
if (IsDayTime) then
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.75
elseif (ValueNumber == 3) then
return 0.00
elseif (ValueNumber == 4) then
return 0.1875 + 0.1875 * IntensityValue
elseif (ValueNumber == 5) then
return 0.25 + 0.25 * IntensityValue
endif
else
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.40 + 0.35 * IntensityValue
elseif (ValueNumber == 3) then
return 0.00
elseif (ValueNumber == 4) then
return 0.1875 * IntensityValue
elseif (ValueNumber == 5) then
return 0.25 * IntensityValue
endif
endif
elseif (WeatherType == "Heavy rain") then
if (IsDayTime) then
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.50
elseif (ValueNumber == 3) then
return 0.00
elseif (ValueNumber == 4) then
return 0.1875 + 0.1875 * IntensityValue
elseif (ValueNumber == 5) then
return 0.25 + 0.25 * IntensityValue
endif
else
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
return 0.35 + 0.15 * IntensityValue
elseif (ValueNumber == 3) then
return 0.00
elseif (ValueNumber == 4) then
return 0.1875 * IntensityValue
elseif (ValueNumber == 5) then
return 0.25 * IntensityValue
endif
endif
endif
elseif (udg_FogSetting == 2) then
if (WeatherType == "Light sun") then
if (ValueNumber == 1) then
return 0.80 * IntensityValue
elseif (ValueNumber == 2) then
if (IsDayTime) then
return 1.00
else
return 1.00 + 0.60 * IntensityValue
endif
elseif (ValueNumber == 3) then
return 0.80 * IntensityValue
elseif (ValueNumber == 4) then
return 0.80 * IntensityValue
elseif (ValueNumber == 5) then
return 0.40 * IntensityValue
endif
elseif (WeatherType == "Heavy sun") then
if (ValueNumber == 1) then
return 0.80 * IntensityValue
elseif (ValueNumber == 2) then
if (IsDayTime) then
return 1.00
else
return 1.00 + 0.50 * IntensityValue
endif
elseif (ValueNumber == 3) then
return 1.00 * IntensityValue
elseif (ValueNumber == 4) then
return 1.00 * IntensityValue
elseif (ValueNumber == 5) then
return 0.50 * IntensityValue
endif
elseif (WeatherType == "Light mist") then
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
if (IsDayTime) then
return 0.50
else
return 0.50 + 0.10 * IntensityValue
endif
elseif (ValueNumber == 3) then
return 0.20 + 0.60 * IntensityValue
elseif (ValueNumber == 4) then
return 0.20 + 0.60 * IntensityValue
elseif (ValueNumber == 5) then
return 0.25 + 0.75 * IntensityValue
endif
elseif (WeatherType == "Heavy mist") then
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
if (IsDayTime) then
return 0.25
else
return 0.25 + 0.05 * IntensityValue
endif
elseif (ValueNumber == 3) then
return 0.20 + 0.60 * IntensityValue
elseif (ValueNumber == 4) then
return 0.20 + 0.60 * IntensityValue
elseif (ValueNumber == 5) then
return 0.25 + 0.75 * IntensityValue
endif
elseif (WeatherType == "Light wind") then
if (ValueNumber == 1) then
return IntensityValue
elseif (ValueNumber == 2) then
if (IsDayTime) then
return 1.00
else
return 1.00 + 0.60 * IntensityValue
endif
elseif (ValueNumber == 3) then
return 1.00 * IntensityValue
elseif (ValueNumber == 4) then
return 1.00 * IntensityValue
elseif (ValueNumber == 5) then
return 1.00 * IntensityValue
endif
elseif (WeatherType == "Heavy wind") then
if (ValueNumber == 1) then
return IntensityValue
elseif (ValueNumber == 2) then
if (IsDayTime) then
return 1.00
else
return 1.00 + 0.60 * IntensityValue
endif
elseif (ValueNumber == 3) then
return 1.00 * IntensityValue
elseif (ValueNumber == 4) then
return 1.00 * IntensityValue
elseif (ValueNumber == 5) then
return 1.00 * IntensityValue
endif
elseif (WeatherType == "Light snow") then
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
if (IsDayTime) then
return 1.00 + IntensityValue
else
return 1.00 + 0.60 * IntensityValue
endif
elseif (ValueNumber == 3) then
return 1.00 * IntensityValue
elseif (ValueNumber == 4) then
return 1.00 * IntensityValue
elseif (ValueNumber == 5) then
return 1.00 * IntensityValue
endif
elseif (WeatherType == "Heavy snow") then
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
if (IsDayTime) then
return 1.00
else
return 1.00 + 0.60 * IntensityValue
endif
elseif (ValueNumber == 3) then
return 1.00 * IntensityValue
elseif (ValueNumber == 4) then
return 1.00 * IntensityValue
elseif (ValueNumber == 5) then
return 1.00 * IntensityValue
endif
elseif (WeatherType == "Light rain") then
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
if (IsDayTime) then
return 0.75
else
return 0.75 + 0.35 * IntensityValue
endif
elseif (ValueNumber == 3) then
return 0.00
elseif (ValueNumber == 4) then
return 0.1875 + 0.1875 * IntensityValue
elseif (ValueNumber == 5) then
return 0.25 + 0.25 * IntensityValue
endif
elseif (WeatherType == "Heavy rain") then
if (ValueNumber == 1) then
return 0.00
elseif (ValueNumber == 2) then
if (IsDayTime) then
return 0.50
else
return 0.50 + 0.15 * IntensityValue
endif
elseif (ValueNumber == 3) then
return 0.00
elseif (ValueNumber == 4) then
return 0.1875 + 0.1875 * IntensityValue
elseif (ValueNumber == 5) then
return 0.25 + 0.25 * IntensityValue
endif
endif
endif
return 0.00
endfunction
private function GetRandomWeather takes integer Season returns string
local integer IntRandom = GetRandomInt(1, 10)
if (IntRandom == 1) then
return "Light sun"
elseif (IntRandom == 2) then
return "Heavy sun"
elseif (IntRandom == 3) then
return "Light wind"
elseif (IntRandom == 4) then
return "Heavy wind"
elseif (IntRandom == 5) then
if (Season == 4) then
return "Light snow"
else
return "Light rain"
endif
elseif (IntRandom == 6) then
if (Season == 4) then
return "Heavy snow"
else
return "Heavy rain"
endif
elseif (IntRandom == 7) then
return "Light mist"
elseif (IntRandom == 8) then
return "Heavy mist"
elseif (IntRandom == 9) then
if (Season == 1) then
return "Light mist"
elseif (Season == 2) then
return "Light sun"
elseif (Season == 3) then
return "Light wind"
elseif (Season == 4) then
return "Light snow"
endif
elseif (IntRandom == 10) then
if (Season == 1) then
return "Heavy mist"
elseif (Season == 2) then
return "Heavy sun"
elseif (Season == 3) then
return "Heavy wind"
elseif (Season == 4) then
return "Heavy snow"
endif
endif
return null
endfunction
//-------------------------
//PUBLIC/CUSTOMIZABLE PART:
//-------------------------
globals
public string udg_CurrentWeather = "Light sun"
public string udg_NextWeather = null
public real udg_DistantVision = 10000.00
endglobals
//-----------------
//DECLARATION PART:
//-----------------
globals
private constant real udg_AntiSingularityAddition = 0.000001
private weathereffect udg_Weathereffect = null
private timer udg_WeatherTimer = CreateTimer()
private trigger gg_trg_FogAdjustment = CreateTrigger()
endglobals
//-------------
//PRIVATE PART:
//-------------
private function GetIntensityValue takes real AtTime returns real
local real MinIntensity
local real MaxIntensity
local real RealTemp1
local real HalfTime
if (udg_FogSetting == 1) then
set MinIntensity = 0.00
set MaxIntensity = 1.00
if (AtTime >= libTim_udg_SunriseTime and AtTime < libTim_udg_SunsetTime) then
set HalfTime = (libTim_udg_SunsetTime - libTim_udg_SunriseTime) / 2
//Get the hours the current time is away from dusk or dawn:
set RealTemp1 = AtTime - libTim_udg_SunriseTime
else
set HalfTime = (24.00 - libTim_udg_SunsetTime + libTim_udg_SunriseTime) / 2
//Get the hours the current time is away from dusk or dawn:
if (AtTime >= libTim_udg_SunsetTime) then
set RealTemp1 = AtTime - libTim_udg_SunsetTime
else
set RealTemp1 = libTim_udg_SunriseTime - AtTime
endif
endif
if (RealTemp1 > HalfTime) then
set RealTemp1 = HalfTime * 2 - RealTemp1
endif
//Get the percentage value of the intensity:
set RealTemp1 = RealTemp1 / (HalfTime + udg_AntiSingularityAddition)
//Fit to min and max intensity:
set RealTemp1 = MinIntensity + RealTemp1 * (MaxIntensity - MinIntensity)
elseif (udg_FogSetting == 2) then
set MinIntensity = -1.00
set MaxIntensity = 1.00
//Fitted sinus-behaviour:
set RealTemp1 = 0.5 * (MaxIntensity + MinIntensity) + 0.5 * (MaxIntensity - MinIntensity) * Sin(2 * bj_PI * (AtTime - libTim_udg_SunriseTime) / 24)
endif
return RealTemp1
endfunction
//------------
//PUBLIC PART:
//------------
public function SetCurrentWeather takes string WeatherType returns nothing
local real CurrentTime = GetFloatGameState(GAME_STATE_TIME_OF_DAY)
local string StringTemp1 = GetSkyModelPath(WeatherType, CurrentTime)
local integer IntTemp1 = GetWeathereffectID(WeatherType)
if (StringTemp1 != null) then
call RemoveWeatherEffect(udg_Weathereffect)
set udg_CurrentWeather = WeatherType
if (IntTemp1 != 0) then
set udg_Weathereffect = AddWeatherEffect(bj_mapInitialPlayableArea, IntTemp1)
call EnableWeatherEffect(udg_Weathereffect, true)
else
set udg_Weathereffect = null
endif
call SetSkyModel(StringTemp1)
endif
endfunction
public function SetNextWeather takes string WeatherType returns nothing
if (GetSkyModelPath(WeatherType, 0.00) != null) then
set udg_NextWeather = WeatherType
endif
endfunction
//---------------------
//EVENT TRIGGERED PART:
//---------------------
private function FogAdjustment takes nothing returns nothing
local real CurrentTime = GetFloatGameState(GAME_STATE_TIME_OF_DAY)
local real IntensityValue = GetIntensityValue(CurrentTime)
local real array RealArrayTemp1
local real RealTemp1 = TimerGetElapsed(udg_WeatherTimer) / (TimerGetTimeout(udg_WeatherTimer) + udg_AntiSingularityAddition)
local real RealTemp2
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > 5
set RealArrayTemp1[IntLoop1] = GetFogValue(udg_CurrentWeather, CurrentTime, IntensityValue, IntLoop1)
if (RealArrayTemp1[IntLoop1] < 0.00) then
set RealArrayTemp1[IntLoop1] = 0.00
endif
if (udg_NextWeather != null) then
set RealTemp2 = GetFogValue(udg_NextWeather, CurrentTime, IntensityValue, IntLoop1)
if (RealTemp2 < 0.00) then
set RealTemp2 = 0.00
endif
set RealArrayTemp1[IntLoop1] = RealArrayTemp1[IntLoop1] * (1.00 - RealTemp1) + RealTemp1 * RealTemp2
endif
set IntLoop1 = IntLoop1 + 1
endloop
call SetTerrainFogEx(0, udg_DistantVision * (RealArrayTemp1[1] * udg_FogIntensity + 1 - udg_FogIntensity), udg_DistantVision * (RealArrayTemp1[2] * udg_FogIntensity + 1 - udg_FogIntensity), 0.50, RealArrayTemp1[3], RealArrayTemp1[4], RealArrayTemp1[5])
endfunction
private function ChangeWeather takes nothing returns nothing
if (udg_NextWeather != null) then
call SetCurrentWeather(udg_NextWeather)
set udg_NextWeather = null
call TimerStart(udg_WeatherTimer, GetRandomReal(udg_MinWeatherDuration, udg_MaxWeatherDuration), false, function ChangeWeather)
else
set udg_NextWeather = GetRandomWeather(libTim_GetCurrentSeason())
call TimerStart(udg_WeatherTimer, udg_WeatherTransitionDuration, false, function ChangeWeather)
endif
endfunction
//---------------
//INITIALISATION:
//---------------
private function Init_AdvancedWeatherSystem takes nothing returns nothing
//Triggers:
call TriggerRegisterTimerEvent(gg_trg_FogAdjustment, udg_FogAdjustmentRate, true)
//Actions:
call TriggerAddAction(gg_trg_FogAdjustment, function FogAdjustment)
//Timers:
call TimerStart(udg_WeatherTimer, 0.01, false, function ChangeWeather)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_InvisibleUnitIsOrdered_Conditions takes nothing returns boolean
return (GetUnitAbilityLevel(GetOrderedUnit(), libId_udg_InvisibilityBuff) > 0) //Invisibility
endfunction
function Trig_InvisibleUnitIsOrdered_Actions takes nothing returns nothing
call UnitRemoveAbility(GetOrderedUnit(), libId_udg_InvisibilityBuff) //Invisibility
endfunction
//===========================================================================
function InitTrig_InvisibleUnitIsOrdered takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers:
set gg_trg_InvisibleUnitIsOrdered = CreateTrigger()
loop
exitwhen IntLoop1 > 16
call TriggerRegisterPlayerUnitEvent(gg_trg_InvisibleUnitIsOrdered, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_InvisibleUnitIsOrdered, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_InvisibleUnitIsOrdered, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Conditions:
call TriggerAddCondition(gg_trg_InvisibleUnitIsOrdered, Condition( function Trig_InvisibleUnitIsOrdered_Conditions))
//Actions:
call TriggerAddAction(gg_trg_InvisibleUnitIsOrdered, function Trig_InvisibleUnitIsOrdered_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Infect_Conditions takes nothing returns boolean
return (GetUnitAbilityLevel(GetAttacker(), libId_udg_InfectionAttack) >= 1 and GetUnitAbilityLevel(GetTriggerUnit(), libId_udg_InfectedBuff) == 0 and IsUnitType(GetTriggerUnit(), UNIT_TYPE_MECHANICAL) == false) //Infection attack, Infected
endfunction
function Trig_Infect_Actions takes nothing returns nothing
call libDum_CastOnTarget(libId_udg_AddInfection, 1, "parasite", GetTriggerUnit(), GetOwningPlayer(GetAttacker())) //Add infection
endfunction
//===========================================================================
function InitTrig_Infect takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers:
set gg_trg_Infect = CreateTrigger()
loop
exitwhen IntLoop1 > 16
call TriggerRegisterPlayerUnitEvent(gg_trg_Infect, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ATTACKED, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Conditions:
call TriggerAddCondition(gg_trg_Infect, Condition( function Trig_Infect_Conditions))
//Actions:
call TriggerAddAction(gg_trg_Infect, function Trig_Infect_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Ensnare_Conditions takes nothing returns boolean
return (GetUnitAbilityLevel(GetAttacker(), libId_udg_EnsnareRaider) >= 1 and IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) == false) //Ensnare (Raider)
endfunction
function Trig_Ensnare_Actions takes nothing returns nothing
local unit UnitTemp1 = GetAttacker()
local unit UnitTemp2 = GetTriggerUnit()
call IssueTargetOrder(UnitTemp1, "ensnare", UnitTemp2)
//Anti-Memory-Leak:
set UnitTemp1 = null
set UnitTemp2 = null
endfunction
//===========================================================================
function InitTrig_Ensnare takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers:
set gg_trg_Ensnare = CreateTrigger()
loop
exitwhen IntLoop1 > 16
call TriggerRegisterPlayerUnitEvent(gg_trg_Ensnare, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ATTACKED, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Conditions:
call TriggerAddCondition(gg_trg_Ensnare, Condition( function Trig_Ensnare_Conditions))
//Actions:
call TriggerAddAction(gg_trg_Ensnare, function Trig_Ensnare_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_AngleOfLight_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_AngleOfLight) //Angle of Light
endfunction
function Trig_AngleOfLight_Actions_Filter1 takes nothing returns boolean
return (IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false)
endfunction
function Trig_AngleOfLight_Actions takes nothing returns nothing
local location LocationTemp1 = GetSpellTargetLoc()
local boolexpr Filter1 = Condition(function Trig_AngleOfLight_Actions_Filter1)
local group GroupTemp1 = CreateGroup()
local unit UnitTemp1 = GetSpellAbilityUnit()
local integer IntTemp1 = GetUnitAbilityLevel(UnitTemp1, libId_udg_AngleOfLight) //Angle of Light
call TriggerSleepAction(1.50)
call GroupEnumUnitsInRange(GroupTemp1, GetLocationX(LocationTemp1), GetLocationY(LocationTemp1), 200.00, Filter1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call libDum_CastOnTarget(libId_udg_HolyLightAn, IntTemp1, "holybolt", UnitTemp1, Player(PLAYER_NEUTRAL_PASSIVE)) //Holy light (Angle of Light)
endloop
//Anti-Memory-Leak:
call RemoveLocation(LocationTemp1)
set LocationTemp1 = null
call DestroyBoolExpr(Filter1)
set Filter1 = null
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
endfunction
//===========================================================================
function InitTrig_AngleOfLight takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers:
set gg_trg_AngleOfLight = CreateTrigger()
loop
exitwhen IntLoop1 > 16
call TriggerRegisterPlayerUnitEvent(gg_trg_AngleOfLight, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Conditions:
call TriggerAddCondition(gg_trg_AngleOfLight, Condition( function Trig_AngleOfLight_Conditions))
//Actions:
call TriggerAddAction(gg_trg_AngleOfLight, function Trig_AngleOfLight_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_AvatarOfLight_Conditions takes nothing returns boolean
return (GetUnitTypeId(GetSummonedUnit()) == libId_udg_AvatarOfLight)
endfunction
function Trig_AvatarOfLight_Actions takes nothing returns nothing
local unit UnitTemp1 = GetSummonedUnit()
local unit UnitTemp2 = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), libId_udg_Dummy, 0.00, 0.00, 0.00)
call UnitAddAbility(UnitTemp2, libId_udg_HolyLightAv) //Holy light (Avatar of Light)
loop
call TriggerSleepAction(1.50)
exitwhen GetUnitState(UnitTemp1, UNIT_STATE_LIFE) < 1.00
call IssueTargetOrder(UnitTemp2, "bloodlust", UnitTemp1)
endloop
call RemoveUnit(UnitTemp2)
//Anti-Memory-Leak:
set UnitTemp1 = null
set UnitTemp2 = null
endfunction
//===========================================================================
function InitTrig_AvatarOfLight takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers:
set gg_trg_AvatarOfLight = CreateTrigger()
loop
exitwhen IntLoop1 > 16
call TriggerRegisterPlayerUnitEvent(gg_trg_AvatarOfLight, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SUMMON, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Conditions:
call TriggerAddCondition(gg_trg_AvatarOfLight, Condition( function Trig_AvatarOfLight_Conditions))
//Actions:
call TriggerAddAction(gg_trg_AvatarOfLight, function Trig_AvatarOfLight_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_PassiveInvisibleAbilities_Actions takes nothing returns nothing
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > 16
call SetPlayerAbilityAvailable(Player(IntLoop1 - 1), libId_udg_PassiveInvisibleAbilities, false) //Passive invisible abilities
set IntLoop1 = IntLoop1 + 1
endloop
endfunction
//===========================================================================
function InitTrig_PassiveInvisibleAbilities takes nothing returns nothing
set gg_trg_PassiveInvisibleAbilities = CreateTrigger()
call TriggerAddAction(gg_trg_PassiveInvisibleAbilities, function Trig_PassiveInvisibleAbilities_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Dispel_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_Dispel) //Dispel
endfunction
function Trig_Dispel_Actions takes nothing returns nothing
local location LocationTemp1 = GetSpellTargetLoc()
local group GroupTemp1 = CreateGroup()
local unit UnitTemp1
call GroupEnumUnitsInRange(GroupTemp1, GetLocationX(LocationTemp1), GetLocationY(LocationTemp1), 100.00, null)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call UnitRemoveBuffs(UnitTemp1, true, true)
endloop
//Anti-Memory-Leak:
call RemoveLocation(LocationTemp1)
set LocationTemp1 = null
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
endfunction
//===========================================================================
function InitTrig_Dispel takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers:
set gg_trg_Dispel = CreateTrigger()
loop
exitwhen IntLoop1 > 16
call TriggerRegisterPlayerUnitEvent(gg_trg_Dispel, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Conditions:
call TriggerAddCondition(gg_trg_Dispel, Condition( function Trig_Dispel_Conditions))
//Actions:
call TriggerAddAction(gg_trg_Dispel, function Trig_Dispel_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_ZombieMissile_Conditions takes nothing returns boolean
return (GetUnitTypeId(GetAttacker()) == libId_udg_MeatWagon and IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) == false)
endfunction
function Trig_ZombieMissile_Actions takes nothing returns nothing
local unit UnitTemp1 = GetTriggerUnit()
local real PosX = GetUnitX(UnitTemp1)
local real PosY = GetUnitY(UnitTemp1)
local player Owner = Player(PLAYER_NEUTRAL_PASSIVE)
call TriggerSleepAction(6.50)
set UnitTemp1 = CreateCorpse(Owner, libId_udg_Zombie, PosX, PosY, GetRandomReal(0.00, 360.00))
call libDum_CastOnTarget(libId_udg_RaiseZombie, 1, "raisedead", UnitTemp1, Owner) //Raise zombie
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
//===========================================================================
function InitTrig_ZombieMissile takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers:
set gg_trg_ZombieMissile = CreateTrigger()
loop
exitwhen IntLoop1 > 16
call TriggerRegisterPlayerUnitEvent(gg_trg_ZombieMissile, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ATTACKED, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Conditions:
call TriggerAddCondition(gg_trg_ZombieMissile, Condition( function Trig_ZombieMissile_Conditions))
//Actions:
call TriggerAddAction(gg_trg_ZombieMissile, function Trig_ZombieMissile_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_ZombieSummoned_Conditions takes nothing returns boolean
return (GetUnitTypeId(GetSummonedUnit()) == libId_udg_Zombie and GetOwningPlayer(GetSummonedUnit()) == Player(PLAYER_NEUTRAL_PASSIVE))
endfunction
function Trig_ZombieSummoned_Actions takes nothing returns nothing
call SetUnitOwner(GetSummonedUnit(), Player(4 - 1), true)
endfunction
//===========================================================================
function InitTrig_ZombieSummoned takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers:
set gg_trg_ZombieSummoned = CreateTrigger()
loop
exitwhen IntLoop1 > 16
call TriggerRegisterPlayerUnitEvent(gg_trg_ZombieSummoned, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SUMMON, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Conditions:
call TriggerAddCondition(gg_trg_ZombieSummoned, Condition( function Trig_ZombieSummoned_Conditions))
//Actions:
call TriggerAddAction(gg_trg_ZombieSummoned, function Trig_ZombieSummoned_Actions)
endfunction
//TESH.scrollpos=61
//TESH.alwaysfold=0
function Trig_Initialisation_Function1 takes nothing returns nothing
local integer PlayerID = 1
local real MaxSkipTime = 0.50
local real RealTemp1
//Play intro:
call libCin_SwitchCinematicMode(PlayerID, true)
call libCin_ApplyCameraTimed(PlayerID, gg_cam_INTRO_Camera01, 0.00)
call libCin_ApplyCameraTimed(PlayerID, gg_cam_INTRO_Camera02, 3.20)
call TriggerSleepAction(0.01)
call EndThematicMusic()
call PlayThematicMusic("Sound\\Music\\mp3Music\\SadMystery.mp3")
set RealTemp1 = 0.01
loop
if (libCin_IsCinematicSkipped(PlayerID)) then
return
endif
set RealTemp1 = RealTemp1 + MaxSkipTime
call TriggerSleepAction(MaxSkipTime)
exitwhen RealTemp1 >= 3.00
endloop
call libCin_ShowSpeakScene(PlayerID, "Once upon a time, there was a commander of a small ruined castle at the borders of the kingdom.|nHe had been ordered to rebuild the fort and defend it against any threats.|nAnd this is how the story begins...", "Narrator", 'nmed', 1)
call libCin_ApplyCameraTimed(PlayerID, gg_cam_INTRO_Camera03, 6.00)
set RealTemp1 = 0.01
loop
if (libCin_IsCinematicSkipped(PlayerID)) then
return
endif
set RealTemp1 = RealTemp1 + MaxSkipTime
call TriggerSleepAction(MaxSkipTime)
exitwhen RealTemp1 >= 8.00
endloop
call libCin_ApplyCameraTimed(PlayerID, gg_cam_INTRO_Camera04, 4.20)
set RealTemp1 = 0.01
loop
if (libCin_IsCinematicSkipped(PlayerID)) then
return
endif
set RealTemp1 = RealTemp1 + MaxSkipTime
call TriggerSleepAction(MaxSkipTime)
exitwhen RealTemp1 >= 4.00
endloop
call libCin_ApplyCameraTimed(PlayerID, gg_cam_INTRO_Camera05, 2.20)
set RealTemp1 = 0.01
loop
if (libCin_IsCinematicSkipped(PlayerID)) then
return
endif
set RealTemp1 = RealTemp1 + MaxSkipTime
call TriggerSleepAction(MaxSkipTime)
exitwhen RealTemp1 >= 2.00
endloop
call libCin_ShowSpeakScene(PlayerID, "My Lord, our scouts discovered a larger band of Orc raiders living in this area.|nThey will soon discover that this fort is no longer abandoned.|nAlso there are reports that the enemy kingdom is sending troops to claim this fort for themself.|nWe should quickly repair the walls and train some troops for defence.|nFurthermore there are rumors about the dead walking in the night...", "Watchman", 'nhea', 1)
call libCin_ApplyCameraTimed(PlayerID, gg_cam_INTRO_Camera06, 5.00)
set RealTemp1 = 0.01
loop
if (libCin_IsCinematicSkipped(PlayerID)) then
return
endif
set RealTemp1 = RealTemp1 + MaxSkipTime
call TriggerSleepAction(MaxSkipTime)
exitwhen RealTemp1 >= 10.00
endloop
call libCin_SwitchCinematicMode(PlayerID, false)
endfunction
function Trig_Initialisation_Actions takes nothing returns nothing
local integer PlayerID = 1
//General settings:
call SetSkyModel("Environment\\Sky\\LordaeronSummerSky\\LordaeronSummerSky.mdl")
call SetPlayerState(Player(PlayerID - 1), PLAYER_STATE_RESOURCE_GOLD, 50)
call SetPlayerState(Player(PlayerID - 1), PLAYER_STATE_RESOURCE_LUMBER, 100)
call FogModifierStart(CreateFogModifierRect(Player(PLAYER_NEUTRAL_PASSIVE), FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea, true, false))
//Play intro:
call SetTimeOfDayScale(0.00)
call Trig_Initialisation_Function1()
call SetTimeOfDayScale(1.00)
//Change to normal settings:
if (GetLocalPlayer() == Player(PlayerID - 1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 1650.00, 2.00)
call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 304.00, 2.00)
call SetCameraField(CAMERA_FIELD_FARZ, 10000.00, 2.00)
call SetCameraField(CAMERA_FIELD_ROTATION, 90.00, 2.00)
call PanCameraToTimed(-2944.00, 5120.00, 2.00)
endif
call libWav_InitSpawnTeams()
//Create credits quest:
set bj_lastCreatedQuest = CreateQuest()
call QuestSetTitle(bj_lastCreatedQuest, "Credits")
call QuestSetDescription(bj_lastCreatedQuest, "Models:|nNasrudin (Willow trees)|nBorn²Modificate (Other trees)|Mr. Bob (Barracks)|Tranquil (Pikeman and Paladin)")
call QuestSetIconPath(bj_lastCreatedQuest, "ReplaceableTextures\\WorldEditUI\\Editor-MultipleUnits.blp")
call QuestSetRequired(bj_lastCreatedQuest, false)
call QuestSetDiscovered(bj_lastCreatedQuest, true)
call QuestSetCompleted(bj_lastCreatedQuest, false)
//Create main quest:
set bj_lastCreatedQuest = CreateQuest()
call QuestSetTitle(bj_lastCreatedQuest, "Defend the castle")
call QuestSetDescription(bj_lastCreatedQuest, "Rebuild the fort and defend it against any threats for 10 days.|nThe castle must not fall!")
call QuestSetIconPath(bj_lastCreatedQuest, "ReplaceableTextures\\CommandButtons\\BTNHumanBarracks.blp")
call QuestSetRequired(bj_lastCreatedQuest, true)
call QuestSetDiscovered(bj_lastCreatedQuest, true)
call QuestSetCompleted(bj_lastCreatedQuest, false)
call FlashQuestDialogButton()
endfunction
//===========================================================================
function InitTrig_Initialisation takes nothing returns nothing
set gg_trg_Initialisation = CreateTrigger()
call TriggerAddAction(gg_trg_Initialisation, function Trig_Initialisation_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_TurnStartBuildings_Filter1 takes nothing returns boolean
local integer StructureID = GetUnitTypeId(GetFilterUnit())
if (StructureID == libId_udg_ThatchedCottages1) then //Thatched cottages (Level1)
return true
elseif (StructureID == libId_udg_ThatchedCottages2) then //Thatched cottages (Level2)
return true
elseif (StructureID == libId_udg_ThatchedCottages3) then //Thatched cottages (Level3)
return true
elseif (StructureID == libId_udg_ThatchedCottages4) then //Thatched cottages (Level4)
return true
elseif (StructureID == libId_udg_VillageHouse1) then //Village house (Level1)
return true
elseif (StructureID == libId_udg_VillageHouse2) then //Village house (Level2)
return true
elseif (StructureID == libId_udg_VillageHouse3) then //Village house (Level3)
return true
elseif (StructureID == libId_udg_VillageHouse4) then //Village house (Level4)
return true
elseif (StructureID == libId_udg_VillageHouse5) then //Village house (Level5)
return true
endif
return false
endfunction
function Trig_TurnStartBuildings_Actions takes nothing returns nothing
local real RealTemp1
local real RealTemp2
local player Owner
local integer IntTemp1
local unit UnitTemp1
local group GroupTemp1 = CreateGroup()
local boolexpr Filter1 = Condition(function Trig_TurnStartBuildings_Filter1)
call GroupEnumUnitsInRect(GroupTemp1, bj_mapInitialPlayableArea, Filter1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
set RealTemp1 = GetUnitX(UnitTemp1)
set RealTemp2 = GetUnitY(UnitTemp1)
set Owner = GetOwningPlayer(UnitTemp1)
set IntTemp1 = GetUnitTypeId(UnitTemp1)
call RemoveUnit(UnitTemp1)
call CreateUnit(Owner, IntTemp1, RealTemp1, RealTemp2, GetRandomInt(1, 4) * 90.00)
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
endloop
//Anti-Memory-Leak:
set UnitTemp1 = null
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
call DestroyBoolExpr(Filter1)
set Filter1 = null
endfunction
//===========================================================================
function InitTrig_TurnStartBuildings takes nothing returns nothing
set gg_trg_TurnStartBuildings = CreateTrigger()
call TriggerAddAction(gg_trg_TurnStartBuildings, function Trig_TurnStartBuildings_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Victory_Conditions_Filter1 takes nothing returns boolean
return (IsUnitType(GetFilterUnit(), UNIT_TYPE_TAUREN) == false and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) >= 1.00)
endfunction
function Trig_Victory_Conditions takes nothing returns boolean
local boolexpr Filter1 = null
local group GroupTemp1 = null
local unit UnitTemp1 = null
local boolean ReturnValue = true
if (libTim_GetElapsedTime() <= (10 * 24 + 4) * libTim_udg_HourLength) then
return false
endif
set Filter1 = Condition(function Trig_Victory_Conditions_Filter1)
set GroupTemp1 = CreateGroup()
call GroupEnumUnitsOfPlayer(GroupTemp1, Player(3 - 1), Filter1)
set UnitTemp1 = FirstOfGroup(GroupTemp1)
if (UnitTemp1 != null) then
set ReturnValue = false
endif
call GroupClear(GroupTemp1)
call GroupEnumUnitsOfPlayer(GroupTemp1, Player(4 - 1), Filter1)
set UnitTemp1 = FirstOfGroup(GroupTemp1)
if (UnitTemp1 != null) then
set ReturnValue = false
endif
call GroupClear(GroupTemp1)
call GroupEnumUnitsOfPlayer(GroupTemp1, Player(6 - 1), Filter1)
set UnitTemp1 = FirstOfGroup(GroupTemp1)
if (UnitTemp1 != null) then
set ReturnValue = false
endif
//Anti-Memory-Leak:
call DestroyBoolExpr(Filter1)
set Filter1 = null
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
//-----------------
return ReturnValue
endfunction
function Trig_Victory_Actions takes nothing returns nothing
local integer PlayerID = 1
local real MaxSkipTime = 0.50
local real RealTemp1
call DisableTrigger(gg_trg_Victory)
call QuestSetCompleted(bj_lastCreatedQuest, true)
call FlashQuestDialogButton()
call TriggerSleepAction(3.00)
//Play outro:
call EndThematicMusic()
call PlayThematicMusic("Sound\\Music\\mp3Music\\HeroicVictory.mp3")
call libCin_SwitchCinematicMode(PlayerID, true)
call libCin_ApplyCameraTimed(PlayerID, gg_cam_OUTRO_Camera01, 2.00)
call TriggerSleepAction(2.00)
set RealTemp1 = 0.01
loop
if (libCin_IsCinematicSkipped(PlayerID)) then
call libCin_ApplyCameraTimed(PlayerID, gg_cam_OUTRO_Camera01, 0.00)
exitwhen true
endif
set RealTemp1 = RealTemp1 + MaxSkipTime
call TriggerSleepAction(MaxSkipTime)
exitwhen RealTemp1 >= 2.00
endloop
call libCin_ShowSpeakScene(PlayerID, "...So the commander defeated all enemies that dared to attack the castle.|nAnd this how the story ends.", "Narrator", 'nmed', 1)
call TriggerSleepAction(4.00)
call libCin_SwitchCinematicMode(PlayerID, false)
//Show victory:
call RemovePlayer(Player(PlayerID - 1), PLAYER_GAME_RESULT_VICTORY)
if not bj_isSinglePlayer then
call DisplayTimedTextFromPlayer(Player(PlayerID - 1), 0, 0, 60, GetLocalizedString("PLAYER_VICTORIOUS"))
endif
if (GetPlayerController(Player(PlayerID - 1)) == MAP_CONTROL_USER) then
set bj_changeLevelShowScores = false
call CustomVictoryDialogBJ(Player(PlayerID - 1))
endif
endfunction
//===========================================================================
function InitTrig_Victory takes nothing returns nothing
set gg_trg_Victory = CreateTrigger()
call TriggerRegisterTimerEvent(gg_trg_Victory, 5.00, true)
call TriggerAddCondition(gg_trg_Victory, Condition(function Trig_Victory_Conditions))
call TriggerAddAction(gg_trg_Victory, function Trig_Victory_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Defeat_Conditions takes nothing returns boolean
return (IsUnitType(GetDyingUnit(), UNIT_TYPE_TOWNHALL))
endfunction
function Trig_Defeat_Actions takes nothing returns nothing
local integer PlayerID = 1
local real MaxSkipTime = 0.50
local real RealTemp1
call DisableTrigger(gg_trg_Defeat)
call QuestSetCompleted(bj_lastCreatedQuest, false)
call FlashQuestDialogButton()
call TriggerSleepAction(3.00)
//Play outro:
call EndThematicMusic()
call PlayThematicMusic("Sound\\Music\\mp3Music\\HeroicVictory.mp3")
call libCin_SwitchCinematicMode(PlayerID, true)
call libCin_ApplyCameraTimed(PlayerID, gg_cam_OUTRO_Camera01, 2.00)
call TriggerSleepAction(2.00)
set RealTemp1 = 0.01
loop
if (libCin_IsCinematicSkipped(PlayerID)) then
call libCin_ApplyCameraTimed(PlayerID, gg_cam_OUTRO_Camera01, 0.00)
exitwhen true
endif
set RealTemp1 = RealTemp1 + MaxSkipTime
call TriggerSleepAction(MaxSkipTime)
exitwhen RealTemp1 >= 2.00
endloop
call libCin_ShowSpeakScene(PlayerID, "...So the castle finally fell to the overwhelming waves of attackers.|nAnd this how the story ends.", "Narrator", 'nmed', 1)
call TriggerSleepAction(4.00)
call libCin_SwitchCinematicMode(PlayerID, false)
//Show defeat:
call RemovePlayer(Player(PlayerID - 1), PLAYER_GAME_RESULT_DEFEAT)
if not bj_isSinglePlayer then
call DisplayTimedTextFromPlayer(Player(PlayerID - 1), 0, 0, 60, GetLocalizedString("PLAYER_DEFEATED"))
endif
if (GetPlayerController(Player(PlayerID - 1)) == MAP_CONTROL_USER) then
call CustomDefeatDialogBJ(Player(PlayerID - 1), "Defeated!")
endif
endfunction
//===========================================================================
function InitTrig_Defeat takes nothing returns nothing
set gg_trg_Defeat = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(gg_trg_Defeat, Player(1 - 1), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerAddCondition(gg_trg_Defeat, Condition(function Trig_Defeat_Conditions))
call TriggerAddAction(gg_trg_Defeat, function Trig_Defeat_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_SiegeReinforcement_Conditions_Filter1 takes nothing returns boolean
local unit UnitTemp1 = GetFilterUnit()
local boolean Return = (GetOwningPlayer(UnitTemp1) == Player(1 - 1) and IsUnitType(UnitTemp1, UNIT_TYPE_STRUCTURE) == false and GetUnitState(UnitTemp1, UNIT_STATE_LIFE) >= 1.00 and IsUnitLoaded(UnitTemp1) == false)
//Anti-Memory-Leak:
set UnitTemp1 = null
//-----------------
return Return
endfunction
function Trig_SiegeReinforcement_Conditions takes nothing returns boolean
local group GroupTemp1 = CreateGroup()
local boolexpr FilterTemp1 = Condition(function Trig_SiegeReinforcement_Conditions_Filter1)
local unit UnitTemp1
local boolean Return
call GroupEnumUnitsInRange(GroupTemp1, -2816.00, 5632.00, 1536.00, FilterTemp1)
call DestroyBoolExpr(FilterTemp1)
set UnitTemp1 = FirstOfGroup(GroupTemp1)
call DestroyGroup(GroupTemp1)
set Return = (UnitTemp1 == null)
//Anti-Memory-Leak:
set GroupTemp1 = null
set FilterTemp1 = null
set UnitTemp1 = null
//-----------------
return Return
endfunction
function Trig_SiegeReinforcement_Filter1 takes nothing returns boolean
local unit UnitTemp1 = GetFilterUnit()
local boolean Return = (GetOwningPlayer(UnitTemp1) != Player(1 - 1) and GetUnitState(UnitTemp1, UNIT_STATE_LIFE) >= 1.00 and IsUnitType(UnitTemp1, UNIT_TYPE_STRUCTURE) == false)
//Anti-Memory-Leak:
set UnitTemp1 = null
//-----------------
return Return
endfunction
function Trig_SiegeReinforcement_Filter2 takes nothing returns boolean
return (IsUnitType(GetFilterUnit(), UNIT_TYPE_TOWNHALL))
endfunction
function Trig_SiegeReinforcement_Filter3 takes nothing returns boolean
local unit UnitTemp1 = GetFilterUnit()
local boolean Return = (GetUnitState(UnitTemp1, UNIT_STATE_LIFE) >= 1.00 and (GetUnitTypeId(UnitTemp1) == libId_udg_MortarTeam or GetUnitTypeId(UnitTemp1) == libId_udg_MeatWagon or GetUnitTypeId(UnitTemp1) == libId_udg_Devastor)) //Mortar team, Meat wagon, Devastator
//Anti-Memory-Leak:
set UnitTemp1 = null
//-----------------
return Return
endfunction
function Trig_SiegeReinforcement_Actions takes nothing returns nothing
local group GroupTemp1 = CreateGroup()
local boolexpr FilterTemp1 = Condition(function Trig_SiegeReinforcement_Filter1)
local unit UnitTemp1
local unit UnitTemp2
local player PlayerTemp1
local real RealTemp1
local real RealTemp2
call GroupEnumUnitsInRange(GroupTemp1, -2816.00, 5632.00, 1536.00, FilterTemp1)
call DestroyBoolExpr(FilterTemp1)
set UnitTemp2 = FirstOfGroup(GroupTemp1)
if (UnitTemp2 != null) then
call GroupRemoveUnit(GroupTemp1, UnitTemp2)
set PlayerTemp1 = GetOwningPlayer(UnitTemp2)
//Check for competing units:
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
if (GetOwningPlayer(UnitTemp1) != PlayerTemp1) then
call DestroyGroup(GroupTemp1)
//Anti-Memory-Leak:
set GroupTemp1 = null
set FilterTemp1 = null
set UnitTemp1 = null
set UnitTemp2 = null
//-----------------
return
endif
endloop
//Get main building:
call GroupClear(GroupTemp1)
set FilterTemp1 = Condition(function Trig_SiegeReinforcement_Filter2)
call GroupEnumUnitsInRange(GroupTemp1, -2816.00, 5632.00, 256.00, FilterTemp1)
call DestroyBoolExpr(FilterTemp1)
set UnitTemp2 = FirstOfGroup(GroupTemp1)
//Check for siege units:
call GroupClear(GroupTemp1)
set FilterTemp1 = Condition(function Trig_SiegeReinforcement_Filter3)
call GroupEnumUnitsOfPlayer(GroupTemp1, PlayerTemp1, FilterTemp1)
call DestroyBoolExpr(FilterTemp1)
set UnitTemp1 = FirstOfGroup(GroupTemp1)
if (UnitTemp1 == null) then
//Create siege reinforcement:
call GroupClear(GroupTemp1)
if (PlayerTemp1 == Player(3 - 1)) then
set RealTemp1 = GetRandomReal(0.0, 2.0)
if (RealTemp1 <= 1.0) then
set RealTemp1 = 0.00
set RealTemp2 = 3584.00
else
set RealTemp1 = -8832.00
set RealTemp2 = 4352.00
endif
call GroupAddUnit(GroupTemp1, CreateUnit(PlayerTemp1, libId_udg_MortarTeam, RealTemp1, RealTemp2, 0.00)) //Mortar team
call GroupAddUnit(GroupTemp1, CreateUnit(PlayerTemp1, libId_udg_MortarTeam, RealTemp1, RealTemp2, 0.00)) //Mortar team
call GroupAddUnit(GroupTemp1, CreateUnit(PlayerTemp1, libId_udg_MortarTeam, RealTemp1, RealTemp2, 0.00)) //Mortar team
elseif (PlayerTemp1 == Player(4 - 1)) then
set RealTemp1 = -6272.00
set RealTemp2 = 5760.00
call GroupAddUnit(GroupTemp1, CreateUnit(PlayerTemp1, libId_udg_MeatWagon, RealTemp1, RealTemp2, 0.00)) //Meat wagon
call GroupAddUnit(GroupTemp1, CreateUnit(PlayerTemp1, libId_udg_MeatWagon, RealTemp1, RealTemp2, 0.00)) //Meat wagon
call GroupAddUnit(GroupTemp1, CreateUnit(PlayerTemp1, libId_udg_MeatWagon, RealTemp1, RealTemp2, 0.00)) //Meat wagon
elseif (PlayerTemp1 == Player(6 - 1)) then
set RealTemp1 = GetRandomReal(0.0, 2.0)
if (RealTemp1 <= 1.0) then
set RealTemp1 = 0.00
set RealTemp2 = 3584.00
else
set RealTemp1 = -6912.00
set RealTemp2 = 8320.00
endif
call GroupAddUnit(GroupTemp1, CreateUnit(PlayerTemp1, libId_udg_Devastor, RealTemp1, RealTemp2, 0.00)) //Devastator
call GroupAddUnit(GroupTemp1, CreateUnit(PlayerTemp1, libId_udg_Devastor, RealTemp1, RealTemp2, 0.00)) //Devastator
call GroupAddUnit(GroupTemp1, CreateUnit(PlayerTemp1, libId_udg_Devastor, RealTemp1, RealTemp2, 0.00)) //Devastator
endif
endif
//Order to attack main building:
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call IssueTargetOrder(UnitTemp1, "attack", UnitTemp2)
endloop
call DestroyGroup(GroupTemp1)
endif
//Anti-Memory-Leak:
set GroupTemp1 = null
set FilterTemp1 = null
set UnitTemp1 = null
set UnitTemp2 = null
endfunction
//===========================================================================
function InitTrig_SiegeReinforcement takes nothing returns nothing
set gg_trg_SiegeReinforcement = CreateTrigger()
call TriggerRegisterTimerEvent(gg_trg_SiegeReinforcement, 5.00, true)
call TriggerAddCondition(gg_trg_SiegeReinforcement, Condition(function Trig_SiegeReinforcement_Conditions))
call TriggerAddAction(gg_trg_SiegeReinforcement, function Trig_SiegeReinforcement_Actions)
endfunction