native UnitAlive takes unit u returns boolean
native GetPlayerUnitTypeCount takes player p, integer unitid returns integer
function Msg takes string s returns nothing
//call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.00, 0.00, 20.00, s)
endfunction
Name | Type | is_array | initial_value |
AIGroup | group | No | |
AIgroup1 | group | No | |
autoTrain | boolean | No | false |
CargoEvent | real | No | |
CargoTransportGroup | group | Yes | |
CargoTransportUnit | unit | Yes | |
CheckDeathInList | boolean | Yes | |
CheckDeathList | integer | Yes | |
CheckDeathTimer | timer | No | |
DeathEvent | real | No | |
DetectRemoveAbility | abilcode | No | |
DetectTransformAbility | abilcode | No | |
dial | dialog | No | |
DigitLever | destructable | Yes | |
DigitObelisk | unit | No | |
DigitWin | integer | No | |
dummyResurrection | unit | No | |
enemyRessurectionLoc | location | No | |
EngineerLeverChoosen | integer | No | |
engineerQuest | quest | No | |
EngineersItem | itemcode | Yes | |
EngineersLever | destructable | Yes | |
hero | unit | No | |
heroMuradin | unit | No | |
HideGroup | group | No | |
ic | integer | Yes | |
IllidanGroup | group | No | |
IsUnitAlive | boolean | Yes | |
IsUnitBeingUnloaded | boolean | Yes | |
IsUnitNew | boolean | Yes | |
IsUnitPreplaced | boolean | Yes | |
IsUnitReincarnating | boolean | Yes | |
IsUnitRemoved | boolean | Yes | |
IsUnitTransforming | boolean | Yes | |
itemid1 | integer | Yes | |
itemid2 | integer | Yes | |
itemid3 | integer | Yes | |
itemid4 | integer | Yes | |
itemid5 | integer | Yes | |
itemid6 | integer | Yes | |
KillerOfUnit | unit | Yes | |
longPassageQuest | quest | No | |
lp_point | location | No | |
medivhQuest | quest | No | |
mesetaCount | integer | No | |
mesetaGroup | group | No | |
muradinTalkEffect | effect | No | |
output | integer | Yes | |
questReq | questitem | Yes | |
QWispActivated | integer | No | |
QWispAwardItem | item | No | |
QWispBuilding | unit | Yes | |
QWispChild | unit | Yes | |
QWispDruid | unit | No | |
QWispNo | integer | No | |
RC | boolean | No | |
ResurrectionStoneItem | item | No | ItemNull |
RN | integer | No | |
RT | trigger | No | |
SummonerOfUnit | unit | Yes | |
tempInt | integer | No | |
tempPoint | location | No | |
tempU | unit | No | |
testSound | sound | No | |
UDex | integer | No | |
UDexGen | integer | No | |
UDexLastRecycled | integer | No | |
UDexMax | integer | No | |
UDexNext | integer | Yes | |
UDexPrev | integer | Yes | |
UDexRecycle | integer | No | |
UDexUnits | unit | Yes | |
UDexWasted | integer | No | |
UnitIndexerEnabled | boolean | No | |
UnitIndexEvent | real | No | |
UnitName | string | Yes | |
UnitTypeEvent | real | No | |
UnitTypeOf | unitcode | Yes | |
waterBucket3 | unit | No | |
waterBucket5 | unit | No | |
waterBucket8 | unit | No | |
waterPriest | unit | No | |
waterQuest | quest | No | |
waterRoots | destructable | No | |
WispQuestNo | integer | No | |
wispsQuest | quest | No | |
WorldMaxX | real | No | |
WorldMaxY | real | No |
//===========================================================================
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 = 0
loop
set i = udg_CheckDeathList[i]
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 udg_CheckDeathInList[i] = false
endloop
//Empty the list
set udg_CheckDeathList[0] = 0
endfunction
function UnitEventCheckAfterProxy takes integer i returns nothing
if udg_CheckDeathList[0] == 0 then
call TimerStart(udg_CheckDeathTimer, 0.00, false, function UnitEventCheckAfter)
endif
if not udg_CheckDeathInList[i] then
set udg_CheckDeathList[i] = udg_CheckDeathList[0]
set udg_CheckDeathList[0] = i
set udg_CheckDeathInList[i] = true
endif
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
set udg_CheckDeathInList[i] = false
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 = bj_MAX_PLAYER_SLOTS //update to make it work with 1.29
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_CheckDeathList[0] = 0
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=248
//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 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
//
//func: CSUnit_GetPrimaryAttacker takes unit victim returns unit
//var: isAttacked // unit user data of victim
globals
boolexpr cs_filtr_alive=null
boolexpr cs_filtr_onlyUnits=null
boolexpr cs_filtr_onlyHeroes=null
hashtable g_CShash = InitHashtable() // used only by CombatState system
group array g_AttackersGroup // [victim's unit user data]
group cs_group=CreateGroup()
unit g_gaPrimaryAttacker=null //Get-Unit-PrimaryAttacker part
timer array g_CSS_tmr //unit user data of victim
boolean array isAttacked // unit user data of victim
trigger trg_CSS_OnDmg=null
endglobals
//hash
// GetHandleId(victim) -->
// SaveReal - attackerId (GetUnitUserData) - saves attacker's damage dealt to victim
// SaveReal - playerId + KEY_DAMAGE_DEALT_BY_PLAYER saves player attacker's damage dealt to victim
// SaveReal - KEY_SAVE_THREAD_PLAYERS_TIME saves time to not repeat actions "CSSortThreadPlayers"
// SaveInteger - KEY_THREAD_PLAYER + positionOnList saves player's id who is on given position on thread list
function CSUnit_Attacked takes unit victim returns boolean
return isAttacked[GetUnitUserData(victim)]
endfunction
function CSUnit_GetDamageDealtByUnit takes unit victim, unit attacker returns real
return LoadReal(g_CShash, GetHandleId(victim), GetUnitUserData(attacker))
endfunction
//-------------------------------------------------------------------------------------------------------------
//---------GET UNIT PRIMARY ATTACKER ---------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
function CSUnit_GetPrimaryAttackerEx takes unit victim, real x, real y, integer maxRangeFromXY returns unit
local player p=GetOwningPlayer(victim)
local integer id=GetUnitUserData(victim)
local unit FoG=null
local real value=0.00
local real maxValue=0.00
set g_gaPrimaryAttacker=null
if isAttacked[id] then
//unit or hero
call GroupEnumUnitsInRange(cs_group, x, y, maxRangeFromXY, cs_filtr_alive)
loop
set FoG = FirstOfGroup(cs_group)
exitwhen FoG == null
if (IsUnitVisible(FoG, p)) and IsUnitInGroup(FoG, g_AttackersGroup[id]) and IsUnitEnemy(FoG, p) then
set value = LoadReal(g_CShash, GetHandleId(victim), GetUnitUserData(FoG))
set value = value / (GetWidgetLife(FoG)+1.00) //for CS_BY_THREAD_AND_HP
if value>maxValue then
set maxValue=value
set g_gaPrimaryAttacker = FoG
endif
endif
call GroupRemoveUnit(cs_group, FoG)
endloop
call GroupClear(cs_group)
//---------------------
endif
set p=null
return g_gaPrimaryAttacker
endfunction
//------------------------------------------------------------
function CSUnit_GetPrimaryAttacker takes unit victim returns unit
return CSUnit_GetPrimaryAttackerEx(victim, GetUnitX(victim), GetUnitY(victim), 600)
endfunction
//------------------------------------------------------------
//------------------------------------------------------------
function CSS_tmr_exp takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer id = LoadInteger(g_CShash, GetHandleId(t), 0)
set isAttacked[id]=false
set t=null
endfunction
//===========================================================================
//===== trigger's related functions: unit takesDamage ==============================
//===========================================================================
function Trig_CSSOnDamage takes nothing returns boolean
// local real time = TimerGetElapsed(g_timerGame) // time stamp ticking up ...
local integer id = GetUnitUserData(GetTriggerUnit()) // damaged
local integer h_id = GetHandleId(GetTriggerUnit())
local integer attackerId = GetUnitUserData(GetEventDamageSource())
local real cumulatedDamage = 0.00
local real dmg = GetEventDamage()
//DAMAGED UNIT:
//save attacker damage
if IsUnitInGroup(GetEventDamageSource(), g_AttackersGroup[id]) then
set cumulatedDamage = LoadReal(g_CShash, h_id, attackerId) // previous cumulated damage dealt by this attacker
endif
call SaveReal(g_CShash, h_id, attackerId, cumulatedDamage+dmg) //save damage for attacker
//ATTACKER
call GroupAddUnit(g_AttackersGroup[id], GetEventDamageSource())
set isAttacked[id]=true
call SaveInteger(g_CShash, GetHandleId(g_CSS_tmr[id]), 0, id)//save victim id with a timer
call TimerStart(g_CSS_tmr[id], 6.00, false, function CSS_tmr_exp)
return false
endfunction
//===========================================================================
function F_Alive takes nothing returns boolean
return UnitAlive(GetFilterUnit()) and (not BlzIsUnitInvulnerable(GetFilterUnit())) and(GetUnitAbilityLevel(GetFilterUnit(), 'Aloc')==0)
endfunction
function F_OnlyHeroes takes nothing returns boolean
return UnitAlive(GetFilterUnit()) and IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO)
endfunction
function F_OnlyUnits takes nothing returns boolean
return UnitAlive(GetFilterUnit()) and (not IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO))
endfunction
//============== run on map init for each unit =============================
function CSS_RegisterUnit takes unit u returns nothing
local integer id=GetUnitUserData(u)
call TriggerRegisterUnitEvent(trg_CSS_OnDmg, u, EVENT_UNIT_DAMAGED) //REGISTER UNIT
//create attackers group and timer for all registered units:
set g_AttackersGroup[id] = CreateGroup()
set g_CSS_tmr[id] = CreateTimer()
endfunction
//===========================================================================
function InitTrig_CombatStateSimple takes nothing returns nothing
set trg_CSS_OnDmg = CreateTrigger()
call TriggerAddCondition(trg_CSS_OnDmg, Condition(function Trig_CSSOnDamage))
//---
//call TimerStart(g_timerGame, 36000.00, false, null)//=10 hours
set cs_filtr_alive = Condition(function F_Alive)
set cs_filtr_onlyHeroes = Condition(function F_OnlyHeroes)
set cs_filtr_onlyUnits = Condition(function F_OnlyUnits)
endfunction
globals
boolean array g_unitChanneling // [unit's unit user data]
endglobals
//-------------------------------------------------------------------------------------------
function UnitChanneling takes unit u returns boolean
return g_unitChanneling[GetUnitUserData(u)]
endfunction
//-------------------------------------------------------------------------------------------
function UnitSpellReady takes unit u, integer spellId returns boolean
local integer level = GetUnitAbilityLevel(u, spellId)
local boolean cdReady = (level>0) and (BlzGetUnitAbilityCooldownRemaining(u, spellId) == 0.00)
local boolean hasMana = (GetUnitState(u, UNIT_STATE_MANA) >= I2R(BlzGetAbilityManaCost(spellId, level)))
return cdReady and hasMana
endfunction
//-------------------------------------------------------------------------------------------
function Trig_Unit_StartChannel takes nothing returns boolean
set g_unitChanneling[GetUnitUserData(GetTriggerUnit())] = true
return false
endfunction
//-------------------------------------------------------------------------------------------
function Trig_Unit_EndChannel takes nothing returns boolean
set g_unitChanneling[GetUnitUserData(GetTriggerUnit())] = false
return false
endfunction
//==================================================================
function InitTrig_SpellState takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CHANNEL) //triggers to set boolean variable "g_unitChanneling[unit user data]"
call TriggerAddCondition(t, Condition(function Trig_Unit_StartChannel))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_ENDCAST)
call TriggerAddCondition(t, Condition(function Trig_Unit_EndChannel))
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
library IsDestructableTree uses optional UnitIndexer /* v1.3.1
*************************************************************************************
* http://www.hiveworkshop.com/forums/jass-resources-412/snippet-isdestructabletree-248054/
* by BPower
* Detect whether a destructable is a tree or not.
*
***************************************************************************
*
* Credits
*
* To PitzerMike
* -----------------------
*
* for IsDestructableTree
*
*************************************************************************************
*
* Functions
*
* function IsDestructableTree takes destructable d returns boolean
*
* function IsDestructableAlive takes destructable d returns boolean
*
* function IsDestructableDead takes destructable d returns boolean
*
* function IsTreeAlive takes destructable tree returns boolean
* - May only return true for trees.
*
* function KillTree takes destructable tree returns boolean
* - May only kill trees.
*
*/
globals
private constant integer HARVESTER_UNIT_ID = 'hpea'//* human peasant
private constant integer HARVEST_ABILITY = 'Ahrl'//* ghoul harvest
private constant integer HARVEST_ORDER_ID = 0xD0032//* harvest order ( 852018 )
private constant player NEUTRAL_PLAYER = Player(PLAYER_NEUTRAL_PASSIVE)
private unit harvester = null
endglobals
function IsDestructableTree takes destructable d returns boolean
//* 851973 is the order id for stunned, it will interrupt the preceding harvest order.
return (IssueTargetOrderById(harvester, HARVEST_ORDER_ID, d)) and (IssueImmediateOrderById(harvester, 851973))
endfunction
function IsDestructableDead takes destructable d returns boolean
return (GetWidgetLife(d) <= 0.405)
endfunction
function IsDestructableAlive takes destructable d returns boolean
return (GetWidgetLife(d) > .405)
endfunction
function IsTreeAlive takes destructable tree returns boolean
return IsDestructableAlive(tree) and IsDestructableTree(tree)
endfunction
function KillTree takes destructable tree returns boolean
if (IsTreeAlive(tree)) then
call KillDestructable(tree)
return true
endif
return false
endfunction
private function Init takes nothing returns nothing
static if LIBRARY_UnitIndexer then//* You may adapt this to your own indexer.
set UnitIndexer.enabled = false
endif
set harvester = CreateUnit(NEUTRAL_PLAYER, HARVESTER_UNIT_ID, 0, 0, 0)
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = true
endif
call UnitAddAbility(harvester, HARVEST_ABILITY)
call UnitAddAbility(harvester, 'Aloc')
call ShowUnit(harvester, false)
endfunction
//* Seriously?
private module Inits
private static method onInit takes nothing returns nothing
call Init()
endmethod
endmodule
private struct I extends array
implement Inits
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
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
//TESH.scrollpos=672
//TESH.alwaysfold=0
library KnockbackSimple initializer Init uses IsDestructableTree, TerrainPathability // by ZibiTheWand3r3r v.1.03
// Features:
// Simple to use knockback: one function call, configurable behavior (16 possible versions), supports diffrent collision sizes
// callback function, can destroy knockbacks any time, system is for ground units only
// *****************************
// Requires:
// library IsDestructableTree * by BPower:
// http://www.hiveworkshop.com/forums/jass-resources-412/snippet-isdestructabletree-248054/
// library TerrainPathability * by Rising_Dusk
// http://www.wc3c.net/showthread.php?t=103862
// GUI Unit Event v2.2.1.0 * by Bribe
// http://www.hiveworkshop.com/threads/gui-unit-event-v2-2-1-0.201641/
// *****************************
// How to use:
// function KnockBack takes:
// (code) onHitCode = code that will be executed when unit bounce/hits other unit/obstacles (structure, cliff, doodad, tree)
// set to "null" if not needed, (onHitCode is executed as trigger action)
// (unit) u = knockbacked unit
// (real) distance = how far unit will be moved
// (real) duration = how long knockback exists [sec]
// (real) angle = knockback angle [in radians!]
// (boolean) interruptSpells = if "true" it's interrupts orders/channeling spells on unit u, when knockback starts
// (boolean) killTrees = if "true" unit(s) will destroy trees if unit travels with >minimum speed, kb_minSpeedToKillTree
// (boolean) disableMovement = if "true" unit won't be able to move during knockback, it's using SetUnitPropWindow
// technique, so if you already using this in your map it may interfere. In this case set this boolean to false.
// (integer) kbType see table below, avaiable 4 types: KB_TYPE_NO_BOUNCE ,
// KB_TYPE_SLIDE , KB_TYPE_STOP_ON_OBSTACLES , KB_TYPE_NORMAL
// (integer) bounceTypeFiltr see table below, avaiable 4 filters: KB_FILTR_BOUNCE_NONE ,
// KB_FILTR_BOUNCE_ENEMY_ONLY , KB_FILTR_BOUNCE_ALLIED_ONLY , KB_FILTR_BOUNCE_ALL
// (string) effects - special effect played on unit(s) every given distance (variable effectOccursDistance),
// if null, no effect will be played
// (string) effectAttachPoint - atachment point for special effect, example: "origin"
// (real) effectOccursDistance - special effect declared above will be played every [effectOccursDistance] distance
// *****************************
// (code) onHitCode example:
// function OnHitExample takes nothing returns nothing
// avaiable global variables inside this callback function, read-only:
// (unit) kb_unit = main unit connected with this function
// (unit) kb_obstacle_unit = unit who was hit by kb_unit (if a unit was hit)
// (integer) kb_hitCount = counts all hits done by kb_unit
// (integer) kb_callback use to determine 2 'events' type: KB_HIT_OBSTACLE_UNIT or KB_HIT_THE_WALL
// KB_HIT_THE_WALL = structure or doodad or cliff or tree, if KB_HIT_OBSTACLE_UNIT it refers to kb_obstacle_unit
// don't use "waits" here
// if kb_callback == KB_HIT_OBSTACLE_UNIT and kb_hitCount == 1 then
// call DisplayTextToForce(GetPlayersAll(), GetUnitName(kb_unit) + " hits the " + GetUnitName(kb_obstacle_unit))
// endif
// endfunction
// *****************************
// knockback types / bounce types description
// kbType: KB_TYPE_NO_BOUNCE: stops on obstacles /structures/cliffs/doodads
// if code "onHitCode" is specifed then it will be executed when unit hits obstacle/unit
// kb_bounceFiltrType: KB_FILTR_BOUNCE_NONE:
// ignore all units pathing on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ENEMY_ONLY:
// ignore alied units pathing on my way, stops on first enemy unit on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALLIED_ONLY:
// ignore enemy units pathing on my way, stops on first allied unit on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALL:
// stops on first unit found on my way
// kb_type: KB_TYPE_SLIDE: bounce me on obstacles and:
// if code "onHitCode" is specifed then it will be executed when unit hits obstacle/unit
// kb_bounceFiltrType: KB_FILTR_BOUNCE_NONE:
// ignore all units pathing on my way, don't bounce me from other units, and *don't bounce any units on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ENEMY_ONLY:
// ignore all units pathing on my way, don't bounce me from other units, but bounce unit on my way- enemies only
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALLIED_ONLY:
// ignore all units pathing on my way, don't bounce me from other units, but bounce unit on my way- allied only
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALL:
// ignore all units pathing on my way, don't bounce me from other units, but bounce all units on my way
// --> if 2 knockbacked units meet, KB_TYPE_SLIDE has priority and it *may* overwrite existing knockback <---
// --> if KB_TYPE_SLIDE will bounce other units it will be done with angle 90 degrees <--
// kb_type: KB_TYPE_STOP_ON_OBSTACLES: don't bounce me on obstacles structures/cliffs/doodads/trees and:
// if code "onHitCode" is specifed then it will be executed if unit hits obstacle/unit
// kb_bounceFiltrType: KB_FILTR_BOUNCE_NONE:
// bounce me on any other unit, and don't bounce units on my way (allied and enemy)
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ENEMY_ONLY:
// ignore only allies pathing on my way, and bounce me and enemy units on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALLIED_ONLY:
// ignore only enemies pathing on my way, and bounce me and allied units on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALL:
// bounce me on other unit, and bounce all units on my way (allied and enemy)
// kb_type: KB_TYPE_NORMAL: bounce me on obstacles and:
// if code "onHitCode" is specifed then it will be executed if unit hits obstacle/unit
// kb_bounceFiltrType: KB_FILTR_BOUNCE_NONE:
// bounce me on any other unit, and don't bounce units on my way (allied and enemy)
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ENEMY_ONLY:
// ignore only allies pathing on my way, and bounce me and enemy units on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALLIED_ONLY:
// ignore only enemies pathing on my way, and bounce me and allied units on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALL:
// bounce me on other unit, and bounce all units on my way (allied and enemy)
//
private function KB_FilterOutAbility takes integer abiId returns nothing
set kb_filterOutAbiInteger = kb_filterOutAbiInteger + 1
set kb_filterOutAbility[kb_filterOutAbiInteger] = abiId
endfunction
//*****************************************************************
// **************** BEGIN OF USER CONFIGURABLES **********************
private function KB_AdvancedUserConfigurables takes nothing returns nothing
// these will apply >globaly< to knockback system:
set kb_minSpeedToKillTree = 500.00 // minimum unit speed that allow to destroy tree, only positive values allowed
set kb_reduceSpeedOnHitFactor = 20.00 // allowed range: 0 ... 100
// (very high values of kb_reduceSpeedOnHitFactor may look ugly and cause unit to stop instantly)
// following settings will filter out units with abilities "ghost" "ghosts visible" and with buff "windwalk"
// so units with these abilities will not be bounced, as they already can be walked over
call KB_FilterOutAbility('Agho')
call KB_FilterOutAbility('Aeth')
call KB_FilterOutAbility('BOwk')
// you can add more abilities/buffs here like 3 above
// call KB_FilterOutAbility('YourAbiId')
endfunction
// **************** END OF USER CONFIGURABLES ************************
//*****************************************************************
globals
group kb_ug
real array kb_distance
real array kb_time
real array kb_angle
real array kb_d1
real array kb_d2
real array kb_sin
real array kb_cos
boolean array kb_killTrees
boolean array kb_interruptSpells
boolean array kb_disableMovement
integer array kb_knockbackType
integer array kb_bounceFiltrType
string array kb_effect
string array kb_effectAttachPoint
real array kb_effectOccursDistance
real array kb_lastDistanceEffect
real array kb_collision
real array kb_distanceLeft
real array kb_timeLeft
trigger array kb_trg_onHit
trigger kb_trg_loop
integer array kb_hitCounter // for callback function
integer kb_hitCount = 0 // for callback function
unit kb_unit = null // for callback function
unit kb_obstacle_unit = null // for callback function
player kb_player
rect kb_rect
group kb_group
timer kb_timer
real kb_minSpeedToKillTree = 500.00
real kb_reduceSpeedOnHitFactor = 10.00
real kb_reduceSpeedOnHit = 1.00
constant real KB_DETECT_OBSTACLE_UNIT_RADIUS = 150.00
constant real KB_INTERVAL = 0.03125
constant real KB_STEPS_PER_SEC = 1.00 / KB_INTERVAL
constant real KB_PI_DIVIDED_BY_2 = bj_PI / 2.00
constant real KB_PI_MULTIPLIED_BY_2 = bj_PI * 2.00
boolexpr array kb_filtr
constant integer KB_FILTR_BOUNCE_NONE = 0
constant integer KB_FILTR_BOUNCE_ENEMY_ONLY = 2
constant integer KB_FILTR_BOUNCE_ALLIED_ONLY = 3
constant integer KB_FILTR_BOUNCE_ALL = 4
constant integer KB_TYPE_NO_BOUNCE = 0
constant integer KB_TYPE_SLIDE = 10
constant integer KB_TYPE_STOP_ON_OBSTACLES = 20
constant integer KB_TYPE_NORMAL = 30
constant integer KB_HIT_OBSTACLE_UNIT = 101
constant integer KB_HIT_THE_WALL = 102
integer kb_callback
integer kb_filterOutAbiInteger = 0
integer array kb_filterOutAbility
endglobals
//-----------------------------------------------------------
//x, y, = centerX, centerY
//-----------------------------------------------------------
function KB_IsPointWalkableForSize takes real x, real y, real whatSize returns boolean //x, y, = centerX, centerY
if whatSize <= 16.00 then //one item check:
return IsTerrainWalkable(x, y)
endif // for larger units: 5 item checks
return IsTerrainWalkable(x, y) and IsTerrainWalkable(x+32.00, y) and IsTerrainWalkable(x-32.00, y) and IsTerrainWalkable(x, y+32.00) and IsTerrainWalkable(x, y-32.00)
endfunction
//------------------------------------------------------------
//------------------------------------------------------------
function KB_GetBounceAngle takes real angle, real x, real y, integer id returns real
local real newAngleVer1 = ( - angle )
local real newAngleVer2 = ( - bj_PI - angle ) // for negative angles
if angle>0.00 then
set newAngleVer2 = (bj_PI - angle)
endif
//++++
if KB_IsPointWalkableForSize(x+kb_d1[id] * Cos(newAngleVer1), y+kb_d1[id] * Sin(newAngleVer1), kb_collision[id]) then
return newAngleVer1
elseif KB_IsPointWalkableForSize(x+kb_d1[id] * Cos(newAngleVer2), y+kb_d1[id] * Sin(newAngleVer2), kb_collision[id]) then
return newAngleVer2
else //3rd version - reverse direction:
set newAngleVer1 = (angle + bj_PI) // for negative angle
if angle>0.00 then
set newAngleVer1 = (angle - bj_PI)
endif
endif
return newAngleVer1
endfunction
//------------------------------------------------------------
//-----------------------------x/y = obstacleUnit X/Y
function KB_GetBounceAngle90 takes real angle, real x, real y, real unitX, real unitY returns real
local real newAnglePlus = ModuloReal((angle + KB_PI_DIVIDED_BY_2), KB_PI_MULTIPLIED_BY_2) // +90
local real newAngleMinus = ModuloReal((angle - KB_PI_DIVIDED_BY_2), KB_PI_MULTIPLIED_BY_2) // -90
local real x1 = x+32.00 * Cos(newAnglePlus)
local real y1 = y+32.00 * Sin(newAnglePlus)
local real x2 = x+32.00 * Cos(newAngleMinus)
local real y2 = y+32.00 * Sin(newAngleMinus)
//compare distances
if ((x1-unitX) * (x1-unitX) + (y1-unitY) * (y1-unitY)) > ((x2-unitX) * (x2-unitX) + (y2-unitY) * (y2-unitY)) then
return newAnglePlus
endif
return newAngleMinus
endfunction
//-------------------------------------------------------------------------------
//-------------Zwiebelchen:-------------------------------------------
// The difference between GroupEnumUnitsInRange and IsUnitInRangeXY is, that the former will only enumerate units
// whose coordinate center is inside the radius.
// The IsUnitInRange natives will already return true if only a part of the unit is inside the radius.
//--------------------------------------------------------
// KB_GetUnitCollisionSize checks up to 64 unit collision size // returns values from 8 ..to.. 64
//--------------------------------------------------------
function KB_GetUnitCollisionSize takes unit u, real unitX, real unitY returns real
local real i=0.00
local real size=64.00
loop
exitwhen i==64.00
if not IsUnitInRangeXY(u, (unitX+i), unitY, 0.00) then
set size = (i-1.00)
exitwhen true
endif
set i=i+1.00
endloop
if size<8.00 then
return 8.00
endif
return size
endfunction
//------------------------------------------------------------
function IsUnitAlive takes unit u returns boolean
return not (GetUnitTypeId(u) == 0 or IsUnitType(u, UNIT_TYPE_DEAD))
endfunction
//------------------------------------------------------------
// DisableUnitMovement /* v1.0.0.1
// * Disables unit movement. They can still turn, but will stay in
// * place. It simulates an ensnare-like effect, except that it will
// * not ground units, it does not have buffs, does not interrupt
// * channeled casts and appears to have no downsides.
// * Full credits to WaterKnight for discovering this technique.
//--------------------------------------------------------------------
function DisableUnitMovement takes unit u returns nothing
call SetUnitPropWindow(u, 0)
endfunction
//--------------------------------------------------------------------
function EnableUnitMovement takes unit u returns nothing
call SetUnitPropWindow(u, GetUnitDefaultPropWindow(u) * bj_DEGTORAD)
endfunction
//------------------------------------------------------------
function KBFiltr_1 takes unit u returns boolean
local integer a=1
local integer id = GetUnitUserData(u)
local boolean isKb = IsUnitInGroup(u, kb_group) // is knockbacked?
if IsUnitAlive(u) and (not IsUnitType(u, UNIT_TYPE_FLYING)) and (not IsUnitType(u, UNIT_TYPE_STRUCTURE)) and (IsUnitVisible(u, kb_player)) then
if not (isKb and ((kb_knockbackType[id]==KB_TYPE_SLIDE) or (kb_knockbackType[id]==KB_TYPE_NO_BOUNCE and kb_bounceFiltrType[id]==KB_FILTR_BOUNCE_NONE))) then
if not (isKb and ((IsUnitAlly(u, kb_player) and kb_bounceFiltrType[id]==KB_FILTR_BOUNCE_ENEMY_ONLY) or (IsUnitEnemy(u, kb_player) and kb_bounceFiltrType[id]==KB_FILTR_BOUNCE_ALLIED_ONLY))) then
loop
exitwhen a>kb_filterOutAbiInteger
if GetUnitAbilityLevel(u, kb_filterOutAbility[a]) > 0 then
return false
endif
set a=a+1
endloop
return true
endif
endif
endif
return false
endfunction
//--------
function KBFiltr_groundNotStruc takes nothing returns boolean
return KBFiltr_1(GetFilterUnit())
endfunction
// set kb_player before confirm this 2 checks!
function KBFiltr_groundNotStrucAlliedOnly takes nothing returns boolean
return KBFiltr_1(GetFilterUnit()) and IsUnitAlly(GetFilterUnit(), kb_player)
endfunction
function KBFiltr_groundNotStrucEnemyOnly takes nothing returns boolean
return KBFiltr_1(GetFilterUnit()) and IsUnitEnemy(GetFilterUnit(), kb_player)
endfunction
//------------------------------------------------------------------------
function KB_OnRemoveFromGame takes nothing returns nothing
call GroupRemoveUnit(kb_group, udg_UDexUnits[udg_UDex])
//clean:
if kb_trg_onHit[udg_UDex] != null then
call DestroyTrigger(kb_trg_onHit[udg_UDex])
set kb_trg_onHit[udg_UDex] = null
endif
set kb_effect[udg_UDex] = null
set kb_effectAttachPoint[udg_UDex] = null
if FirstOfGroup(kb_group)==null then
call PauseTimer(kb_timer)
endif
endfunction
//----------------------------------------------------------------------------
function KB_DestroyKnockbackOnUnit takes unit u returns nothing
local integer id = GetUnitUserData(u)
call GroupRemoveUnit(kb_group, u)
if kb_trg_onHit[id] != null then
call DestroyTrigger(kb_trg_onHit[id])
set kb_trg_onHit[id] = null
endif
call EnableUnitMovement(u)
set kb_effect[id] = null
set kb_effectAttachPoint[id] = null
if FirstOfGroup(kb_group)==null then
call PauseTimer(kb_timer)
endif
endfunction
//----------------------------------------------------------------------------
function KB_DestroyAllEnum takes nothing returns nothing
call KB_DestroyKnockbackOnUnit(GetEnumUnit())
endfunction
//----------------------------
function KB_DestroyAllKnockbacks takes nothing returns nothing
call ForGroup(kb_group, function KB_DestroyAllEnum)
endfunction
//----------------------------
//=======================================================
function KB_CheckAllowedTypes takes integer kbType, integer bounceTypeFiltr returns boolean
if kbType == KB_TYPE_NO_BOUNCE or kbType == KB_TYPE_SLIDE or kbType == KB_TYPE_STOP_ON_OBSTACLES or kbType == KB_TYPE_NORMAL then
if bounceTypeFiltr == KB_FILTR_BOUNCE_NONE or bounceTypeFiltr == KB_FILTR_BOUNCE_ENEMY_ONLY or bounceTypeFiltr == KB_FILTR_BOUNCE_ALLIED_ONLY or bounceTypeFiltr == KB_FILTR_BOUNCE_ALL then
return true
endif
endif
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Knockback error: wrong integer pass to function")
return false
endfunction
//-----------------------------------------------------------------------------------------
//-----main function --------------------------------------------------------------------
function KnockBack takes code onHitCode, unit u, real distance, real duration, real angle, boolean interruptSpells, boolean killTrees, boolean disableMovement, integer kbType, integer bounceTypeFiltr, string effects, string effectAttachPoint, real effectOccursDistance returns nothing
local integer id = GetUnitUserData(u)
local integer q = R2I(duration / KB_INTERVAL) // (Number of steps)
local real x = GetUnitX(u)
local real y = GetUnitY(u)
if GetUnitDefaultMoveSpeed(u) == 0.00 or (not KB_CheckAllowedTypes(kbType, bounceTypeFiltr)) then //protection
return
endif
set kb_effect[id] = null
set kb_effectAttachPoint[id] = null
if kb_trg_onHit[id] != null then
call DestroyTrigger(kb_trg_onHit[id])
set kb_trg_onHit[id] = null
endif
if onHitCode != null then
set kb_trg_onHit[id] = CreateTrigger()
call TriggerAddAction(kb_trg_onHit[id], onHitCode)
endif
set kb_distance[id] = distance
set kb_distanceLeft[id] = distance
set kb_time[id] = duration
set kb_timeLeft[id] = duration
set kb_hitCounter[id] = 0
set kb_angle[id] = angle
set kb_sin[id] = Sin(angle)
set kb_cos[id] = Cos(angle)
set kb_d1[id] = 2 * kb_distance[id] / (q + 1) // the "bit" in "moving a unit a bit a time"
set kb_d2[id] = kb_d1[id] / q // will decrease d1 with each execution
set kb_killTrees[id] = killTrees
set kb_interruptSpells[id] = interruptSpells
set kb_disableMovement[id] = disableMovement
set kb_knockbackType[id] = kbType
set kb_bounceFiltrType[id] = bounceTypeFiltr
if kb_interruptSpells[id] then
call SetUnitPosition(u, x, y)
endif
if kb_disableMovement[id] then
call DisableUnitMovement(u)
endif
if effects != null then
set kb_effect[id] = effects
endif
set kb_effectAttachPoint[id] = effectAttachPoint
set kb_lastDistanceEffect[id] = kb_distance[id]
set kb_effectOccursDistance[id] = effectOccursDistance
set kb_collision[id] = KB_GetUnitCollisionSize(u, x, y)
if FirstOfGroup(kb_group)==null then
call TimerStart(kb_timer, KB_INTERVAL, true, null)
endif
call GroupAddUnit(kb_group, u)
endfunction
// KBLOOP part =============================================
function KB_BounceEvent takes unit u, integer id, integer eventType returns nothing
if kb_trg_onHit[id] != null then
set kb_callback = eventType // KB_HIT_OBSTACLE_UNIT or KB_HIT_THE_WALL
set kb_unit = u
set kb_hitCounter[id] = kb_hitCounter[id] + 1
set kb_hitCount = kb_hitCounter[id]
call TriggerExecute(kb_trg_onHit[id])
endif
endfunction
//------------------------------------------------------------------------------------------------
// use this for bounce from structures/cliffs/doodads ONLY:
//------------------------------------------------------------------------------------------------
function KB_BounceUnit takes unit u, integer id, real unitX, real unitY returns nothing
set kb_angle[id] = KB_GetBounceAngle(kb_angle[id], unitX, unitY, id) //change angle
set kb_sin[id] = Sin(kb_angle[id])
set kb_cos[id] = Cos(kb_angle[id])
call SetUnitX(u, unitX + kb_d1[id] * kb_cos[id])
call SetUnitY(u, unitY + kb_d1[id] * kb_sin[id])
set kb_d1[id] = kb_d1[id] * kb_reduceSpeedOnHit // reducing distance kb_d1
call KB_BounceEvent(u, id, KB_HIT_THE_WALL) //fire hit event
endfunction
//------------------------------------------------------------------------------------------------
//-this for better visual effect --
//-KB_BounceEvent is not included here inside this func -----------
function KB_BounceUnitReverseWithMinSpeed takes unit u, integer id returns nothing
local real angle = (kb_angle[id] + bj_PI)
if kb_angle[id]>0.00 then // reverse direction:
set angle = (kb_angle[id] - bj_PI)
endif // initiate new kb, so old one will be ended:
call KnockBack(null, u, 25.00, 0.30, angle, false, kb_killTrees[id], kb_disableMovement[id], KB_TYPE_SLIDE, KB_FILTR_BOUNCE_NONE, null, null, 1.00)
endfunction
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
function KB_TwoUnitsHit takes unit mainUnit, integer id, unit obstacleUnit, integer obstacleId returns nothing
local integer kb1 = kb_knockbackType[id]
local integer kb2
if IsUnitInGroup(obstacleUnit, kb_group) then
set kb2 = kb_knockbackType[obstacleId]
if kb2 == KB_TYPE_NO_BOUNCE then
set kb_obstacle_unit = obstacleUnit
call KB_BounceEvent(mainUnit, id, KB_HIT_OBSTACLE_UNIT)
set kb_obstacle_unit = mainUnit
call KB_BounceEvent(obstacleUnit, obstacleId, KB_HIT_OBSTACLE_UNIT)
if kb2 == kb1 then // both "no-bounce"
call KB_BounceUnitReverseWithMinSpeed(mainUnit, id)
call KB_BounceUnitReverseWithMinSpeed(obstacleUnit, obstacleId)
endif
elseif (kb2 == KB_TYPE_NORMAL or kb2 == KB_TYPE_STOP_ON_OBSTACLES) and (kb1 == KB_TYPE_NORMAL or kb1 == KB_TYPE_STOP_ON_OBSTACLES or kb1 == KB_TYPE_SLIDE) then
set kb_obstacle_unit = mainUnit
call KB_BounceEvent(obstacleUnit, obstacleId, KB_HIT_OBSTACLE_UNIT)
set kb_obstacle_unit = obstacleUnit
call KB_BounceEvent(mainUnit, id, KB_HIT_OBSTACLE_UNIT)
endif
else // obstacle unit *not* in kb_group:
set kb_obstacle_unit = obstacleUnit
call KB_BounceEvent(mainUnit, id, KB_HIT_OBSTACLE_UNIT)
if kb1 == KB_TYPE_NO_BOUNCE then
call KB_BounceUnitReverseWithMinSpeed(mainUnit, id)
endif
endif
endfunction
//-------------------------------------------------------------------------------
// kb_u primary unit, unitX = GetUnitX(kb_u)
// bouncePrimaryUnit - if "true" will bounce kb_u in opposite direction to new unit on way
// bounceNewUnit -if "true" will bounce new unit in opposite direction to kb_u unit
function KB_CheckUnitsAroundAndBounce takes unit kb_u, integer kb_id, real unitX, real unitY, real targetX, real targetY, integer filtrNr, boolean bouncePrimaryUnit, boolean bounceNewUnit returns boolean
local unit obst_u
local integer obst_id
local real obstX
local real obstY
local integer foundUnits=0
local real angle
local integer t
local integer b
local real Tx
local real Ty
local real c
local real newDistance
set kb_player = GetOwningPlayer(kb_u)
call GroupEnumUnitsInRange(kb_ug, targetX, targetY, KB_DETECT_OBSTACLE_UNIT_RADIUS, kb_filtr[filtrNr])
loop
set obst_u = FirstOfGroup(kb_ug)
exitwhen obst_u == null
set obstX = GetUnitX(obst_u)
set obstY = GetUnitY(obst_u)
set c = KB_GetUnitCollisionSize(obst_u, obstX, obstY)
if (obst_u != kb_u) and IsUnitInRange(obst_u, kb_u, RMaxBJ(c, kb_collision[kb_id])) then //pick bigger collision
set foundUnits = 1
set obst_id = GetUnitUserData(obst_u)
call KB_TwoUnitsHit(kb_u, kb_id, obst_u, obst_id)
// if bounce primary unit:
if bouncePrimaryUnit then
set angle = Atan2(unitY - obstY, unitX - obstX) // reverse angle
set Tx = unitX+kb_d1[kb_id] * Cos(angle)
set Ty = unitY+kb_d1[kb_id] * Sin(angle)
if KB_IsPointWalkableForSize(Tx, Ty, kb_collision[kb_id]) then
call SetUnitX(kb_u, Tx)
call SetUnitY(kb_u, Ty)
set kb_angle[kb_id] = angle //change angle
set kb_sin[kb_id] = Sin(kb_angle[kb_id])
set kb_cos[kb_id] = Cos(kb_angle[kb_id])
set kb_d1[kb_id] = kb_d1[kb_id] * kb_reduceSpeedOnHit // reducing distance kb_d1
else // not walkable:
set kb_d1[kb_id] = 0.00 // end knockback
endif
elseif kb_knockbackType[kb_id] == KB_TYPE_SLIDE then // if not bounce, then move [for slide type only]:
call SetUnitX(kb_u, targetX)
call SetUnitY(kb_u, targetY)
endif
// if bounce obstacle unit:
if bounceNewUnit then
set angle = Atan2(obstY - unitY, obstX - unitX) // reverse angle
if IsUnitInGroup(obst_u, kb_group) then
if kb_knockbackType[kb_id] == KB_TYPE_SLIDE then // hit by sliding unit, initiate new slide, slide overwrites existing one
if kb_timeLeft[kb_id] * kb_distanceLeft[kb_id] > 1.00 then //don't run very low knockbacks! <---
set b = kb_bounceFiltrType[kb_id] // new bounce filter:
if kb_bounceFiltrType[kb_id] == KB_FILTR_BOUNCE_ENEMY_ONLY then
set b = KB_FILTR_BOUNCE_ALLIED_ONLY
endif
set angle = KB_GetBounceAngle90(kb_angle[kb_id], obstX, obstY, unitX, unitY) //angle 90 degrees
if KB_IsPointWalkableForSize((obstX+kb_d1[obst_id] * Cos(angle)), (obstY+kb_d1[obst_id] * Sin(angle)), c) then
call KnockBack(null, obst_u, kb_distanceLeft[kb_id], kb_timeLeft[kb_id], angle, kb_interruptSpells[kb_id], kb_killTrees[kb_id], kb_disableMovement[kb_id], kb_knockbackType[kb_id], b, kb_effect[kb_id], kb_effectAttachPoint[kb_id], kb_effectOccursDistance[kb_id])
endif
endif
else // hit by non-sliding unit, update existing kb:
set Tx = obstX+kb_d1[obst_id] * Cos(angle)
set Ty = obstY+kb_d1[obst_id] * Sin(angle)
if KB_IsPointWalkableForSize(Tx, Ty, c) then
call SetUnitX(obst_u, Tx)
call SetUnitY(obst_u, Ty)
set kb_angle[obst_id] = angle //change angle
set kb_sin[obst_id] = Sin(kb_angle[obst_id])
set kb_cos[obst_id] = Cos(kb_angle[obst_id])
set kb_d1[obst_id] = kb_d1[obst_id] * kb_reduceSpeedOnHit // reducing distance kb_d1
endif
endif
elseif (kb_timeLeft[kb_id] * kb_distanceLeft[kb_id]) > 1.00 then //unit NOT in kb_group, initial new kb; don't run very low knockbacks! <---
set b = kb_bounceFiltrType[kb_id] // new bounce filter:
if b == KB_FILTR_BOUNCE_ENEMY_ONLY then
set b = KB_FILTR_BOUNCE_ALLIED_ONLY
endif
if kb_knockbackType[kb_id] == KB_TYPE_SLIDE then // if obstacle hits by sliding unit, change angle to 90
set angle = KB_GetBounceAngle90(kb_angle[kb_id], obstX, obstY, unitX, unitY) //angle 90 degrees
endif // now calculate new distance to get the same speed as kb_u
set newDistance = (kb_d1[kb_id] * ((I2R(R2I(kb_timeLeft[kb_id] / KB_INTERVAL)) + 1))) / 2.00
if KB_IsPointWalkableForSize((obstX+kb_d1[obst_id] * Cos(angle)), (obstY+kb_d1[obst_id] * Sin(angle)), c) then
call KnockBack(null, obst_u, newDistance, kb_timeLeft[kb_id], angle, kb_interruptSpells[kb_id], kb_killTrees[kb_id], kb_disableMovement[kb_id], kb_knockbackType[kb_id], b, kb_effect[kb_id], kb_effectAttachPoint[kb_id], kb_effectOccursDistance[kb_id])
endif
endif
endif
//bounce obstacle unit:end
endif
call GroupRemoveUnit(kb_ug, obst_u)
endloop
call GroupClear (kb_ug)
set obst_u=null
return foundUnits > 0
endfunction
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
function KB_MoveUnit takes unit u, integer id, real unitX, real unitY, real targetX, real targetY returns nothing
local boolean isWalkable = KB_IsPointWalkableForSize(targetX, targetY, kb_collision[id])
if kb_knockbackType[id] == KB_TYPE_NO_BOUNCE then // no bounce at all
if not isWalkable then
call KB_BounceEvent(u, id, KB_HIT_THE_WALL) //fire hit event, obstacle
call KB_BounceUnitReverseWithMinSpeed(u, id)
elseif kb_bounceFiltrType[id] == KB_FILTR_BOUNCE_NONE then // walkable:
call SetUnitX(u, targetX)
call SetUnitY(u, targetY)
elseif (not KB_CheckUnitsAroundAndBounce(u, id, unitX, unitY, targetX, targetY, kb_bounceFiltrType[id], false, false)) then //3 other filters:
call SetUnitX(u, targetX)
call SetUnitY(u, targetY)
endif
//---------------------------------SLIDE:-------------------------------------------------
elseif kb_knockbackType[id] == KB_TYPE_SLIDE then
if not isWalkable then
call KB_BounceUnit(u, id, unitX, unitY) //fires hit event
elseif kb_bounceFiltrType[id] == KB_FILTR_BOUNCE_NONE then
call SetUnitX(u, targetX)
call SetUnitY(u, targetY)
elseif (not KB_CheckUnitsAroundAndBounce(u, id, unitX, unitY, targetX, targetY, kb_bounceFiltrType[id], false, true)) then //3 other filters:
call SetUnitX(u, targetX)
call SetUnitY(u, targetY)
endif
//--------------------------------- KB_TYPE_NORMAL / KB_TYPE_STOP_ON_OBSTACLES -------------------
elseif kb_knockbackType[id] == KB_TYPE_NORMAL or kb_knockbackType[id] == KB_TYPE_STOP_ON_OBSTACLES then
if not isWalkable then
if kb_knockbackType[id] == KB_TYPE_NORMAL then
call KB_BounceUnit(u, id, unitX, unitY)
elseif kb_knockbackType[id] == KB_TYPE_STOP_ON_OBSTACLES then
call KB_BounceEvent(u, id, KB_HIT_THE_WALL) //fire hit event, obstacle
call KB_BounceUnitReverseWithMinSpeed(u, id)
endif
elseif (kb_bounceFiltrType[id] == KB_FILTR_BOUNCE_NONE) then //walkable:
if (not (KB_CheckUnitsAroundAndBounce(u, id, unitX, unitY, targetX, targetY, KB_FILTR_BOUNCE_ALL, true, false))) then
call SetUnitX(u, targetX)
call SetUnitY(u, targetY)
endif
elseif (not (KB_CheckUnitsAroundAndBounce(u, id, unitX, unitY, targetX, targetY, kb_bounceFiltrType[id], true, true))) then //3 other filters
call SetUnitX(u, targetX)
call SetUnitY(u, targetY)
endif
endif
endfunction
//-----------------------------------------------------------------
function KB_KillTree takes nothing returns nothing
call KillTree(GetEnumDestructable())
endfunction
//------------------------------------------------------------------
function KB_ShowEffect takes unit u, integer id returns nothing
if kb_effect[id] != null and (kb_distanceLeft[id] < (kb_lastDistanceEffect[id] - kb_effectOccursDistance[id])) then
call DestroyEffect(AddSpecialEffectTarget(kb_effect[id], u, kb_effectAttachPoint[id]))
set kb_lastDistanceEffect[id] = kb_distanceLeft[id]
endif
endfunction
//------------------------------------------------------------------
function KB_LoopEnum takes nothing returns nothing
local unit u = GetEnumUnit()
local integer id = GetUnitUserData(u)
local real unitX = GetUnitX(u)
local real unitY = GetUnitY(u)
local real targetX = unitX + kb_d1[id] * kb_cos[id]
local real targetY = unitY + kb_d1[id] * kb_sin[id]
if (not IsUnitAlive(u)) or kb_d1[id] <= 0.00 then
call KB_DestroyKnockbackOnUnit(u)
set u=null
return
endif
if kb_killTrees[id] and ((kb_d1[id]*KB_STEPS_PER_SEC) > kb_minSpeedToKillTree) then
call MoveRectTo(kb_rect, targetX, targetY)
call EnumDestructablesInRect(kb_rect, null, function KB_KillTree)
endif
call KB_ShowEffect(u, id)
call KB_MoveUnit(u, id, unitX, unitY, targetX, targetY)
set kb_d1[id] = kb_d1[id] - kb_d2[id] // decrease speed
set kb_distanceLeft[id] = kb_distanceLeft[id] - kb_d1[id] // for additional kb-ed units
set kb_timeLeft[id] = kb_timeLeft[id] - KB_INTERVAL // for additional kb-ed units
set u=null
endfunction
//--------------------------------------------------------------------------
function KB_Loop takes nothing returns boolean
call ForGroup(kb_group, function KB_LoopEnum)
return false
endfunction
//=======================================================
//=======================================================
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
set kb_ug = CreateGroup()
set kb_group = CreateGroup()
set kb_timer = CreateTimer()
set kb_rect = Rect(0.0, 0.0, 256.0, 256.0)
set kb_trg_loop = CreateTrigger()
call TriggerRegisterTimerExpireEvent(kb_trg_loop, kb_timer) //timer kb_timer expires
call TriggerAddCondition(kb_trg_loop, Condition(function KB_Loop))
//----------------------------------------------------
call KB_AdvancedUserConfigurables()
set kb_minSpeedToKillTree = RMaxBJ(kb_minSpeedToKillTree, 0.00)
if kb_reduceSpeedOnHitFactor < 0.00 then
set kb_reduceSpeedOnHitFactor = 0.00
elseif kb_reduceSpeedOnHitFactor > 100.00 then
set kb_reduceSpeedOnHitFactor = 100.00
endif
set kb_reduceSpeedOnHit = 1.00 - (kb_reduceSpeedOnHitFactor / 100.00) // for kb_d1, range: 0.00 ... 1.00
//----------------------------------------------------
set kb_filtr[KB_FILTR_BOUNCE_NONE] = Condition(function KBFiltr_groundNotStruc)
set kb_filtr[KB_FILTR_BOUNCE_ALL] = Condition(function KBFiltr_groundNotStruc)
set kb_filtr[KB_FILTR_BOUNCE_ALLIED_ONLY] = Condition(function KBFiltr_groundNotStrucAlliedOnly)
set kb_filtr[KB_FILTR_BOUNCE_ENEMY_ONLY] = Condition(function KBFiltr_groundNotStrucEnemyOnly)
call TriggerRegisterVariableEvent( t, "udg_UnitIndexEvent", EQUAL, 2.00 ) // remove unit detection
call TriggerAddAction(t, function KB_OnRemoveFromGame)
set t=null
endfunction
endlibrary
library Timed initializer Init
globals
private hashtable h = null
constant integer KEY_TIMED_EFFECT_XY = 1
constant integer KEY_TIMED_EFFECT_UNIT = 2
constant integer KEY_TIMED_EFFECT_EFFECT = 3
constant integer KEY_TIMED_EFFECT_DURATION = 4
constant integer KEY_TIMED_ABILITY_UNIT = 5
constant integer KEY_TIMED_ABILITY_ID = 6
constant integer KEY_TIMED_ABILITY_DURATION = 7
endglobals
//=======================================================
//=========== TIMED EFFECT ==============================
//=======================================================
function AddTimedEffectTarget_Child takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer h_id=GetHandleId(t)
local unit u = LoadUnitHandle(h, h_id, KEY_TIMED_EFFECT_UNIT)
local real durationLeft=LoadReal(h, h_id, KEY_TIMED_EFFECT_DURATION) - 1.00
call SaveReal(h, h_id, KEY_TIMED_EFFECT_DURATION, durationLeft)
if durationLeft<=0.00 or not UnitAlive(u) then
set bj_lastCreatedEffect=LoadEffectHandle(h, h_id, KEY_TIMED_EFFECT_EFFECT)
call DestroyEffect(bj_lastCreatedEffect)
//---
call FlushChildHashtable(h, h_id)
call PauseTimer(t)
call DestroyTimer(t)
endif
set t = null
set u=null
endfunction
function AddTimedEffectTarget takes unit u, real duration, string attPoint, string eff returns nothing
local timer t=CreateTimer()
set bj_lastCreatedEffect=AddSpecialEffectTarget(eff, u, attPoint)
call SaveUnitHandle(h, GetHandleId(t), KEY_TIMED_EFFECT_UNIT, u)
call SaveEffectHandle(h, GetHandleId(t), KEY_TIMED_EFFECT_EFFECT, bj_lastCreatedEffect)
call SaveReal(h, GetHandleId(t), KEY_TIMED_EFFECT_DURATION, duration)
call TimerStart(t, 1.00, true, function AddTimedEffectTarget_Child)
set t=null
endfunction
//-------------------------------------------------------------------------------------------------
function AddTimedEffect_Child takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer h_id=GetHandleId(t)
set bj_lastCreatedEffect=LoadEffectHandle(h, h_id, KEY_TIMED_EFFECT_XY)
call DestroyEffect(bj_lastCreatedEffect)
call FlushChildHashtable(h, h_id)
call DestroyTimer(t)
set t = null
endfunction
function AddTimedEffect takes real x, real y, real duration, string eff returns nothing
local timer t=CreateTimer()
set bj_lastCreatedEffect=AddSpecialEffect(eff, x, y)
call SaveEffectHandle(h, GetHandleId(t), KEY_TIMED_EFFECT_XY, bj_lastCreatedEffect)
call TimerStart(t, duration, false, function AddTimedEffect_Child)
set t=null
endfunction
//=======================================================
//=========== TIMED ABILITY =============================
//=======================================================
function AddTimedAbility_Child takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer h_id=GetHandleId(t)
local unit u = LoadUnitHandle(h, h_id, KEY_TIMED_ABILITY_UNIT)
local integer abiId = LoadInteger(h, h_id, KEY_TIMED_ABILITY_ID)
local real durationLeft = LoadReal(h, h_id, KEY_TIMED_ABILITY_DURATION) - 1.00
call SaveReal(h, h_id, KEY_TIMED_ABILITY_DURATION, durationLeft)
if durationLeft<=0.00 or not UnitAlive(u) then
call UnitRemoveAbility(u, abiId)
//---
call FlushChildHashtable(h, h_id)
call PauseTimer(t)
call DestroyTimer(t)
endif
set t = null
set u=null
endfunction
function AddTimedAbility takes unit u, integer abiId, real duration returns nothing
local timer t=CreateTimer()
local integer h_id = GetHandleId(t)
call SaveUnitHandle(h, h_id, KEY_TIMED_ABILITY_UNIT, u)
call SaveInteger(h, h_id, KEY_TIMED_ABILITY_ID, abiId)
call SaveReal(h, h_id, KEY_TIMED_ABILITY_DURATION, duration)
call UnitAddAbility(u, abiId)
call TimerStart(t, 1.00, true, function AddTimedAbility_Child)
set t=null
endfunction
private function Init takes nothing returns nothing
set h = InitHashtable()
endfunction
endlibrary
function Trig_CheckOrder_Actions takes nothing returns nothing
local integer h = GetHandleId(GetTriggerEventId())
local integer ord = GetIssuedOrderId()
//if GetOrderedUnit()==BARRACK then
if h==38 then
call DisplayTextToPlayer(GetLocalPlayer(), 0.00, 0.00, "instant " + I2S(ord) + ", " + OrderId2StringBJ(ord))
elseif h==39 then
call DisplayTextToPlayer(GetLocalPlayer(), 0.00, 0.00, "point " + I2S(ord) + ", " + OrderId2StringBJ(ord))
elseif h==40 then
call DisplayTextToPlayer(GetLocalPlayer(), 0.00, 0.00, "target " + 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
//=======================================================================================================
// Recipe System
// By Fredbrik(Diablo-dk)
//
//=======================================================================================================
//globals
//integer RN=0 // Recipe number.
//trigger RT=CreateTrigger() // Main recipe trigger.
//boolean RC=true
//integer array itemid1
//integer array itemid2
//integer array itemid3
//integer array itemid4
//integer array itemid5
//integer array itemid6
//integer array ic //item count
//integer array output
//endglobals
//=======================================================================================================
// User changeable constants
//=======================================================================================================
constant function Recipe_Effect takes nothing returns string
return "Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl" //An effect that comes whenever a recipe is made.
endfunction
constant function Recipe_AP takes nothing returns string
return "origin" //Attachment point for Recipe_Effect()
endfunction
//=======================================================================================================
// This function will return the first item of entered Id in the unit's inventory.
function GetItem takes unit u, integer Id returns item
local integer i=0
local item it
loop
exitwhen i==6
if GetItemTypeId(UnitItemInSlot(u,i)) == Id then
return UnitItemInSlot(u,i)
set i=5
endif
set i=i+1
endloop
return null
endfunction
//==============================
function HasItems takes unit u, integer i returns boolean
local integer index=0
local integer id=-1
local integer b1=0
local integer b2=0
local integer b3=0
local integer b4=0
local integer b5=0
local integer b6=0
loop
exitwhen index==6
set id=GetItemTypeId(UnitItemInSlot(u,index))
if id == 0 then
set id=-1
endif
if id == udg_itemid1[i] and b1 == 0 then
set b1=1
set id=-1
endif
if id == udg_itemid2[i] and b2 == 0 then
set b2=1
set id=-1
endif
if id == udg_itemid3[i] and b3 == 0 then
set b3=1
set id=-1
endif
if id == udg_itemid4[i] and b4 == 0 then
set b4=1
set id=-1
endif
if id == udg_itemid5[i] and b5 == 0 then
set b5=1
set id=-1
endif
if id == udg_itemid6[i] and b6 == 0 then
set b6=1
set id=-1
endif
if b1+b2+b3+b4+b5+b6 == udg_ic[i] then
return true
endif
set index=index+1
endloop
return false
endfunction
//=======================================================================================================
// User Functions:
// Recipe Creating:
//
//=======================================================================================================
function CreateRecipe takes integer i1,integer i2,integer i3,integer i4,integer i5,integer i6,integer output returns nothing
set udg_RN=udg_RN+1
set udg_itemid1[udg_RN]=i1
set udg_itemid2[udg_RN]=i2
set udg_ic[udg_RN]=2
if i3 != 0 then
set udg_itemid3[udg_RN]=i3
set udg_ic[udg_RN]=udg_ic[udg_RN]+1
endif
if i4 != 0 then
set udg_itemid4[udg_RN]=i4
set udg_ic[udg_RN]=udg_ic[udg_RN]+1
endif
if i5 != 0 then
set udg_itemid5[udg_RN]=i5
set udg_ic[udg_RN]=udg_ic[udg_RN]+1
endif
if i6 != 0 then
set udg_itemid6[udg_RN]=i6
set udg_ic[udg_RN]=udg_ic[udg_RN]+1
endif
set udg_output[udg_RN]=output
endfunction
function CreateRecipe2 takes integer i1,integer i2,integer i3 returns nothing
set udg_RN=udg_RN+1
set udg_itemid1[udg_RN]=i1
set udg_itemid2[udg_RN]=i2
set udg_output[udg_RN]=i3
set udg_ic[udg_RN]=2
endfunction
// Creates a recipe that requires 2 items to combine into a new item. i3 is the combined item.
// Example: call CreateRecipe2('I000','I001','I002')
function CreateRecipe3 takes integer i1,integer i2,integer i3,integer i4 returns nothing
set udg_RN=udg_RN+1
set udg_itemid1[udg_RN]=i1
set udg_itemid2[udg_RN]=i2
set udg_itemid3[udg_RN]=i3
set udg_output[udg_RN]=i4
set udg_ic[udg_RN]=3
endfunction
// The same as CreateRecipe2 except this requires 3 items to combine. i4 is the combined item.
function CreateRecipe4 takes integer i1,integer i2,integer i3,integer i4,integer i5 returns nothing
set udg_RN=udg_RN+1
set udg_itemid1[udg_RN]=i1
set udg_itemid2[udg_RN]=i2
set udg_itemid3[udg_RN]=i3
set udg_itemid4[udg_RN]=i4
set udg_output[udg_RN]=i5
set udg_ic[udg_RN]=4
endfunction
// The same as CreateRecipe2 except this requires 4 items to combine. i5 is the combined item.
function CreateRecipe5 takes integer i1,integer i2,integer i3,integer i4,integer i5,integer i6 returns nothing
set udg_RN=udg_RN+1
set udg_itemid1[udg_RN]=i1
set udg_itemid2[udg_RN]=i2
set udg_itemid3[udg_RN]=i3
set udg_itemid4[udg_RN]=i4
set udg_itemid5[udg_RN]=i5
set udg_output[udg_RN]=i6
set udg_ic[udg_RN]=5
endfunction
// The same as CreateRecipe2 except this requires 5 items to combine. i6 is the combined item.
function CreateRecipe6 takes integer i1,integer i2,integer i3,integer i4,integer i5,integer i6,integer i7 returns nothing
set udg_RN=udg_RN+1
set udg_itemid1[udg_RN]=i1
set udg_itemid2[udg_RN]=i2
set udg_itemid3[udg_RN]=i3
set udg_itemid4[udg_RN]=i4
set udg_itemid5[udg_RN]=i5
set udg_itemid6[udg_RN]=i6
set udg_output[udg_RN]=i7
set udg_ic[udg_RN]=6
endfunction
// The same as CreateRecipe2 except this requires 6 items to combine. i7 is the combined item.
//===================================================================================================
// This function disassembles a recipe item to its original components.
function DisItem takes unit u,item it returns boolean
local integer c=GetItemUserData(it)
local item array newitem
local integer i=udg_ic[c]
if it != null then
if i <= 6-UnitInventoryCount(u)+1 and i > 0 then
set udg_RC=false
if udg_itemid2[c] != null then
set newitem[1]=CreateItem(udg_itemid1[c],GetUnitX(u),GetUnitY(u))
set newitem[2]=CreateItem(udg_itemid2[c],GetUnitX(u),GetUnitY(u))
endif
if udg_itemid3[c] != null then
set newitem[3]=CreateItem(udg_itemid3[c],GetUnitX(u),GetUnitY(u))
call UnitAddItem(u,newitem[3])
endif
if udg_itemid4[c] != null then
set newitem[4]=CreateItem(udg_itemid4[c],GetUnitX(u),GetUnitY(u))
call UnitAddItem(u,newitem[4])
endif
if udg_itemid5[c] != null then
set newitem[5]=CreateItem(udg_itemid5[c],GetUnitX(u),GetUnitY(u))
call UnitAddItem(u,newitem[5])
endif
if udg_itemid6[c] != null then
set newitem[6]=CreateItem(udg_itemid6[c],GetUnitX(u),GetUnitY(u))
call UnitAddItem(u,newitem[6])
endif
call RemoveItem(it)
call UnitAddItem(u,newitem[1])
call UnitAddItem(u,newitem[2])
set newitem[1]=null
set newitem[2]=null
set newitem[3]=null
set newitem[4]=null
set newitem[5]=null
set newitem[6]=null
set udg_RC=true
else
return false
endif
endif
return true
endfunction
//=======================================================================================================
//
//Main Recipe Function: Do not change unless you know what you are doing
//
//=======================================================================================================
function Recipe_Main takes nothing returns nothing
local item it
local integer i=0
local unit u=GetManipulatingUnit()
loop
exitwhen i==udg_RN
set i=i+1
if udg_RC == true then
if udg_ic[i] == 6 then
if HasItems(u,i) then
call RemoveItem(GetItem(u,udg_itemid1[i]))
call RemoveItem(GetItem(u,udg_itemid2[i]))
call RemoveItem(GetItem(u,udg_itemid3[i]))
call RemoveItem(GetItem(u,udg_itemid4[i]))
call RemoveItem(GetItem(u,udg_itemid5[i]))
call RemoveItem(GetItem(u,udg_itemid6[i]))
call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
call SetItemUserData(it,i) //Used for disassembling.
call UnitAddItem(u,it)
set i=udg_RN
endif
elseif udg_ic[i] == 5 then
if HasItems(u,i) then
call RemoveItem(GetItem(u,udg_itemid1[i]))
call RemoveItem(GetItem(u,udg_itemid2[i]))
call RemoveItem(GetItem(u,udg_itemid3[i]))
call RemoveItem(GetItem(u,udg_itemid4[i]))
call RemoveItem(GetItem(u,udg_itemid5[i]))
call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
call SetItemUserData(it,i) //Used for disassembling.
call UnitAddItem(u,it)
set i=udg_RN
endif
elseif udg_ic[i] == 4 then
if HasItems(u,i) then
call RemoveItem(GetItem(u,udg_itemid1[i]))
call RemoveItem(GetItem(u,udg_itemid2[i]))
call RemoveItem(GetItem(u,udg_itemid3[i]))
call RemoveItem(GetItem(u,udg_itemid4[i]))
call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
call SetItemUserData(it,i) //Used for disassembling.
call UnitAddItem(u,it)
set i=udg_RN
endif
elseif udg_ic[i] == 3 then
if HasItems(u,i) then
call RemoveItem(GetItem(u,udg_itemid1[i]))
call RemoveItem(GetItem(u,udg_itemid2[i]))
call RemoveItem(GetItem(u,udg_itemid3[i]))
call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
call SetItemUserData(it,i) //Used for disassembling.
call UnitAddItem(u,it)
set i=udg_RN
endif
elseif udg_ic[i] == 2 then
if HasItems(u,i) then
call RemoveItem(GetItem(u,udg_itemid1[i]))
call RemoveItem(GetItem(u,udg_itemid2[i]))
call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
call SetItemUserData(it,i) //Used for disassembling.
call UnitAddItem(u,it)
set i=udg_RN
endif
endif
endif
endloop
set it=null
set u=null
endfunction
function InitRecipe takes nothing returns nothing
set udg_RT=CreateTrigger()
set udg_RC=true
call TriggerRegisterAnyUnitEventBJ( udg_RT, EVENT_PLAYER_UNIT_PICKUP_ITEM )
call TriggerAddAction(udg_RT,function Recipe_Main)
endfunction
//call this at map init.
//forced by WE
function InitTrig_Recipe takes nothing returns nothing
endfunction
// End Recipe
globals
constant integer DUMMY = 'n009'
boolexpr g_filtr_alive
//spells variables
unit array spellCaster
unit array spellTargetUnit
unit array spellMissle
real array spellDamage
real array spellDamage2
real array spellRadius
real array spellDuration
real array spellReal
real array spellAngle
real array spellDistance
integer array spellCounter
integer array spellLevel
integer array spellInteger
integer array spellUnitType
effect array spellEffect
effect array spellEffect2
boolean array spellBool
group array spellGroup
timer array spellTimer
group array spellGroupVictims
group array spellGroupToAdd
endglobals
function Fun_Alive takes nothing returns boolean
return UnitAlive(GetFilterUnit()) and (not BlzIsUnitInvulnerable(GetFilterUnit())) and (GetUnitAbilityLevel(GetFilterUnit(), 'Aloc')==0)
endfunction
function Trig_Vars_Actions takes nothing returns nothing
local integer i=1
set g_filtr_alive = Condition(function Fun_Alive)
//create groups/timers for spells:
set i=1
loop
exitwhen i>10 // max number of spell types
set spellGroup[i] = CreateGroup()
set spellTimer[i] = CreateTimer()
set i=i+1
endloop
endfunction
//===========================================================================
function InitTrig_Vars takes nothing returns nothing
set gg_trg_Vars = CreateTrigger( )
call TriggerAddAction( gg_trg_Vars, function Trig_Vars_Actions )
endfunction
function Trig_RemindStone_Actions takes nothing returns nothing
local unit lizard1=gg_unit_n00D_0063
local unit lizard2=gg_unit_n00D_0129
local real x1=GetUnitX(lizard1)
local real y1=GetUnitY(lizard1)
local real x2=GetUnitX(lizard2)
local real y2=GetUnitY(lizard2)
//remind about Stone !
loop
exitwhen stoneCreated
if UnitAlive(lizard1) then
call PingMinimap(x1, y1, 8.00)
endif
if UnitAlive(lizard2) then
call PingMinimap(x2, y2, 8.00)
endif
call TriggerSleepAction(20.00)
endloop
set lizard1=null
set lizard2=null
endfunction
//===========================================================================
function InitTrig_RemindStone takes nothing returns nothing
set gg_trg_RemindStone = CreateTrigger( )
call TriggerAddAction( gg_trg_RemindStone, function Trig_RemindStone_Actions )
endfunction
function Trig_DuchyBalance_Actions takes nothing returns nothing
local boolean isMuradin = (GetOwningPlayer(gg_unit_H00I_0186) == Player(0))
local boolean isTyrande = (GetOwningPlayer(gg_unit_Etyr_0225) == Player(0))
if (not isMuradin) and (not isTyrande) then
//kill most
// veteran knight group:
call KillUnit(gg_unit_n00S_0222)//mage,
call KillUnit(gg_unit_n00S_0223)
//boss group:
call KillUnit(gg_unit_n00T_0198) // veteran knight
call KillUnit(gg_unit_n00T_0199)
call KillUnit(gg_unit_n00S_0194) // mage
call KillUnit(gg_unit_n00S_0195)
call KillUnit(gg_unit_n00U_0003) // spearman
call KillUnit(gg_unit_n00U_0185)
call KillUnit(gg_unit_n00U_0187)
elseif (not isMuradin) or (not isTyrande) then
//kill few
// veteran knight group:
call KillUnit(gg_unit_n00S_0222)//mage
//boss group:
call KillUnit(gg_unit_n00T_0198) // veteran knight
call KillUnit(gg_unit_n00S_0194) // mage
call KillUnit(gg_unit_n00U_0003) // spearman
call KillUnit(gg_unit_n00U_0185)
endif
//set hero levels in boss group
if isMuradin and isTyrande then //level 10
call SetHeroLevel(gg_unit_E003_0218, 10, false)
call SetHeroLevel(gg_unit_E002_0220, 10, false)
call SetHeroLevel(gg_unit_H00K_0219, 10, false)
call SetHeroLevel(gg_unit_H00E_0221, 10, false)
elseif isMuradin or isTyrande then //level 8
call SetHeroLevel(gg_unit_E003_0218, 8, false)
call SetHeroLevel(gg_unit_E002_0220, 8, false)
call SetHeroLevel(gg_unit_H00K_0219, 8, false)
call SetHeroLevel(gg_unit_H00E_0221, 8, false)
endif
endfunction
//===========================================================================
function InitTrig_DuchyBalance takes nothing returns nothing
set gg_trg_DuchyBalance = CreateTrigger( )
call TriggerAddAction( gg_trg_DuchyBalance, function Trig_DuchyBalance_Actions )
endfunction
globals
boolean stoneCreated=false
constant integer ITEM_RESURRECTION_STONE = 'I00A'
constant integer ITEM_STONE_PART = 'I00B'
constant integer DUMMY_REVIVE_EFFECT = 'h00F'
endglobals
function Trig_ResurrectionStone_Cond takes nothing returns boolean
return GetItemTypeId(GetManipulatedItem()) == ITEM_RESURRECTION_STONE
endfunction
//--Resurrection Stone pick up:
function Trig_ResurrectionStone_Pick takes nothing returns nothing
if not stoneCreated then
set stoneCreated=true
set udg_ResurrectionStoneItem = GetManipulatedItem()
call SetItemInvulnerableBJ( udg_ResurrectionStoneItem, true )
call QuestItemSetCompletedBJ( udg_questReq[2], true )
call QuestMessageBJ( GetPlayersAll(), bj_QUESTMESSAGE_UPDATED, "|cffffff00Quest Update|r: Find Resurrection Stone parts|cff808080. (completed)|r" )
endif
call SetUnitOwner(udg_dummyResurrection, Player(PLAYER_NEUTRAL_PASSIVE), true)
endfunction
//--Resurrection Stone dropped:
function Trig_ResurrectionStone_Drop takes nothing returns nothing
call SetUnitOwner(udg_dummyResurrection, Player(0), true)
call SetUnitX(udg_dummyResurrection, GetUnitX(GetManipulatingUnit()))
call SetUnitY(udg_dummyResurrection, GetUnitY(GetManipulatingUnit()))
endfunction
function ResurrectionStone_OnTheGround takes nothing returns boolean
return (udg_ResurrectionStoneItem != null) and (not CheckItemStatus(udg_ResurrectionStoneItem, bj_ITEM_STATUS_OWNED))
endfunction
function Trig_ReviveHero takes nothing returns nothing
local unit u=GetTriggerUnit()
local real x = 0.00
local real y = 0.00
if ResurrectionStone_OnTheGround() then
set x=GetItemX(udg_ResurrectionStoneItem)
set y=GetItemY(udg_ResurrectionStoneItem)
set bj_lastCreatedUnit = CreateUnit(Player(0), DUMMY_REVIVE_EFFECT, x, y, 25.00)
call UnitApplyTimedLife(bj_lastCreatedUnit, 'BTLF', 6.00)
call TriggerSleepAction( 7.00 )
if ResurrectionStone_OnTheGround() then
set x=GetItemX(udg_ResurrectionStoneItem)
set y=GetItemY(udg_ResurrectionStoneItem)
call ReviveHero(u, x, y, true)
call SetUnitManaBJ(u, 100.00)
endif
elseif u == udg_hero then
call TriggerSleepAction( 3.00 )
call DisplayTextToForce( GetPlayersAll(), "Resurrection Stone was not found on the ground!" )
call TriggerExecute( gg_trg_GameDefeat )
endif
set u=null
endfunction
//=======RUN ON MAP INIT=======================================================
function ResurrectionStone_Init takes nothing returns nothing
local trigger t=CreateTrigger()
set udg_ResurrectionStoneItem = null
set udg_dummyResurrection = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'h007', -3000.00, -7000.00, 0.00)
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_PICKUP_ITEM)
call TriggerAddCondition(t, Condition( function Trig_ResurrectionStone_Cond))
call TriggerAddAction(t, function Trig_ResurrectionStone_Pick)
set t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DROP_ITEM)
call TriggerAddCondition(t, Condition( function Trig_ResurrectionStone_Cond))
call TriggerAddAction(t, function Trig_ResurrectionStone_Drop)
//hero resurrection:
set t = CreateTrigger()
//register all heroes here :
call TriggerRegisterUnitEvent(t, gg_unit_H00B_0111, EVENT_UNIT_DEATH)//Arius
call TriggerRegisterUnitEvent(t, gg_unit_H00I_0186, EVENT_UNIT_DEATH)//Muradin
call TriggerRegisterUnitEvent(t, gg_unit_Etyr_0225, EVENT_UNIT_DEATH)//Tyrande
call TriggerAddAction(t, function Trig_ReviveHero)
endfunction
function InitTrig_StoneF takes nothing returns nothing
endfunction
globals
constant integer ABI_ANGELS_HELP='A00H'
endglobals
function Trig_Paladin_AngelicSupport_Conditions takes nothing returns boolean
return GetSpellAbilityId() == ABI_ANGELS_HELP
endfunction
function Trig_Paladin_AngelicSupport_LoopEnum takes nothing returns nothing
local unit d = GetEnumUnit()
local integer id = GetUnitUserData(d)
local real x=0.00
local real y=0.00
local unit u=null
local player pla=null
local real angle=0.00
if spellCounter[id]<19 and (not UnitChanneling(spellCaster[id])) then
set spellDuration[id]=0.00
elseif spellCounter[id]>=19 then
set spellDuration[id]=0.00
//call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\HolyStomp.mdl", spellCaster[id], "origin"))
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\LightNova.mdl", spellCaster[id], "origin"))
set pla=GetOwningPlayer(spellCaster[id])
set x=GetUnitX(spellCaster[id])
set y=GetUnitY(spellCaster[id])
call GroupEnumUnitsInRange(ug, x, y, 350.00, g_filtr_alive)
loop
set u = FirstOfGroup(ug)
exitwhen (u == null)
if IsUnitEnemy(u, pla) then//magic dmg
call UnitDamageTarget(spellCaster[id], u, spellDamage[id], true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
set angle=Atan2(GetUnitY(u) - y, GetUnitX(u) - x)
call KnockBack(null, u, 500.00, 1.00, angle, false, false, true, KB_TYPE_NORMAL, KB_FILTR_BOUNCE_ALLIED_ONLY, null, null, 1.00)
endif
//---
call GroupRemoveUnit(ug, u)
endloop
call GroupClear(ug)
set u=null
endif
//---
set spellCounter[id] = spellCounter[id] + 1
set spellDuration[id] = spellDuration[id] - 0.10
if spellDuration[id] <= 0.00 then // Clean up any data attached to this spell
set spellCaster[id] = null
//---
call GroupRemoveUnit(spellGroup[1], d)
call RemoveUnit(d)
if FirstOfGroup(spellGroup[1]) == null then
call PauseTimer(spellTimer[1])
endif
endif
set d=null
endfunction
//--------------------------------------------------------------------------------------
function Trig_Paladin_AngelicSupport_Loop takes nothing returns nothing
call ForGroup(spellGroup[1], function Trig_Paladin_AngelicSupport_LoopEnum)
endfunction
//--------------------------------------------------------------------------------------
function Trig_Paladin_AngelicSupport_Actions takes nothing returns nothing
local unit u=GetTriggerUnit()
local unit dummy=CreateUnit(GetOwningPlayer(u), DUMMY, GetUnitX(u), GetUnitY(u), 0.00)
local integer id=GetUnitUserData(dummy)
set spellCaster[id]=u
set spellDuration[id] = 4.00
set spellCounter[id] = 0
set spellDamage[id] = 250.00
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\Resurrect\\ResurrectCaster.mdl", u, "origin"))
if FirstOfGroup(spellGroup[1]) == null then
call TimerStart(spellTimer[1], 0.10, true, function Trig_Paladin_AngelicSupport_Loop)
endif
call GroupAddUnit(spellGroup[1], dummy)
set u=null
set dummy=null
endfunction
//===========================================================================
function InitTrig_AngelsHelp takes nothing returns nothing
set gg_trg_AngelsHelp = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_AngelsHelp, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_AngelsHelp, Condition( function Trig_Paladin_AngelicSupport_Conditions ) )
call TriggerAddAction( gg_trg_AngelsHelp, function Trig_Paladin_AngelicSupport_Actions )
endfunction
globals
constant integer ABI_BATTLE_HUNGER='A00M'
constant integer BUFF_BATTLE_HUNGER = 'B003'
constant integer ABI_ARIUS_CRITICAL_STRIKE = 'A00L'
constant integer ABI_ARIUS_CLEAVING_ATTACK = 'A00K'
endglobals
function Trig_BattleHunger_Conditions takes nothing returns boolean
return GetSpellAbilityId() == ABI_BATTLE_HUNGER
endfunction
function Trig_BattleHunger_LoopEnum takes nothing returns nothing
local unit d = GetEnumUnit()
local integer id = GetUnitUserData(d)
if (not UnitAlive(spellCaster[id])) or GetUnitAbilityLevel(spellCaster[id], BUFF_BATTLE_HUNGER)==0 then
set spellDuration[id]=0.00
endif
//---
set spellDuration[id] = spellDuration[id] - 0.50
if spellDuration[id] <= 0.00 then // Clean up any data attached to this spell
call UnitRemoveAbility(spellCaster[id], ABI_ARIUS_CRITICAL_STRIKE)
call UnitRemoveAbility(spellCaster[id], ABI_ARIUS_CLEAVING_ATTACK)
set spellCaster[id] = null
//---
call GroupRemoveUnit(spellGroup[2], d)
call RemoveUnit(d)
if FirstOfGroup(spellGroup[2]) == null then
call PauseTimer(spellTimer[2])
endif
endif
set d=null
endfunction
//--------------------------------------------------------------------------------------
function Trig_BattleHunger_Loop takes nothing returns nothing
call ForGroup(spellGroup[2], function Trig_BattleHunger_LoopEnum)
endfunction
//--------------------------------------------------------------------------------------
function Trig_BattleHunger_Actions takes nothing returns nothing
local unit u=GetTriggerUnit()
local unit dummy=CreateUnit(GetOwningPlayer(u), DUMMY, GetUnitX(u), GetUnitY(u), 0.00)
local integer id=GetUnitUserData(dummy)
local integer lvl = GetUnitAbilityLevel(u, ABI_BATTLE_HUNGER)
set spellCaster[id]=u
set spellDuration[id] = 14.00 + I2R(lvl)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl", u, "origin"))
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\Holy Nova.mdl", u, "origin"))
call UnitAddAbility(spellCaster[id], ABI_ARIUS_CRITICAL_STRIKE)
call SetUnitAbilityLevel(spellCaster[id], ABI_ARIUS_CRITICAL_STRIKE, lvl)
call UnitAddAbility(spellCaster[id], ABI_ARIUS_CLEAVING_ATTACK)
call SetUnitAbilityLevel(spellCaster[id], ABI_ARIUS_CLEAVING_ATTACK, lvl)
if FirstOfGroup(spellGroup[2]) == null then
call TimerStart(spellTimer[2], 0.50, true, function Trig_BattleHunger_Loop)
endif
call GroupAddUnit(spellGroup[2], dummy)
set u=null
set dummy=null
endfunction
//===========================================================================
function InitTrig_BattleHunger takes nothing returns nothing
set gg_trg_BattleHunger = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_BattleHunger, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_BattleHunger, Condition( function Trig_BattleHunger_Conditions ) )
call TriggerAddAction( gg_trg_BattleHunger, function Trig_BattleHunger_Actions )
endfunction
globals
constant integer ABI_LIGHTNING_UNIT2UNIT = 'A00N'
constant integer ABI_HOLY_PUNISHMENT='A00O'
constant integer ABI_LIGHT_UNIT2UNIT = 'A00N'
constant integer ABI_PUNISHMENT_INDICATOR = 'A00P'
constant integer BUFF_PUNISHMENT_INDICATOR = 'B004'
endglobals
function Trig_HolyPunishment_Conditions takes nothing returns boolean
return GetSpellAbilityId() == ABI_LIGHTNING_UNIT2UNIT
endfunction
function HolyPunishment_LoopCond takes integer id, player pla returns boolean
if UnitAlive(spellCaster[id]) and UnitAlive(spellTargetUnit[id]) then
if IsUnitVisible(spellTargetUnit[id], pla) and IsUnitInRange(spellTargetUnit[id], spellCaster[id], 1000.00) then
return true //visible, not to far, both alive
endif
endif
return false
endfunction
function Trig_HolyPunishment_LoopEnum takes nothing returns nothing
local unit d = GetEnumUnit()
local integer id = GetUnitUserData(d)
local real x=0.00
local real y=0.00
local unit u=null
local player pla=GetOwningPlayer(spellCaster[id])
if HolyPunishment_LoopCond(id, pla) then
if spellCounter[id]==1 then
//call IssueTargetOrder(spellCaster[id], "fingerofdeath", spellTargetUnit[id])
elseif spellCounter[id]==50 then
set spellDuration[id] = 0.00 // end the spell
if GetUnitAbilityLevel(spellTargetUnit[id], BUFF_HOLY_BOLT_ENEMY)>0 then //aoe dmg
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\HolyStomp.mdl", spellTargetUnit[id], "origin"))
call GroupEnumUnitsInRange(ug, GetUnitX(spellTargetUnit[id]), GetUnitY(spellTargetUnit[id]), 300.00, g_filtr_alive)
loop
set u = FirstOfGroup(ug)
exitwhen (u == null)
if IsUnitEnemy(u, pla) then//magic dmg
call UnitDamageTarget(spellCaster[id], u, spellDamage[id], true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
endif
//---
call GroupRemoveUnit(ug, u)
endloop
call GroupClear(ug)
set u=null
else//individual dmg only:
call AddTimedEffectTarget(spellTargetUnit[id], 3.00, "origin", "Doodads\\Cinematic\\Lightningbolt\\Lightningbolt.mdl")
call UnitDamageTarget(spellCaster[id], spellTargetUnit[id], spellDamage[id], true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
endif
endif
else //interrupt
set spellDuration[id] = 0.00
endif
//---
set spellCounter[id] = spellCounter[id] + 1
set spellDuration[id] = spellDuration[id] - 0.10
if spellDuration[id] <= 0.00 then // Clean up any data attached to this spell
call UnitRemoveAbility(spellCaster[id], ABI_LIGHT_UNIT2UNIT)
call UnitAddAbility(spellCaster[id], ABI_LIGHT_UNIT2UNIT)
call UnitRemoveAbility(spellTargetUnit[id], ABI_PUNISHMENT_INDICATOR)
set spellCaster[id] = null
set spellTargetUnit[id] = null
//---
call GroupRemoveUnit(spellGroup[3], d)
call RemoveUnit(d)
if FirstOfGroup(spellGroup[3]) == null then
call PauseTimer(spellTimer[3])
endif
endif
set d=null
endfunction
//--------------------------------------------------------------------------------------
function Trig_HolyPunishment_Loop takes nothing returns nothing
call ForGroup(spellGroup[3], function Trig_HolyPunishment_LoopEnum)
endfunction
//--------------------------------------------------------------------------------------
function Trig_HolyPunishment_Actions takes nothing returns nothing
local unit u=GetTriggerUnit()
local unit dummy=CreateUnit(GetOwningPlayer(u), DUMMY, GetUnitX(u), GetUnitY(u), 0.00)
local integer id=GetUnitUserData(dummy)
local integer lvl=GetUnitAbilityLevel(u, ABI_HOLY_PUNISHMENT)
set spellCaster[id]=u
set spellTargetUnit[id]=GetSpellTargetUnit()
set spellDuration[id] = 6.00
set spellCounter[id] = 0
set spellDamage[id] = 100.00 + (50.00*I2R(lvl))
call UnitAddAbility(spellTargetUnit[id], ABI_PUNISHMENT_INDICATOR)
if FirstOfGroup(spellGroup[3]) == null then
call TimerStart(spellTimer[3], 0.10, true, function Trig_HolyPunishment_Loop)
endif
call GroupAddUnit(spellGroup[3], dummy)
set u=null
set dummy=null
endfunction
//============================================================
//ORDER
function Trig_HolyPunishment takes nothing returns nothing
if GetSpellAbilityId() == ABI_HOLY_PUNISHMENT then
if GetUnitAbilityLevel(GetSpellTargetUnit(), ABI_PUNISHMENT_INDICATOR)==0 then
call IssueTargetOrder(GetTriggerUnit(), "fingerofdeath", GetSpellTargetUnit())
endif
endif
endfunction
//===========================================================================
function InitTrig_HolyPunishment takes nothing returns nothing
local trigger t=CreateTrigger() // pusnishment casted
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddAction(t, function Trig_HolyPunishment)
set gg_trg_HolyPunishment = CreateTrigger() // lightning unit2unit casted
call TriggerRegisterAnyUnitEventBJ(gg_trg_HolyPunishment, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(gg_trg_HolyPunishment, Condition(function Trig_HolyPunishment_Conditions))
call TriggerAddAction(gg_trg_HolyPunishment, function Trig_HolyPunishment_Actions)
endfunction
globals
constant integer ABI_HOLY_BOLT='A00G'
constant integer ABI_HOLY_BOLT_FEARIEFIRE='A00F'
constant integer ABI_HOLY_BOLT_INNERFIRE='A00I'
constant integer BUFF_HOLY_BOLT_ENEMY = 'B002'
endglobals
function Trig_HolyBolt_Conditions takes nothing returns boolean
return GetSpellAbilityId() == ABI_HOLY_BOLT
endfunction
//--------------------------------------------------------------------------------------
function Trig_HolyBolt_Actions takes nothing returns nothing
local unit u=GetTriggerUnit()
local player pla=GetOwningPlayer(u)
local integer lvl=GetUnitAbilityLevel(u, ABI_HOLY_BOLT)
local unit target=GetSpellTargetUnit()
local real heal = 100.00+(100.00*I2R(lvl))
local unit dummy=CreateUnit(pla, DUMMY, GetUnitX(target), GetUnitY(target), 0.00)
call UnitApplyTimedLife(dummy, 'BTLF', 2.00)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl", target, "origin"))
if IsUnitEnemy(target, pla) then
call UnitDamageTarget(u, target, heal/2.00, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call UnitAddAbility(dummy, ABI_HOLY_BOLT_FEARIEFIRE)
call SetUnitAbilityLevel(dummy, ABI_HOLY_BOLT_FEARIEFIRE, lvl)
call IssueTargetOrder(dummy, "faeriefire", target)
else//ally
if GetWidgetLife(target) == GetUnitState(target, UNIT_STATE_MAX_LIFE) then
call UnitAddAbility(dummy, ABI_HOLY_BOLT_INNERFIRE)
call SetUnitAbilityLevel(dummy, ABI_HOLY_BOLT_INNERFIRE, lvl)
call IssueTargetOrder(dummy, "innerfire", target)
else
call SetWidgetLife(target, GetWidgetLife(target)+heal)
endif
endif
set dummy=null
set u=null
set target=null
endfunction
//===========================================================================
function InitTrig_HolyBolt takes nothing returns nothing
set gg_trg_HolyBolt = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_HolyBolt, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_HolyBolt, Condition( function Trig_HolyBolt_Conditions ) )
call TriggerAddAction( gg_trg_HolyBolt, function Trig_HolyBolt_Actions )
endfunction
// Items Bag
globals
constant integer ABI_ITEM_BAG = 'A015'
item array g_itemsInBag
integer g_itemsInBagCount = 0
endglobals
function ItemBag_IsItemValid takes unit u, item itm returns boolean
local integer itemId = GetItemTypeId(itm)
if g_itemsInBagCount >= 25 then
return false
endif
if GetItemType(itm) == ITEM_TYPE_POWERUP then // not power up items (rune type for quests)!
return false
elseif itemId==ITEM_RESURRECTION_STONE or itemId==ITEM_STONE_PART then
return false
endif
if IsItemOwned(itm) then //if item is in inventory, it must be in caster inventory
return UnitHasItem(u, itm)
endif
return true
endfunction
function Trig_ib1_Conditions takes nothing returns boolean
return GetSpellAbilityId() == ABI_ITEM_BAG
endfunction
function IB_GetColumn takes integer i returns integer
local integer column=1
if i<6 then
set column=1
elseif i<11 then
set column=2
elseif i<16 then
set column=3
elseif i<21 then
set column=4
else
set column=5
endif
return column
endfunction
function IB_GetRow takes integer i returns integer
local integer row=1
if i<6 then
set row=i
elseif i<11 then
set row=i-5
elseif i<16 then
set row=i-10
elseif i<21 then
set row=i-15
else
set row=i-20
endif
return row
endfunction
function Trig_ib1_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local item itm = GetSpellTargetItem()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local integer i=0
local integer row=1
local integer column=1
local real Tx=0.00
local real Ty=0.00
if not (itm==null) then
if ItemBag_IsItemValid(u, itm) then
//call Msg("item valid")
if IsItemOwned(itm) then //item in inventory:
call UnitRemoveItem(u, itm)
endif
set g_itemsInBagCount = g_itemsInBagCount + 1
set g_itemsInBag[g_itemsInBagCount] = itm
call SetItemVisible(itm, false)
call DisplayTextToPlayer(GetLocalPlayer(), 0.00, 0.00, I2S(g_itemsInBagCount)+" items in bag.")
else
call DisplayTextToPlayer(GetLocalPlayer(), 0.00, 0.00, "Cannot target this item!")
endif
else
//DROP ALL
//call Msg("droping all...")
set i=1
loop
exitwhen i > g_itemsInBagCount
set row = IB_GetRow(i)
set column = IB_GetColumn(i)
set Tx = x + (50.00*I2R(row))
set Ty = y - (50.00*I2R(column))
call SetItemPosition(g_itemsInBag[i], Tx, Ty)
set g_itemsInBag[i] = null
set i=i+1
endloop
set g_itemsInBagCount=0
endif
set u=null
set itm=null
endfunction
//===========================================================================
function InitTrig_ib1 takes nothing returns nothing
set gg_trg_ib1 = CreateTrigger( )
call TriggerRegisterUnitEvent( gg_trg_ib1, gg_unit_H00B_0111, EVENT_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_ib1, Condition( function Trig_ib1_Conditions ) )
call TriggerAddAction( gg_trg_ib1, function Trig_ib1_Actions )
endfunction
globals
//hashtable hash_lp = null
constant integer SWORDSMAN = 'h006'
constant integer SHOOTER = 'h008'
constant integer MAGE = 'e001'
constant integer AUTO_TRAIN = 'h00H'
constant integer ABI_AUTO_TRAIN = 'A00J' //indicator
// my force
unit LP_CAPTAIN = null
constant real BARRACK_X = 3890.00
constant real BARRACK_Y = 2300.00
player PLAYER_ORANGE = Player(5)
unit BARRACK=null
unit array TOWER // 1,2 guard, 3 siege
timer tmr_update_food
group lp_orangeGroup
timer tmr_autoBarracks=null
integer g_lastTrainedId = 0
timer tmr_cancelFakeUnit=null
timer tmr_restoreFakeUnit=null
// enemy force:
constant integer ENEMY_SOLDIER = 'n008'
constant integer ENEMY_BRIGAND = 'n007'
constant integer ENEMY_SORCERESS = 'h00G'
unit LP_ENEMY_HERO = null
unit LP_ENEMY_CAPTAIN = null
player PLAYER_BLUE = Player(1)
unit ENEMY_BARRACK=null
constant real ENEMY_BARRACK_X = -1880.00
constant real ENEMY_BARRACK_Y = 2300.00
timer tmr_barrackSpawn = null
unit array ENEMY_TOWER // 1,2 guard, 3 siege
integer lp_food = 0
group lp_blueGroup
integer barracksSlotsOccupied = 0
constant real SPAWN_ENEMY_INTERVAL = 9.00
endglobals
//-----------------------------------------------------------------
function BarracksCancelFakeUnit takes nothing returns nothing
call IssueImmediateOrderById(BARRACK, 851976)
endfunction
function BarracksRestoreFakeUnit takes nothing returns nothing
call SetPlayerUnitAvailableBJ(AUTO_TRAIN, true, Player(0))
endfunction
function BarracksOrderTrain takes nothing returns nothing
local integer ord=GetIssuedOrderId()
if ord==SWORDSMAN or ord==SHOOTER or ord==MAGE then//or ord==AUTO_TRAIN then
set barracksSlotsOccupied = barracksSlotsOccupied + 1
endif
if ord==AUTO_TRAIN then
call SetPlayerUnitAvailableBJ(AUTO_TRAIN, false, Player(0))
if udg_autoTrain then
set udg_autoTrain=false
call UnitRemoveAbility(BARRACK, ABI_AUTO_TRAIN)
else
set udg_autoTrain=true
call UnitAddAbility(BARRACK, ABI_AUTO_TRAIN)
endif
//call TimerStart(tmr_cancelFakeUnit, 1.00, false, function BarracksCancelFakeUnit)
call TimerStart(tmr_restoreFakeUnit, 1.00, false, function BarracksRestoreFakeUnit)
endif
endfunction
function BarracksCancelsTrain takes nothing returns nothing
set barracksSlotsOccupied = barracksSlotsOccupied - 1
endfunction
function BarracksDuringTraining takes nothing returns boolean
return (barracksSlotsOccupied>0)
endfunction
//----------------------------------------------------------
//----------------------------------------------------------
function Trig_SetFoodToOriginalEnum takes nothing returns nothing
set lp_food = lp_food + GetUnitFoodUsed(GetEnumUnit())
endfunction
function LongPassage_UpdateFood takes nothing returns nothing
local integer orange_food = GetPlayerState(PLAYER_ORANGE, PLAYER_STATE_RESOURCE_FOOD_USED)
call SetPlayerState(Player(0), PLAYER_STATE_RESOURCE_FOOD_USED, orange_food)
if IsQuestCompleted(udg_longPassageQuest) or IsQuestFailed(udg_longPassageQuest) then
// set food to original:
set lp_food=0
call ForGroup(GetUnitsOfPlayerAll(Player(0)), function Trig_SetFoodToOriginalEnum)
call SetPlayerState(Player(0), PLAYER_STATE_RESOURCE_FOOD_USED, lp_food)
else
call TimerStart(tmr_update_food, 0.30, false, function LongPassage_UpdateFood)
endif
endfunction
//player barracks
function Trig_BarrackOnTrainFinish takes nothing returns nothing
local unit u=GetTrainedUnit()
set g_lastTrainedId = GetUnitTypeId(u)
set barracksSlotsOccupied = barracksSlotsOccupied - 1 //to know if structure is during train
call SetUnitOwner(u, PLAYER_ORANGE, true)
call GroupAddUnit(lp_orangeGroup, u)
call IssuePointOrder(u, "attack", ENEMY_BARRACK_X, ENEMY_BARRACK_Y)
set u = CreateUnit(PLAYER_ORANGE, g_lastTrainedId, BARRACK_X, BARRACK_Y, 180.00)
call GroupAddUnit(lp_orangeGroup, u)
call IssuePointOrder(u, "attack", ENEMY_BARRACK_X, ENEMY_BARRACK_Y)
set u=null
endfunction
function LongPassage_AutoBarracks takes nothing returns nothing
if udg_autoTrain and (barracksSlotsOccupied==0) then
call IssueImmediateOrderById(BARRACK, g_lastTrainedId)
endif
if not (IsQuestCompleted(udg_longPassageQuest) or IsQuestFailed(udg_longPassageQuest)) then
call TimerStart(tmr_autoBarracks, 1.00, false, function LongPassage_AutoBarracks)
endif
endfunction
// on map init: ------------------------------------------
function LongPassageSetVars takes nothing returns nothing
local trigger t=CreateTrigger()
//set hash_lp = InitHashtable()
set BARRACK = gg_unit_hbar_0009
set TOWER[1] = gg_unit_hgtw_0012
set TOWER[2] = gg_unit_hgtw_0013
set TOWER[3] = gg_unit_hctw_0016
set LP_CAPTAIN = gg_unit_n003_0128
set ENEMY_BARRACK = gg_unit_hbar_0010
set ENEMY_TOWER[1] = gg_unit_hgtw_0014
set ENEMY_TOWER[2] = gg_unit_hgtw_0015
set ENEMY_TOWER[3] = gg_unit_hctw_0017
set LP_ENEMY_CAPTAIN = gg_unit_n003_0120
set LP_ENEMY_HERO = gg_unit_H00E_0130
set lp_orangeGroup = CreateGroup()
set lp_blueGroup = CreateGroup()
//set invulnerable
call SetUnitInvulnerable(BARRACK, true)
call SetUnitInvulnerable(TOWER[1], true)
call SetUnitInvulnerable(TOWER[2], true)
call SetUnitInvulnerable(TOWER[3], true)
call SetUnitInvulnerable(ENEMY_BARRACK, true)
call SetUnitInvulnerable(ENEMY_TOWER[1], true)
call SetUnitInvulnerable(ENEMY_TOWER[2], true)
call SetUnitInvulnerable(ENEMY_TOWER[3], true)
call SetUnitInvulnerable(LP_CAPTAIN, true)
call SetUnitInvulnerable(LP_ENEMY_CAPTAIN, true)
call SetUnitInvulnerable(LP_ENEMY_HERO, true)
set tmr_barrackSpawn = CreateTimer()
set tmr_update_food = CreateTimer()
set tmr_autoBarracks = CreateTimer()
set tmr_cancelFakeUnit = CreateTimer()
set tmr_restoreFakeUnit = CreateTimer()
//player's barracks train finish
call TriggerRegisterUnitEvent(t, BARRACK, EVENT_UNIT_TRAIN_FINISH)
call TriggerAddAction(t, function Trig_BarrackOnTrainFinish)
set t=CreateTrigger()
call TriggerRegisterUnitEvent(t, BARRACK, EVENT_UNIT_ISSUED_ORDER )
call TriggerAddAction(t, function BarracksOrderTrain)
set t=CreateTrigger()
call TriggerRegisterUnitEvent(t, BARRACK, EVENT_UNIT_TRAIN_CANCEL)
call TriggerAddAction(t, function BarracksCancelsTrain)
endfunction
//------------------- ENEMY ---------------------------------
function GetUnitIdToSpawn takes nothing returns integer
local integer sw = GetPlayerUnitTypeCount(PLAYER_ORANGE, SWORDSMAN)
local integer sh = GetPlayerUnitTypeCount(PLAYER_ORANGE, SHOOTER)
local integer m = GetPlayerUnitTypeCount(PLAYER_ORANGE, MAGE)
local integer max = IMaxBJ(IMaxBJ(sw, sh), m)
if max==sw then
return ENEMY_SORCERESS
elseif max==sh then
return ENEMY_SOLDIER
endif
return ENEMY_BRIGAND
endfunction
function SpawnEnemySoldiers takes nothing returns nothing
local integer unitId = GetUnitIdToSpawn()
local unit u=null
if UnitAlive(ENEMY_BARRACK) then
set u = CreateUnit(PLAYER_BLUE, unitId, ENEMY_BARRACK_X, ENEMY_BARRACK_Y, 0.00)
call GroupAddUnit(lp_blueGroup, u)
call IssuePointOrder(u, "attack", BARRACK_X, BARRACK_Y)
set u = CreateUnit(PLAYER_BLUE, unitId, ENEMY_BARRACK_X, ENEMY_BARRACK_Y, 0.00)
call GroupAddUnit(lp_blueGroup, u)
call IssuePointOrder(u, "attack", BARRACK_X, BARRACK_Y)
if UnitAlive(BARRACK) then
call TimerStart(tmr_barrackSpawn, SPAWN_ENEMY_INTERVAL, false, function SpawnEnemySoldiers)
endif
endif
set u=null
endfunction
// run on quest activation:
function LongPassage_OnQuestActivation takes nothing returns nothing
//set vulnerable
call SetUnitInvulnerable(BARRACK, false)
call SetUnitInvulnerable(TOWER[1], false)
call SetUnitInvulnerable(TOWER[2], false)
call SetUnitInvulnerable(TOWER[3], false)
call SetUnitInvulnerable(ENEMY_BARRACK, false)
call SetUnitInvulnerable(ENEMY_TOWER[1], false)
call SetUnitInvulnerable(ENEMY_TOWER[2], false)
call SetUnitInvulnerable(ENEMY_TOWER[3], false)
call SetUnitInvulnerable(LP_CAPTAIN, false)
call SetUnitInvulnerable(LP_ENEMY_CAPTAIN, false)
call SetUnitInvulnerable(LP_ENEMY_HERO, false)
call TimerStart(tmr_barrackSpawn, SPAWN_ENEMY_INTERVAL, false, function SpawnEnemySoldiers)
call TimerStart(tmr_update_food, 0.30, false, function LongPassage_UpdateFood)
call TimerStart(tmr_autoBarracks, 1.00, false, function LongPassage_AutoBarracks)
endfunction
//===========================================================================
function InitTrig_LongPassageF takes nothing returns nothing
endfunction
globals
real orange_X=4000.00
real blue_X=-2000.00
constant integer BEAZEL_SHOCKWAVE = 'A00A'
constant integer BEAZEL_CLAP = 'A00B'
constant integer BUFF_BEAZEL_CLAP = 'BHtc'
group ug=CreateGroup()
group ug2=CreateGroup()
boolexpr lp_filtr = null
unit g_beazelTarget=null
constant integer BEAZEL_EVASION = 'A00C'
constant integer BEAZEL_COMMAND_AURA = 'A00E'
endglobals
//-----------------------------------------------------------
//-----------------------------------------------------------
function LP_GetOrangeFrontEnum takes nothing returns nothing
// 4000 start, -2000 enemy barracks, get lowest x
if UnitAlive(GetEnumUnit()) and (GetUnitX(GetEnumUnit()) < orange_X) then
set orange_X = GetUnitX(GetEnumUnit())
endif
endfunction
function LP_GetBlueFrontEnum takes nothing returns nothing
// -2000 start, 4000 enemy barracks, get max x
if UnitAlive(GetEnumUnit()) and (GetUnitX(GetEnumUnit()) > blue_X) then
set blue_X = GetUnitX(GetEnumUnit())
endif
endfunction
function LP_GetFrontLine takes nothing returns real
//lp_blueGroup lp_orangeGroup
set orange_X=4000.00
set blue_X=-2000.00
call ForGroup(lp_orangeGroup, function LP_GetOrangeFrontEnum)
call ForGroup(lp_blueGroup, function LP_GetBlueFrontEnum)
return (orange_X + blue_X)/2.00
endfunction
//------------------------------------------------------------------
//------------------------------------------------------------------
//------------------------------------------------------------------
//function UnitChanneling takes unit u returns boolean
//function UnitSpellReady takes unit u, integer spellId returns boolean
//func: CSUnit_GetPrimaryAttacker takes unit victim returns unit
//var: isAttacked // unit user data of victim
function BeazelExitConditions takes nothing returns boolean
return (IsQuestCompleted(udg_longPassageQuest) or IsQuestFailed(udg_longPassageQuest)) and (not UnitAlive(LP_ENEMY_HERO))
endfunction
function BeazelAttacked takes nothing returns boolean
return isAttacked[GetUnitUserData(LP_ENEMY_HERO)]
endfunction
function BeazelToFarFromFrontLine takes nothing returns boolean
return GetUnitX(LP_ENEMY_HERO) > (300.00+LP_GetFrontLine())
endfunction
function BeazelToFar_Back takes nothing returns boolean
return GetUnitX(LP_ENEMY_HERO)+600.00 < LP_GetFrontLine()
endfunction
function BeazelInBase takes nothing returns boolean
return IsUnitInRangeXY(LP_ENEMY_HERO, -1550.00, 2300.00, 900.00)
endfunction
//-------------------------------------------------------------
//ORDERS:
function BeazelMoveBack_Loop takes nothing returns nothing
local integer c=4
call IssuePointOrder(LP_ENEMY_HERO, "move", -1550.00, 2300.00)
loop
exitwhen BeazelExitConditions()
exitwhen not BeazelToFarFromFrontLine()
exitwhen BeazelInBase()
exitwhen c==0
set c=c-1
call TriggerSleepAction(1.00)
endloop
endfunction
//-------------------------------------------------------------
//--------------------- SPELLS --------------------------------
//-------------------------------------------------------------
//--------------- Shockwave -----------------------------------
function BeazelShockwave_GetStructure takes nothing returns unit
if IsUnitInRange(LP_ENEMY_HERO, TOWER[1], 600.00) then
return TOWER[1]
elseif IsUnitInRange(LP_ENEMY_HERO, TOWER[2], 600.00) then
return TOWER[2]
elseif IsUnitInRange(LP_ENEMY_HERO, TOWER[3], 600.00) then
return TOWER[3]
elseif IsUnitInRange(LP_ENEMY_HERO, BARRACK, 600.00) then
return BARRACK
endif
return null
endfunction
function BeazelShockwave_GetEnemyGroupMember takes nothing returns unit
local unit FoG=null
local unit u2=null
local integer c=0
set g_beazelTarget = null
call GroupEnumUnitsInRange(ug, LP_GetFrontLine()+200.00, 2300.00, 600.00, lp_filtr)//alive,enemy, non-invul, not-locust
loop
set FoG = FirstOfGroup(ug)
exitwhen FoG == null
//---inner loop start
set c=0
call GroupEnumUnitsInRange(ug2, GetUnitX(FoG), GetUnitY(FoG), 300.00, lp_filtr)
loop
set u2 = FirstOfGroup(ug2)
exitwhen (u2 == null) or c>1
if u2 != FoG then
set c=c+1
endif
call GroupRemoveUnit(ug2, u2)
endloop
set u2=null
//---inner loop end
if c>1 then//FoG is valid
set g_beazelTarget=FoG
exitwhen true //exit main loop
endif
call GroupRemoveUnit(ug, FoG)
endloop
call GroupClear(ug)
return g_beazelTarget
endfunction
//pass "null" for no-target
function BeazelCastShockwave takes unit target returns nothing
local unit t = null
local boolean found=false
if UnitSpellReady(LP_ENEMY_HERO, BEAZEL_SHOCKWAVE) then
set t = BeazelShockwave_GetStructure()
if UnitAlive(t) then
set found=true
else
set t = BeazelShockwave_GetEnemyGroupMember()
if UnitAlive(t) then
set found=true
endif
endif
if found then
call IssuePointOrder(LP_ENEMY_HERO, "shockwave", GetUnitX(t), GetUnitY(t))
call TriggerSleepAction(1.00)
endif
if UnitAlive(target) then
call IssueTargetOrder(LP_ENEMY_HERO, "attack", target)
else
call IssuePointOrder(LP_ENEMY_HERO, "attack", LP_GetFrontLine(), 2300.00)
endif
call TriggerSleepAction(0.20)
endif
set t=null
endfunction
//--------------- Thunderclap ---------------------------------
function BeazelCastClap takes unit target returns nothing
local unit FoG=null
local integer c=0
if UnitSpellReady(LP_ENEMY_HERO, BEAZEL_CLAP) then
call GroupEnumUnitsInRange(ug, GetUnitX(LP_ENEMY_HERO), GetUnitY(LP_ENEMY_HERO), 300.00, lp_filtr)
loop
set FoG = FirstOfGroup(ug)
exitwhen (FoG == null) or c>2
set c=c+1
call GroupRemoveUnit(ug, FoG)
endloop
set FoG=null
if c>2 then
call IssueImmediateOrder(LP_ENEMY_HERO, "thunderclap")
call TriggerSleepAction(1.00)
if UnitAlive(target) then
call IssueTargetOrder(LP_ENEMY_HERO, "attack", target)
else
call IssuePointOrder(LP_ENEMY_HERO, "attack", LP_GetFrontLine(), 2300.00)
endif
call TriggerSleepAction(0.20)
endif
endif
endfunction
//-------------------------------------------------------------
//-------------------------------------------------------------
function Trig_Beazel_Act takes nothing returns nothing
local unit u=LP_ENEMY_HERO
local integer id=GetUnitUserData(u)
local real frontLine = 0.00
local integer c=0
local unit target=null
loop
exitwhen BeazelExitConditions()
call IssuePointOrder(u, "attack", LP_GetFrontLine(), 2300.00)
call TriggerSleepAction(0.20)
loop
exitwhen BeazelExitConditions()
exitwhen BeazelAttacked() and (not BeazelInBase()) and BeazelToFarFromFrontLine()
exitwhen (not BeazelAttacked()) and BeazelToFar_Back()
set target = CSUnit_GetPrimaryAttacker(u)
if target != null then
call IssueTargetOrder(u, "attack", target)
set c=8
loop
exitwhen BeazelExitConditions()
exitwhen BeazelAttacked() and (not BeazelInBase()) and BeazelToFarFromFrontLine()
exitwhen not UnitAlive(target)
exitwhen c==0
set c=c-1
call BeazelCastShockwave(target)
call BeazelCastClap(target)
call TriggerSleepAction(0.50)
endloop
endif
call TriggerSleepAction(0.50)
endloop
if BeazelAttacked() and (not BeazelInBase()) and BeazelToFarFromFrontLine() then
call BeazelMoveBack_Loop()
endif
call TriggerSleepAction(0.50)
endloop
set u=null
set target=null
endfunction
//===========================================================================
function F_LPFiltr1 takes nothing returns boolean
return UnitAlive(GetFilterUnit()) and (not BlzIsUnitInvulnerable(GetFilterUnit())) and (GetUnitAbilityLevel(GetFilterUnit(), 'Aloc')==0) and IsUnitEnemy(GetFilterUnit(), PLAYER_BLUE) and (not IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE))
endfunction
//===========================================================================
function InitTrig_EnemyHeroBehaviour takes nothing returns nothing
set lp_filtr = Condition(function F_LPFiltr1)
set gg_trg_EnemyHeroBehaviour = CreateTrigger( )
call TriggerAddAction(gg_trg_EnemyHeroBehaviour, function Trig_Beazel_Act)
endfunction
globals
//hashtable
hashtable ai_hash = null
//these for parent key handleId of a group
constant integer H_GROUP_COUNT=1
constant integer H_UNIT=100
constant integer H_UNIT_START_X=200
constant integer H_UNIT_START_Y=300
constant integer H_TARGET1=400
constant integer H_TARGET2=401
constant integer H_TEAM_STATUS=402
constant integer H_TEAM_CENTER_X=403
constant integer H_TEAM_CENTER_Y=404
constant integer H_TEAM_CURRENT_CENTER_X=405
constant integer H_TEAM_CURRENT_CENTER_Y=406
integer H_PARENT_KEY = 0
integer hash_tempInt1 = 0
integer hash_tempInt2 = 0
unit AI_tempTarget_1=null
unit AI_tempTarget_2=null
trigger trg_AI = CreateTrigger()
group AI_tempG=CreateGroup()
//units
constant integer SOLDIER1 = 'n008'
constant integer BRIGAND1 = 'n007'
constant integer SORCERESS1 = 'h00G'
constant integer KNIGHT1 = 'h00J'
constant integer SPEARMAN1 = 'n00U'
constant integer VETERAN_KNIGHT1 = 'n00T'
constant integer MAGE1 = 'n00S'
//heroes
constant integer ILLIDAN1 = 'E003'
constant integer ILLIDANMORPHED1 = 'E004'
constant integer KAEL1 = 'H00K'
constant integer LORDBEAZEL1 = 'H00E'
constant integer MAIEV1 = 'E002'
constant integer TEAM_IDLE = 0
constant integer TEAM_ATTACKED = 1
constant integer TEAM_UNPROVOKED = 2
constant integer TEAM_TOO_FAR = 3
// MURADIN_ACTIVE boolean
//declared in long passage BEAZEL_SHOCKWAVE BEAZEL_CLAP BUFF_BEAZEL_CLAP
//Illidan's:
constant integer ABI_MANA_BURN = 'A00X' // "manaburn"
constant integer ABI_GLAIVE_THROW = 'A00Y' // "thunderbolt"
constant integer BUFF_GLAIVE_THROW = 'BPSE' // stunned
constant integer ABI_PURGE = 'A014' // "purge"
constant integer ABI_METAMORPHOSIS = 'A00W' // "metamorphosis"
//Maiev
constant integer ABI_MAIEV_KNIVES = 'A011' // "fanofknives"
constant integer ABI_MAIEV_BLINK = 'A00Z' // "blink"
constant integer ABI_MAIEV_SHADOW_STRIKES = 'A010' // "shadowstrike"
constant integer BUFF_MAIEV_SHADOW_STRIKES = 'BEsh'
constant integer ABI_MAIEV_HEALING_WARD = 'A012' // "healingward"
constant integer MAIEV_HEALING_WARD = 'o000'
//Kael
constant integer ABI_KAEL_FLAME_STRIKE = 'A00S' // "flamestrike"
constant integer ABI_KAEL_BANISH = 'A00T' // "banish"
constant integer BUFF_KAEL_BANISH = 'BHbn'
constant integer ABI_KAEL_SIPHON_MANA = 'A00U' // "drain" 852487
constant integer ABI_KAEL_ANTI_MAGIC = 'A00Q' // "roar"
constant integer BUFF_KAEL_ANTI_MAGIC = 'A00R'
//Mage(unit)
constant integer ABI_MAGE_SLOW = 'ACsw' // "slow"
constant integer BUFF_SLOW = 'Bslo'
constant integer ABI_MAGE_POLYMORPH = 'ACpy' // "polymorph"
constant integer ABI_MAGE_SHADOW_MELD = 'Ashm' // "ambush"
endglobals
//======================================================================
// HaveSavedHandle
// RemoveSavedHandle
function AIGroupRegister_Enum takes nothing returns nothing
local unit u=GetEnumUnit()
set hash_tempInt1 = hash_tempInt1 + 1
call SaveUnitHandle(ai_hash, H_PARENT_KEY, H_UNIT+hash_tempInt1, u) //starts from 101..102..etc
call SaveReal(ai_hash, H_PARENT_KEY, H_UNIT_START_X+hash_tempInt1, GetUnitX(u))
call SaveReal(ai_hash, H_PARENT_KEY, H_UNIT_START_Y+hash_tempInt1, GetUnitY(u))
set u=null
endfunction
function AIGroupRegister takes group g, real centerX, real centerY returns nothing
set H_PARENT_KEY = H_PARENT_KEY + 1
set hash_tempInt1 = 0
//set hash_tempInt2 = GetHandleId(g)
call SaveInteger(ai_hash, H_PARENT_KEY, H_GROUP_COUNT, BlzGroupGetSize(g))
call SaveInteger(ai_hash, H_PARENT_KEY, H_TEAM_STATUS, TEAM_IDLE)
call SaveReal(ai_hash, H_PARENT_KEY, H_TEAM_CENTER_X, centerX)
call SaveReal(ai_hash, H_PARENT_KEY, H_TEAM_CENTER_Y, centerY)
call ForGroup(g, function AIGroupRegister_Enum)
endfunction
//------------------------------------------------------------------
function AIGroupGetCount takes integer h_id returns integer
return LoadInteger(ai_hash, h_id, H_GROUP_COUNT)
endfunction
function AIGroupGetStatus takes integer h_id returns integer
return LoadInteger(ai_hash, h_id, H_TEAM_STATUS)
endfunction
function AIGroupSetStatus takes integer h_id, integer status returns nothing
call SaveInteger(ai_hash, h_id, H_TEAM_STATUS, status)
endfunction
function AIGroupGetStartCenter_X takes integer h_id returns real
return LoadReal(ai_hash, h_id, H_TEAM_CENTER_X)
endfunction
function AIGroupGetStartCenter_Y takes integer h_id returns real
return LoadReal(ai_hash, h_id, H_TEAM_CENTER_Y)
endfunction
//=================================================================
function AITeam_Dead takes integer h_id returns boolean//handleid of a group
local integer i=1
local integer count=AIGroupGetCount(h_id)
local unit u = null
local boolean result=true
loop
exitwhen i>count
set u = LoadUnitHandle(ai_hash, h_id, H_UNIT+i)
if UnitAlive(u) then
set result=false
exitwhen true
endif
set i=i+1
endloop
set u=null
return result
endfunction
//-----------------------------------------------------------------
function AITeam_Attacked takes integer h_id returns boolean
local integer i=1
local integer count=AIGroupGetCount(h_id)
local unit u = null
local boolean result=false
loop
exitwhen i>count
set u = LoadUnitHandle(ai_hash, h_id, H_UNIT+i)
if (not (u==null)) and CSUnit_Attacked(u) then
set result=true
exitwhen true
endif
set i=i+1
endloop
set u=null
return result
endfunction
//-----------------------------------------------------------------
function AITeam_GetTarget takes integer h_id returns unit
return LoadUnitHandle(ai_hash, h_id, H_TARGET1)
endfunction
function AITeam_GetAltTarget takes integer h_id returns unit
return LoadUnitHandle(ai_hash, h_id, H_TARGET2)
endfunction
//-----------------------------------------------------------------
// saves in hash attacker of first attacked team member
function AITeam_SaveAttacker takes integer h_id returns boolean
local boolean result=false
local integer i=1
local integer count=AIGroupGetCount(h_id)
local unit u = null
local unit target=null
call RemoveSavedHandle(ai_hash, h_id, H_TARGET1) //clean target1
//CSUnit_GetPrimaryAttackerEx takes unit victim, real x, real y, integer maxRangeFromXY
loop
exitwhen i>count
set u = LoadUnitHandle(ai_hash, h_id, H_UNIT+i)
if not (u==null) then
set target = CSUnit_GetPrimaryAttackerEx(u, GetUnitX(u), GetUnitY(u), 1500)
if UnitAlive(target) and (not IsUnitType(target, UNIT_TYPE_ETHEREAL)) then
call SaveUnitHandle(ai_hash, h_id, H_TARGET1, target)
set result=true
exitwhen true
endif
endif
set i=i+1
endloop
set u=null
set target=null
return result
endfunction
//-----------------------------------------------------------------
function AITeam_UnprovokedSaveTarget takes integer h_id, real x, real y, real range returns boolean
local boolean result=false
set AI_tempTarget_1=null
call GroupEnumUnitsInRange(AI_tempG, x, y, range, cs_filtr_alive)
loop
set AI_tempTarget_1 = FirstOfGroup(AI_tempG)
exitwhen AI_tempTarget_1 == null
if IsUnitEnemy(AI_tempTarget_1, Player(1)) and (not IsUnitType(AI_tempTarget_1, UNIT_TYPE_ETHEREAL)) then
//not banished UNIT_TYPE_ETHEREAL added 26.02
call SaveUnitHandle(ai_hash, h_id, H_TARGET1, AI_tempTarget_1)
set result=true
endif
call GroupRemoveUnit(AI_tempG, AI_tempTarget_1)
endloop
return result
endfunction
//-----------------------------------------------------------------
//for spell casters..
function AITeam_IsTargetThread takes integer h_id, unit target returns boolean
local integer i=1
local integer count=AIGroupGetCount(h_id)
local unit u = null
local boolean result=false
loop
exitwhen i>count
set u = LoadUnitHandle(ai_hash, h_id, H_UNIT+i)
if (not (u==null)) and (CSUnit_GetDamageDealtByUnit(u, target)>0.00) then
set result=true
exitwhen true
endif
set i=i+1
endloop
set u=null
return result
endfunction
function AITeam_SaveAlternateTarget takes integer h_id, real x, real y, real range returns boolean
local boolean result=false
set AI_tempTarget_2 = null
set AI_tempTarget_1 = AITeam_GetTarget(h_id) //primary target
call GroupEnumUnitsInRange(AI_tempG, x, y, range, cs_filtr_alive)
loop
set AI_tempTarget_2 = FirstOfGroup(AI_tempG)
exitwhen AI_tempTarget_2 == null
if IsUnitEnemy(AI_tempTarget_2, Player(1)) and GetUnitLevel(AI_tempTarget_2)>1 and (AI_tempTarget_2 != AI_tempTarget_1) then
//did he deal damage to the group?
if AITeam_IsTargetThread(h_id, AI_tempTarget_2) then
call SaveUnitHandle(ai_hash, h_id, H_TARGET2, AI_tempTarget_2)
set result=true
exitwhen true
endif
endif
call GroupRemoveUnit(AI_tempG, AI_tempTarget_2)
endloop
return result
endfunction
//-----------------------------------------------------------------
function AITeam_InHome takes integer h_id returns boolean
local integer i=1
local integer count=AIGroupGetCount(h_id)
local boolean result=true
local unit u=null
local real x = 0.00
local real y = 0.00
loop
exitwhen i>count
set u = LoadUnitHandle(ai_hash, h_id, H_UNIT+i)
set x = LoadReal(ai_hash, h_id, H_UNIT_START_X+i)
set y = LoadReal(ai_hash, h_id, H_UNIT_START_Y+i)
if UnitAlive(u) and (not IsUnitInRangeXY(u, x, y, 125.00)) then
set result=false
exitwhen true
endif
set i=i+1
endloop
set u=null
return result
endfunction
//-----------------------------------------------------------------
function AITeam_TooFar takes integer h_id returns boolean
local integer i=1
local integer count=AIGroupGetCount(h_id)
local boolean result=false
local unit u=null
local real x = 0.00
local real y = 0.00
loop
exitwhen i>count
set u = LoadUnitHandle(ai_hash, h_id, H_UNIT+i)
set x = LoadReal(ai_hash, h_id, H_UNIT_START_X+i)
set y = LoadReal(ai_hash, h_id, H_UNIT_START_Y+i)
if UnitAlive(u) and (not IsUnitInRangeXY(u, x, y, 1500.00)) then
set result=true
exitwhen true
endif
set i=i+1
endloop
set u=null
return result
endfunction
//-------------------------------------------------
//--- saves in hash current center x/y of a group
//----------------------------------------------------------
function AITeam_SaveCenter takes integer h_id returns nothing
local integer i=1
local integer count=AIGroupGetCount(h_id)
local unit u=null
local real x = 0.00
local real y = 0.00
local integer members=0
loop
exitwhen i>count
set u = LoadUnitHandle(ai_hash, h_id, H_UNIT+i)
if UnitAlive(u) and (not IsUnitLoaded(u)) then
set x=x + GetUnitX(u)
set y=y + GetUnitY(u)
set members=members+1
endif
set i=i+1
endloop
//---
if members>0 then
set x=x / members
set y=y / members
call IsTerrainWalkable(x, y)
set x = TerrainPathability_X // from library TerrainPathability
set y = TerrainPathability_Y // from library TerrainPathability
endif
//save in hash:
call SaveReal(ai_hash, h_id, H_TEAM_CURRENT_CENTER_X, x)
call SaveReal(ai_hash, h_id, H_TEAM_CURRENT_CENTER_Y, y)
set u=null
endfunction
//----------------------------------------------------------
function AITeam_GetTeamPercentLife takes integer h_id returns real
local integer i=1
local integer count=AIGroupGetCount(h_id)
local unit u=null
local real lifes=0.00
local integer members=0
loop
exitwhen i>count
set u = LoadUnitHandle(ai_hash, h_id, H_UNIT+i)
if UnitAlive(u) then
set lifes=lifes + (GetWidgetLife(u)/GetUnitState(u, UNIT_STATE_MAX_LIFE))
set members=members+1
endif
set i=i+1
endloop
set u=null
return (lifes/I2R(members))
endfunction
//===========================================================================
function InitTrig_AIMain takes nothing returns nothing
endfunction
//-----------------------------------------------------------------
// SPELLS
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// KAEL
//-----------------------------------------------------------------
//----------------- Flame Strike ----------------------------------
function Kael_CastFlameStrike takes integer h_id, unit u, unit target returns boolean
local boolean casted=false
local integer c=0
local boolean b1 = UnitSpellReady(u, ABI_KAEL_FLAME_STRIKE)
local boolean b2 = (not BlzIsUnitInvulnerable(target))
local boolean b3 = (not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE))
local boolean b4 = IsUnitInRange(target, u, 700.00)
if b1 and b2 and b3 and b4 then
set casted = true
call IssuePointOrderById(u, ORDER_flamestrike, GetUnitX(target), GetUnitY(target))
loop
set c=c+1
exitwhen c>12
exitwhen GetUnitCurrentOrder(u) != ORDER_flamestrike
call TriggerSleepAction(0.20)
endloop
if AIGroupGetStatus(h_id) == TEAM_ATTACKED and GetUnitAbilityLevel(target, BUFF_KAEL_BANISH)==0 then
call IssueTargetOrderById(u, ORDER_attack, target)
call TriggerSleepAction(0.20)
endif
endif
return casted
endfunction
//------------------ Banish + Flame Strike ----------------------------------
function Kael_CastBanish_FlameStrike takes integer h_id, unit u, unit target returns boolean
local boolean casted=false
local integer c=0
local boolean b1 = UnitSpellReady(u, ABI_KAEL_FLAME_STRIKE)
local boolean b2 = UnitSpellReady(u, ABI_KAEL_BANISH)
local boolean b3 = not BlzIsUnitInvulnerable(target)
local boolean b4 = not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)
local boolean b5 = not IsUnitType(target, UNIT_TYPE_MECHANICAL)
local boolean b6 = not IsUnitType(target, UNIT_TYPE_STRUCTURE)
local boolean b7 = IsUnitInRange(target, u, 700.00)
if b1 and b2 and b3 and b4 and b5 and b6 and b7 then
set casted = true
call IssueTargetOrderById(u, ORDER_banish, target)
loop
set c=c+1
exitwhen c>10
exitwhen GetUnitAbilityLevel(target, BUFF_KAEL_BANISH)>0
exitwhen not UnitAlive(target)
call TriggerSleepAction(0.20)
endloop
if UnitAlive(target) then
//flame strike begin
call IssuePointOrderById(u, ORDER_flamestrike, GetUnitX(target), GetUnitY(target))
set c=0
loop
set c=c+1
exitwhen c>12
exitwhen GetUnitCurrentOrder(u) != ORDER_flamestrike
call TriggerSleepAction(0.20)
endloop
//flame strike end
endif
endif
return casted
endfunction
//------------------ Siphon Mana ----------------------------------
function Kael_CastSiphonMana takes integer h_id, unit u, unit target returns boolean
local boolean casted=false
local integer c=0
local boolean b1 = UnitSpellReady(u, ABI_KAEL_SIPHON_MANA)
local boolean b2 = not BlzIsUnitInvulnerable(target)
local boolean b3 = not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)
local boolean b4 = not IsUnitType(target, UNIT_TYPE_MECHANICAL)
local boolean b5 = not IsUnitType(target, UNIT_TYPE_STRUCTURE)
local boolean b6 = IsUnitInRange(target, u, 550.00)
local boolean b7 = (GetUnitState(target, UNIT_STATE_MANA)>50.00)
if b1 and b2 and b3 and b4 and b5 and b6 and b7 then
set casted = true
call IssueTargetOrderById(u, ORDER_drain, target)
loop
set c=c+1
exitwhen c>15
exitwhen GetUnitCurrentOrder(u) != ORDER_drain
exitwhen AIGroupGetStatus(h_id) != TEAM_ATTACKED //status changed
exitwhen not UnitAlive(target)
call TriggerSleepAction(0.50)
endloop
if AIGroupGetStatus(h_id) == TEAM_ATTACKED and GetUnitAbilityLevel(target, BUFF_KAEL_BANISH)==0 then
call IssueTargetOrderById(u, ORDER_attack, target)
call TriggerSleepAction(0.20)
endif
endif
return casted
endfunction
//------------------ Anti Magic ----------------------------------
function Kael_CastAntiMagic takes integer h_id, unit u, unit target returns boolean
local boolean casted=false
if UnitSpellReady(u, ABI_KAEL_ANTI_MAGIC) then
set casted = true
call IssueImmediateOrderById(u, ORDER_roar)
call TriggerSleepAction(0.50)
call IssueTargetOrderById(u, ORDER_attack, target)
call TriggerSleepAction(0.20)
endif
return casted
endfunction
//----------------------------------------------------------------------------
function AI_KAEL_Spell takes integer h_id, unit u, unit target returns nothing
local integer randomizer=GetRandomInt(1,100)
call Kael_CastAntiMagic(h_id, u, target)
if randomizer<50 then
if Kael_CastSiphonMana(h_id, u, target) then
elseif Kael_CastBanish_FlameStrike(h_id, u, target) then
endif
else
if Kael_CastBanish_FlameStrike(h_id, u, target) then
elseif Kael_CastSiphonMana(h_id, u, target) then
endif
endif
endfunction
//-----------------------------------------------------------------
// LORD BEAZEL
//-----------------------------------------------------------------
//Learn Beazel Command Aura for 6th level !
//Beazel spells are 3-levels
//--------------------------- Thunder Clap ----------------------------------------
function Beazel_CastThunderClap takes integer h_id, unit u, unit target returns boolean
local boolean casted = false
local integer count=0
local unit FoG=null
if not UnitSpellReady(u, BEAZEL_CLAP) then
return false
endif
call GroupEnumUnitsInRange(ug, GetUnitX(u), GetUnitY(u), 300.00, lp_filtr)
loop
set FoG = FirstOfGroup(ug)
exitwhen FoG == null
if (not IsUnitType(FoG, UNIT_TYPE_MECHANICAL)) then
set count=count+1
endif
call GroupRemoveUnit(ug, FoG)
endloop
if count>0 then
set casted=true
call IssueImmediateOrderById(u, ORDER_thunderclap)
call TriggerSleepAction(0.70)
endif
set FoG=null
return casted
endfunction
//--------------------------- Shockwave -------------------------------------------
function Beazel_CastShockwave takes integer h_id, unit u, unit target returns boolean
local boolean casted = false
local boolean found = false
local unit FoG=null
local unit u2=null
local integer c=0
if not UnitSpellReady(u, BEAZEL_SHOCKWAVE) then
return false
endif
call GroupEnumUnitsInRange(ug, GetUnitX(u), GetUnitX(u), 550.00, lp_filtr)//alive,enemy, non-invul, not magic-immune, not-locust
loop
set FoG = FirstOfGroup(ug)
exitwhen FoG == null
//---inner loop start
set c=0
call GroupEnumUnitsInRange(ug2, GetUnitX(FoG), GetUnitY(FoG), 300.00, lp_filtr)
loop
set u2 = FirstOfGroup(ug2)
exitwhen (u2 == null) or c>1
if u2 != FoG then
set c=c+1
endif
call GroupRemoveUnit(ug2, u2)
endloop
set u2=null
//---inner loop end
if c>1 then//FoG is valid
set found=true
exitwhen true //exit main loop
endif
call GroupRemoveUnit(ug, FoG)
endloop
call GroupClear(ug)
if found then
set casted=true
//FoG is valid target
call IssuePointOrderById(u, ORDER_shockwave, GetUnitX(FoG), GetUnitY(FoG))
call TriggerSleepAction(0.70)
endif
return casted
endfunction
// --------------------- BEAZEL -----------------------------------------------
function AI_BEAZEL_Spell takes integer h_id, unit u, unit target returns nothing
if GetRandomInt(1,100)<50 then
if Beazel_CastShockwave(h_id, u, target) then
elseif Beazel_CastThunderClap(h_id, u, target) then
endif
else
if Beazel_CastThunderClap(h_id, u, target) then
elseif Beazel_CastShockwave(h_id, u, target) then
endif
endif
endfunction
//-----------------------------------------------------------------
// MAIEV
//-----------------------------------------------------------------
//-----------------------------------------------------------------------------
function Maiev_CastHealingWard takes integer h_id, unit u, unit target returns boolean
local boolean casted=false
local integer c=0
local real x=0.00
local real y=0.00
local boolean b1 = UnitSpellReady(u, ABI_MAIEV_HEALING_WARD)
local boolean b2 = AITeam_GetTeamPercentLife(h_id)<0.80
local boolean b3 = (GetWidgetLife(u)/GetUnitState(u, UNIT_STATE_MAX_LIFE)) < 0.70
if b1 and (b2 or b3) then
call AITeam_SaveCenter(h_id)
set x = LoadReal(ai_hash, h_id, H_TEAM_CURRENT_CENTER_X)
set y = LoadReal(ai_hash, h_id, H_TEAM_CURRENT_CENTER_Y)
set casted = true
call IssuePointOrderById(u, ORDER_healingward, x, y)
loop
set c=c+1
exitwhen c>7
exitwhen GetUnitCurrentOrder(u) != ORDER_healingward
exitwhen AIGroupGetStatus(h_id) != TEAM_ATTACKED //status changed
exitwhen not UnitAlive(target)
call TriggerSleepAction(0.20)
endloop
endif
return casted
endfunction
//-----------------------------------------------------------------------------
function Maiev_CastBlinkOut takes integer h_id, unit u, unit target returns boolean
local integer c=0
local boolean casted=false
local real x=GetUnitX(u)
local real y=GetUnitY(u)
local real Cx=0.00
local real Cy=0.00
local real Tx=0.00
local real Ty=0.00
local real angle = 0.00
local real lifePerc=GetWidgetLife(u)/GetUnitState(u, UNIT_STATE_MAX_LIFE)
if UnitSpellReady(u, ABI_MAIEV_BLINK) and (lifePerc<0.30) then
call AITeam_SaveCenter(h_id)
set Cx = LoadReal(ai_hash, h_id, H_TEAM_CURRENT_CENTER_X)
set Cy = LoadReal(ai_hash, h_id, H_TEAM_CURRENT_CENTER_Y)
set angle = Atan2(Cy-y, Cx-x)
set Tx = x + 700.00 * Cos(angle)
set Ty = y + 700.00 * Sin(angle)
call IsTerrainWalkable(Tx, Ty)
set Tx = TerrainPathability_X // from library TerrainPathability
set Ty = TerrainPathability_Y // from library TerrainPathability
set casted = true
call IssuePointOrderById(u, ORDER_blink, Tx, Ty)
call TriggerSleepAction(1.00)
endif
return casted
endfunction
//-----------------------------------------------------------------------------
function Maiev_CastBlinkIn takes integer h_id, unit u, unit target returns boolean
local integer c=0
local boolean casted=false
local real angle = 0.00
local real x=0.00
local real y=0.00
local real Tx=0.00
local real Ty=0.00
local real dist=0.00
//must be not to close also!!
if IsUnitInRange(u, target, 500.00) then
return false
endif
if UnitSpellReady(u, ABI_MAIEV_BLINK) and (GetWidgetLife(u)/GetUnitState(u, UNIT_STATE_MAX_LIFE)) > 0.30 then
if not IsUnitInRange(u, target, 800.00) then
call IssueTargetOrderById(u, ORDER_attack, target)
set c=0
loop
set c=c+1
exitwhen c>4
exitwhen AIGroupGetStatus(h_id) != TEAM_ATTACKED //status changed
exitwhen not UnitAlive(target)
exitwhen IsUnitInRangeXY(u, GetUnitX(target), GetUnitY(target), 800.00)
call TriggerSleepAction(0.50)
endloop
endif
set x=GetUnitX(u)
set y=GetUnitY(u)
set Tx=GetUnitX(target)
set Ty=GetUnitY(target)
if IsUnitInRange(u, target, 800.00) then
set casted = true
set angle = Atan2(Ty-y, Tx-x)
set dist = SquareRoot((Tx-x) * (Tx-x) + (Ty-y) * (Ty-y))
set Tx = x+(dist+150.00)*Cos(angle)
set Ty = y+(dist+150.00)*Sin(angle)
call IsTerrainWalkable(Tx, Ty)
set Tx = TerrainPathability_X // from library TerrainPathability
set Ty = TerrainPathability_Y // from library TerrainPathability
call IssuePointOrderById(u, ORDER_blink, Tx, Ty)
set c=0
loop
set c=c+1
exitwhen c>5
exitwhen GetUnitCurrentOrder(u) != ORDER_blink
exitwhen AIGroupGetStatus(h_id) != TEAM_ATTACKED //status changed
exitwhen not UnitAlive(target)
call TriggerSleepAction(0.20)
endloop
endif
endif
return casted
endfunction
//----------------------------------------------------------------------------
function Maiev_CastKnives takes integer h_id, unit u, unit target returns boolean
local boolean casted = false
local integer count=0
local unit FoG=null
if not UnitSpellReady(u, ABI_MAIEV_KNIVES) then
return false
endif
call GroupEnumUnitsInRange(ug, GetUnitX(u), GetUnitY(u), 400.00, lp_filtr)
loop
set FoG = FirstOfGroup(ug)
exitwhen FoG == null
if (not IsUnitType(FoG, UNIT_TYPE_ETHEREAL)) and (not IsUnitType(FoG, UNIT_TYPE_STRUCTURE)) and (not IsUnitType(FoG, UNIT_TYPE_MECHANICAL)) then
set count=count+1
endif
call GroupRemoveUnit(ug, FoG)
endloop
if count>1 then
set casted=true
call IssueImmediateOrderById(u, ORDER_fanofknives)
call TriggerSleepAction(1.00)
endif
set FoG=null
return casted
endfunction
//----------------------------------------------------------------------------
function Maiev_CastStrike takes integer h_id, unit u, unit target returns boolean
local boolean b1 = not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)
local boolean b2 = not IsUnitType(target, UNIT_TYPE_POLYMORPHED)
local boolean b3 = not IsUnitType(target, UNIT_TYPE_STRUCTURE)
local boolean b4 = not IsUnitType(target, UNIT_TYPE_MECHANICAL)
local boolean b5 = IsUnitInRange(target, u, 400.00)
local boolean b6 = GetUnitAbilityLevel(target, BUFF_MAIEV_SHADOW_STRIKES)==0
local boolean b7 = UnitSpellReady(u, ABI_MAIEV_SHADOW_STRIKES)
local integer c=0
local boolean casted = false
if b1 and b2 and b3 and b4 and b5 and b6 and b7 then
set casted = true
call IssueTargetOrderById(u, ORDER_shadowstrike, target)
loop
set c=c+1
exitwhen c>4
exitwhen GetUnitCurrentOrder(u) != ORDER_shadowstrike
exitwhen AIGroupGetStatus(h_id) != TEAM_ATTACKED //status changed
exitwhen not UnitAlive(target)
call TriggerSleepAction(0.20)
endloop
endif
return casted
endfunction
//----------------------------------------------------------------------------
function Maiev_DontMove takes integer h_id, unit u, unit target returns nothing
local integer c=0
call IssueImmediateOrderById(u, ORDER_holdposition)
call TriggerSleepAction(0.20)
call IssueImmediateOrderById(u, ORDER_ambush) //shadow meld
loop
set c=c+1
exitwhen c>12
exitwhen (GetWidgetLife(u)/GetUnitState(u, UNIT_STATE_MAX_LIFE)) > 0.45
exitwhen AIGroupGetStatus(h_id) != TEAM_ATTACKED //status changed
call TriggerSleepAction(0.50)
endloop
if AIGroupGetStatus(h_id) == TEAM_ATTACKED then
call IssueTargetOrderById(u, ORDER_attack, target)
call TriggerSleepAction(0.20)
endif
endfunction
//----------------------------------------------------------------------------
function AI_MAIEV_Spell takes integer h_id, unit u, unit target returns nothing
if Maiev_CastHealingWard(h_id, u, target) then //checks team's life and Maiev's life
elseif Maiev_CastBlinkIn(h_id, u, target) then //life>0.30
if Maiev_CastStrike(h_id, u, target) then
elseif Maiev_CastKnives(h_id, u, target) then
endif
elseif Maiev_CastBlinkOut(h_id, u, target) then //low hp (life<0.30)
if Maiev_CastHealingWard(h_id, u, target) then
call Maiev_DontMove(h_id, u, target)
endif
elseif Maiev_CastStrike(h_id, u, target) then
elseif Maiev_CastKnives(h_id, u, target) then
endif
endfunction
//-----------------------------------------------------------------
// ILLIDAN
//-----------------------------------------------------------------
//------------------- Illidan Metamoprhosis ----------------------------------
function Illidan_CastMetamorphosis takes integer h_id, unit u, unit target returns boolean
local boolean b1 = UnitSpellReady(u, ABI_METAMORPHOSIS)
local boolean b2 = (GetWidgetLife(target) / GetUnitState(target, UNIT_STATE_MAX_LIFE)) > 0.20
local boolean casted = false
if b1 and b2 then
set casted=true
call IssueImmediateOrderById(u, ORDER_metamorphosis)
call TriggerSleepAction(1.00)
call IssueTargetOrderById(u, ORDER_attack, target)
call TriggerSleepAction(0.20)
endif
return casted
endfunction
//------------------- Illidan Mana Burn --------------------------------------
function Illidan_CastManaBurn takes integer h_id, unit u, unit target returns boolean
local boolean b1 = not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)
local boolean b2 = not IsUnitType(target, UNIT_TYPE_POLYMORPHED)
local boolean b3 = not IsUnitType(target, UNIT_TYPE_STRUCTURE)
local boolean b4 = not IsUnitType(target, UNIT_TYPE_MECHANICAL)
local boolean b5 = IsUnitInRange(target, u, 400.00)
local boolean b6 = (GetUnitState(target, UNIT_STATE_MANA) > 50.00)
local boolean b7 = UnitSpellReady(u, ABI_MANA_BURN)
local integer c=0
local boolean casted = false
if b1 and b2 and b3 and b4 and b5 and b6 and b7 then
set casted = true
call IssueTargetOrderById(u, ORDER_manaburn, target)
loop
set c=c+1
exitwhen c>3
exitwhen GetUnitCurrentOrder(u) != ORDER_manaburn
exitwhen AIGroupGetStatus(h_id) != TEAM_ATTACKED //status changed
exitwhen not UnitAlive(target)
call TriggerSleepAction(1.00)
endloop
endif
return casted
endfunction
//------------------- Illidan Glaive Throw -----------------------------------
function Illidan_CastGlaiveThrow takes integer h_id, unit u, unit target returns boolean
local boolean b1 = not IsUnitType(target, UNIT_TYPE_STRUCTURE)
local boolean b2 = not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)
local boolean b3 = not IsUnitType(target, UNIT_TYPE_POLYMORPHED)
local boolean b4 = not IsUnitType(target, UNIT_TYPE_MECHANICAL)
local boolean b5 = IsUnitInRange(target, u, 600.00)
local boolean b6 = UnitSpellReady(u, ABI_GLAIVE_THROW)
local integer c=0
local boolean casted = false
if b1 and b2 and b3 and b4 and b5 and b6 then
set casted = true
call IssueTargetOrderById(u, ORDER_thunderbolt, target)
loop
set c=c+1
exitwhen c>3
exitwhen GetUnitCurrentOrder(u) != ORDER_thunderbolt
exitwhen AIGroupGetStatus(h_id) != TEAM_ATTACKED //status changed
exitwhen not UnitAlive(target)
call TriggerSleepAction(1.00)
endloop
endif
return casted
endfunction
//------------------- Illidan Purge ----------------------------------------
function Illidan_CastPurge takes integer h_id, unit u, unit target returns boolean
local unit FoG=null
local boolean casted=false
local boolean b1 = not IsUnitType(udg_hero, UNIT_TYPE_ETHEREAL)
if UnitSpellReady(u, ABI_PURGE) then //first check Arius:
if b1 and IsUnitInRange(udg_hero, u, 600.00) and GetUnitAbilityLevel(udg_hero, BUFF_BATTLE_HUNGER)>0 then
set casted=true
call IssueTargetOrderById(u, ORDER_purge, udg_hero)
call TriggerSleepAction(1.00)
else //check for ally with BUFF_HOLY_BOLT_ENEMY
call GroupEnumUnitsInRange(ug, GetUnitX(u), GetUnitY(u), 600.00, cs_filtr_alive)
loop
set FoG = FirstOfGroup(ug)
exitwhen FoG == null
if GetUnitLevel(FoG)>2 and GetOwningPlayer(FoG)==Player(1) and (GetUnitAbilityLevel(FoG, BUFF_HOLY_BOLT_ENEMY)>0) then
//cast
set casted=true
call IssueTargetOrderById(u, ORDER_purge, FoG)
call TriggerSleepAction(1.00)
exitwhen true
endif
call GroupRemoveUnit(ug, FoG)
endloop
endif
endif
set FoG=null
return casted
endfunction
//-----------------------------------------------------------------
function AI_ILLIDAN_Spell takes integer h_id, unit u, unit target returns nothing
local integer randomizer=GetRandomInt(1,100)
if Illidan_CastMetamorphosis(h_id, u, target) then
return
endif
if randomizer<33 then
if Illidan_CastManaBurn(h_id, u, target) then
elseif Illidan_CastGlaiveThrow(h_id, u, target) then
elseif Illidan_CastPurge(h_id, u, target) then
endif
elseif randomizer>66 then
if Illidan_CastPurge(h_id, u, target) then
elseif Illidan_CastManaBurn(h_id, u, target) then
elseif Illidan_CastGlaiveThrow(h_id, u, target) then
endif
else
if Illidan_CastGlaiveThrow(h_id, u, target) then
elseif Illidan_CastPurge(h_id, u, target) then
elseif Illidan_CastManaBurn(h_id, u, target) then
endif
endif
endfunction
//-----------------------------------------------------------------
// MAGE
//-----------------------------------------------------------------
function Mage_CastSlow takes integer h_id, unit u, unit target returns boolean
local boolean b1 = (GetUnitAbilityLevel(target, BUFF_SLOW)==0)
local boolean b2 = not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)
local boolean b3 = not IsUnitType(target, UNIT_TYPE_POLYMORPHED)
local boolean b4 = not IsUnitType(target, UNIT_TYPE_STRUCTURE)
local boolean b5 = UnitSpellReady(u, ABI_MAGE_SLOW)
local integer c=0
local boolean casted = false
if b1 and b2 and b3 and b4 and b5 then
set casted = true
call IssueTargetOrderById(u, ORDER_slow, target)
loop
set c=c+1
exitwhen c>5 // give mage few seconds to cast, but not to much
exitwhen GetUnitCurrentOrder(u) != ORDER_slow //slow casted
exitwhen AIGroupGetStatus(h_id) != TEAM_ATTACKED //status changed
exitwhen not UnitAlive(target)
call TriggerSleepAction(1.00)
endloop
endif
return casted
endfunction
//-----------------------------------------------------------------
function Mage_CastPolymorph takes integer h_id, unit u, unit target returns boolean
local boolean b1 = (GetUnitAbilityLevel(target, BUFF_SLOW)==0)
local boolean b2 = not IsUnitType(target, UNIT_TYPE_POLYMORPHED)
local boolean b3 = not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)
local boolean b4 = not IsUnitType(target, UNIT_TYPE_STRUCTURE)
local boolean b5 = not IsUnitType(target, UNIT_TYPE_MECHANICAL)
local boolean b6 = not IsUnitType(target, UNIT_TYPE_ETHEREAL)
local boolean b7 = UnitSpellReady(u, ABI_MAGE_POLYMORPH)
local integer c=0
local boolean casted = false
if b1 and b2 and b3 and b4 and b5 and b6 and b7 then
set casted = true
call IssueTargetOrderById(u, ORDER_polymorph, target)
loop
set c=c+1
exitwhen c>5 // give mage few seconds to cast, but not to much
exitwhen GetUnitCurrentOrder(u) != ORDER_polymorph //spell casted
exitwhen AIGroupGetStatus(h_id) != TEAM_ATTACKED //status changed
exitwhen not UnitAlive(target)
call TriggerSleepAction(1.00)
endloop
endif
return casted
endfunction
//-----------------------------------------------------------------
function AI_MAGE_Spell takes integer h_id, unit u, unit target returns nothing
local unit target_2=null
local boolean castedOnPrimaryTarget = true
local integer randomizer=GetRandomInt(1,100)
if randomizer <50 then
if Mage_CastSlow(h_id, u, target) then
elseif Mage_CastPolymorph(h_id, u, target) then
else
set castedOnPrimaryTarget = false
endif
else
if Mage_CastPolymorph(h_id, u, target) then
elseif Mage_CastSlow(h_id, u, target) then
else
set castedOnPrimaryTarget = false
endif
endif
if not castedOnPrimaryTarget then
//alternate target start
if AITeam_SaveAlternateTarget(h_id, GetUnitX(u), GetUnitY(u), 500.00) then
set target_2 = AITeam_GetAltTarget(h_id)
if not Mage_CastSlow(h_id, u, target_2) then
call Mage_CastPolymorph(h_id, u, target_2)
endif
endif
//alternate target end
endif
set target_2=null
endfunction
//-----------------------------------------------------------------
// COMMON
//-----------------------------------------------------------------
function AITeam_CastSpell takes integer h_id returns nothing
local integer i=1
local integer count=AIGroupGetCount(h_id)
local unit u=null
local integer unitId=0
local unit target=AITeam_GetTarget(h_id)
loop
exitwhen i>count
set u = LoadUnitHandle(ai_hash, h_id, H_UNIT+i)
if UnitAlive(u) then
set unitId=GetUnitTypeId(u)
if unitId==MAGE1 then
call AI_MAGE_Spell(h_id, u, target)
elseif unitId==ILLIDAN1 or unitId==ILLIDANMORPHED1 then
call AI_ILLIDAN_Spell(h_id, u, target)
elseif unitId==LORDBEAZEL1 then
call AI_BEAZEL_Spell(h_id, u, target)
elseif unitId==MAIEV1 then
call AI_MAIEV_Spell(h_id, u, target)
elseif unitId==KAEL1 then
call AI_KAEL_Spell(h_id, u, target)
endif
endif
set i=i+1
endloop
set u=null
set target=null
call TriggerSleepAction(0.20)
endfunction
//===========================================================================
function InitTrig_AISpells takes nothing returns nothing
endfunction
//-----------------------------------------------------------------
// ORDERS
//-----------------------------------------------------------------
function AITeam_OrderBack takes integer h_id returns nothing
local integer i=1
local integer count=AIGroupGetCount(h_id)
local unit u=null
local real x=0.00
local real y=0.00
loop
exitwhen i>count
set u = LoadUnitHandle(ai_hash, h_id, H_UNIT+i)
set x = LoadReal(ai_hash, h_id, H_UNIT_START_X+i)
set y = LoadReal(ai_hash, h_id, H_UNIT_START_Y+i)
if UnitAlive(u) then
call IssuePointOrderById(u, ORDER_move, x, y)
endif
set i=i+1
endloop
set u=null
call TriggerSleepAction(0.20)
endfunction
//-----------------------------------------------------------------
function AITeam_Fight_OrderAttack takes integer h_id returns nothing
local integer i=1
local integer count=AIGroupGetCount(h_id)
local integer unitId=0
local unit u=null
local unit target = LoadUnitHandle(ai_hash, h_id, H_TARGET1)
loop
exitwhen i>count
set u = LoadUnitHandle(ai_hash, h_id, H_UNIT+i)
if UnitAlive(u) then
set unitId=GetUnitTypeId(u)
if unitId==SOLDIER1 or unitId==BRIGAND1 or unitId==SORCERESS1 then
call IssuePointOrderById(u, ORDER_attack, GetUnitX(target), GetUnitY(target))
elseif unitId == MAGE1 then
call IssueTargetOrderById(u, ORDER_attackonce, target)
else
call IssueTargetOrderById(u, ORDER_attack, target)
endif
endif
set i=i+1
endloop
set u=null
set target=null
call TriggerSleepAction(0.20)
endfunction
//-----------------------------------------------------------------
function AITeam_Unprovoked_OrderAttack takes integer h_id returns nothing
local integer i=1
local integer count=AIGroupGetCount(h_id)
local unit u=null
local unit target = LoadUnitHandle(ai_hash, h_id, H_TARGET1)
loop
exitwhen i>count
set u = LoadUnitHandle(ai_hash, h_id, H_UNIT+i)
if UnitAlive(u) then
call IssueTargetOrderById(u, ORDER_attack, target)
endif
set i=i+1
endloop
set u=null
set target=null
call TriggerSleepAction(0.20)
endfunction
//-----------------------------------------------------------------
// LOOPs
//-----------------------------------------------------------------
function AI_Fight_Loop takes integer h_id returns nothing
local unit target = LoadUnitHandle(ai_hash, h_id, H_TARGET1)
local integer c=0
call AITeam_Fight_OrderAttack(h_id)
call TriggerSleepAction(0.20)
call Msg("Fight ("+I2S(h_id)+")")
loop
set c=c+1
exitwhen AITeam_Dead(h_id)
exitwhen not UnitAlive(target)
exitwhen AITeam_TooFar(h_id) and (not AITeam_Attacked(h_id))
exitwhen c>5
//SPELLS
call AITeam_CastSpell(h_id)
//END SPELLS
call TriggerSleepAction(1.00)
endloop
endfunction
//-----------------------------------------------------------------
function AI_FightUnprovoked_Loop takes integer h_id returns nothing
local unit target = LoadUnitHandle(ai_hash, h_id, H_TARGET1)
call AITeam_Unprovoked_OrderAttack(h_id)
call TriggerSleepAction(0.20)
call Msg("Uprovoked fight ("+I2S(h_id)+")")
loop
exitwhen AITeam_Dead(h_id)
exitwhen AITeam_Attacked(h_id)
exitwhen AITeam_TooFar(h_id)
exitwhen not UnitAlive(target)
call TriggerSleepAction(1.00)
endloop
endfunction
//-----------------------------------------------------------------
function AI_MoveBack_Loop takes integer h_id returns nothing
local integer c=0
call AITeam_OrderBack(h_id)
call TriggerSleepAction(0.20)
call Msg("Move-Back ("+I2S(h_id)+")")
loop
set c=c+1
exitwhen AITeam_Dead(h_id)
exitwhen AITeam_Attacked(h_id) and AITeam_SaveAttacker(h_id)
exitwhen AITeam_InHome(h_id)
exitwhen c>4
call TriggerSleepAction(1.00)
endloop
endfunction
//-----------------------------------------------------------------
function AI_Idle_Loop takes integer h_id, real x, real y returns nothing
call Msg("Idle.. ("+I2S(h_id)+")")
loop //wait for enemy...
if AITeam_Attacked(h_id) and AITeam_SaveAttacker(h_id) then
call AIGroupSetStatus(h_id, TEAM_ATTACKED)
exitwhen true
elseif (not AITeam_InHome(h_id)) then
call AIGroupSetStatus(h_id, TEAM_TOO_FAR)
exitwhen true
else
if AITeam_UnprovokedSaveTarget(h_id, x, y, 1200.00) then
call AIGroupSetStatus(h_id, TEAM_UNPROVOKED)
exitwhen true
endif
endif
exitwhen AITeam_Dead(h_id)
call TriggerSleepAction(1.00)
endloop
endfunction
//-----------------------------------------------------------------
//----------------MAIN AI------------------------------------------
//-----------------------------------------------------------------
function Trig_AI_Actions takes nothing returns nothing
//local integer h_id = GetHandleId(udg_AIGroup)
local integer h_id = H_PARENT_KEY
local integer status = TEAM_IDLE
local real x=AIGroupGetStartCenter_X(h_id)
local real y=AIGroupGetStartCenter_Y(h_id)
call Msg("StartingAI for group no " + I2S(h_id))
loop
exitwhen AITeam_Dead(h_id)
call AI_Idle_Loop(h_id, x, y)
set status = AIGroupGetStatus(h_id)
if status==TEAM_ATTACKED then
call AI_Fight_Loop(h_id)
elseif status==TEAM_UNPROVOKED then
call AI_FightUnprovoked_Loop(h_id)
elseif status==TEAM_TOO_FAR then
call AI_MoveBack_Loop(h_id)
endif
call TriggerSleepAction(0.20)
endloop
call Msg("AI team dead")
//CSUnit_GetDamageDealtByUnit takes unit victim, unit attacker returns real
//CSUnit_GetPrimaryAttacker takes unit victim returns unit
//CSUnit_Attacked takes unit victim returns boolean
//UnitSpellReady takes unit u, integer spellId returns boolean
//UnitChanneling takes unit u returns boolean
endfunction
//===========================================================================
function InitTrig_AIData takes nothing returns nothing
call TriggerAddAction(trg_AI, function Trig_AI_Actions)
endfunction
//TESH.scrollpos=253
//TESH.alwaysfold=0
globals
real array wallFacing
integer array wallPositionNr
unit array wallShadowed
unit array wall
// integer wallsMana
group wallShadowGroup
group wallGroup
constant real X_LEFTTOP = 1150.00
constant real Y_LEFTTOP = 896.00
constant integer WALL = 'h000'
constant integer HORIZONTAL_SQUARES = 7
constant integer VERTICAL_SQUARES = 7
constant integer TOTAL_SIDES = HORIZONTAL_SQUARES*(VERTICAL_SQUARES+1) + (HORIZONTAL_SQUARES+1)*VERTICAL_SQUARES
constant real SQUARE_SIZE = 128.00 // 0.60scaling value in OE
integer moveableWalls
integer array startingLoc
integer array winningLoc
integer numberOfWalls
integer array wallMovedIndicator // unit id
integer wallsMovedCounter = 0
string array wallDescription
endglobals
//===========================================
//===========================================
function Walls_RemoveUnitEnum takes nothing returns nothing
call RemoveUnit(GetEnumUnit())
endfunction
//-------------------------------------------------------------------
function Walls_CheckManaEnum takes nothing returns nothing
// set wallsMana = wallsMana + R2I(GetUnitState(GetEnumUnit(), UNIT_STATE_MANA))
set wallsMovedCounter = wallsMovedCounter + wallMovedIndicator[GetUnitUserData(GetEnumUnit())]
endfunction
//-------------------------------------------------------------------
function Walls_CheckForVictory takes nothing returns boolean
local integer a=1
loop
exitwhen a>numberOfWalls
if not IsUnitHidden(wallShadowed[winningLoc[a]]) then
return false
endif
set a=a+1
endloop
return true
endfunction
//-------------------------------------------------------------------
function Walls_IsWallOnStartingLoc takes integer i returns boolean
local integer a=1
loop
exitwhen a>numberOfWalls
if startingLoc[a] == i then
return true
endif
set a=a+1
endloop
return false
endfunction
//-------------------------------------------------------------------
function Walls_ResetWalls takes nothing returns nothing
local integer i=1
call ForGroup(wallGroup, function Walls_RemoveUnitEnum)
call GroupClear(wallGroup)
loop
call ShowUnit(wallShadowed[i], true)
if Walls_IsWallOnStartingLoc(i) then
call ShowUnit(wallShadowed[i], false)
set bj_lastCreatedUnit = CreateUnit(Player(0), WALL, GetUnitX(wallShadowed[i]), GetUnitY(wallShadowed[i]), wallFacing[GetUnitUserData(wallShadowed[i])])
set wallPositionNr[GetUnitUserData(bj_lastCreatedUnit)] = i
call GroupAddUnit(wallGroup, bj_lastCreatedUnit)
set wallMovedIndicator[GetUnitUserData(bj_lastCreatedUnit)] = 0
endif
exitwhen i==TOTAL_SIDES
set i=i+1
endloop
endfunction
//-------------------------------------------------------------------
//-------------------------------------------------------------------
function Walls_SetStartingWalls takes integer i1, integer i2, integer i3, integer i4, integer i5, integer i6, integer i7, integer i8, integer i9, integer i10, integer i11, integer i12, integer i13, integer i14, integer i15, integer i16, integer i17, integer i18, integer i19, integer i20, integer i21, integer i22, integer i23, integer i24, integer i25, integer i26, integer i27, integer i28, integer i29, integer i30 returns nothing
local integer a=1
set numberOfWalls = 0
set startingLoc[1] = i1
set startingLoc[2] = i2
set startingLoc[3] = i3
set startingLoc[4] = i4
set startingLoc[5] = i5
set startingLoc[6] = i6
set startingLoc[7] = i7
set startingLoc[8] = i8
set startingLoc[9] = i9
set startingLoc[10] = i10
set startingLoc[11] = i11
set startingLoc[12] = i12
set startingLoc[13] = i13
set startingLoc[14] = i14
set startingLoc[15] = i15
set startingLoc[16] = i16
set startingLoc[17] = i17
set startingLoc[18] = i18
set startingLoc[19] = i19
set startingLoc[20] = i20
set startingLoc[21] = i21
set startingLoc[22] = i22
set startingLoc[23] = i23
set startingLoc[24] = i24
set startingLoc[25] = i25
set startingLoc[26] = i26
set startingLoc[27] = i27
set startingLoc[28] = i28
set startingLoc[29] = i29
set startingLoc[30] = i30
loop
exitwhen a>30
if startingLoc[a] > 0 then
set numberOfWalls = numberOfWalls + 1
endif
set a=a+1
endloop
endfunction
//-------------------------------------------------------------------
function Walls_SetWinningWalls takes integer i1, integer i2, integer i3, integer i4, integer i5, integer i6, integer i7, integer i8, integer i9, integer i10, integer i11, integer i12, integer i13, integer i14, integer i15, integer i16, integer i17, integer i18, integer i19, integer i20, integer i21, integer i22, integer i23, integer i24, integer i25, integer i26, integer i27, integer i28, integer i29, integer i30 returns nothing
local integer a=1
local integer tempWall = 0
set winningLoc[1] = i1
set winningLoc[2] = i2
set winningLoc[3] = i3
set winningLoc[4] = i4
set winningLoc[5] = i5
set winningLoc[6] = i6
set winningLoc[7] = i7
set winningLoc[8] = i8
set winningLoc[9] = i9
set winningLoc[10] = i10
set winningLoc[11] = i11
set winningLoc[12] = i12
set winningLoc[13] = i13
set winningLoc[14] = i14
set winningLoc[15] = i15
set winningLoc[16] = i16
set winningLoc[17] = i17
set winningLoc[18] = i18
set winningLoc[19] = i19
set winningLoc[20] = i20
set winningLoc[21] = i21
set winningLoc[22] = i22
set winningLoc[23] = i23
set winningLoc[24] = i24
set winningLoc[25] = i25
set winningLoc[26] = i26
set winningLoc[27] = i27
set winningLoc[28] = i28
set winningLoc[29] = i29
set winningLoc[30] = i30
loop
exitwhen a>30
if winningLoc[a] > 0 then
set tempWall = tempWall + 1
endif
set a=a+1
endloop
if numberOfWalls != tempWall then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Walls: Wrong settings for starting/winning locations!")
endif
endfunction
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//7x7
//----------------------------------------------------------
function Walls_CreateShadowWalls takes nothing returns nothing
local integer a=1
local integer b=1
local integer i=1
local real x
local real y
//poziome create horizontal: x:1-7, y:1-8
set b=1
loop
set a=1
loop
set x = (X_LEFTTOP+(SQUARE_SIZE/2.00)) + (I2R(a-1)*SQUARE_SIZE)
set y = Y_LEFTTOP - (I2R(b-1)*SQUARE_SIZE)
set bj_lastCreatedUnit = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), WALL, x, y, 45.00)
call SetUnitVertexColor( bj_lastCreatedUnit, 255, 255, 255, 25 )
set wallFacing[GetUnitUserData(bj_lastCreatedUnit)] = 45.00
set wallPositionNr[GetUnitUserData(bj_lastCreatedUnit)] = i
set wallShadowed[i] = bj_lastCreatedUnit
call GroupAddUnit(wallShadowGroup, wallShadowed[i])
set i=i+1
exitwhen a==HORIZONTAL_SQUARES
set a=a+1
endloop
exitwhen b==VERTICAL_SQUARES+1
set b=b+1
endloop
//--------------------------------
//create vertical pionowe: //x:8 , y:7 , HORIZONTAL_SQUARES+1 , VERTICAL_SQUARES
set b=1
loop
set a=1
loop
set y = (Y_LEFTTOP-(SQUARE_SIZE/2.00)) - (I2R(b-1)*SQUARE_SIZE)
set x = X_LEFTTOP + (I2R(a-1)*SQUARE_SIZE)
set bj_lastCreatedUnit = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), WALL, x, y, 135.00)
call SetUnitVertexColor( bj_lastCreatedUnit, 255, 255, 255, 25 )
set wallFacing[GetUnitUserData(bj_lastCreatedUnit)] = 135.00
set wallPositionNr[GetUnitUserData(bj_lastCreatedUnit)] = i
set wallShadowed[i] = bj_lastCreatedUnit
call GroupAddUnit(wallShadowGroup, wallShadowed[i])
set i=i+1
exitwhen a==HORIZONTAL_SQUARES+1
set a=a+1
endloop
exitwhen b==VERTICAL_SQUARES
set b=b+1
endloop
//-------------------------
endfunction
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//--------------------------------------------------------------------
function Walls_CreateTask takes integer taskNumber returns nothing
local integer i=1
if taskNumber==1 then // str51 move2 make4
set wallDescription[1] = "Move 2 walls to make 4 squares"
set moveableWalls = 2
call Walls_SetStartingWalls(9,10,11,16,17,18,19,25,26,66,67,68,69,76,77,78,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
call Walls_SetWinningWalls(9,24,11,16,17,18,19,75,26,66,67,68,69,76,77,78,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
elseif taskNumber==2 then // str61 move2, make7
set wallDescription[2] = "Move 2 walls to make 7 squares"
set moveableWalls = 2
call Walls_SetStartingWalls(18,19,24,25,26,31,32,33,38,39,40,76,77,78,83,84,85,86,91,92,93,94,0,0,0,0,0,0,0,0)
call Walls_SetWinningWalls(18,19,24,25,26,31,32,33,38,75,40,76,77,78,83,84,85,17,91,92,93,94,0,0,0,0,0,0,0,0)
// ------------
elseif taskNumber==3 then // str57 move3, make4
set wallDescription[3] = "Move 3 walls to make 4 squares"
set moveableWalls = 3
call Walls_SetStartingWalls(17,19,24,25,26,31,32,33,75,76,77,78,83,84,85,86,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
call Walls_SetWinningWalls(17,19,24,25,26,23,32,82,75,76,77,78,83,84,85,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
elseif taskNumber==4 then // str72 move3, make6
set wallDescription[4] = "Move 3 walls to make 6 squares"
set moveableWalls = 3
call Walls_SetStartingWalls(19,78,26,77,18,25,76,85,84,83,82,23,24,30,31,32,33,38,39,40,91,92,93,94,0,0,0,0,0,0)
call Walls_SetWinningWalls(19,78,26,77,18,25,68,85,84,83,82,23,69,30,31,32,33,38,11,40,91,92,93,94,0,0,0,0,0,0)
// ------------
elseif taskNumber==5 then // str59 move4, make6
set wallDescription[5] = "Move 4 walls to make 6 squares"
set moveableWalls = 4
call Walls_SetStartingWalls(20,24,25,26,27,31,32,33,34,38,40,41,78,79,83,84,85,86,87,91,92,93,94,95,0,0,0,0,0,0)
call Walls_SetWinningWalls(20,24,39,26,27,31,32,33,34,30,90,41,78,79,83,84,85,86,37,91,92,93,94,95,0,0,0,0,0,0)
elseif taskNumber==6 then // str74 move4, make7
set wallDescription[6] = "Move 4 walls to make 7 squares"
set moveableWalls = 4
call Walls_SetStartingWalls(20,27,78,79,87,86,85,84,25,26,32,33,34,24,31,83,91,92,93,94,95,38,39,40,41,99,100,45,0,0)
call Walls_SetWinningWalls(20,27,78,79,75,86,85,84,16,26,32,33,34,24,31,83,74,92,93,94,95,38,39,23,41,99,100,45,0,0)
endif
loop // hide some shadowed walls, and create normal walls
if Walls_IsWallOnStartingLoc(i) then
call ShowUnit(wallShadowed[i], false)
set bj_lastCreatedUnit = CreateUnit(Player(0), WALL, GetUnitX(wallShadowed[i]), GetUnitY(wallShadowed[i]), wallFacing[GetUnitUserData(wallShadowed[i])])
set wallPositionNr[GetUnitUserData(bj_lastCreatedUnit)] = i
call GroupAddUnit(wallGroup, bj_lastCreatedUnit)
set wallMovedIndicator[GetUnitUserData(bj_lastCreatedUnit)] = 0
endif
exitwhen i==TOTAL_SIDES
set i=i+1
endloop
//call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, I2S(numberOfWalls))
// quest condition:
// each wall must be a part of a square
endfunction
//===========================================================================
function InitTrig_Walls takes nothing returns nothing
set wallShadowGroup = CreateGroup()
set wallGroup = CreateGroup()
endfunction
//TESH.scrollpos=20
//TESH.alwaysfold=0
function Z1orderCond takes nothing returns boolean
local unit wall = GetOrderedUnit()
local unit wallShadow = GetOrderTargetUnit()
local integer wallId = GetUnitUserData(wall)
local integer wallShadowId = GetUnitUserData(wallShadow)
local integer nr = wallPositionNr[wallId]
local integer newNr = wallPositionNr[wallShadowId]
if IsUnitInGroup(wall, wallGroup) and IsUnitInGroup(wallShadow, wallShadowGroup) then
//unhide wallShadow on u location, hide targeted wallShadow
call ShowUnit(wallShadowed[nr], true)
call ShowUnit(wallShadowed[newNr], false)
//set new PositionNumber to wall
set wallPositionNr[wallId] = newNr
//move and set angle
call SetUnitX(wall, GetUnitX(wallShadow))
call SetUnitY(wall, GetUnitY(wallShadow))
call SetUnitFacing(wall, wallFacing[wallShadowId])
if Walls_IsWallOnStartingLoc(newNr) then
set wallMovedIndicator[GetUnitUserData(wall)] = 0
//call SetUnitState(wall, UNIT_STATE_MANA, 0.00)
else // set mana==1 if moved to new position
//call SetUnitState(wall, UNIT_STATE_MANA, 1.00)
set wallMovedIndicator[GetUnitUserData(wall)] = 1
endif
set wallsMovedCounter = 0
//set wallsMana = 0 //check how many walls moved:
call ForGroup(wallGroup, function Walls_CheckManaEnum)
if wallsMovedCounter > moveableWalls then
call DisplayTextToPlayer(Player(0), 0,0,"Only " + I2S(moveableWalls) + " walls can be moved to new positions!")
call Walls_ResetWalls()
elseif Walls_CheckForVictory() then // check victory
call TriggerExecute(gg_trg_EngineerAward)
//clear
//call ForGroup(wallGroup, function Walls_RemoveUnitEnum)
//call GroupClear(wallGroup)
//call ForGroup(wallShadowGroup, function Walls_RemoveUnitEnum)
//call GroupClear(wallShadowGroup)
//next:
// call Z2_Prepare()
call DisableTrigger(GetTriggeringTrigger())
// call EnableTrigger(gg_trg_Z2order)
endif
endif
set wall=null
set wallShadow=null
return false
endfunction
//===========================================================================
function InitTrig_Z1order takes nothing returns nothing
set gg_trg_Z1order = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Z1order, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
call TriggerAddCondition( gg_trg_Z1order, Condition( function Z1orderCond ) )
endfunction
function SetEngineerLevers takes boolean invulner returns nothing
call SetDestructableInvulnerable(udg_EngineersLever[1], invulner)
call SetDestructableInvulnerable(udg_EngineersLever[2], invulner)
call SetDestructableInvulnerable(udg_EngineersLever[3], invulner)
call SetDestructableInvulnerable(udg_EngineersLever[4], invulner)
call SetDestructableInvulnerable(udg_EngineersLever[5], invulner)
call SetDestructableInvulnerable(udg_EngineersLever[6], invulner)
endfunction
function Trig_EngineersLeverDies takes nothing returns nothing
local destructable lever = GetDyingDestructable()
local integer i=1
call DisableTrigger(GetTriggeringTrigger())
//find dying lever
loop
exitwhen i>6
exitwhen lever==udg_EngineersLever[i]
set i=i+1
endloop
call SetEngineerLevers(true)
set udg_EngineerLeverChoosen = i
call Walls_CreateTask(i)
call BJDebugMsg(wallDescription[i])
call CreateQuestItemBJ( udg_engineerQuest, wallDescription[i] )
set lever=null
endfunction
function EngineerRegisterLevers takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerRegisterDeathEvent( t, udg_EngineersLever[1] )
call TriggerRegisterDeathEvent( t, udg_EngineersLever[2] )
call TriggerRegisterDeathEvent( t, udg_EngineersLever[3] )
call TriggerRegisterDeathEvent( t, udg_EngineersLever[4] )
call TriggerRegisterDeathEvent( t, udg_EngineersLever[5] )
call TriggerRegisterDeathEvent( t, udg_EngineersLever[6] )
call TriggerAddAction( t, function Trig_EngineersLeverDies )
endfunction
//===========================================================================
function InitTrig_Lever takes nothing returns nothing
set gg_trg_Lever = CreateTrigger( )
endfunction
function PointOnThePond takes real x, real y returns boolean
return x>3270.00 and x<3490.00 and y> -770.00 and y< -510.00
endfunction
globals
effect array water_effect
endglobals
function Trig_w1_Actions takes nothing returns nothing
local unit u = GetOrderedUnit()
local real x=GetOrderPointX()
local real y=GetOrderPointY()
local integer id=GetUnitUserData(u)
local real mana=GetUnitState(u, UNIT_STATE_MANA)
local real freeSpace = GetUnitState(u, UNIT_STATE_MAX_MANA) - mana
if PointOnThePond(x,y) then
if water_effect[id]==null then
set water_effect[id] = AddSpecialEffectTarget("war3mapImported\\MoonWellTarget60.mdx", u, "origin")
endif
if freeSpace>0.00 then
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\WaterElementalMissile\\WaterElementalMissile.mdx", x, y))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\WaterElementalMissile\\WaterElementalMissile.mdx", u, "origin"))
call PlaySoundOnUnitBJ( gg_snd_WaterElementalMissile1, 100, u)
endif
call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MAX_MANA))// to max
else
if GetUnitState(u, UNIT_STATE_MANA)>0.00 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\WaterElementalMissile\\WaterElementalMissile.mdl", u, "origin"))
call SetUnitState(u, UNIT_STATE_MANA, 0.00)
call DestroyEffect(water_effect[id])
set water_effect[id] = null
call PlaySoundOnUnitBJ( gg_snd_SummonWaterElementalCaster, 100, u)
endif
endif
set u=null
endfunction
//===========================================================================
function InitTrig_w1 takes nothing returns nothing
set gg_trg_w1 = CreateTrigger( )
call TriggerRegisterUnitEvent( gg_trg_w1, gg_unit_h003_0052, EVENT_UNIT_ISSUED_POINT_ORDER )
call TriggerRegisterUnitEvent( gg_trg_w1, gg_unit_h004_0053, EVENT_UNIT_ISSUED_POINT_ORDER )
call TriggerRegisterUnitEvent( gg_trg_w1, gg_unit_h005_0054, EVENT_UNIT_ISSUED_POINT_ORDER )
call TriggerAddAction( gg_trg_w1, function Trig_w1_Actions )
endfunction
function QuestWater_Enable takes nothing returns nothing
call SetUnitOwner(udg_waterBucket3, Player(0), false)
call SetUnitOwner(udg_waterBucket5, Player(0), false)
call SetUnitOwner(udg_waterBucket8, Player(0), false)
endfunction
function QuestWater_Block takes nothing returns nothing
call SetUnitOwner(udg_waterBucket3, Player(PLAYER_NEUTRAL_PASSIVE), false)
call SetUnitOwner(udg_waterBucket5, Player(PLAYER_NEUTRAL_PASSIVE), false)
call SetUnitOwner(udg_waterBucket8, Player(PLAYER_NEUTRAL_PASSIVE), false)
call SetUnitState(udg_waterBucket3, UNIT_STATE_MANA, 0.00)
call SetUnitState(udg_waterBucket5, UNIT_STATE_MANA, 0.00)
call SetUnitState(udg_waterBucket8, UNIT_STATE_MANA, 0.00)
call DestroyEffect(water_effect[GetUnitUserData(udg_waterBucket3)])
call DestroyEffect(water_effect[GetUnitUserData(udg_waterBucket5)])
call DestroyEffect(water_effect[GetUnitUserData(udg_waterBucket8)])
set water_effect[GetUnitUserData(udg_waterBucket3)]=null
set water_effect[GetUnitUserData(udg_waterBucket5)]=null
set water_effect[GetUnitUserData(udg_waterBucket8)]=null
endfunction
function BuckedTargeted takes nothing returns nothing
local unit t = GetOrderTargetUnit()
local unit u = GetOrderedUnit()
local integer id=GetUnitUserData(u)
local real mana=GetUnitState(u, UNIT_STATE_MANA)
local real freeSpace = GetUnitState(t, UNIT_STATE_MAX_MANA) - GetUnitState(t, UNIT_STATE_MANA)
local real amountTransfered = RMinBJ(freeSpace, mana)
call SetUnitState(u, UNIT_STATE_MANA, mana-amountTransfered)
call SetUnitState(t, UNIT_STATE_MANA, GetUnitState(t, UNIT_STATE_MANA)+amountTransfered)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\HealingSpray\\HealBottleMissile.mdl", u, "origin"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\HealingSpray\\HealBottleMissile.mdl", t, "origin"))
//target:
set id=GetUnitUserData(t)
if water_effect[id]==null then
set water_effect[id] = AddSpecialEffectTarget("war3mapImported\\MoonWellTarget60.mdx", t, "origin")
endif
//source:
if GetUnitState(u, UNIT_STATE_MANA)==0.00 then
set id=GetUnitUserData(u)
call DestroyEffect(water_effect[id])
set water_effect[id] = null
endif
set t=null
set u=null
endfunction
function Trig_w2_Conditions takes nothing returns boolean
local unit t = GetOrderTargetUnit()
if t != null and t != GetOrderedUnit() and GetUnitState(GetOrderedUnit(), UNIT_STATE_MANA)>0.00 then
if t==udg_waterPriest then
set t=null
return true //run trigger action for priest
elseif t==udg_waterBucket3 or t==udg_waterBucket5 or t==udg_waterBucket8 then
if GetUnitState(t, UNIT_STATE_MAX_MANA) - GetUnitState(t, UNIT_STATE_MANA) > 0.00 then
call BuckedTargeted()
endif
endif
endif
set t=null
return false
endfunction
function Trig_w2_Actions takes nothing returns nothing
local unit t = GetOrderTargetUnit()
local unit u = GetOrderedUnit()
local integer id=GetUnitUserData(u)
local real mana=GetUnitState(u, UNIT_STATE_MANA)
call SetUnitState(u, UNIT_STATE_MANA, 0.00)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\HealingSpray\\HealBottleMissile.mdl", u, "origin"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\HealingSpray\\HealBottleMissile.mdl", t, "origin"))
call DestroyEffect(water_effect[id])
set water_effect[id] = null
if mana==4.00 then
//WATER QUEST COMPLETED
call TriggerExecute(gg_trg_waterAward)
endif
endfunction
//===========================================================================
function InitTrig_w2 takes nothing returns nothing
set gg_trg_w2 = CreateTrigger( )
call TriggerRegisterUnitEvent( gg_trg_w2, gg_unit_h003_0052, EVENT_UNIT_ISSUED_TARGET_ORDER )
call TriggerRegisterUnitEvent( gg_trg_w2, gg_unit_h004_0053, EVENT_UNIT_ISSUED_TARGET_ORDER )
call TriggerRegisterUnitEvent( gg_trg_w2, gg_unit_h005_0054, EVENT_UNIT_ISSUED_TARGET_ORDER )
call TriggerAddCondition( gg_trg_w2, Condition( function Trig_w2_Conditions ) )
call TriggerAddAction( gg_trg_w2, function Trig_w2_Actions )
endfunction
function CountTheSame takes string s returns string
local integer i=1
local string newString=""
local integer count=0
local string a=""
loop
exitwhen i > StringLength(s)
set count = 0
set a = SubStringBJ(s, i, i)
loop
exitwhen SubStringBJ(s, i, i) != a
set i=i+1
set count=count+1
endloop
set newString = newString + I2S(count) + a
endloop
return newString
endfunction
function ExpandDigit takes integer i returns string
local string s = CountTheSame(I2S(i))
set s = CountTheSame(s)
set s = CountTheSame(s)
set s = CountTheSame(s)
return s
endfunction
function DigitsTest takes string s returns nothing
local string s1 = ""
local string s2 = ""
local string s3 = ""
local string s4 = ""
call BJDebugMsg(s)
set s1 = CountTheSame(s)
call BJDebugMsg(s1)
set s2 = CountTheSame(s1)
call BJDebugMsg(s2)
set s3 = CountTheSame(s2)
call BJDebugMsg(s3)
set s4 = CountTheSame(s3)
call BJDebugMsg(s4)
endfunction
//-------------------------------------------------------------
//-------------------------------------------------------------
function SetMedivhLevers takes boolean invulner returns nothing
local integer i=1
loop
exitwhen i>9
call SetDestructableInvulnerable(udg_DigitLever[i], invulner)
set i=i+1
endloop
endfunction
function Trig_MedivhLeverDies takes nothing returns nothing
local destructable lever = GetDyingDestructable()
local integer i=1
call DisableTrigger(GetTriggeringTrigger())
//find dying lever
loop
exitwhen i>9
exitwhen lever==udg_DigitLever[i]
set i=i+1
endloop
call SetMedivhLevers(true)
if udg_DigitWin == i then
call TriggerExecute(gg_trg_MedivhAward)
else
call QuestMessageBJ( GetPlayersAll(), bj_QUESTMESSAGE_FAILED, "|cffffff00Medivh Quest Failed!|r Wrong lever." )
call QuestSetFailedBJ( udg_medivhQuest, true )
endif
set lever=null
endfunction
function MedivhRegisterLevers takes nothing returns nothing
local trigger t=CreateTrigger()
local integer i=1
loop
exitwhen i>9
call TriggerRegisterDeathEvent( t, udg_DigitLever[i] )
set i=i+1
endloop
call TriggerAddAction( t, function Trig_MedivhLeverDies )
endfunction
function MedivhSetCode takes nothing returns nothing
local string s = ExpandDigit(udg_DigitWin)
call CreateQuestItemBJ( udg_medivhQuest, "The code: " + s )
call BlzSetUnitName(udg_DigitObelisk, s)
endfunction
//===========================================================================
function InitTrig_DigitsFunc takes nothing returns nothing
set gg_trg_DigitsFunc = CreateTrigger( )
endfunction
globals
integer QWispAwardArmor = 0
integer QWispAwardDamage = 0
boolean tyrandeRescuable=false
// TYRANDE: gg_unit_Etyr_0225
endglobals
// on award item pick-up ------------------------------------
function Trig_OnWispAwardItemPickUp_Cond takes nothing returns boolean
return GetManipulatedItem() == udg_QWispAwardItem
endfunction
function Trig_OnWispAwardItemPickUp_Act takes nothing returns nothing
//remove all abi
call BlzItemRemoveAbilityBJ(udg_QWispAwardItem, 'AId1')
call BlzItemRemoveAbilityBJ(udg_QWispAwardItem, 'AItg')
call BlzItemRemoveAbilityBJ(udg_QWispAwardItem, 'AId2')
call BlzItemRemoveAbilityBJ(udg_QWispAwardItem, 'AItj')
call BlzItemRemoveAbilityBJ(udg_QWispAwardItem, 'AId3')
call BlzItemRemoveAbilityBJ(udg_QWispAwardItem, 'AItl')
call BlzItemRemoveAbilityBJ(udg_QWispAwardItem, 'AId5')
call BlzItemRemoveAbilityBJ(udg_QWispAwardItem, 'AItx')
call BlzItemAddAbilityBJ(udg_QWispAwardItem, QWispAwardArmor)
call BlzItemAddAbilityBJ(udg_QWispAwardItem, QWispAwardDamage)
endfunction
//===========================================================================
function WispSetAwardValues takes nothing returns nothing
local integer lvl=udg_QWispActivated
local integer heroLevel = GetHeroLevel(gg_unit_Etyr_0225)
local integer newHeroLevel=1
//level I (1..6)
//level II (7..10)
//level III (11)
//level IV (12)
if lvl>0 and lvl<7 then
set QWispAwardArmor = 'AId1' //armor 1
set QWispAwardDamage = 'AItg' // damage 1
set newHeroLevel = 1 //for Tyrande
elseif lvl<11 then
set QWispAwardArmor = 'AId2' //armor 2
set QWispAwardDamage = 'AItj' // damage 5
set newHeroLevel = 4 //for Tyrande
elseif lvl==11 then
set QWispAwardArmor = 'AId3' //armor 3
set QWispAwardDamage = 'AItl' // damage 8
set newHeroLevel = 5 //for Tyrande
elseif lvl==12 then
set QWispAwardArmor = 'AId5' //armor 5
set QWispAwardDamage = 'AItx' // damage 20
set newHeroLevel = 6 //for Tyrande
endif
call Trig_OnWispAwardItemPickUp_Act()
//Tyrande:
set tyrandeRescuable = true
if GetOwningPlayer(gg_unit_Etyr_0225)==Player(PLAYER_NEUTRAL_PASSIVE) and (newHeroLevel > heroLevel) then
call SetHeroLevel(gg_unit_Etyr_0225, newHeroLevel, false)
endif
endfunction
// the best result player has
function WispCheckActivated takes integer wispBuildingNo returns nothing
local integer i=1
local integer count=0
local real x = GetUnitX(udg_QWispBuilding[wispBuildingNo])
local real y = GetUnitY(udg_QWispBuilding[wispBuildingNo])
local string eff = "Doodads\\Cinematic\\Lightningbolt\\Lightningbolt.mdx"
call ShowUnit(udg_QWispBuilding[wispBuildingNo], true)
//effects..
call AddTimedEffect(x, y, 1.00, eff)
//count currently activated wisps:
loop
exitwhen i>12
if not IsUnitHidden(udg_QWispBuilding[i]) then
set count=count+1
endif
set i=i+1
endloop
if count > udg_QWispActivated then
set udg_QWispActivated = count
call BlzSetUnitName(udg_QWispDruid, "Druid (" + I2S(count) + ")")
endif
call WispSetAwardValues()
endfunction
//--------------------- 1 ----------------------------------
function Trig_wisp_11 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==12 and IsUnitHidden(udg_QWispBuilding[1]) then
call WispCheckActivated(1)
endif
set udg_QWispNo = 11
endif
return false
endfunction
function Trig_wisp_12 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==11 and IsUnitHidden(udg_QWispBuilding[1]) then
call WispCheckActivated(1)
endif
set udg_QWispNo = 12
endif
return false
endfunction
//---------------------- 2 ---------------------------------
function Trig_wisp_21 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==22 and IsUnitHidden(udg_QWispBuilding[2]) then
call WispCheckActivated(2)
endif
set udg_QWispNo = 21
endif
return false
endfunction
function Trig_wisp_22 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==21 and IsUnitHidden(udg_QWispBuilding[2]) then
call WispCheckActivated(2)
endif
set udg_QWispNo = 22
endif
return false
endfunction
//---------------------- 3 ---------------------------------
function Trig_wisp_31 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==32 and IsUnitHidden(udg_QWispBuilding[3]) then
call WispCheckActivated(3)
endif
set udg_QWispNo = 31
endif
return false
endfunction
function Trig_wisp_32 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==31 and IsUnitHidden(udg_QWispBuilding[3]) then
call WispCheckActivated(3)
endif
set udg_QWispNo = 32
endif
return false
endfunction
//---------------------- 4 ---------------------------------
function Trig_wisp_41 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==42 and IsUnitHidden(udg_QWispBuilding[4]) then
call WispCheckActivated(4)
endif
set udg_QWispNo = 41
endif
return false
endfunction
function Trig_wisp_42 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==41 and IsUnitHidden(udg_QWispBuilding[4]) then
call WispCheckActivated(4)
endif
set udg_QWispNo = 42
endif
return false
endfunction
//---------------------- 5 ---------------------------------
function Trig_wisp_51 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==52 and IsUnitHidden(udg_QWispBuilding[5]) then
call WispCheckActivated(5)
endif
set udg_QWispNo = 51
endif
return false
endfunction
function Trig_wisp_52 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==51 and IsUnitHidden(udg_QWispBuilding[5]) then
call WispCheckActivated(5)
endif
set udg_QWispNo = 52
endif
return false
endfunction
//---------------------- 6 ---------------------------------
function Trig_wisp_61 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==62 and IsUnitHidden(udg_QWispBuilding[6]) then
call WispCheckActivated(6)
endif
set udg_QWispNo = 61
endif
return false
endfunction
function Trig_wisp_62 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==61 and IsUnitHidden(udg_QWispBuilding[6]) then
call WispCheckActivated(6)
endif
set udg_QWispNo = 62
endif
return false
endfunction
//---------------------- 7 ---------------------------------
function Trig_wisp_71 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==72 and IsUnitHidden(udg_QWispBuilding[7]) then
call WispCheckActivated(7)
endif
set udg_QWispNo = 71
endif
return false
endfunction
function Trig_wisp_72 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==71 and IsUnitHidden(udg_QWispBuilding[7]) then
call WispCheckActivated(7)
endif
set udg_QWispNo = 72
endif
return false
endfunction
//---------------------- 8 ---------------------------------
function Trig_wisp_81 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==82 and IsUnitHidden(udg_QWispBuilding[8]) then
call WispCheckActivated(8)
endif
set udg_QWispNo = 81
endif
return false
endfunction
function Trig_wisp_82 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==81 and IsUnitHidden(udg_QWispBuilding[8]) then
call WispCheckActivated(8)
endif
set udg_QWispNo = 82
endif
return false
endfunction
//---------------------- 9 ---------------------------------
function Trig_wisp_91 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==92 and IsUnitHidden(udg_QWispBuilding[9]) then
call WispCheckActivated(9)
endif
set udg_QWispNo = 91
endif
return false
endfunction
function Trig_wisp_92 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==91 and IsUnitHidden(udg_QWispBuilding[9]) then
call WispCheckActivated(9)
endif
set udg_QWispNo = 92
endif
return false
endfunction
//---------------------- 10 ---------------------------------
function Trig_wisp_101 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==102 and IsUnitHidden(udg_QWispBuilding[10]) then
call WispCheckActivated(10)
endif
set udg_QWispNo = 101
endif
return false
endfunction
function Trig_wisp_102 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==101 and IsUnitHidden(udg_QWispBuilding[10]) then
call WispCheckActivated(10)
endif
set udg_QWispNo = 102
endif
return false
endfunction
//---------------------- 11 ---------------------------------
function Trig_wisp_111 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==112 and IsUnitHidden(udg_QWispBuilding[11]) then
call WispCheckActivated(11)
endif
set udg_QWispNo = 111
endif
return false
endfunction
function Trig_wisp_112 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==111 and IsUnitHidden(udg_QWispBuilding[11]) then
call WispCheckActivated(11)
endif
set udg_QWispNo = 112
endif
return false
endfunction
//---------------------- 12 ---------------------------------
function Trig_wisp_121 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==122 and IsUnitHidden(udg_QWispBuilding[12]) then
call WispCheckActivated(12)
endif
set udg_QWispNo = 121
endif
return false
endfunction
function Trig_wisp_122 takes nothing returns boolean
if GetTriggerUnit() == udg_QWispDruid then
if udg_QWispNo==121 and IsUnitHidden(udg_QWispBuilding[12]) then
call WispCheckActivated(12)
endif
set udg_QWispNo = 122
endif
return false
endfunction
//-------------------------------------------------------
//-------------------------------------------------------
//-------------------------------------------------------
function WispQuestReset takes nothing returns nothing
local integer i=1
call SetUnitPosition(udg_QWispDruid, -2960.00, -5760.00)
set udg_QWispNo = 0
loop // hide wisp-buildings
exitwhen i>12
call ShowUnit(udg_QWispBuilding[i], false)
set i=i+1
endloop
endfunction
//-------------------------------------------------------
function WispQuestInit takes nothing returns nothing
local trigger t=null
local integer i=1
local string s=""
//set colors and hide wisp-buildings
loop
exitwhen i>12
call SetUnitColor(udg_QWispBuilding[i], PLAYER_COLOR_RED)
call ShowUnit(udg_QWispBuilding[i], false)
set i=i+1
endloop
//hide childs
set i=1
loop
exitwhen i>12
set s=I2S(i) + "1"
call ShowUnit(udg_QWispChild[S2I(s)], false)
set s=I2S(i) + "2"
call ShowUnit(udg_QWispChild[S2I(s)], false)
set i=i+1
endloop
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_PICKUP_ITEM)
call TriggerAddCondition(t, Condition(function Trig_OnWispAwardItemPickUp_Cond))
call TriggerAddAction(t, function Trig_OnWispAwardItemPickUp_Act)
// create triggers
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[11])
call TriggerAddCondition(t, Condition(function Trig_wisp_11))
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[12])
call TriggerAddCondition(t, Condition(function Trig_wisp_12))
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[21])
call TriggerAddCondition(t, Condition(function Trig_wisp_21))
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[22])
call TriggerAddCondition(t, Condition(function Trig_wisp_22))
set t=CreateTrigger() //3
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[31])
call TriggerAddCondition(t, Condition(function Trig_wisp_31))
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[32])
call TriggerAddCondition(t, Condition(function Trig_wisp_32))
set t=CreateTrigger() //4
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[41])
call TriggerAddCondition(t, Condition(function Trig_wisp_41))
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[42])
call TriggerAddCondition(t, Condition(function Trig_wisp_42))
set t=CreateTrigger() //5
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[51])
call TriggerAddCondition(t, Condition(function Trig_wisp_51))
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[52])
call TriggerAddCondition(t, Condition(function Trig_wisp_52))
set t=CreateTrigger() //6
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[61])
call TriggerAddCondition(t, Condition(function Trig_wisp_61))
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[62])
call TriggerAddCondition(t, Condition(function Trig_wisp_62))
set t=CreateTrigger() //7
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[71])
call TriggerAddCondition(t, Condition(function Trig_wisp_71))
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[72])
call TriggerAddCondition(t, Condition(function Trig_wisp_72))
set t=CreateTrigger() //8
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[81])
call TriggerAddCondition(t, Condition(function Trig_wisp_81))
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[82])
call TriggerAddCondition(t, Condition(function Trig_wisp_82))
set t=CreateTrigger() //9
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[91])
call TriggerAddCondition(t, Condition(function Trig_wisp_91))
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[92])
call TriggerAddCondition(t, Condition(function Trig_wisp_92))
set t=CreateTrigger() //10
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[101])
call TriggerAddCondition(t, Condition(function Trig_wisp_101))
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[102])
call TriggerAddCondition(t, Condition(function Trig_wisp_102))
set t=CreateTrigger() //11
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[111])
call TriggerAddCondition(t, Condition(function Trig_wisp_111))
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[112])
call TriggerAddCondition(t, Condition(function Trig_wisp_112))
set t=CreateTrigger() //12
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[121])
call TriggerAddCondition(t, Condition(function Trig_wisp_121))
set t=CreateTrigger()
call TriggerRegisterUnitInRangeSimple(t, 32.00, udg_QWispChild[122])
call TriggerAddCondition(t, Condition(function Trig_wisp_122))
endfunction
//===========================================================================
function InitTrig_WispF takes nothing returns nothing
endfunction
//
// TYRANDE: gg_unit_Etyr_0225
// set tyrandeRescuable = true
//if GetOwningPlayer(gg_unit_Etyr_0225)==Player(PLAYER_NEUTRAL_PASSIVE)
function Trig_WispTyrande_Conditions takes nothing returns boolean
return (GetTriggerUnit() == udg_hero) and tyrandeRescuable
endfunction
function TakeTyrande takes unit tyrande returns nothing
local string eff = "Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl"
local string s="|cff808000Tyrande|r: I can help you."
call AddTimedEffect(GetUnitX(tyrande), GetUnitY(tyrande), 3.00, eff)
call TriggerSleepAction(3.00)
call ShowUnit(tyrande, true)
call SetUnitOwner(tyrande, Player(0), true)
call DisplayTextToPlayer(GetLocalPlayer(), 0.00, 0.00, s)
call PlaySoundBJ( gg_snd_Rescue )
endfunction
function Trig_WispTyrande_Actions takes nothing returns nothing
local unit tyrande = gg_unit_Etyr_0225
local unit arius = udg_hero
local unit circle = gg_unit_ncop_0104
local real face = 0.00
local integer c=0
local boolean array b
local boolean takeTyrande=false
local real x=0.00
local real y=0.00
call DisableTrigger(GetTriggeringTrigger())
loop //main
//inner loop start
set c=0
loop
set face=GetUnitFacing(arius)
set b[1] = IsUnitInRange(arius, circle, 50.00)
set b[2] = (face>150.00) and (face<215.00)
set b[3] = (x==GetUnitX(arius)) and (y==GetUnitY(arius))
if b[1] and b[2] and b[3] then
set c=c+1
else
exitwhen true
endif
if c==10 then
set takeTyrande = true
exitwhen true
endif
call TriggerSleepAction(0.50)
endloop
//inner loop end
if takeTyrande then
call TakeTyrande(tyrande)
exitwhen true //exit main loop
endif
set x=GetUnitX(arius)
set y=GetUnitY(arius)
exitwhen not IsUnitInRange(arius, circle, 350.00)
call TriggerSleepAction(1.00)
endloop//main end
//Arius go away
if not takeTyrande then
call EnableTrigger(GetTriggeringTrigger())
endif
set arius=null
set tyrande=null
set circle=null
endfunction
//===========================================================================
function InitTrig_WispTyrande takes nothing returns nothing
set gg_trg_WispTyrande = CreateTrigger( )
call TriggerRegisterUnitInRangeSimple( gg_trg_WispTyrande, 256.00, gg_unit_ncop_0104 )
call TriggerAddCondition( gg_trg_WispTyrande, Condition( function Trig_WispTyrande_Conditions ) )
call TriggerAddAction( gg_trg_WispTyrande, function Trig_WispTyrande_Actions )
endfunction