Name | Type | is_array | initial_value |
ALLY_Ally_Command | string | No | |
ALLY_Color | string | Yes | |
ALLY_Player_Name | string | No | |
ALLY_Player_Names | string | Yes | |
ALLY_Player_Numbers | integer | No | |
ALLY_String | string | No | |
ALLY_Unally_Command | string | No | |
CargoEvent | real | No | |
CargoTransportGroup | group | Yes | |
CargoTransportUnit | unit | Yes | |
CheckDeathList | integer | Yes | |
CheckDeathTimer | timer | No | |
ClosestPeasant | unit | No | |
Corpse | destructable | No | |
DamageEvent | real | No | |
DamageEventAmount | real | No | |
DamageEventTarget | unit | No | |
DamageEventType | integer | No | |
DamageTypeBlocked | integer | No | |
DamageTypeCritical | integer | No | |
DamageTypeHeal | integer | No | |
DamageTypeReduced | integer | No | |
DeathEvent | real | No | |
DetectRemoveAbility | abilcode | No | A009 |
DetectTransformAbility | abilcode | No | A00A |
IsDamageSpell | boolean | No | |
IsUnitAlive | boolean | Yes | |
IsUnitBeingUnloaded | boolean | Yes | |
IsUnitNew | boolean | Yes | |
IsUnitPreplaced | boolean | Yes | |
IsUnitReincarnating | boolean | Yes | |
IsUnitRemoved | boolean | Yes | |
IsUnitTransforming | boolean | Yes | |
KillerOfUnit | unit | Yes | |
lb | leaderboard | Yes | |
P | location | No | |
PlayerGroup | force | No | |
PRM_Change | integer | No | |
PRM_EVENT | real | No | |
PRM_FireEvent | boolean | No | |
PRM_GoldLevel | integer | Yes | |
PRM_LumberLevel | integer | Yes | |
PRM_MonitorPlayer | boolean | Yes | |
PRM_Player | player | No | |
PRM_WORKER_EVENT | real | No | |
PRM_WorkerLumber | unit | No | |
PRM_WorkerLumberAmmount | integer | No | |
RangeCheck | integer | No | |
RangeCheck2 | real | No | |
Resource_Ability | abilcode | No | |
Resource_Cost | integer | Yes | |
Resource_CostResearch | techcode | No | |
Resource_CostUnit | unitcode | No | |
Resource_Destructable | destructablecode | Yes | |
Resource_DummyTree | destructablecode | No | |
Resource_Event | real | No | |
Resource_Name | string | Yes | |
Resource_Number | integer | No | |
Resource_Player | player | No | |
Resource_Structure | unitcode | Yes | |
Resource_Value | integer | No | |
Resource_Worker | unitcode | Yes | |
Sheep | group | No | |
stopGroup | group | No | |
stopTimer | timer | No | |
SummonerOfUnit | unit | Yes | |
SwitchAttack_Ability1 | abilcode | No | |
SwitchAttack_Ability2 | abilcode | No | |
SwitchAttack_Tree | destructablecode | No | |
SwitchAttackTo1_Unit | unit | No | |
SwitchAttackTo2_Unit | unit | No | |
tempGroup | group | No | |
tempGroup2 | group | No | |
tempInt | integer | No | |
tempInt0 | integer | No | |
tempPoint | location | No | |
tempPoint2 | location | No | |
tempPoint3 | location | No | |
TimerHealTo100 | timer | No | |
UDex | integer | No | |
UDexLastRecycled | integer | No | |
UDexMax | integer | No | |
UDexNext | integer | Yes | |
UDexPrev | integer | Yes | |
UDexUnits | unit | Yes | |
unit | unit | No | |
UnitAlive | boolean | No | |
UnitIndexerEnabled | boolean | No | false |
UnitIndexEvent | real | No | |
UnitNew | boolean | No | |
UnitRemoved | boolean | No | |
UnitTypeEvent | real | No | |
UnitTypeOf | unitcode | Yes | |
UpUnit | unit | No | |
Worker | unit | No | |
WorldMaxX | real | No | |
WorldMaxY | real | No |
function Trig_Exploding_Barrel_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A06X' ) ) then
return false
endif
return true
endfunction
function Trig_Exploding_Barrel_Actions takes nothing returns nothing
local location l = GetSpellTargetLoc()
local unit u = CreateUnitAtLoc(GetOwningPlayer(GetSpellAbilityUnit()), 'o000', l, 0)
call UnitApplyTimedLife(u, 'BTLF', 1)
call IssuePointOrderLocBJ(u, "clusterrockets", l)
call RemoveLocation(l)
set u = null
endfunction
function InitTrig_Exploding_Barrel takes nothing returns nothing
local trigger Exploding_Barrel = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( Exploding_Barrel, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( Exploding_Barrel, Condition( function Trig_Exploding_Barrel_Conditions ) )
call TriggerAddAction( Exploding_Barrel, function Trig_Exploding_Barrel_Actions )
endfunction
//TESH.scrollpos=239
//TESH.alwaysfold=0
//===========================================================================
function UnitEventDestroyGroup takes integer i returns nothing
if udg_CargoTransportGroup[i] != null then
call DestroyGroup(udg_CargoTransportGroup[i])
set udg_CargoTransportGroup[i] = null
endif
endfunction
function UnitEventCheckDeath takes nothing returns nothing
local integer i = udg_CheckDeathList[0]
set udg_CheckDeathList[0] = 0
loop
exitwhen i == 0
if udg_IsUnitNew[i] then
//The unit was just created.
set udg_IsUnitNew[i] = false
elseif udg_IsUnitAlive[i] then
//The unit has started reincarnating.
set udg_IsUnitReincarnating[i] = true
set udg_IsUnitAlive[i] = false
set udg_UDex = i
set udg_DeathEvent = 0.50
set udg_DeathEvent = 0.00
endif
set i = udg_CheckDeathList[i]
endloop
endfunction
function UnitEventCheckDeathProxy takes integer i returns nothing
if udg_CheckDeathList[0] == 0 then
call TimerStart(udg_CheckDeathTimer, 0.00, false, function UnitEventCheckDeath)
endif
set udg_CheckDeathList[i] = udg_CheckDeathList[0]
set udg_CheckDeathList[0] = i
endfunction
function UnitEventOnUnload takes nothing returns nothing
local integer i = udg_UDex
call GroupRemoveUnit(udg_CargoTransportGroup[GetUnitUserData(udg_CargoTransportUnit[i])], udg_UDexUnits[i])
set udg_IsUnitBeingUnloaded[i] = true
set udg_CargoEvent = 0.00
set udg_CargoEvent = 2.00
set udg_CargoEvent = 0.00
set udg_IsUnitBeingUnloaded[i] = false
if not IsUnitLoaded(udg_UDexUnits[i]) or IsUnitType(udg_CargoTransportUnit[i], UNIT_TYPE_DEAD) or GetUnitTypeId(udg_CargoTransportUnit[i]) == 0 then
set udg_CargoTransportUnit[i] = null
endif
endfunction
function UnitEventOnDeath takes nothing returns boolean
local integer pdex = udg_UDex
set udg_UDex = GetUnitUserData(GetTriggerUnit())
if udg_UDex != 0 then
set udg_KillerOfUnit[udg_UDex] = GetKillingUnit() //Added 29 May 2017 for GIMLI_2
set udg_IsUnitAlive[udg_UDex] = false
set udg_DeathEvent = 0.00
set udg_DeathEvent = 1.00
set udg_DeathEvent = 0.00
set udg_KillerOfUnit[udg_UDex] = null
if udg_CargoTransportUnit[udg_UDex] != null then
call UnitEventOnUnload()
endif
endif
set udg_UDex = pdex
return false
endfunction
function UnitEventOnOrder takes nothing returns boolean
local integer pdex = udg_UDex
local unit u = GetFilterUnit()
local integer i = GetUnitUserData(u)
if i > 0 then
set udg_UDex = i
if GetUnitAbilityLevel(u, udg_DetectRemoveAbility) == 0 then
if not udg_IsUnitRemoved[i] then
set udg_IsUnitRemoved[i] = true
set udg_IsUnitAlive[i] = false
set udg_SummonerOfUnit[i] = null
//For backwards-compatibility:
set udg_DeathEvent = 0.00
set udg_DeathEvent = 3.00
set udg_DeathEvent = 0.00
//Fire deindex event for UDex:
set udg_UnitIndexEvent = 0.00
set udg_UnitIndexEvent = 2.00
set udg_UnitIndexEvent = 0.00
set udg_UDexNext[udg_UDexPrev[i]] = udg_UDexNext[i]
set udg_UDexPrev[udg_UDexNext[i]] = udg_UDexPrev[i]
// Recycle the index for later use
set udg_UDexUnits[i] = null
set udg_UDexPrev[i] = udg_UDexLastRecycled
set udg_UDexLastRecycled = i
call UnitEventDestroyGroup(i)
endif
elseif not udg_IsUnitAlive[i] then
if not IsUnitType(u, UNIT_TYPE_DEAD) then
set udg_IsUnitAlive[i] = true
set udg_DeathEvent = 0.00
set udg_DeathEvent = 2.00
set udg_DeathEvent = 0.00
set udg_IsUnitReincarnating[i] = false
endif
elseif IsUnitType(u, UNIT_TYPE_DEAD) then
if udg_IsUnitNew[i] then
//This unit was created as a corpse.
set udg_IsUnitAlive[i] = false
set udg_DeathEvent = 0.00
set udg_DeathEvent = 1.00
set udg_DeathEvent = 0.00
elseif udg_CargoTransportUnit[i] == null or not IsUnitType(u, UNIT_TYPE_HERO) then
//The unit may have just started reincarnating.
call UnitEventCheckDeathProxy(i)
endif
elseif GetUnitAbilityLevel(u, udg_DetectTransformAbility) == 0 then
call UnitAddAbility(u, udg_DetectTransformAbility)
set udg_UnitTypeEvent = 0.00
set udg_UnitTypeEvent = 1.00
set udg_UnitTypeEvent = 0.00
endif
if udg_CargoTransportUnit[i] != null and not udg_IsUnitBeingUnloaded[i] and not IsUnitLoaded(u) or IsUnitType(u, UNIT_TYPE_DEAD) then
call UnitEventOnUnload()
endif
set udg_UDex = pdex
endif
set u = null
return false
endfunction
function UnitEventOnSummon takes nothing returns boolean
local integer pdex = udg_UDex
set udg_UDex = GetUnitUserData(GetTriggerUnit())
if udg_IsUnitNew[udg_UDex] then
set udg_SummonerOfUnit[udg_UDex] = GetSummoningUnit()
set udg_UnitIndexEvent = 0.00
set udg_UnitIndexEvent = 0.50
set udg_UnitIndexEvent = 0.00
endif
set udg_UDex = pdex
return false
endfunction
function UnitEventOnLoad takes nothing returns boolean
local integer pdex = udg_UDex
local integer i = GetUnitUserData(GetTriggerUnit())
local integer index
if i != 0 then
set udg_UDex = i
if udg_CargoTransportUnit[i] != null then
call UnitEventOnUnload()
endif
//Loaded corpses do not issue an order when unloaded, therefore must
//use the enter-region event method taken from Jesus4Lyf's Transport.
if not udg_IsUnitAlive[i] then
call SetUnitX(udg_UDexUnits[i], udg_WorldMaxX)
call SetUnitY(udg_UDexUnits[i], udg_WorldMaxY)
endif
set udg_CargoTransportUnit[i] = GetTransportUnit()
set index = GetUnitUserData(udg_CargoTransportUnit[i])
if udg_CargoTransportGroup[index] == null then
set udg_CargoTransportGroup[index] = CreateGroup()
endif
call GroupAddUnit(udg_CargoTransportGroup[index], udg_UDexUnits[i])
set udg_CargoEvent = 0.00
set udg_CargoEvent = 1.00
set udg_CargoEvent = 0.00
set udg_UDex = pdex
endif
return false
endfunction
function UnitEventEnter takes nothing returns boolean
local integer pdex = udg_UDex
local integer i = udg_UDexLastRecycled
local unit u = GetFilterUnit()
if udg_UnitIndexerEnabled and GetUnitAbilityLevel(u, udg_DetectRemoveAbility) == 0 then
//Generate a unique integer index for this unit
if i == 0 then
set i = udg_UDexMax + 1
set udg_UDexMax = i
else
set udg_UDexLastRecycled = udg_UDexPrev[i]
endif
//Link index to unit, unit to index
set udg_UDexUnits[i] = u
call SetUnitUserData(u, i)
//For backwards-compatibility, add the unit to a linked list
set udg_UDexNext[i] = udg_UDexNext[0]
set udg_UDexPrev[udg_UDexNext[0]] = i
set udg_UDexNext[0] = i
set udg_UDexPrev[i] = 0
call UnitAddAbility(u, udg_DetectRemoveAbility)
call UnitMakeAbilityPermanent(u, true, udg_DetectRemoveAbility)
call UnitAddAbility(u, udg_DetectTransformAbility)
set udg_IsUnitNew[i] = true
set udg_IsUnitAlive[i] = true
set udg_IsUnitRemoved[i] = false
set udg_IsUnitReincarnating[i] = false
set udg_IsUnitPreplaced[i] = udg_IsUnitPreplaced[0] //Added 29 May 2017 for Spellbound
call UnitEventCheckDeathProxy(i)
//Fire index event for UDex
set udg_UDex = i
set udg_UnitIndexEvent = 0.00
set udg_UnitIndexEvent = 1.00
set udg_UnitIndexEvent = 0.00
else
set udg_UDex = GetUnitUserData(u)
if udg_CargoTransportUnit[udg_UDex] != null and not IsUnitLoaded(u) then
//The unit was dead, but has re-entered the map.
call UnitEventOnUnload()
endif
endif
set udg_UDex = pdex
set u = null
return false
endfunction
//===========================================================================
function UnitEventInit takes nothing returns nothing
local integer i = 16
local player p
local trigger t = CreateTrigger()
local trigger summon = CreateTrigger()
local trigger death = CreateTrigger()
local trigger load = CreateTrigger()
local region re = CreateRegion()
local rect r = GetWorldBounds()
set udg_WorldMaxX = GetRectMaxX(r)
set udg_WorldMaxY = GetRectMaxY(r)
call RegionAddRect(re, r)
call RemoveRect(r)
call UnitEventDestroyGroup(0)
call UnitEventDestroyGroup(1)
set udg_UnitIndexerEnabled = true
call TriggerRegisterEnterRegion(CreateTrigger(), re, Filter(function UnitEventEnter))
call TriggerAddCondition(summon, Filter(function UnitEventOnSummon))
call TriggerAddCondition(death, Filter(function UnitEventOnDeath))
call TriggerAddCondition(load, Filter(function UnitEventOnLoad))
loop
set i = i - 1
set p = Player(i)
call SetPlayerAbilityAvailable(p, udg_DetectRemoveAbility, false)
call SetPlayerAbilityAvailable(p, udg_DetectTransformAbility, false)
call TriggerRegisterPlayerUnitEvent(t, p, EVENT_PLAYER_UNIT_ISSUED_ORDER, Filter(function UnitEventOnOrder))
call TriggerRegisterPlayerUnitEvent(summon, p, EVENT_PLAYER_UNIT_SUMMON, null)
call TriggerRegisterPlayerUnitEvent(death, p, EVENT_PLAYER_UNIT_DEATH, null)
call TriggerRegisterPlayerUnitEvent(load, p, EVENT_PLAYER_UNIT_LOADED, null)
call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, p, Filter(function UnitEventEnter))
exitwhen i == 0
endloop
set summon = null
set death = null
set load = null
set re = null
set p = null
set r = null
set t = null
endfunction
function InitTrig_Unit_Event takes nothing returns nothing
endfunction
library ORDER
globals
//strange ones at bottom
public constant integer OFFSET=851970
public constant integer absorb=852529
public constant integer acidbomb=852662
public constant integer acolyteharvest=852185
public constant integer AImove=851988
public constant integer ambush=852131
public constant integer ancestralspirit=852490
public constant integer ancestralspirittarget=852491
public constant integer animatedead=852217
public constant integer antimagicshell=852186
public constant integer attack=851983
public constant integer attackground=851984
public constant integer attackonce=851985
public constant integer attributemodskill=852576
public constant integer auraunholy=852215
public constant integer auravampiric=852216
public constant integer autodispel=852132
public constant integer autodispeloff=852134
public constant integer autodispelon=852133
public constant integer autoentangle=852505
public constant integer autoentangleinstant=852506
public constant integer autoharvestgold=852021
public constant integer autoharvestlumber=852022
public constant integer avatar=852086
public constant integer avengerform=852531
public constant integer awaken=852466
public constant integer banish=852486
public constant integer barkskin=852135
public constant integer barkskinoff=852137
public constant integer barkskinon=852136
public constant integer battleroar=852099
public constant integer battlestations=852099
public constant integer bearform=852138
public constant integer berserk=852100
public constant integer blackarrow=852577
public constant integer blackarrowoff=852579
public constant integer blackarrowon=852578
public constant integer blight=852187
public constant integer blink=852525
public constant integer blizzard=852089
public constant integer bloodlust=852101
public constant integer bloodlustoff=852103
public constant integer bloodluston=852102
public constant integer board=852043
public constant integer breathoffire=852580
public constant integer breathoffrost=852560
public constant integer build=851994
public constant integer burrow=852533
public constant integer cannibalize=852188
public constant integer carrionscarabs=852551
public constant integer carrionscarabsinstant=852554
public constant integer carrionscarabsoff=852553
public constant integer carrionscarabson=852552
public constant integer carrionswarm=852218
public constant integer chainlightning=852119
public constant integer channel=852600
public constant integer charm=852581
public constant integer chemicalrage=852663
public constant integer cloudoffog=852473
public constant integer clusterrockets=852652
public constant integer coldarrows=852244
public constant integer coldarrowstarg=852243
public constant integer controlmagic=852474
public constant integer corporealform=852493
public constant integer corrosivebreath=852140
public constant integer coupleinstant=852508
public constant integer coupletarget=852507
public constant integer creepanimatedead=852246
public constant integer creepdevour=852247
public constant integer creepheal=852248
public constant integer creephealoff=852250
public constant integer creephealon=852249
public constant integer creepthunderbolt=852252
public constant integer creepthunderclap=852253
public constant integer cripple=852189
public constant integer curse=852190
public constant integer curseoff=852192
public constant integer curseon=852191
public constant integer cyclone=852144
public constant integer darkconversion=852228
public constant integer darkportal=852229
public constant integer darkritual=852219
public constant integer darksummoning=852220
public constant integer deathanddecay=852221
public constant integer deathcoil=852222
public constant integer deathpact=852223
public constant integer decouple=852509
public constant integer defend=852055
public constant integer detectaoe=852015
public constant integer detonate=852145
public constant integer devour=852104
public constant integer devourmagic=852536
public constant integer disassociate=852240
public constant integer disenchant=852495
public constant integer dismount=852470
public constant integer dispel=852057
public constant integer divineshield=852090
public constant integer doom=852583
public constant integer drain=852487
public constant integer dreadlordinferno=852224
public constant integer dropitem=852001
public constant integer drunkenhaze=852585
public constant integer earthquake=852121
public constant integer eattree=852146
public constant integer elementalfury=852586
public constant integer ensnare=852106
public constant integer ensnareoff=852108
public constant integer ensnareon=852107
public constant integer entangle=852147
public constant integer entangleinstant=852148
public constant integer entanglingroots=852171
public constant integer etherealform=852496
public constant integer evileye=852105
public constant integer faeriefire=852149
public constant integer faeriefireoff=852151
public constant integer faeriefireon=852150
public constant integer fanofknives=852526
public constant integer farsight=852122
public constant integer fingerofdeath=852230
public constant integer firebolt=852231
public constant integer flamestrike=852488
public constant integer flamingarrows=852174
public constant integer flamingarrowstarg=852173
public constant integer flamingattack=852540
public constant integer flamingattacktarg=852539
public constant integer flare=852060
public constant integer forceboard=852044
public constant integer forceofnature=852176
public constant integer forkedlightning=852587
public constant integer freezingbreath=852195
public constant integer frenzy=852561
public constant integer frenzyoff=852563
public constant integer frenzyon=852562
public constant integer frostarmor=852225
public constant integer frostarmoroff=852459
public constant integer frostarmoron=852458
public constant integer frostnova=852226
public constant integer getitem=851981
public constant integer gold2lumber=852233
public constant integer grabtree=852511
public constant integer harvest=852018
public constant integer heal=852063
public constant integer healingspray=852664
public constant integer healingward=852109
public constant integer healingwave=852501
public constant integer healoff=852065
public constant integer healon=852064
public constant integer hex=852502
public constant integer holdposition=851993
public constant integer holybolt=852092
public constant integer howlofterror=852588
public constant integer humanbuild=851995
public constant integer immolation=852177
public constant integer impale=852555
public constant integer incineratearrow=852670
public constant integer incineratearrowoff=852672
public constant integer incineratearrowon=852671
public constant integer inferno=852232
public constant integer innerfire=852066
public constant integer innerfireoff=852068
public constant integer innerfireon=852067
public constant integer instant=852200
public constant integer invisibility=852069
public constant integer lavamonster=852667
public constant integer lightningshield=852110
public constant integer load=852046
public constant integer loadarcher = 852142
public constant integer loadcorpse=852050
public constant integer loadcorpseinstant=852053
public constant integer locustswarm=852556
public constant integer lumber2gold=852234
public constant integer magicdefense=852478
public constant integer magicleash=852480
public constant integer magicundefense=852479
public constant integer manaburn=852179
public constant integer manaflareoff=852513
public constant integer manaflareon=852512
public constant integer manashieldoff=852590
public constant integer manashieldon=852589
public constant integer massteleport=852093
public constant integer mechanicalcritter=852564
public constant integer metamorphosis=852180
public constant integer militia=852072
public constant integer militiaconvert=852071
public constant integer militiaoff=852073
public constant integer militiaunconvert=852651
public constant integer mindrot=852565
public constant integer mirrorimage=852123
public constant integer monsoon=852591
public constant integer mount=852469
public constant integer mounthippogryph=852143
public constant integer move=851986
public constant integer nagabuild=852467
public constant integer neutraldetectaoe=852023
public constant integer neutralinteract=852566
public constant integer neutralspell=852630
public constant integer nightelfbuild=851997
public constant integer orcbuild=851996
public constant integer parasite=852601
public constant integer parasiteoff=852603
public constant integer parasiteon=852602
public constant integer patrol=851990
public constant integer phaseshift=852514
public constant integer phaseshiftinstant=852517
public constant integer phaseshiftoff=852516
public constant integer phaseshifton=852515
public constant integer phoenixfire=852481
public constant integer phoenixmorph=852482
public constant integer poisonarrows=852255
public constant integer poisonarrowstarg=852254
public constant integer polymorph=852074
public constant integer possession=852196
public constant integer preservation=852568
public constant integer purge=852111
public constant integer rainofchaos=852237
public constant integer rainoffire=852238
public constant integer raisedead=852197
public constant integer raisedeadoff=852199
public constant integer raisedeadon=852198
public constant integer ravenform=852155
public constant integer recharge=852157
public constant integer rechargeoff=852159
public constant integer rechargeon=852158
public constant integer rejuvination=852160
public constant integer renew=852161
public constant integer renewoff=852163
public constant integer renewon=852162
public constant integer repair=852024
public constant integer repairoff=852026
public constant integer repairon=852025
public constant integer replenish=852542
public constant integer replenishlife=852545
public constant integer replenishlifeoff=852547
public constant integer replenishlifeon=852546
public constant integer replenishmana=852548
public constant integer replenishmanaoff=852550
public constant integer replenishmanaon=852549
public constant integer replenishoff=852544
public constant integer replenishon=852543
public constant integer request_hero=852239
public constant integer requestsacrifice=852201
public constant integer restoration=852202
public constant integer restorationoff=852204
public constant integer restorationon=852203
public constant integer resumebuild=851999
public constant integer resumeharvesting=852017
public constant integer resurrection=852094
public constant integer returnresources=852020
public constant integer reveal=852270
public constant integer revenge=852241
public constant integer revive=852039
public constant integer roar=852164
public constant integer robogoblin=852656
public constant integer root=852165
public constant integer sacrifice=852205
public constant integer sanctuary=852569
public constant integer scout=852181
public constant integer selfdestruct=852040
public constant integer selfdestructoff=852042
public constant integer selfdestructon=852041
public constant integer sentinel=852182
public constant integer setrally=851980
public constant integer shadowsight=852570
public constant integer shadowstrike=852527
public constant integer shockwave=852125
public constant integer silence=852592
public constant integer sleep=852227
public constant integer slow=852075
public constant integer slowoff=852077
public constant integer slowon=852076
public constant integer smart=851971
public constant integer soulburn=852668
public constant integer soulpreservation=852242
public constant integer spellshield=852571
public constant integer spellshieldaoe=852572
public constant integer spellsteal=852483
public constant integer spellstealoff=852485
public constant integer spellstealon=852484
public constant integer spies=852235
public constant integer spiritlink=852499
public constant integer spiritofvengeance=852528
public constant integer spirittroll=852573
public constant integer spiritwolf=852126
public constant integer stampede=852593
public constant integer standdown=852113
public constant integer starfall=852183
public constant integer stasistrap=852114
public constant integer steal=852574
public constant integer stomp=852127
public constant integer stoneform=852206
public constant integer stop=851972
public constant integer submerge=852604
public constant integer summonfactory=852658
public constant integer summongrizzly=852594
public constant integer summonphoenix=852489
public constant integer summonquillbeast=852595
public constant integer summonwareagle=852596
public constant integer tankdroppilot=852079
public constant integer tankloadpilot=852080
public constant integer tankpilot=852081
public constant integer taunt=852520
public constant integer thunderbolt=852095
public constant integer thunderclap=852096
public constant integer tornado=852597
public constant integer townbelloff=852083
public constant integer townbellon=852082
public constant integer tranquility=852184
public constant integer transmute=852665
public constant integer unavatar=852087
public constant integer unavengerform=852532
public constant integer unbearform=852139
public constant integer unburrow=852534
public constant integer uncoldarrows=852245
public constant integer uncorporealform=852494
public constant integer undeadbuild=851998
public constant integer undefend=852056
public constant integer undivineshield=852091
public constant integer unetherealform=852497
public constant integer unflamingarrows=852175
public constant integer unflamingattack=852541
public constant integer unholyfrenzy=852209
public constant integer unimmolation=852178
public constant integer unload=852047
public constant integer unloadall=852048
public constant integer unloadallcorpses=852054
public constant integer unloadallinstant=852049
public constant integer unpoisonarrows=852256
public constant integer unravenform=852156
public constant integer unrobogoblin=852657
public constant integer unroot=852166
public constant integer unstableconcoction=852500
public constant integer unstoneform=852207
public constant integer unsubmerge=852605
public constant integer unsummon=852210
public constant integer unwindwalk=852130
public constant integer vengeance=852521
public constant integer vengeanceinstant=852524
public constant integer vengeanceoff=852523
public constant integer vengeanceon=852522
public constant integer volcano=852669
public constant integer voodoo=852503
public constant integer ward=852504
public constant integer waterelemental=852097
public constant integer wateryminion=852598
public constant integer web=852211
public constant integer weboff=852213
public constant integer webon=852212
public constant integer whirlwind=852128
public constant integer windwalk=852129
public constant integer wispharvest=852214
public constant integer scrollofspeed=852285
public constant integer cancel=851976
public constant integer moveslot1=852002
public constant integer moveslot2=852003
public constant integer moveslot3=852004
public constant integer moveslot4=852005
public constant integer moveslot5=852006
public constant integer moveslot6=852007
public constant integer useslot1=852008
public constant integer useslot2=852009
public constant integer useslot3=852010
public constant integer useslot4=852011
public constant integer useslot5=852012
public constant integer useslot6=852013
public constant integer skillmenu=852000
public constant integer stunned=851973
public constant integer instant1=851991 //?
public constant integer instant2=851987 //?
public constant integer instant3=851975 //?
public constant integer instant4=852019 //?
public constant integer itemillusion = 852274 // added by zibi
endglobals
endlibrary
//===============================================
// Player Resources Monitoring ver 1.01
// fires an event when gold/lumber has changed
// Use Event: "Game PRM_EVENT becomes Equal to 1.00" to detect gold changes
// Use Event: "Game PRM_EVENT becomes Equal to 2.00" to detect lumber changes
// Use "PRM_Player" to filter who's resource changed
// "PRM_Change" is the amount of gold (or lumber) player gain or lose on event
// (can be positive or negative).
// If boolean "PRM_MonitorPlayer[gui-player-number]" is set to false then corresponding
// player will not be monitored, anyway by default all (16) players are monitored.
// If you want to add/subtract/set resource *inside* PRM_EVENT trigger then:
// 1. set boolean "PRM_FireEvent" to false
// 2. add/subtract/set resource
// 3. set boolean "PRM_FireEvent" to true
// --------------------------------------
// happy mapping;] ZibiTheWand3r3r
//================================================
function PRM_Monitor takes nothing returns boolean
local player p = GetTriggerPlayer()
local integer id = GetPlayerId(p)
local integer g = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
local integer l = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
if not udg_PRM_MonitorPlayer[id+1] then // keep up-to date player's resources:
set udg_PRM_GoldLevel[id] = g
set udg_PRM_LumberLevel[id] = l
return false
endif
set udg_PRM_Player = p
if g != udg_PRM_GoldLevel[id] then //gold change detected
set udg_PRM_Change = g - udg_PRM_GoldLevel[id]
set udg_PRM_GoldLevel[id] = g
if udg_PRM_FireEvent then
set udg_PRM_EVENT = 0.00
set udg_PRM_EVENT = 1.00
endif
elseif l != udg_PRM_LumberLevel[id] then // lumber change detected
set udg_PRM_Change = l - udg_PRM_LumberLevel[id]
set udg_PRM_LumberLevel[id] = l
if udg_PRM_FireEvent then
set udg_PRM_EVENT = 0.00
set udg_PRM_EVENT = 2.00
endif
endif
return false
endfunction
//================================================
//================================================
function InitTrig_PRM takes nothing returns nothing
local integer id=0
set gg_trg_PRM = CreateTrigger( )
set udg_PRM_EVENT = 0.00
set udg_PRM_Change = 0
set udg_PRM_FireEvent = true
set udg_PRM_Player = Player(0)
loop
set udg_PRM_GoldLevel[id] = GetPlayerState(Player(id), PLAYER_STATE_RESOURCE_GOLD)
set udg_PRM_LumberLevel[id] = GetPlayerState(Player(id), PLAYER_STATE_RESOURCE_LUMBER)
set udg_PRM_MonitorPlayer[id+1] = true // for gui use range: 1-16
call TriggerRegisterPlayerStateEvent(gg_trg_PRM, Player(id), PLAYER_STATE_RESOURCE_GOLD, NOT_EQUAL, 0.00)
call TriggerRegisterPlayerStateEvent(gg_trg_PRM, Player(id), PLAYER_STATE_RESOURCE_GOLD, EQUAL, 0.00)
call TriggerRegisterPlayerStateEvent(gg_trg_PRM, Player(id), PLAYER_STATE_RESOURCE_LUMBER, NOT_EQUAL, 0.00)
call TriggerRegisterPlayerStateEvent(gg_trg_PRM, Player(id), PLAYER_STATE_RESOURCE_LUMBER, EQUAL, 0.00)
set id=id+1
exitwhen id == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(gg_trg_PRM, Condition(function PRM_Monitor))
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
library CustomResources initializer Init uses ORDER, libBuilSite, libWal
/*
CustomResource library requires:
1. Player Resources Monitoring ver 1.01
https://www.hiveworkshop.com/threads/player-resource-monitoring-v1-01.276158/
2. GUI Unit Event by Bribe, version 2.3.0.0
https://www.hiveworkshop.com/threads/gui-unit-event-v2-3-0-0.201641/
3. OrderList
https://www.thehelper.net/threads/order-ids.148097/
Installation:
Copy&Paste unit "DummyTreeChecker" from demo-map. It should have abilities: 'Ahrl' 'Avul' 'Aloc'
Copy&Paste destructable "DummyTree" from demo-map.
Copy&Paste whole category "CustomResources" from demo-map.
Write in "CustomResources" library correct raw Id units and trees you just pasted,
also you may change 2 constant booleans: DEVELOPING_MODE and PRINT_WARNINGS
Prepare 1 harvest ability for *each* custom resource (for normal lumber-also). Base it on 'Ahrl' "Harvest (Ghouls Lumber)"
You must use diffrent harvest ability for each custom resource.
Prepare workers (max99 for each resource), returning-structures (max99 for each resource) and
destructables based on tree (max99 for each resource).
All registered workers should have one harvest ability from this system (set it in ObjectEditor).
If worker is able to harvest more then 1 resource then this ability you set in OE will be default (after training/creating).
All registered Buildings must have ability "Return Lumber" 'Arlm' or "Return Gold and Lumber" 'Argl'
You -->cannot<-- use the same destructable in more then one custom resource.
You can use the same Worker(s) in many custom resources.
You can use the same Building(s) in many custom resources.
"ResourceWOOD" is obligatory trigger. It must exist. Define there all trees that will be harvest-able for lumber.
Next triggers (4 in demo map) are examples. Edit them freely, add new (as many as you want).
Every trigger represents one resource. Follow instruction inside triggers.
Example1: To have only 1 custom resource:
Set ability/workers/structures/destructables in "ResourceWOOD" trigger
Rename "ResourceMUSHROOMS", use "Resource_Number=2" and set ability/workers/structures/destructables.
delete 2 triggers: "ResourceSTONES" and "ResourceICEROCKS". Done.
Example2: To have 4 custom resources:
Set ability/workers/structures/destructables in "ResourceWOOD" trigger
Rename "ResourceMUSHROOMS", "ResourceSTONES", "ResourceICEROCKS". Set ability/workers/structures/destructables
in each trigger. Copy/paste "ResourceICEROCKS" trigger. Change new trigger name. Set "Resource_Number=5" and
set ability/workers/structures/destructables inside this new trigger. Done.
available functions:
AdjustPlayerCustomResource(player p, integer resourceNumber, integer value) returns nothing
GetPlayerCustomResource(player p, integer resourceNumber) returns integer
use negative "value" to subtract or positive to add resource
resourceNumber is an integer used in configuration ResourceXXXX triggers in first line (Set Resource_Number = X)
"Custom resource was delivered EVENT"
look at 'food1' trigger as point of reference,
use as event "Resource_Event" becomes equal to X, where X is Resource_Number defined in triggers "ResourceNAME"
variables available inside trigger: "Resource_Player" - owner who recieved resource nr X, value is: "Resource_Value"
In game: to change workers ability to harvest diffrent resource-type:
right-click on resource (left-click and order "harvest" targeted on new destructable-type is blocked)
Additionaly library "CustomResource" offers boolean variable that returns true for building under construction. Use like this:
if CustomResources_isBuildingUnderConstruction[Custom Value of Unit] then ...
*/
globals
private constant integer DUMMY_TREE_CHECKER = 'h006' // used to check if destructable is a tree
// copy from demo map, should have: 'Ahrl' 'Avul' 'Aloc'
private constant integer DUMMY_TREE = 'B000' // copy from demo map
private constant boolean DEVELOPING_MODE = false // prints messages for checking system
private constant boolean PRINT_WARNINGS = true // prints "returning building not found" & "unit cannot harvest this destructable"
public hashtable g_hashCR
private integer array g_harvestAbility
public integer g_customResourcesCount=0
private unit g_unitTreeChecker=null
private real array g_timeStampLastLumberRecived // [player id]
private integer array g_lastLumberRecivedValue // [player id]
private timer g_stopWorkerTimer = CreateTimer()
private timer g_gameTimer = CreateTimer()
private group g_workerToStopGroup = CreateGroup()
private integer array g_workerHarvestAbi // [GetUnitUserData(u)]
private unit g_closestStructure = null
private unit g_returningWorker = null
private real g_tempDistance2 = 0.00
private group array g_deliveryStructureGroup
private destructable array g_connectedDummyTree // [structure's UnitUserData]
boolean array isBuildingUnderConstruction // [GetUnitUserData(u)]
private trigger g_trg_WorkerBringsResources = CreateTrigger()
private trigger g_trg_ResumeharvestingRedirect = CreateTrigger()
private trigger g_trg_DummyTreeDies = CreateTrigger()
endglobals
//=============================================================
private function OnConstruct_Start_Cond takes nothing returns boolean
set isBuildingUnderConstruction[GetUnitUserData(GetConstructingStructure())]=true
return false
endfunction
private function OnConstruct_Finish_Cond takes nothing returns boolean
set isBuildingUnderConstruction[GetUnitUserData(GetConstructedStructure())]=false
return false
endfunction
private function OnBuilding_Enters_Cond takes nothing returns boolean
if IsUnitType(udg_UDexUnits[udg_UDex], UNIT_TYPE_STRUCTURE) then
set isBuildingUnderConstruction[udg_UDex]=false
endif
return false
endfunction
//=============================================================
private function InitSettingGUIVariables takes nothing returns nothing // run at init
local integer x=1
loop
exitwhen x>99
set udg_Resource_Worker[x]=0
set udg_Resource_Destructable[x]=0
set udg_Resource_Structure[x]=0
set x=x+1
endloop
endfunction
//---------------------------------------------------------------------------------------
private function InitResource_SaveWorkers takes nothing returns nothing
local integer x=1
loop
exitwhen udg_Resource_Worker[x]==0 or x>99
call SaveInteger(g_hashCR, udg_Resource_Ability, 100+x, udg_Resource_Worker[x]) // remember 1st worker "id" at 101 key
call SaveBoolean(g_hashCR, udg_Resource_Worker[x], 410, true) // save "true" as sign that worker is registered in this system
set x=x+1
endloop
// abilityId as a parentKey , 420 -- abilityId Number (integer)
call SaveInteger(g_hashCR, udg_Resource_Ability, 420, udg_Resource_Number)
//save total workers quantity at "100 key" for this ability
call SaveInteger(g_hashCR, udg_Resource_Ability, 100, x-1)
//reset:
loop
exitwhen x==0
set udg_Resource_Worker[x]=0
set x=x-1
endloop
endfunction
//--------------------------------------------------------------------------------
private function InitResource_SaveDestructables takes nothing returns nothing
local integer x=1
loop
exitwhen udg_Resource_Destructable[x]==0 or x>99
call SaveInteger(g_hashCR, udg_Resource_Ability, 200+x, udg_Resource_Destructable[x]) // remember 1st destruct at 201 key
call SaveInteger(g_hashCR, udg_Resource_Destructable[x], 400, udg_Resource_Ability) // remember abiID to harvest this destr
call SaveBoolean(g_hashCR, udg_Resource_Destructable[x], 401, true) // for IsDestructableRegistered
set x=x+1
endloop
//save total destructables quantity at "200 key" for this ability
call SaveInteger(g_hashCR, udg_Resource_Ability, 200, x-1)
//reset:
loop
exitwhen x==0
set udg_Resource_Destructable[x]=0
set x=x-1
endloop
endfunction
//--------------------------------------------------------------------------------
private function InitResource_SaveStructures takes nothing returns nothing
local integer x=1
loop
exitwhen udg_Resource_Structure[x]==0 or x>99
call SaveInteger(g_hashCR, udg_Resource_Ability, 300+x, udg_Resource_Structure[x]) // remember 1st structure at 301 key
call SaveBoolean(g_hashCR, udg_Resource_Structure[x], 430, true) // saves boolean for registered structures
set x=x+1
endloop
//save total structures quantity at "300 key" for this ability
call SaveInteger(g_hashCR, udg_Resource_Ability, 300, x-1)
//reset:
loop
exitwhen x==0
set udg_Resource_Structure[x]=0
set x=x-1
endloop
endfunction
//--------------------------------------------------------------------------------
function InitResource takes nothing returns nothing
set g_harvestAbility[udg_Resource_Number] = udg_Resource_Ability
if udg_Resource_Number > g_customResourcesCount then
set g_customResourcesCount = udg_Resource_Number
endif
set g_deliveryStructureGroup[udg_Resource_Number] = CreateGroup()
call InitResource_SaveWorkers()
call InitResource_SaveDestructables()
call InitResource_SaveStructures()
endfunction
//=============================================================
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
/*
HASHTABLE KEYS
abilityId as a parentKey
100 -- workers quantity
101--199 - workers Id's
abilityId as a parentKey
200 -- destructables quantity
201--299 - destructables Id's
abilityId as a parentKey
300 -- structures quantity
301--399 - structures Id's
400 -- destructableId as parentKey --> remembers abilityId to harvest this destructabe
call SaveInteger(g_hashCR, destructableId, 400, abi) // remember abiID to harvest this destr
set abi = LoadInteger(g_hashCR, destructableId, 400) //-- > gives abi id
401 -- destructableId as parentKey --> remembers boolean true as sign that structure is registered in system
call SaveBoolean(g_hashCR, destructableId, 401, true)
if LoadBoolean(g_hashCR, destructableId, 401) then ...
410 -- workerId as parentKey -- > saves boolean true for registered workers in this system
call SaveBoolean(g_hashCR, workerId, 410, true)
if LoadBoolean(g_hashCR, workerId, 410) then ...
abilityId as a parentKey
420 -- abilityId Number (integer)
430 -- structureId as parentKey -- > saves boolean true for registered structures in this system
call SaveBoolean(g_hashCR, structureId, 430, true)
if LoadBoolean(g_hashCR, structureId, 430) then ...
abilityId as a parentKey
500--511 - each players resource value
//for Addon
601 -- units/structure/research/upgradeBuilding ID as parentKey -- > saves boolean true for registered objects for prices purposes
call SaveBoolean(g_hashCR, objectId, 601, true)
if LoadBoolean(g_hashCR, objectId, 601) then ...
602 .. and up for prices -- object ID as parent key
*/
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
function IsTree takes destructable d returns boolean
return (IssueTargetOrderById(g_unitTreeChecker, ORDER_harvest, d)) and (IssueImmediateOrderById(g_unitTreeChecker, ORDER_stop))
endfunction
//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
// is harvest allowed by ability worker currently has:
//------------------------------------------------------------------------------------
private function IsHarvestAllowed takes unit u, integer destructableId returns boolean
local integer x=1
local integer abi = g_workerHarvestAbi[GetUnitUserData(u)] // ability unit has to harvest
local integer count = LoadInteger(g_hashCR, abi, 200) // gives total number of destructables quantity at 200 key
loop
exitwhen x>count
if LoadInteger(g_hashCR, abi, 200+x) == destructableId then
return true
endif
set x=x+1
endloop
return false
endfunction
//----------------------------------------------------------------------------------
// can worker change ability to new one
//----------------------------------------------------------------------------------
private function IsAbilityAllowedForWorker takes integer abi, integer workerId returns boolean
local integer x=1
local integer count = LoadInteger(g_hashCR, abi, 100) // total number of workers at 100 key
loop
exitwhen x>count
if LoadInteger(g_hashCR, abi, 100+x) == workerId then
return true
endif
set x=x+1
endloop
return false
endfunction
//----------------------------------------------------------------------------------
private function ChangeAbilityToHarvestDestructable takes unit u, integer destructableId returns boolean
local integer abi = LoadInteger(g_hashCR, destructableId, 400) //-- > gives abiId able to harvest given destructable
local integer x=1
if abi>0 and IsAbilityAllowedForWorker(abi, GetUnitTypeId(u)) then //can unit have this abi?
call AddUnitAnimationProperties(u, "Lumber", false)
set g_workerHarvestAbi[GetUnitUserData(u)] = abi
loop //remove ALL other harvest abils
exitwhen x>g_customResourcesCount
call UnitRemoveAbility(u, g_harvestAbility[x])
set x=x+1
endloop
call UnitAddAbility(u, abi)
return true
endif
return false
endfunction
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
private function IsWorkerRegistered takes integer workerId returns boolean
return LoadBoolean(g_hashCR, workerId, 410)
endfunction
//----------------------------------------------------------------------------------
private function IsDestructableRegistered takes integer destructableId returns boolean
return LoadBoolean(g_hashCR, destructableId, 401)
endfunction
//----------------------------------------------------------------------------------
private function IsStructureRegistered takes integer structureId returns boolean
return LoadBoolean(g_hashCR, structureId, 430)
endfunction
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
// returns udg_Resource_Number set up at ResourceXXXXX triggers by user
private function GetHarvestAbilityNumber takes integer workerCurentAbi returns integer
return LoadInteger(g_hashCR, workerCurentAbi, 420)
endfunction
//-----------------------------------------------------------------------------------------------------------
//------------------------------DELIVERY STRUCTURES---------------------------------------------------
//-----------------------------------------------------------------------------------------------------------
private function RemoveDeliveryStructureFromAllGroups takes unit structure returns nothing
local integer c=1
loop //loop over all groups
exitwhen c>g_customResourcesCount
call GroupRemoveUnit(g_deliveryStructureGroup[c], structure)
set c=c+1
endloop
endfunction
//----------------------------------------------------------------------------------
private function AddDeliveryStructureToGroups takes unit structure returns nothing
local integer structureId = GetUnitTypeId(structure)
local integer abi
local integer count
local integer x
local integer c=1
loop //loop over all harvest abiliies
exitwhen c>g_customResourcesCount
//inside loop begin
set abi = g_harvestAbility[c]
set count = LoadInteger(g_hashCR, abi, 300) // total number of structures for this abi (at 300 key)
set x=1
loop
exitwhen x>count
if LoadInteger(g_hashCR, abi, 300+x) == structureId then
call GroupAddUnit(g_deliveryStructureGroup[c], structure)
endif
set x=x+1
endloop
//inside loop end
set c=c+1
endloop
endfunction
//----------------------------------------------------------------------------------
private function IsDeliveryStructureValid takes unit u, unit structure returns boolean
local integer abi = g_workerHarvestAbi[GetUnitUserData(u)] // current worker's ability to harvest
local integer nr = GetHarvestAbilityNumber(abi)
return IsUnitInGroup(structure, g_deliveryStructureGroup[nr])
endfunction
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
//this not for a user:
private function AdjustPlayerCustomResource_ByAbility takes integer playerId, integer abi, integer value returns nothing
local integer currentValue = LoadInteger(g_hashCR, abi, 500+playerId)
call SaveInteger(g_hashCR, abi, 500+playerId, currentValue+value)
//abilityId as a parentKey
//500--511 - each players resource value
endfunction
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
//for user:
//use negative "value" to subtract or positive to add resource
function AdjustPlayerCustomResource takes player p, integer resourceNumber, integer value returns nothing
call AdjustPlayerCustomResource_ByAbility(GetPlayerId(p), g_harvestAbility[resourceNumber], value)
endfunction
//----------------------------------------------------------------------------------
//for user:
function GetPlayerCustomResource takes player p, integer resourceNumber returns integer
local integer abi = g_harvestAbility[resourceNumber]
return LoadInteger(g_hashCR, abi, 500+GetPlayerId(p))
endfunction
//===========================================================================
//===========================================================================
//-------------------------------TRIGGERS RELATED FUNCTIONS--------------------------------------------------------------
//===========================================================================
//===========================================================================
private function Trig_LumberChanged takes nothing returns nothing // "udg_PRM_EVENT", EQUAL, 2.00
local integer i = GetPlayerId(udg_PRM_Player)
if udg_PRM_Change > 0 then
//it fires as 1st, after this - "order harvest" (or other) runs
//remember time-stamp for this player and value:
set g_timeStampLastLumberRecived[i] = TimerGetElapsed(g_gameTimer)
set g_lastLumberRecivedValue[i] = udg_PRM_Change
if DEVELOPING_MODE then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "(PRM) time stamp: " + R2S(TimerGetElapsed(g_gameTimer)))
endif
endif
endfunction
//===========================================================================
// this is an EVENT "worker brings resources"
// we got unit "u", g_lastLumberRecivedValue[playerId], and g_workerHarvestAbi[GetunitUserData(u)] - integer abiId
private function Trig_WorkerBringsResources_Cond takes nothing returns boolean
//if peasant recive ANY order like: harvest dummyTree, harvest normal resources ,
//or player queued any order (stop, attack, move, etc) then:
if TimerGetElapsed(g_gameTimer) == g_timeStampLastLumberRecived[GetPlayerId(GetOwningPlayer(GetOrderedUnit()))] then
return IsWorkerRegistered(GetUnitTypeId(GetOrderedUnit()))
// ordered unit is 'last lumber supplier'
endif
return false
endfunction
//------------------------------------------------------------------------------------
private function Trig_WorkerBringsResources_Act takes nothing returns nothing
local unit u = GetOrderedUnit()
local player pla = GetOwningPlayer(u)
local integer i = GetPlayerId(pla)
local integer abi = g_workerHarvestAbi[GetUnitUserData(u)]
local integer resourceNr = GetHarvestAbilityNumber(abi) // new <---
if not (abi == g_harvestAbility[1]) then // it is *custom resource* - subtract from normal wood!
set udg_PRM_FireEvent = false
call SetPlayerState(pla, PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState(pla, PLAYER_STATE_RESOURCE_LUMBER)-g_lastLumberRecivedValue[i])
set udg_PRM_FireEvent = true
call AdjustPlayerCustomResource_ByAbility(i, abi, g_lastLumberRecivedValue[i]) // writes value in hash
endif
if DEVELOPING_MODE then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, GetUnitName(u) + " brings resource nr(" + I2S(GetHarvestAbilityNumber(abi)) +"), value: " + I2S(g_lastLumberRecivedValue[i]) + ", time stamp: " + R2S(TimerGetElapsed(g_gameTimer)))
endif
set udg_Resource_Player = pla
set udg_Resource_Value = g_lastLumberRecivedValue[i]
set udg_Resource_Event = 0.00
set udg_Resource_Event = I2R(resourceNr)
set udg_Resource_Event = 0.00
set udg_Resource_Player = null
set udg_Resource_Value = 0
set u=null
set pla=null
endfunction
//===========================================================================
private function StopWorker_Enum takes nothing returns nothing
call IssueImmediateOrderById(GetEnumUnit(), ORDER_stop)
call GroupRemoveUnit(g_workerToStopGroup, GetEnumUnit())
endfunction
private function StopWorker takes nothing returns nothing
call DisableTrigger(g_trg_WorkerBringsResources) // protect agains double fire "worker brings resource" event
call ForGroup(g_workerToStopGroup, function StopWorker_Enum)
call EnableTrigger(g_trg_WorkerBringsResources)
endfunction
//--------------------------------------------------------------------------------
private function Trig_HarvestSmartOffset_Cond takes nothing returns boolean
local integer ord=GetIssuedOrderId() // ORDER_OFFSET when building right-cick on destructable and trained worker start walking
if ord==ORDER_harvest or ord==ORDER_smart or ord==ORDER_OFFSET then // 851970
return GetOrderTargetDestructable() != null and IsWorkerRegistered(GetUnitTypeId(GetOrderedUnit()))
endif
return false
endfunction
//--------------------------------------------------------------------------------
private function Trig_HarvestSmartOffset_Act takes nothing returns nothing
local unit u = GetOrderedUnit()
local integer destructableId = GetDestructableTypeId(GetOrderTargetDestructable())
local integer ord = GetIssuedOrderId()
if ord==ORDER_harvest and (not IsHarvestAllowed(u, destructableId)) then
// does current ability allow to harvest this destr? if no, then stop worker
call GroupAddUnit(g_workerToStopGroup, u)
call TimerStart(g_stopWorkerTimer, 0.00, false, function StopWorker)
endif
// 851970 --> when worker trained with rally-point set up on tree
// 851970 or "smart" order --> need to change ability harvest for diffrent destructables
if (ord==ORDER_smart or ord==ORDER_OFFSET) and IsTree(GetOrderTargetDestructable()) then
if (not IsHarvestAllowed(u, destructableId)) then
if not ChangeAbilityToHarvestDestructable(u, destructableId) then
if PRINT_WARNINGS then
call DisplayTextToPlayer(GetOwningPlayer(u), 0, 0, GetUnitName(u) + " |cffff0000cannot|r harvest " + GetDestructableName(GetOrderTargetDestructable()))
endif
call GroupAddUnit(g_workerToStopGroup, u)
call TimerStart(g_stopWorkerTimer, 0.00, false, function StopWorker)
endif
endif
endif
set u=null
endfunction
//===========================================================================
private function FindClosestStructure_Enum takes nothing returns nothing
local unit u = GetEnumUnit()
local real dx = GetUnitX(g_returningWorker)-GetUnitX(u)
local real dy = GetUnitY(g_returningWorker)-GetUnitY(u)
local real dist2 = SquareRoot(dx * dx + dy * dy)
if GetOwningPlayer(u)==GetOwningPlayer(g_returningWorker) and (not isBuildingUnderConstruction[GetUnitUserData(u)]) then
if dist2 < g_tempDistance2 then
set g_tempDistance2 = dist2
set g_closestStructure = u
endif
endif
set u=null
endfunction
//-----------------------------------------------------------------------------
private function FindClosestStructure takes unit worker returns nothing
local integer id = GetUnitUserData(worker)
local integer nr = GetHarvestAbilityNumber(g_workerHarvestAbi[id])
set g_tempDistance2 = 999999.00
set g_closestStructure = null
set g_returningWorker = worker
call ForGroup(g_deliveryStructureGroup[nr], function FindClosestStructure_Enum)
endfunction
//-----------------------------------------------------------------------------
private function Trig_ResumeharvestingRedirect_Cond takes nothing returns boolean
return GetIssuedOrderId()==ORDER_resumeharvesting and IsWorkerRegistered(GetUnitTypeId(GetOrderedUnit()))
endfunction
//-----------------------------------------------------------------------------
// when button "return resources" clicked OR auto come-back with resources
private function Trig_ResumeharvestingRedirect_Act takes nothing returns nothing
local unit u = GetOrderedUnit()
local integer id = GetUnitUserData(u)
call FindClosestStructure(u) // it writes global "g_closestStructure" as a valid building to deliver resources
if g_closestStructure != null then
call DisableTrigger(g_trg_ResumeharvestingRedirect) // this trigger
if IssueTargetOrderById(u, ORDER_resumeharvesting, g_closestStructure) and DEVELOPING_MODE then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Redirecting " + GetUnitName(u) + " to " + GetUnitName(g_closestStructure))
endif
call EnableTrigger(g_trg_ResumeharvestingRedirect)
else //no valid structure..
if PRINT_WARNINGS then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, GetUnitName(u) + ": |cffffff00 No proper building found to return. |r")
endif
call GroupAddUnit(g_workerToStopGroup, u)
call TimerStart(g_stopWorkerTimer, 0.00, false, function StopWorker)
endif
set u=null
endfunction
//===========================================================================
private function Trig_ReturnSmartRestrictions_Cond takes nothing returns boolean
if libWal_SmartOrderOnWalkableBuilding_Conditions() then // WallSystemOLD , line 3118
return false
elseif libBuilSite_SmartOrderOnBuildingSite_Conditions() then // BuildingSiteSystem , line 1514
return false
elseif GetIssuedOrderId() == ORDER_smart then
if GetOrderTargetUnit() != null and IsWorkerRegistered(GetUnitTypeId(GetOrderedUnit())) then
return GetOwningPlayer(GetOrderedUnit()) == GetOwningPlayer(GetOrderTargetUnit())
endif
endif
return false
endfunction
//-------------------------------------------------------------------------------------
//if player give order "smart" on Worker and if building is not valid to take resources then convert smart-->move order
private function Trig_ReturnSmartRestrictions_Act takes nothing returns nothing
local unit u = GetOrderedUnit()
local unit target = GetOrderTargetUnit()
//check if worker is returning resources (it may also be order repair/finish construction)
call DisableTrigger(g_trg_ResumeharvestingRedirect)
if IssueTargetOrderById(u, ORDER_resumeharvesting, target) then //he has resources
if (not IsDeliveryStructureValid(u, target)) then
call IssueTargetOrderById(u, ORDER_move, target)
endif
endif
call EnableTrigger(g_trg_ResumeharvestingRedirect)
set u=null
set target=null
endfunction
//===========================================================================
private function Trig_WorkerStructureCreated_Cond takes nothing returns boolean
local integer unitId = GetUnitTypeId(udg_UDexUnits[udg_UDex])
return IsStructureRegistered(unitId) or IsWorkerRegistered(unitId)
endfunction
//------------------------------------------------------------------------------------
private function Trig_WorkerStructureCreated_Act takes nothing returns nothing
local integer x=1
local integer unitId = GetUnitTypeId(udg_UDexUnits[udg_UDex])
if IsStructureRegistered(unitId) then //BUILDING CREATED:
//find x/y for DummyTree : item (Wirt's Leg) version
set bj_lastCreatedItem = CreateItem('wtlg', GetUnitX(udg_UDexUnits[udg_UDex]), GetUnitY(udg_UDexUnits[udg_UDex]))
set g_connectedDummyTree[udg_UDex] = CreateDestructable(DUMMY_TREE, GetItemX(bj_lastCreatedItem), GetItemY(bj_lastCreatedItem), 0.00, 1, 0)
call RemoveItem(bj_lastCreatedItem)
call TriggerRegisterDeathEvent(g_trg_DummyTreeDies, g_connectedDummyTree[udg_UDex]) //add event to DummyTreeDies
call AddDeliveryStructureToGroups(udg_UDexUnits[udg_UDex]) //add to delivery group
elseif IsWorkerRegistered(unitId) then //WORKER CREATED:
//------------------------------------------------------------------------------
// all registered workers should have one harvest ability from this system (set in OE)
//-----------------------------------------------------------------------------
loop
exitwhen x>g_customResourcesCount // loop over all harvest abilities and set variable
if GetUnitAbilityLevel(udg_UDexUnits[udg_UDex], g_harvestAbility[x])>0 then
set g_workerHarvestAbi[udg_UDex] = g_harvestAbility[x]
return
endif
set x=x+1
endloop
endif
endfunction
//===========================================================================
private function Trig_StructureUpgraded_Act takes nothing returns nothing // runs when structure *finishes* upgrade
call RemoveDeliveryStructureFromAllGroups(udg_UDexUnits[udg_UDex]) //remove from groups
if IsStructureRegistered(GetUnitTypeId(udg_UDexUnits[udg_UDex])) then // is upgraded building registered?
call AddDeliveryStructureToGroups(udg_UDexUnits[udg_UDex]) // add this new upgraded building
//if connected dummy TREE is dead/none (means previous structure was not registered)
if g_connectedDummyTree[udg_UDex]==null or GetDestructableLife(g_connectedDummyTree[udg_UDex]) <= 0 then
//find x/y for DummyTree : item version
set bj_lastCreatedItem = CreateItem('wtlg', GetUnitX(udg_UDexUnits[udg_UDex]), GetUnitY(udg_UDexUnits[udg_UDex]))
set g_connectedDummyTree[udg_UDex] = CreateDestructable(DUMMY_TREE, GetItemX(bj_lastCreatedItem), GetItemY(bj_lastCreatedItem), 0.00, 1, 0)
call RemoveItem(bj_lastCreatedItem)
call TriggerRegisterDeathEvent(g_trg_DummyTreeDies, g_connectedDummyTree[udg_UDex]) //add event to DummyTreeDies
endif
else // New (upgraded) structure is not registered --> remove connected dummy TREE
call RemoveDestructable(g_connectedDummyTree[udg_UDex])
endif
endfunction
//===========================================================================
private function Trig_RegisteredStructureDies_Cond takes nothing returns boolean
if IsStructureRegistered(GetUnitTypeId(GetDyingUnit())) then
call RemoveDeliveryStructureFromAllGroups(GetDyingUnit()) //remove from all groups
call RemoveDestructable(g_connectedDummyTree[GetUnitUserData(GetDyingUnit())]) //remove connected dummy TREE
endif
return false
endfunction
//===========================================================================
private function Trig_DummyTreeDies_Actions takes nothing returns nothing
call DestructableRestoreLife(GetDyingDestructable(), GetDestructableMaxLife(GetDyingDestructable()), false) //resurect
endfunction
//===========================================================================
//===========================================================================
//===========================================================================
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i=0
loop
set g_timeStampLastLumberRecived[i] = 0.00
set i=i+1
exitwhen i==bj_MAX_PLAYERS //12
endloop
set udg_Resource_Event = 0.00
set g_hashCR = InitHashtable()
call TimerStart(g_gameTimer, 36000.00, false, null)
call InitSettingGUIVariables()
set udg_UnitIndexerEnabled = false
set g_unitTreeChecker = CreateUnit(Player(15), DUMMY_TREE_CHECKER, 0.00, 0.00, 0.00)
set udg_UnitIndexerEnabled = true
call ShowUnit(g_unitTreeChecker, false)
//--------for isBuildingUnderConstruction check [GetUnitUserData(u)] ------------
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_CONSTRUCT_START)
call TriggerAddCondition(t, Condition(function OnConstruct_Start_Cond))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH)
call TriggerAddCondition(t, Condition(function OnConstruct_Finish_Cond))
set t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 1.00)
call TriggerAddCondition(t, Condition(function OnBuilding_Enters_Cond))
//----for lumber changed trigger -----------------------------------------------------
set t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_PRM_EVENT", EQUAL, 2.00)
call TriggerAddAction(t, function Trig_LumberChanged)
//-----------for worker-brings-resources event --------------------------------------
call TriggerRegisterAnyUnitEventBJ(g_trg_WorkerBringsResources, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerRegisterAnyUnitEventBJ(g_trg_WorkerBringsResources, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
call TriggerRegisterAnyUnitEventBJ(g_trg_WorkerBringsResources, EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerAddCondition(g_trg_WorkerBringsResources, Condition(function Trig_WorkerBringsResources_Cond))
call TriggerAddAction(g_trg_WorkerBringsResources, function Trig_WorkerBringsResources_Act)
// ----------harvest destructable, orders: harvest/smart/offset ---------------------
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(t, Condition(function Trig_HarvestSmartOffset_Cond))
call TriggerAddAction(t, function Trig_HarvestSmartOffset_Act)
//------ for order resumeharvesting -> redirect -------------------------------------
call TriggerRegisterAnyUnitEventBJ(g_trg_ResumeharvestingRedirect, EVENT_PLAYER_UNIT_ISSUED_ORDER) // when button "return resources" clicked
call TriggerRegisterAnyUnitEventBJ(g_trg_ResumeharvestingRedirect, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER) // auto come-back
call TriggerAddCondition(g_trg_ResumeharvestingRedirect, Condition(function Trig_ResumeharvestingRedirect_Cond))
call TriggerAddAction(g_trg_ResumeharvestingRedirect, function Trig_ResumeharvestingRedirect_Act)
// if player give order "smart" on Worker and if building is not valid to take resources then convert smart-->move order
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(t, Condition( function Trig_ReturnSmartRestrictions_Cond))
call TriggerAddAction(t, function Trig_ReturnSmartRestrictions_Act)
// worker / building created -----------------------------------------------------------
set t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 1.00)
call TriggerAddCondition(t, Condition( function Trig_WorkerStructureCreated_Cond))
call TriggerAddAction(t, function Trig_WorkerStructureCreated_Act)
// building transformed (upgraded) ---------------------------------------------------
set t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_UnitTypeEvent", EQUAL, 1.00)
call TriggerAddAction(t, function Trig_StructureUpgraded_Act)
// building dies ------------------------------------------------------------------------
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(t, Condition( function Trig_RegisteredStructureDies_Cond))
// dummy tree dies -------------------------------------------------------------------
set g_trg_DummyTreeDies = CreateTrigger()
call TriggerAddAction(g_trg_DummyTreeDies, function Trig_DummyTreeDies_Actions)
set t=null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
//=========================================================
library CustomResourcesCosts initializer Init uses CustomResources
//------------------------------------------------------------------------------------------------
globals
private constant boolean PRINT_WARNING = true
private group g_groupCancel = CreateGroup()
private timer g_timerCancel = CreateTimer()
private integer array g_upgradeTarget
private constant string GREEN = "|cff00ff00"
private constant string RED = "|cffff0000"
trigger g_triggerMultiOrderCancel = CreateTrigger()
endglobals
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
/*
//for Addon
601 -- units/structure/research/upgradeBuilding ID as parentKey -- >
saves boolean true for registered objects for prices purposes
call SaveBoolean(g_hashCR, objectId, 601, true)
if LoadBoolean(g_hashCR, objectId, 601) then ...
602 .. and up - for prices -- object ID as parent key
*/
function CustomResource_SaveCosts takes nothing returns nothing
local integer x=2 // we do not start from "1" as 1 is normal-wood
local integer parentKey
//is it object or research?
if udg_Resource_CostUnit>0 then
set parentKey = udg_Resource_CostUnit
elseif udg_Resource_CostResearch>0 then
set parentKey = udg_Resource_CostResearch
endif
call SaveBoolean(CustomResources_g_hashCR, parentKey, 601, true) // save "true" as sign that object is registered
loop
exitwhen x>CustomResources_g_customResourcesCount
call SaveInteger(CustomResources_g_hashCR, parentKey, 600+x, udg_Resource_Cost[x])
// remember resource2 cost at 602 key, resource3 at 603 key, .. etc
//reset for next object:
set udg_Resource_Cost[x] = 0
set x=x+1
endloop
//reset integers:
set udg_Resource_CostUnit = 0
set udg_Resource_CostResearch = 0
endfunction
//------------------------------------------------------------------------------------------------
function IsCustomCostDefined takes integer objectId returns boolean // object: unit/structure/upgrade-building/research
return LoadBoolean(CustomResources_g_hashCR, objectId, 601)
endfunction
//------------------------------------------------------------------------------------------------
function GetObjectCost takes integer objectId, integer resourceNumber returns integer
// resourceNumber = defined in ResourceMUSHROOM and so on triggers, as udg_Resource_Number
// will not return value for resourceNumber=1 as it is normal war3 wood!
return LoadInteger(CustomResources_g_hashCR, objectId, 600+resourceNumber)
endfunction
//=========================================================
//------------------------TRIGGERS RELATED---------------------------------------------------
//=========================================================
//------------------------------------------------------------------------------
function CancelOrder_Enum takes nothing returns nothing
local unit u = GetEnumUnit()
call GroupRemoveUnit(g_groupCancel, u)
call IssueImmediateOrderById(u, 851976) //upgrades , researches , trains
call IssueImmediateOrderById(u, ORDER_stop) //for builders
set u=null
endfunction
function CancelOrder takes nothing returns nothing
call DisableTrigger(g_triggerMultiOrderCancel)
call ForGroup(g_groupCancel, function CancelOrder_Enum)
call EnableTrigger(g_triggerMultiOrderCancel)
endfunction
function UnitCancelOrder takes unit u returns nothing
call GroupAddUnit(g_groupCancel, u)
call TimerStart(g_timerCancel, 0.00, false, function CancelOrder)
endfunction
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
function PlayerHasMoneyForObject takes player pla, integer objectId returns boolean
local integer x=2
local integer cost=0
local string s = " "
local boolean hasMoney = true
loop
exitwhen x>CustomResources_g_customResourcesCount
set cost = GetObjectCost(objectId, x)
if cost>0 then
if cost <= GetPlayerCustomResource(pla, x) then
set s = s + (GREEN+udg_Resource_Name[x] + "|r(" + I2S(cost) + ") ") // green color
else // not enough resource nr x
set hasMoney=false
set s = s + (RED+udg_Resource_Name[x] + "|r(" + I2S(cost) + ") ") // red color
endif
endif
set x=x+1
endloop
if (not hasMoney) and PRINT_WARNING then
call DisplayTextToPlayer(pla, 0.00, 0.00, "Not enough resources: " + s)
endif
return hasMoney
endfunction
//-------------------------------------------------------------------------------------------
function PlayerPayPriceForObject takes player pla, integer objectId returns nothing
local integer x=2
local integer cost=0
loop
exitwhen x>CustomResources_g_customResourcesCount
set cost = GetObjectCost(objectId, x)
if cost>0 then
call AdjustPlayerCustomResource(pla, x, - cost)
//event
set udg_Resource_Player = pla
set udg_Resource_Value = -cost
set udg_Resource_Event = 0.00
set udg_Resource_Event = I2R(x)
set udg_Resource_Event = 0.00
set udg_Resource_Player = null
set udg_Resource_Value = 0
endif
set x=x+1
endloop
endfunction
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
function Trig_MultiOrder_Cond takes nothing returns boolean
return IsCustomCostDefined(GetIssuedOrderId())
endfunction
//------------------------------------------------------------------------------
function Trig_MultiOrder_Act takes nothing returns nothing
local integer h = GetHandleId(GetTriggerEventId())
local unit u = GetOrderedUnit()
local player pla = GetOwningPlayer(u)
local integer ord = GetIssuedOrderId()
local integer id = GetUnitUserData(u)
if h==38 then // instant: TRAIN UNIT or RESEARCH or UPGRADE
//call BJDebugMsg("cost2: " + I2S(GetObjectCost(ord, 2)) + ", cost3: " + I2S(GetObjectCost(ord, 3)) + ", cost4: " + I2S(GetObjectCost(ord, 4)))
if not PlayerHasMoneyForObject(pla, ord) then //no $$$ ?
call UnitCancelOrder(u)
else //has $?, pay price:
set g_upgradeTarget[id] = ord //if it is UPGRADE save target-building (ord) as variable under number id
call PlayerPayPriceForObject(pla, ord)
endif
elseif h==39 and (UnitId2String(ord) != null) then // point-order: BUILD STRUCTURE
//call BJDebugMsg("cost2: " + I2S(GetObjectCost(ord, 2)) + ", cost3: " + I2S(GetObjectCost(ord, 3)) + ", cost4: " + I2S(GetObjectCost(ord, 4)))
if not PlayerHasMoneyForObject(pla, ord) then //no $$$ ?
call UnitCancelOrder(u)
endif // paying is executed under event EVENT_PLAYER_UNIT_CONSTRUCT_START
endif
set u=null
set pla=null
endfunction
//----------------------------------------------------------------------------------
//---------------------------trigger Begins Construction -------------------------
//----------------------------------------------------------------------------------
function Trig_BeginsConstr_Cond takes nothing returns boolean
return IsCustomCostDefined(GetUnitTypeId(GetConstructingStructure()))
endfunction
//------------------------------------------------------------------
function Trig_BeginsConstr_Act takes nothing returns nothing
local unit u = GetConstructingStructure()
local player pla = GetOwningPlayer(u)
local integer objectId = GetUnitTypeId(u)
if not PlayerHasMoneyForObject(pla, objectId) then //no $$$ ?
call UnitCancelOrder(u)
else //has $?, pay price:
call PlayerPayPriceForObject(pla, objectId)
endif
set u=null
set pla=null
endfunction
//---------------------------------------------------------------------------------------------
// --------------------------trigger CANCEL--------------------------------------------------
//---------------------------------------------------------------------------------------------
private function GiveMoneyBackOnCancel takes player pla, integer objectId returns nothing
local integer x=2
local integer cost=0
loop
exitwhen x>CustomResources_g_customResourcesCount
set cost = GetObjectCost(objectId, x)
call AdjustPlayerCustomResource(pla, x, cost)
//event
set udg_Resource_Player = pla
set udg_Resource_Value = cost
set udg_Resource_Event = 0.00
set udg_Resource_Event = I2R(x)
set udg_Resource_Event = 0.00
set udg_Resource_Player = null
set udg_Resource_Value = 0
set x=x+1
endloop
endfunction
//---------------------------------------------------------------------------------------------
private function Trig_MultiOrderCancel_Actions takes nothing returns nothing
local integer h = GetHandleId(GetTriggerEventId())
local unit u = GetTriggerUnit() // the same for all 4 events
local player pla = GetOwningPlayer(u) // the same for all 4 events
local integer objectId
//---------------------------------------------------------------------------
if h==33 then // EVENT_PLAYER_UNIT_TRAIN_CANCEL
set objectId = GetTrainedUnitType()
if IsCustomCostDefined(objectId) then
call GiveMoneyBackOnCancel(pla, objectId)
//call DisplayTextToForce( GetPlayersAll(), GetUnitName(u) + " canceled custom-cost TRAIN" )
endif
//---------------------------------------------------------------------------
elseif h==27 then // EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL
set objectId = GetUnitTypeId(u)
if IsCustomCostDefined(objectId) then
call GiveMoneyBackOnCancel(pla, objectId)
//call DisplayTextToForce( GetPlayersAll(), "canceled custom-cost BUILD" )
endif
//---------------------------------------------------------------------------
elseif h==36 then // EVENT_PLAYER_UNIT_RESEARCH_CANCEL
set objectId = GetResearched()
if IsCustomCostDefined(objectId) then
call GiveMoneyBackOnCancel(pla, objectId)
//call DisplayTextToForce( GetPlayersAll(), "canceled custom-cost research" )
endif
//---------------------------------------------------------------------------
elseif h==30 then // EVENT_PLAYER_UNIT_UPGRADE_CANCEL
set objectId = g_upgradeTarget[GetUnitUserData(u)] // upgrade TARGET building
// (gives Keep - if Keep cancels upgrade and revert itself to TownHall)
if IsCustomCostDefined(objectId) then
call GiveMoneyBackOnCancel(pla, objectId)
//call DisplayTextToForce( GetPlayersAll(), "canceled custom-cost upgrade-building" )
endif
//---------------------------------------------------------------------------
endif
set u=null
set pla=null
endfunction
//=========================================================
//=========================================================
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerAddCondition( t, Condition(function Trig_MultiOrder_Cond))
call TriggerAddAction( t, function Trig_MultiOrder_Act )
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_CONSTRUCT_START )
call TriggerAddCondition( t, Condition( function Trig_BeginsConstr_Cond ) )
call TriggerAddAction( t, function Trig_BeginsConstr_Act )
call TriggerRegisterAnyUnitEventBJ( g_triggerMultiOrderCancel, EVENT_PLAYER_UNIT_TRAIN_CANCEL )
call TriggerRegisterAnyUnitEventBJ( g_triggerMultiOrderCancel, EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL )
call TriggerRegisterAnyUnitEventBJ( g_triggerMultiOrderCancel, EVENT_PLAYER_UNIT_RESEARCH_CANCEL )
call TriggerRegisterAnyUnitEventBJ( g_triggerMultiOrderCancel, EVENT_PLAYER_UNIT_UPGRADE_CANCEL )
call TriggerAddAction( g_triggerMultiOrderCancel, function Trig_MultiOrderCancel_Actions )
set t=null
endfunction
endlibrary
library TerrainPathability initializer Init
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This script can be used to detect the type of pathing at a specific point.
//* It is valuable to do it this way because the IsTerrainPathable is very
//* counterintuitive and returns in odd ways and aren't always as you would
//* expect. This library, however, facilitates detecting those things reliably
//* and easily.
//*
//******************************************************************************
//*
//* > function IsTerrainDeepWater takes real x, real y returns boolean
//* > function IsTerrainShallowWater takes real x, real y returns boolean
//* > function IsTerrainLand takes real x, real y returns boolean
//* > function IsTerrainPlatform takes real x, real y returns boolean
//* > function IsTerrainWalkable takes real x, real y returns boolean
//*
//* These functions return true if the given point is of the type specified
//* in the function's name and false if it is not. For the IsTerrainWalkable
//* function, the MAX_RANGE constant below is the maximum deviation range from
//* the supplied coordinates that will still return true.
//*
//* The IsTerrainPlatform works for any preplaced walkable destructable. It will
//* return true over bridges, destructable ramps, elevators, and invisible
//* platforms. Walkable destructables created at runtime do not create the same
//* pathing hole as preplaced ones do, so this will return false for them. All
//* other functions except IsTerrainWalkable return false for platforms, because
//* the platform itself erases their pathing when the map is saved.
//*
//* After calling IsTerrainWalkable(x, y), the following two global variables
//* gain meaning. They return the X and Y coordinates of the nearest walkable
//* point to the specified coordinates. These will only deviate from the
//* IsTerrainWalkable function arguments if the function returned false.
//*
//* Variables that can be used from the library:
//* [real] TerrainPathability_X
//* [real] TerrainPathability_Y
//*
globals
private constant real MAX_RANGE = 10.
private constant integer DUMMY_ITEM_ID = 'wolg'
endglobals
globals
private item Item = null
private rect Find = null
private item array Hid
private integer HidMax = 0
public real X = 0.
public real Y = 0.
endglobals
function IsTerrainDeepWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
function IsTerrainShallowWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
function IsTerrainLand takes real x, real y returns boolean
return IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY)
endfunction
function IsTerrainPlatform takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
private function HideItem takes nothing returns nothing
if IsItemVisible(GetEnumItem()) then
set Hid[HidMax] = GetEnumItem()
call SetItemVisible(Hid[HidMax], false)
set HidMax = HidMax + 1
endif
endfunction
function IsTerrainWalkable takes real x, real y returns boolean
//Hide any items in the area to avoid conflicts with our item
call MoveRectTo(Find, x, y)
call EnumItemsInRect(Find ,null, function HideItem)
//Try to move the test item and get its coords
call SetItemPosition(Item, x, y) //Unhides the item
set X = GetItemX(Item)
set Y = GetItemY(Item)
static if LIBRARY_IsTerrainWalkable then
//This is for compatibility with the IsTerrainWalkable library
set IsTerrainWalkable_X = X
set IsTerrainWalkable_Y = Y
endif
call SetItemVisible(Item, false)//Hide it again
//Unhide any items hidden at the start
loop
exitwhen HidMax <= 0
set HidMax = HidMax - 1
call SetItemVisible(Hid[HidMax], true)
set Hid[HidMax] = null
endloop
//Return walkability
return (X-x)*(X-x)+(Y-y)*(Y-y) <= MAX_RANGE*MAX_RANGE and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
private function Init takes nothing returns nothing
set Find = Rect(0., 0., 128., 128.)
set Item = CreateItem(DUMMY_ITEM_ID, 0, 0)
call SetItemVisible(Item, false)
endfunction
endlibrary
function Trig_update2_Actions takes nothing returns nothing
local integer i = GetPlayerId(udg_Resource_Player)+1
local integer Clay = GetPlayerCustomResource(udg_Resource_Player, 2)
local integer Stone = GetPlayerCustomResource(udg_Resource_Player, 3)
local integer Ore = GetPlayerCustomResource(udg_Resource_Player, 4)
local integer Gold = GetPlayerCustomResource(udg_Resource_Player, 5)
call LeaderboardSetPlayerItemValueBJ( Player(11), udg_lb[i], Clay)
call LeaderboardSetPlayerItemValueBJ( Player(8), udg_lb[i], Stone)
call LeaderboardSetPlayerItemValueBJ( Player(9), udg_lb[i], Ore)
call LeaderboardSetPlayerItemValueBJ( Player(4), udg_lb[i], Gold)
endfunction
//==============================================================
function InitTrig_update2 takes nothing returns nothing
set gg_trg_update2 = CreateTrigger( )
call TriggerRegisterVariableEvent( gg_trg_update2, "udg_Resource_Event", EQUAL, 2.00 )
call TriggerRegisterVariableEvent( gg_trg_update2, "udg_Resource_Event", EQUAL, 3.00 )
call TriggerRegisterVariableEvent( gg_trg_update2, "udg_Resource_Event", EQUAL, 4.00 )
call TriggerRegisterVariableEvent( gg_trg_update2, "udg_Resource_Event", EQUAL, 5.00 )
call TriggerAddAction( gg_trg_update2, function Trig_update2_Actions )
endfunction
//--------------------------------------------------------------------------------------
library PlantsGrow initializer Init uses TerrainPathability, CustomResources // by ZibiTheWand3r3r. v.1.10 (04-08-2017)
//--------------------------------------------------------------------------------------
// API
// nothing CreatePlant(integer <babyCropId>, integer <matureCropId>, integer <bigCropId>, real <x>, real <y>, real <matureChangeTime>, real <totalGrowTime>)
//
//--------------------------------------------------------------------------------------
globals
//configurable
private constant integer TERRAIN_TYPE_CROPS = 'Vcrp' //VILLAGE-crops, it is a terrain where seeds can be used
private constant integer ABI_PLOW_FARMLAND = 'A05J' //ability to change TERRAIN --> TERRAIN_TYPE_CROPS
private constant integer ITM_SEEDS_WHEAT = 'I000'
private constant integer ITM_SEEDS_TOBACCO = 'I001'
constant real SPREAD_TERRAIN_EDGE_LIMIT = 32.00 // Use lower value to let plants spread seeds closer to the terrain edge and vice versa
constant real CROPS_DENSITY = 128.00 // Use higher value (like 164) to increase distance between plants
//end configurable
//integer ABI_ITM_SEEDS_FAKE = 'A006'//fake item ability
private integer array TERRAIN
private integer array DESTR_WHEAT
private integer array DESTR_TOBACCO //new plant: tobacco ;)
private constant real INTERVAL = 1.00
private integer maxId = 0
private real array instChangeTime
private real array instDuration
private destructable array instDestr
private integer array instDestr1Id
private integer array instDestr2Id
private integer array instDestr3Id
private timer t = CreateTimer()
real g_spreadCenterX //used in trigger trg_spreadSeeds
real g_spreadCenterY
integer array g_spreadId // baby/mature/big destructable id
private trigger trg_spreadSeeds = CreateTrigger()
private rect r_crops
private rect r_crops128
private boolean g_terrainEmpty = true
endglobals
//=========================================================
private function Settings takes nothing returns nothing
set r_crops = Rect(0.00, 0.00, 384.00, 384.00)
set r_crops128 = Rect(0.00, 0.00, CROPS_DENSITY, CROPS_DENSITY)
//save in hash terrain types:
set TERRAIN[1] = 'Adrg' //lordaeron summer -grass, it is a terrain able to change into farmland
call SaveBoolean(CustomResources_g_hashCR, TERRAIN[1], 706, true)
set TERRAIN[2] = 'Alrd'
call SaveBoolean(CustomResources_g_hashCR, TERRAIN[2], 706, true)
set TERRAIN[3] = 'Agrs'
call SaveBoolean(CustomResources_g_hashCR, TERRAIN[3], 706, true)
set TERRAIN[4] = 'Alvd'
call SaveBoolean(CustomResources_g_hashCR, TERRAIN[4], 706, true)
//call SaveBoolean(CustomResources_g_hashCR, TERRAIN[4], 706, true)
//etc..
//define your plants:
set DESTR_WHEAT[1] = 'B00M' //small
set DESTR_WHEAT[2] = 'B00N'//medium
set DESTR_WHEAT[3] = 'B00O'//big
set DESTR_TOBACCO[1] = 'B00C' //small
set DESTR_TOBACCO[2] = 'B00B'//medium
set DESTR_TOBACCO[3] = 'B00A'//big
//save in hash:
call SaveBoolean(CustomResources_g_hashCR, DESTR_WHEAT[1], 701, true)
call SaveBoolean(CustomResources_g_hashCR, DESTR_WHEAT[2], 701, true)
call SaveBoolean(CustomResources_g_hashCR, DESTR_WHEAT[3], 701, true)
call SaveBoolean(CustomResources_g_hashCR, DESTR_TOBACCO[1], 701, true)
call SaveBoolean(CustomResources_g_hashCR, DESTR_TOBACCO[2], 701, true)
call SaveBoolean(CustomResources_g_hashCR, DESTR_TOBACCO[3], 701, true)
//save seeds-items
call SaveBoolean(CustomResources_g_hashCR, ITM_SEEDS_WHEAT, 702, true)
call SaveBoolean(CustomResources_g_hashCR, ITM_SEEDS_TOBACCO, 702, true)
//save itemSeeds--> plant baby id:
call SaveInteger(CustomResources_g_hashCR, ITM_SEEDS_WHEAT, 703, DESTR_WHEAT[1])
call SaveInteger(CustomResources_g_hashCR, ITM_SEEDS_TOBACCO, 703, DESTR_TOBACCO[1])
//save itemSeeds--> plant mature id:
call SaveInteger(CustomResources_g_hashCR, ITM_SEEDS_WHEAT, 704, DESTR_WHEAT[2])
call SaveInteger(CustomResources_g_hashCR, ITM_SEEDS_TOBACCO, 704, DESTR_TOBACCO[2])
//save itemSeeds--> plant big id:
call SaveInteger(CustomResources_g_hashCR, ITM_SEEDS_WHEAT, 705, DESTR_WHEAT[3])
call SaveInteger(CustomResources_g_hashCR, ITM_SEEDS_TOBACCO, 705, DESTR_TOBACCO[3])
endfunction
/*
HASHTABLE KEYS
//for Addon PlantsGrowSpread
701 -- destructableId as parentKey --> remembers boolean true as sign that destructable-plant is registered
call SaveBoolean(CustomResources_g_hashCR, parentKey, 701, true) // save "true" as sign that object is registered
if LoadBoolean(CustomResources_g_hashCR, destructableId, 701) then ...
702 -- Seeds-ItemId as parentKey --> remembers boolean true as sign that Seeds-ItemId is registered
call SaveBoolean(CustomResources_g_hashCR, parentKey, 702, true) // save "true" as sign that object is registered
if LoadBoolean(CustomResources_g_hashCR, SeedsItemId, 702) then ...
703 -- SeedsItemId as parentKey --> remembers destructabl-plant-baby Id
call SaveInteger(g_hashCR, SeedsItemId, 703, destructabl-plant-baby Id)
set plantBabyId = LoadInteger(g_hashCR, SeedsItemId, 703) //--> gives destructable-plant-baby Id
704 -- SeedsItemId as parentKey --> remembers destructabl-plant-mature Id
call SaveInteger(g_hashCR, SeedsItemId, 704, destructabl-plant-mature Id)
set plantMatureId = LoadInteger(g_hashCR, SeedsItemId, 704)
705 -- SeedsItemId as parentKey --> remembers destructabl-plant-big Id
call SaveInteger(g_hashCR, SeedsItemId, 705, destructabl-plant-big Id)
set plantBigId = LoadInteger(g_hashCR, SeedsItemId, 705)
706 -- terrainTypeId as parentKey --> remembers boolean true as sign that terrainTypeId is registered [able to change into farmlands]
call SaveBoolean(g_hashCR, terrainTypeId, 706, true)
if LoadBoolean(g_hashCR, terrainTypeId, 706) then ...
*/
//-----------------------------------------------------------
//used in spread and item seeds actions. It looks for alive, registered plants
//-----------------------------------------------------------
private function EnumPlants takes nothing returns nothing
local integer id = GetDestructableTypeId(GetEnumDestructable())
if GetDestructableLife(GetEnumDestructable())>0.00 and LoadBoolean(CustomResources_g_hashCR, id, 701) then
set g_terrainEmpty=false
endif
endfunction
//-----------------------------------------------------------
//-----------------------------------------------------------
private function Loop takes nothing returns nothing
local integer id=1
loop
exitwhen id>maxId
if (GetDestructableLife(instDestr[id]) <= 0) then //dead
set instDuration[id] = 0.00
elseif instDuration[id]==instChangeTime[id] then //alive, and time for change
//call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Change time - mature " )
set bj_lastCreatedDestructable = CreateDestructable(instDestr2Id[id], GetDestructableX(instDestr[id]), GetDestructableY(instDestr[id]), GetRandomReal(0, 360), 0.50, 0)//scale:1, variation:0
call RemoveDestructable(instDestr[id])
set instDestr[id] = bj_lastCreatedDestructable
endif
//---
set instDuration[id] = instDuration[id] - INTERVAL
if instDuration[id] <= 0.00 then
if (GetDestructableLife(instDestr[id])>0) then//alive, time for final change
//call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Final Change time " )
set g_spreadCenterX = GetDestructableX(instDestr[id])
set g_spreadCenterY = GetDestructableY(instDestr[id])
set g_spreadId[1] = instDestr1Id[id]
set g_spreadId[2] = instDestr2Id[id]
set g_spreadId[3] = instDestr3Id[id]
set bj_lastCreatedDestructable = CreateDestructable(instDestr3Id[id], g_spreadCenterX, g_spreadCenterY, GetRandomReal(0, 360), 0.70, 0)//scale:1, variation:0
call RemoveDestructable(instDestr[id])
set instDestr[id] = bj_lastCreatedDestructable
call TriggerExecute(trg_spreadSeeds)
endif
//call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Instance ended on destr " + GetDestructableName(instDestr[id]))
//---
//dealloc: /move data from max to current/
set instDestr1Id[id] = instDestr1Id[maxId]
set instDestr2Id[id] = instDestr2Id[maxId]
set instDestr3Id[id] = instDestr3Id[maxId]
set instChangeTime[id] = instChangeTime[maxId]
set instDuration[id] = instDuration[maxId]
set instDestr[id] = instDestr[maxId]
//clean:
set instDestr[maxId]=null
//---
set maxId=maxId-1
set id=id-1
if maxId==0 then
call PauseTimer(t)
endif
endif
set id=id+1
endloop
endfunction
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
function CreatePlant takes integer d1, integer d2, integer d3, real x, real y, real matureChangeTime, real totalGrowTime returns nothing
set maxId = maxId + 1
set instDestr1Id[maxId] = d1
set instDestr2Id[maxId] = d2
set instDestr3Id[maxId] = d3
set instChangeTime[maxId] = matureChangeTime
set instDuration[maxId] = totalGrowTime
set instDestr[maxId] = CreateDestructable(d1, x, y, GetRandomReal(0, 360), 0.30, 0)//scale:1, variation:0
if maxId==1 then
call TimerStart(t, INTERVAL, true, function Loop)
endif
endfunction
//----------------------------------------------------------------------------------------------
//-----------------------------------------------------------
//it uses 2 real globals: g_spreadCenterX & g_spreadCenterY and 3 integer globals: g_spreadId[1,2,3]
//-----------------------------------------------------------
private function SpreadOnPoint_Ex takes real x, real y returns boolean
local real off=SPREAD_TERRAIN_EDGE_LIMIT //check center, and 4 points around
if GetTerrainType(x, y)==TERRAIN_TYPE_CROPS and IsTerrainLand(x,y) and IsTerrainWalkable(x,y) then
if GetTerrainType(x+off, y)==TERRAIN_TYPE_CROPS and IsTerrainLand(x+off,y) and IsTerrainWalkable(x+off,y) then //0
if GetTerrainType(x-off, y)==TERRAIN_TYPE_CROPS and IsTerrainLand(x-off,y) and IsTerrainWalkable(x-off,y) then //180
if GetTerrainType(x, y+off)==TERRAIN_TYPE_CROPS and IsTerrainLand(x,y+off) and IsTerrainWalkable(x,y+off) then //90
if GetTerrainType(x, y-off)==TERRAIN_TYPE_CROPS and IsTerrainLand(x,y-off) and IsTerrainWalkable(x,y-off) then //270
return true
endif
endif
endif
endif
endif
return false
endfunction
//-----------------------------------------------------------
private function SpreadOnPoint takes real x, real y returns nothing
if SpreadOnPoint_Ex(x,y) then
set g_terrainEmpty=true
call MoveRectTo(r_crops128, x, y)
call EnumDestructablesInRect(r_crops128, null, function EnumPlants)
if g_terrainEmpty then
call CreatePlant(g_spreadId[1], g_spreadId[2], g_spreadId[3], x, y, 10.00, 20.00)
endif
endif
endfunction
//----------------------------------------------------------- used as action in trigger trg_spreadSeeds
private function Spread takes nothing returns nothing
///local real offset=128.00
local real offset=CROPS_DENSITY
//8 squares offset by 128, without center
call SpreadOnPoint(g_spreadCenterX+offset, g_spreadCenterY) //for 0
call SpreadOnPoint(g_spreadCenterX-offset, g_spreadCenterY) //for 180
call SpreadOnPoint(g_spreadCenterX, g_spreadCenterY+offset) //for 90
call SpreadOnPoint(g_spreadCenterX, g_spreadCenterY-offset) //for 270
call SpreadOnPoint(g_spreadCenterX+offset, g_spreadCenterY+offset) //for 45
call SpreadOnPoint(g_spreadCenterX-offset, g_spreadCenterY+offset) //for 135
call SpreadOnPoint(g_spreadCenterX-offset, g_spreadCenterY-offset) //for 225
call SpreadOnPoint(g_spreadCenterX+offset, g_spreadCenterY-offset) //for 315
endfunction
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// trigger EVENT_PLAYER_UNIT_SPELL_EFFECT, changing terrain type
//-------------------------------------------------------------------------
private function EnumDestr takes nothing returns nothing
if GetDestructableLife(GetEnumDestructable()) > 0.00 then
set g_terrainEmpty=false
endif
endfunction
//-------------------------------------------------------------------------
private function Trig_TerrainChangeCond takes nothing returns boolean
return GetSpellAbilityId() == ABI_PLOW_FARMLAND
endfunction
//-------------------------------------------------------------------------
private function ChangeTerrainType takes real Tx, real Ty returns nothing
if LoadBoolean(CustomResources_g_hashCR, GetTerrainType(Tx, Ty), 706) then//if terrain able to change into farmland?
if IsTerrainLand(Tx,Ty) and IsTerrainWalkable(Tx,Ty) then
call SetTerrainType(Tx, Ty, TERRAIN_TYPE_CROPS, -1, 1, 1) //size:1, last "1"==square
endif
endif
endfunction
//-------------------------------------------------------------------------
private function Trig_TerrainChange takes nothing returns nothing
local real x=GetSpellTargetX()
local real y=GetSpellTargetY()
local real offset = 128.00
set g_terrainEmpty=true
call MoveRectTo(r_crops, x, y)
call EnumDestructablesInRect(r_crops, null, function EnumDestr)
if not g_terrainEmpty then
call DisplayTextToPlayer(GetOwningPlayer(GetTriggerUnit()), 0, 0, "Targeted terrain should be empty")
return
endif
//center + 8 squares offset by 128
call ChangeTerrainType(x, y) //center
call ChangeTerrainType(x+offset, y) //for 0
call ChangeTerrainType(x-offset, y) //for 180
call ChangeTerrainType(x, y+offset) //for 90
call ChangeTerrainType(x, y-offset) //for 270
call ChangeTerrainType(x+offset, y+offset) //for 45
call ChangeTerrainType(x-offset, y+offset) //for 135
call ChangeTerrainType(x-offset, y-offset) //for 225
call ChangeTerrainType(x+offset, y-offset) //for 315
endfunction
//-------------------------------------------------------------------------------------------
// trigger EVENT_PLAYER_UNIT_USE_ITEM
//-------------------------------------------------------------------------------------------
private function Trig_ItemCond takes nothing returns boolean
return LoadBoolean(CustomResources_g_hashCR, GetItemTypeId(GetManipulatedItem()), 702)
endfunction
//--------------------------------------------------------------------
private function Trig_Itm takes nothing returns nothing
local integer i = GetItemTypeId(GetManipulatedItem())
local unit u=GetManipulatingUnit()
local real x=GetUnitX(u)
local real y=GetUnitY(u)
local integer plantBaby = LoadInteger(CustomResources_g_hashCR, i, 703)
local integer plantMature = LoadInteger(CustomResources_g_hashCR, i, 704)
local integer plantBig = LoadInteger(CustomResources_g_hashCR, i, 705)
if GetTerrainType(x, y)==TERRAIN_TYPE_CROPS then
set g_terrainEmpty=true
call MoveRectTo(r_crops128, x, y)
call EnumDestructablesInRect(r_crops128, null, function EnumPlants)
if not g_terrainEmpty then
call DisplayTextToPlayer(GetOwningPlayer(u), 0, 0, "There is growing plant at this position")
return
endif
call CreatePlant(plantBaby, plantMature, plantBig, x, y, 10.00, 20.00)
else
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Use seeds on right terrain")
endif
set u=null
endfunction
//=================================================
private function Init takes nothing returns nothing
local trigger t=CreateTrigger()
call Settings()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition( function Trig_TerrainChangeCond))
call TriggerAddAction(t, function Trig_TerrainChange)
set t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_USE_ITEM)
call TriggerAddCondition(t, Condition( function Trig_ItemCond))
call TriggerAddAction(t, function Trig_Itm)
call TriggerAddAction(trg_spreadSeeds, function Spread)
endfunction
endlibrary
/*-------------------------------------------------------------
//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_BuildingSiteMisc = 'h001' //Building Site - Misc
public constant integer udg_BuildingSiteSmall = 'hZ1F' //Building Site - Small
public constant integer udg_BuildingSiteFort = 'h000' //Building Site - Fortification
public constant integer udg_BuildingSiteWide = 'hZ0Q' //Building Site - Wide
public constant integer udg_BuildingSiteMedium = 'hZ9M' //Building Site - Medium
public constant integer udg_BuildingSiteLarge = 'hZ0I' //Building Site - Large
public constant integer udg_BuildingSiteHuge = 'hZ11' //Building Site - Huge
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 (Misc):
public constant integer udg_Barricade = 'hZ0Z' //Barricade
public constant integer udg_TrainD1 = 'nmh0' //Training Dummy (1)
public constant integer udg_TrainD2 = 'nmh1' //Training Dummy (2)
public constant integer udg_TrainD3 = 'nnzg' //Training Dummy (3)
public constant integer udg_Target1 = 'ntn2' //Archery Target (1)
public constant integer udg_Target2 = 'ntnt' //Archery Target (2)
//Buildings (Tiny):
public constant integer udg_FirePit = 'net1' //Fire Pit
public constant integer udg_LightP1 = 'nfv4' //Light Post (1)
public constant integer udg_LightP2 = 'nfv3' //Light Post (2)
public constant integer udg_Well1 = 'nfh1' //Well (1)
public constant integer udg_Well2 = 'nfh0' //Well (2)
public constant integer udg_Well3 = 'nfr2' //Well (3)
public constant integer udg_Fountain1 = 'nfr1' //Fountain (1)
public constant integer udg_Fountain2 = 'ngnh' //Fountain (2)
public constant integer udg_Banner1 = 'ngt2' //Banner (1)
public constant integer udg_Banner2 = 'nhns' //Banner (2)
public constant integer udg_Stash1 = 'nvr0' //Stash (1)
public constant integer udg_Stash2 = 'nvr2' //Stash (2)
public constant integer udg_Statue1 = 'nth0' //Statue (1)
public constant integer udg_Statue2 = 'nth1' //Statue (2)
//Buildings (Small):
public constant integer udg_House1 = 'nefm' //House (1)
public constant integer udg_House2 = 'nef0' //House (2)
public constant integer udg_House3 = 'nef1' //House (3)
public constant integer udg_House4 = 'nef2' //House (4)
public constant integer udg_Tent1 = 'npgr' //Tent (1)
public constant integer udg_Tent2 = 'nwc1' //Tent (2)
public constant integer udg_Tent3 = 'nwc2' //Tent (3)
public constant integer udg_Path1 = 'ndch' //Path (1)
public constant integer udg_Path2 = 'ndh1' //Path (2)
public constant integer udg_Path3 = 'ndh0' //Path (3)
public constant integer udg_Blacksmith = 'hhou' //Blacksmith
public constant integer udg_WindMill1 = 'uzig' //Wind Mill (1)
public constant integer udg_WindMill2 = 'uzg1' //Wind Mill (2)
public constant integer udg_TowerB1 = 'net2' //Bell Tower (1)
public constant integer udg_TowerB2 = 'nft2' //Bell Tower (2)
public constant integer udg_Tower1 = 'hwtw' //Tower (1)
public constant integer udg_Tower2 = 'hgtw' //Tower (2)
public constant integer udg_Tower3 = 'hctw' //Tower (3)
public constant integer udg_Tower4 = 'hatw' //Tower (4)
public constant integer udg_TowerR = 'negm' //TowerR
public constant integer udg_TowerRB = 'ntx2' //TowerRB
public constant integer udg_TowerRC = 'ndt2' //TowerRC
public constant integer udg_TowerS = 'negf' //TowerS
public constant integer udg_TowerSB = 'negt' //TowerSB
public constant integer udg_TowerSC = 'ndgt' //TowerSC
//Buildings (Wide):
public constant integer udg_LongHall1 = 'htow' //Long Hall (1)
public constant integer udg_LongHall2 = 'hkee' //Long Hall (2)
public constant integer udg_LongHall3 = 'hcas' //Long Hall (3)
public constant integer udg_LongHall4 = 'ngwr' //Long Hall (4)
public constant integer udg_Manor1 = 'nef3' //Manor (1)
public constant integer udg_Manor2 = 'nef4' //Manor (2)
public constant integer udg_Manor3 = 'nef5' //Manor (3)
public constant integer udg_Tavern1 = 'hars' //Tavern (1)
public constant integer udg_Tavern2 = 'hgra' //Tavern (2)
public constant integer udg_Tavern3 = 'hvlt' //Tavern (3)
public constant integer udg_LumberMill1 = 'osld' //Lumber Mill (1)
public constant integer udg_LumberMill2 = 'otrb' //Lumber Mill (2)
public constant integer udg_LumberMill3 = 'owtw' //Lumber Mill (3)
public constant integer udg_LumberMill4 = 'npgf' //Lumber Mill (4)
public constant integer udg_StoneMill1 = 'ovln' //Stone Mill (1)
public constant integer udg_StoneMill2 = 'ndrb' //Stone Mill (2)
public constant integer udg_StoneMill3 = 'ocbw' //Stone Mill (3)
public constant integer udg_StoneMill4 = 'nitb' //Stone Mill (4)
public constant integer udg_Forge1 = 'halt' //Forge (1)
public constant integer udg_Forge2 = 'hlum' //Forge (2)
public constant integer udg_Forge3 = 'hbla' //Forge (3)
public constant integer udg_Forge4 = 'harm' //Forge (4)
public constant integer udg_Barn1 = 'oalt' //Barn (1)
public constant integer udg_Barn2 = 'ofor' //Barn (2)
public constant integer udg_Barn3 = 'otto' //Barn (3)
//Buildings (Medium):
public constant integer udg_GreatHall1 = 'ogre' //Great Hall (1)
public constant integer udg_GreatHall2 = 'ostr' //Great Hall (2)
public constant integer udg_GreatHall3 = 'ofrt' //Great Hall (3)
public constant integer udg_University1 = 'nef6' //University (1)
public constant integer udg_University2 = 'nef7' //University (2)
public constant integer udg_Warehouse1 = 'nfv2' //Warehouse (1)
public constant integer udg_Warehouse2 = 'nvr1' //Warehouse (2)
public constant integer udg_Warehouse3 = 'nfv0' //Warehouse (3)
public constant integer udg_WaterMill1 = 'ncnt' //Watermill (1)
public constant integer udg_WaterMill2 = 'nct1' //Watermill (2)
public constant integer udg_WaterMill3 = 'nct2' //Watermill (3)
public constant integer udg_Granary1 = 'nft1' //Granary (1)
public constant integer udg_Granary2 = 'nbt2' //Granary (2)
public constant integer udg_Granary3 = 'nntg' //Granary (3)
public constant integer udg_TrainG1 = 'ntt2' //Training Grounds (1)
public constant integer udg_TrainG2 = 'nten' //Training Grounds (2)
public constant integer udg_Altar1 = 'nmg0' //Altar (1)
public constant integer udg_Altar2 = 'nmg1' //Altar (2)
//Buildings (Large):
public constant integer udg_Barracks1 = 'hZ2Q' //Barracks (1)
public constant integer udg_Barracks2 = 'edob' //Barracks (2)
public constant integer udg_Barracks3 = 'edos' //Barracks (3)
public constant integer udg_Barracks4 = 'hbar' //Barracks (4)
public constant integer udg_ArcheryR1 = 'nnad' //Archery Range (1)
public constant integer udg_ArcheryR2 = 'nbwd' //Archery Range (2)
public constant integer udg_ArcheryR3 = 'nnfm' //Archery Range (3)
public constant integer udg_Stables1 = 'nheb' //Stables (1)
public constant integer udg_Stables2 = 'obar' //Stables (2)
public constant integer udg_Stables3 = 'obea' //Stables (3)
public constant integer udg_Workshop1 = 'nbt1' //Workshop (1)
public constant integer udg_Workshop2 = 'ndt1' //Workshop (2)
public constant integer udg_Workshop3 = 'ntt1' //Workshop (3)
public constant integer udg_Docks1 = 'hshy' //Docks (1)
public constant integer udg_Docks2 = 'eshy' //Docks (2)
public constant integer udg_Docks3 = 'oshy' //Docks (3)
public constant integer udg_VillageSquare = 'hZ2Y' //Village Square
//Buildings (Huge):
public constant integer udg_Stronghold = 'nntt' //Stronghold
public constant integer udg_Cathedral1 = 'nnsa' //Cathedral (1)
public constant integer udg_Cathedral2 = 'nnsg' //Cathedral (2)
public constant integer udg_Cathedral3 = 'haro' //Cathedral (3)
public constant integer udg_Market1 = 'nmgv' //Market (1)
public constant integer udg_Market2 = 'nfv1' //Market (2)
public constant integer udg_Market3 = 'ngob' //Market (3)
public constant integer udg_Market4 = 'nfrt' //Market (4)
//Standard units (Human):
public constant integer udg_Worker = 'hZ00' //Worker
public constant integer udg_Worker2a = 'ewsp' //Worker (2)
public constant integer udg_Worker3a = 'efon' //Worker (3)
public constant integer udg_Worker4a = 'hpea' //Worker (4)
public constant integer udg_Worker1b = 'opeo' //Worker (1)
public constant integer udg_Worker2b = 'ncpn' //Worker (2)
public constant integer udg_Worker3b = 'uaco' //Worker (3)
public constant integer udg_Worker4b = 'ushd' //Worker (4)
public constant integer udg_Worker1e = 'nvlk' //Engineer (1)
public constant integer udg_Worker2e = 'nvk2' //Engineer (2)
public constant integer udg_Architect = 'hZ38' //Architect
public constant integer udg_Architect2 = 'nbee' //Architect (2)
public constant integer udg_Architect3 = 'nhew' //Architect (3)
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 = 'hZ2N' //Ladder Carrier
public constant integer udg_Peon2 = 'nbld' //Ladder Carrier2
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
/*-------------------------------------------------------------
//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 = false //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
/*-------------------------------------------------------------
//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
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
/*-------------------------------------------------------------
//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 or CasterID == libId_udg_Peon2) then //Peon
if (Number == 1) then
return libId_udg_BuildingSiteLadder //Building site (Ladder)
elseif (Number == 2) then
if (TargetID == libId_udg_WallUn or TargetID == libId_udg_WallDa or TargetID == libId_udg_WallOEUn or TargetID == libId_udg_WallOEDa) then //Wall (no Edge), Wall (Outer Edge)
return libId_udg_LadderWall //Ladder (Wall)
elseif (TargetID == libId_udg_PalisadeUn or TargetID == libId_udg_PalisadeDa or TargetID == libId_udg_PalisadeOEUn or TargetID == libId_udg_PalisadeOEDa or TargetID == libId_udg_PalisadeLadderUn or TargetID == libId_udg_PalisadeLadderDa) then //Palisade (no Edge), Palisade (Outer Edge)
return libId_udg_LadderPalisade //Ladder (Palisade)
endif
elseif (Number == 3) then
return libId_udg_SiegeLadderAttachment //Siege Ladder (Attachment)
endif
elseif (CasterID == libId_udg_PalisadeUn) then
if (Number == 2) then
return libId_udg_PalisadeLadderUn //Palisade (Ladder) (Undamaged)
endif
elseif (CasterID == libId_udg_PalisadeDa) then
if (Number == 2) then
return libId_udg_PalisadeLadderDa //Palisade (Ladder) (Damaged)
endif
endif
return 0
endfunction
//Returns the addition path checker position (Number, ReturnX) to a building with the given data (BuildingID, PosX, PosY, Facing):
private function GetFortificationAdditionPathCheckerPos takes integer BuildingSiteID, real PosX, real PosY, real Facing, integer Number, boolean ReturnX returns real
local real RealTemp1 = PosY
if (ReturnX) then
set RealTemp1 = PosX
endif
if (BuildingSiteID == libId_udg_BuildingSiteStairs) then //Building site (Stairs)
if (Number == 1) then
if (ReturnX and (Facing == 90.00 or Facing == 270.00)) then
return RealTemp1 + 64.00
elseif (ReturnX == false and (Facing == 0.00 or Facing == 180.00)) then
return RealTemp1 + 64.00
endif
return RealTemp1
elseif (Number == 2) then
return RealTemp1
elseif (Number == 3) then
if (ReturnX and (Facing == 90.00 or Facing == 270.00)) then
return RealTemp1 - 64.00
elseif (ReturnX == false and (Facing == 0.00 or Facing == 180.00)) then
return RealTemp1 - 64.00
endif
return RealTemp1
endif
elseif (BuildingSiteID == libId_udg_BuildingSiteLadder) then //Building site (Ladder)
if (Number == 1) then
if (ReturnX and (Facing == 90.00 or Facing == 270.00)) then
return RealTemp1 + 32.00
elseif (ReturnX == false and (Facing == 0.00 or Facing == 180.00)) then
return RealTemp1 + 32.00
endif
return RealTemp1
elseif (Number == 2) then
if (ReturnX and (Facing == 90.00 or Facing == 270.00)) then
return RealTemp1 - 32.00
elseif (ReturnX == false and (Facing == 0.00 or Facing == 180.00)) then
return RealTemp1 - 32.00
endif
return RealTemp1
endif
endif
return 99999.99
endfunction
//Checks if the given unit is allowed to move:
private function IsUnitWithoutMovement takes integer UnitID returns boolean
if (UnitID == libId_udg_Ballista) then //Ballista
return true
endif
return false
endfunction
//-------------
//PRIVATE PART:
//-------------
//Rounds (up or down) in the direction of minimal deviation:
private function Round takes real Dividend, real Divisor returns real
local real RealTemp1 = 0.00
if (Divisor > 0.00) then
set RealTemp1 = I2R(R2I(Dividend / Divisor)) * Divisor
if (Dividend - RealTemp1 > 0.5 * Divisor) then
return RealTemp1 + Divisor
elseif (Dividend - RealTemp1 < (-0.5) * Divisor) then
return RealTemp1 - Divisor
endif
endif
return RealTemp1
endfunction
private function AdjustOrthogonalAngle takes real Input returns real
local real MaxResidual = 0.001
if (0.00 - Input <= MaxResidual and 0.00 - Input >= (-1) * MaxResidual) then
return 0.00
elseif (90.00 - Input <= MaxResidual and 90.00 - Input >= (-1) * MaxResidual) then
return 90.00
elseif (180.00 - Input <= MaxResidual and 180.00 - Input >= (-1) * MaxResidual) then
return 180.00
elseif (270.00 - Input <= MaxResidual and 270.00 - Input >= (-1) * MaxResidual) then
return 270.00
elseif (360.00 - Input <= MaxResidual and 360.00 - Input >= (-1) * MaxResidual) then
return 0.00
elseif (450.00 - Input <= MaxResidual and 450.00 - Input >= (-1) * MaxResidual) then
return 90.00
elseif (540.00 - Input <= MaxResidual and 540.00 - Input >= (-1) * MaxResidual) then
return 180.00
elseif (630.00 - Input <= MaxResidual and 630.00 - Input >= (-1) * MaxResidual) then
return 270.00
elseif (720.00 - Input <= MaxResidual and 720.00 - Input >= (-1) * MaxResidual) then
return 0.00
endif
return Input
endfunction
//------------
//PUBLIC PART:
//------------
globals
public boolean udg_InitFinished = false
endglobals
//-----------------
//DECLARATION PART:
//-----------------
globals
private constant integer udg_MaxWalkBuildingsP = udg_MaxWalkBuildings + 1
private constant integer udg_CountPlayersP = udg_CountPlayers + 1
endglobals
private struct WalkBuilding
public integer BuildingObjectNumber = 0
public destructable Destructable = null
public boolean UnderConstruction = false
public method remove takes nothing returns nothing
call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, 0)
set this.BuildingObjectNumber = 0
call RemoveDestructable(this.Destructable)
set this.Destructable = null
set this.UnderConstruction = false
call this.destroy()
endmethod
//--------------
//OTHER METHODS:
//--------------
public method New takes unit Building, integer WalkBuildingNumber returns nothing
set this.BuildingObjectNumber = libUnitDat_GetObjectNumber(Building, true)
call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, WalkBuildingNumber)
set this.Destructable = CreateDestructable(GetWalkDestructableID(GetUnitTypeId(Building), 0), GetUnitX(Building), GetUnitY(Building), AdjustOrthogonalAngle(GetUnitFacing(Building)), 1.00, 0)
set this.UnderConstruction = false
endmethod
public method AdjustSystemNumber takes integer NewSystemNumber returns nothing
call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, NewSystemNumber)
endmethod
endstruct
globals
private integer udg_WalkBuildingsCount = 0
private WalkBuilding array udg_WalkBuildings [udg_MaxWalkBuildingsP]
private boolean udg_RepositionAllBuildingsRunning = false
private boolean udg_RepositionAllBuildingsRestart = false
private integer udg_AdjustPathingForWalkBuildingGroup_Counter = 0
private constant trigger gg_trg_GateClosingOrOpeningStarts = CreateTrigger()
private constant trigger gg_trg_FortificationDies = CreateTrigger()
private constant trigger gg_trg_FortificationBuildsFinish = CreateTrigger()
private constant trigger gg_trg_AddStairs = CreateTrigger()
private constant trigger gg_trg_AddLadders = CreateTrigger()
private constant trigger gg_trg_UseSiegeLadder = CreateTrigger()
private constant trigger gg_trg_AutoUseSiegeLadder = CreateTrigger()
private constant trigger gg_trg_SmallPathingBuildsStart = CreateTrigger()
private constant trigger gg_trg_DisableMovementFinish = CreateTrigger()
private constant trigger gg_trg_SmartOrderOnWalkableBuilding = CreateTrigger()
endglobals
//-------------
//PRIVATE PART:
//-------------
private function AddWalkBuilding takes unit Building returns nothing
set udg_WalkBuildingsCount = udg_WalkBuildingsCount + 1
set udg_WalkBuildings[udg_WalkBuildingsCount] = WalkBuilding.create()
if (udg_WalkBuildings[udg_WalkBuildingsCount] == 0) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: WalkBuilding struct cap exceeded")
return
endif
call udg_WalkBuildings[udg_WalkBuildingsCount].New(Building, udg_WalkBuildingsCount)
endfunction
private function RemoveWalkBuilding takes unit Building returns nothing
local integer WalkBuildingNumber = libUnitDat_GetSystemNumberOfUnit(Building, udg_SystemSlot)
if (WalkBuildingNumber > 0) then
call udg_WalkBuildings[WalkBuildingNumber].remove()
set udg_WalkBuildings[WalkBuildingNumber] = udg_WalkBuildings[udg_WalkBuildingsCount]
call udg_WalkBuildings[WalkBuildingNumber].AdjustSystemNumber(WalkBuildingNumber)
set udg_WalkBuildings[udg_WalkBuildingsCount] = 0
set udg_WalkBuildingsCount = udg_WalkBuildingsCount - 1
endif
endfunction
private function GetAdjoiningFortificationBuildings_Filter1 takes nothing returns boolean
return (IsFortificationBuilding(GetUnitTypeId(GetFilterUnit())))
endfunction
private function GetAdjoiningFortificationBuildings takes unit Building returns group
local rect RectTemp1
local boolexpr Filter1 = null
local unit UnitTemp1
local unit UnitTemp2
local group GroupTemp1 = CreateGroup()
local group UncheckedUnits = CreateGroup()
local group ReturnGroup = CreateGroup()
local integer IntTemp1
local integer IntTemp2
local integer IntLoop1
local integer IntLoop2
local real RealTemp1
local real RealTemp2
local real RealTemp3
call GroupAddUnit(UncheckedUnits, Building)
call GroupAddUnit(ReturnGroup, Building)
loop
set UnitTemp1 = FirstOfGroup(UncheckedUnits)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(UncheckedUnits, UnitTemp1)
set IntTemp1 = GetUnitTypeId(UnitTemp1)
set IntTemp2 = GetFortificationBuildingAdjoiningSlots(IntTemp1)
set RealTemp1 = GetUnitX(UnitTemp1)
set RealTemp2 = GetUnitY(UnitTemp1)
set RealTemp3 = AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1))
set IntLoop2 = 1
loop
exitwhen IntLoop2 > IntTemp2
set IntLoop1 = 1
loop
set RectTemp1 = GetFortificationBuildingAdjoiningRect(IntTemp1, RealTemp1, RealTemp2, RealTemp3, IntLoop2, IntLoop1)
exitwhen RectTemp1 == null
call GroupClear(GroupTemp1)
if (Filter1 == null) then
set Filter1 = Condition(function GetAdjoiningFortificationBuildings_Filter1)
endif
call GroupEnumUnitsInRect(GroupTemp1, RectTemp1, Filter1)
call RemoveRect(RectTemp1)
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
loop
set UnitTemp2 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp2 == null
if (GetUnitState(UnitTemp2, UNIT_STATE_LIFE) >= 1.00) then
exitwhen IsFortificationBuildingAdjoining(IntTemp1, IntLoop2, IntLoop1, RealTemp3, UnitTemp2)
endif
call GroupRemoveUnit(GroupTemp1, UnitTemp2)
endloop
exitwhen UnitTemp2 != null
set IntLoop1 = IntLoop1 + 1
endloop
if (UnitTemp2 != null and IsUnitInGroup(UnitTemp2, ReturnGroup) == false) then
call GroupAddUnit(UncheckedUnits, UnitTemp2)
call GroupAddUnit(ReturnGroup, UnitTemp2)
endif
set IntLoop2 = IntLoop2 + 1
endloop
endloop
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
call DestroyGroup(UncheckedUnits)
set UncheckedUnits = null
if (Filter1 != null) then
call DestroyBoolExpr(Filter1)
set Filter1 = null
endif
set RectTemp1 = null
set UnitTemp1 = null
set UnitTemp2 = null
//-----------------
return ReturnGroup
endfunction
private function GetDirectAdjoiningFortificationBuildings_Filter1 takes nothing returns boolean
return (IsFortificationBuilding(GetUnitTypeId(GetFilterUnit())))
endfunction
private function GetDirectAdjoiningFortificationBuildings takes unit Building, boolean IncludeGivenBuilding returns group
local rect RectTemp1
local boolexpr Filter1 = null
local group GroupTemp1 = CreateGroup()
local group GroupTemp2 = CreateGroup()
local unit UnitTemp1
local real PosX = GetUnitX(Building)
local real PosY = GetUnitY(Building)
local real Facing = AdjustOrthogonalAngle(GetUnitFacing(Building))
local integer BuildingID = GetUnitTypeId(Building)
local integer IntTemp1 = GetFortificationBuildingAdjoiningSlots(BuildingID)
local integer IntLoop1 = 1
local integer IntLoop2
loop
exitwhen IntLoop1 > IntTemp1
set IntLoop2 = 1
loop
set RectTemp1 = GetFortificationBuildingAdjoiningRect(BuildingID, PosX, PosY, Facing, IntLoop1, IntLoop2)
exitwhen RectTemp1 == null
call GroupClear(GroupTemp1)
if (Filter1 == null) then
set Filter1 = Condition(function GetDirectAdjoiningFortificationBuildings_Filter1)
endif
call GroupEnumUnitsInRect(GroupTemp1, RectTemp1, Filter1)
call RemoveRect(RectTemp1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
if (GetUnitState(UnitTemp1, UNIT_STATE_LIFE) >= 1.00) then
exitwhen IsFortificationBuildingAdjoining(BuildingID, IntLoop1, IntLoop2, Facing, UnitTemp1)
endif
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
endloop
exitwhen UnitTemp1 != null
set IntLoop2 = IntLoop2 + 1
endloop
call GroupAddUnit(GroupTemp2, UnitTemp1)
set IntLoop1 = IntLoop1 + 1
endloop
if (IncludeGivenBuilding) then
call GroupAddUnit(GroupTemp2, Building)
endif
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
if (Filter1 != null) then
call DestroyBoolExpr(Filter1)
set Filter1 = null
endif
call RemoveRect(RectTemp1)
set RectTemp1 = null
set UnitTemp1 = null
//-----------------
return GroupTemp2
endfunction
private function GetAdjoiningFortificationBuildingBySlot takes integer BuildingID, real PosX, real PosY, real Facing, integer Slot, integer CounterAddition returns unit
local rect RectTemp1
local group GroupTemp1 = CreateGroup()
local unit ReturnUnit
local integer IntLoop1 = 1
loop
set RectTemp1 = GetFortificationBuildingAdjoiningRect(BuildingID, PosX, PosY, Facing, Slot, IntLoop1)
set udg_AdjustPathingForWalkBuildingGroup_Counter = udg_AdjustPathingForWalkBuildingGroup_Counter + CounterAddition
exitwhen RectTemp1 == null
call GroupClear(GroupTemp1)
call GroupEnumUnitsInRect(GroupTemp1, RectTemp1, null)
call RemoveRect(RectTemp1)
loop
set ReturnUnit = FirstOfGroup(GroupTemp1)
exitwhen ReturnUnit == null
set udg_AdjustPathingForWalkBuildingGroup_Counter = udg_AdjustPathingForWalkBuildingGroup_Counter + CounterAddition
if (IsFortificationBuilding(GetUnitTypeId(ReturnUnit)) and GetUnitState(ReturnUnit, UNIT_STATE_LIFE) >= 1.00) then
set udg_AdjustPathingForWalkBuildingGroup_Counter = udg_AdjustPathingForWalkBuildingGroup_Counter + CounterAddition
exitwhen IsFortificationBuildingAdjoining(BuildingID, Slot, IntLoop1, Facing, ReturnUnit)
endif
call GroupRemoveUnit(GroupTemp1, ReturnUnit)
endloop
exitwhen ReturnUnit != null
set IntLoop1 = IntLoop1 + 1
endloop
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
call RemoveRect(RectTemp1)
set RectTemp1 = null
//-----------------
return ReturnUnit
endfunction
private function RepositionBuilding takes unit Building returns nothing
local integer IntLoop1 = 1
//Hide all walk destructables:
loop
exitwhen IntLoop1 > udg_WalkBuildingsCount
call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, false)
set IntLoop1 = IntLoop1 + 1
endloop
call ShowUnit(Building, false)
call ShowUnit(Building, true)
//Show all walk destructables:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_WalkBuildingsCount
call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, true)
set IntLoop1 = IntLoop1 + 1
endloop
endfunction
private function RepositionBuildings takes group Buildings returns nothing
local unit UnitTemp1
local integer IntLoop1 = 1
//Hide all walk destructables:
loop
exitwhen IntLoop1 > udg_WalkBuildingsCount
call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, false)
set IntLoop1 = IntLoop1 + 1
endloop
//Reposition buildings:
loop
set UnitTemp1 = FirstOfGroup(Buildings)
exitwhen UnitTemp1 == null
call ShowUnit(UnitTemp1, false)
call ShowUnit(UnitTemp1, true)
call GroupRemoveUnit(Buildings, UnitTemp1)
endloop
call DestroyGroup(Buildings)
//Show all walk destructables:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_WalkBuildingsCount
call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, true)
set IntLoop1 = IntLoop1 + 1
endloop
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function RepositionAllBuildings_Filter1 takes nothing returns boolean
return (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE))
endfunction
private function RepositionAllBuildings_Filter2 takes nothing returns boolean
return (IsFortificationBuilding(GetUnitTypeId(GetFilterUnit())))
endfunction
private function RepositionAllBuildings takes nothing returns nothing
local boolexpr Filter1
local group GroupTemp1 = CreateGroup()
local group GroupTemp2 = CreateGroup()
local unit UnitTemp1
local integer IntLoop1
local integer IntLoop2 = 0
if (udg_RepositionOnlyFortifications <= 2) then
set Filter1 = Condition(function RepositionAllBuildings_Filter1)
else
set Filter1 = Condition(function RepositionAllBuildings_Filter2)
endif
set udg_RepositionAllBuildingsRunning = true
loop
set udg_RepositionAllBuildingsRestart = false
call GroupClear(GroupTemp1)
call GroupEnumUnitsInRect(GroupTemp1, bj_mapInitialPlayableArea, Filter1)
//Hide all walk destructables:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_WalkBuildingsCount
call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, false)
set IntLoop1 = IntLoop1 + 1
endloop
//Reposition buildings:
call SyncSelections()
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_CountPlayers
if (GetPlayerController(Player(IntLoop1 - 1)) == MAP_CONTROL_USER) then
call GroupClear(GroupTemp2)
call GroupEnumUnitsSelected(GroupTemp2, Player(IntLoop1 - 1), Filter1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp2)
exitwhen UnitTemp1 == null
call ShowUnit(UnitTemp1, false)
call ShowUnit(UnitTemp1, true)
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call GroupRemoveUnit(GroupTemp2, UnitTemp1)
if (GetLocalPlayer() == Player(IntLoop1 - 1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SelectUnit(UnitTemp1, true)
endif
set IntLoop2 = IntLoop2 + 1
endloop
endif
set IntLoop1 = IntLoop1 + 1
endloop
loop
//Reposition buildings:
loop
exitwhen udg_RepositionAllBuildingsRestart
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call ShowUnit(UnitTemp1, false)
call ShowUnit(UnitTemp1, true)
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
exitwhen IntLoop2 >= 40
set IntLoop2 = IntLoop2 + 1
endloop
set IntLoop2 = 0
//Show all walk destructables:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_WalkBuildingsCount
call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, true)
set IntLoop1 = IntLoop1 + 1
endloop
exitwhen udg_RepositionAllBuildingsRestart
exitwhen UnitTemp1 == null
call TriggerSleepAction(0.01)
//Hide all walk destructables:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_WalkBuildingsCount
call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, false)
set IntLoop1 = IntLoop1 + 1
endloop
endloop
exitwhen udg_RepositionAllBuildingsRestart == false
call TriggerSleepAction(0.01)
endloop
set udg_RepositionAllBuildingsRunning = false
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
call DestroyGroup(GroupTemp2)
set GroupTemp2 = null
call DestroyBoolExpr(Filter1)
set Filter1 = null
set UnitTemp1 = null
endfunction
private function RecreateWalkDestructables takes group Buildings returns nothing
local unit UnitTemp1
local integer array IntArrayTemp1
local integer IntLoop1
//Remove all walk destructables:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_WalkBuildingsCount
if (IsUnitInGroup(libUnitDat_GetUnit(udg_WalkBuildings[IntLoop1].BuildingObjectNumber), Buildings)) then
set IntArrayTemp1[IntLoop1] = GetDestructableTypeId(udg_WalkBuildings[IntLoop1].Destructable)
call RemoveDestructable(udg_WalkBuildings[IntLoop1].Destructable)
else
set IntArrayTemp1[IntLoop1] = 0
endif
set IntLoop1 = IntLoop1 + 1
endloop
//Recreate all walk destructables:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_WalkBuildingsCount
if (IntArrayTemp1[IntLoop1] != 0) then
set UnitTemp1 = libUnitDat_GetUnit(udg_WalkBuildings[IntLoop1].BuildingObjectNumber)
set udg_WalkBuildings[IntLoop1].Destructable = CreateDestructable(IntArrayTemp1[IntLoop1], GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1)), 1.00, 0)
endif
set IntLoop1 = IntLoop1 + 1
endloop
//Anti-Memory-Leak:
call DestroyGroup(Buildings)
set UnitTemp1 = null
endfunction
private function RaiseBuildingsOnSameHeight_Function1 takes integer Number, integer Type, integer ReturnValue returns real
if (Type == 1) then
if (Number == 1) then
if (ReturnValue == 3) then
return 1.00
endif
elseif (Number == 2) then
if (ReturnValue == 1) then
return 128.00
elseif (ReturnValue == 3) then
return udg_HeightAdjustSmooth
endif
elseif (Number == 3) then
if (ReturnValue == 2) then
return 128.00
elseif (ReturnValue == 3) then
return udg_HeightAdjustSmooth
endif
elseif (Number == 4) then
if (ReturnValue == 1) then
return -128.00
elseif (ReturnValue == 3) then
return udg_HeightAdjustSmooth
endif
elseif (Number == 5) then
if (ReturnValue == 2) then
return -128.00
elseif (ReturnValue == 3) then
return udg_HeightAdjustSmooth
endif
endif
elseif (Type == 2) then
if (Number == 1) then
if (ReturnValue == 2) then
return 64.00
elseif (ReturnValue == 3) then
return 1.00
endif
elseif (Number == 2) then
if (ReturnValue == 2) then
return -64.00
elseif (ReturnValue == 3) then
return 1.00
endif
elseif (Number == 3) then
if (ReturnValue == 1) then
return 128.00
elseif (ReturnValue == 2) then
return 64.00
elseif (ReturnValue == 3) then
return udg_HeightAdjustSmooth
endif
elseif (Number == 4) then
if (ReturnValue == 1) then
return -128.00
elseif (ReturnValue == 2) then
return 64.00
elseif (ReturnValue == 3) then
return udg_HeightAdjustSmooth
endif
elseif (Number == 5) then
if (ReturnValue == 1) then
return 128.00
elseif (ReturnValue == 2) then
return -64.00
elseif (ReturnValue == 3) then
return udg_HeightAdjustSmooth
endif
elseif (Number == 6) then
if (ReturnValue == 1) then
return -128.00
elseif (ReturnValue == 2) then
return -64.00
elseif (ReturnValue == 3) then
return udg_HeightAdjustSmooth
endif
endif
elseif (Type == 3) then
if (Number == 1) then
if (ReturnValue == 1) then
return 64.00
elseif (ReturnValue == 3) then
return 1.00
endif
elseif (Number == 2) then
if (ReturnValue == 1) then
return -64.00
elseif (ReturnValue == 3) then
return 1.00
endif
elseif (Number == 3) then
if (ReturnValue == 1) then
return 64.00
elseif (ReturnValue == 2) then
return 128.00
elseif (ReturnValue == 3) then
return udg_HeightAdjustSmooth
endif
elseif (Number == 4) then
if (ReturnValue == 1) then
return 64.00
elseif (ReturnValue == 2) then
return -128.00
elseif (ReturnValue == 3) then
return udg_HeightAdjustSmooth
endif
elseif (Number == 5) then
if (ReturnValue == 1) then
return -64.00
elseif (ReturnValue == 2) then
return 128.00
elseif (ReturnValue == 3) then
return udg_HeightAdjustSmooth
endif
elseif (Number == 6) then
if (ReturnValue == 1) then
return -64.00
elseif (ReturnValue == 2) then
return -128.00
elseif (ReturnValue == 3) then
return udg_HeightAdjustSmooth
endif
endif
elseif (Type == 4) then
if (Number == 1) then
if (ReturnValue == 1) then
return 64.00
elseif (ReturnValue == 2) then
return 64.00
elseif (ReturnValue == 3) then
return 1.00
endif
elseif (Number == 2) then
if (ReturnValue == 1) then
return -64.00
elseif (ReturnValue == 2) then
return 64.00
elseif (ReturnValue == 3) then
return 1.00
endif
elseif (Number == 3) then
if (ReturnValue == 1) then
return 64.00
elseif (ReturnValue == 2) then
return -64.00
elseif (ReturnValue == 3) then
return 1.00
endif
elseif (Number == 4) then
if (ReturnValue == 1) then
return -64.00
elseif (ReturnValue == 2) then
return -64.00
elseif (ReturnValue == 3) then
return 1.00
endif
endif
endif
return 0.00
endfunction
private function RaiseBuildingsOnSameHeight takes group Buildings returns boolean
local real MaxResidual = 0.001
local real AverageHeight = 0.00
local real array PosXs
local real array PosYs
local real array Factors
local integer UsedSlots = 0
local real RealTemp1
local real RealTemp2
local real RealTemp3
local real RealTemp4
local real RealTemp5
local unit UnitTemp1
local location LocationTemp1 = null
local group GroupTemp1 = null
local group GroupTemp2 = null
local group GroupTemp3 = null
local terraindeformation TerraindeformationTemp1 = null
local integer IntTemp1 = 0
local integer IntTemp2
local integer IntLoop1
local integer IntLoop2 = 0
local integer IntLoop3 = 0
//Exit if group has not more than one unit:
set UnitTemp1 = FirstOfGroup(Buildings)
call GroupRemoveUnit(Buildings, UnitTemp1)
if (FirstOfGroup(Buildings) == null) then
//Anti-Memory-Leak:
set UnitTemp1 = null
//-----------------
return false
endif
call GroupAddUnit(Buildings, UnitTemp1)
//Hide all walk destructables:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_WalkBuildingsCount
call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, false)
set IntLoop1 = IntLoop1 + 1
endloop
//Get building heights:
set GroupTemp1 = CreateGroup()
set GroupTemp2 = CreateGroup()
set GroupTemp3 = CreateGroup()
loop
set UnitTemp1 = FirstOfGroup(Buildings)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(Buildings, UnitTemp1)
call GroupAddUnit(GroupTemp1, UnitTemp1)
call GroupAddUnit(GroupTemp2, UnitTemp1)
call GroupAddUnit(GroupTemp3, UnitTemp1)
set LocationTemp1 = Location(GetUnitX(UnitTemp1), GetUnitY(UnitTemp1))
set RealTemp1 = GetLocationZ(LocationTemp1)
call RemoveLocation(LocationTemp1)
if (IntTemp1 == 0) then
//Check if all buildings are on the same hight:
if (AverageHeight == 0.00) then
set RealTemp2 = RealTemp1
elseif (RealTemp1 >= RealTemp2 + MaxResidual or RealTemp1 <= RealTemp2 - MaxResidual) then
set IntTemp1 = 1
endif
endif
set AverageHeight = AverageHeight + RealTemp1
set IntLoop2 = IntLoop2 + 1
endloop
if (IntLoop2 > 0) then
set AverageHeight = AverageHeight / IntLoop2
endif
//Show all walk destructables:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_WalkBuildingsCount
call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, true)
set IntLoop1 = IntLoop1 + 1
endloop
call TriggerSleepAction(0.01)
//Exit if no buildings have to be adjusted:
if (IntTemp1 == 0) then
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
call DestroyGroup(GroupTemp2)
set GroupTemp2 = null
call DestroyGroup(GroupTemp3)
set GroupTemp3 = null
call DestroyGroup(Buildings)
set Buildings = null
set UnitTemp1 = null
set LocationTemp1 = null
//-----------------
return false
endif
//Get positions that have to be adjusted:
set IntTemp2 = 30
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
set RealTemp1 = I2R(R2I(GetUnitX(UnitTemp1) / 64.00)) * 64.00
set RealTemp2 = I2R(R2I(GetUnitY(UnitTemp1) / 64.00)) * 64.00
if (RealTemp1 - I2R(R2I(RealTemp1 / 128.00)) * 128.00 == 0.00) then
if (RealTemp2 - I2R(R2I(RealTemp2 / 128.00)) * 128.00 == 0.00) then
set IntTemp1 = 1
else
set IntTemp1 = 2
endif
else
if (RealTemp2 - I2R(R2I(RealTemp2 / 128.00)) * 128.00 == 0.00) then
set IntTemp1 = 3
else
set IntTemp1 = 4
endif
endif
set IntLoop2 = 1
loop
set RealTemp5 = RaiseBuildingsOnSameHeight_Function1(IntLoop2, IntTemp1, 3)
exitwhen RealTemp5 == 0.00
set RealTemp3 = RealTemp1 + RaiseBuildingsOnSameHeight_Function1(IntLoop2, IntTemp1, 1)
set RealTemp4 = RealTemp2 + RaiseBuildingsOnSameHeight_Function1(IntLoop2, IntTemp1, 2)
set IntLoop1 = 1
loop
exitwhen IntLoop1 > UsedSlots
exitwhen (PosXs[IntLoop1] == RealTemp3 and PosYs[IntLoop1] == RealTemp4)
set IntLoop1 = IntLoop1 + 1
endloop
if (IntLoop1 > UsedSlots) then
set UsedSlots = UsedSlots + 1
set PosXs[UsedSlots] = RealTemp3
set PosYs[UsedSlots] = RealTemp4
set Factors[UsedSlots] = RealTemp5
elseif (Factors[IntLoop1] < RealTemp5) then
set Factors[IntLoop1] = RealTemp5
endif
set IntLoop2 = IntLoop2 + 1
endloop
set IntLoop3 = IntLoop3 + 1
if (IntLoop3 >= IntTemp2) then
set IntTemp2 = 4 + R2I(IntTemp2 * 0.5)
set IntLoop3 = 0
call TriggerSleepAction(0.01)
endif
endloop
call TriggerSleepAction(0.01)
//Hide all walk destructables:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_WalkBuildingsCount
call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, false)
set IntLoop1 = IntLoop1 + 1
endloop
//Adjust heights of the positions:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > UsedSlots
set LocationTemp1 = Location(PosXs[IntLoop1], PosYs[IntLoop1])
set RealTemp1 = (GetLocationZ(LocationTemp1) - AverageHeight) * Factors[IntLoop1]
call RemoveLocation(LocationTemp1)
if (RealTemp1 >= MaxResidual or RealTemp1 <= (-1) * MaxResidual) then
set TerraindeformationTemp1 = TerrainDeformCrater(PosXs[IntLoop1], PosYs[IntLoop1], 1.00, RealTemp1, 10, true)
endif
set IntLoop1 = IntLoop1 + 1
endloop
//Show all walk destructables:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_WalkBuildingsCount
call ShowDestructable(udg_WalkBuildings[IntLoop1].Destructable, true)
set IntLoop1 = IntLoop1 + 1
endloop
call TriggerSleepAction(0.01)
call RecreateWalkDestructables(GroupTemp2)
call RepositionBuildings(GroupTemp3)
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set GroupTemp2 = null
set GroupTemp3 = null
call DestroyGroup(Buildings)
set UnitTemp1 = null
set LocationTemp1 = null
set TerraindeformationTemp1 = null
//-----------------
return true
endfunction
private function AdjustPathingForWalkBuildingGroup takes group BuildingGroup, boolean WaitsNotAllowed returns nothing
local group GroupTemp1 = BuildingGroup
local unit UnitTemp1
local integer IntTemp1
local integer IntTemp2
local integer IntTemp3
local integer IntTemp4
local integer IntTemp5
local integer IntLoop1
local real RealTemp1
local real RealTemp2
local real RealTemp3
set udg_AdjustPathingForWalkBuildingGroup_Counter = 0
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
set IntTemp1 = GetUnitTypeId(UnitTemp1)
if (GetWalkDestructableID(IntTemp1, 0) != 0 and GetUnitState(UnitTemp1, UNIT_STATE_LIFE) >= 1.00) then
set IntTemp2 = libUnitDat_GetSystemNumberOfUnit(UnitTemp1, udg_SystemSlot)
if (IntTemp2 > 0) then
set RealTemp1 = GetUnitX(UnitTemp1)
set RealTemp2 = GetUnitY(UnitTemp1)
set RealTemp3 = AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1))
if (udg_WalkBuildings[IntTemp2].UnderConstruction and GetRepairedBuildingID(IntTemp1) == 0) then
set IntTemp5 = GetConstructionPathDestructableID(IntTemp1)
else
set IntTemp4 = GetFortificationBuildingAdjoiningSlots(IntTemp1)
set IntTemp3 = 0
set IntTemp5 = 0
//Get needed walk destructable type:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > IntTemp4
set UnitTemp1 = GetAdjoiningFortificationBuildingBySlot(IntTemp1, RealTemp1, RealTemp2, RealTemp3, IntLoop1, 1)
if (IntLoop1 == 3) then
set IntTemp3 = IntTemp3 + 1
elseif (IntLoop1 == 4) then
set IntTemp3 = IntTemp3 + 3
endif
if (UnitTemp1 == null) then
set IntTemp5 = IntTemp5 + IntLoop1 + IntTemp3
endif
set IntLoop1 = IntLoop1 + 1
endloop
set IntTemp5 = GetWalkDestructableID(IntTemp1, IntTemp5)
endif
set udg_AdjustPathingForWalkBuildingGroup_Counter = udg_AdjustPathingForWalkBuildingGroup_Counter + 1
//Replace walk destructable if needed:
if (GetDestructableTypeId(udg_WalkBuildings[IntTemp2].Destructable) != IntTemp5) then
call RemoveDestructable(udg_WalkBuildings[IntTemp2].Destructable)
set udg_WalkBuildings[IntTemp2].Destructable = CreateDestructable(IntTemp5, RealTemp1, RealTemp2, RealTemp3, 1.00, 0)
endif
if (udg_AdjustPathingForWalkBuildingGroup_Counter >= 1000) then
set udg_AdjustPathingForWalkBuildingGroup_Counter = 0
if (WaitsNotAllowed) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Too many units to adjust at once")
endif
call TriggerSleepAction(0.01)
endif
endif
endif
endloop
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
endfunction
private function AdjustWalkBuildingsAtPos_Filter1 takes nothing returns boolean
return (GetWalkDestructableID(GetUnitTypeId(GetFilterUnit()), 0) != 0)
endfunction
private function AdjustWalkBuildingsAtPos takes real PosX, real PosY returns nothing
local real HalfRectSize = 384.00
local rect RectTemp1
local boolexpr Filter1 = Condition(function AdjustWalkBuildingsAtPos_Filter1)
local group GroupTemp1 = CreateGroup()
//Check if target rect is in world bounds:
if(GetRectMinX(bj_mapInitialPlayableArea) <= PosX - HalfRectSize and GetRectMinY(bj_mapInitialPlayableArea) <= PosY - HalfRectSize and GetRectMaxX(bj_mapInitialPlayableArea) >= PosX + HalfRectSize and GetRectMaxY(bj_mapInitialPlayableArea) >= PosY + HalfRectSize) then
set RectTemp1 = Rect(PosX - HalfRectSize, PosY - HalfRectSize, PosX + HalfRectSize, PosY + HalfRectSize)
call GroupEnumUnitsInRect(GroupTemp1, RectTemp1, Filter1)
call RemoveRect(RectTemp1)
call AdjustPathingForWalkBuildingGroup(GroupTemp1, true)
endif
//Anti-Memory-Leak:
set GroupTemp1 = null
call DestroyBoolExpr(Filter1)
set Filter1 = null
set RectTemp1 = null
endfunction
private function PlaceFortificationAddition_Filter1 takes nothing returns boolean
return (IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND) and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false)
endfunction
private function PlaceFortificationAddition takes rect TargetRect, player Owner, integer BuildingSiteID, real Facing returns unit
local unit BuildingSite = null
local real PosX = Round(GetRectCenterX(TargetRect), 1)
local real PosY = Round(GetRectCenterY(TargetRect), 1)
local boolexpr Filter1 = Condition(function PlaceFortificationAddition_Filter1)
local group GroupTemp1 = CreateGroup()
local group GroupTemp2 = CreateGroup()
local unit UnitTemp1
local real RealTemp1
local real RealTemp2
local integer IntLoop1 = 1
//Hide ground units in the way:
call GroupEnumUnitsInRect(GroupTemp1, TargetRect, Filter1)
call RemoveRect(TargetRect)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call ShowUnit(UnitTemp1, false)
call GroupAddUnit(GroupTemp2, UnitTemp1)
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
endloop
//Check if target position is free:
loop
set RealTemp1 = GetFortificationAdditionPathCheckerPos(BuildingSiteID, PosX, PosY, Facing, IntLoop1, true)
exitwhen RealTemp1 == 99999.99
set RealTemp2 = GetFortificationAdditionPathCheckerPos(BuildingSiteID, PosX, PosY, Facing, IntLoop1, false)
set UnitTemp1 = CreateUnit(Owner, libId_udg_PathingCheckDummy, RealTemp1, RealTemp2, Facing)
exitwhen (GetUnitX(UnitTemp1) != RealTemp1 or GetUnitY(UnitTemp1) != RealTemp2)
call RemoveUnit(UnitTemp1)
set IntLoop1 = IntLoop1 + 1
endloop
//Create building site if target position is free:
if (RealTemp1 == 99999.99) then
set BuildingSite = CreateUnit(Owner, BuildingSiteID, PosX, PosY, Facing)
call SetUnitX(BuildingSite, PosX)
call SetUnitY(BuildingSite, PosY)
else
call RemoveUnit(UnitTemp1)
endif
//Show ground units in the way:
loop
set UnitTemp1 = FirstOfGroup(GroupTemp2)
exitwhen UnitTemp1 == null
call ShowUnit(UnitTemp1, true)
call GroupRemoveUnit(GroupTemp2, UnitTemp1)
endloop
//Anti-Memory-Leak:
call DestroyBoolExpr(Filter1)
set Filter1 = null
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
call DestroyGroup(GroupTemp2)
set GroupTemp2 = null
set UnitTemp1 = null
//-----------------
return BuildingSite
endfunction
//------------
//PUBLIC PART:
//------------
public function AdjustConstructingFortification takes unit Building returns boolean
local unit UnitTemp1 = null
local integer IntTemp1 = GetUnitTypeId(Building)
local integer IntTemp2
local integer IntTemp3
local integer IntTemp4 = 0
local integer IntTemp5
local integer IntTemp6
local integer IntLoop1 = 0
local integer IntLoop2
local integer IntLoop3
local real RealTemp1
local real RealTemp2
local real RealTemp3
local real RealTemp4
if (IsFortificationBuilding(IntTemp1)) then
set RealTemp1 = GetUnitX(Building)
set RealTemp2 = GetUnitY(Building)
//Get base walk building type:
set IntTemp1 = GetBaseWalkBuildingID(IntTemp1)
//Get adjusted facing and walk building type:
loop
set RealTemp3 = AdjustOrthogonalAngle(GetUnitFacing(Building) + IntLoop1 * 90.00)
exitwhen IntLoop1 >= 4
set IntLoop2 = 1
loop
set IntTemp2 = GetSubWalkBuildingID(IntTemp1, IntLoop2)
exitwhen IntTemp2 == 0
set IntTemp3 = 0
set IntTemp6 = GetFortificationBuildingAdjoiningSlots(IntTemp2)
set IntLoop3 = 1
loop
exitwhen IntLoop3 > IntTemp6
set UnitTemp1 = GetAdjoiningFortificationBuildingBySlot(IntTemp2, RealTemp1, RealTemp2, RealTemp3, IntLoop3, 0)
if (UnitTemp1 != null) then
set IntTemp3 = IntTemp3 + 1
endif
set IntLoop3 = IntLoop3 + 1
endloop
if (IntTemp3 > IntTemp4) then
set IntTemp4 = IntTemp3
set IntTemp5 = IntTemp2
set RealTemp4 = RealTemp3
endif
set IntLoop2 = IntLoop2 + 1
endloop
exitwhen IntLoop2 <= 1
set IntLoop1 = IntLoop1 + 1
endloop
//Change building, if adjustment is different to the stats of the given building:
if (IntTemp4 > 0 and (GetUnitTypeId(Building) != IntTemp5 or RealTemp4 != AdjustOrthogonalAngle(GetUnitFacing(Building)))) then
call ShowUnit(Building, false)
call libUnitDat_ChangeUnit(Building, CreateUnit(GetOwningPlayer(Building), IntTemp5, RealTemp1, RealTemp2, RealTemp4))
call RemoveUnit(Building)
set IntTemp1 = 0
endif
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
//-----------------
return (IntTemp1 == 0)
endfunction
public function AddBuildingUnderConstruction takes unit Building returns nothing
local integer BuildingID = GetUnitTypeId(Building)
local integer IntTemp1
if (GetWalkDestructableID(BuildingID, 0) != 0) then
//Add walk destructable if needed and adjust:
set IntTemp1 = libUnitDat_GetSystemNumberOfUnit(Building, udg_SystemSlot)
if (IntTemp1 == 0) then
set udg_WalkBuildingsCount = udg_WalkBuildingsCount + 1
set IntTemp1 = udg_WalkBuildingsCount
set udg_WalkBuildings[IntTemp1] = WalkBuilding.create()
if (udg_WalkBuildings[IntTemp1] == 0) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: WalkBuilding struct cap exceeded")
return
endif
call udg_WalkBuildings[IntTemp1].New(Building, IntTemp1)
endif
set udg_WalkBuildings[IntTemp1].UnderConstruction = true
call AdjustPathingForWalkBuildingGroup(GetDirectAdjoiningFortificationBuildings(Building, true), true)
endif
call RepositionBuilding(Building)
endfunction
public function RemoveBuildingUnderConstruction takes unit Building returns nothing
if (libUnitDat_GetSystemNumberOfUnit(Building, udg_SystemSlot) > 0) then
call RemoveWalkBuilding(Building)
endif
call AdjustWalkBuildingsAtPos(GetUnitX(Building), GetUnitY(Building))
endfunction
public function AdjustReplacedBuilding takes unit Building returns nothing
if (HasSmallPathing(GetUnitTypeId(Building))) then
call RepositionBuilding(Building)
endif
endfunction
//---------------------
//EVENT-TRIGGERED PART:
//---------------------
private function GateClosingOrOpeningStarts_Conditions takes nothing returns boolean
return (GetGateInfo(GetUnitTypeId(GetTriggerUnit()), 1) != 0)
endfunction
private function GateClosingOrOpeningStarts takes nothing returns nothing
local real CheckInterval = 0.5
local unit UnitTemp1 = GetTriggerUnit()
local unit UnitTemp2
local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
local integer IntTemp2 = libUnitDat_SetNoRecyclingOfUnit(UnitTemp1, true)
local real RealTemp1 = I2R(GetGateInfo(IntTemp1, 2)) * 0.7
loop
exitwhen RealTemp1 <= 0.00
if (RealTemp1 > CheckInterval) then
call TriggerSleepAction(CheckInterval)
else
call TriggerSleepAction(RealTemp1)
endif
set RealTemp1 = RealTemp1 - CheckInterval
set UnitTemp1 = libUnitDat_GetUnit(IntTemp2)
//Check if gate is dead or the closing/opening aborted:
exitwhen (UnitTemp1 == null or GetGateInfo(GetUnitTypeId(UnitTemp1), 1) == 0)
endloop
call libUnitDat_SetNoRecycling(IntTemp2, false)
if (UnitTemp1 == null) then
//Recycle object of dead gate:
call libUnitDat_RemoveObject(IntTemp2)
elseif (GetGateInfo(GetUnitTypeId(UnitTemp1), 1) != 0) then
//Change gate to closed/opened:
call ShowUnit(UnitTemp1, false)
set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), GetGateInfo(IntTemp1, 1), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1))
call libUnitDat_ChangeUnit(UnitTemp1, UnitTemp2)
call RemoveUnit(UnitTemp1)
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
set UnitTemp2 = null
endfunction
private function FortificationDies_Conditions takes nothing returns boolean
return (IsFortificationBuilding(GetUnitTypeId(GetDyingUnit())))
endfunction
private function FortificationDies_Filter1 takes nothing returns boolean
return (IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND) and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false)
endfunction
private function FortificationDies takes nothing returns nothing
local unit UnitTemp1 = GetDyingUnit()
local unit UnitTemp2
local group GroupTemp1
local boolexpr Filter1
local rect RectTemp1
local destructable DestructableTemp1
local integer IntLoop1 = 1
local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
local integer IntTemp2 = GetDestructedBuildingID(IntTemp1)
local real RealTemp1 = GetDestructionTime(IntTemp1)
local boolean IsOldWalkBuilding = (GetWalkDestructableID(IntTemp1, 0) != 0)
local boolean IsNewWalkBuilding = (GetWalkDestructableID(IntTemp2, 0) != 0)
if (IsOldWalkBuilding and GetRepairedBuildingID(IntTemp1) == 0) then
if (udg_WalkBuildings[libUnitDat_GetSystemNumberOfUnit(UnitTemp1, udg_SystemSlot)].UnderConstruction) then
set IntTemp2 = 0
set RealTemp1 = -1.00
set IsNewWalkBuilding = false
endif
endif
if (IsOldWalkBuilding) then
if (IsNewWalkBuilding == false) then
//Kill units on destroyed walkable building:
set GroupTemp1 = CreateGroup()
set RectTemp1 = GetFortificationBuildingAdjoiningRect(IntTemp1, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1)), 0, 0)
set Filter1 = Condition(function FortificationDies_Filter1)
call GroupEnumUnitsInRect(GroupTemp1, RectTemp1, Filter1)
loop
set UnitTemp2 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp2 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp2)
call KillUnit(UnitTemp2)
endloop
call DestroyGroup(GroupTemp1)
call DestroyBoolExpr(Filter1)
call RemoveRect(RectTemp1)
endif
call RemoveWalkBuilding(UnitTemp1)
endif
call AdjustPathingForWalkBuildingGroup(GetDirectAdjoiningFortificationBuildings(UnitTemp1, false), true)
if (IsNewWalkBuilding) then
//Create destructed version and hide it:
call ShowUnit(UnitTemp1, false)
set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), IntTemp2, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1))
call AddWalkBuilding(UnitTemp2)
call AdjustPathingForWalkBuildingGroup(GetDirectAdjoiningFortificationBuildings(UnitTemp2, true), true)
call ShowUnit(UnitTemp2, false)
call ShowUnit(UnitTemp1, true)
call RepositionBuilding(UnitTemp1)
elseif (IntTemp2 != 0) then
//Create pathing destructable of dying building:
set DestructableTemp1 = CreateDestructable(GetDyingPathDestructableID(IntTemp1), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1)), 1.00, 0)
endif
if (RealTemp1 > 0.00) then
call TriggerSleepAction(RealTemp1)
endif
if (IntTemp2 != 0) then
call ShowUnit(UnitTemp1, false)
if (IsNewWalkBuilding) then
call ShowUnit(UnitTemp2, true)
else
call RemoveDestructable(DestructableTemp1)
set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), IntTemp2, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1))
call libUnitDat_ChangeUnit(UnitTemp1, UnitTemp2)
endif
call RepositionBuilding(UnitTemp2)
call libUnitDat_RemoveObjectUnit(UnitTemp1)
elseif (RealTemp1 == -1.00) then
call libUnitDat_RemoveObjectUnit(UnitTemp1)
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
set UnitTemp2 = null
set GroupTemp1 = null
set Filter1 = null
set RectTemp1 = null
set DestructableTemp1 = null
endfunction
private function FortificationBuildsFinish_Conditions takes nothing returns boolean
return (IsFortificationBuilding(GetUnitTypeId(GetTriggerUnit())))
endfunction
private function FortificationBuildsFinish takes nothing returns nothing
local unit UnitTemp1 = GetTriggerUnit()
local unit UnitTemp2
local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
local boolean IsOldWalkBuilding = (GetWalkDestructableID(IntTemp1, 0) != 0)
local boolean IsNewWalkBuilding = IsOldWalkBuilding
set IntTemp1 = GetRepairedBuildingID(IntTemp1)
if (IntTemp1 != 0) then
set IsNewWalkBuilding = (GetWalkDestructableID(IntTemp1, 0) != 0)
endif
call TriggerSleepAction(0.01)
if (IsOldWalkBuilding and IsNewWalkBuilding == false) then
call RemoveWalkBuilding(UnitTemp1)
endif
//Change building, if it was rebuilt:
if (IntTemp1 != 0) then
call ShowUnit(UnitTemp1, false)
set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), IntTemp1, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1))
call libUnitDat_ChangeUnit(UnitTemp1, UnitTemp2)
call RemoveUnit(UnitTemp1)
call RepositionBuilding(UnitTemp2)
set UnitTemp1 = UnitTemp2
endif
if (IsNewWalkBuilding) then
if (IsOldWalkBuilding) then
set udg_WalkBuildings[libUnitDat_GetSystemNumberOfUnit(UnitTemp1, udg_SystemSlot)].UnderConstruction = false
else
call AddWalkBuilding(UnitTemp1)
endif
endif
call AdjustPathingForWalkBuildingGroup(GetDirectAdjoiningFortificationBuildings(UnitTemp1, true), true)
if (IsNewWalkBuilding and udg_TerrainDeformation) then
if (RaiseBuildingsOnSameHeight(GetAdjoiningFortificationBuildings(UnitTemp1)) and udg_RepositionOnlyFortifications <= 1) then
//Reposition all buildings:
if (udg_RepositionAllBuildingsRunning) then
set udg_RepositionAllBuildingsRestart = true
else
call TriggerSleepAction(0.01)
call RepositionAllBuildings()
endif
endif
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
set UnitTemp2 = null
endfunction
private function AddStairs_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_AddStairs)
endfunction
private function AddStairs takes nothing returns nothing
local unit UnitTemp1 = GetSpellAbilityUnit()
local player PlayerTemp1 = GetOwningPlayer(UnitTemp1)
local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
local real RealTemp1 = AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1))
local real RealTemp2 = GetUnitX(UnitTemp1)
local real RealTemp3 = GetUnitY(UnitTemp1)
local rect RectTemp1 = GetFortificationBuildingAdjoiningRect(IntTemp1, RealTemp2, RealTemp3, RealTemp1, 3, 1)
set UnitTemp1 = PlaceFortificationAddition(RectTemp1, PlayerTemp1, GetFortificationAdditionInfo(IntTemp1, 0, 1), RealTemp1)
if (UnitTemp1 != null) then
if (GetLocalPlayer() == PlayerTemp1) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call ClearSelection()
call SelectUnit(UnitTemp1, true)
endif
call IssueImmediateOrderById(UnitTemp1, GetFortificationAdditionInfo(IntTemp1, 0, 2))
else
call DisplayTextToPlayer(PlayerTemp1, 0, 0, "No place for stairs here.")
endif
//Anti-Memory-Leak:
set RectTemp1 = null
set UnitTemp1 = null
set PlayerTemp1 = null
endfunction
private function AddLadders_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_AddLadders)
endfunction
private function AddLadders takes nothing returns nothing
local unit UnitTemp1 = GetSpellAbilityUnit()
local unit UnitTemp2
call ShowUnit(UnitTemp1, false)
set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), GetFortificationAdditionInfo(GetUnitTypeId(UnitTemp1), 0, 2), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1)))
call libUnitDat_ChangeUnit(UnitTemp1, UnitTemp2)
call RemoveUnit(UnitTemp1)
call AdjustPathingForWalkBuildingGroup(GetDirectAdjoiningFortificationBuildings(UnitTemp2, true), true)
call RepositionBuilding(UnitTemp2)
if (GetLocalPlayer() == GetOwningPlayer(UnitTemp2)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call ClearSelection()
call SelectUnit(UnitTemp2, true)
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
set UnitTemp2 = null
endfunction
private function UseSiegeLadder_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_UseSiegeLadder and IsLadderTakeableBuilding(GetUnitTypeId(GetSpellTargetUnit())))
endfunction
private function UseSiegeLadder takes nothing returns nothing
local unit UnitTemp1 = GetSpellTargetUnit()
local unit UnitTemp2 = GetSpellAbilityUnit()
local player PlayerTemp1 = GetOwningPlayer(UnitTemp2)
local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
local integer IntTemp2 = GetUnitTypeId(UnitTemp2)
local real RealTemp1 = AdjustOrthogonalAngle(GetUnitFacing(UnitTemp1))
local real RealTemp2 = GetUnitX(UnitTemp1)
local real RealTemp3 = GetUnitY(UnitTemp1)
local rect RectTemp1 = GetFortificationBuildingAdjoiningRect(IntTemp1, RealTemp2, RealTemp3, RealTemp1, 4, 1)
if (RectTemp1 == null) then
set RectTemp1 = GetFortificationBuildingAdjoiningRect(IntTemp1, RealTemp2, RealTemp3, RealTemp1, 3, 1)
endif
set UnitTemp1 = PlaceFortificationAddition(RectTemp1, PlayerTemp1, GetFortificationAdditionInfo(IntTemp2, IntTemp1, 1), RealTemp1)
if (UnitTemp1 != null) then
call IssueImmediateOrder(UnitTemp2, "stop")
call UnitRemoveAbility(UnitTemp2, libId_udg_UseSiegeLadder)
call UnitAddAbility(UnitTemp2, libId_udg_AttackingCivilian)
call UnitRemoveAbility(UnitTemp2, GetFortificationAdditionInfo(IntTemp2, IntTemp1, 3))
call IssueImmediateOrderById(UnitTemp1, GetFortificationAdditionInfo(IntTemp2, IntTemp1, 2))
if (GetLocalPlayer() == PlayerTemp1) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call ClearSelection()
call SelectUnit(UnitTemp2, true)
endif
else
call DisplayTextToPlayer(PlayerTemp1, 0, 0, "No place for a ladder here.")
endif
//Anti-Memory-Leak:
set RectTemp1 = null
set UnitTemp1 = null
set UnitTemp2 = null
set PlayerTemp1 = null
endfunction
private function AutoUseSiegeLadder_Filter1 takes nothing returns boolean
return (GetUnitAbilityLevel(GetFilterUnit(), libId_udg_UseSiegeLadder) > 0 and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) >= 1.00)
endfunction
private function AutoUseSiegeLadder_Filter2 takes nothing returns boolean
return (IsLadderTakeableBuilding(GetUnitTypeId(GetFilterUnit())))
endfunction
private function AutoUseSiegeLadder_Filter3 takes nothing returns boolean
return (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE))
endfunction
private function AutoUseSiegeLadder takes nothing returns nothing
local boolexpr Filter1 = Condition(function AutoUseSiegeLadder_Filter1)
local boolexpr Filter2 = Condition(function AutoUseSiegeLadder_Filter2)
local boolexpr Filter3 = Condition(function AutoUseSiegeLadder_Filter3)
local group GroupTemp1 = CreateGroup()
local group GroupTemp2 = CreateGroup()
local group GroupTemp3 = CreateGroup()
local group GroupTemp4 = CreateGroup()
local unit UnitTemp1
local unit UnitTemp2
local unit UnitTemp3
local rect RectTemp1
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > 16
if (GetPlayerController(Player(IntLoop1 - 1)) == MAP_CONTROL_COMPUTER) then
call GroupEnumUnitsOfPlayer(GroupTemp1, Player(IntLoop1 - 1), Filter1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call GroupEnumUnitsInRange(GroupTemp2, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), udg_MaxLadderRadius, Filter2)
loop
set UnitTemp2 = FirstOfGroup(GroupTemp2)
exitwhen UnitTemp2 == null
call GroupRemoveUnit(GroupTemp2, UnitTemp2)
//Check if Wall isn't already a target and that it is from an enemy:
if (IsUnitInGroup(UnitTemp2, GroupTemp4) == false and GetPlayerAlliance(Player(IntLoop1 - 1), GetOwningPlayer(UnitTemp2), ALLIANCE_PASSIVE) == false) then
//Check if a structure is in the way:
set RectTemp1 = GetFortificationBuildingAdjoiningRect(GetUnitTypeId(UnitTemp2), GetUnitX(UnitTemp2), GetUnitY(UnitTemp2), AdjustOrthogonalAngle(GetUnitFacing(UnitTemp2)), 4, 1)
if (RectTemp1 == null) then
set RectTemp1 = GetFortificationBuildingAdjoiningRect(GetUnitTypeId(UnitTemp2), GetUnitX(UnitTemp2), GetUnitY(UnitTemp2), AdjustOrthogonalAngle(GetUnitFacing(UnitTemp2)), 3, 1)
endif
if (RectTemp1 != null) then
call GroupEnumUnitsInRect(GroupTemp3, RectTemp1, Filter3)
call RemoveRect(RectTemp1)
call GroupRemoveUnit(GroupTemp3, UnitTemp2)
set UnitTemp3 = FirstOfGroup(GroupTemp3)
call GroupClear(GroupTemp3)
if (UnitTemp3 == null) then
call IssueTargetOrder(UnitTemp1, "thunderbolt", UnitTemp2)
call GroupAddUnit(GroupTemp4, UnitTemp2)
exitwhen true
endif
endif
endif
endloop
call GroupClear(GroupTemp2)
endloop
endif
set IntLoop1 = IntLoop1 + 1
endloop
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
call DestroyGroup(GroupTemp2)
set GroupTemp2 = null
call DestroyGroup(GroupTemp3)
set GroupTemp3 = null
call DestroyGroup(GroupTemp4)
set GroupTemp4 = null
call DestroyBoolExpr(Filter1)
set Filter1 = null
call DestroyBoolExpr(Filter2)
set Filter2 = null
call DestroyBoolExpr(Filter3)
set Filter3 = null
set UnitTemp1 = null
set UnitTemp2 = null
set UnitTemp3 = null
set RectTemp1 = null
endfunction
private function SmallPathingBuildsStart_Conditions takes nothing returns boolean
return (HasSmallPathing(GetUnitTypeId(GetConstructingStructure())) or HasSmallPathing(GetUnitTypeId(GetTriggerUnit())))
endfunction
private function SmallPathingBuildsStart takes nothing returns nothing
local unit UnitTemp1 = GetConstructingStructure()
if (UnitTemp1 == null) then
set UnitTemp1 = GetTriggerUnit()
endif
call RepositionBuilding(UnitTemp1)
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function DisableMovementFinish_Conditions takes nothing returns boolean
return (IsUnitWithoutMovement(GetUnitTypeId(GetConstructedStructure())) or IsUnitWithoutMovement(GetUnitTypeId(GetTriggerUnit())))
endfunction
private function DisableMovementFinish takes nothing returns nothing
local unit UnitTemp1 = GetConstructedStructure()
if (UnitTemp1 == null) then
set UnitTemp1 = GetTriggerUnit()
endif
call SetUnitPropWindow(UnitTemp1, 0)
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
//original "private" function changed to "public" for 'CustomResourceSystem' compatibility:
public function SmartOrderOnWalkableBuilding_Conditions takes nothing returns boolean
return (OrderId2String(GetIssuedOrderId()) == "smart" and GetWalkDestructableID(GetUnitTypeId(GetOrderTargetUnit()), 0) != 0 and IsUnitType(GetOrderedUnit(), UNIT_TYPE_PEON) == false)
endfunction
private function SmartOrderOnWalkableBuilding takes nothing returns nothing
local unit OrderedUnit = GetOrderedUnit()
local unit Fortification = GetOrderTargetUnit()
call IssuePointOrder(OrderedUnit, "move", GetUnitX(Fortification), GetUnitY(Fortification))
//Anti-Memory-Leak:
set OrderedUnit = null
set Fortification = null
endfunction
//---------------
//INITIALISATION:
//---------------
private function CreateInitWalls_Filter1 takes nothing returns boolean
return (GetReplacingInitBuildingID(GetUnitTypeId(GetFilterUnit())) != 0)
endfunction
private function CreateInitWalls_Filter2 takes nothing returns boolean
return (IsFortificationBuilding(GetUnitTypeId(GetFilterUnit())))
endfunction
private function CreateInitWalls takes nothing returns nothing
local group GroupTemp1 = CreateGroup()
local group GroupTemp2 = CreateGroup()
local group GroupTemp3
local boolexpr Filter1 = Condition(function CreateInitWalls_Filter1)
local boolexpr Filter2
local unit UnitTemp1
local unit UnitTemp2
local integer IntTemp1
local integer IntLoop1 = 1
//Replace init units:
call GroupEnumUnitsInRect(GroupTemp1, bj_mapInitialPlayableArea, Filter1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call ShowUnit(UnitTemp1, false)
set IntTemp1 = GetReplacingInitBuildingID(GetUnitTypeId(UnitTemp1))
set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), IntTemp1, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1))
if (GetWalkDestructableID(IntTemp1, 0) != 0) then
call AddWalkBuilding(UnitTemp2)
call GroupAddUnit(GroupTemp2, UnitTemp2)
endif
call RemoveUnit(UnitTemp1)
set IntLoop1 = IntLoop1 + 1
if (IntLoop1 >= 200) then
set IntLoop1 = 0
call TriggerSleepAction(0.01)
endif
endloop
call TriggerSleepAction(0.01)
call RepositionAllBuildings()
call TriggerSleepAction(0.01)
//Adjust replaced units:
call DestroyGroup(GroupTemp1)
call AdjustPathingForWalkBuildingGroup(GroupTemp2, false)
//Adjust building heights:
if (udg_TerrainDeformation) then
call TriggerSleepAction(0.01)
set Filter2 = Condition(function CreateInitWalls_Filter2)
set GroupTemp2 = CreateGroup()
call GroupEnumUnitsInRect(GroupTemp2, bj_mapInitialPlayableArea, Filter2)
call DestroyBoolExpr(Filter2)
set GroupTemp1 = CreateGroup()
loop
set UnitTemp1 = FirstOfGroup(GroupTemp2)
exitwhen UnitTemp1 == null
call GroupClear(GroupTemp1)
set GroupTemp3 = GroupTemp1
set GroupTemp1 = GetAdjoiningFortificationBuildings(UnitTemp1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call GroupRemoveUnit(GroupTemp2, UnitTemp1)
call GroupAddUnit(GroupTemp3, UnitTemp1)
endloop
//Raise adjoining buildings on same height:
call RaiseBuildingsOnSameHeight(GroupTemp3)
endloop
call DestroyGroup(GroupTemp1)
if (udg_RepositionOnlyFortifications <= 2) then
//Reposition all buildings:
if (udg_RepositionAllBuildingsRunning) then
set udg_RepositionAllBuildingsRestart = true
else
call TriggerSleepAction(0.01)
call RepositionAllBuildings()
endif
endif
endif
call DestroyGroup(GroupTemp2)
set udg_InitFinished = true
//Anti-Memory-Leak:
set GroupTemp1 = null
set GroupTemp2 = null
set GroupTemp3 = null
call DestroyBoolExpr(Filter1)
set Filter1 = null
set Filter2 = null
set UnitTemp1 = null
set UnitTemp2 = null
endfunction
private function DisableMovementInit_Filter1 takes nothing returns boolean
return (IsUnitWithoutMovement(GetUnitTypeId(GetFilterUnit())))
endfunction
private function DisableMovementInit takes nothing returns nothing
local boolexpr Filter1 = Condition(function DisableMovementInit_Filter1)
local group GroupTemp1 = CreateGroup()
local unit UnitTemp1
call TriggerSleepAction(0.01)
call GroupEnumUnitsInRect(GroupTemp1, bj_mapInitialPlayableArea, Filter1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call SetUnitPropWindow(UnitTemp1, 0)
endloop
//Anti-Memory-Leak:
call DestroyBoolExpr(Filter1)
set Filter1 = null
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
endfunction
private function Init_WallSystem takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers and variables:
call TriggerRegisterTimerEvent(gg_trg_AutoUseSiegeLadder, udg_AutoUseSiegeLadderRate, true)
loop
exitwhen IntLoop1 > udg_CountPlayers
call TriggerRegisterPlayerUnitEvent(gg_trg_GateClosingOrOpeningStarts, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_START, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_FortificationDies, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_FortificationBuildsFinish, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_FINISH, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_AddStairs, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_AddLadders, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_UseSiegeLadder, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_SmallPathingBuildsStart, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_CONSTRUCT_START, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_SmallPathingBuildsStart, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_START, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_DisableMovementFinish, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_FINISH, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_DisableMovementFinish, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_CONSTRUCT_FINISH, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_SmartOrderOnWalkableBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Conditions:
call TriggerAddCondition(gg_trg_GateClosingOrOpeningStarts, Condition(function GateClosingOrOpeningStarts_Conditions))
call TriggerAddCondition(gg_trg_FortificationDies, Condition(function FortificationDies_Conditions))
call TriggerAddCondition(gg_trg_FortificationBuildsFinish, Condition(function FortificationBuildsFinish_Conditions))
call TriggerAddCondition(gg_trg_AddStairs, Condition(function AddStairs_Conditions))
call TriggerAddCondition(gg_trg_AddLadders, Condition(function AddLadders_Conditions))
call TriggerAddCondition(gg_trg_UseSiegeLadder, Condition(function UseSiegeLadder_Conditions))
call TriggerAddCondition(gg_trg_SmallPathingBuildsStart, Condition(function SmallPathingBuildsStart_Conditions))
call TriggerAddCondition(gg_trg_DisableMovementFinish, Condition(function DisableMovementFinish_Conditions))
call TriggerAddCondition(gg_trg_SmartOrderOnWalkableBuilding, Condition(function SmartOrderOnWalkableBuilding_Conditions))
//Actions:
call TriggerAddAction(gg_trg_GateClosingOrOpeningStarts, function GateClosingOrOpeningStarts)
call TriggerAddAction(gg_trg_FortificationDies, function FortificationDies)
call TriggerAddAction(gg_trg_FortificationBuildsFinish, function FortificationBuildsFinish)
call TriggerAddAction(gg_trg_AddStairs, function AddStairs)
call TriggerAddAction(gg_trg_AddLadders, function AddLadders)
call TriggerAddAction(gg_trg_UseSiegeLadder, function UseSiegeLadder)
call TriggerAddAction(gg_trg_AutoUseSiegeLadder, function AutoUseSiegeLadder)
call TriggerAddAction(gg_trg_SmallPathingBuildsStart, function SmallPathingBuildsStart)
call TriggerAddAction(gg_trg_DisableMovementFinish, function DisableMovementFinish)
call TriggerAddAction(gg_trg_SmartOrderOnWalkableBuilding, function SmartOrderOnWalkableBuilding)
//Init functions:
call CreateInitWalls()
call DisableMovementInit()
endfunction
endlibrary
/*-------------------------------------------------------------
//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_FirePit or BuildingID == libId_udg_LightP1 or BuildingID == libId_udg_LightP2 or BuildingID == libId_udg_Stash1 or BuildingID == libId_udg_Stash2) then //Lights & Stash
return 10.00
elseif (BuildingID == libId_udg_Banner1 or BuildingID == libId_udg_Banner2 or BuildingID == libId_udg_LadderPalisade or BuildingID == libId_udg_LadderWall) then //Banner (1,2)
return 10.00
elseif (BuildingID == libId_udg_Statue1 or BuildingID == libId_udg_Statue2 or BuildingID == libId_udg_Fountain1 or BuildingID == libId_udg_Fountain2) then //Statues & Fountains
return 30.00
elseif (BuildingID == libId_udg_Well1 or BuildingID == libId_udg_Well2 or BuildingID == libId_udg_Well3) then //Well (1,2,3)
return 10.00
//Building Site - Misc:
elseif (BuildingID == libId_udg_Barricade) then //Barricade
return 10.00
elseif (BuildingID == libId_udg_TrainD1 or BuildingID == libId_udg_TrainD2 or BuildingID == libId_udg_TrainD3 or BuildingID == libId_udg_Target1 or BuildingID == libId_udg_Target2) then //Dummys
return 10.00
//Building Site - Small:
elseif (BuildingID == libId_udg_House1 or BuildingID == libId_udg_House2 or BuildingID == libId_udg_House3 or BuildingID == libId_udg_House4) then //Houses
return 20.00
elseif (BuildingID == libId_udg_Tent1 or BuildingID == libId_udg_Tent2 or BuildingID == libId_udg_Tent3 or BuildingID == libId_udg_Path1 or BuildingID == libId_udg_Path2 or BuildingID == libId_udg_Path3) then //Tents & Paths
return 10.00
//Building Site - Fortification:
elseif (BuildingID == libId_udg_Tower1 or BuildingID == libId_udg_Tower2 or BuildingID == libId_udg_Tower3 or BuildingID == libId_udg_Tower4) then //Towers
return 35.00
elseif (BuildingID == libId_udg_TowerB1 or BuildingID == libId_udg_TowerB2) then //Bell Tower (1,2)
return 45.00
elseif (BuildingID == libId_udg_TowerR or BuildingID == libId_udg_TowerS or BuildingID == libId_udg_BigGateCl) then //TowerBig & GateBig
return 45.00
elseif (BuildingID == libId_udg_TowerRB or BuildingID == libId_udg_TowerRC or BuildingID == libId_udg_TowerSB or BuildingID == libId_udg_TowerSC) then //TowerUP
return 45.00
elseif (BuildingID == libId_udg_GateCl) then //Gate (Closed)
return 35.00
elseif (BuildingID == libId_udg_PalisadeGateCl) then //Palisade gate (Closed)
return 25.00
elseif (BuildingID == libId_udg_WallUn or BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallIEUn) then //Wall (all Undamaged)
return 20.00
elseif (BuildingID == libId_udg_PalisadeUn or BuildingID == libId_udg_PalisadeOEUn or BuildingID == libId_udg_PalisadeIEUn) then //Palisade (all Undamaged)
return 10.00
elseif (BuildingID == libId_udg_TowerUn or BuildingID == libId_udg_TowerOEUn or BuildingID == libId_udg_TowerIEUn) then //Tower (all Undamaged)
return 60.00
elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerIEUn) then //Big tower (all Undamaged)
return 75.00
elseif (BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (all Undamaged)
return 75.00
//Building Site - Wide:
elseif (BuildingID == libId_udg_LongHall1 or BuildingID == libId_udg_LongHall2 or BuildingID == libId_udg_LongHall3 or BuildingID == libId_udg_LongHall4) then //Long Halls
return 50.00
elseif (BuildingID == libId_udg_Manor1 or BuildingID == libId_udg_Manor2 or BuildingID == libId_udg_Manor3 or BuildingID == libId_udg_Tavern1 or BuildingID == libId_udg_Tavern2 or BuildingID == libId_udg_Tavern3) then //Manors + Taverns
return 30.00
elseif (BuildingID == libId_udg_Barn1 or BuildingID == libId_udg_Barn2 or BuildingID == libId_udg_Barn3 or BuildingID == libId_udg_WindMill1 or BuildingID == libId_udg_WindMill2) then //Barns
return 30.00
elseif (BuildingID == libId_udg_Forge1 or BuildingID == libId_udg_Forge2 or BuildingID == libId_udg_Forge3 or BuildingID == libId_udg_Forge4) then //Forges
return 40.00
elseif (BuildingID == libId_udg_LumberMill1 or BuildingID == libId_udg_LumberMill2 or BuildingID == libId_udg_LumberMill3 or BuildingID == libId_udg_LumberMill4) then //Lumber Mill (1)
return 30.00
elseif (BuildingID == libId_udg_StoneMill1 or BuildingID == libId_udg_StoneMill2 or BuildingID == libId_udg_StoneMill3 or BuildingID == libId_udg_StoneMill4) then //Stone Mill (1)
return 30.00
//Building Site - Medium:
elseif (BuildingID == libId_udg_GreatHall1 or BuildingID == libId_udg_GreatHall2 or BuildingID == libId_udg_GreatHall3) then //Great Halls
return 60.00
elseif (BuildingID == libId_udg_University1 or BuildingID == libId_udg_University2) then //Universities
return 75.00
elseif (BuildingID == libId_udg_Warehouse1 or BuildingID == libId_udg_Warehouse2 or BuildingID == libId_udg_Warehouse3 or BuildingID == libId_udg_WaterMill1 or BuildingID == libId_udg_WaterMill2 or BuildingID == libId_udg_WaterMill3) then //W + WM
return 45.00
elseif (BuildingID == libId_udg_Altar1 or BuildingID == libId_udg_Altar2 or BuildingID == libId_udg_TrainG1 or BuildingID == libId_udg_TrainG2) then //Altar & Training Grounds
return 30.00
//Building Site - Large:
elseif (BuildingID == libId_udg_Barracks1 or BuildingID == libId_udg_Barracks2 or BuildingID == libId_udg_Barracks3 or BuildingID == libId_udg_Barracks4) then //Barracks
return 60.00
elseif (BuildingID == libId_udg_ArcheryR1 or BuildingID == libId_udg_ArcheryR2 or BuildingID == libId_udg_ArcheryR3 or BuildingID == libId_udg_Stables1 or BuildingID == libId_udg_Stables2 or BuildingID == libId_udg_Stables3) then //AR + Stbls
return 60.00
elseif (BuildingID == libId_udg_Workshop1 or BuildingID == libId_udg_Workshop2 or BuildingID == libId_udg_Workshop3 or BuildingID == libId_udg_Docks1 or BuildingID == libId_udg_Docks2 or BuildingID == libId_udg_Docks3) then //WS + Dcks
return 60.00
elseif (BuildingID == libId_udg_VillageSquare or BuildingID == libId_udg_Granary1 or BuildingID == libId_udg_Granary2 or BuildingID == libId_udg_Granary3) then //Village Square+
return 30.00
//Building Site - Huge:
elseif (BuildingID == libId_udg_Stronghold) then //Stronghold
return 120.00
elseif (BuildingID == libId_udg_Cathedral1 or BuildingID == libId_udg_Cathedral2 or BuildingID == libId_udg_Cathedral3) then //Cathedrals
return 75.00
elseif (BuildingID == libId_udg_Market1 or BuildingID == libId_udg_Market2 or BuildingID == libId_udg_Market3 or BuildingID == libId_udg_Market4) then //Markets
return 30.00
//Building site (special):
elseif (BuildingID == libId_udg_Stairs) then //Stairs
return 10.00
elseif (BuildingID == libId_udg_LadderWall or BuildingID == libId_udg_LadderPalisade) then //Ladders
return 10.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 20.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 35.00
elseif (BuildingID == libId_udg_PalisadeGateDa) then //Palisade gate (Damaged)
return 25.00
elseif (BuildingID == libId_udg_BigGateDa) then //Big gate (Damaged)
return 45.00
elseif (BuildingID == libId_udg_TowerDa or BuildingID == libId_udg_TowerOEDa or BuildingID == libId_udg_TowerIEDa) then //Tower (all Damaged)
return 60.00
elseif (BuildingID == libId_udg_TowerDe or BuildingID == libId_udg_TowerOEDe or BuildingID == libId_udg_TowerIEDe) then //Tower (all Destroyed)
return 60.00
elseif (BuildingID == libId_udg_BigTowerDa or BuildingID == libId_udg_BigTowerOEDa or BuildingID == libId_udg_BigTowerIEDa) then //Big tower (all Damaged)
return 70.00
elseif (BuildingID == libId_udg_BigTowerDe or BuildingID == libId_udg_BigTowerOEDe or BuildingID == libId_udg_BigTowerIEDe) then //Big tower (all Destroyed)
return 70.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 or BuildingID == libId_udg_TrainD2 or BuildingID == libId_udg_Target1) then
return 0.45
elseif (BuildingID == libId_udg_LongHall1 or BuildingID == libId_udg_LongHall2 or BuildingID == libId_udg_LongHall3 or BuildingID == libId_udg_LongHall4 or BuildingID == libId_udg_VillageSquare) then
return 1.80
elseif (BuildingID == libId_udg_GreatHall1 or BuildingID == libId_udg_GreatHall2 or BuildingID == libId_udg_GreatHall3 or BuildingID == libId_udg_Granary1 or BuildingID == libId_udg_Granary2 or BuildingID == libId_udg_Granary3) then
return 1.55
elseif (BuildingID == libId_udg_University1 or BuildingID == libId_udg_University2) then
return 1.70
elseif (BuildingID == libId_udg_Barracks1 or BuildingID == libId_udg_Barracks2 or BuildingID == libId_udg_Barracks3 or BuildingID == libId_udg_Barracks4) then
return 2.25
elseif (BuildingID == libId_udg_TrainD1 or BuildingID == libId_udg_TrainD3 or BuildingID == libId_udg_LightP2 or BuildingID == libId_udg_Banner1 or BuildingID == libId_udg_Banner2 or BuildingID == libId_udg_Target2) then
return 0.70
elseif (BuildingID == libId_udg_Stash1 or BuildingID == libId_udg_Stash2 or BuildingID == libId_udg_Statue2 or BuildingID == libId_udg_Fountain2 or BuildingID == libId_udg_Altar1) then
return 0.30
elseif (BuildingID == libId_udg_Well1 or BuildingID == libId_udg_Well2 or BuildingID == libId_udg_Tent1 or BuildingID == libId_udg_Tent3 or BuildingID == libId_udg_Well3) then
return 0.80
elseif (BuildingID == libId_udg_House1 or BuildingID == libId_udg_House2 or BuildingID == libId_udg_House3 or BuildingID == libId_udg_House4 or BuildingID == libId_udg_Warehouse1 or BuildingID == libId_udg_Warehouse2 or BuildingID == libId_udg_Warehouse3) then
return 1.40
elseif (BuildingID == libId_udg_Forge1 or BuildingID == libId_udg_Forge2 or BuildingID == libId_udg_Forge3 or BuildingID == libId_udg_Forge4 or BuildingID == libId_udg_Stables1 or BuildingID == libId_udg_Stables2 or BuildingID == libId_udg_Stables3) then
return 1.40
elseif (BuildingID == libId_udg_Cathedral1 or BuildingID == libId_udg_Cathedral2 or BuildingID == libId_udg_Cathedral3 or BuildingID == libId_udg_Tavern1 or BuildingID == libId_udg_Tavern2 or BuildingID == libId_udg_Tavern3 or BuildingID == libId_udg_Tent2) then
return 1.40
elseif (BuildingID == libId_udg_WaterMill1 or BuildingID == libId_udg_WaterMill2 or BuildingID == libId_udg_WaterMill3 or BuildingID == libId_udg_Workshop1 or BuildingID == libId_udg_Workshop2 or BuildingID == libId_udg_Workshop3) then
return 1.45
elseif (BuildingID == libId_udg_WindMill1 or BuildingID == libId_udg_WindMill2) then
return 1.45
elseif (BuildingID == libId_udg_ArcheryR1 or BuildingID == libId_udg_ArcheryR2 or BuildingID == libId_udg_ArcheryR3 or BuildingID == libId_udg_Tower1 or BuildingID == libId_udg_Tower2 or BuildingID == libId_udg_Tower3 or BuildingID == libId_udg_Tower4) then
return 1.25
elseif (BuildingID == libId_udg_Manor1 or BuildingID == libId_udg_Manor2 or BuildingID == libId_udg_Manor3 or BuildingID == libId_udg_TowerB1 or BuildingID == libId_udg_FirePit) then
return 1.25
elseif (BuildingID == libId_udg_LumberMill1 or BuildingID == libId_udg_LumberMill2 or BuildingID == libId_udg_LumberMill3 or BuildingID == libId_udg_LumberMill4) then
return 1.60
elseif (BuildingID == libId_udg_StoneMill1 or BuildingID == libId_udg_StoneMill2 or BuildingID == libId_udg_StoneMill3 or BuildingID == libId_udg_StoneMill4) then
return 1.60
elseif (BuildingID == libId_udg_Market1 or BuildingID == libId_udg_Market2 or BuildingID == libId_udg_Market3 or BuildingID == libId_udg_Market4 or BuildingID == libId_udg_TowerB2) then
return 1.60
elseif (BuildingID == libId_udg_Docks1 or BuildingID == libId_udg_Docks2 or BuildingID == libId_udg_Docks3) then
return 2.00
elseif (BuildingID == libId_udg_TowerR or BuildingID == libId_udg_TowerRB or BuildingID == libId_udg_TowerRC or BuildingID == libId_udg_TowerS or BuildingID == libId_udg_TowerSB or BuildingID == libId_udg_TowerSC) then
return 1.10
elseif (BuildingID == libId_udg_Barn1 or BuildingID == libId_udg_Barn2 or BuildingID == libId_udg_Barn3 or BuildingID == libId_udg_Altar2) then
return 1.15
elseif (BuildingID == libId_udg_TrainG1 or BuildingID == libId_udg_TrainG2) then
return 1.20
elseif (BuildingID == libId_udg_Stronghold) then
return 0.60
endif
return 1.00
endfunction
//Returns the minimal/maximal number of required/allowed workers of the given type number for the given building type:
private function GetNeededWorkers takes integer BuildingID, integer WorkerSlot, boolean ReturnMin returns integer
//Building Site - Misc:
if (BuildingID == libId_udg_Barricade or BuildingID == libId_udg_TrainD1 or BuildingID == libId_udg_TrainD2 or BuildingID == libId_udg_TrainD3 or BuildingID == libId_udg_Target1 or BuildingID == libId_udg_Target2) then //Misc
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
//Building Site - Tiny:
elseif (BuildingID == libId_udg_FirePit or BuildingID == libId_udg_LightP1 or BuildingID == libId_udg_LightP2 or BuildingID == libId_udg_Banner1 or BuildingID == libId_udg_Banner2 or BuildingID == libId_udg_LadderWall or BuildingID == libId_udg_LadderPalisade) then
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_Statue1 or BuildingID == libId_udg_Statue2 or BuildingID == libId_udg_Fountain1 or BuildingID == libId_udg_Fountain2 or BuildingID == libId_udg_WindMill1 or BuildingID == libId_udg_WindMill2) then //Statue (1,2)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_Well1 or BuildingID == libId_udg_Well2 or BuildingID == libId_udg_Well3 or BuildingID == libId_udg_Stash1 or BuildingID == libId_udg_Stash2) then //Well (1,2,3)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
//Building Site - Small:
elseif (BuildingID == libId_udg_House1 or BuildingID == libId_udg_House2 or BuildingID == libId_udg_House3 or BuildingID == libId_udg_House4) then //House (1,2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_Tent1 or BuildingID == libId_udg_Tent2 or BuildingID == libId_udg_Tent3 or BuildingID == libId_udg_Path1 or BuildingID == libId_udg_Path2 or BuildingID == libId_udg_Path3) then //Tents & Paths
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
//Building Site - Fortification:
elseif (BuildingID == libId_udg_Tower1 or BuildingID == libId_udg_Tower2 or BuildingID == libId_udg_Tower3 or BuildingID == libId_udg_Tower4 or BuildingID == libId_udg_TowerB1 or BuildingID == libId_udg_TowerB2) then //Tower (1,2,3,4) & Bell
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_TowerR or BuildingID == libId_udg_TowerRB or BuildingID == libId_udg_TowerRC or BuildingID == libId_udg_TowerS or BuildingID == libId_udg_TowerSB or BuildingID == libId_udg_TowerSC) then //Tower Round/Square
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_GateCl or BuildingID == libId_udg_WallUn or BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallIEUn) then //Gate + Wall
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_PalisadeGateCl or BuildingID == libId_udg_PalisadeUn or BuildingID == libId_udg_PalisadeOEUn or BuildingID == libId_udg_PalisadeIEUn) then //Palisade
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_BigGateCl or BuildingID == libId_udg_TowerUn or BuildingID == libId_udg_TowerOEUn or BuildingID == libId_udg_TowerIEUn) then //Big Gate + Tower
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerIEUn or BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerIEUn) then //Big/Drum Tower (all Undamaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
//Building Site - Wide:
elseif (BuildingID == libId_udg_LongHall1 or BuildingID == libId_udg_LumberMill1 or BuildingID == libId_udg_StoneMill1 or BuildingID == libId_udg_Granary1 or BuildingID == libId_udg_Granary2 or BuildingID == libId_udg_Granary3) then //Long Hall (1) + Mills (1)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_LongHall2 or BuildingID == libId_udg_LongHall3 or BuildingID == libId_udg_LongHall4 or BuildingID == libId_udg_Barn1 or BuildingID == libId_udg_Barn2 or BuildingID == libId_udg_Barn3) then //Long Hall (2,3,4) + Barns
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_Manor1 or BuildingID == libId_udg_Manor2 or BuildingID == libId_udg_Manor3 or BuildingID == libId_udg_Tavern1 or BuildingID == libId_udg_Tavern2 or BuildingID == libId_udg_Tavern3) then //Manors + Taverns
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_Forge1 or BuildingID == libId_udg_Forge2 or BuildingID == libId_udg_Forge3 or BuildingID == libId_udg_Forge4) then //Forge (1,2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_LumberMill2 or BuildingID == libId_udg_LumberMill3 or BuildingID == libId_udg_LumberMill4) then //Lumber Mill (2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_StoneMill2 or BuildingID == libId_udg_StoneMill3 or BuildingID == libId_udg_StoneMill4) then //Stone Mill (2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
//Building Site - Medium:
elseif (BuildingID == libId_udg_GreatHall1 or BuildingID == libId_udg_GreatHall2 or BuildingID == libId_udg_GreatHall3 or BuildingID == libId_udg_University1 or BuildingID == libId_udg_University2) then //Great Halls & Universities
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_WaterMill1 or BuildingID == libId_udg_WaterMill2 or BuildingID == libId_udg_WaterMill3 or BuildingID == libId_udg_Warehouse1 or BuildingID == libId_udg_Warehouse2 or BuildingID == libId_udg_Warehouse3) then //WM + WH
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_Altar1 or BuildingID == libId_udg_Altar2) then //Altar (1,2)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_TrainG1 or BuildingID == libId_udg_TrainG2 or BuildingID == libId_udg_VillageSquare) then // Grounds
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
//Building Site - Large:
elseif (BuildingID == libId_udg_Barracks1 or BuildingID == libId_udg_Barracks2 or BuildingID == libId_udg_Barracks3 or BuildingID == libId_udg_Barracks4) then //Barracks (1,2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_ArcheryR1 or BuildingID == libId_udg_ArcheryR2 or BuildingID == libId_udg_ArcheryR3 or BuildingID == libId_udg_Stables1 or BuildingID == libId_udg_Stables2 or BuildingID == libId_udg_Stables3) then //AR + Stbls
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_Workshop1 or BuildingID == libId_udg_Workshop2 or BuildingID == libId_udg_Workshop3 or BuildingID == libId_udg_Docks1 or BuildingID == libId_udg_Docks2 or BuildingID == libId_udg_Docks3) then //WS + Dcks
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
//Building Site - Huge:
elseif (BuildingID == libId_udg_Stronghold) then //Stronghold
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 25
endif
endif
elseif (BuildingID == libId_udg_Cathedral1 or BuildingID == libId_udg_Cathedral2 or BuildingID == libId_udg_Cathedral3) then //Cathedral (1,2,3)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 15
endif
endif
elseif (BuildingID == libId_udg_Market1 or BuildingID == libId_udg_Market2 or BuildingID == libId_udg_Market3 or BuildingID == libId_udg_Market4) then //Market (1,2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
//Building site (special):
elseif (BuildingID == libId_udg_Stairs or BuildingID == libId_udg_PalisadeGateDa) then //Stairs + P Gate
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
endif
endif
elseif (BuildingID == libId_udg_GateDa or BuildingID == libId_udg_BigGateDa) then //Gate (Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
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 10
endif
endif
elseif (BuildingID == libId_udg_WallDe or BuildingID == libId_udg_WallOEDe or BuildingID == libId_udg_WallIEDe) then //Wall (all Destroyed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 10
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 10
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 10
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 10
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 1
else
return 10
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 10
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 1
else
return 10
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 10
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 1
else
return 10
endif
endif
endif
return 0
endfunction
//Returns the building site for the given building type (only required for multi-edge fortifications):
private function GetBuildingSiteID takes integer BuildingID returns integer
if (BuildingID == libId_udg_WallUn) then //Wall (Undamaged)
return libId_udg_BuildingSiteFort //Building Site - Fortification
elseif (BuildingID == libId_udg_WallOEUn) then //Wall (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_WallIEUn) then //Wall (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_PalisadeUn) then //Palisade (Undamaged)
return libId_udg_BuildingSiteFort //Building Site - Fortification
elseif (BuildingID == libId_udg_PalisadeOEUn) then //Palisade (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_PalisadeIEUn) then //Palisade (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_TowerUn) then //Tower (Undamaged)
return libId_udg_BuildingSiteFort //Building Site - Fortification
elseif (BuildingID == libId_udg_TowerOEUn) then //Tower (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_TowerIEUn) then //Tower (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_BigTowerUn) then //Big tower (Undamaged)
return libId_udg_BuildingSiteFort //Building Site - Fortification
elseif (BuildingID == libId_udg_BigTowerOEUn) then //Big tower (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_BigTowerIEUn) then //Big tower (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_DrumTowerUn) then //Drum tower (Undamaged)
return libId_udg_BuildingSiteFort //Building Site - Fortification
elseif (BuildingID == libId_udg_DrumTowerOEUn) then //Drum tower (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
endif
return 0
endfunction
// ADDED BY WIETLOL
private function UnitTypeIdIsInWorkerSlot takes integer unitTypeId, integer workerSlot returns boolean
if (workerSlot == 1) then
return unitTypeId == libId_udg_Worker or unitTypeId == libId_udg_Worker1b or unitTypeId == libId_udg_Worker2a or unitTypeId == libId_udg_Worker2b or unitTypeId == libId_udg_Worker3a or unitTypeId == libId_udg_Worker3b or unitTypeId == libId_udg_Worker4a or unitTypeId == libId_udg_Worker4b or unitTypeId == libId_udg_Worker1e or unitTypeId == libId_udg_Worker2e
elseif (workerSlot == 2) then
return unitTypeId == libId_udg_Architect or unitTypeId == libId_udg_Architect2 or unitTypeId == libId_udg_Architect3
endif
return false
endfunction
// END BY WIETLOL
//Returns the unit type of the given WorkerSlot:
private function WorkerSlot2UnitID takes integer WorkerSlot returns integer
if (WorkerSlot == 1) then
return libId_udg_Worker //Worker
elseif (WorkerSlot == 1) then
return libId_udg_Worker1b //Worker (1)
elseif (WorkerSlot == 1) then
return libId_udg_Worker2a //Worker (2)
elseif (WorkerSlot == 1) then
return libId_udg_Worker2b //Worker (2)
elseif (WorkerSlot == 1) then
return libId_udg_Worker3a //Worker (3)
elseif (WorkerSlot == 1) then
return libId_udg_Worker3b //Worker (3)
elseif (WorkerSlot == 1) then
return libId_udg_Worker4a //Worker (4)
elseif (WorkerSlot == 1) then
return libId_udg_Worker4b //Worker (4)
elseif (WorkerSlot == 1) then
return libId_udg_Worker1e //Engineer (1)
elseif (WorkerSlot == 1) then
return libId_udg_Worker2e //Engineer (2)
elseif (WorkerSlot == 2) then
return libId_udg_Architect //Architect
elseif (WorkerSlot == 2) then
return libId_udg_Architect2 //Architect (2)
elseif (WorkerSlot == 2) then
return libId_udg_Architect3 //Architect (3)
endif
return 0
endfunction
//Returns the square size of the given building site type:
private function GetBuildingSiteSquareSize takes integer BuildingID returns real
if (BuildingID == libId_udg_BuildingSiteTiny) then //Building Site - Tiny
return 64.00
elseif (BuildingID == libId_udg_BuildingSiteMisc) then //Building Site - Misc
return 64.00
elseif (BuildingID == libId_udg_BuildingSiteSmall) then //Building site - Small
return 128.00
elseif (BuildingID == libId_udg_BuildingSiteFort) then //Building Site - Fortification
return 128.00
elseif (BuildingID == libId_udg_BuildingSiteWide) then //Building Site - Wide
return 192.00
elseif (BuildingID == libId_udg_BuildingSiteMedium) then //Building Site - Medium
return 192.00
elseif (BuildingID == libId_udg_BuildingSiteLarge) then //Building Site - Large
return 320.00
elseif (BuildingID == libId_udg_BuildingSiteHuge) then //Building Site - Huge
return 512.00
elseif (BuildingID == libId_udg_BuildingSiteStairs) then //Building site (Stairs)
return 192.00
elseif (BuildingID == libId_udg_BuildingSiteLadder) then //Building site (Ladder)
return 128.00
endif
return 0.00
endfunction
//Returns the work power per second:
private function GetWorkPower takes integer UnitID returns real
if (UnitID == libId_udg_Worker) then //Worker
return 1.00
elseif (UnitID == libId_udg_Worker2a) then //Worker (2)
return 1.20
elseif (UnitID == libId_udg_Worker3a) then //Worker (3)
return 1.40
elseif (UnitID == libId_udg_Worker4a) then //Worker (4)
return 1.60
elseif (UnitID == libId_udg_Worker1b) then //Worker (1)
return 1.00
elseif (UnitID == libId_udg_Worker2b) then //Worker (2)
return 1.20
elseif (UnitID == libId_udg_Worker3b) then //Worker (3)
return 1.40
elseif (UnitID == libId_udg_Worker4b) then //Worker (4)
return 1.60
elseif (UnitID == libId_udg_Worker1e) then //Engineer (1)
return 2.00
elseif (UnitID == libId_udg_Worker2e) then //Engineer (2)
return 2.25
elseif (UnitID == libId_udg_Architect) then //Architect
return 1.60
elseif (UnitID == libId_udg_Architect2) then //Architect (2)
return 1.80
elseif (UnitID == libId_udg_Architect3) then //Architect (3)
return 2.00
endif
return 0.00
endfunction
//-----------------
//DECLARATION PART:
//-----------------
globals
private constant real udg_AntiSingularityAddition = 0.000001
private constant integer udg_MaxBuildingSitesP = udg_MaxBuildingSites + 1
private constant integer udg_MaxWorkerTypesP = udg_MaxWorkerTypes + 1
endglobals
private struct BuildingSite
private integer BuildingObjectNumber = 0
private integer WorkersClusterNumber = 0
private real Progress = 0.00
private real Workpower = 0.00
private integer array WorkerCounts [udg_MaxWorkerTypesP]
private boolean EnoughWorker = false
public method remove takes nothing returns nothing
local group GroupTemp1 = libUnitDat_GetGroup(this.WorkersClusterNumber)
local unit UnitTemp1
local integer IntLoop1 = 1
call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, 0)
set this.BuildingObjectNumber = 0
call libUnitDat_SetClusterSystemNumbers(this.WorkersClusterNumber, udg_SystemSlot, 0)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call UnitRemoveAbility(UnitTemp1, libId_udg_ConstructingBuff)
call SetUnitAnimation(UnitTemp1, "stand")
endloop
call libUnitDat_RemoveCluster(this.WorkersClusterNumber)
set this.WorkersClusterNumber = 0
set this.Progress = 0.00
set this.Workpower = 0.00
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
set this.WorkerCounts[IntLoop1] = 0
set IntLoop1 = IntLoop1 + 1
endloop
set this.EnoughWorker = false
call this.destroy()
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
endmethod
//------------
//GET METHODS:
//------------
public method GetBuilding takes nothing returns unit
return libUnitDat_GetUnit(this.BuildingObjectNumber)
endmethod
public method GetWorkers takes nothing returns group
return libUnitDat_GetGroup(this.WorkersClusterNumber)
endmethod
public method GetProgress takes nothing returns real
return this.Progress
endmethod
public method GetWorkerCounts takes integer WorkerSlot returns integer
return this.WorkerCounts[WorkerSlot]
endmethod
//------------
//SET METHODS:
//------------
public method SetBuilding takes unit Building returns nothing
set this.BuildingObjectNumber = libUnitDat_GetObjectNumber(Building, true)
endmethod
//--------------
//OTHER METHODS:
//--------------
public method New takes unit Building, integer BuildingSiteNumber returns nothing
local integer IntLoop1 = 1
set this.BuildingObjectNumber = libUnitDat_GetObjectNumber(Building, true)
call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, BuildingSiteNumber)
set this.WorkersClusterNumber = libUnitDat_CreateCluster()
set this.Progress = GetBuildingValue(GetUnitTypeId(Building))
set this.Workpower = 0.00
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
set this.WorkerCounts[IntLoop1] = 0
set IntLoop1 = IntLoop1 + 1
endloop
set this.EnoughWorker = false
endmethod
public method IsWorker takes unit Person returns boolean
return (libUnitDat_GetSystemNumber(libUnitDat_GetObjectNumber(Person, false), udg_SystemSlot) == libUnitDat_GetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot))
endmethod
public method CheckWorkerCount takes nothing returns nothing
local integer BuildingID = GetUnitTypeId(libUnitDat_GetUnit(this.BuildingObjectNumber))
local boolean EnoughWorkerOld = this.EnoughWorker
local group GroupTemp1
local unit UnitTemp1
local integer IntLoop1 = 1
set this.EnoughWorker = true
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
if (this.EnoughWorker and this.WorkerCounts[IntLoop1] < GetNeededWorkers(BuildingID, IntLoop1, true)) then
set this.EnoughWorker = false
exitwhen true
endif
set IntLoop1 = IntLoop1 + 1
endloop
if (EnoughWorkerOld == false and this.EnoughWorker) then
set GroupTemp1 = libUnitDat_GetGroup(this.WorkersClusterNumber)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call SetUnitAnimation(UnitTemp1, "work")
endloop
call DestroyGroup(GroupTemp1)
elseif (EnoughWorkerOld and this.EnoughWorker == false) then
set GroupTemp1 = libUnitDat_GetGroup(this.WorkersClusterNumber)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call SetUnitAnimation(UnitTemp1, "stand")
endloop
call DestroyGroup(GroupTemp1)
endif
//Anti-Memory-Leak:
set GroupTemp1 = null
set UnitTemp1 = null
endmethod
public method AddWorker takes unit Person returns nothing
local integer PersonObjectNumber
local integer PersonID = GetUnitTypeId(Person)
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
// ADDED BY WIETLOL
exitwhen UnitTypeIdIsInWorkerSlot(PersonID, IntLoop1)
// REMOVED BY WIETLOL
//exitwhen WorkerSlot2UnitID(IntLoop1) == PersonID
// END BY WIETLOL
set IntLoop1 = IntLoop1 + 1
endloop
if (IntLoop1 > udg_MaxWorkerTypes) then
call DisplayTextToPlayer(GetOwningPlayer(Person), 0, 0, "This builder can't work at this type of building.")
elseif (this.WorkerCounts[IntLoop1] >= GetNeededWorkers(GetUnitTypeId(libUnitDat_GetUnit(this.BuildingObjectNumber)), IntLoop1, false)) then
call DisplayTextToPlayer(GetOwningPlayer(Person), 0, 0, "The worker limit for this building site has already been reached.")
else
set this.WorkerCounts[IntLoop1] = this.WorkerCounts[IntLoop1] + 1
set PersonObjectNumber = libUnitDat_SetSystemNumberOfUnit(Person, udg_SystemSlot, libUnitDat_GetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot))
call libUnitDat_ClusterChangeObject(this.WorkersClusterNumber, PersonObjectNumber, true)
set this.Workpower = this.Workpower + GetWorkPower(PersonID)
call libDum_CastOnTarget(libId_udg_AddConstructionBuff, 1, "innerfire", Person, Player(PLAYER_NEUTRAL_PASSIVE))
if (this.EnoughWorker == false) then
call TriggerSleepAction(0.01)
call this.CheckWorkerCount()
else
call TriggerSleepAction(0.01)
call SetUnitAnimation(Person, "work")
endif
endif
endmethod
public method RemoveWorker takes unit Person returns nothing
local integer PersonObjectNumber
local integer PersonID = GetUnitTypeId(Person)
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
// ADDED BY WIETLOL
exitwhen UnitTypeIdIsInWorkerSlot(PersonID, IntLoop1)
// REMOVED BY WIETLOL
//exitwhen WorkerSlot2UnitID(IntLoop1) == PersonID
// END BY WIETLOL
set IntLoop1 = IntLoop1 + 1
endloop
if (IntLoop1 > udg_MaxWorkerTypes or this.WorkerCounts[IntLoop1] <= 0) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Can't remove more builders of this type")
return
else
set this.WorkerCounts[IntLoop1] = this.WorkerCounts[IntLoop1] - 1
set PersonObjectNumber = libUnitDat_SetSystemNumberOfUnit(Person, udg_SystemSlot, 0)
call libUnitDat_ClusterChangeObject(this.WorkersClusterNumber, PersonObjectNumber, false)
call SetUnitAnimation(Person, "stand")
set this.Workpower = this.Workpower - GetWorkPower(PersonID)
call UnitRemoveAbility(Person, libId_udg_ConstructingBuff)
if (this.EnoughWorker) then
call this.CheckWorkerCount()
endif
endif
endmethod
public method ReduceBuildingTime takes nothing returns nothing
local unit Building = libUnitDat_GetUnit(this.BuildingObjectNumber)
local integer BuildingID
local integer IntTemp1
if (this.Progress > 0.00) then
set BuildingID = GetUnitTypeId(Building)
if (this.EnoughWorker) then
set this.Progress = this.Progress - this.Workpower * udg_BuildingRate
endif
set IntTemp1 = R2I(100.00 - 100.00 * this.Progress / (GetBuildingValue(BuildingID) + udg_AntiSingularityAddition))
if (IntTemp1 >= 100 and this.Progress > 0.00) then
set IntTemp1 = 99
elseif (IntTemp1 <= 0) then
set IntTemp1 = 1
endif
call UnitSetUpgradeProgress(Building, IntTemp1)
elseif (this.Progress == 0.00) then
call UnitSetUpgradeProgress(Building, 1)
endif
//Anit-Memory-Leak:
set Building = null
endmethod
public method AdjustSystemNumber takes integer NewSystemNumber returns nothing
call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, NewSystemNumber)
call libUnitDat_SetClusterSystemNumbers(this.WorkersClusterNumber, udg_SystemSlot, NewSystemNumber)
endmethod
endstruct
globals
private BuildingSite array udg_BuildingSites [udg_MaxBuildingSitesP]
private integer udg_CountBuildingSites = 0
private constant trigger gg_trg_AdjustBuildingTime = CreateTrigger()
private constant trigger gg_trg_TurnBuilding = CreateTrigger()
private constant trigger gg_trg_RemoveBuilding = CreateTrigger()
private constant trigger gg_trg_StartBuilding = CreateTrigger()
private constant trigger gg_trg_FinishBuilding = CreateTrigger()
private constant trigger gg_trg_AbortBuilding = CreateTrigger()
private constant trigger gg_trg_BuildingDies = CreateTrigger()
private constant trigger gg_trg_DuplicateBuildingSite = CreateTrigger()
private constant trigger gg_trg_SmartOrderOnBuildingSite = CreateTrigger()
private constant trigger gg_trg_LeaveBuildingSite = CreateTrigger()
private constant trigger gg_trg_Construct = CreateTrigger()
endglobals
//-------------
//PRIVATE PART:
//-------------
private function GetAdjustedAngle takes real Input returns real
local real MaxResidual = 0.001
if (0.00 - Input <= MaxResidual and 0.00 - Input >= (-1) * MaxResidual) then
return 0.00
elseif (90.00 - Input <= MaxResidual and 90.00 - Input >= (-1) * MaxResidual) then
return 90.00
elseif (180.00 - Input <= MaxResidual and 180.00 - Input >= (-1) * MaxResidual) then
return 180.00
elseif (270.00 - Input <= MaxResidual and 270.00 - Input >= (-1) * MaxResidual) then
return 270.00
elseif (360.00 - Input <= MaxResidual and 360.00 - Input >= (-1) * MaxResidual) then
return 0.00
endif
return Input
endfunction
private function FindBuildingSitesForWorkers_Filter1 takes nothing returns boolean
return (GetBuildingValue(GetUnitTypeId(GetFilterUnit())) != 0.00 and libUnitDat_GetSystemNumberOfUnit(GetFilterUnit(), udg_SystemSlot) > 0)
endfunction
private function FindBuildingSitesForWorkers takes group Workers, real PosX, real PosY returns nothing
local player Owner = GetOwningPlayer(FirstOfGroup(Workers))
local unit array StackBuildings
local real array StackDistances
local integer StackSize = 0
local group array WorkerGroups
local boolexpr Filter1 = Condition(function FindBuildingSitesForWorkers_Filter1)
local group GroupTemp1 = CreateGroup()
local unit UnitTemp1
local real RealTemp1
local real RealTemp2
local integer IntTemp1
local integer IntTemp2
local integer IntTemp3
local integer IntLoop1
local integer IntLoop2
//Sort nearby building sites after the their distance:
call GroupEnumUnitsInRange(GroupTemp1, PosX, PosY, udg_MaxAutoBuildRange, Filter1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
if (Owner == GetOwningPlayer(UnitTemp1)) then
set RealTemp1 = GetUnitX(UnitTemp1) - PosX
set RealTemp2 = GetUnitY(UnitTemp1) - PosY
set RealTemp1 = SquareRoot(RealTemp1 * RealTemp1 + RealTemp2 * RealTemp2)
set IntLoop1 = StackSize
set StackSize = StackSize + 1
loop
exitwhen IntLoop1 <= 0
exitwhen StackDistances[IntLoop1] <= RealTemp1
set StackBuildings[IntLoop1 + 1] = StackBuildings[IntLoop1]
set StackDistances[IntLoop1 + 1] = StackDistances[IntLoop1]
set IntLoop1 = IntLoop1 - 1
endloop
set StackBuildings[IntLoop1 + 1] = UnitTemp1
set StackDistances[IntLoop1 + 1] = RealTemp1
endif
endloop
call DestroyGroup(GroupTemp1)
//Sort workers after their worker type slot:
set IntLoop1 = 1
set WorkerGroups[IntLoop1] = Workers
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
set GroupTemp1 = WorkerGroups[IntLoop1]
set WorkerGroups[IntLoop1] = CreateGroup()
if (IntLoop1 + 1 <= udg_MaxWorkerTypes) then
set WorkerGroups[IntLoop1 + 1] = CreateGroup()
endif
// REMOVED BY WIETLOL
//set IntTemp1 = WorkerSlot2UnitID(IntLoop1)
// END BY WIETLOL
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
// ADDED BY WIETLOL
if (UnitTypeIdIsInWorkerSlot(GetUnitTypeId(UnitTemp1), IntLoop1)) then
// REMOVED BY WIETLOL
//if (GetUnitTypeId(UnitTemp1) == IntTemp1) then
// END BY WIETLOL
call GroupAddUnit(WorkerGroups[IntLoop1], UnitTemp1)
elseif (IntLoop1 + 1 <= udg_MaxWorkerTypes) then
call GroupAddUnit(WorkerGroups[IntLoop1 + 1], UnitTemp1)
endif
endloop
call DestroyGroup(GroupTemp1)
set IntLoop1 = IntLoop1 + 1
endloop
//Distribute workers to building sites:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > StackSize
set IntTemp1 = libUnitDat_GetSystemNumberOfUnit(StackBuildings[IntLoop1], udg_SystemSlot)
set IntTemp2 = GetUnitTypeId(StackBuildings[IntLoop1])
set IntTemp3 = -1
set IntLoop2 = 1
loop
exitwhen IntLoop2 > udg_MaxWorkerTypes
if (WorkerGroups[IntLoop2] != null) then
set IntTemp3 = GetNeededWorkers(IntTemp2, IntLoop2, false)
if (IntTemp3 > 0) then
set IntTemp3 = IntTemp3 - udg_BuildingSites[IntTemp1].GetWorkerCounts(IntLoop2)
loop
exitwhen IntTemp3 <= 0
set UnitTemp1 = FirstOfGroup(WorkerGroups[IntLoop2])
if (UnitTemp1 == null) then
call DestroyGroup(WorkerGroups[IntLoop2])
set WorkerGroups[IntLoop2] = null
exitwhen true
endif
call GroupRemoveUnit(WorkerGroups[IntLoop2], UnitTemp1)
call IssueTargetOrder(UnitTemp1, "thunderbolt", StackBuildings[IntLoop1])
set IntTemp3 = IntTemp3 - 1
endloop
endif
endif
set IntLoop2 = IntLoop2 + 1
endloop
set StackBuildings[IntLoop1] = null
set IntLoop1 = IntLoop1 + 1
exitwhen IntTemp3 == -1
endloop
//Anti-Memory-Leak:
if (IntLoop1 > StackSize) then
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
if (WorkerGroups[IntLoop1] != null) then
call DestroyGroup(WorkerGroups[IntLoop1])
set WorkerGroups[IntLoop1] = null
endif
set IntLoop1 = IntLoop1 + 1
endloop
else
loop
exitwhen IntLoop1 > StackSize
set StackBuildings[IntLoop1] = null
set IntLoop1 = IntLoop1 + 1
endloop
endif
set GroupTemp1 = null
call DestroyBoolExpr(Filter1)
set Filter1 = null
set UnitTemp1 = null
endfunction
//------------
//PUBLIC PART:
//------------
public function GetBuildingSiteNumber takes unit Building returns integer
return (libUnitDat_GetSystemNumberOfUnit(Building, udg_SystemSlot))
endfunction
public function GetBuildingSiteInfo takes integer BuildingSiteNumber, integer InfoNumber, integer SubNumber returns integer
local integer ReturnValue = 0
local real RealTemp1 = 0.00
local real RealTemp2
local integer IntTemp1
local integer IntTemp2
local integer IntLoop1 = 1
if (InfoNumber == 1) then //Left building time
set RealTemp2 = udg_BuildingSites[BuildingSiteNumber].GetProgress()
if (RealTemp2 == 0.00) then
set ReturnValue = -2000
elseif (RealTemp2 < 0.00) then
set ReturnValue = R2I(RealTemp2)
else
set IntTemp1 = GetUnitTypeId(udg_BuildingSites[BuildingSiteNumber].GetBuilding())
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
set IntTemp2 = udg_BuildingSites[BuildingSiteNumber].GetWorkerCounts(IntLoop1)
if (IntTemp2 < GetNeededWorkers(IntTemp1, IntLoop1, true)) then
set ReturnValue = -1000
exitwhen true
endif
set RealTemp1 = RealTemp1 + IntTemp2 * GetWorkPower(WorkerSlot2UnitID(IntLoop1)) // TODO replace this function
set IntLoop1 = IntLoop1 + 1
endloop
if (ReturnValue == 0) then
set ReturnValue = R2I(RealTemp2 / (RealTemp1 + udg_AntiSingularityAddition))
endif
endif
elseif (InfoNumber == 2) then //Employed worker ID of type number
if (SubNumber > udg_MaxWorkerTypes) then
set ReturnValue = -1
else
set ReturnValue = WorkerSlot2UnitID(SubNumber) // TODO replace this function
endif
elseif (InfoNumber == 3) then //Employed worker count of type number
set ReturnValue = udg_BuildingSites[BuildingSiteNumber].GetWorkerCounts(SubNumber)
elseif (InfoNumber == 4) then //Minimal required worker count of type number
set ReturnValue = GetNeededWorkers(GetUnitTypeId(udg_BuildingSites[BuildingSiteNumber].GetBuilding()), SubNumber, true)
elseif (InfoNumber == 5) then //Maximal allowed worker count of type number
set ReturnValue = GetNeededWorkers(GetUnitTypeId(udg_BuildingSites[BuildingSiteNumber].GetBuilding()), SubNumber, false)
endif
return ReturnValue
endfunction
public function GetWorkerGroup takes integer BuildingSiteNumber returns group
return udg_BuildingSites[BuildingSiteNumber].GetWorkers()
endfunction
//---------------------
//EVENT-TRIGGERED PART:
//---------------------
private function TurnBuilding_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_TurnBuilding)
endfunction
private function TurnBuilding takes nothing returns nothing
local group GroupTemp1 = CreateGroup()
local unit UnitTemp1 = GetSpellAbilityUnit()
local unit UnitTemp2
local real RealTemp1
call SyncSelections()
call GroupEnumUnitsSelected(GroupTemp1, GetOwningPlayer(UnitTemp1), null)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
if (GetUnitAbilityLevel(UnitTemp1, libId_udg_TurnBuilding) != 0) then
set RealTemp1 = GetAdjustedAngle(GetUnitFacing(UnitTemp1)) + 90.00
if (RealTemp1 >= 360.00) then
set RealTemp1 = RealTemp1 - 360.00
endif
call ShowUnit(UnitTemp1, false)
set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), GetUnitTypeId(UnitTemp1), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), RealTemp1)
call libUnitDat_ChangeUnit(UnitTemp1, UnitTemp2)
call RemoveUnit(UnitTemp1)
if (RealTemp1 == 90.00) then
call UnitRemoveAbility(UnitTemp2, libId_udg_BuildingFacingDown)
call UnitAddAbility(UnitTemp2, libId_udg_BuildingFacingUp)
elseif (RealTemp1 == 180.00) then
call UnitRemoveAbility(UnitTemp2, libId_udg_BuildingFacingDown)
call UnitAddAbility(UnitTemp2, libId_udg_BuildingFacingLeft)
elseif (RealTemp1 == 0.00) then
call UnitRemoveAbility(UnitTemp2, libId_udg_BuildingFacingDown)
call UnitAddAbility(UnitTemp2, libId_udg_BuildingFacingRight)
endif
call libWal_AdjustReplacedBuilding(UnitTemp2)
if (GetLocalPlayer() == GetOwningPlayer(UnitTemp2)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SelectUnit(UnitTemp2, true)
endif
endif
endloop
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
set UnitTemp2 = null
endfunction
private function RemoveBuilding_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_RemoveBuilding)
endfunction
private function RemoveBuilding takes nothing returns nothing
local unit UnitTemp1 = GetSpellAbilityUnit()
call KillUnit(UnitTemp1)
call ShowUnit(UnitTemp1, false)
call TriggerSleepAction(1.00)
call RemoveUnit(UnitTemp1)
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function StartBuilding_Conditions takes nothing returns boolean
local unit UnitTemp1 = GetTriggerUnit()
local integer IntTemp1 = 1
if (GetBuildingValue(GetUnitTypeId(UnitTemp1)) != 0.00) then
set IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
//-----------------
return (IntTemp1 == 0)
endfunction
private function StartBuilding takes nothing returns nothing
local unit UnitTemp1 = GetTriggerUnit()
local real RealTemp1
local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
set udg_CountBuildingSites = udg_CountBuildingSites + 1
set udg_BuildingSites[udg_CountBuildingSites] = BuildingSite.create()
if (udg_BuildingSites[udg_CountBuildingSites] == 0) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: BuildingSite struct cap exceeded")
return
endif
call udg_BuildingSites[udg_CountBuildingSites].New(UnitTemp1, udg_CountBuildingSites)
set RealTemp1 = GetBuildingSize(IntTemp1)
call SetUnitScale(UnitTemp1, RealTemp1, RealTemp1, RealTemp1)
if (libWal_AdjustConstructingFortification(UnitTemp1)) then
set UnitTemp1 = udg_BuildingSites[udg_CountBuildingSites].GetBuilding()
call ShowUnit(UnitTemp1, false)
set IntTemp1 = GetUnitTypeId(UnitTemp1)
call libUnitDat_ChangeUnit(UnitTemp1, CreateUnit(GetOwningPlayer(UnitTemp1), GetBuildingSiteID(IntTemp1), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1)))
call RemoveUnit(UnitTemp1)
set UnitTemp1 = udg_BuildingSites[udg_CountBuildingSites].GetBuilding()
call IssueImmediateOrderById(UnitTemp1, IntTemp1)
set RealTemp1 = GetBuildingSize(IntTemp1)
call SetUnitScale(UnitTemp1, RealTemp1, RealTemp1, RealTemp1)
endif
call libWal_AddBuildingUnderConstruction(UnitTemp1)
if (GetLocalPlayer() == GetOwningPlayer(UnitTemp1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SelectUnit(UnitTemp1, true)
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function FinishBuilding_Conditions takes nothing returns boolean
return (GetBuildingValue(GetUnitTypeId(GetTriggerUnit())) != 0.00)
endfunction
private function FinishBuilding takes nothing returns nothing
local unit UnitTemp1 = GetTriggerUnit()
local group GroupTemp1
local integer IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
if (IntTemp1 <= udg_CountBuildingSites and IntTemp1 > 0) then
set GroupTemp1 = udg_BuildingSites[IntTemp1].GetWorkers()
call udg_BuildingSites[IntTemp1].remove()
if (udg_CountBuildingSites != IntTemp1) then
set udg_BuildingSites[IntTemp1] = udg_BuildingSites[udg_CountBuildingSites]
call udg_BuildingSites[IntTemp1].AdjustSystemNumber(IntTemp1)
endif
set udg_BuildingSites[udg_CountBuildingSites] = 0
set udg_CountBuildingSites = udg_CountBuildingSites - 1
call FindBuildingSitesForWorkers(GroupTemp1, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1))
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
set GroupTemp1 = null
endfunction
private function AbortBuilding_Conditions takes nothing returns boolean
return (GetBuildingSiteNumber(GetTriggerUnit()) > 0)
endfunction
private function AbortBuilding takes nothing returns nothing
local unit UnitTemp1 = GetTriggerUnit()
local integer IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
if (IntTemp1 <= udg_CountBuildingSites) then
call udg_BuildingSites[IntTemp1].remove()
if (udg_CountBuildingSites != IntTemp1) then
set udg_BuildingSites[IntTemp1] = udg_BuildingSites[udg_CountBuildingSites]
call udg_BuildingSites[IntTemp1].AdjustSystemNumber(IntTemp1)
endif
set udg_BuildingSites[udg_CountBuildingSites] = 0
set udg_CountBuildingSites = udg_CountBuildingSites - 1
if (GetUnitAbilityLevel(UnitTemp1, libId_udg_RemoveBuilding) > 0) then
call libWal_RemoveBuildingUnderConstruction(UnitTemp1)
call libUnitDat_RemoveObjectUnit(UnitTemp1)
endif
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function BuildingDies_Conditions takes nothing returns boolean
local unit UnitTemp1 = GetDyingUnit()
local integer IntTemp1 = 0
if (GetBuildingValue(GetUnitTypeId(UnitTemp1)) != 0.00) then
set IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
//-----------------
return (IntTemp1 != 0)
endfunction
private function BuildingDies takes nothing returns nothing
local unit UnitTemp1 = GetDyingUnit()
local integer IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
if (IntTemp1 <= udg_CountBuildingSites) then
call udg_BuildingSites[IntTemp1].remove()
if (udg_CountBuildingSites != IntTemp1) then
set udg_BuildingSites[IntTemp1] = udg_BuildingSites[udg_CountBuildingSites]
call udg_BuildingSites[IntTemp1].AdjustSystemNumber(IntTemp1)
endif
set udg_BuildingSites[udg_CountBuildingSites] = 0
set udg_CountBuildingSites = udg_CountBuildingSites - 1
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function AdjustBuildingTime takes nothing returns nothing
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_CountBuildingSites
call udg_BuildingSites[IntLoop1].ReduceBuildingTime()
set IntLoop1 = IntLoop1 + 1
endloop
endfunction
private function Construct_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_Construct)
endfunction
private function Construct takes nothing returns nothing
local unit Worker = GetSpellAbilityUnit()
local unit Building = GetSpellTargetUnit()
local integer BuildingSiteNumber = GetBuildingSiteNumber(Building)
if (BuildingSiteNumber > 0) then
call TriggerSleepAction(0.01)
call udg_BuildingSites[BuildingSiteNumber].AddWorker(Worker)
endif
//Anti-Memory-Leak:
set Worker = null
set Building = null
endfunction
private function LeaveBuildingSite_Conditions takes nothing returns boolean
return (GetWorkPower(GetUnitTypeId(GetTriggerUnit())) > 0.00)
endfunction
private function LeaveBuildingSite takes nothing returns nothing
local unit Worker = GetTriggerUnit()
local integer BuildingSiteNumber = GetBuildingSiteNumber(Worker)
if (BuildingSiteNumber > 0) then
call udg_BuildingSites[BuildingSiteNumber].RemoveWorker(Worker)
endif
//Anti-Memory-Leak:
set Worker = null
endfunction
private function DuplicateBuildingSite_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_Duplicate)
endfunction
private function DuplicateBuildingSite takes nothing returns nothing
local unit Building = GetSpellAbilityUnit()
local unit Duplicate
local integer BuildingID = GetUnitTypeId(Building)
local real Facing = GetAdjustedAngle(GetUnitFacing(Building))
local real PosX = GetUnitX(Building)
local real PosY = GetUnitY(Building)
if (Facing == 0.00) then
set PosY = PosY - GetBuildingSiteSquareSize(BuildingID)
elseif (Facing == 90.00) then
set PosX = PosX + GetBuildingSiteSquareSize(BuildingID)
elseif (Facing == 180.00) then
set PosY = PosY + GetBuildingSiteSquareSize(BuildingID)
elseif (Facing == 270.00) then
set PosX = PosX - GetBuildingSiteSquareSize(BuildingID)
endif
if (GetRectMinX(bj_mapInitialPlayableArea) <= PosX and PosX <= GetRectMaxX(bj_mapInitialPlayableArea) and GetRectMinY(bj_mapInitialPlayableArea) <= PosY and PosY <= GetRectMaxY(bj_mapInitialPlayableArea) and IsVisibleToPlayer(PosX, PosY, GetOwningPlayer(Building))) then
set Duplicate = CreateUnit(GetOwningPlayer(Building), BuildingID, PosX, PosY, Facing)
if (Facing == 90.00) then
call UnitRemoveAbility(Duplicate, libId_udg_BuildingFacingDown)
call UnitAddAbility(Duplicate, libId_udg_BuildingFacingUp)
elseif (Facing == 180.00) then
call UnitRemoveAbility(Duplicate, libId_udg_BuildingFacingDown)
call UnitAddAbility(Duplicate, libId_udg_BuildingFacingLeft)
elseif (Facing == 0.00) then
call UnitRemoveAbility(Duplicate, libId_udg_BuildingFacingDown)
call UnitAddAbility(Duplicate, libId_udg_BuildingFacingRight)
endif
if (GetLocalPlayer() == GetOwningPlayer(Duplicate)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call ClearSelection()
call SelectUnit(Duplicate, true)
endif
endif
//Anti-Memory-Leak:
set Building = null
set Duplicate = null
endfunction
//original "private" function changed to "public" for 'CustomResourceSystem' compatibility:
public 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
/*-------------------------------------------------------------
//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
/*-------------------------------------------------------------
//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_BuildingSiteMisc = 'h001' //Building Site - Misc
public constant integer udg_BuildingSiteSmall = 'hZ1F' //Building Site - Small
public constant integer udg_BuildingSiteFort = 'h000' //Building Site - Fortification
public constant integer udg_BuildingSiteWide = 'hZ0Q' //Building Site - Wide
public constant integer udg_BuildingSiteMedium = 'hZ9M' //Building Site - Medium
public constant integer udg_BuildingSiteLarge = 'hZ0I' //Building Site - Large
public constant integer udg_BuildingSiteHuge = 'hZ11' //Building Site - Huge
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 (Misc):
public constant integer udg_Barricade = 'hZ0Z' //Barricade
public constant integer udg_TrainD1 = 'nmh0' //Training Dummy (1)
public constant integer udg_TrainD2 = 'nmh1' //Training Dummy (2)
public constant integer udg_TrainD3 = 'nnzg' //Training Dummy (3)
public constant integer udg_Target1 = 'ntn2' //Archery Target (1)
public constant integer udg_Target2 = 'ntnt' //Archery Target (2)
//Buildings (Tiny):
public constant integer udg_FirePit = 'net1' //Fire Pit
public constant integer udg_LightP1 = 'nfv4' //Light Post (1)
public constant integer udg_LightP2 = 'nfv3' //Light Post (2)
public constant integer udg_Well1 = 'nfh1' //Well (1)
public constant integer udg_Well2 = 'nfh0' //Well (2)
public constant integer udg_Well3 = 'nfr2' //Well (3)
public constant integer udg_Fountain1 = 'nfr1' //Fountain (1)
public constant integer udg_Fountain2 = 'ngnh' //Fountain (2)
public constant integer udg_Banner1 = 'ngt2' //Banner (1)
public constant integer udg_Banner2 = 'nhns' //Banner (2)
public constant integer udg_Stash1 = 'nvr0' //Stash (1)
public constant integer udg_Stash2 = 'nvr2' //Stash (2)
public constant integer udg_Statue1 = 'nth0' //Statue (1)
public constant integer udg_Statue2 = 'nth1' //Statue (2)
//Buildings (Small):
public constant integer udg_House1 = 'nefm' //House (1)
public constant integer udg_House2 = 'nef0' //House (2)
public constant integer udg_House3 = 'nef1' //House (3)
public constant integer udg_House4 = 'nef2' //House (4)
public constant integer udg_Tent1 = 'npgr' //Tent (1)
public constant integer udg_Tent2 = 'nwc1' //Tent (2)
public constant integer udg_Tent3 = 'nwc2' //Tent (3)
public constant integer udg_Path1 = 'ndch' //Path (1)
public constant integer udg_Path2 = 'ndh1' //Path (2)
public constant integer udg_Path3 = 'ndh0' //Path (3)
public constant integer udg_Blacksmith = 'hhou' //Blacksmith
public constant integer udg_WindMill1 = 'uzig' //Wind Mill (1)
public constant integer udg_WindMill2 = 'uzg1' //Wind Mill (2)
public constant integer udg_TowerB1 = 'net2' //Bell Tower (1)
public constant integer udg_TowerB2 = 'nft2' //Bell Tower (2)
public constant integer udg_Tower1 = 'hwtw' //Tower (1)
public constant integer udg_Tower2 = 'hgtw' //Tower (2)
public constant integer udg_Tower3 = 'hctw' //Tower (3)
public constant integer udg_Tower4 = 'hatw' //Tower (4)
public constant integer udg_TowerR = 'negm' //TowerR
public constant integer udg_TowerRB = 'ntx2' //TowerRB
public constant integer udg_TowerRC = 'ndt2' //TowerRC
public constant integer udg_TowerS = 'negf' //TowerS
public constant integer udg_TowerSB = 'negt' //TowerSB
public constant integer udg_TowerSC = 'ndgt' //TowerSC
//Buildings (Wide):
public constant integer udg_LongHall1 = 'htow' //Long Hall (1)
public constant integer udg_LongHall2 = 'hkee' //Long Hall (2)
public constant integer udg_LongHall3 = 'hcas' //Long Hall (3)
public constant integer udg_LongHall4 = 'ngwr' //Long Hall (4)
public constant integer udg_Manor1 = 'nef3' //Manor (1)
public constant integer udg_Manor2 = 'nef4' //Manor (2)
public constant integer udg_Manor3 = 'nef5' //Manor (3)
public constant integer udg_Tavern1 = 'hars' //Tavern (1)
public constant integer udg_Tavern2 = 'hgra' //Tavern (2)
public constant integer udg_Tavern3 = 'hvlt' //Tavern (3)
public constant integer udg_LumberMill1 = 'osld' //Lumber Mill (1)
public constant integer udg_LumberMill2 = 'otrb' //Lumber Mill (2)
public constant integer udg_LumberMill3 = 'owtw' //Lumber Mill (3)
public constant integer udg_LumberMill4 = 'npgf' //Lumber Mill (4)
public constant integer udg_StoneMill1 = 'ovln' //Stone Mill (1)
public constant integer udg_StoneMill2 = 'ndrb' //Stone Mill (2)
public constant integer udg_StoneMill3 = 'ocbw' //Stone Mill (3)
public constant integer udg_StoneMill4 = 'nitb' //Stone Mill (4)
public constant integer udg_Forge1 = 'halt' //Forge (1)
public constant integer udg_Forge2 = 'hlum' //Forge (2)
public constant integer udg_Forge3 = 'hbla' //Forge (3)
public constant integer udg_Forge4 = 'harm' //Forge (4)
public constant integer udg_Barn1 = 'oalt' //Barn (1)
public constant integer udg_Barn2 = 'ofor' //Barn (2)
public constant integer udg_Barn3 = 'otto' //Barn (3)
//Buildings (Medium):
public constant integer udg_GreatHall1 = 'ogre' //Great Hall (1)
public constant integer udg_GreatHall2 = 'ostr' //Great Hall (2)
public constant integer udg_GreatHall3 = 'ofrt' //Great Hall (3)
public constant integer udg_University1 = 'nef6' //University (1)
public constant integer udg_University2 = 'nef7' //University (2)
public constant integer udg_Warehouse1 = 'nfv2' //Warehouse (1)
public constant integer udg_Warehouse2 = 'nvr1' //Warehouse (2)
public constant integer udg_Warehouse3 = 'nfv0' //Warehouse (3)
public constant integer udg_WaterMill1 = 'ncnt' //Watermill (1)
public constant integer udg_WaterMill2 = 'nct1' //Watermill (2)
public constant integer udg_WaterMill3 = 'nct2' //Watermill (3)
public constant integer udg_Granary1 = 'nft1' //Granary (1)
public constant integer udg_Granary2 = 'nbt2' //Granary (2)
public constant integer udg_Granary3 = 'nntg' //Granary (3)
public constant integer udg_TrainG1 = 'ntt2' //Training Grounds (1)
public constant integer udg_TrainG2 = 'nten' //Training Grounds (2)
public constant integer udg_Altar1 = 'nmg0' //Altar (1)
public constant integer udg_Altar2 = 'nmg1' //Altar (2)
//Buildings (Large):
public constant integer udg_Barracks1 = 'hZ2Q' //Barracks (1)
public constant integer udg_Barracks2 = 'edob' //Barracks (2)
public constant integer udg_Barracks3 = 'edos' //Barracks (3)
public constant integer udg_Barracks4 = 'hbar' //Barracks (4)
public constant integer udg_ArcheryR1 = 'nnad' //Archery Range (1)
public constant integer udg_ArcheryR2 = 'nbwd' //Archery Range (2)
public constant integer udg_ArcheryR3 = 'nnfm' //Archery Range (3)
public constant integer udg_Stables1 = 'nheb' //Stables (1)
public constant integer udg_Stables2 = 'obar' //Stables (2)
public constant integer udg_Stables3 = 'obea' //Stables (3)
public constant integer udg_Workshop1 = 'nbt1' //Workshop (1)
public constant integer udg_Workshop2 = 'ndt1' //Workshop (2)
public constant integer udg_Workshop3 = 'ntt1' //Workshop (3)
public constant integer udg_Docks1 = 'hshy' //Docks (1)
public constant integer udg_Docks2 = 'eshy' //Docks (2)
public constant integer udg_Docks3 = 'oshy' //Docks (3)
public constant integer udg_VillageSquare = 'hZ2Y' //Village Square
//Buildings (Huge):
public constant integer udg_Stronghold = 'nntt' //Stronghold
public constant integer udg_Cathedral1 = 'nnsa' //Cathedral (1)
public constant integer udg_Cathedral2 = 'nnsg' //Cathedral (2)
public constant integer udg_Cathedral3 = 'haro' //Cathedral (3)
public constant integer udg_Market1 = 'nmgv' //Market (1)
public constant integer udg_Market2 = 'nfv1' //Market (2)
public constant integer udg_Market3 = 'ngob' //Market (3)
public constant integer udg_Market4 = 'nfrt' //Market (4)
//Standard units (Human):
public constant integer udg_Worker = 'hZ00' //Worker
public constant integer udg_Worker2a = 'ewsp' //Worker (2)
public constant integer udg_Worker3a = 'efon' //Worker (3)
public constant integer udg_Worker4a = 'hpea' //Worker (4)
public constant integer udg_Worker1b = 'opeo' //Worker (1)
public constant integer udg_Worker2b = 'ncpn' //Worker (2)
public constant integer udg_Worker3b = 'uaco' //Worker (3)
public constant integer udg_Worker4b = 'ushd' //Worker (4)
public constant integer udg_Worker1e = 'nvlk' //Engineer (1)
public constant integer udg_Worker2e = 'nvk2' //Engineer (2)
public constant integer udg_Architect = 'hZ38' //Architect
public constant integer udg_Architect2 = 'nbee' //Architect (2)
public constant integer udg_Architect3 = 'nhew' //Architect (3)
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=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_FirePit or BuildingID == libId_udg_LightP1 or BuildingID == libId_udg_LightP2 or BuildingID == libId_udg_Stash1 or BuildingID == libId_udg_Stash2) then //Lights & Stash
return 25.00
elseif (BuildingID == libId_udg_Banner1 or BuildingID == libId_udg_Banner2 or BuildingID == libId_udg_LadderPalisade or BuildingID == libId_udg_LadderWall) then //Banner (1,2)
return 20.00
elseif (BuildingID == libId_udg_Statue1 or BuildingID == libId_udg_Statue2 or BuildingID == libId_udg_Fountain1 or BuildingID == libId_udg_Fountain2) then //Statues & Fountains
return 50.00
elseif (BuildingID == libId_udg_Well1 or BuildingID == libId_udg_Well2 or BuildingID == libId_udg_Well3) then //Well (1,2,3)
return 30.00
//Building Site - Misc:
elseif (BuildingID == libId_udg_Barricade) then //Barricade
return 10.00
elseif (BuildingID == libId_udg_TrainD1 or BuildingID == libId_udg_TrainD2 or BuildingID == libId_udg_TrainD3 or BuildingID == libId_udg_Target1 or BuildingID == libId_udg_Target2) then //Dummys
return 25.00
//Building Site - Small:
elseif (BuildingID == libId_udg_House1 or BuildingID == libId_udg_House2 or BuildingID == libId_udg_House3 or BuildingID == libId_udg_House4) then //Houses
return 40.00
elseif (BuildingID == libId_udg_Tent1 or BuildingID == libId_udg_Tent2 or BuildingID == libId_udg_Tent3 or BuildingID == libId_udg_Path1 or BuildingID == libId_udg_Path2 or BuildingID == libId_udg_Path3) then //Tents & Paths
return 25.00
//Building Site - Fortification:
elseif (BuildingID == libId_udg_Tower1 or BuildingID == libId_udg_Tower2 or BuildingID == libId_udg_Tower3 or BuildingID == libId_udg_Tower4) then //Towers
return 75.00
elseif (BuildingID == libId_udg_TowerB1 or BuildingID == libId_udg_TowerB2) then //Bell Tower (1,2)
return 75.00
elseif (BuildingID == libId_udg_TowerR or BuildingID == libId_udg_TowerS or BuildingID == libId_udg_BigGateCl) then //TowerBig & GateBig
return 125.00
elseif (BuildingID == libId_udg_TowerRB or BuildingID == libId_udg_TowerRC or BuildingID == libId_udg_TowerSB or BuildingID == libId_udg_TowerSC) then //TowerUP
return 25.00
elseif (BuildingID == libId_udg_GateCl) then //Gate (Closed)
return 100.00
elseif (BuildingID == libId_udg_PalisadeGateCl) then //Palisade gate (Closed)
return 50.00
elseif (BuildingID == libId_udg_WallUn or BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallIEUn) then //Wall (all Undamaged)
return 80.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 125.00
elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerIEUn) then //Big tower (all Undamaged)
return 150.00
elseif (BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (all Undamaged)
return 150.00
//Building Site - Wide:
elseif (BuildingID == libId_udg_LongHall1 or BuildingID == libId_udg_LongHall2 or BuildingID == libId_udg_LongHall3 or BuildingID == libId_udg_LongHall4) then //Long Halls
return 125.00
elseif (BuildingID == libId_udg_Manor1 or BuildingID == libId_udg_Manor2 or BuildingID == libId_udg_Manor3 or BuildingID == libId_udg_Tavern1 or BuildingID == libId_udg_Tavern2 or BuildingID == libId_udg_Tavern3) then //Manors + Taverns
return 100.00
elseif (BuildingID == libId_udg_Barn1 or BuildingID == libId_udg_Barn2 or BuildingID == libId_udg_Barn3 or BuildingID == libId_udg_WindMill1 or BuildingID == libId_udg_WindMill2) then //Barns
return 90.00
elseif (BuildingID == libId_udg_Forge1 or BuildingID == libId_udg_Forge2 or BuildingID == libId_udg_Forge3 or BuildingID == libId_udg_Forge4) then //Forges
return 100.00
elseif (BuildingID == libId_udg_LumberMill1 or BuildingID == libId_udg_LumberMill2 or BuildingID == libId_udg_LumberMill3 or BuildingID == libId_udg_LumberMill4) then //Lumber Mill (1)
return 75.00
elseif (BuildingID == libId_udg_StoneMill1 or BuildingID == libId_udg_StoneMill2 or BuildingID == libId_udg_StoneMill3 or BuildingID == libId_udg_StoneMill4) then //Stone Mill (1)
return 75.00
//Building Site - Medium:
elseif (BuildingID == libId_udg_GreatHall1 or BuildingID == libId_udg_GreatHall2 or BuildingID == libId_udg_GreatHall3) then //Great Halls
return 200.00
elseif (BuildingID == libId_udg_University1 or BuildingID == libId_udg_University2) then //Universities
return 175.00
elseif (BuildingID == libId_udg_Warehouse1 or BuildingID == libId_udg_Warehouse2 or BuildingID == libId_udg_Warehouse3 or BuildingID == libId_udg_WaterMill1 or BuildingID == libId_udg_WaterMill2 or BuildingID == libId_udg_WaterMill3) then //W + WM
return 125.00
elseif (BuildingID == libId_udg_Altar1 or BuildingID == libId_udg_Altar2 or BuildingID == libId_udg_TrainG1 or BuildingID == libId_udg_TrainG2) then //Altar & Training Grounds
return 75.00
//Building Site - Large:
elseif (BuildingID == libId_udg_Barracks1 or BuildingID == libId_udg_Barracks2 or BuildingID == libId_udg_Barracks3 or BuildingID == libId_udg_Barracks4) then //Barracks
return 200.00
elseif (BuildingID == libId_udg_ArcheryR1 or BuildingID == libId_udg_ArcheryR2 or BuildingID == libId_udg_ArcheryR3 or BuildingID == libId_udg_Stables1 or BuildingID == libId_udg_Stables2 or BuildingID == libId_udg_Stables3) then //AR + Stbls
return 150.00
elseif (BuildingID == libId_udg_Workshop1 or BuildingID == libId_udg_Workshop2 or BuildingID == libId_udg_Workshop3 or BuildingID == libId_udg_Docks1 or BuildingID == libId_udg_Docks2 or BuildingID == libId_udg_Docks3) then //WS + Dcks
return 200.00
elseif (BuildingID == libId_udg_VillageSquare or BuildingID == libId_udg_Granary1 or BuildingID == libId_udg_Granary2 or BuildingID == libId_udg_Granary3) then //Village Square+
return 75.00
//Building Site - Huge:
elseif (BuildingID == libId_udg_Stronghold) then //Stronghold
return 500.00
elseif (BuildingID == libId_udg_Cathedral1 or BuildingID == libId_udg_Cathedral2 or BuildingID == libId_udg_Cathedral3) then //Cathedrals
return 225.00
elseif (BuildingID == libId_udg_Market1 or BuildingID == libId_udg_Market2 or BuildingID == libId_udg_Market3 or BuildingID == libId_udg_Market4) then //Markets
return 125.00
//Building site (special):
elseif (BuildingID == libId_udg_Stairs) then //Stairs
return 50.00
elseif (BuildingID == libId_udg_LadderWall or BuildingID == libId_udg_LadderPalisade) then //Ladders
return 10.00
elseif (BuildingID == libId_udg_WallDa or BuildingID == libId_udg_WallOEDa or BuildingID == libId_udg_WallIEDa) then //Wall (all Damaged)
return 40.00
elseif (BuildingID == libId_udg_WallDe or BuildingID == libId_udg_WallOEDe or BuildingID == libId_udg_WallIEDe) then //Wall (all Destroyed)
return 70.00
elseif (BuildingID == libId_udg_PalisadeDa or BuildingID == libId_udg_PalisadeOEDa or BuildingID == libId_udg_PalisadeIEDa or BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (all Damaged)
return 15.00
elseif (BuildingID == libId_udg_PalisadeDe or BuildingID == libId_udg_PalisadeOEDe or BuildingID == libId_udg_PalisadeIEDe) then //Palisade (all Destroyed)
return 25.00
elseif (BuildingID == libId_udg_GateDa) then //Gate (Damaged)
return 50.00
elseif (BuildingID == libId_udg_PalisadeGateDa) then //Palisade gate (Damaged)
return 30.00
elseif (BuildingID == libId_udg_BigGateDa) then //Big gate (Damaged)
return 70.00
elseif (BuildingID == libId_udg_TowerDa or BuildingID == libId_udg_TowerOEDa or BuildingID == libId_udg_TowerIEDa) then //Tower (all Damaged)
return 40.00
elseif (BuildingID == libId_udg_TowerDe or BuildingID == libId_udg_TowerOEDe or BuildingID == libId_udg_TowerIEDe) then //Tower (all Destroyed)
return 90.00
elseif (BuildingID == libId_udg_BigTowerDa or BuildingID == libId_udg_BigTowerOEDa or BuildingID == libId_udg_BigTowerIEDa) then //Big tower (all Damaged)
return 140.00
elseif (BuildingID == libId_udg_BigTowerDe or BuildingID == libId_udg_BigTowerOEDe or BuildingID == libId_udg_BigTowerIEDe) then //Big tower (all Destroyed)
return 150.00
endif
return 0.00
endfunction
//Returns the building size ("Grafic - Scaling value") of the building type:
private function GetBuildingSize takes integer BuildingID returns real
//Building Site - Tiny:
if (BuildingID == libId_udg_Barricade or BuildingID == libId_udg_TrainD2 or BuildingID == libId_udg_Target1) then
return 0.45
elseif (BuildingID == libId_udg_LongHall1 or BuildingID == libId_udg_LongHall2 or BuildingID == libId_udg_LongHall3 or BuildingID == libId_udg_LongHall4 or BuildingID == libId_udg_VillageSquare) then
return 1.80
elseif (BuildingID == libId_udg_GreatHall1 or BuildingID == libId_udg_GreatHall2 or BuildingID == libId_udg_GreatHall3 or BuildingID == libId_udg_Granary1 or BuildingID == libId_udg_Granary2 or BuildingID == libId_udg_Granary3) then
return 1.55
elseif (BuildingID == libId_udg_University1 or BuildingID == libId_udg_University2) then
return 1.70
elseif (BuildingID == libId_udg_Barracks1 or BuildingID == libId_udg_Barracks2 or BuildingID == libId_udg_Barracks3 or BuildingID == libId_udg_Barracks4) then
return 2.25
elseif (BuildingID == libId_udg_TrainD1 or BuildingID == libId_udg_TrainD3 or BuildingID == libId_udg_LightP2 or BuildingID == libId_udg_Banner1 or BuildingID == libId_udg_Banner2 or BuildingID == libId_udg_Target2) then
return 0.70
elseif (BuildingID == libId_udg_Stash1 or BuildingID == libId_udg_Stash2 or BuildingID == libId_udg_Statue2 or BuildingID == libId_udg_Fountain2 or BuildingID == libId_udg_Altar1) then
return 0.30
elseif (BuildingID == libId_udg_Well1 or BuildingID == libId_udg_Well2 or BuildingID == libId_udg_Tent1 or BuildingID == libId_udg_Tent3 or BuildingID == libId_udg_Well3) then
return 0.80
elseif (BuildingID == libId_udg_House1 or BuildingID == libId_udg_House2 or BuildingID == libId_udg_House3 or BuildingID == libId_udg_House4 or BuildingID == libId_udg_Warehouse1 or BuildingID == libId_udg_Warehouse2 or BuildingID == libId_udg_Warehouse3) then
return 1.40
elseif (BuildingID == libId_udg_Forge1 or BuildingID == libId_udg_Forge2 or BuildingID == libId_udg_Forge3 or BuildingID == libId_udg_Forge4 or BuildingID == libId_udg_Stables1 or BuildingID == libId_udg_Stables2 or BuildingID == libId_udg_Stables3) then
return 1.40
elseif (BuildingID == libId_udg_Cathedral1 or BuildingID == libId_udg_Cathedral2 or BuildingID == libId_udg_Cathedral3 or BuildingID == libId_udg_Tavern1 or BuildingID == libId_udg_Tavern2 or BuildingID == libId_udg_Tavern3 or BuildingID == libId_udg_Tent2) then
return 1.40
elseif (BuildingID == libId_udg_WaterMill1 or BuildingID == libId_udg_WaterMill2 or BuildingID == libId_udg_WaterMill3 or BuildingID == libId_udg_Workshop1 or BuildingID == libId_udg_Workshop2 or BuildingID == libId_udg_Workshop3) then
return 1.45
elseif (BuildingID == libId_udg_WindMill1 or BuildingID == libId_udg_WindMill2) then
return 1.45
elseif (BuildingID == libId_udg_ArcheryR1 or BuildingID == libId_udg_ArcheryR2 or BuildingID == libId_udg_ArcheryR3 or BuildingID == libId_udg_Tower1 or BuildingID == libId_udg_Tower2 or BuildingID == libId_udg_Tower3 or BuildingID == libId_udg_Tower4) then
return 1.25
elseif (BuildingID == libId_udg_Manor1 or BuildingID == libId_udg_Manor2 or BuildingID == libId_udg_Manor3 or BuildingID == libId_udg_TowerB1) then
return 1.25
elseif (BuildingID == libId_udg_LumberMill1 or BuildingID == libId_udg_LumberMill2 or BuildingID == libId_udg_LumberMill3 or BuildingID == libId_udg_LumberMill4) then
return 1.60
elseif (BuildingID == libId_udg_StoneMill1 or BuildingID == libId_udg_StoneMill2 or BuildingID == libId_udg_StoneMill3 or BuildingID == libId_udg_StoneMill4) then
return 1.60
elseif (BuildingID == libId_udg_Market1 or BuildingID == libId_udg_Market2 or BuildingID == libId_udg_Market3 or BuildingID == libId_udg_Market4 or BuildingID == libId_udg_TowerB2) then
return 1.60
elseif (BuildingID == libId_udg_Docks1 or BuildingID == libId_udg_Docks2 or BuildingID == libId_udg_Docks3) then
return 2.00
elseif (BuildingID == libId_udg_TowerR or BuildingID == libId_udg_TowerRB or BuildingID == libId_udg_TowerRC or BuildingID == libId_udg_TowerS or BuildingID == libId_udg_TowerSB or BuildingID == libId_udg_TowerSC) then
return 1.10
elseif (BuildingID == libId_udg_Barn1 or BuildingID == libId_udg_Barn2 or BuildingID == libId_udg_Barn3 or BuildingID == libId_udg_Altar2) then
return 1.15
elseif (BuildingID == libId_udg_TrainG1 or BuildingID == libId_udg_TrainG2) then
return 1.20
elseif (BuildingID == libId_udg_Stronghold) then
return 0.60
endif
return 1.00
endfunction
//Returns the minimal/maximal number of required/allowed workers of the given type number for the given building type:
private function GetNeededWorkers takes integer BuildingID, integer WorkerSlot, boolean ReturnMin returns integer
//Building Site - Misc:
if (BuildingID == libId_udg_Barricade or BuildingID == libId_udg_TrainD1 or BuildingID == libId_udg_TrainD2 or BuildingID == libId_udg_TrainD3 or BuildingID == libId_udg_Target1 or BuildingID == libId_udg_Target2) then //Misc
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 4
endif
endif
//Building Site - Tiny:
elseif (BuildingID == libId_udg_FirePit or BuildingID == libId_udg_LightP1 or BuildingID == libId_udg_LightP2 or BuildingID == libId_udg_Banner1 or BuildingID == libId_udg_Banner2 or BuildingID == libId_udg_LadderWall or BuildingID == libId_udg_LadderPalisade) then
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 4
endif
endif
elseif (BuildingID == libId_udg_Statue1 or BuildingID == libId_udg_Statue2 or BuildingID == libId_udg_Fountain1 or BuildingID == libId_udg_Fountain2 or BuildingID == libId_udg_WindMill1 or BuildingID == libId_udg_WindMill2) then //Statue (1,2)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 6
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 1
endif
endif
elseif (BuildingID == libId_udg_Well1 or BuildingID == libId_udg_Well2 or BuildingID == libId_udg_Well3 or BuildingID == libId_udg_Stash1 or BuildingID == libId_udg_Stash2) then //Well (1,2,3)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 4
endif
endif
//Building Site - Small:
elseif (BuildingID == libId_udg_House1 or BuildingID == libId_udg_House2 or BuildingID == libId_udg_House3 or BuildingID == libId_udg_House4) then //House (1,2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 6
endif
endif
elseif (BuildingID == libId_udg_Tent1 or BuildingID == libId_udg_Tent2 or BuildingID == libId_udg_Tent3 or BuildingID == libId_udg_Path1 or BuildingID == libId_udg_Path2 or BuildingID == libId_udg_Path3) then //Tents & Paths
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 4
endif
endif
//Building Site - Fortification:
elseif (BuildingID == libId_udg_Tower1 or BuildingID == libId_udg_Tower2 or BuildingID == libId_udg_Tower3 or BuildingID == libId_udg_Tower4 or BuildingID == libId_udg_TowerB1 or BuildingID == libId_udg_TowerB2) then //Tower (1,2,3,4) & Bell
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 6
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_TowerR or BuildingID == libId_udg_TowerRB or BuildingID == libId_udg_TowerRC or BuildingID == libId_udg_TowerS or BuildingID == libId_udg_TowerSB or BuildingID == libId_udg_TowerSC) then //Tower Round/Square
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 8
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 3
endif
endif
elseif (BuildingID == libId_udg_GateCl or BuildingID == libId_udg_WallUn or BuildingID == libId_udg_WallOEUn or BuildingID == libId_udg_WallIEUn) then //Gate + Wall
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 6
endif
endif
elseif (BuildingID == libId_udg_PalisadeGateCl or BuildingID == libId_udg_PalisadeUn or BuildingID == libId_udg_PalisadeOEUn or BuildingID == libId_udg_PalisadeIEUn) then //Palisade
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 4
endif
endif
elseif (BuildingID == libId_udg_BigGateCl or BuildingID == libId_udg_TowerUn or BuildingID == libId_udg_TowerOEUn or BuildingID == libId_udg_TowerIEUn) then //Big Gate + Tower
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 8
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 3
endif
endif
elseif (BuildingID == libId_udg_BigTowerUn or BuildingID == libId_udg_BigTowerOEUn or BuildingID == libId_udg_BigTowerIEUn or BuildingID == libId_udg_DrumTowerUn or BuildingID == libId_udg_DrumTowerOEUn or BuildingID == libId_udg_DrumTowerIEUn) then //Big/Drum Tower (all Undamaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 8
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 3
endif
endif
//Building Site - Wide:
elseif (BuildingID == libId_udg_LongHall1 or BuildingID == libId_udg_LumberMill1 or BuildingID == libId_udg_StoneMill1 or BuildingID == libId_udg_Granary1 or BuildingID == libId_udg_Granary2 or BuildingID == libId_udg_Granary3) then //Long Hall (1) + Mills (1)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 6
endif
endif
elseif (BuildingID == libId_udg_LongHall2 or BuildingID == libId_udg_LongHall3 or BuildingID == libId_udg_LongHall4) then //Long Hall (2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 8
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_Manor1 or BuildingID == libId_udg_Manor2 or BuildingID == libId_udg_Manor3 or BuildingID == libId_udg_Tavern1 or BuildingID == libId_udg_Tavern2 or BuildingID == libId_udg_Tavern3) then //Manors + Taverns
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 8
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_Forge1 or BuildingID == libId_udg_Forge2 or BuildingID == libId_udg_Forge3 or BuildingID == libId_udg_Forge4) then //Forge (1,2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 6
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_LumberMill2 or BuildingID == libId_udg_LumberMill3 or BuildingID == libId_udg_LumberMill4) then //Lumber Mill (2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 8
endif
endif
elseif (BuildingID == libId_udg_StoneMill2 or BuildingID == libId_udg_StoneMill3 or BuildingID == libId_udg_StoneMill4) then //Stone Mill (2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 8
endif
endif
//Building Site - Medium:
elseif (BuildingID == libId_udg_GreatHall1 or BuildingID == libId_udg_GreatHall2 or BuildingID == libId_udg_GreatHall3 or BuildingID == libId_udg_University1 or BuildingID == libId_udg_University2) then //Great Halls & Universities
if (WorkerSlot == 1) then
if (ReturnMin) then
return 4
else
return 10
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 2
else
return 5
endif
endif
elseif (BuildingID == libId_udg_WaterMill1 or BuildingID == libId_udg_WaterMill2 or BuildingID == libId_udg_WaterMill3 or BuildingID == libId_udg_Warehouse1 or BuildingID == libId_udg_Warehouse2 or BuildingID == libId_udg_Warehouse3) then //WM + WH
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 8
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_Altar1 or BuildingID == libId_udg_Altar2) then //Altar (1,2)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 6
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_TrainG1 or BuildingID == libId_udg_TrainG2 or BuildingID == libId_udg_VillageSquare) then // Grounds
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 8
endif
endif
//Building Site - Large:
elseif (BuildingID == libId_udg_Barracks1 or BuildingID == libId_udg_Barracks2 or BuildingID == libId_udg_Barracks3 or BuildingID == libId_udg_Barracks4) then //Barracks (1,2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 4
else
return 10
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 2
else
return 4
endif
endif
elseif (BuildingID == libId_udg_ArcheryR1 or BuildingID == libId_udg_ArcheryR2 or BuildingID == libId_udg_ArcheryR3 or BuildingID == libId_udg_Stables1 or BuildingID == libId_udg_Stables2 or BuildingID == libId_udg_Stables3) then //AR + Stbls
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 8
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_Workshop1 or BuildingID == libId_udg_Workshop2 or BuildingID == libId_udg_Workshop3 or BuildingID == libId_udg_Docks1 or BuildingID == libId_udg_Docks2 or BuildingID == libId_udg_Docks3) then //WS + Dcks
if (WorkerSlot == 1) then
if (ReturnMin) then
return 4
else
return 10
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 4
endif
endif
//Building Site - Huge:
elseif (BuildingID == libId_udg_Stronghold) then //Stronghold
if (WorkerSlot == 1) then
if (ReturnMin) then
return 10
else
return 25
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 4
else
return 10
endif
endif
elseif (BuildingID == libId_udg_Cathedral1 or BuildingID == libId_udg_Cathedral2 or BuildingID == libId_udg_Cathedral3) then //Cathedral (1,2,3)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 5
else
return 12
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 3
else
return 7
endif
endif
elseif (BuildingID == libId_udg_Market1 or BuildingID == libId_udg_Market2 or BuildingID == libId_udg_Market3 or BuildingID == libId_udg_Market4) then //Market (1,2,3,4)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 10
endif
endif
//Building site (special):
elseif (BuildingID == libId_udg_Stairs or BuildingID == libId_udg_PalisadeGateDa) then //Stairs + P Gate
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 4
endif
endif
elseif (BuildingID == libId_udg_GateDa or BuildingID == libId_udg_BigGateDa) then //Gate (Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 6
endif
endif
elseif (BuildingID == libId_udg_WallDa or BuildingID == libId_udg_WallOEDa or BuildingID == libId_udg_WallIEDa) then //Wall (all Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 4
endif
endif
elseif (BuildingID == libId_udg_WallDe or BuildingID == libId_udg_WallOEDe or BuildingID == libId_udg_WallIEDe) then //Wall (all Destroyed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 4
endif
endif
elseif (BuildingID == libId_udg_PalisadeDa or BuildingID == libId_udg_PalisadeOEDa or BuildingID == libId_udg_PalisadeIEDa or BuildingID == libId_udg_PalisadeLadderDa) then //Palisade (all Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_PalisadeDe or BuildingID == libId_udg_PalisadeOEDe or BuildingID == libId_udg_PalisadeIEDe) then //Palisade (all Destroyed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_TowerDa or BuildingID == libId_udg_TowerOEDa or BuildingID == libId_udg_TowerIEDa) then //Tower (all Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_TowerDe or BuildingID == libId_udg_TowerOEDe or BuildingID == libId_udg_TowerIEDe) then //Tower (all Destroyed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 4
endif
endif
elseif (BuildingID == libId_udg_BigTowerDa or BuildingID == libId_udg_BigTowerOEDa or BuildingID == libId_udg_BigTowerIEDa) then //Big tower (all Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 3
endif
endif
elseif (BuildingID == libId_udg_BigTowerDe or BuildingID == libId_udg_BigTowerOEDe or BuildingID == libId_udg_BigTowerIEDe) then //Big tower (all Destroyed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 2
else
return 5
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
elseif (BuildingID == libId_udg_DrumTowerDa or BuildingID == libId_udg_DrumTowerOEDa or BuildingID == libId_udg_DrumTowerIEDa) then //Drum tower (all Damaged)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 1
else
return 3
endif
endif
elseif (BuildingID == libId_udg_DrumTowerDe or BuildingID == libId_udg_DrumTowerOEDe or BuildingID == libId_udg_DrumTowerIEDe) then //Drum tower (all Destroyed)
if (WorkerSlot == 1) then
if (ReturnMin) then
return 3
else
return 8
endif
elseif (WorkerSlot == 2) then
if (ReturnMin) then
return 1
else
return 2
endif
endif
endif
return 0
endfunction
//Returns the building site for the given building type (only required for multi-edge fortifications):
private function GetBuildingSiteID takes integer BuildingID returns integer
if (BuildingID == libId_udg_WallUn) then //Wall (Undamaged)
return libId_udg_BuildingSiteFort //Building Site - Fortification
elseif (BuildingID == libId_udg_WallOEUn) then //Wall (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_WallIEUn) then //Wall (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_PalisadeUn) then //Palisade (Undamaged)
return libId_udg_BuildingSiteFort //Building Site - Fortification
elseif (BuildingID == libId_udg_PalisadeOEUn) then //Palisade (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_PalisadeIEUn) then //Palisade (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_TowerUn) then //Tower (Undamaged)
return libId_udg_BuildingSiteFort //Building Site - Fortification
elseif (BuildingID == libId_udg_TowerOEUn) then //Tower (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_TowerIEUn) then //Tower (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_BigTowerUn) then //Big tower (Undamaged)
return libId_udg_BuildingSiteFort //Building Site - Fortification
elseif (BuildingID == libId_udg_BigTowerOEUn) then //Big tower (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_BigTowerIEUn) then //Big tower (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_DrumTowerUn) then //Drum tower (Undamaged)
return libId_udg_BuildingSiteFort //Building Site - Fortification
elseif (BuildingID == libId_udg_DrumTowerOEUn) then //Drum tower (Outer Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
elseif (BuildingID == libId_udg_DrumTowerIEUn) then //Drum tower (Inner Edge) (Undamaged)
return libId_udg_BuildingSiteEdge //Building site (Edge)
endif
return 0
endfunction
// ADDED BY WIETLOL
private function UnitTypeIdIsInWorkerSlot takes integer unitTypeId, integer workerSlot returns boolean
if (workerSlot == 1) then
return unitTypeId == libId_udg_Worker or unitTypeId == libId_udg_Worker1b or unitTypeId == libId_udg_Worker2a or unitTypeId == libId_udg_Worker2b or unitTypeId == libId_udg_Worker3a or unitTypeId == libId_udg_Worker3b or unitTypeId == libId_udg_Worker4a or unitTypeId == libId_udg_Worker4b
elseif (workerSlot == 2) then
return unitTypeId == libId_udg_Architect or unitTypeId == libId_udg_Architect2 or unitTypeId == libId_udg_Architect3 or unitTypeId == libId_udg_Worker1e or unitTypeId == libId_udg_Worker2e
endif
return false
endfunction
// END BY WIETLOL
//Returns the unit type of the given WorkerSlot:
private function WorkerSlot2UnitID takes integer WorkerSlot returns integer
if (WorkerSlot == 1) then
return libId_udg_Worker //Worker
elseif (WorkerSlot == 1) then
return libId_udg_Worker1b //Worker (1)
elseif (WorkerSlot == 1) then
return libId_udg_Worker2a //Worker (2)
elseif (WorkerSlot == 1) then
return libId_udg_Worker2b //Worker (2)
elseif (WorkerSlot == 1) then
return libId_udg_Worker3a //Worker (3)
elseif (WorkerSlot == 1) then
return libId_udg_Worker3b //Worker (3)
elseif (WorkerSlot == 1) then
return libId_udg_Worker4a //Worker (4)
elseif (WorkerSlot == 1) then
return libId_udg_Worker4b //Worker (4)
elseif (WorkerSlot == 2) then
return libId_udg_Architect //Architect
elseif (WorkerSlot == 2) then
return libId_udg_Architect2 //Architect (2)
elseif (WorkerSlot == 2) then
return libId_udg_Architect3 //Architect (3)
elseif (WorkerSlot == 2) then
return libId_udg_Worker1e //Engineer (1)
elseif (WorkerSlot == 2) then
return libId_udg_Worker2e //Engineer (2)
endif
return 0
endfunction
//Returns the square size of the given building site type:
private function GetBuildingSiteSquareSize takes integer BuildingID returns real
if (BuildingID == libId_udg_BuildingSiteTiny) then //Building Site - Tiny
return 64.00
elseif (BuildingID == libId_udg_BuildingSiteMisc) then //Building Site - Misc
return 64.00
elseif (BuildingID == libId_udg_BuildingSiteSmall) then //Building site - Small
return 128.00
elseif (BuildingID == libId_udg_BuildingSiteFort) then //Building Site - Fortification
return 128.00
elseif (BuildingID == libId_udg_BuildingSiteWide) then //Building Site - Wide
return 192.00
elseif (BuildingID == libId_udg_BuildingSiteMedium) then //Building Site - Medium
return 192.00
elseif (BuildingID == libId_udg_BuildingSiteLarge) then //Building Site - Large
return 320.00
elseif (BuildingID == libId_udg_BuildingSiteHuge) then //Building Site - Huge
return 512.00
elseif (BuildingID == libId_udg_BuildingSiteStairs) then //Building site (Stairs)
return 192.00
elseif (BuildingID == libId_udg_BuildingSiteLadder) then //Building site (Ladder)
return 128.00
endif
return 0.00
endfunction
//Returns the work power per second:
private function GetWorkPower takes integer UnitID returns real
if (UnitID == libId_udg_Worker) then //Worker
return 1.00
elseif (UnitID == libId_udg_Worker2a) then //Worker (2)
return 1.20
elseif (UnitID == libId_udg_Worker3a) then //Worker (3)
return 1.40
elseif (UnitID == libId_udg_Worker4a) then //Worker (4)
return 1.60
elseif (UnitID == libId_udg_Worker1b) then //Worker (1)
return 1.00
elseif (UnitID == libId_udg_Worker2b) then //Worker (2)
return 1.20
elseif (UnitID == libId_udg_Worker3b) then //Worker (3)
return 1.40
elseif (UnitID == libId_udg_Worker4b) then //Worker (4)
return 1.60
elseif (UnitID == libId_udg_Worker1e) then //Engineer (1)
return 2.00
elseif (UnitID == libId_udg_Worker2e) then //Engineer (2)
return 2.25
elseif (UnitID == libId_udg_Architect) then //Architect
return 1.60
elseif (UnitID == libId_udg_Architect2) then //Architect (2)
return 1.80
elseif (UnitID == libId_udg_Architect3) then //Architect (3)
return 2.00
endif
return 0.00
endfunction
//-----------------
//DECLARATION PART:
//-----------------
globals
private constant real udg_AntiSingularityAddition = 0.000001
private constant integer udg_MaxBuildingSitesP = udg_MaxBuildingSites + 1
private constant integer udg_MaxWorkerTypesP = udg_MaxWorkerTypes + 1
endglobals
private struct BuildingSite
private integer BuildingObjectNumber = 0
private integer WorkersClusterNumber = 0
private real Progress = 0.00
private real Workpower = 0.00
private integer array WorkerCounts [udg_MaxWorkerTypesP]
private boolean EnoughWorker = false
public method remove takes nothing returns nothing
local group GroupTemp1 = libUnitDat_GetGroup(this.WorkersClusterNumber)
local unit UnitTemp1
local integer IntLoop1 = 1
call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, 0)
set this.BuildingObjectNumber = 0
call libUnitDat_SetClusterSystemNumbers(this.WorkersClusterNumber, udg_SystemSlot, 0)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call UnitRemoveAbility(UnitTemp1, libId_udg_ConstructingBuff)
call SetUnitAnimation(UnitTemp1, "stand")
endloop
call libUnitDat_RemoveCluster(this.WorkersClusterNumber)
set this.WorkersClusterNumber = 0
set this.Progress = 0.00
set this.Workpower = 0.00
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
set this.WorkerCounts[IntLoop1] = 0
set IntLoop1 = IntLoop1 + 1
endloop
set this.EnoughWorker = false
call this.destroy()
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
endmethod
//------------
//GET METHODS:
//------------
public method GetBuilding takes nothing returns unit
return libUnitDat_GetUnit(this.BuildingObjectNumber)
endmethod
public method GetWorkers takes nothing returns group
return libUnitDat_GetGroup(this.WorkersClusterNumber)
endmethod
public method GetProgress takes nothing returns real
return this.Progress
endmethod
public method GetWorkerCounts takes integer WorkerSlot returns integer
return this.WorkerCounts[WorkerSlot]
endmethod
//------------
//SET METHODS:
//------------
public method SetBuilding takes unit Building returns nothing
set this.BuildingObjectNumber = libUnitDat_GetObjectNumber(Building, true)
endmethod
//--------------
//OTHER METHODS:
//--------------
public method New takes unit Building, integer BuildingSiteNumber returns nothing
local integer IntLoop1 = 1
set this.BuildingObjectNumber = libUnitDat_GetObjectNumber(Building, true)
call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, BuildingSiteNumber)
set this.WorkersClusterNumber = libUnitDat_CreateCluster()
set this.Progress = GetBuildingValue(GetUnitTypeId(Building))
set this.Workpower = 0.00
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
set this.WorkerCounts[IntLoop1] = 0
set IntLoop1 = IntLoop1 + 1
endloop
set this.EnoughWorker = false
endmethod
public method IsWorker takes unit Person returns boolean
return (libUnitDat_GetSystemNumber(libUnitDat_GetObjectNumber(Person, false), udg_SystemSlot) == libUnitDat_GetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot))
endmethod
public method CheckWorkerCount takes nothing returns nothing
local integer BuildingID = GetUnitTypeId(libUnitDat_GetUnit(this.BuildingObjectNumber))
local boolean EnoughWorkerOld = this.EnoughWorker
local group GroupTemp1
local unit UnitTemp1
local integer IntLoop1 = 1
set this.EnoughWorker = true
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
if (this.EnoughWorker and this.WorkerCounts[IntLoop1] < GetNeededWorkers(BuildingID, IntLoop1, true)) then
set this.EnoughWorker = false
exitwhen true
endif
set IntLoop1 = IntLoop1 + 1
endloop
if (EnoughWorkerOld == false and this.EnoughWorker) then
set GroupTemp1 = libUnitDat_GetGroup(this.WorkersClusterNumber)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call SetUnitAnimation(UnitTemp1, "work")
endloop
call DestroyGroup(GroupTemp1)
elseif (EnoughWorkerOld and this.EnoughWorker == false) then
set GroupTemp1 = libUnitDat_GetGroup(this.WorkersClusterNumber)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
call SetUnitAnimation(UnitTemp1, "stand")
endloop
call DestroyGroup(GroupTemp1)
endif
//Anti-Memory-Leak:
set GroupTemp1 = null
set UnitTemp1 = null
endmethod
public method AddWorker takes unit Person returns nothing
local integer PersonObjectNumber
local integer PersonID = GetUnitTypeId(Person)
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
// ADDED BY WIETLOL
exitwhen UnitTypeIdIsInWorkerSlot(PersonID, IntLoop1)
// REMOVED BY WIETLOL
//exitwhen WorkerSlot2UnitID(IntLoop1) == PersonID
// END BY WIETLOL
set IntLoop1 = IntLoop1 + 1
endloop
if (IntLoop1 > udg_MaxWorkerTypes) then
call DisplayTextToPlayer(GetOwningPlayer(Person), 0, 0, "This builder can't work at this type of building.")
elseif (this.WorkerCounts[IntLoop1] >= GetNeededWorkers(GetUnitTypeId(libUnitDat_GetUnit(this.BuildingObjectNumber)), IntLoop1, false)) then
call DisplayTextToPlayer(GetOwningPlayer(Person), 0, 0, "The worker limit for this building site has already been reached.")
else
set this.WorkerCounts[IntLoop1] = this.WorkerCounts[IntLoop1] + 1
set PersonObjectNumber = libUnitDat_SetSystemNumberOfUnit(Person, udg_SystemSlot, libUnitDat_GetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot))
call libUnitDat_ClusterChangeObject(this.WorkersClusterNumber, PersonObjectNumber, true)
set this.Workpower = this.Workpower + GetWorkPower(PersonID)
call libDum_CastOnTarget(libId_udg_AddConstructionBuff, 1, "innerfire", Person, Player(PLAYER_NEUTRAL_PASSIVE))
if (this.EnoughWorker == false) then
call TriggerSleepAction(0.01)
call this.CheckWorkerCount()
else
call TriggerSleepAction(0.01)
call SetUnitAnimation(Person, "work")
endif
endif
endmethod
public method RemoveWorker takes unit Person returns nothing
local integer PersonObjectNumber
local integer PersonID = GetUnitTypeId(Person)
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
// ADDED BY WIETLOL
exitwhen UnitTypeIdIsInWorkerSlot(PersonID, IntLoop1)
// REMOVED BY WIETLOL
//exitwhen WorkerSlot2UnitID(IntLoop1) == PersonID
// END BY WIETLOL
set IntLoop1 = IntLoop1 + 1
endloop
if (IntLoop1 > udg_MaxWorkerTypes or this.WorkerCounts[IntLoop1] <= 0) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: Can't remove more builders of this type")
return
else
set this.WorkerCounts[IntLoop1] = this.WorkerCounts[IntLoop1] - 1
set PersonObjectNumber = libUnitDat_SetSystemNumberOfUnit(Person, udg_SystemSlot, 0)
call libUnitDat_ClusterChangeObject(this.WorkersClusterNumber, PersonObjectNumber, false)
call SetUnitAnimation(Person, "stand")
set this.Workpower = this.Workpower - GetWorkPower(PersonID)
call UnitRemoveAbility(Person, libId_udg_ConstructingBuff)
if (this.EnoughWorker) then
call this.CheckWorkerCount()
endif
endif
endmethod
public method ReduceBuildingTime takes nothing returns nothing
local unit Building = libUnitDat_GetUnit(this.BuildingObjectNumber)
local integer BuildingID
local integer IntTemp1
if (this.Progress > 0.00) then
set BuildingID = GetUnitTypeId(Building)
if (this.EnoughWorker) then
set this.Progress = this.Progress - this.Workpower * udg_BuildingRate
endif
set IntTemp1 = R2I(100.00 - 100.00 * this.Progress / (GetBuildingValue(BuildingID) + udg_AntiSingularityAddition))
if (IntTemp1 >= 100 and this.Progress > 0.00) then
set IntTemp1 = 99
elseif (IntTemp1 <= 0) then
set IntTemp1 = 1
endif
call UnitSetUpgradeProgress(Building, IntTemp1)
elseif (this.Progress == 0.00) then
call UnitSetUpgradeProgress(Building, 1)
endif
//Anit-Memory-Leak:
set Building = null
endmethod
public method AdjustSystemNumber takes integer NewSystemNumber returns nothing
call libUnitDat_SetSystemNumber(this.BuildingObjectNumber, udg_SystemSlot, NewSystemNumber)
call libUnitDat_SetClusterSystemNumbers(this.WorkersClusterNumber, udg_SystemSlot, NewSystemNumber)
endmethod
endstruct
globals
private BuildingSite array udg_BuildingSites [udg_MaxBuildingSitesP]
private integer udg_CountBuildingSites = 0
private constant trigger gg_trg_AdjustBuildingTime = CreateTrigger()
private constant trigger gg_trg_TurnBuilding = CreateTrigger()
private constant trigger gg_trg_RemoveBuilding = CreateTrigger()
private constant trigger gg_trg_StartBuilding = CreateTrigger()
private constant trigger gg_trg_FinishBuilding = CreateTrigger()
private constant trigger gg_trg_AbortBuilding = CreateTrigger()
private constant trigger gg_trg_BuildingDies = CreateTrigger()
private constant trigger gg_trg_DuplicateBuildingSite = CreateTrigger()
private constant trigger gg_trg_SmartOrderOnBuildingSite = CreateTrigger()
private constant trigger gg_trg_LeaveBuildingSite = CreateTrigger()
private constant trigger gg_trg_Construct = CreateTrigger()
endglobals
//-------------
//PRIVATE PART:
//-------------
private function GetAdjustedAngle takes real Input returns real
local real MaxResidual = 0.001
if (0.00 - Input <= MaxResidual and 0.00 - Input >= (-1) * MaxResidual) then
return 0.00
elseif (90.00 - Input <= MaxResidual and 90.00 - Input >= (-1) * MaxResidual) then
return 90.00
elseif (180.00 - Input <= MaxResidual and 180.00 - Input >= (-1) * MaxResidual) then
return 180.00
elseif (270.00 - Input <= MaxResidual and 270.00 - Input >= (-1) * MaxResidual) then
return 270.00
elseif (360.00 - Input <= MaxResidual and 360.00 - Input >= (-1) * MaxResidual) then
return 0.00
endif
return Input
endfunction
private function FindBuildingSitesForWorkers_Filter1 takes nothing returns boolean
return (GetBuildingValue(GetUnitTypeId(GetFilterUnit())) != 0.00 and libUnitDat_GetSystemNumberOfUnit(GetFilterUnit(), udg_SystemSlot) > 0)
endfunction
private function FindBuildingSitesForWorkers takes group Workers, real PosX, real PosY returns nothing
local player Owner = GetOwningPlayer(FirstOfGroup(Workers))
local unit array StackBuildings
local real array StackDistances
local integer StackSize = 0
local group array WorkerGroups
local boolexpr Filter1 = Condition(function FindBuildingSitesForWorkers_Filter1)
local group GroupTemp1 = CreateGroup()
local unit UnitTemp1
local real RealTemp1
local real RealTemp2
local integer IntTemp1
local integer IntTemp2
local integer IntTemp3
local integer IntLoop1
local integer IntLoop2
//Sort nearby building sites after the their distance:
call GroupEnumUnitsInRange(GroupTemp1, PosX, PosY, udg_MaxAutoBuildRange, Filter1)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
if (Owner == GetOwningPlayer(UnitTemp1)) then
set RealTemp1 = GetUnitX(UnitTemp1) - PosX
set RealTemp2 = GetUnitY(UnitTemp1) - PosY
set RealTemp1 = SquareRoot(RealTemp1 * RealTemp1 + RealTemp2 * RealTemp2)
set IntLoop1 = StackSize
set StackSize = StackSize + 1
loop
exitwhen IntLoop1 <= 0
exitwhen StackDistances[IntLoop1] <= RealTemp1
set StackBuildings[IntLoop1 + 1] = StackBuildings[IntLoop1]
set StackDistances[IntLoop1 + 1] = StackDistances[IntLoop1]
set IntLoop1 = IntLoop1 - 1
endloop
set StackBuildings[IntLoop1 + 1] = UnitTemp1
set StackDistances[IntLoop1 + 1] = RealTemp1
endif
endloop
call DestroyGroup(GroupTemp1)
//Sort workers after their worker type slot:
set IntLoop1 = 1
set WorkerGroups[IntLoop1] = Workers
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
set GroupTemp1 = WorkerGroups[IntLoop1]
set WorkerGroups[IntLoop1] = CreateGroup()
if (IntLoop1 + 1 <= udg_MaxWorkerTypes) then
set WorkerGroups[IntLoop1 + 1] = CreateGroup()
endif
// REMOVED BY WIETLOL
//set IntTemp1 = WorkerSlot2UnitID(IntLoop1)
// END BY WIETLOL
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
// ADDED BY WIETLOL
if (UnitTypeIdIsInWorkerSlot(GetUnitTypeId(UnitTemp1), IntLoop1)) then
// REMOVED BY WIETLOL
//if (GetUnitTypeId(UnitTemp1) == IntTemp1) then
// END BY WIETLOL
call GroupAddUnit(WorkerGroups[IntLoop1], UnitTemp1)
elseif (IntLoop1 + 1 <= udg_MaxWorkerTypes) then
call GroupAddUnit(WorkerGroups[IntLoop1 + 1], UnitTemp1)
endif
endloop
call DestroyGroup(GroupTemp1)
set IntLoop1 = IntLoop1 + 1
endloop
//Distribute workers to building sites:
set IntLoop1 = 1
loop
exitwhen IntLoop1 > StackSize
set IntTemp1 = libUnitDat_GetSystemNumberOfUnit(StackBuildings[IntLoop1], udg_SystemSlot)
set IntTemp2 = GetUnitTypeId(StackBuildings[IntLoop1])
set IntTemp3 = -1
set IntLoop2 = 1
loop
exitwhen IntLoop2 > udg_MaxWorkerTypes
if (WorkerGroups[IntLoop2] != null) then
set IntTemp3 = GetNeededWorkers(IntTemp2, IntLoop2, false)
if (IntTemp3 > 0) then
set IntTemp3 = IntTemp3 - udg_BuildingSites[IntTemp1].GetWorkerCounts(IntLoop2)
loop
exitwhen IntTemp3 <= 0
set UnitTemp1 = FirstOfGroup(WorkerGroups[IntLoop2])
if (UnitTemp1 == null) then
call DestroyGroup(WorkerGroups[IntLoop2])
set WorkerGroups[IntLoop2] = null
exitwhen true
endif
call GroupRemoveUnit(WorkerGroups[IntLoop2], UnitTemp1)
call IssueTargetOrder(UnitTemp1, "thunderbolt", StackBuildings[IntLoop1])
set IntTemp3 = IntTemp3 - 1
endloop
endif
endif
set IntLoop2 = IntLoop2 + 1
endloop
set StackBuildings[IntLoop1] = null
set IntLoop1 = IntLoop1 + 1
exitwhen IntTemp3 == -1
endloop
//Anti-Memory-Leak:
if (IntLoop1 > StackSize) then
set IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
if (WorkerGroups[IntLoop1] != null) then
call DestroyGroup(WorkerGroups[IntLoop1])
set WorkerGroups[IntLoop1] = null
endif
set IntLoop1 = IntLoop1 + 1
endloop
else
loop
exitwhen IntLoop1 > StackSize
set StackBuildings[IntLoop1] = null
set IntLoop1 = IntLoop1 + 1
endloop
endif
set GroupTemp1 = null
call DestroyBoolExpr(Filter1)
set Filter1 = null
set UnitTemp1 = null
endfunction
//------------
//PUBLIC PART:
//------------
public function GetBuildingSiteNumber takes unit Building returns integer
return (libUnitDat_GetSystemNumberOfUnit(Building, udg_SystemSlot))
endfunction
public function GetBuildingSiteInfo takes integer BuildingSiteNumber, integer InfoNumber, integer SubNumber returns integer
local integer ReturnValue = 0
local real RealTemp1 = 0.00
local real RealTemp2
local integer IntTemp1
local integer IntTemp2
local integer IntLoop1 = 1
if (InfoNumber == 1) then //Left building time
set RealTemp2 = udg_BuildingSites[BuildingSiteNumber].GetProgress()
if (RealTemp2 == 0.00) then
set ReturnValue = -2000
elseif (RealTemp2 < 0.00) then
set ReturnValue = R2I(RealTemp2)
else
set IntTemp1 = GetUnitTypeId(udg_BuildingSites[BuildingSiteNumber].GetBuilding())
loop
exitwhen IntLoop1 > udg_MaxWorkerTypes
set IntTemp2 = udg_BuildingSites[BuildingSiteNumber].GetWorkerCounts(IntLoop1)
if (IntTemp2 < GetNeededWorkers(IntTemp1, IntLoop1, true)) then
set ReturnValue = -1000
exitwhen true
endif
set RealTemp1 = RealTemp1 + IntTemp2 * GetWorkPower(WorkerSlot2UnitID(IntLoop1)) // TODO replace this function
set IntLoop1 = IntLoop1 + 1
endloop
if (ReturnValue == 0) then
set ReturnValue = R2I(RealTemp2 / (RealTemp1 + udg_AntiSingularityAddition))
endif
endif
elseif (InfoNumber == 2) then //Employed worker ID of type number
if (SubNumber > udg_MaxWorkerTypes) then
set ReturnValue = -1
else
set ReturnValue = WorkerSlot2UnitID(SubNumber) // TODO replace this function
endif
elseif (InfoNumber == 3) then //Employed worker count of type number
set ReturnValue = udg_BuildingSites[BuildingSiteNumber].GetWorkerCounts(SubNumber)
elseif (InfoNumber == 4) then //Minimal required worker count of type number
set ReturnValue = GetNeededWorkers(GetUnitTypeId(udg_BuildingSites[BuildingSiteNumber].GetBuilding()), SubNumber, true)
elseif (InfoNumber == 5) then //Maximal allowed worker count of type number
set ReturnValue = GetNeededWorkers(GetUnitTypeId(udg_BuildingSites[BuildingSiteNumber].GetBuilding()), SubNumber, false)
endif
return ReturnValue
endfunction
public function GetWorkerGroup takes integer BuildingSiteNumber returns group
return udg_BuildingSites[BuildingSiteNumber].GetWorkers()
endfunction
//---------------------
//EVENT-TRIGGERED PART:
//---------------------
private function TurnBuilding_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_TurnBuilding)
endfunction
private function TurnBuilding takes nothing returns nothing
local group GroupTemp1 = CreateGroup()
local unit UnitTemp1 = GetSpellAbilityUnit()
local unit UnitTemp2
local real RealTemp1
call SyncSelections()
call GroupEnumUnitsSelected(GroupTemp1, GetOwningPlayer(UnitTemp1), null)
loop
set UnitTemp1 = FirstOfGroup(GroupTemp1)
exitwhen UnitTemp1 == null
call GroupRemoveUnit(GroupTemp1, UnitTemp1)
if (GetUnitAbilityLevel(UnitTemp1, libId_udg_TurnBuilding) != 0) then
set RealTemp1 = GetAdjustedAngle(GetUnitFacing(UnitTemp1)) + 90.00
if (RealTemp1 >= 360.00) then
set RealTemp1 = RealTemp1 - 360.00
endif
call ShowUnit(UnitTemp1, false)
set UnitTemp2 = CreateUnit(GetOwningPlayer(UnitTemp1), GetUnitTypeId(UnitTemp1), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), RealTemp1)
call libUnitDat_ChangeUnit(UnitTemp1, UnitTemp2)
call RemoveUnit(UnitTemp1)
if (RealTemp1 == 90.00) then
call UnitRemoveAbility(UnitTemp2, libId_udg_BuildingFacingDown)
call UnitAddAbility(UnitTemp2, libId_udg_BuildingFacingUp)
elseif (RealTemp1 == 180.00) then
call UnitRemoveAbility(UnitTemp2, libId_udg_BuildingFacingDown)
call UnitAddAbility(UnitTemp2, libId_udg_BuildingFacingLeft)
elseif (RealTemp1 == 0.00) then
call UnitRemoveAbility(UnitTemp2, libId_udg_BuildingFacingDown)
call UnitAddAbility(UnitTemp2, libId_udg_BuildingFacingRight)
endif
call libWal_AdjustReplacedBuilding(UnitTemp2)
if (GetLocalPlayer() == GetOwningPlayer(UnitTemp2)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SelectUnit(UnitTemp2, true)
endif
endif
endloop
//Anti-Memory-Leak:
call DestroyGroup(GroupTemp1)
set GroupTemp1 = null
set UnitTemp1 = null
set UnitTemp2 = null
endfunction
private function RemoveBuilding_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_RemoveBuilding)
endfunction
private function RemoveBuilding takes nothing returns nothing
local unit UnitTemp1 = GetSpellAbilityUnit()
call KillUnit(UnitTemp1)
call ShowUnit(UnitTemp1, false)
call TriggerSleepAction(1.00)
call RemoveUnit(UnitTemp1)
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function StartBuilding_Conditions takes nothing returns boolean
local unit UnitTemp1 = GetTriggerUnit()
local integer IntTemp1 = 1
if (GetBuildingValue(GetUnitTypeId(UnitTemp1)) != 0.00) then
set IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
//-----------------
return (IntTemp1 == 0)
endfunction
private function StartBuilding takes nothing returns nothing
local unit UnitTemp1 = GetTriggerUnit()
local real RealTemp1
local integer IntTemp1 = GetUnitTypeId(UnitTemp1)
set udg_CountBuildingSites = udg_CountBuildingSites + 1
set udg_BuildingSites[udg_CountBuildingSites] = BuildingSite.create()
if (udg_BuildingSites[udg_CountBuildingSites] == 0) then
call DisplayTextToPlayer(Player(0), 0, 0, "ERROR: BuildingSite struct cap exceeded")
return
endif
call udg_BuildingSites[udg_CountBuildingSites].New(UnitTemp1, udg_CountBuildingSites)
set RealTemp1 = GetBuildingSize(IntTemp1)
call SetUnitScale(UnitTemp1, RealTemp1, RealTemp1, RealTemp1)
if (libWal_AdjustConstructingFortification(UnitTemp1)) then
set UnitTemp1 = udg_BuildingSites[udg_CountBuildingSites].GetBuilding()
call ShowUnit(UnitTemp1, false)
set IntTemp1 = GetUnitTypeId(UnitTemp1)
call libUnitDat_ChangeUnit(UnitTemp1, CreateUnit(GetOwningPlayer(UnitTemp1), GetBuildingSiteID(IntTemp1), GetUnitX(UnitTemp1), GetUnitY(UnitTemp1), GetUnitFacing(UnitTemp1)))
call RemoveUnit(UnitTemp1)
set UnitTemp1 = udg_BuildingSites[udg_CountBuildingSites].GetBuilding()
call IssueImmediateOrderById(UnitTemp1, IntTemp1)
set RealTemp1 = GetBuildingSize(IntTemp1)
call SetUnitScale(UnitTemp1, RealTemp1, RealTemp1, RealTemp1)
endif
call libWal_AddBuildingUnderConstruction(UnitTemp1)
if (GetLocalPlayer() == GetOwningPlayer(UnitTemp1)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call SelectUnit(UnitTemp1, true)
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function FinishBuilding_Conditions takes nothing returns boolean
return (GetBuildingValue(GetUnitTypeId(GetTriggerUnit())) != 0.00)
endfunction
private function FinishBuilding takes nothing returns nothing
local unit UnitTemp1 = GetTriggerUnit()
local group GroupTemp1
local integer IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
if (IntTemp1 <= udg_CountBuildingSites and IntTemp1 > 0) then
set GroupTemp1 = udg_BuildingSites[IntTemp1].GetWorkers()
call udg_BuildingSites[IntTemp1].remove()
if (udg_CountBuildingSites != IntTemp1) then
set udg_BuildingSites[IntTemp1] = udg_BuildingSites[udg_CountBuildingSites]
call udg_BuildingSites[IntTemp1].AdjustSystemNumber(IntTemp1)
endif
set udg_BuildingSites[udg_CountBuildingSites] = 0
set udg_CountBuildingSites = udg_CountBuildingSites - 1
call FindBuildingSitesForWorkers(GroupTemp1, GetUnitX(UnitTemp1), GetUnitY(UnitTemp1))
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
set GroupTemp1 = null
endfunction
private function AbortBuilding_Conditions takes nothing returns boolean
return (GetBuildingSiteNumber(GetTriggerUnit()) > 0)
endfunction
private function AbortBuilding takes nothing returns nothing
local unit UnitTemp1 = GetTriggerUnit()
local integer IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
if (IntTemp1 <= udg_CountBuildingSites) then
call udg_BuildingSites[IntTemp1].remove()
if (udg_CountBuildingSites != IntTemp1) then
set udg_BuildingSites[IntTemp1] = udg_BuildingSites[udg_CountBuildingSites]
call udg_BuildingSites[IntTemp1].AdjustSystemNumber(IntTemp1)
endif
set udg_BuildingSites[udg_CountBuildingSites] = 0
set udg_CountBuildingSites = udg_CountBuildingSites - 1
if (GetUnitAbilityLevel(UnitTemp1, libId_udg_RemoveBuilding) > 0) then
call libWal_RemoveBuildingUnderConstruction(UnitTemp1)
call libUnitDat_RemoveObjectUnit(UnitTemp1)
endif
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function BuildingDies_Conditions takes nothing returns boolean
local unit UnitTemp1 = GetDyingUnit()
local integer IntTemp1 = 0
if (GetBuildingValue(GetUnitTypeId(UnitTemp1)) != 0.00) then
set IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
//-----------------
return (IntTemp1 != 0)
endfunction
private function BuildingDies takes nothing returns nothing
local unit UnitTemp1 = GetDyingUnit()
local integer IntTemp1 = GetBuildingSiteNumber(UnitTemp1)
if (IntTemp1 <= udg_CountBuildingSites) then
call udg_BuildingSites[IntTemp1].remove()
if (udg_CountBuildingSites != IntTemp1) then
set udg_BuildingSites[IntTemp1] = udg_BuildingSites[udg_CountBuildingSites]
call udg_BuildingSites[IntTemp1].AdjustSystemNumber(IntTemp1)
endif
set udg_BuildingSites[udg_CountBuildingSites] = 0
set udg_CountBuildingSites = udg_CountBuildingSites - 1
endif
//Anti-Memory-Leak:
set UnitTemp1 = null
endfunction
private function AdjustBuildingTime takes nothing returns nothing
local integer IntLoop1 = 1
loop
exitwhen IntLoop1 > udg_CountBuildingSites
call udg_BuildingSites[IntLoop1].ReduceBuildingTime()
set IntLoop1 = IntLoop1 + 1
endloop
endfunction
private function Construct_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_Construct)
endfunction
private function Construct takes nothing returns nothing
local unit Worker = GetSpellAbilityUnit()
local unit Building = GetSpellTargetUnit()
local integer BuildingSiteNumber = GetBuildingSiteNumber(Building)
if (BuildingSiteNumber > 0) then
call TriggerSleepAction(0.01)
call udg_BuildingSites[BuildingSiteNumber].AddWorker(Worker)
endif
//Anti-Memory-Leak:
set Worker = null
set Building = null
endfunction
private function LeaveBuildingSite_Conditions takes nothing returns boolean
return (GetWorkPower(GetUnitTypeId(GetTriggerUnit())) > 0.00)
endfunction
private function LeaveBuildingSite takes nothing returns nothing
local unit Worker = GetTriggerUnit()
local integer BuildingSiteNumber = GetBuildingSiteNumber(Worker)
if (BuildingSiteNumber > 0) then
call udg_BuildingSites[BuildingSiteNumber].RemoveWorker(Worker)
endif
//Anti-Memory-Leak:
set Worker = null
endfunction
private function DuplicateBuildingSite_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == libId_udg_Duplicate)
endfunction
private function DuplicateBuildingSite takes nothing returns nothing
local unit Building = GetSpellAbilityUnit()
local unit Duplicate
local integer BuildingID = GetUnitTypeId(Building)
local real Facing = GetAdjustedAngle(GetUnitFacing(Building))
local real PosX = GetUnitX(Building)
local real PosY = GetUnitY(Building)
if (Facing == 0.00) then
set PosY = PosY - GetBuildingSiteSquareSize(BuildingID)
elseif (Facing == 90.00) then
set PosX = PosX + GetBuildingSiteSquareSize(BuildingID)
elseif (Facing == 180.00) then
set PosY = PosY + GetBuildingSiteSquareSize(BuildingID)
elseif (Facing == 270.00) then
set PosX = PosX - GetBuildingSiteSquareSize(BuildingID)
endif
if (GetRectMinX(bj_mapInitialPlayableArea) <= PosX and PosX <= GetRectMaxX(bj_mapInitialPlayableArea) and GetRectMinY(bj_mapInitialPlayableArea) <= PosY and PosY <= GetRectMaxY(bj_mapInitialPlayableArea) and IsVisibleToPlayer(PosX, PosY, GetOwningPlayer(Building))) then
set Duplicate = CreateUnit(GetOwningPlayer(Building), BuildingID, PosX, PosY, Facing)
if (Facing == 90.00) then
call UnitRemoveAbility(Duplicate, libId_udg_BuildingFacingDown)
call UnitAddAbility(Duplicate, libId_udg_BuildingFacingUp)
elseif (Facing == 180.00) then
call UnitRemoveAbility(Duplicate, libId_udg_BuildingFacingDown)
call UnitAddAbility(Duplicate, libId_udg_BuildingFacingLeft)
elseif (Facing == 0.00) then
call UnitRemoveAbility(Duplicate, libId_udg_BuildingFacingDown)
call UnitAddAbility(Duplicate, libId_udg_BuildingFacingRight)
endif
if (GetLocalPlayer() == GetOwningPlayer(Duplicate)) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call ClearSelection()
call SelectUnit(Duplicate, true)
endif
endif
//Anti-Memory-Leak:
set Building = null
set Duplicate = null
endfunction
private function SmartOrderOnBuildingSite_Conditions takes nothing returns boolean
return (OrderId2String(GetIssuedOrderId()) == "smart" and GetUnitState(GetOrderTargetUnit(), UNIT_STATE_LIFE) == GetUnitState(GetOrderTargetUnit(), UNIT_STATE_MAX_LIFE) and GetBuildingSiteNumber(GetOrderTargetUnit()) > 0 and GetWorkPower(GetUnitTypeId(GetOrderedUnit())) > 0.00)
endfunction
private function SmartOrderOnBuildingSite takes nothing returns nothing
local unit Worker = GetOrderedUnit()
local unit Building = GetOrderTargetUnit()
call IssueTargetOrder(Worker, "thunderbolt", Building)
//Anti-Memory-Leak:
set Worker = null
set Building = null
endfunction
//---------------
//INITIALISATION:
//---------------
private function Init_BuildingSiteSystem takes nothing returns nothing
local integer IntLoop1 = 1
//Triggers:
call TriggerRegisterTimerEvent(gg_trg_AdjustBuildingTime, udg_BuildingRate, true)
loop
exitwhen IntLoop1 > udg_CountPlayers
call TriggerRegisterPlayerUnitEvent(gg_trg_TurnBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_RemoveBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_StartBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_START, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_FinishBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_FINISH, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_AbortBuilding, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_UPGRADE_CANCEL, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_BuildingDies, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_DuplicateBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_SmartOrderOnBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ISSUED_UNIT_ORDER, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_LeaveBuildingSite, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_ATTACKED, null)
call TriggerRegisterPlayerUnitEvent(gg_trg_Construct, Player(IntLoop1 - 1), EVENT_PLAYER_UNIT_SPELL_CAST, null)
set IntLoop1 = IntLoop1 + 1
endloop
//Conditions:
call TriggerAddCondition(gg_trg_TurnBuilding, Condition(function TurnBuilding_Conditions))
call TriggerAddCondition(gg_trg_RemoveBuilding, Condition(function RemoveBuilding_Conditions))
call TriggerAddCondition(gg_trg_StartBuilding, Condition(function StartBuilding_Conditions))
call TriggerAddCondition(gg_trg_FinishBuilding, Condition(function FinishBuilding_Conditions))
call TriggerAddCondition(gg_trg_AbortBuilding, Condition(function AbortBuilding_Conditions))
call TriggerAddCondition(gg_trg_BuildingDies, Condition(function BuildingDies_Conditions))
call TriggerAddCondition(gg_trg_DuplicateBuildingSite, Condition(function DuplicateBuildingSite_Conditions))
call TriggerAddCondition(gg_trg_SmartOrderOnBuildingSite, Condition(function SmartOrderOnBuildingSite_Conditions))
call TriggerAddCondition(gg_trg_LeaveBuildingSite, Condition(function LeaveBuildingSite_Conditions))
call TriggerAddCondition(gg_trg_Construct, Condition(function Construct_Conditions))
//Actions:
call TriggerAddAction(gg_trg_AdjustBuildingTime, function AdjustBuildingTime)
call TriggerAddAction(gg_trg_TurnBuilding, function TurnBuilding)
call TriggerAddAction(gg_trg_RemoveBuilding, function RemoveBuilding)
call TriggerAddAction(gg_trg_StartBuilding, function StartBuilding)
call TriggerAddAction(gg_trg_FinishBuilding, function FinishBuilding)
call TriggerAddAction(gg_trg_AbortBuilding, function AbortBuilding)
call TriggerAddAction(gg_trg_BuildingDies, function BuildingDies)
call TriggerAddAction(gg_trg_DuplicateBuildingSite, function DuplicateBuildingSite)
call TriggerAddAction(gg_trg_SmartOrderOnBuildingSite, function SmartOrderOnBuildingSite)
call TriggerAddAction(gg_trg_LeaveBuildingSite, function LeaveBuildingSite)
call TriggerAddAction(gg_trg_Construct, function Construct)
endfunction
endlibrary
//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_Worker1b) then //Worker (1)
return "ReplaceableTextures\\CommandButtons\\BTNPeasant.blp"
elseif (UnitID == libId_udg_Worker2a) then //Worker (2)
return "ReplaceableTextures\\CommandButtons\\BTNPeasant.blp"
elseif (UnitID == libId_udg_Worker2b) then //Worker (2)
return "ReplaceableTextures\\CommandButtons\\BTNPeasant.blp"
elseif (UnitID == libId_udg_Worker3a) then //Worker (3)
return "ReplaceableTextures\\CommandButtons\\BTNPeasant.blp"
elseif (UnitID == libId_udg_Worker3b) then //Worker (3)
return "ReplaceableTextures\\CommandButtons\\BTNPeasant.blp"
elseif (UnitID == libId_udg_Worker4a) then //Worker (4)
return "ReplaceableTextures\\CommandButtons\\BTNPeasant.blp"
elseif (UnitID == libId_udg_Worker4b) then //Worker (4)
return "ReplaceableTextures\\CommandButtons\\BTNPeasant.blp"
elseif (UnitID == libId_udg_Worker1e) then //Engineer (1)
return "ReplaceableTextures\\CommandButtons\\BTNMilitia.blp"
elseif (UnitID == libId_udg_Worker2e) then //Engineer (2)
return "ReplaceableTextures\\CommandButtons\\BTNMilitia.blp"
elseif (UnitID == libId_udg_Architect) then //Architect
return "ReplaceableTextures\\CommandButtons\\BTNMilitia.blp"
elseif (UnitID == libId_udg_Architect2) then //Architect (2)
return "ReplaceableTextures\\CommandButtons\\BTNMilitia.blp"
elseif (UnitID == libId_udg_Architect3) then //Architect (3)
return "ReplaceableTextures\\CommandButtons\\BTNMilitia.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=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=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
function Trig_Regrow_Trees_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'AHbz' ) ) then
return false
endif
return true
endfunction
function Trig_Regrow_Trees_Func001003 takes nothing returns nothing
call DestructableRestoreLife( GetEnumDestructable(), GetDestructableMaxLife(GetEnumDestructable()), true )
endfunction
function Trig_Regrow_Trees_Actions takes nothing returns nothing
local location l = GetSpellTargetLoc()
call EnumDestructablesInCircleBJ( 400.00, l, function Trig_Regrow_Trees_Func001003 )
call RemoveLocation(l)
endfunction
//===========================================================================
function InitTrig_Regrow_Trees takes nothing returns nothing
local trigger Regrow_Trees = CreateTrigger( )
call DisableTrigger( gg_trg_Regrow_Trees )
call TriggerRegisterAnyUnitEventBJ( Regrow_Trees , EVENT_PLAYER_UNIT_SPELL_FINISH )
call TriggerAddCondition( Regrow_Trees , Condition( function Trig_Regrow_Trees_Conditions ) )
call TriggerAddAction( Regrow_Trees , function Trig_Regrow_Trees_Actions )
endfunction