//TESH.scrollpos=0
//TESH.alwaysfold=0
Name | Type | is_array | initial_value |
CargoEvent | real | No | |
CargoTransportGroup | group | Yes | |
CargoTransportUnit | unit | Yes | |
CheckDeathList | integer | Yes | |
CheckDeathTimer | timer | No | |
DamageEvent | real | No | |
DamageEventAmount | real | No | |
DamageEventTarget | unit | No | |
DamageEventType | integer | No | |
DamageTypeBlocked | integer | No | |
DamageTypeCriticalStrike | integer | No | |
DamageTypeHeal | integer | No | |
DamageTypeReduced | integer | No | |
DeathEvent | real | No | |
DetectRemoveAbility | abilcode | No | A000 |
DetectTransformAbility | abilcode | No | A001 |
isBuildingUnderConstruction | boolean | Yes | |
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 | |
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_WorkerLumber | unit | No | |
PRM_WorkerLumberValue | integer | No | |
Resource_Ability | abilcode | No | |
Resource_Cost | integer | Yes | |
Resource_CostItem | itemcode | No | |
Resource_CostResearch | techcode | No | |
Resource_CostUnit | unitcode | No | |
Resource_Destructable | destructablecode | Yes | |
Resource_Dummy | unitcode | No | |
Resource_DummyTree | destructablecode | No | |
Resource_Event | real | No | |
Resource_Name | string | Yes | |
Resource_Number | integer | No | |
Resource_Player | player | No | |
Resource_PrintMsgDeveloping | boolean | No | |
Resource_PrintWarnings | boolean | No | |
Resource_Structure | unitcode | Yes | |
Resource_UnitTreeChecker | unit | No | |
Resource_Value | integer | No | |
Resource_Worker | unitcode | Yes | |
SummonerOfUnit | unit | Yes | |
tempInt | integer | No | |
UDex | integer | No | |
UDexLastRecycled | integer | No | |
UDexMax | integer | No | |
UDexNext | integer | Yes | |
UDexPrev | integer | Yes | |
UDexUnits | unit | Yes | |
UnitIndexerEnabled | boolean | No | |
UnitIndexEvent | real | No | |
UnitTypeEvent | real | No | |
UnitTypeOf | unitcode | Yes | |
WorldMaxX | real | No | |
WorldMaxY | real | No |
//TESH.scrollpos=195
//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 UnitEventCheckAfter 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_IsUnitTransforming[i] then
//Added 21 July 2017 to fix the issue re-adding this ability in the same instant
set udg_UDex = i
set udg_UnitTypeEvent = 0.00
set udg_UnitTypeEvent = 1.00
set udg_UnitTypeOf[i] = GetUnitTypeId(udg_UDexUnits[i]) //Set this afterward to give the user extra reference
set udg_IsUnitTransforming[i] = false
call UnitAddAbility(udg_UDexUnits[i], udg_DetectTransformAbility)
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 UnitEventCheckAfterProxy takes integer i returns nothing
if udg_CheckDeathList[0] == 0 then
call TimerStart(udg_CheckDeathTimer, 0.00, false, function UnitEventCheckAfter)
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 UnitEventCheckAfterProxy(i)
endif
elseif GetUnitAbilityLevel(u, udg_DetectTransformAbility) == 0 and not udg_IsUnitTransforming[i] then
set udg_IsUnitTransforming[i] = true
call UnitEventCheckAfterProxy(i) //This block has been updated on 21 July 2017
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_UnitTypeOf[i] = GetUnitTypeId(u)
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 UnitEventCheckAfterProxy(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 load = CreateTrigger()
local trigger death = CreateTrigger()
local trigger summon = CreateTrigger()
local rect r = GetWorldBounds()
local region re = CreateRegion()
local boolexpr enterB = Filter(function UnitEventEnter)
local boolexpr orderB = Filter(function UnitEventOnOrder)
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, enterB)
call TriggerAddCondition(load, Filter(function UnitEventOnLoad))
call TriggerAddCondition(death, Filter(function UnitEventOnDeath))
call TriggerAddCondition(summon, Filter(function UnitEventOnSummon))
loop
set i = i - 1
set p = Player(i)
call SetPlayerAbilityAvailable(p, udg_DetectRemoveAbility, false)
call SetPlayerAbilityAvailable(p, udg_DetectTransformAbility, false)
call TriggerRegisterPlayerUnitEvent(summon, p, EVENT_PLAYER_UNIT_SUMMON, null)
call TriggerRegisterPlayerUnitEvent(t, p, EVENT_PLAYER_UNIT_ISSUED_ORDER, orderB)
call TriggerRegisterPlayerUnitEvent(death, p, EVENT_PLAYER_UNIT_DEATH, null)
call TriggerRegisterPlayerUnitEvent(load, p, EVENT_PLAYER_UNIT_LOADED, null)
call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, p, enterB)
exitwhen i == 0
endloop
set summon = null
set death = null
set load = null
set re = null
set enterB = null
set orderB = null
set p = null
set r = null
set t = null
endfunction
function InitTrig_Unit_Event takes nothing returns nothing
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
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
//TESH.scrollpos=0
//TESH.alwaysfold=0
//===============================================
// 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
// CustomResources 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.4.0.0
// https://www.hiveworkshop.com/threads/gui-unit-event-v2-4-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.
// Configuration is done in "CustomResourcesConfig" trigger. There is nothing to configure here.
// 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 can use the same Worker(s) in many custom resources.
// You can use the same Building(s) in many custom resources.
// You -->cannot<-- use the same destructable in more then one custom resource.
// "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 triggers (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 triggers "ResourceSTONES", "ResourceICEROCKS", "ResourcePlants".
// Example2: To have 5 custom resources:
// Edit existing triggers "ResourceWood/Mushrooms/Stones/Icerocks/Plants".
// Copy/paste "ResourcePLANTS" trigger. Rename it. 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
// use negative <value> to subtract or positive to add resource
// GetPlayerCustomResource(player <p>, integer <resourceNumber>) returns integer
// <resourceNumber> is an integer used in configuration ResourceSOMENAME triggers in first line (Set Resource_Number = X)
// "Custom resource has been changed EVENT"
// use as event "Resource_Event" becomes equal to X (where X is Resource_Number defined in triggers "ResourceSOMENAME")
// variables available inside trigger: "Resource_Player" - owner whos resource nr X has been changed, value is: "Resource_Value" and
// "Resource_Number" - resource's number (defined in triggers "ResourceSOMENAME")
// Tip: 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 udg_isBuildingUnderConstruction[Custom Value of Unit] then ...
library CustomResources initializer Init uses ORDER //v1.31 25-12-2017
globals
public hashtable g_hashCR
private integer array g_harvestAbility
public integer g_customResourcesCount=0
unit g_resourceUnitTreeChecker=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 group g_workerRedirectGroup = CreateGroup()
private timer g_workerRedirectTimer = CreateTimer()
private real array g_X // [GetUnitUserData(u)]
private real array g_Y // [GetUnitUserData(u)]
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]
public trigger g_trg_WorkerBringsResources = CreateTrigger()
private trigger g_trg_ResumeharvestingRedirect = CreateTrigger()
private trigger g_trg_DummyTreeDies = CreateTrigger()
//hashtable keys:
private constant integer KEY_100 = 100 // total workers quantity, connected with harvest ability (abilityId as a parentKey)
private constant integer KEY_200 = 200 // total destructables quantity, connected with harvest ability (abilityId as a parentKey)
private constant integer KEY_300 = 300 // total structures quantity, connected with harvest ability (abilityId as a parentKey)
private constant integer KEY_400 = 400 // for saving abilityId able to harvest given destructable (destructableId as parentKey)
private constant integer KEY_401 = 401 // for saving boolean, as a sign that destructable is registered (destructableId as parentKey)
private constant integer KEY_410 = 410 // for saving boolean, as a sign that worker is registered (workerId as parentKey)
private constant integer KEY_420 = 420 // for saving integer udg_Resource_Number set up at ResourceXXXXX triggers (abilityId as a parentKey)
private constant integer KEY_430 = 430 // for saving boolean, as a sign that structure is registered (structureId as parentKey)
private constant integer KEY_500 = 500 // for saving each players custom resource value (abilityId as a parentKey)
//used in "CustomResourcesCost" addon:
public constant integer KEY_600 = 600 // for saving prices, used as 600 + resourceNumber, (objectId as parentKey)
// remember resource2 cost at 602 key, resource3 at 603 key, .. etc
public constant integer KEY_601 = 601 // for saving boolean, as a sign that object is registered (objectId as parentKey)
endglobals
//=============================================================
function MsgD takes string s returns nothing //for developing mode messages
if udg_Resource_PrintMsgDeveloping then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 10.00, s)
endif
endfunction
function Msg takes player p, string s returns nothing //warning messages
if udg_Resource_PrintWarnings then
call DisplayTextToPlayer(p, 0.00, 0.00, s)
endif
endfunction
private function OnConstruct_Start_Cond takes nothing returns boolean
set udg_isBuildingUnderConstruction[GetUnitUserData(GetConstructingStructure())]=true
return false
endfunction
private function OnConstruct_Finish_Cond takes nothing returns boolean
set udg_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 udg_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, KEY_100+x, udg_Resource_Worker[x]) // remember 1st worker "id" at 101 key
call SaveBoolean(g_hashCR, udg_Resource_Worker[x], KEY_410, true) // save "true" as sign that worker is registered in this system
set x=x+1
endloop
// abilityId as a parentKey , KEY_420 -- abilityId Number (integer)
call SaveInteger(g_hashCR, udg_Resource_Ability, KEY_420, udg_Resource_Number)
//save total workers quantity at "100 key" for this ability
call SaveInteger(g_hashCR, udg_Resource_Ability, KEY_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, KEY_200+x, udg_Resource_Destructable[x]) // remember 1st destruct at 201 key
call SaveInteger(g_hashCR, udg_Resource_Destructable[x], KEY_400, udg_Resource_Ability) // remember abiID to harvest this destr
call SaveBoolean(g_hashCR, udg_Resource_Destructable[x], KEY_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, KEY_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, KEY_300+x, udg_Resource_Structure[x]) // remember 1st structure at 301 key
call SaveBoolean(g_hashCR, udg_Resource_Structure[x], KEY_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, KEY_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
KEY_100 -- workers quantity (abilityId as a parentKey)
101--199 - workers Id's (abilityId as a parentKey)
KEY_200 -- destructables quantity (abilityId as a parentKey)
201--299 - destructables Id's (abilityId as a parentKey)
KEY_300 -- structures quantity (abilityId as a parentKey)
301--399 - structures Id's (abilityId as a parentKey)
KEY_400 -- destructableId as parentKey --> remembers abilityId to harvest this destructabe
call SaveInteger(g_hashCR, destructableId, KEY_400, abiId) --> set abiId = LoadInteger(g_hashCR, destructableId, KEY_400)
KEY_401 -- destructableId as parentKey --> remembers boolean true as sign that destructabe is registered in system
call SaveBoolean(g_hashCR, destructableId, KEY_401, true) --> if LoadBoolean(g_hashCR, destructableId, KEY_401) then ...
KEY_410 -- workerId as parentKey -- > saves boolean true for registered workers in this system
call SaveBoolean(g_hashCR, workerId, KEY_410, true) --> if LoadBoolean(g_hashCR, workerId, KEY_410) then ...
abilityId as a parentKey
KEY_420 -- abilityId Number - integer: udg_Resource_Number (set up at ResourceXXXXX triggers by a user)
KEY_430 -- structureId as parentKey -- > saves boolean true for registered structures in this system
call SaveBoolean(g_hashCR, structureId, KEY_430, true) --> if LoadBoolean(g_hashCR, structureId, KEY_430) then ...
abilityId as a parentKey
KEY_500+playerId => 500 ..to.. 511 - each players resource value
//for Addon "CustomResourcesCost"
KEY_601 -- units/structure/research/upgradeBuilding/items ID as parentKey -- > saves boolean true for registered objects for prices purposes
call SaveBoolean(g_hashCR, objectId, KEY_601, true) --> if LoadBoolean(g_hashCR, objectId, KEY_601) then ...
KEY_600+resourceNumber => 602 .. and up for prices -- object ID as parent key
*/
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
function IsTree takes destructable d returns boolean
return (IssueTargetOrderById(g_resourceUnitTreeChecker, ORDER_harvest, d)) and (IssueImmediateOrderById(g_resourceUnitTreeChecker, 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, KEY_200) // gives total number of destructables quantity at 200 key
loop
exitwhen x>count
if LoadInteger(g_hashCR, abi, KEY_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, KEY_100) // total number of workers at 100 key
loop
exitwhen x>count
if LoadInteger(g_hashCR, abi, KEY_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, KEY_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, KEY_410)
endfunction
//----------------------------------------------------------------------------------
private function IsDestructableRegistered takes integer destructableId returns boolean
return LoadBoolean(g_hashCR, destructableId, KEY_401)
endfunction
//----------------------------------------------------------------------------------
private function IsStructureRegistered takes integer structureId returns boolean
return LoadBoolean(g_hashCR, structureId, KEY_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, KEY_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, KEY_300) // total number of structures for this abi (at 300 key)
set x=1
loop
exitwhen x>count
if LoadInteger(g_hashCR, abi, KEY_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 resourceNr = GetHarvestAbilityNumber(abi)
local integer currentValue = LoadInteger(g_hashCR, abi, KEY_500+playerId)
local integer newValue = currentValue+value
if newValue<0 then //resource level cannot be negative
set newValue=0
endif
call SaveInteger(g_hashCR, abi, KEY_500+playerId, newValue)
// here FIRE EVENT (changed 22-12-2017)
set udg_Resource_Player = Player(playerId)
set udg_Resource_Value = value
set udg_Resource_Number = resourceNr
set udg_Resource_Event = 0.00
set udg_Resource_Event = I2R(resourceNr)
set udg_Resource_Event = 0.00
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, KEY_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
call MsgD("(PRM) time stamp: " + R2S(TimerGetElapsed(g_gameTimer)) + ", " + GetPlayerName(udg_PRM_Player) + ", value: " + I2S(udg_PRM_Change))
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 (we're not writing "normal lumber")
call MsgD(GetUnitName(u) + " brings resource nr(" + I2S(resourceNr) +"), value: " + I2S(g_lastLumberRecivedValue[i]) + ", time stamp: " + R2S(TimerGetElapsed(g_gameTimer)))
endif //FIRE EVENT - MOVED 22-12-2017
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
call Msg(GetOwningPlayer(u), GetUnitName(u) + " |cffff0000cannot|r harvest " + GetDestructableName(GetOrderTargetDestructable()))
call GroupAddUnit(g_workerToStopGroup, u)
call TimerStart(g_stopWorkerTimer, 0.00, false, function StopWorker)
endif
endif
endif
set u=null
endfunction
//---------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------
private function Trig_PointOrderHarvestSmartOffset_Cond takes nothing returns boolean
local integer ord=GetIssuedOrderId() // ORDER_OFFSET = 851970 when building right-cick on destructable and trained worker start walking
return (ord==ORDER_harvest or ord==ORDER_smart or ord==ORDER_OFFSET) and IsWorkerRegistered(GetUnitTypeId(GetOrderedUnit()))
endfunction
//---------------------------------------------------------------------------------------------------------------
private function RedirectWorker_Enum takes nothing returns nothing
call IssuePointOrder(GetEnumUnit(), "smart", g_X[GetUnitUserData(GetEnumUnit())], g_Y[GetUnitUserData(GetEnumUnit())]) //attack-move
call GroupRemoveUnit(g_workerRedirectGroup, GetEnumUnit())
endfunction
private function RedirectWorker takes nothing returns nothing
call ForGroup(g_workerRedirectGroup, function RedirectWorker_Enum)
endfunction
//------------------------------------
private function Trig_PointOrderHarvestSmartOffset_Act takes nothing returns nothing
local unit u=GetOrderedUnit()
if not IsVisibleToPlayer(GetOrderPointX(), GetOrderPointY(), GetOwningPlayer(u)) then
set g_X[GetUnitUserData(u)]=GetOrderPointX()
set g_Y[GetUnitUserData(u)]=GetOrderPointY()
call GroupAddUnit(g_workerRedirectGroup, u)
call TimerStart(g_workerRedirectTimer, 0.00, false, function RedirectWorker)
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 udg_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) then//and udg_Resource_PrintMsgDeveloping then
call MsgD("Redirecting " + GetUnitName(u) + " to " + GetUnitName(g_closestStructure))
endif
call EnableTrigger(g_trg_ResumeharvestingRedirect)
else //no valid structure..
call Msg(GetOwningPlayer(u), GetUnitName(u) + ": |cffffff00 No proper building found to return. |r")
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 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(udg_Resource_DummyTree, 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(udg_Resource_DummyTree, 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()
//moved to the trigger "CustomResourcesConfig"
//set udg_UnitIndexerEnabled = false
//set g_resourceUnitTreeChecker = CreateUnit(Player(15), udg_Resource_Dummy, 0.00, 0.00, 0.00)
//set udg_UnitIndexerEnabled = true
//call ShowUnit(g_resourceUnitTreeChecker, false)
//--------for udg_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)
// point order on destructable - if point not visible redirect order to "smart" to prevent auto-harvest on not-valid destructables
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
call TriggerAddCondition(t, Condition(function Trig_PointOrderHarvestSmartOffset_Cond))
call TriggerAddAction(t, function Trig_PointOrderHarvestSmartOffset_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)
call MsgD("Init in library CS finished succefully")
set t=null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
// This is an addon to "CustomResources" library.
// Allows to set prices for: training / building / upgrades / researches
// This library does not support custom prices for item sell / unit sell.
//
// Installation and configuration
// Copy 2 triggers: "CustomResourcesCostConfig" and "CustomResourcesCost"
// All configuration is done inside trigger "CustomResourcesCostConfig".
// If you're going to use not more then 10 custom resources - use custom script
// in this demo-map there are 4 custom resources (don't count normal WOOD): Mushrooms/Stones/Icerocks/Plants
// they have numbers: Mushrooms-2/Stones-3/Icerocks-4/Plants-5
// for 4 resources to configure cost use function CR_SaveCost4, (for 6 resources use CR_SaveCost6, etc.)
// So unit cost is set using 2 lines:
// Set Resource_CostUnit = Peasant
// Custom Script: call CR_SaveCost4(1, 0, 0, 1)
// First CR_SaveCost4 parameter is Mushrooms price, then Stones price, Icerocks price and Plants price.
// So Peasant costs: 1 Mushroom(number2), 0 Stones(number3), 0 Icerocks(number4) and 1 Plant(number5).
//
// (there is alternative configuration trigger for users who needs more then 10 custom resources)
//
//=========================================================
library CustomResourcesCosts initializer Init uses CustomResources
//------------------------------------------------------------------------------------------------
globals
private group g_groupCancel = CreateGroup()
private timer g_timerCancel = CreateTimer()
private integer array g_upgradeTarget
trigger g_triggerMultiOrderCancel = CreateTrigger()
endglobals
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
// this Addon uses 2 hashtable keys
// KEY_600 => for saving prices, used as 600 + resourceNumber, (objectId as parentKey)
// remember resource2 cost at 602 key, resource3 at 603 key, .. etc
// KEY_601 => for saving boolean, as a sign that object is registered (objectId as parentKey)
//===============================================================================
//experimental version of saving cost 25-12-2017
function CR_SaveCost10 takes integer v2, integer v3, integer v4, integer v5, integer v6, integer v7, integer v8, integer v9, integer v10, integer v11 returns nothing
local integer x=2 // we do not start from "1" as 1 is normal-wood
local integer parentKey // check if it's object or research or item?
local integer array cost
set cost[2]=v2
set cost[3]=v3
set cost[4]=v4
set cost[5]=v5
set cost[6]=v6
set cost[7]=v7
set cost[8]=v8
set cost[9]=v9
set cost[10]=v10
set cost[11]=v11
if udg_Resource_CostUnit>0 then
set parentKey = udg_Resource_CostUnit
elseif udg_Resource_CostResearch>0 then
set parentKey = udg_Resource_CostResearch
elseif udg_Resource_CostItem>0 then
set parentKey = udg_Resource_CostItem
endif
call SaveBoolean(CustomResources_g_hashCR, parentKey, CustomResources_KEY_601, true) // save "true" as sign that object is registered
loop
exitwhen x>CustomResources_g_customResourcesCount
call SaveInteger(CustomResources_g_hashCR, parentKey, CustomResources_KEY_600+x, cost[x])
// remember resource2 cost at 602 key, resource3 at 603 key, .. etc
set x=x+1
endloop
//reset integers for next call:
set udg_Resource_CostUnit = 0
set udg_Resource_CostResearch = 0
set udg_Resource_CostItem = 0
endfunction
//-------------------------------------------------------------------------------------------------------------------------
function CR_SaveCost9 takes integer v2, integer v3, integer v4, integer v5, integer v6, integer v7, integer v8, integer v9, integer v10 returns nothing
call CR_SaveCost10(v2,v3,v4,v5,v6,v7,v8,v9,v10,0)
endfunction
function CR_SaveCost8 takes integer v2, integer v3, integer v4, integer v5, integer v6, integer v7, integer v8, integer v9 returns nothing
call CR_SaveCost10(v2,v3,v4,v5,v6,v7,v8,v9,0,0)
endfunction
function CR_SaveCost7 takes integer v2, integer v3, integer v4, integer v5, integer v6, integer v7, integer v8 returns nothing
call CR_SaveCost10(v2,v3,v4,v5,v6,v7,v8,0,0,0)
endfunction
function CR_SaveCost6 takes integer v2, integer v3, integer v4, integer v5, integer v6, integer v7 returns nothing
call CR_SaveCost10(v2,v3,v4,v5,v6,v7,0,0,0,0)
endfunction
function CR_SaveCost5 takes integer v2, integer v3, integer v4, integer v5, integer v6 returns nothing
call CR_SaveCost10(v2,v3,v4,v5,v6,0,0,0,0,0)
endfunction
function CR_SaveCost4 takes integer v2, integer v3, integer v4, integer v5 returns nothing
call CR_SaveCost10(v2,v3,v4,v5,0,0,0,0,0,0)
endfunction
function CR_SaveCost3 takes integer v2, integer v3, integer v4 returns nothing
call CR_SaveCost10(v2,v3,v4,0,0,0,0,0,0,0)
endfunction
function CR_SaveCost2 takes integer v2, integer v3 returns nothing
call CR_SaveCost10(v2,v3,0,0,0,0,0,0,0,0)
endfunction
function CR_SaveCost1 takes integer v2 returns nothing
call CR_SaveCost10(v2,0,0,0,0,0,0,0,0,0)
endfunction
//-------------------------------------------------------------------------------------------------------------------------
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 or item?
if udg_Resource_CostUnit>0 then
set parentKey = udg_Resource_CostUnit
elseif udg_Resource_CostResearch>0 then
set parentKey = udg_Resource_CostResearch
elseif udg_Resource_CostItem>0 then
set parentKey = udg_Resource_CostItem
endif
call SaveBoolean(CustomResources_g_hashCR, parentKey, CustomResources_KEY_601, true) // save "true" as sign that object is registered
loop
exitwhen x>CustomResources_g_customResourcesCount
call SaveInteger(CustomResources_g_hashCR, parentKey, CustomResources_KEY_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
set udg_Resource_CostItem = 0
endfunction
//------------------------------------------------------------------------------------------------
private function IsCustomCostDefined takes integer objectId returns boolean // object: unit/structure/upgrade-building/research
return LoadBoolean(CustomResources_g_hashCR, objectId, CustomResources_KEY_601)
endfunction
//------------------------------------------------------------------------------------------------
private 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, CustomResources_KEY_600+resourceNumber)
endfunction
//=========================================================
//------------------------TRIGGERS RELATED---------------------------------------------------
//=========================================================
//------------------------------------------------------------------------------
private 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
private function CancelOrder takes nothing returns nothing
call DisableTrigger(g_triggerMultiOrderCancel)
call DisableTrigger(CustomResources_g_trg_WorkerBringsResources) // protect agains double fire "worker brings resource" event
call ForGroup(g_groupCancel, function CancelOrder_Enum)
call EnableTrigger(CustomResources_g_trg_WorkerBringsResources)
call EnableTrigger(g_triggerMultiOrderCancel)
endfunction
private function UnitCancelOrder takes unit u returns nothing
call GroupAddUnit(g_groupCancel, u)
call TimerStart(g_timerCancel, 0.00, false, function CancelOrder)
endfunction
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
private 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 + ("|cff00ff00"+udg_Resource_Name[x] + "|r(" + I2S(cost) + ") ") // green color
else // not enough resource nr x
set hasMoney=false
set s = s + ("|cffff0000"+udg_Resource_Name[x] + "|r(" + I2S(cost) + ") ") // red color
endif
endif
set x=x+1
endloop
if (not hasMoney) then//and udg_Resource_PrintWarnings then
call Msg(pla, "Not enough resources: " + s)
endif
return hasMoney
endfunction
//-------------------------------------------------------------------------------------------
private 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)
//endif
set x=x+1
endloop
call MsgD("CustomCost "+GetPlayerName(pla) + " just payed price for " + GetObjectName(objectId))
endfunction
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
private function Trig_MultiOrder_Cond takes nothing returns boolean
return IsCustomCostDefined(GetIssuedOrderId())
endfunction
//------------------------------------------------------------------------------
private 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
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
if not PlayerHasMoneyForObject(pla, ord) then //no $$$ ?
call UnitCancelOrder(u)
call MsgD("CustomCost "+GetUnitName(u) + " canceled build structure - no money" )
endif // paying is executed under event EVENT_PLAYER_UNIT_CONSTRUCT_START
endif
set u=null
set pla=null
endfunction
//----------------------------------------------------------------------------------
//---------------------------trigger Begins Construction -------------------------
//----------------------------------------------------------------------------------
private function Trig_BeginsConstr_Cond takes nothing returns boolean
return IsCustomCostDefined(GetUnitTypeId(GetConstructingStructure()))
endfunction
//------------------------------------------------------------------
private 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)
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 MsgD("CustomCost "+GetUnitName(u) + " canceled TRAIN" )
endif
//---------------------------------------------------------------------------
elseif h==27 then // EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL
set objectId = GetUnitTypeId(u)
if IsCustomCostDefined(objectId) then
call GiveMoneyBackOnCancel(pla, objectId)
call MsgD("CustomCost "+GetUnitName(u) + " canceled BUILD" )
endif
//---------------------------------------------------------------------------
elseif h==36 then // EVENT_PLAYER_UNIT_RESEARCH_CANCEL
set objectId = GetResearched()
if IsCustomCostDefined(objectId) then
call GiveMoneyBackOnCancel(pla, objectId)
call MsgD("CustomCost "+GetPlayerName(pla) + " canceled 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 MsgD("CustomCost "+GetPlayerName(pla) + " canceled UPGRADE BUILDING" )
endif
//---------------------------------------------------------------------------
endif
set u=null
set pla=null
endfunction
//---------------------------------------------------------------------------------------------
// items based on "Build Tiny Farm" etc:
private function Trig_ItemUsed takes nothing returns boolean
local integer itemId=GetItemTypeId(GetManipulatedItem())
local unit u=GetManipulatingUnit()
local boolean backup=udg_Resource_PrintWarnings
set udg_Resource_PrintWarnings=false
if IsCustomCostDefined(itemId) and (not PlayerHasMoneyForObject(GetOwningPlayer(u), itemId)) then //refund lost item:
set bj_lastCreatedItem = CreateItem(itemId, GetUnitX(u), GetUnitY(u))
call UnitAddItem(u, bj_lastCreatedItem)
endif
set udg_Resource_PrintWarnings=backup
set u=null
return false
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 = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_USE_ITEM)
call TriggerAddCondition(t, Condition(function Trig_ItemUsed))
call MsgD("Init in library Cost finished succefully")
set t=null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_CheckOrder_Actions takes nothing returns nothing
local integer h = GetHandleId(GetTriggerEventId())
local integer ord = GetIssuedOrderId()
if h==38 then
call DisplayTextToPlayer(GetLocalPlayer(), 0.00, 0.00, "instant " + GetUnitName(GetOrderedUnit()) + ", " + I2S(ord) + ", " + OrderId2StringBJ(ord))
elseif h==39 then
call DisplayTextToPlayer(GetLocalPlayer(), 0.00, 0.00, "point " + I2S(ord) + ", " + OrderId2StringBJ(ord))
elseif h==40 then
if GetOrderTargetUnit() != null then
call DisplayTextToPlayer(GetLocalPlayer(), 0.00, 0.00, "target (unit) " + GetUnitName(GetOrderTargetUnit()) + ", " + I2S(ord) + ", " + OrderId2StringBJ(ord))
elseif GetOrderTargetItem() != null then
call DisplayTextToPlayer(GetLocalPlayer(), 0.00, 0.00, "target (item) " + GetItemName(GetOrderTargetItem()) + ", " + I2S(ord) + ", " + OrderId2StringBJ(ord))
elseif GetOrderTargetDestructable() != null then
call DisplayTextToPlayer(GetLocalPlayer(), 0.00, 0.00, "target (destructable) " + GetDestructableName(GetOrderTargetDestructable()) + ", " + I2S(ord) + ", " + OrderId2StringBJ(ord))
endif
endif
endfunction
//===========================================================================
function InitTrig_CheckOrder takes nothing returns nothing
set gg_trg_CheckOrder = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_CheckOrder, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerRegisterAnyUnitEventBJ( gg_trg_CheckOrder, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerRegisterAnyUnitEventBJ( gg_trg_CheckOrder, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
call TriggerAddAction( gg_trg_CheckOrder, function Trig_CheckOrder_Actions )
endfunction