Name | Type | is_array | initial_value |
BUS_Loc | location | No | |
BUS_MapMaxX | real | No | |
BUS_MapMaxY | real | No | |
BUS_MapMinX | real | No | |
BUS_MapMinY | real | No | |
BUS_Target | unit | No | |
BUS_Unit | unit | No | |
BUS_X | real | No | |
BUS_Y | real | No | |
BUSC_Ability | real | Yes | |
BUSC_Cancel | boolean | Yes | |
BUSC_CChangeHueDelay | real | Yes | |
BUSC_CDelay | real | Yes | |
BUSC_CDuration | real | Yes | |
BUSC_ChangeHueDelay | real | Yes | |
BUSC_ChannelId | integer | Yes | |
BUSC_CHueAlpha | integer | Yes | |
BUSC_CHueBlue | integer | Yes | |
BUSC_CHueGreen | integer | Yes | |
BUSC_CHueRed | integer | Yes | |
BUSC_Delay | real | Yes | |
BUSC_Event | real | No | |
BUSC_HueChange | boolean | Yes | |
BUSC_HueChangeAlpha | integer | Yes | |
BUSC_HueChangeBlue | integer | Yes | |
BUSC_HueChangeGreen | integer | Yes | |
BUSC_HueChangeRed | integer | Yes | |
BUSC_NextNode | integer | Yes | |
BUSC_NodeNumber | integer | No | |
BUSC_Order | ordercode | Yes | |
BUSC_PCaster | unit | Yes | |
BUSC_PCurrentEffect | effect | Yes | |
BUSC_PCurrentZ | real | Yes | |
BUSC_PNextNode | integer | Yes | |
BUSC_PNodeNumber | integer | No | |
BUSC_PPrevNode | integer | Yes | |
BUSC_PRecyclableNodes | integer | No | |
BUSC_PRecycleNodes | integer | Yes | |
BUSC_PrevNode | integer | Yes | |
BUSC_PUnit | unit | Yes | |
BUSC_PXVelocity | real | Yes | |
BUSC_PYVelocity | real | Yes | |
BUSC_PZVelocity | real | Yes | |
BUSC_RecyclableNodes | integer | No | |
BUSC_RecycleNodes | integer | Yes | |
BUSC_Running | boolean | Yes | |
BUSC_Target | unit | Yes | |
BUSC_TargetX | real | Yes | |
BUSC_TargetY | real | Yes | |
BUSC_Timer | timer | No | |
BUSC_Unit | unit | Yes | |
BUSCR_AbsorbAOE | real | Yes | |
BUSCR_Counter | integer | No | 5 |
BUSCR_Effect | string | Yes | |
BUSCR_HueAlpha | real | Yes | |
BUSCR_HueBlue | real | Yes | |
BUSCR_HueGreen | real | Yes | |
BUSCR_HueRed | real | Yes | |
BUSCR_HueSpeed | real | Yes | |
BUSCR_MaxAOE | real | Yes | |
BUSCR_MaxSize | real | Yes | |
BUSCR_MinAOE | real | Yes | |
BUSCR_MinSize | real | Yes | |
BUSCR_Name | string | Yes | |
BUSCR_Power | real | Yes | |
BUSCR_SpawnCount | integer | Yes | |
BUSCR_SpawnRate | real | Yes | |
CP_HiddenItems | item | Yes | |
CP_HiddenItemsIndex | integer | No | |
CP_Item | item | No | |
CP_Point | location | No | |
CP_PointIsWalkable | boolean | No | |
CP_Rect | rect | No | |
MainUnit | unit | Yes | |
TempInt | integervar | No | |
TempLoc | location | No | |
TmpGroup | group | No |
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=852586
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 //?
endglobals
endlibrary
library Ascii
///////////////////////////////////////////////////////////////////
// function Char2Ascii takes string s returns integer
// integer ascii = Char2Ascii("F")
//
// function Ascii2Char takes integer a returns string
// string char = Ascii2Char('F')
//
// function A2S takes integer a returns string
// string rawcode = A2S('CODE')
//
// function S2A takes string s returns integer
// integer rawcode = S2A("CODE")
//
///////////////////////////////////////////////////////////////////
globals
private integer array i //hash
private string array c //char
endglobals
function Char2Ascii takes string s returns integer
local integer a
if ("\\"==s) then
return 92
endif
set a=i[StringHash(s)/0x1F0748+0x3EA]
if (s!=c[a]) then
debug if (0==a) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"ASCII ERROR: INVALID CHARACTER")
debug return 0
debug endif
return a+32
endif
return a
endfunction
function Ascii2Char takes integer a returns string
return c[a]
endfunction
function A2S takes integer a returns string
local string s=""
loop
set s=c[a-a/256*256]+s
set a=a/256
exitwhen 0==a
endloop
return s
endfunction
function S2A takes string s returns integer
local integer a=0
local integer l=StringLength(s)
local integer j=0
local string m
local integer h
loop
exitwhen j==l
set m=SubString(s,j,j+1)
if ("\\"==m) then
set a=a*256+92
else
set h=i[StringHash(m)/0x1F0748+0x3EA]
if (m!=c[h]) then
debug if (0==h) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"ASCII ERROR: INVALID CHARACTER")
debug return 0
debug endif
set a=a*256+h+32
else
set a=a*256+h
endif
endif
set j=j+1
endloop
return a
endfunction
private module Init
private static method onInit takes nothing returns nothing
set i[931]=8
set i[1075]=9
set i[1586]=10
set i[1340]=12
set i[412]=13
set i[198]=32
set i[1979]=33
set i[1313]=34
set i[1003]=35
set i[1264]=36
set i[983]=37
set i[1277]=38
set i[306]=39
set i[904]=40
set i[934]=41
set i[917]=42
set i[1972]=43
set i[1380]=44
set i[1985]=45
set i[869]=46
set i[1906]=47
set i[883]=48
set i[1558]=49
set i[684]=50
set i[582]=51
set i[668]=52
set i[538]=53
set i[672]=54
set i[1173]=55
set i[71]=56
set i[277]=57
set i[89]=58
set i[1141]=59
set i[39]=60
set i[1171]=61
set i[51]=62
set i[305]=63
set i[0]=64
set i[222]=65
set i[178]=66
set i[236] =67
set i[184]=68
set i[1295]=69
set i[1390]=70
set i[1276]=71
set i[203]=72
set i[1314]=73
set i[209]=74
set i[1315]=75
set i[170]=76
set i[1357]=77
set i[1343]=78
set i[1397]=79
set i[1420]=80
set i[1419]=81
set i[1396]=82
set i[1374]=83
set i[1407]=84
set i[499]=85
set i[1465]=86
set i[736]=87
set i[289]=88
set i[986]=89
set i[38]=90
set i[1230]=91
set i[1636]=93
set i[1416]=94
set i[1917]=95
set i[217]=96
set i[833]=123
set i[1219]=124
set i[553]=125
set i[58]=126
set c[8]="\b"
set c[9]="\t"
set c[10]="\n"
set c[12]="\f"
set c[13]="\r"
set c[32]=" "
set c[33]="!"
set c[34]="\""
set c[35]="#"
set c[36]="$"
set c[37]="%"
set c[38]="&"
set c[39]="'"
set c[40]="("
set c[41]=")"
set c[42]="*"
set c[43]="+"
set c[44]=","
set c[45]="-"
set c[46]="."
set c[47]="/"
set c[48]="0"
set c[49]="1"
set c[50]="2"
set c[51]="3"
set c[52]="4"
set c[53]="5"
set c[54]="6"
set c[55]="7"
set c[56]="8"
set c[57]="9"
set c[58]=":"
set c[59]=";"
set c[60]="<"
set c[61]="="
set c[62]=">"
set c[63]="?"
set c[64]="@"
set c[65]="A"
set c[66]="B"
set c[67]="C"
set c[68]="D"
set c[69]="E"
set c[70]="F"
set c[71]="G"
set c[72]="H"
set c[73]="I"
set c[74]="J"
set c[75]="K"
set c[76]="L"
set c[77]="M"
set c[78]="N"
set c[79]="O"
set c[80]="P"
set c[81]="Q"
set c[82]="R"
set c[83]="S"
set c[84]="T"
set c[85]="U"
set c[86]="V"
set c[87]="W"
set c[88]="X"
set c[89]="Y"
set c[90]="Z"
set c[92]="\\"
set c[97]="a"
set c[98]="b"
set c[99]="c"
set c[100]="d"
set c[101]="e"
set c[102]="f"
set c[103]="g"
set c[104]="h"
set c[105]="i"
set c[106]="j"
set c[107]="k"
set c[108]="l"
set c[109]="m"
set c[110]="n"
set c[111]="o"
set c[112]="p"
set c[113]="q"
set c[114]="r"
set c[115]="s"
set c[116]="t"
set c[117]="u"
set c[118]="v"
set c[119]="w"
set c[120]="x"
set c[121]="y"
set c[122]="z"
set c[91]="["
set c[93]="]"
set c[94]="^"
set c[95]="_"
set c[96]="`"
set c[123]="{"
set c[124]="|"
set c[125]="}"
set c[126]="~"
endmethod
endmodule
private struct Inits extends array
implement Init
endstruct
endlibrary
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~ Alloc ~~ By Sevion ~~ Version 1.09 ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// What is Alloc?
// - Alloc implements an intuitive allocation method for array structs
//
// =Pros=
// - Efficient.
// - Simple.
// - Less overhead than regular structs.
//
// =Cons=
// - Must use array structs (hardly a con).
// - Must manually call OnDestroy.
// - Must use Delegates for inheritance.
// - No default values for variables (use onInit instead).
// - No array members (use another Alloc struct as a linked list or type declaration).
//
// Methods:
// - struct.allocate()
// - struct.deallocate()
//
// These methods are used just as they should be used in regular structs.
//
// Modules:
// - Alloc
// Implements the most basic form of Alloc. Includes only create and destroy
// methods.
//
// Details:
// - Less overhead than regular structs
//
// - Use array structs when using Alloc. Put the implement at the top of the struct.
//
// - Alloc operates almost exactly the same as default structs in debug mode with the exception of onDestroy.
//
// How to import:
// - Create a trigger named Alloc.
// - Convert it to custom text and replace the whole trigger text with this.
//
// Thanks:
// - Nestharus for the method of allocation and suggestions on further merging.
// - Bribe for suggestions like the static if and method names.
// - PurgeandFire111 for some suggestions like the merging of Alloc and AllocX as well as OnDestroy stuff.
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library Alloc
module Alloc
private static integer instanceCount = 0
private thistype recycle
static method allocate takes nothing returns thistype
local thistype this
if (thistype(0).recycle == 0) then
debug if (instanceCount == 8190) then
debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Alloc ERROR: Attempted to allocate too many instances!")
debug return 0
debug endif
set instanceCount = instanceCount + 1
set this = instanceCount
else
set this = thistype(0).recycle
set thistype(0).recycle = thistype(0).recycle.recycle
endif
debug set this.recycle = -1
return this
endmethod
method deallocate takes nothing returns nothing
debug if (this.recycle != -1) then
debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Alloc ERROR: Attempted to deallocate an invalid instance at [" + I2S(this) + "]!")
debug return
debug endif
set this.recycle = thistype(0).recycle
set thistype(0).recycle = this
endmethod
endmodule
endlibrary
library BJObjectId // 1.0
//! novjass
// creating:
// from native object-id / integer
set oid = BJObjectId('A000')
// from string
set oid = BJObjectId.from_str("I001")
// printing:
call BJDebugMsg(oid.to_str())
// looping through a set of object-id(s)
// forward
local BJObjectId oid = BJObjectId('A000')
local BJObjectId last_oid = BJObjectId('A010')
loop
exitwhen oid > last_oid
// do stuff
set oid = oid.plus_1()
endloop
// backward
local BJObjectId oid = BJObjectId('A010')
local BJObjectId last_oid = BJObjectId('A000')
loop
exitwhen oid < last_oid
// do stuff
set oid = oid.minus_1()
endloop
// mapping BJObjectId(s) to array-indices / struct instances
local integer index
local MyStruct my_struct
set index = BJObjectId('H000').to_unit_index()
set my_struct = MyStruct( BJObjectId('h001').to_unit_index() )
set index = BJObjectId('I000').to_item_index()
set my_struct = BJObjectId('I001').to_item_index() // don't really need the MyStruct cast (because vJass =))
set index = BJObjectId('B000').to_destructable_index()
set my_struct = BJObjectId('B001').to_destructable_index()
set index = BJObjectId('D000').to_doodad_index()
set my_struct = BJObjectId('D001').to_doodad_index()
set index = BJObjectId('A000').to_ability_index()
set my_struct = BJObjectId('A001').to_ability_index()
set index = BJObjectId('B000').to_buff_index()
set my_struct = BJObjectId('B001').to_buff_index()
set index = BJObjectId('R000').to_upgrade_index()
set my_struct = BJObjectId('R001').to_upgrade_index()
// for campaign objects the methods have a "c" after the "to_"
set index = BJObjectId('A000').to_cunit_index()
set index = BJObjectId('A000').to_cability_index()
...
// NOTE: the to_*_index methods break for object-id(s) > 'XXOZ', i.e
// 900 is the maximum number of objects you can have and still be able to use those methods;
// the reason is that the object-id(s) after 'XXOZ' have indices > 8190
//! endnovjass
struct BJObjectId extends array
static method from_str takes string oid returns thistype
// '0' = 48 .. '9' = 57,
// 'A' = 65 .. 'Z' = 90
// 'a' = 97 .. 'z' = 122
//
// index(<chr>):
// '0' = 0; chr(0 + 48) = '0' = 48
// 'A' = 17; chr(17 + 48) = 'A' = 65
// 'a' = 49; chr(49 + 48) = 'a' = 97
//
local string chars = "0123456789.......ABCDEFGHIJKLMNOPQRSTUVWXYZ......abcdefghijklmnopqrstuvwxyz"
local integer this = 0
local integer i
local integer j
local integer ordinal
local string chr
local integer pow_256 = 1
set i = 3
loop
exitwhen i < 0
set chr = SubString(oid, i, i + 1)
set j = 0
loop
exitwhen j >= 75
if chr == SubString(chars, j, j + 1) then
set this = this + (j + 48) * pow_256
set pow_256 = pow_256 * 256
exitwhen true
endif
set j = j + 1
endloop
set i = i - 1
endloop
return this
endmethod
method to_str takes nothing returns string
local string chars = "0123456789.......ABCDEFGHIJKLMNOPQRSTUVWXYZ......abcdefghijklmnopqrstuvwxyz"
local integer t = this
local integer i
local integer b
local string result = ""
set i = t
set t = i / 0x100
set b = i - t * 0x100 - 48
set result = SubString(chars, b, b + 1) + result
set i = t
set t = i / 0x100
set b = i - t * 0x100 - 48
set result = SubString(chars, b, b + 1) + result
set i = t
set t = i / 0x100
set b = i - t * 0x100 - 48
set result = SubString(chars, b, b + 1) + result
set t = t - 48
set result = SubString(chars, t, t + 1) + result
return result
endmethod
method plus_1 takes nothing returns thistype
local integer t = this
local integer i
local integer b1
local integer b2
local integer b3
local integer b4
set i = t
set t = i / 0x100
set b4 = i - t * 0x100
if b4 < 'Z' then
if b4 != '9' then
set i = i + 1
else
set i = i + 8
endif
else
set i = t
set t = i / 0x100
set b3 = i - t * 0x100
if b3 < 'Z' then
if b3 != '9' then
set i = i * 0x00000100 + 0x00000100 + '0'
else
set i = i * 0x00000100 + 0x00000800 + '0'
endif
else
set i = t
set t = i / 0x100
set b2 = i - t * 0x100
if b2 < 'Z' then
if b2 != '9' then
set i = i * 0x00010000 + 0x00010000 + '0' * 0x00000100 + '0'
else
set i = i * 0x00010000 + 0x00080000 + '0' * 0x00000100 + '0'
endif
else
set i = t
if i != '9' then
set i = i * 0x01000000 + 0x01000000 + '0' * 0x00010000 + '0' * 0x00000100 + '0'
else
set i = i * 0x01000000 + 0x08000000 + '0' * 0x00010000 + '0' * 0x00000100 + '0'
endif
endif
endif
endif
return i
endmethod
method minus_1 takes nothing returns thistype
local integer t = this
local integer i
local integer b1
local integer b2
local integer b3
local integer b4
set i = t
set t = i / 0x100
set b4 = i - t * 0x100
if b4 > '0' then
if b4 != 'A' then
set i = i - 1
else
set i = i - 8
endif
else
set i = t
set t = i / 0x100
set b3 = i - t * 0x100
if b3 > '0' then
if b3 != 'A' then
set i = i * 0x00000100 - 0x00000100 + 'Z'
else
set i = i * 0x00000100 - 0x00000800 + 'Z'
endif
else
set i = t
set t = i / 0x100
set b2 = i - t * 0x100
if b2 > '0' then
if b2 != 'A' then
set i = i * 0x00010000 - 0x00010000 + 'Z' * 0x00000100 + 'Z'
else
set i = i * 0x00010000 - 0x00080000 + 'Z' * 0x00000100 + 'Z'
endif
else
set i = t
if i != 'A' then
set i = i * 0x01000000 - 0x01000000 + 'Z' * 0x00010000 + 'Z' * 0x00000100 + 'Z'
else
set i = i * 0x01000000 - 0x08000000 + 'Z' * 0x00010000 + 'Z' * 0x00000100 + 'Z'
endif
endif
endif
endif
return i
endmethod
method operator< takes thistype other returns boolean
return integer(this) < integer(other)
endmethod
private static integer array first_unit_oid
private static integer array first_cunit_oid
private static method onInit takes nothing returns nothing
set first_unit_oid['H'] = 'H000'
set first_unit_oid['h'] = 'h000'
set first_unit_oid['O'] = 'O000'
set first_unit_oid['o'] = 'o000'
set first_unit_oid['E'] = 'E000'
set first_unit_oid['e'] = 'e000'
set first_unit_oid['U'] = 'U000'
set first_unit_oid['u'] = 'u000'
set first_unit_oid['N'] = 'N000'
set first_unit_oid['n'] = 'n000'
set first_cunit_oid['H'] = 'H600'
set first_cunit_oid['h'] = 'h600'
set first_cunit_oid['O'] = 'O600'
set first_cunit_oid['o'] = 'o600'
set first_cunit_oid['E'] = 'E600'
set first_cunit_oid['e'] = 'e600'
set first_cunit_oid['U'] = 'U600'
set first_cunit_oid['u'] = 'u600'
set first_cunit_oid['N'] = 'N600'
set first_cunit_oid['n'] = 'n600'
endmethod
method to_unit_index takes nothing returns integer
return this - first_unit_oid[this / 0x01000000] + 1
endmethod
method to_cunit_index takes nothing returns integer
return this - first_cunit_oid[this / 0x01000000] + 1
endmethod
method to_item_index takes nothing returns integer
return this - 'I000' + 1
endmethod
method to_citem_index takes nothing returns integer
return this - 'I600' + 1
endmethod
method to_destructable_index takes nothing returns integer
return this - 'B000' + 1
endmethod
method to_cdestructable_index takes nothing returns integer
return this - 'B600' + 1
endmethod
method to_doodad_index takes nothing returns integer
return this - 'D000' + 1
endmethod
method to_cdoodad_index takes nothing returns integer
return this - 'D600' + 1
endmethod
method to_ability_index takes nothing returns integer
return this - 'A000' + 1
endmethod
method to_cability_index takes nothing returns integer
return this - 'A600' + 1
endmethod
method to_buff_index takes nothing returns integer
return this - 'B000' + 1
endmethod
method to_cbuff_index takes nothing returns integer
return this - 'B600' + 1
endmethod
method to_upgrade_index takes nothing returns integer
return this - 'R000' + 1
endmethod
method to_cupgrade_index takes nothing returns integer
return this - 'R600' + 1
endmethod
endstruct
endlibrary
library_once Event /* v2.0.0.1
************************************************************************************
*
* Functions
*
* function CreateEvent takes nothing returns integer
* function TriggerRegisterEvent takes trigger t, integer ev returns nothing
*
************************************************************************************
*
* struct Event extends array
*
* static method create takes nothing returns thistype
* method registerTrigger takes trigger t returns nothing
* method register takes boolexpr c returns nothing
* method fire takes nothing returns nothing
*
************************************************************************************/
globals
private real q=0
endglobals
struct Event extends array
private static integer w=0
private static trigger array e
static method create takes nothing returns thistype
set w=w+1
set e[w]=CreateTrigger()
return w
endmethod
method registerTrigger takes trigger t returns nothing
call TriggerRegisterVariableEvent(t,SCOPE_PRIVATE+"q",EQUAL,this)
endmethod
method register takes boolexpr c returns nothing
call TriggerAddCondition(e[this],c)
endmethod
method fire takes nothing returns nothing
set q=0
set q=this
call TriggerEvaluate(e[this])
endmethod
endstruct
function CreateEvent takes nothing returns Event
return Event.create()
endfunction
function TriggerRegisterEvent takes trigger t,Event ev returns nothing
call ev.registerTrigger(t)
endfunction
function RegisterEvent takes boolexpr c,Event ev returns nothing
call ev.register(c)
endfunction
function FireEvent takes Event ev returns nothing
call ev.fire()
endfunction
endlibrary
library IPool requires Table, Alloc
/*
IPool 3.0.0.0 by Bribe
Special thanks to Pyrogasm on wc3c.net for the original Pools resource, and to
Rising_Dusk for popularizing it.
Quick Intro of IPool:
Do you want a random integer from a multiple-choice list instead of a number
between x and y? Do you want one of those choices to have a lower or higher chance
to be picked? How about each item has its own odds of being picked?
IPool is similar to the native types itempool and unitpool, however returns
integers instead of handles. Integer-based pools can be used for all sorts of
things, ranging from randomized creep drops, spawning systems, random abilities
being cast (a la traps), random instances of a atruct, etc.
Object-Types of IPool:
IPool - Fast .getItem() method, slow add/remove. Uses a Table index formatted
as an array to get a random item without searching.
SubPool - Fast add/remove, slower .getItem method. Uses an O(n) search to
get a random item.
Main IPool API:
IPool.create()->IPool
returns a new IPool for your needs
iPoolInstance.flush()
reset all values of the IPool to default settings
iPoolInstance.destroy()
use this if you are totally done with that IPool
iPoolInstance.add(integer value, integer weight)
add any integer to the pool. The weight must be greater than 0 to have a
chance of being picked.
iPoolInstance.remove(integer value)
that value will no longer have a chance if you use this method on it!
iPoolInstance.getItem()->integer
returns one of the integers you added. Has higher chance to pick an item
with higher weight
Main SubPool API:
SubPool.create(integer totalWeight)->SubPool
The totalWeight must be equal to or greater than the sum of all items you
will add to the SubPool. Each added item has a chance of itsWeight/
totalWeight.
The rest of the main API is the same as IPool. Only keep in mind that
subPoolInstance.getItem() will return 0 in many cases due to the improbability
of an integer being picked.
Secondary API for both structs is included as follows:
poolInstance.contains(integer value)->boolean
Was the value added to the pool?
poolInstance.copy()->pool
Returns a new pool with the same properties as the pool you want copied.
debug poolInstance.print()
Useful for identifying what objects are in the pool during tests.
poolInstance.lock/unlock()
SubPools can associate with another subPool and/or an IPool. If you
have a single nested pool you wish to not get auto-destroyed, simply
call pool.lock(). pool.unlock() reverses it. If you do not use these, all
nested pools will auto-destruct when the containing SubPool is destroyed.
API for getting/setting the weight of an already-added value to a pool:
iPoolInstance.add(integer value, integer additionalWeight)
You can add more weight to a value in IPool, but the only way to reduce
it is to completely null it using the .remove(integer value) method. This
is to avoid the cumbersome giant that was the original IPool.
subPoolInstance[integer value].weight = integer newWeight
Setting a SubPool value's weight can be done arbitrarily.
iPoolInstance.weightOf(integer value)->integer
&
subPoolInstance[integer value].weight
Just in case you lost track of how much weight you assigned to a value.
API for nesting pools:
subPoolInstance.subPool = SubPool.create()
The SubPool member can be get and set arbitrarily. It cannot be the same
SubPool as the SubPool that's trying to nest it, as that would cause
recursion errors.
If the SubPool was not able to pick an integer, it will default to the
next nested SubPool within itself.
subPoolInstance.pool = IPool.create()
The .pool member can be get and set arbitrarily. If the SubPool and any
nested SubPools could not pick an integer, this pool will be the last resort.
*/
private module Init
private static method onInit takes nothing returns nothing
set .tar = TableArray[8192]
endmethod
endmodule
private struct data extends array
static TableArray tar
integer int
integer locks
integer weight
implement Alloc
implement Init
endstruct
private function Create takes nothing returns data
local data this = data.allocate()
set this.locks = 0
return this
endfunction
private function Destroy takes data this returns boolean
if this.locks == -1 or this == 0 then
debug call BJDebugMsg("IPool Error: Attempt to double-free instance!")
return false
endif
set this.locks = -1
call this.deallocate()
return true
endfunction
private function Lock takes data i returns nothing
if i.locks == -1 then
debug call BJDebugMsg("IPool Error: Attempt to lock a destroyed instance!")
return
endif
set i.locks = i.locks + 1
endfunction
private function Unlock takes data i returns boolean
if i.locks == -1 then
debug call BJDebugMsg("IPool Error: Attempt to unlock destroyed instance!")
return false
endif
set i.locks = i.locks - 1
return i.locks == 0
endfunction
struct IPool extends array
method operator weight takes nothing returns integer
return data(this).weight
endmethod
private method operator weight= takes integer lbs returns nothing
set data(this).weight = lbs
endmethod
private method operator table takes nothing returns Table
return data(this).int
endmethod
private method operator table= takes Table t returns nothing
set data(this).int = t
endmethod
static method create takes nothing returns thistype
local thistype this = Create()
set this.table = Table.create()
return this
endmethod
method flush takes nothing returns nothing
call this.table.flush()
call data.tar[this].flush()
set this.weight = 0
endmethod
method destroy takes nothing returns nothing
if Destroy(this) then
call this.table.destroy()
call data.tar[this].flush()
set this.weight = 0
endif
endmethod
method lock takes nothing returns nothing
call Lock(this)
endmethod
method unlock takes nothing returns nothing
if Unlock(this) then
call this.destroy()
endif
endmethod
//One-liner method to get a random item from the pool based on weight
method getItem takes nothing returns integer
return this.table[GetRandomInt(0, this.weight -1)]
endmethod
method weightOf takes integer value returns integer
return data.tar[this][value]
endmethod
method chanceOf takes integer value returns real //returns between 0. and 1.
return this.weightOf(value) / (this.weight + 0.) //don't divide by 0 here or else!
endmethod
method contains takes integer value returns boolean
return data.tar[this].has(value)
endmethod
method add takes integer value, integer lbs returns nothing
local Table tb = this.table
local integer i = this.weight
if lbs < 1 then
debug call BJDebugMsg("IPool Error: Tried to add value with invalid weight!")
return
endif
set data.tar[this][value] = data.tar[this][value] + lbs
set lbs = i + lbs
set this.weight = lbs //Important
loop
exitwhen i == lbs
set tb[i] = value //treat this.table as an array
set i = i + 1
endloop
endmethod
method remove takes integer value returns nothing
local Table tb = this.table
local Table new
local integer i = this.weight
local integer n = 0
local integer val
if not this.contains(value) then
debug call BJDebugMsg("IPool Error: Attempt to remove un-added instance!")
return
endif
set new = Table.create()
set this.table = new
loop
set i = i - 1
set val = tb[i]
if val != value then
set new[n] = val //write to the new Table without gaps
set n = n + 1
endif
exitwhen i == 0
endloop
set this.weight = n //lower pool weight
call tb.destroy() //abandon old Table instance
call data.tar[this].remove(value) //clear the value's weight now that it's gone
endmethod
method copy takes nothing returns thistype
local thistype new = .create()
local integer i = this.weight
local Table tt = this.table
local Table nt = new.table
local Table dt = data.tar[new]
local integer val
if i == 0 then
debug call BJDebugMsg("IPool Error: Attempt to copy invalid instance!")
call new.destroy()
return 0
endif
set new.weight = i
loop
set i = i - 1
exitwhen i == 0
set val = tt[i]
set nt[i] = val
set dt[val] = dt[val] + 1
endloop
return new
endmethod
static if DEBUG_MODE then
method print takes nothing returns nothing //print the array of the pool
local string s = "IPool: |cffffcc33Weight: "
local integer i = this.weight
local Table t = this.table
set s = s + I2S(i) + "; Indices: "
loop
set i = i - 1
exitwhen i <= 0
set s = s + "[" + I2S(t[i]) + "]"
endloop
call BJDebugMsg(s + "|r")
endmethod
endif
endstruct
//New struct to handle deliberately-rare chances
struct SubPool extends array
private IPool iPool //for association if you want it
private thistype nest //you can nest IPoolMinis for poolception
//you can change a value's weight via subpoolinstance[value].weight = blah
//you can also change the entire pool's weight via subpoolinstance.weight = blah.
method operator weight takes nothing returns integer
return data(this).weight
endmethod
method operator weight= takes integer lbs returns nothing
set data(this).weight = lbs
endmethod
private method operator value takes nothing returns integer
return data(this).int
endmethod
private method operator value= takes integer val returns nothing
set data(this).int = val
endmethod
private thistype next
private thistype prev
method operator pool takes nothing returns IPool
return this.iPool
endmethod
method operator pool= takes IPool ip returns nothing
if ip != 0 then
call ip.lock()
endif
if this.iPool != 0 then
call this.iPool.unlock()
endif
set this.iPool = ip
endmethod
static method create takes integer totalWeight returns thistype
local thistype this = Create()
set this.next = this
set this.prev = this //I'm my own best friend
set this.weight = totalWeight
return this
endmethod
method destroy takes nothing returns nothing
local thistype curr = this
if this.next == -1 then
debug call BJDebugMsg("SubPool Error: Attempt to double-free!")
return
endif
loop
set curr = curr.next
call Destroy(curr) //destroy all the things
exitwhen curr == this
endloop
set this.next = -1
set this.pool = 0
if this.nest != 0 then
if data(this.nest).locks == 1 then
call this.nest.destroy()
else
call Unlock(this.nest)
endif
set this.nest = 0
endif
call data.tar[this].flush()
endmethod
method lock takes nothing returns nothing
call Lock(this)
endmethod
method unlock takes nothing returns nothing
if Unlock(this) then
call this.destroy()
endif
endmethod
method operator subPool takes nothing returns thistype //need to return thistype and not IPool :P
return this.nest
endmethod
method operator subPool= takes thistype ip returns nothing
if this == ip then
debug call BJDebugMsg("SubPool Error: Don't set a subPool within itself. Use the .copy() method, instead.")
return
endif
if ip != 0 then
call ip.lock()
endif
if this.nest != 0 then
call this.nest.unlock()
endif
set this.nest = ip
endmethod
method add takes integer val, integer lbs returns nothing
local thistype new
if lbs <= 0 then
debug call BJDebugMsg("SubPool Error: Don't add a value without weight")
return
endif
if data.tar[this].has(val) then
set new = data.tar[this][val]
set new.weight = new.weight + lbs
return
endif
set new = Create()
set new.prev = this.prev
set this.prev.next = new
set this.prev = new
set new.next = this
set new.value = val
set new.weight = lbs
set data.tar[this][val] = new
endmethod
method contains takes integer val returns boolean
return data.tar[this].has(val)
endmethod
method operator [] takes integer val returns thistype
return data.tar[this][val]
endmethod
method operator []= takes integer val, integer newWeight returns nothing
set this[val].weight = newWeight
endmethod
method remove takes integer val returns nothing
local thistype node = this[val]
if Destroy(node) then
set node.prev.next = node.next
set node.next.prev = node.prev
call data.tar[this].remove(val)
else
debug call BJDebugMsg("SubPool Error: Attempt to remove non-added value")
endif
endmethod
method getItem takes nothing returns integer
local thistype curr = this
local integer i = GetRandomInt(1, this.weight)
loop
set curr = curr.next
set i = i - curr.weight
exitwhen i <= 0
endloop
if curr == this then
if this.nest != 0 then
set i = this.nest.getItem()
else
set i = 0
endif
if i == 0 and this.pool != 0 then //if no low-probability item could be found...
set i = this.pool.getItem() //pick a random int from main pool
endif
else
set i = curr.value
endif
return i
endmethod
method copy takes nothing returns thistype
local thistype new = .create(this.weight)
local thistype curr = this
set new.pool = this.iPool
set new.subPool = this.nest
loop
set curr = curr.next
exitwhen curr == this
call new.add(curr.value, curr.weight)
endloop
return new
endmethod
static if DEBUG_MODE then
method print takes nothing returns nothing
local thistype curr = this
local string s = "SubPool: |cffffcc33Instance: " + I2S(this) + ", TotalWeight: " + I2S(this.weight) + ", Indices: "
if curr.next == this then
call BJDebugMsg("SubPool is empty!")
//return
endif
loop
set curr = curr.next
exitwhen curr == this
set s = s + "[" + I2S(curr.value) + "]<" + I2S(curr.weight) + ">"
endloop
call BJDebugMsg(s + "|r")
if this.nest != 0 then
call this.nest.print()
endif
if this.iPool != 0 then
call this.iPool.print()
endif
endmethod
endif
endstruct
endlibrary
library GameVersion initializer init
globals
constant integer PATCH_LEVEL_127 = 1
constant integer PATCH_LEVEL_128 = 2
constant integer PATCH_LEVEL_129 = 3
constant integer PATCH_LEVEL_130 = 4
constant integer PATCH_LEVEL_132 = 5
integer PatchVersion = 0
string PatchVersionStr = ""
endglobals
function GetPatchLevel takes nothing returns integer
local image img
local string tmp
// This icon wasn't introduced until 1.28a
set img = CreateImage("ReplaceableTextures\\WorldEditUI\\Editor-Toolbar-MapValidation.blp", 64, 64, 0, 0,0,0,64,64,0, 1)
if (GetHandleId(img) == -1) then
set PatchVersionStr = "Legacy"
return PATCH_LEVEL_127 // 1.27b or lower
endif
call DestroyImage(img)
// The array size limit was increased in 1.29, so if it's the same
// then we are on 1.28.
if (JASS_MAX_ARRAY_SIZE <= 8192) then
set PatchVersionStr = "1.28"
return PATCH_LEVEL_128
endif
// This string didn't exist until 1.30
if (GetLocalizedString("DOWNLOADING_MAP") == "DOWNLOADING_MAP") then
set PatchVersionStr = "1.29"
return PATCH_LEVEL_129
endif
// This string changed in 1.30.2.
set tmp = GetLocalizedString("ERROR_ID_CDKEY_INUSE")
if (SubString(tmp, StringLength(tmp)-1, StringLength(tmp)) == ")") then // check the last character to presumably support all locales
set PatchVersionStr = "1.30"
return PATCH_LEVEL_130
endif
set PatchVersionStr = "1.32"
return PATCH_LEVEL_132 // or higher
endfunction
private function init takes nothing returns nothing
set PatchVersion = GetPatchLevel()
endfunction
endlibrary
library PathingLib
// Object generator
///! external ObjectMerger w3u hgry hPLF unsf "(PathingLib) FlyChecker" unam "" umdl ".mdl" ubdg 0 uabi "Aloc" uble 0 ulum 0 upoi 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" ugol 0 uaen "" udea "" umvt "fly" usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
///! external ObjectMerger w3u hfoo hPLW unsf "(PathingLib) WalkChecker" unam "" umdl ".mdl" ubdg 0 uabi "Aloc" uble 0 ulum 0 upoi 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" ugol 0 uaen "" udea "" umvt "foot" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
///! external ObjectMerger w3u hhou hPLB unsf "(PathingLib) BuildChecker" unam "" umdl ".mdl" ubdg 1 uabi "Aloc" upat "" ulum 0 upoi 0 uubs "" uble 0 ushb "" uico "" ugol 0 ufma 0 umxp 0 ubsl "" umxr 0 ussc 0 ushu "" uaen "" udea "" umvt "" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
///! external ObjectMerger w3u hpea hPLP unsf "(PathingLib) PathChecker" unam "" umdl ".mdl" ubdg 0 uabi "Aloc" uble 0 ubui "hPLF,hPLW,hPLB" ulum 0 upoi 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" ugol 0 uaen "" udea "" umvt "foot" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
// Configuration
globals
private constant integer PATH_CHECKER = 'hPLP'
private constant integer FLY_CHECKER = 'hPLF'
private constant integer WALK_CHECKER = 'hPLW'
private constant integer BUILD_CHECKER = 'hPLB'
private constant player DUMMY_PLAYER = Player(15)
endglobals
/*
Pathing Library v1.6
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Description
¯¯¯¯¯¯¯¯¯¯¯
Allows you to detect all pathability types:
walkablility, flyability, and buildability.
Warning!
Please keep informed that this system is more sensitive than
any other walkability checker systems out there, as it also
detects pathing map generated by normal units as well.
API
¯¯¯
| function IsTerrainFlyable takes real x, real y returns boolean
| function IsTerrainWalkable takes real x, real y returns boolean
| function IsTerrainBuildable takes real x, real y returns boolean
How to import
¯¯¯¯¯¯¯¯¯¯¯¯¯
- Copy Fly, Walk, Build, and Path Checker at object editor (Unit).
- Make sure Path Checker is able to build Fly, Walk, and Build Checker
(at object editor>unit>Path Checker>"Techtree - Structures built")
- Configure this system correctly.
Link: hiveworkshop.com/forums/spells-569/pathing-type-v1-2-a-263230/
*/
globals
private unit PathChecker
endglobals
function IsTerrainFlyable takes real x, real y returns boolean
return IssueBuildOrderById(PathChecker, FLY_CHECKER, x, y)
endfunction
function IsTerrainWalkable takes real x, real y returns boolean
return IssueBuildOrderById(PathChecker, WALK_CHECKER, x, y)
endfunction
function IsTerrainBuildable takes real x, real y returns boolean
return IssueBuildOrderById(PathChecker, BUILD_CHECKER, x, y)
endfunction
private module Init
private static method onInit takes nothing returns nothing
call init()
endmethod
endmodule
private struct InitStruct extends array
private static method init takes nothing returns nothing
set PathChecker = CreateUnit(DUMMY_PLAYER, PATH_CHECKER, 0, 0, 0)
call UnitRemoveAbility(PathChecker, 'Amov')
call ShowUnit(PathChecker, false)
if GetLocalPlayer() == DUMMY_PLAYER then
call FogEnable(false)
endif
endmethod
implement Init
endstruct
endlibrary
library PathingColor requires PathingLib
/*
Pathing Color v1.5
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Pathing may generate color based on their characteristics.
If the pathing is not walkable, it will have red color. If
the pathing is not buildable, it will have blue color. And
if the pathing is not flyable, it will have green color.
The rests are just combinations between these colors.
Here is the summary to ease everything: (o = yes, x = no)
Color Buildable Walkable Flyable Red Green Blue
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
White x x x 255 255 255
Magenta x x o 255 0 255
Cyan x o x 0 255 255
Blue x o o 0 0 255
Yellow o x x 255 255 0
Red o x o 255 0 0
Green o o x 0 255 0
Black o o o 0 0 0
(You can check your pathing map by pressing 'p' at terrain editor)
API
¯¯¯
| function GetTerrainPathingColor takes real x, real y returns integer
(Constants)
| PATHING_COLOR_WHITE
| PATHING_COLOR_MAGENTA
| PATHING_COLOR_CYAN
| PATHING_COLOR_BLUE
| PATHING_COLOR_YELLOW
| PATHING_COLOR_RED
| PATHING_COLOR_GREEN
| PATHING_COLOR_BLACK
*/
globals
constant integer PATHING_COLOR_WHITE = 0
constant integer PATHING_COLOR_MAGENTA = 1
constant integer PATHING_COLOR_CYAN = 2
constant integer PATHING_COLOR_BLUE = 3
constant integer PATHING_COLOR_YELLOW = 4
constant integer PATHING_COLOR_RED = 5
constant integer PATHING_COLOR_GREEN = 6
constant integer PATHING_COLOR_BLACK = 7
endglobals
function GetTerrainPathingColor takes real x, real y returns integer
local integer color = 0
if IsTerrainFlyable(x, y) then
set color = color + 1
endif
if IsTerrainWalkable(x, y) then
set color = color + 2
endif
if IsTerrainBuildable(x, y) then
set color = color + 4
endif
return color
endfunction
endlibrary
/**
* IsTerrainWalkable snippet for estimating the walkability status of a co-ordinate pair, credits
* to Anitarf and Vexorian.
*
* API:
* boolean IsTerrainWalkable(real x, real y) - returns the walkability of (x,y)
*/
library IsTerrainWalkable initializer init
globals
// this value is how far from a point the item may end up for the point to be considered pathable
private constant real MAX_RANGE=10.
// the following two variables are set to the position of the item after each pathing check
// that way, if a point isn't pathable, these will be the coordinates of the nearest point that is
public real X=0.
public real Y=0.
private rect r
private item check
private item array hidden
private integer hiddenMax=0
endglobals
private function init takes nothing returns nothing
set check=CreateItem('ciri',0.,0.)
call SetItemVisible(check,false)
set r=Rect(0.0,0.0,128.0,128.0)
endfunction
private function hideBothersomeItem takes nothing returns nothing
if IsItemVisible(GetEnumItem()) then
set hidden[hiddenMax]=GetEnumItem()
call SetItemVisible(hidden[hiddenMax],false)
set hiddenMax=hiddenMax+1
endif
endfunction
function IsTerrainWalkable takes real x, real y returns boolean
// first, hide any items in the area so they don't get in the way of our item
call MoveRectTo(r,x,y)
call EnumItemsInRect(r,null,function hideBothersomeItem)
// try to move the check item and get its coordinates
// this unhides the item...
call SetItemPosition(check,x,y)
set X=GetItemX(check)
set Y=GetItemY(check)
//...so we must hide it again
call SetItemVisible(check,false)
// before returning, unhide any items that got hidden at the start
loop
exitwhen hiddenMax==0
set hiddenMax=hiddenMax-1
call SetItemVisible(hidden[hiddenMax],true)
endloop
// return pathability status
return (x-X)*(x-X)+(y-Y)*(y-Y)<MAX_RANGE*MAX_RANGE
endfunction
endlibrary
library NumberKeyEvent initializer init
// Configurations
globals
// Key detector dummy's raw code in OE
private constant integer DUMMY_ID = 'h009'
// Location of dummy, better to be a permanently
// invisible spot in your map
private constant real DUMMY_X = 14000
private constant real DUMMY_Y = 14000
// If true, system will use periodical check
// results in more instaneous press event
private constant boolean USE_TIMER = false
private constant real CHECK_RATE = 0.01
endglobals
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* NumberKeyEvent v1.3
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*
* Description
* ¯¯¯¯¯¯¯¯¯¯¯
* Allows you to do actions when a player presses
* any number key (0-9)
*
* Cons
* ¯¯¯¯
* - Needs calibration (check demo)
* - Disturbs unit selection
*
* Requirement
* ¯¯¯¯¯¯¯¯¯¯¯
* -
*
* How to import
* ¯¯¯¯¯¯¯¯¯¯¯¯¯
* - Copy KeyDetectorDummy unit from object editor to your map
* - Copy the trigger folder to your map
* - Configure the system accordingly
*
* API
* ¯¯¯
* function CalibrateNumberKeys takes integer playerId returns nothing
* function GetPressedNumberKey takes nothing returns integer
* function GetPressingPlayer takes nothing returns player
* function RegisterAnyNumberKeyEvent takes boolexpr func returns triggercondition
* function UnregisterAnyNumberKeyEvent takes triggercondition tc returns nothing
*
* Notes
* ¯¯¯¯¯
* - Better to preserve an invisible area for dummy
* units to avoid unwanted camera panning
* - Player must be pressing CTRL when CalibrateNumberKeys
* function is called
* - You must allow players to calibrate their keys
* anytime whenever they want, in case the calibration
* is failed or broken
* - By using this system players are no longer supposed
* to use the control group shortcut keys: CTRL+(0-9).
* Because it will break the calibration. Warn them.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
globals
private unit array KeyUnit
public boolean array IsCalibrated
private boolean array IsRegistered
private trigger Handler = CreateTrigger()
private integer EventPressed = -1
private player EventPresser = null
private player Locale
private timer Timer = null
private trigger Trigg
endglobals
private function onSelection takes nothing returns boolean
static if USE_TIMER then
local integer i = 0
local integer j
local integer k
local player p
loop
exitwhen i > 11
if IsCalibrated[i] then
set p = Player(i)
set j = 0
loop
exitwhen j > 9
set k = i*10+j
if IsUnitSelected(KeyUnit[k], p) then
if Locale == p then
call SelectUnit(KeyUnit[k], false)
endif
set EventPresser = p
set EventPressed = j
call TriggerEvaluate(Handler)
set EventPressed = -1
set EventPresser = null
endif
set j = j + 1
endloop
endif
set i = i + 1
endloop
else
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(u)
local integer id = GetPlayerId(p)
local integer dt = GetUnitUserData(u)
if Locale == p then
call SelectUnit(u, false)
endif
if IsCalibrated[id] then
set EventPresser = p
set EventPressed = dt
call TriggerEvaluate(Handler)
set EventPressed = -1
set EventPresser = null
elseif dt == 9 then
set IsCalibrated[id] = true
endif
set u = null
endif
return false
endfunction
function CalibrateNumberKeys takes integer playerId returns nothing
local integer i
local integer j
local player p = Player(playerId)
if IsRegistered[playerId] then
set IsCalibrated[playerId] = false
if Locale == p then
call ClearSelection()
endif
set i = 0
loop
exitwhen i > 9
set j = playerId*10+i
if KeyUnit[j] == null then
set KeyUnit[j] = CreateUnit(p, DUMMY_ID, WorldBounds.maxX, WorldBounds.maxY, 0)
static if not USE_TIMER then
call TriggerRegisterUnitEvent(Trigg, KeyUnit[j], EVENT_UNIT_SELECTED)
call SetUnitUserData(KeyUnit[j], i)
endif
endif
if Locale == p then
call SelectUnit(KeyUnit[j], true)
call ForceUIKey(I2S(i))
call SelectUnit(KeyUnit[j], false)
endif
set i = i + 1
endloop
endif
static if USE_TIMER then
if Timer == null then
set Timer = CreateTimer()
call TimerStart(Timer, CHECK_RATE, true, function onSelection)
endif
endif
endfunction
function GetPressedNumberKey takes nothing returns integer
return EventPressed
endfunction
function GetPressingPlayer takes nothing returns player
return EventPresser
endfunction
function RegisterAnyNumberKeyEvent takes boolexpr func returns triggercondition
return TriggerAddCondition(Handler, func)
endfunction
function UnregisterAnyNumberKeyEvent takes triggercondition tc returns nothing
call TriggerRemoveCondition(Handler, tc)
endfunction
private function init takes nothing returns nothing
local integer i = 0
local integer j
local integer k
local player p
static if not USE_TIMER then
set Trigg = CreateTrigger()
call TriggerAddCondition(Trigg, Condition(function onSelection))
endif
set Locale = GetLocalPlayer()
loop
exitwhen i > 11
set p = Player(i)
set IsRegistered[i] = GetPlayerController(p) == MAP_CONTROL_USER and GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING
if IsRegistered[i] then
set j = 0
loop
exitwhen j > 9
set k = i*10+j
set KeyUnit[k] = CreateUnit(p, DUMMY_ID, WorldBounds.maxX, WorldBounds.maxY, 0)
static if not USE_TIMER then
call TriggerRegisterUnitEvent(Trigg, KeyUnit[k], EVENT_UNIT_SELECTED)
call SetUnitUserData(KeyUnit[k], j)
endif
call SetUnitX(KeyUnit[k], DUMMY_X)
call SetUnitY(KeyUnit[k], DUMMY_Y)
call PauseUnit(KeyUnit[k], true)
set j = j + 1
endloop
endif
set i = i + 1
endloop
endfunction
endlibrary
library ErrorMessage /* v1.0.1.4
*************************************************************************************
*
* Issue Compliant Error Messages
*
************************************************************************************
*
* debug function ThrowError takes boolean expression, string libraryName, string functionName, string objectName, integer objectInstance, string description returns nothing
* - In the event of an error the game will be permanently paused
*
* debug function ThrowWarning takes boolean expression, string libraryName, string functionName, string objectName, integer objectInstance, string description returns nothing
*
************************************************************************************/
static if DEBUG_MODE then
private struct Fields extends array
static constant string COLOR_RED = "|cffff0000"
static constant string COLOR_YELLOW = "|cffffff00"
static string lastError = null
endstruct
private function Pause takes nothing returns nothing
//call PauseGame(true)
endfunction
private function ThrowMessage takes string libraryName, string functionName, string objectName, integer objectInstance, string description, string errorType, string color returns nothing
local string str
local string color_braces = "|cff66FF99"
local string orange = "|cffff6600"
set str = "->\n-> " + color_braces + "{|r " + "Library" + color_braces + "(" + orange + libraryName + color_braces + ")"
if (objectName != null) then
if (objectInstance > 0) then
set str = str + "|r.Object" + color_braces + "(" + orange + objectName + color_braces + " (|rinstance = " + orange + I2S(objectInstance) + color_braces + ") )" + "|r." + "Method" + color_braces + "(" + orange + functionName + color_braces + ")"
else
set str = str + "|r.Object" + color_braces + "(" + orange + objectName + color_braces + ")|r." + "Method" + color_braces + "(" + orange + functionName + color_braces + ")"
endif
else
set str = str + "|r." + "Function" + color_braces + "(" + orange + functionName + color_braces + ")"
endif
set str = str + color_braces + " }|r " + "has thrown an exception of type " + color_braces + "(" + color + errorType + color_braces + ")|r."
set Fields.lastError = str + "\n->\n" + "-> " + color + description + "|r\n->"
endfunction
function ThrowError takes boolean expression, string libraryName, string functionName, string objectName, integer objectInstance, string description returns nothing
if (Fields.lastError != null) then
set objectInstance = 1/0
endif
if (expression) then
call ThrowMessage(libraryName, functionName, objectName, objectInstance, description, "Error", Fields.COLOR_RED)
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60000,Fields.lastError)
call TimerStart(CreateTimer(), 0, true, function Pause)
set objectInstance = 1/0
endif
endfunction
function ThrowWarning takes boolean expression, string libraryName, string functionName, string objectName, integer objectInstance, string description returns nothing
if (Fields.lastError != null) then
set objectInstance = 1/0
endif
if (expression) then
call ThrowMessage(libraryName, functionName, objectName, objectInstance, description, "Warning", Fields.COLOR_YELLOW)
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60000,Fields.lastError)
set Fields.lastError = null
endif
endfunction
endif
endlibrary
library RapidSound requires optional TimerUtils
globals
// Actually, just leave this value
private constant real MIN_DELAY_FACTOR = 4.0
endglobals
/* v1.6
Description
¯¯¯¯¯¯¯¯¯¯¯
Allows you to play sounds rapidly and flawlessly without limit.
Remember one sound file can only have one RSound instance.
External Dependencies
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
(Optional)
TimerUtils by Vexorian
wc3c.net/showthread.php?t=101322
User API
¯¯¯¯¯¯¯¯
struct RSound
Instantiate an RapidSound instance
| static method create takes string fileName, boolean is3D, boolean autoStop, integer inRate, integer outRate returns thistype
autoStop => stop when sound is out of range
inRate => fade in rate
outRate => fade out rate
Play the sound at given coordinate
| method play takes real x, real y, real z, integer volume returns nothing
Stop sound
| method stop takes boolean fadeOut returns nothing
Destroy RapidSound instance
| method kill takes nothing returns nothing
Sound file duration (in second)
| method operator duration takes nothing returns real
Resource Link
¯¯¯¯¯¯¯¯¯¯¯¯¯
hiveworkshop.com/threads/snippet-rapidsound.258991/
*/
struct RSound
private static constant integer MAX_COUNT = 4
private static integer Counter = -1
private static string array StrLib
private static thistype array StrDex
private integer ct
private integer lib
private integer dex
private real dur
real pitch
private sound array snd[thistype.MAX_COUNT]
private timer array tmr[thistype.MAX_COUNT]
method operator duration takes nothing returns real
return .dur*MIN_DELAY_FACTOR
endmethod
method kill takes nothing returns nothing
local integer i
set .ct = .ct - 1
if .ct == 0 then
set i = 0
loop
exitwhen i == MAX_COUNT
call StopSound(.snd[i], true, false)
static if LIBRARY_TimerUtils then
call ReleaseTimer(.tmr[i])
else
call DestroyTimer(.tmr[i])
endif
set .snd[i] = null
set .tmr[i] = null
set i = i + 1
endloop
set StrLib[.lib] = StrLib[Counter]
set StrDex[.lib] = StrDex[Counter]
set Counter = Counter - 1
call deallocate()
endif
endmethod
method stop takes boolean fadeOut returns nothing
local integer i = 0
loop
exitwhen i == MAX_COUNT
call StopSound(.snd[i], false, fadeOut)
set i = i + 1
endloop
endmethod
method play takes real x, real y, real z, integer volume returns nothing
set .dex = .dex + 1
if .dex == MAX_COUNT then
set .dex = 0
endif
if TimerGetRemaining(.tmr[.dex]) == 0 then
call StopSound(.snd[.dex], false, false)
call SetSoundPosition(.snd[.dex], x, y, z)
call SetSoundVolume(.snd[.dex], volume)
call SetSoundPitch(.snd[.dex], .pitch)
call StartSound(.snd[.dex])
call TimerStart(.tmr[.dex], .dur, false, null)
endif
endmethod
static method create takes string fileName, boolean is3D, boolean autoStop, integer inRate, integer outRate returns thistype
local thistype this
local integer i = 0
local boolean b = true
loop
exitwhen i > Counter
if fileName == StrLib[i] then
set b = false
exitwhen true
endif
set i = i + 1
endloop
if b then
set this = allocate()
set Counter = Counter + 1
set StrLib[Counter] = fileName
set StrDex[Counter] = this
set .ct = 1
set .dex = -1
set .lib = Counter
set .pitch = 1
set .dur = I2R(GetSoundFileDuration(fileName))/(1000.*MIN_DELAY_FACTOR)
set i = 0
loop
exitwhen i == MAX_COUNT
set .snd[i] = CreateSound(fileName, false, is3D, autoStop, inRate, outRate, "")
static if LIBRARY_TimerUtils then
set .tmr[i] = NewTimer()
call TimerStart(.tmr[i], 0, false, null)
call PauseTimer(.tmr[i])
else
set .tmr[i] = CreateTimer()
endif
set i = i + 1
endloop
else
set this = StrDex[i]
set .ct = .ct + 1
endif
return this
endmethod
endstruct
endlibrary
library PreventSave initializer onInit
//====================================
// by TriggerHappy
//====================================
//
// This library allows you to enable or disable game saving.
// It works by showing a dialog instantly before a game is saved which interrupts it.
// It does nothing visually to the game that I've noticed.
//
// You can toggle saving for a specific player with the PreventSave function.
// Example:
// call PreventSave(Player(0), true) - disables saving for player 0
//
// You also can toggle for everybody by setting
// GameAllowSave to true, or false.
//
//====================================
// Import Instructions
//====================================
//
// Decide whether you want GUI or vJASS, then copy the triggers or script over to your map.
// This script requires JassHelper which is included in JassNewGenPack.
//
//====================================
globals
boolean GameAllowSave = false
endglobals
//====================================
// Do not edit below this line
//====================================
globals
private dialog Dialog = DialogCreate()
private timer Timer = CreateTimer()
private player localplayer
endglobals
function PreventSave takes player p, boolean flag returns nothing
if (p == localplayer) then
set GameAllowSave = not flag
endif
endfunction
private function Exit takes nothing returns nothing
call DialogDisplay(localplayer, Dialog, false)
endfunction
private function StopSave takes nothing returns boolean
if not GameAllowSave then
call DialogDisplay(localplayer, Dialog, true)
endif
call TimerStart(Timer, 0.00, false, function Exit)
return false
endfunction
private function onInit takes nothing returns nothing
local trigger t = CreateTrigger()
set localplayer = GetLocalPlayer()
call TriggerRegisterGameEvent(t, EVENT_GAME_SAVE)
call TriggerAddCondition(t, function StopSave)
endfunction
endlibrary
library SRS initializer ini
/*****************************************************************************************************/
/** **/
/** 'Safe Revive System v1.6' **/
/** ***** **/
/** by Dalvengyr aka ..... **/
/** **/
/* Why safe? This revive system allows you to revive any organic non-Hero units without recreating */
/* them. In the demo map there will be shown floating shits that shows units handle that is not */
/* changed after revived. What are the advantages of using this system? This method is faster than */
/* recreating new unit, and save spaces in memory. The only thing you need to do is set units death */
/* type to 'can raise, does decay'. */
/* */
/* Requirement: */
/* - JNGP */
/* */
/* Disadvantages: */
/* - None */
/* */
/* Implementation: */
/* 1. Copy SRS folder into your map */
/* 2. Copy dummy unit and spell into your map */
/* 3. Make sure dummy and spell id below is the same with their rawcode at OE */
/* 4. If you have dummy.mdx in your map, then open OE, set dummy units file model to that */
/* dummy.mdx is better */
/* 5. Nuff said. Done. */
/* */
/* APIs: */
/* 1. Revive any unit you want at their current position */
/* */
/* function ReviveUnit takes unit whichUnit returns boolean */
/* */
/* 2. Revive any unit you want at certain point */
/* Set boolean flag to true to check target point pathability */
/* Keep in mind that checking pathability is always slower than not */
/* */
/* function ReviveUnitAtPoint takes unit whichUnit, real x, real y, boolean flag returns boolean */
/** **/
/*****************************************************************************************************/
/*****************************************************************************************************/
globals
/* 'CONFIGURATIONS
1. Dummy Id */
private constant integer DUMMY_ID = 'e000'
/* 2. Spell Id */
private constant integer SPELL_ID = 'A00O'
/* 3. Ressurection Order Id */
private constant integer ORDER_ID = 852094
/* 'END-OF-CONFIGURATIONS' */
private unit DUMMY
endglobals
private constant function FilterUnits takes unit u returns boolean
return not(IsUnitType(u, UNIT_TYPE_STRUCTURE) or IsUnitType(u, UNIT_TYPE_MECHANICAL)) and not IsUnitType(u, UNIT_TYPE_HERO)
endfunction
private function ini takes nothing returns nothing
set DUMMY = CreateUnit(Player(15), DUMMY_ID, 0.0, 0.0, 270.0)
call UnitAddAbility(DUMMY, SPELL_ID)
endfunction
/*' APIs '*/
function ReviveUnit takes unit whichUnit returns boolean
if FilterUnits(whichUnit) then
if IsUnitType(whichUnit, UNIT_TYPE_DEAD) and GetUnitTypeId(whichUnit) != 0 then
call SetUnitOwner(DUMMY, GetOwningPlayer(whichUnit), false)
call SetUnitX(DUMMY, GetUnitX(whichUnit))
call SetUnitY(DUMMY, GetUnitY(whichUnit))
call IssueImmediateOrderById(DUMMY, ORDER_ID)
return true
endif
endif
return false
endfunction
function ReviveUnitAtPoint takes unit whichUnit, real x, real y, boolean flag returns boolean
if ReviveUnit(whichUnit) then
if flag then
call SetUnitPosition(whichUnit, x, y)
else
call SetUnitX(whichUnit, x)
call SetUnitY(whichUnit, y)
endif
return true
endif
return false
endfunction
endlibrary
library TimerUtils initializer init
//*********************************************************************
//* TimerUtils (red+blue+orange flavors for 1.24b+) 2.0
//* ----------
//*
//* To implement it , create a custom text trigger called TimerUtils
//* and paste the contents of this script there.
//*
//* To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass) More scripts: htt://www.wc3c.net
//*
//* For your timer needs:
//* * Attaching
//* * Recycling (with double-free protection)
//*
//* set t=NewTimer() : Get a timer (alternative to CreateTimer)
//* set t=NewTimerEx(x) : Get a timer (alternative to CreateTimer), call
//* Initialize timer data as x, instead of 0.
//*
//* ReleaseTimer(t) : Relese a timer (alt to DestroyTimer)
//* SetTimerData(t,2) : Attach value 2 to timer
//* GetTimerData(t) : Get the timer's value.
//* You can assume a timer's value is 0
//* after NewTimer.
//*
//* Multi-flavor:
//* Set USE_HASH_TABLE to true if you don't want to complicate your life.
//*
//* If you like speed and giberish try learning about the other flavors.
//*
//********************************************************************
//================================================================
globals
//How to tweak timer utils:
// USE_HASH_TABLE = true (new blue)
// * SAFEST
// * SLOWEST (though hash tables are kind of fast)
//
// USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = true (orange)
// * kinda safe (except there is a limit in the number of timers)
// * ALMOST FAST
//
// USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = false (red)
// * THE FASTEST (though is only faster than the previous method
// after using the optimizer on the map)
// * THE LEAST SAFE ( you may have to tweak OFSSET manually for it to
// work)
//
private constant boolean USE_HASH_TABLE = true
private constant boolean USE_FLEXIBLE_OFFSET = false
private constant integer OFFSET = 0x100000
private integer VOFFSET = OFFSET
//Timers to preload at map init:
private constant integer QUANTITY = 256
//Changing this to something big will allow you to keep recycling
// timers even when there are already AN INCREDIBLE AMOUNT of timers in
// the stack. But it will make things far slower so that's probably a bad idea...
private constant integer ARRAY_SIZE = 8190
endglobals
//==================================================================================================
globals
private integer array data[ARRAY_SIZE]
private hashtable ht
//integer Dumb = 0
endglobals
//It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
function SetTimerData takes timer t, integer value returns nothing
static if(USE_HASH_TABLE) then
// new blue
call SaveInteger(ht,0,GetHandleId(t), value)
elseif (USE_FLEXIBLE_OFFSET) then
// orange
static if (DEBUG_MODE) then
if(GetHandleId(t)-VOFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
set data[GetHandleId(t)-VOFFSET]=value
else
// new red
static if (DEBUG_MODE) then
if(GetHandleId(t)-OFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
set data[GetHandleId(t)-OFFSET]=value
endif
endfunction
function GetTimerData takes timer t returns integer
static if(USE_HASH_TABLE) then
// new blue
return LoadInteger(ht,0,GetHandleId(t) )
elseif (USE_FLEXIBLE_OFFSET) then
// orange
static if (DEBUG_MODE) then
if(GetHandleId(t)-VOFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
return data[GetHandleId(t)-VOFFSET]
else
// new red
static if (DEBUG_MODE) then
if(GetHandleId(t)-OFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
return data[GetHandleId(t)-OFFSET]
endif
endfunction
//==========================================================================================
globals
private timer array tT[ARRAY_SIZE]
private integer tN = 0
private constant integer HELD=0x28829022
//use a totally random number here, the more improbable someone uses it, the better.
private boolean didinit = false
endglobals
private keyword init
//==========================================================================================
// I needed to decide between duplicating code ignoring the "Once and only once" rule
// and using the ugly textmacros. I guess textmacros won.
//
//! textmacro TIMERUTIS_PRIVATE_NewTimerCommon takes VALUE
// On second thought, no.
//! endtextmacro
function NewTimerEx takes integer value returns timer
//set Dumb = Dumb + 1
//call BJDebugMsg("new " + I2S(Dumb))
if (tN==0) then
if (not didinit) then
//This extra if shouldn't represent a major performance drawback
//because QUANTITY rule is not supposed to be broken every day.
call init.evaluate()
set tN = tN - 1
else
//If this happens then the QUANTITY rule has already been broken, try to fix the
// issue, else fail.
debug call BJDebugMsg("NewTimer: Warning, Exceeding TimerUtils_QUANTITY, make sure all timers are getting recycled correctly")
set tT[0]=CreateTimer()
static if( not USE_HASH_TABLE) then
debug call BJDebugMsg("In case of errors, please increase it accordingly, or set TimerUtils_USE_HASH_TABLE to true")
static if( USE_FLEXIBLE_OFFSET) then
if (GetHandleId(tT[0])-VOFFSET<0) or (GetHandleId(tT[0])-VOFFSET>=ARRAY_SIZE) then
//all right, couldn't fix it
call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
return null
endif
else
if (GetHandleId(tT[0])-OFFSET<0) or (GetHandleId(tT[0])-OFFSET>=ARRAY_SIZE) then
//all right, couldn't fix it
call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
return null
endif
endif
endif
endif
else
set tN=tN-1
endif
call SetTimerData(tT[tN],value)
return tT[tN]
endfunction
function NewTimer takes nothing returns timer
return NewTimerEx(0)
endfunction
//==========================================================================================
function ReleaseTimer takes timer t returns nothing
//set Dumb = Dumb - 1
//call BJDebugMsg("release " + I2S(Dumb))
if(t==null) then
debug call BJDebugMsg("Warning: attempt to release a null timer")
return
endif
if (tN==ARRAY_SIZE) then
debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")
//stack is full, the map already has much more troubles than the chance of bug
call DestroyTimer(t)
else
call TimerStart(t, 0, false, null)
call PauseTimer(t)
if(GetTimerData(t)==HELD) then
debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
return
endif
call SetTimerData(t,HELD)
set tT[tN]=t
set tN=tN+1
endif
endfunction
private function init takes nothing returns nothing
local integer i=0
local integer o=-1
local boolean oops = false
if ( didinit ) then
return
else
set didinit = true
endif
static if( USE_HASH_TABLE ) then
set ht = InitHashtable()
loop
exitwhen(i==QUANTITY)
set tT[i]=CreateTimer()
call SetTimerData(tT[i], HELD)
set i=i+1
endloop
set tN = QUANTITY
else
loop
set i=0
loop
exitwhen (i==QUANTITY)
set tT[i] = CreateTimer()
if(i==0) then
set VOFFSET = GetHandleId(tT[i])
static if(USE_FLEXIBLE_OFFSET) then
set o=VOFFSET
else
set o=OFFSET
endif
endif
if (GetHandleId(tT[i])-o>=ARRAY_SIZE) then
exitwhen true
endif
if (GetHandleId(tT[i])-o>=0) then
set i=i+1
endif
endloop
set tN = i
exitwhen(tN == QUANTITY)
set oops = true
exitwhen not USE_FLEXIBLE_OFFSET
debug call BJDebugMsg("TimerUtils_init: Failed a initialization attempt, will try again")
endloop
if(oops) then
static if ( USE_FLEXIBLE_OFFSET) then
debug call BJDebugMsg("The problem has been fixed.")
//If this message doesn't appear then there is so much
//handle id fragmentation that it was impossible to preload
//so many timers and the thread crashed! Therefore this
//debug message is useful.
elseif(DEBUG_MODE) then
call BJDebugMsg("There were problems and the new timer limit is "+I2S(i))
call BJDebugMsg("This is a rare ocurrence, if the timer limit is too low:")
call BJDebugMsg("a) Change USE_FLEXIBLE_OFFSET to true (reduces performance a little)")
call BJDebugMsg("b) or try changing OFFSET to "+I2S(VOFFSET) )
endif
endif
endif
endfunction
endlibrary
library_once WorldBounds /* v2.0.0.0
************************************************************************************
*
* struct WorldBounds extends array
* readonly static integer maxX
* readonly static integer maxY
* readonly static integer minX
* readonly static integer minY
* readonly static integer centerX
* readonly static integer centerY
* readonly static rect world
* readonly static region worldRegion
*
************************************************************************************/
private module WorldBoundInit
private static method onInit takes nothing returns nothing
set world=GetWorldBounds()
set maxX=R2I(GetRectMaxX(world))
set maxY=R2I(GetRectMaxY(world))
set minX=R2I(GetRectMinX(world))
set minY=R2I(GetRectMinY(world))
set centerX=R2I((maxX+minX)/2)
set centerY=R2I((minY+maxY)/2)
set worldRegion=CreateRegion()
call RegionAddRect(worldRegion,world)
endmethod
endmodule
struct WorldBounds extends array
readonly static integer maxX
readonly static integer maxY
readonly static integer minX
readonly static integer minY
readonly static integer centerX
readonly static integer centerY
readonly static rect world
readonly static region worldRegion
implement WorldBoundInit
endstruct
endlibrary
library UnitIndexer /* v4.0.2.7
*************************************************************************************
*
* Assigns unique indexes to units via unit user data.
*
*************************************************************************************
*
* */uses/*
*
* */ WorldBounds /* hiveworkshop.com/forums/jass-functions-413/snippet-worldbounds-180494/
* */ Event /* hiveworkshop.com/forums/submissions-414/snippet-event-186555/
*
************************************************************************************
*
* SETTINGS
*/
globals
constant integer ABILITIES_UNIT_INDEXER = 'A001'
endglobals
/*
************************************************************************************
*
* Functions
*
* function RegisterUnitIndexEvent takes boolexpr codeToRegister, Event unitIndexEvent returns nothing
* function TriggerRegisterUnitIndexEvent takes trigger triggerToRegister, Event unitIndexEvent returns nothing
*
* function GetUnitById takes integer index returns unit
* - Returns unit given a unit index
* function GetUnitId takes unit u returns integer
* - Returns unit index given a unit
*
* function IsUnitIndexed takes unit u returns boolean
* function IsUnitDeindexing takes unit u returns boolean
*
* function GetIndexedUnitId takes nothing returns integer
* function GetIndexedUnit takes nothing returns unit
*
************************************************************************************
*
* module UnitIndexStructMethods
* static method operator [] takes unit u returns thistype
* - Return GetUnitUserData(u)
*
* readonly unit unit
* - The indexed unit of the struct
*
************************************************************************************
*
* module UnitIndexStruct extends UnitIndexStructMethods
*
* - A pseudo module interface that runs a set of methods if they exist and provides
* - a few fields and operators. Runs on static ifs to minimize code.
*
* readonly boolean allocated
* - Is unit allocated for the struct
*
* Interface:
*
* - These methods don't have to exist. If they don't exist, the code
* - that calls them won't even be in the module.
*
* private method index takes nothing returns nothing
* - called when a unit is indexed and passes the filter.
* -
* - thistype this: Unit's index
* private method deindex takes nothing returns nothing
* - called when a unit is deindexed and is allocated for struct
* -
* - thistype this: Unit's index
* private static method filter takes unit unitToIndex returns boolean
* - Determines whether or not to allocate struct for unit
* -
* - unit unitToIndex: Unit being filtered
*
************************************************************************************
*
* struct UnitIndexer extends array
*
* - Controls the unit indexer system.
*
* static constant Event UnitIndexer.INDEX
* static constant Event UnitIndexer.DEINDEX
* - Don't register functions and triggers directly to the events. Register them via
* - RegisterUnitIndexEvent and TriggerRegisterUnitIndexEvent.
*
* static boolean enabled
* - Enables and disables unit indexing. Useful for filtering out dummy units.
*
************************************************************************************
*
* struct UnitIndex extends UnitIndexStructMethods
*
* - Constrols specific unit indexes.
*
* method lock takes nothing returns nothing
* - Locks an index. When an index is locked, it will not be recycled
* - when the unit is deindexed until all locks are removed. Deindex
* - events still fire at the appropriate times, the index just doesn't
* - get thrown into the recycler.
* method unlock takes nothing returns nothing
* - Unlocks an index.
*
************************************************************************************/
globals
private trigger q=CreateTrigger()
private trigger l=CreateTrigger()
private unit array e
private integer r=0
private integer y=0
private integer o=0
private boolean a=false
private integer array n
private integer array p
private integer array lc
endglobals
function GetIndexedUnitId takes nothing returns integer
return o
endfunction
function GetIndexedUnit takes nothing returns unit
return e[o]
endfunction
//! runtextmacro optional UNIT_LIST_LIB()
private struct PreLoader extends array
public static method run takes nothing returns nothing
call DestroyTimer(GetExpiredTimer())
set a=true
endmethod
public static method eval takes trigger t returns nothing
local integer f=n[0]
local integer d=o
loop
exitwhen 0==f
if (IsTriggerEnabled(t)) then
set o=f
if (TriggerEvaluate(t)) then
call TriggerExecute(t)
endif
else
exitwhen true
endif
set f=n[f]
endloop
set o=d
endmethod
public static method evalb takes boolexpr c returns nothing
local trigger t=CreateTrigger()
local thistype f=n[0]
local integer d=o
call TriggerAddCondition(t,c)
loop
exitwhen 0==f
set o=f
call TriggerEvaluate(t)
set f=n[f]
endloop
call DestroyTrigger(t)
set t=null
set o=d
endmethod
endstruct
//! runtextmacro optional UNIT_EVENT_MACRO()
private module UnitIndexerInit
private static method onInit takes nothing returns nothing
local integer i=bj_MAX_PLAYER_SLOTS
local boolexpr bc=Condition(function thistype.onLeave)
local boolexpr bc2=Condition(function thistype.onEnter)
local group g=CreateGroup()
local player p
set INDEX=CreateEvent()
set DEINDEX=CreateEvent()
call TriggerRegisterEnterRegion(q,WorldBounds.worldRegion,bc2)
loop
set p=Player(i)
call TriggerRegisterPlayerUnitEvent(l,p,EVENT_PLAYER_UNIT_ISSUED_ORDER,bc)
call SetPlayerAbilityAvailable(p,ABILITIES_UNIT_INDEXER,false)
call GroupEnumUnitsOfPlayer(g,p,bc2)
exitwhen 0==i
set i=i-1
endloop
call DestroyGroup(g)
set bc=null
set g=null
set bc2=null
set p=null
call TimerStart(CreateTimer(),0,false,function PreLoader.run)
endmethod
endmodule
struct UnitIndex extends array
method lock takes nothing returns nothing
debug if (null!=e[this]) then
set lc[this]=lc[this]+1
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"UNIT INDEXER ERROR: ATTEMPT TO LOCK NULL INDEX")
debug endif
endmethod
method unlock takes nothing returns nothing
debug if (0<lc[this]) then
set lc[this]=lc[this]-1
if (0==lc[this] and null==e[this]) then
set n[this]=y
set y=this
endif
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"UNIT INDEXER ERROR: ATTEMPT TO UNLOCK UNLOCKED INDEX")
debug endif
endmethod
method operator unit takes nothing returns unit
return e[this]
endmethod
static method operator [] takes unit whichUnit returns thistype
return GetUnitUserData(whichUnit)
endmethod
endstruct
struct UnitIndexer extends array
readonly static Event INDEX
readonly static Event DEINDEX
static boolean enabled=true
private static method onEnter takes nothing returns boolean
local unit Q=GetFilterUnit()
local integer i
local integer d=o
if (enabled and Q!=e[GetUnitUserData(Q)] and 0==GetUnitUserData(Q) and GetUnitTypeId(Q) != 'e02F') then
if (0==y) then
set r=r+1
set i=r
else
set i=y
set y=n[y]
endif
call UnitAddAbility(Q,ABILITIES_UNIT_INDEXER)
call UnitMakeAbilityPermanent(Q,true,ABILITIES_UNIT_INDEXER)
call SetUnitUserData(Q,i)
set e[i]=Q
static if not LIBRARY_UnitList then
if (not a)then
set p[i]=p[0]
set n[p[0]]=i
set n[i]=0
set p[0]=i
endif
else
set p[i]=p[0]
set n[p[0]]=i
set n[i]=0
set p[0]=i
call GroupAddUnit(g,e[i])
endif
set o=i
call FireEvent(INDEX)
set o=d
endif
set Q=null
return false
endmethod
private static method onLeave takes nothing returns boolean
static if LIBRARY_UnitEvent then
implement optional UnitEventModule
else
local unit u=GetFilterUnit()
local integer i=GetUnitUserData(u)
local integer d=o
if (0==GetUnitAbilityLevel(u,ABILITIES_UNIT_INDEXER) and u==e[i]) then
static if not LIBRARY_UnitList then
if (not a)then
set n[p[i]]=n[i]
set p[n[i]]=p[i]
endif
else
set n[p[i]]=n[i]
set p[n[i]]=p[i]
call GroupRemoveUnit(g,e[i])
endif
set o=i
call FireEvent(DEINDEX)
set o=d
if (0==lc[i]) then
set n[i]=y
set y=i
endif
set e[i]=null
endif
set u=null
endif
return false
endmethod
implement UnitIndexerInit
endstruct
//! runtextmacro optional UNIT_EVENT_MACRO_2()
function RegisterUnitIndexEvent takes boolexpr c,integer ev returns nothing
call RegisterEvent(c, ev)
if (not a and ev==UnitIndexer.INDEX and 0!=n[0]) then
call PreLoader.evalb(c)
endif
endfunction
function TriggerRegisterUnitIndexEvent takes trigger t,integer ev returns nothing
call TriggerRegisterEvent(t,ev)
if (not a and ev == UnitIndexer.INDEX and 0!=n[0]) then
call PreLoader.eval(t)
endif
endfunction
function GetUnitById takes integer W returns unit
return e[W]
endfunction
function GetUnitId takes unit u returns integer
return GetUnitUserData(u)
endfunction
function IsUnitIndexed takes unit u returns boolean
return u==e[GetUnitUserData(u)]
endfunction
function IsUnitDeindexing takes unit u returns boolean
return IsUnitIndexed(u) and 0==GetUnitAbilityLevel(u,ABILITIES_UNIT_INDEXER)
endfunction
module UnitIndexStructMethods
static method operator [] takes unit u returns thistype
return GetUnitUserData(u)
endmethod
method operator unit takes nothing returns unit
return e[this]
endmethod
endmodule
module UnitIndexStruct
implement UnitIndexStructMethods
static if thistype.filter.exists then
static if thistype.index.exists then
static if thistype.deindex.exists then
readonly boolean allocated
else
method operator allocated takes nothing returns boolean
return filter(e[this])
endmethod
endif
else
method operator allocated takes nothing returns boolean
return filter(e[this])
endmethod
endif
elseif (thistype.index.exists) then
static if thistype.deindex.exists then
readonly boolean allocated
else
method operator allocated takes nothing returns boolean
return this==GetUnitUserData(e[this])
endmethod
endif
else
method operator allocated takes nothing returns boolean
return this==GetUnitUserData(e[this])
endmethod
endif
static if thistype.index.exists then
private static method onIndexEvent takes nothing returns boolean
static if thistype.filter.exists then
if (filter(e[o])) then
static if thistype.deindex.exists then
set thistype(o).allocated=true
endif
call thistype(o).index()
endif
else
static if thistype.deindex.exists then
set thistype(o).allocated=true
endif
call thistype(o).index()
endif
return false
endmethod
endif
static if thistype.deindex.exists then
private static method onDeindexEvent takes nothing returns boolean
static if thistype.filter.exists then
static if thistype.index.exists then
if (thistype(o).allocated) then
set thistype(o).allocated=false
call thistype(o).deindex()
endif
else
if (filter(e[o])) then
call thistype(o).deindex()
endif
endif
else
static if thistype.index.exists then
set thistype(o).allocated=false
endif
call thistype(o).deindex()
endif
return false
endmethod
endif
static if thistype.index.exists then
static if thistype.deindex.exists then
private static method onInit takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function thistype.onIndexEvent),UnitIndexer.INDEX)
call RegisterUnitIndexEvent(Condition(function thistype.onDeindexEvent),UnitIndexer.DEINDEX)
endmethod
else
private static method onInit takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function thistype.onIndexEvent),UnitIndexer.INDEX)
endmethod
endif
elseif thistype.deindex.exists then
private static method onInit takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function thistype.onDeindexEvent),UnitIndexer.DEINDEX)
endmethod
endif
endmodule
endlibrary
library Queue /* v1.0.0.6
************************************************************************************
*
* */uses/*
*
* */ ErrorMessage /* hiveworkshop.com/forums/submissions-414/snippet-error-message-239210/
*
************************************************************************************
*
* module Queue
*
* Description
* -------------------------
*
* NA
*
* Fields
* -------------------------
*
* readonly static integer sentinel
*
* readonly thistype first
* readonly thistype next
*
* Methods
* -------------------------
*
* static method create takes nothing returns thistype
* method destroy takes nothing returns nothing
* - May only destroy queues
*
* method enqueue takes nothing returns thistype
* method pop takes nothing returns nothing
*
* method clear takes nothing returns nothing
*
* debug static method calculateMemoryUsage takes nothing returns integer
* debug static method getAllocatedMemoryAsString takes nothing returns string
*
************************************************************************************/
module Queue
private static thistype collectionCount = 0
private static thistype nodeCount = 0
debug private boolean isNode
debug private boolean isCollection
private thistype last
private thistype _next
method operator next takes nothing returns thistype
debug call ThrowError(this == 0, "Queue", "next", "thistype", this, "Attempted To Go Out Of Bounds.")
debug call ThrowError(not isNode, "Queue", "next", "thistype", this, "Attempted To Read Invalid Node.")
return _next
endmethod
private thistype _first
method operator first takes nothing returns thistype
debug call ThrowError(this == 0, "Queue", "first", "thistype", this, "Attempted To Read Null Queue.")
debug call ThrowError(not isCollection, "Queue", "first", "thistype", this, "Attempted To Read Invalid Queue.")
return _first
endmethod
static method operator sentinel takes nothing returns integer
return 0
endmethod
private static method allocateCollection takes nothing returns thistype
local thistype this = thistype(0)._first
if (0 == this) then
debug call ThrowError(collectionCount == 8191, "Queue", "allocateCollection", "thistype", 0, "Overflow.")
set this = collectionCount + 1
set collectionCount = this
else
set thistype(0)._first = _first
endif
return this
endmethod
private static method allocateNode takes nothing returns thistype
local thistype this = thistype(0)._next
if (0 == this) then
debug call ThrowError(nodeCount == 8191, "Queue", "allocateNode", "thistype", 0, "Overflow.")
set this = nodeCount + 1
set nodeCount = this
else
set thistype(0)._next = _next
endif
return this
endmethod
static method create takes nothing returns thistype
local thistype this = allocateCollection()
debug set isCollection = true
set _first = 0
return this
endmethod
method enqueue takes nothing returns thistype
local thistype node = allocateNode()
debug call ThrowError(this == 0, "Queue", "enqueue", "thistype", this, "Attempted To Enqueue On To Null Queue.")
debug call ThrowError(not isCollection, "Queue", "enqueue", "thistype", this, "Attempted To Enqueue On To Invalid Queue.")
debug set node.isNode = true
if (_first == 0) then
set _first = node
else
set last._next = node
endif
set last = node
set node._next = 0
return node
endmethod
method pop takes nothing returns nothing
local thistype node = _first
debug call ThrowError(this == 0, "Queue", "pop", "thistype", this, "Attempted To Pop Null Queue.")
debug call ThrowError(not isCollection, "Queue", "pop", "thistype", this, "Attempted To Pop Invalid Queue.")
debug call ThrowError(node == 0, "Queue", "pop", "thistype", this, "Attempted To Pop Empty Queue.")
debug set node.isNode = false
set _first = node._next
set node._next = thistype(0)._next
set thistype(0)._next = node
endmethod
method clear takes nothing returns nothing
debug local thistype node = _first
debug call ThrowError(this == 0, "Queue", "clear", "thistype", this, "Attempted To Clear Null Queue.")
debug call ThrowError(not isCollection, "Queue", "clear", "thistype", this, "Attempted To Clear Invalid Queue.")
static if DEBUG_MODE then
loop
exitwhen node == 0
set node.isNode = false
set node = node._next
endloop
endif
if (_first == 0) then
return
endif
set last._next = thistype(0)._next
set thistype(0)._next = _first
set _first = 0
endmethod
method destroy takes nothing returns nothing
debug call ThrowError(this == 0, "Queue", "destroy", "thistype", this, "Attempted To Destroy Null Queue.")
debug call ThrowError(not isCollection, "Queue", "destroy", "thistype", this, "Attempted To Destroy Invalid Queue.")
static if DEBUG_MODE then
debug call clear()
debug set isCollection = false
else
if (_first != 0) then
set last._next = thistype(0)._next
set thistype(0)._next = _first
endif
endif
set _first = thistype(0)._first
set thistype(0)._first = this
endmethod
static if DEBUG_MODE then
static method calculateMemoryUsage takes nothing returns integer
local thistype start = 1
local thistype end = 8191
local integer count = 0
loop
exitwhen integer(start) > integer(end)
if (integer(start) + 500 > integer(end)) then
return count + checkRegion(start, end)
else
set count = count + checkRegion(start, start + 500)
set start = start + 501
endif
endloop
return count
endmethod
private static method checkRegion takes thistype start, thistype end returns integer
local integer count = 0
loop
exitwhen integer(start) > integer(end)
if (start.isNode) then
set count = count + 1
endif
if (start.isCollection) then
set count = count + 1
endif
set start = start + 1
endloop
return count
endmethod
static method getAllocatedMemoryAsString takes nothing returns string
local thistype start = 1
local thistype end = 8191
local string memory = null
loop
exitwhen integer(start) > integer(end)
if (integer(start) + 500 > integer(end)) then
if (memory != null) then
set memory = memory + ", "
endif
set memory = memory + checkRegion2(start, end)
set start = end + 1
else
if (memory != null) then
set memory = memory + ", "
endif
set memory = memory + checkRegion2(start, start + 500)
set start = start + 501
endif
endloop
return memory
endmethod
private static method checkRegion2 takes thistype start, thistype end returns string
local string memory = null
loop
exitwhen integer(start) > integer(end)
if (start.isNode) then
if (memory == null) then
set memory = I2S(start)
else
set memory = memory + ", " + I2S(start) + "N"
endif
endif
if (start.isCollection) then
if (memory == null) then
set memory = I2S(start)
else
set memory = memory + ", " + I2S(start) + "C"
endif
endif
set start = start + 1
endloop
return memory
endmethod
endif
endmodule
endlibrary
library Stack /* v1.0.0.7
************************************************************************************
*
* */uses/*
*
* */ ErrorMessage /* hiveworkshop.com/forums/submissions-414/snippet-error-message-239210/
*
************************************************************************************
*
* module Stack
*
* Description
* -------------------------
*
* NA
*
* Fields
* -------------------------
*
* readonly static integer sentinel
*
* readonly thistype first
* readonly thistype next
*
* Methods
* -------------------------
*
* static method create takes nothing returns thistype
* method destroy takes nothing returns nothing
* - May only destroy stacks
*
* method push takes nothing returns thistype
* method pop takes nothing returns nothing
*
* method clear takes nothing returns nothing
*
* debug static method calculateMemoryUsage takes nothing returns integer
* debug static method getAllocatedMemoryAsString takes nothing returns string
*
************************************************************************************/
module Stack
private static thistype collectionCount = 0
private static thistype nodeCount = 0
debug private boolean isNode
debug private boolean isCollection
private thistype _next
method operator next takes nothing returns thistype
debug call ThrowError(this == 0, "Stack", "next", "thistype", this, "Attempted To Go Out Of Bounds.")
debug call ThrowError(not isNode, "Stack", "next", "thistype", this, "Attempted To Read Invalid Node.")
return _next
endmethod
private thistype _first
method operator first takes nothing returns thistype
debug call ThrowError(this == 0, "Stack", "first", "thistype", this, "Attempted To Read Null Stack.")
debug call ThrowError(not isCollection, "Stack", "first", "thistype", this, "Attempted To Read Invalid Stack.")
return _first
endmethod
static method operator sentinel takes nothing returns integer
return 0
endmethod
private static method allocateCollection takes nothing returns thistype
local thistype this = thistype(0)._first
if (0 == this) then
debug call ThrowError(collectionCount == 8191, "Stack", "allocateCollection", "thistype", 0, "Overflow.")
set this = collectionCount + 1
set collectionCount = this
else
set thistype(0)._first = _first
endif
return this
endmethod
private static method allocateNode takes nothing returns thistype
local thistype this = thistype(0)._next
if (0 == this) then
debug call ThrowError(nodeCount == 8191, "Stack", "allocateNode", "thistype", 0, "Overflow.")
set this = nodeCount + 1
set nodeCount = this
else
set thistype(0)._next = _next
endif
return this
endmethod
static method create takes nothing returns thistype
local thistype this = allocateCollection()
debug set isCollection = true
set _first = 0
return this
endmethod
method push takes nothing returns thistype
local thistype node = allocateNode()
debug call ThrowError(this == 0, "Stack", "push", "thistype", this, "Attempted To Push On To Null Stack.")
debug call ThrowError(not isCollection, "Stack", "push", "thistype", this, "Attempted To Push On To Invalid Stack.")
debug set node.isNode = true
set node._next = _first
set _first = node
return node
endmethod
method pop takes nothing returns nothing
local thistype node = _first
debug call ThrowError(this == 0, "Stack", "pop", "thistype", this, "Attempted To Pop Null Stack.")
debug call ThrowError(not isCollection, "Stack", "pop", "thistype", this, "Attempted To Pop Invalid Stack.")
debug call ThrowError(node == 0, "Stack", "pop", "thistype", this, "Attempted To Pop Empty Stack.")
debug set node.isNode = false
set _first = node._next
set node._next = thistype(0)._next
set thistype(0)._next = node
endmethod
private method getBottom takes nothing returns thistype
set this = _first
loop
exitwhen _next == 0
set this = _next
endloop
return this
endmethod
method clear takes nothing returns nothing
debug local thistype node = _first
debug call ThrowError(this == 0, "Stack", "clear", "thistype", this, "Attempted To Clear Null Stack.")
debug call ThrowError(not isCollection, "Stack", "clear", "thistype", this, "Attempted To Clear Invalid Stack.")
static if DEBUG_MODE then
loop
exitwhen node == 0
set node.isNode = false
set node = node._next
endloop
endif
if (_first == 0) then
return
endif
set getBottom()._next = thistype(0)._next
set thistype(0)._next = _first
set _first = 0
endmethod
method destroy takes nothing returns nothing
debug call ThrowError(this == 0, "Stack", "destroy", "thistype", this, "Attempted To Destroy Null Stack.")
debug call ThrowError(not isCollection, "Stack", "destroy", "thistype", this, "Attempted To Destroy Invalid Stack.")
static if DEBUG_MODE then
debug call clear()
debug set isCollection = false
else
if (_first != 0) then
set getBottom()._next = thistype(0)._next
set thistype(0)._next = _first
endif
endif
set _first = thistype(0)._first
set thistype(0)._first = this
endmethod
static if DEBUG_MODE then
static method calculateMemoryUsage takes nothing returns integer
local thistype start = 1
local thistype end = 8191
local integer count = 0
loop
exitwhen integer(start) > integer(end)
if (integer(start) + 500 > integer(end)) then
return count + checkRegion(start, end)
else
set count = count + checkRegion(start, start + 500)
set start = start + 501
endif
endloop
return count
endmethod
private static method checkRegion takes thistype start, thistype end returns integer
local integer count = 0
loop
exitwhen integer(start) > integer(end)
if (start.isNode) then
set count = count + 1
endif
if (start.isCollection) then
set count = count + 1
endif
set start = start + 1
endloop
return count
endmethod
static method getAllocatedMemoryAsString takes nothing returns string
local thistype start = 1
local thistype end = 8191
local string memory = null
loop
exitwhen integer(start) > integer(end)
if (integer(start) + 500 > integer(end)) then
if (memory != null) then
set memory = memory + ", "
endif
set memory = memory + checkRegion2(start, end)
set start = end + 1
else
if (memory != null) then
set memory = memory + ", "
endif
set memory = memory + checkRegion2(start, start + 500)
set start = start + 501
endif
endloop
return memory
endmethod
private static method checkRegion2 takes thistype start, thistype end returns string
local string memory = null
loop
exitwhen integer(start) > integer(end)
if (start.isNode) then
if (memory == null) then
set memory = I2S(start)
else
set memory = memory + ", " + I2S(start) + "N"
endif
endif
if (start.isCollection) then
if (memory == null) then
set memory = I2S(start)
else
set memory = memory + ", " + I2S(start) + "C"
endif
endif
set start = start + 1
endloop
return memory
endmethod
endif
endmodule
endlibrary
scope MultiArray // v1.0.0
/****************************************************************************************
== MultiArray ==
by: Dalvengyr
I. Description
¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Allows you to declare a multidimensional array variable.
Basically is an over-sized one-dimensional array variable represented in
a fairly decent multi-dimensional array interface.
The variable could be declared as a global or a static struct member.
II. Disadvantages
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- Allocate tons of memory space for each generated variable.
- Has max size of 2023.
III. API
¯¯¯¯¯¯¯¯
1. Declaring new variable
| //! textmacro CREATE_MULTI_ARRAY takes TYPE, NAME, DIMENSION
TYPE => integer, real, unit, string, etc.
NAME => the variable's name
2. Write the declared variable somewhere (global, struct, etc.)
| //! textmacro PASTE_MULTI_ARRAY_VARIABLE takes PREFIX, NAME
NAME => the variable's name
PREFIX => private, public, static, constant, etc.
3. Initialize the variable, should be placed at map init
| //! textmacro INIT_MULTI_ARRAY_VARIABLE takes NAME
4. Returns max index you may use
| method operator maxIndex takes nothing returns integer
5. Returns dimension of the variable
| method operator dimension takes nothing returns integer
6. Returns the contained value based on assigned indexes.
| method operator value takes nothing returns $TYPE$
| method operator [] takes integer i returns thistype
| method operator []= takes integer i, $TYPE$ param returns nothing
V. Link
¯¯¯¯¯¯¯
-
***************************************************************************************/
//! textmacro INIT_MULTI_ARRAY_VARIABLE takes NAME
set $NAME$ = MultiArray__$NAME$__s.create()
//! endtextmacro
// Write the variable declaration somewhere (globals, struct, etc.)
//! textmacro PASTE_MULTI_ARRAY_VARIABLE takes PREFIX, NAME
$PREFIX$ MultiArray__$NAME$__s $NAME$
//! endtextmacro
//! textmacro CREATE_MULTI_ARRAY takes TYPE, NAME, DIMENSION
scope MultiArray$NAME$var
globals
// Allocated array size per container
private constant integer ALLOCATED_SPACE = 0x63EAE
// Max index for each dimension for the generated variable
private constant integer MAX_INDEX = R2I(Pow(ALLOCATED_SPACE*10, 1./$DIMENSION$))
// Containers
private $TYPE$ array Container__1[ALLOCATED_SPACE]
private $TYPE$ array Container__2[ALLOCATED_SPACE]
private $TYPE$ array Container__3[ALLOCATED_SPACE]
private $TYPE$ array Container__4[ALLOCATED_SPACE]
private $TYPE$ array Container__5[ALLOCATED_SPACE]
private $TYPE$ array Container__6[ALLOCATED_SPACE]
private $TYPE$ array Container__7[ALLOCATED_SPACE]
private $TYPE$ array Container__8[ALLOCATED_SPACE]
private $TYPE$ array Container__9[ALLOCATED_SPACE]
private $TYPE$ array Container__10[ALLOCATED_SPACE]
endglobals
struct MultiArray__$NAME$__s
private static integer read = 0
private static integer array indices
// Check whether some conditions are valid or not
private static method validateIndices takes string state returns boolean
local integer i = 0
// Check the size boundary
loop
exitwhen i == $DIMENSION$
if indices[i] < 0 or indices[i] >= MAX_INDEX then
debug call BJDebugMsg("$Error occured :: NAME$ var (on " + state + ") :: index-" + I2S(i+1) + " is out of bound of 0 or " + I2S(MAX_INDEX-1) + " at " + I2S(indices[i]) + ".")
return false
endif
set i = i + 1
endloop
// If the assigned dimension is valid
if read < $DIMENSION$ then
debug call BJDebugMsg("Error occured :: $NAME$ var (on " + state + ") :: index-" + I2S($DIMENSION$-($DIMENSION$-read-1)) + " couldn't be read.")
return false
elseif read > $DIMENSION$ then
debug call BJDebugMsg("Error occured :: $NAME$ var (on " + state + ") :: assigned indexes oversized the dimension of " + I2S($DIMENSION$) + " at " + I2S(read) + ".")
return false
endif
return true
endmethod
// Returns address based on assigned indices (indexes)
private static method getMemoryOffset takes nothing returns integer
local integer i = 1
local integer result = indices[0]
loop
exitwhen i == $DIMENSION$
set result = result * MAX_INDEX + indices[i]
set i = i + 1
endloop
return result
endmethod
// Max index which user may use
method operator maxIndex takes nothing returns integer
return MAX_INDEX-1
endmethod
// Dimension of generated variable
method operator dimension takes nothing returns integer
return $DIMENSION$
endmethod
// Returns the current value of generated variable
method operator value takes nothing returns $TYPE$
local integer loc
local integer offset
local integer index
if not validateIndices("read") then
set read = 0
endif
// Calculate the address
set offset = getMemoryOffset()
set loc = offset/ALLOCATED_SPACE
set index = offset-loc*ALLOCATED_SPACE
set read = 0
// Locate the position of the address
if loc == 0 then
return Container__1[index]
elseif loc == 1 then
return Container__2[index]
elseif loc == 2 then
return Container__3[index]
elseif loc == 3 then
return Container__4[index]
elseif loc == 4 then
return Container__5[index]
elseif loc == 5 then
return Container__6[index]
elseif loc == 6 then
return Container__7[index]
elseif loc == 7 then
return Container__8[index]
elseif loc == 8 then
return Container__9[index]
elseif loc == 9 then
return Container__10[index]
endif
return 0
endmethod
// Read indices (indexes)
method operator [] takes integer i returns thistype
set indices[read] = i
set read = read + 1
return this
endmethod
// Assign a value to the generated variable
method operator []= takes integer i, $TYPE$ param returns nothing
local integer loc
local integer offset
local integer index
// Read the last index
set indices[read] = i
set read = read + 1
if not validateIndices("write") then
set read = 0
endif
// Calculate the address
set offset = getMemoryOffset()
set loc = offset/ALLOCATED_SPACE
set index = offset-loc*ALLOCATED_SPACE
set read = 0
// Locate the position of the address
if loc == 0 then
set Container__1[index] = param
elseif loc == 1 then
set Container__2[index] = param
elseif loc == 2 then
set Container__3[index] = param
elseif loc == 3 then
set Container__4[index] = param
elseif loc == 4 then
set Container__5[index] = param
elseif loc == 5 then
set Container__6[index] = param
elseif loc == 6 then
set Container__7[index] = param
elseif loc == 7 then
set Container__8[index] = param
elseif loc == 8 then
set Container__9[index] = param
elseif loc == 9 then
set Container__10[index] = param
endif
endmethod
endstruct
endscope
//! endtextmacro
endscope
library Track /* v3.1.0.0
*****************************************************************************
*
* Manages trackable objects, allowing for easy event registrations, data
* retrieval, and the capability of retrieving which player interacted with
* the trackable.
*
*****************************************************************************
*
* */uses/*
*
* */ Table /* hiveworkshop.com/forums/jass-functions-413/snippet-new-table-188084/
*
*****************************************************************************
*
* SETTINGS
*/
globals
private constant integer PLATFORM = 'OTip'
endglobals
/*
*****************************************************************************
*
* FUNCTIONS
*
* CreateTrack( string modelPath, real x, real y, real z, real facing ) returns Track
* - Creates a trackable of modelPath at coordinates ( x, y, z ) with
* - "facing" in radians. Returns the trackable instance.
*
* CreateTrackForPlayer( string modelPath, real x, real y, real z, real facing, player who ) returns Track
* - Same as function above, but creates it for one player.
*
* RegisterAnyClickEvent( code c ) returns nothing
* RegisterAnyHoverEvent( code c ) returns nothing
* - Fires "c" when any trackable is clicked or hovered.
*
* RegisterClickEvent( Track obj, code c ) returns nothing
* RegisterHoverEvent( Track obj, code c ) returns nothing
* - Fires "c" when the trackable of "obj" is clicked or hovered respectively.
* RegisterInteractEvent( Track obj, code c ) returns nothing
* - Fires "c" when the trackable of "obj" is clicked or hovered.
* - Use GetTriggerEventId() == EVENT_GAME_TRACKABLE_TRACK
* to differentiate between the two event occurrences. This
* method is more efficient on handles than the two above.
*
* EnableTrackInstance( Track obj, boolean flag ) returns nothing
* - A disabled Track instance will not fire its events.
* - Track instances are enabled by default.
* IsTrackInstanceEnabled( Track obj ) returns boolean
* - Returns whether an instance is enabled.
*
* EVENT RESPONSES
*
* GetTriggerTrackInstance() returns Track
* - Returns the Track instance that had a player interaction.
* GetTriggerTrackable() returns trackable
* - Returns the trackable object that had a player interaction.
* GetTriggerTrackablePlayer() returns player
* - Returns the player that interacted with the trackable object.
*
*****************************************************************************
*
* struct Track
*
* static Track instance
* - The triggering instance of the event.
* static trackable object
* - The triggering trackable object of the event.
* static player tracker
* - The player who interacted with the trackable object.
*
* readonly real x
* readonly real y
* readonly real z
* readonly real facing
* readonly string model
* - Instance properties.
* - Warning: the invisible platform has a default z-value
* of 2.94794. So if you input 0 into the system, it'll
* end up ~3 units above the ground. For an alternative model,
* see: [url]http://www.hiveworkshop.com/forums/2661555-post54.html[/url]
*
* method operator enabled= takes boolean flag returns nothing
* method operator enabled takes nothing returns boolean
*
* static method create takes string modelPath, real x, real y, real z, real facing returns Track
* static method createForPlayer takes string modelPath, real x, real y, real z, real facing, player p returns Track
*
* static method registerAnyClick takes code c returns nothing
* static method registerAnyHover takes code c returns nothing
*
* method registerClick takes code c returns nothing
* method registerHover takes code c returns nothing
* method registerInteract takes code c returns nothing
*
* - All equivalent to their function counterparts.
*
*****************************************************************************
*
* Credits
* - Azlier: Trackable2 (inspiration)
* - Arhowk: bugfix
* - Dalvengyr: bugfix from a typo.
* - Uberplayer: bugfix; info on the invisible platform Z issue.
*
****************************************************************************/
private module Init
private static method onInit takes nothing returns nothing
set thistype.TrackTable = Table.create()
endmethod
endmodule
struct Track extends array
private static trigger anyClick = CreateTrigger()
private static trigger anyHover = CreateTrigger()
private static Table TrackTable = 0
static thistype instance = 0
static trackable object = null
static player tracker = null
private static integer ic = 0
private static integer ir = 0
private thistype rn
readonly real x
readonly real y
readonly real z
readonly real facing
readonly string model
private trigger reg
private trigger onClick
private trigger onHover
private Table playerIndex
boolean enabled
static method registerAnyClick takes code c returns nothing
call TriggerAddCondition(.anyClick, Filter(c))
endmethod
static method registerAnyHover takes code c returns nothing
call TriggerAddCondition(.anyHover, Filter(c))
endmethod
method registerClick takes code c returns nothing
if .onClick == null then
set .onClick = CreateTrigger()
endif
call TriggerAddCondition(.onClick, Filter(c))
endmethod
method registerHover takes code c returns nothing
if .onHover == null then
set .onHover = CreateTrigger()
endif
call TriggerAddCondition(.onHover, Filter(c))
endmethod
method registerInteract takes code c returns nothing
call TriggerAddCondition(.reg, Filter(c))
endmethod
method destroy takes nothing returns nothing
call TrackTable.remove(GetHandleId(.reg))
call DestroyTrigger(.reg)
call DestroyTrigger(.onClick)
call DestroyTrigger(.onHover)
call .playerIndex.destroy()
set .rn = ir
set ir = this
endmethod
private static method onInteract takes nothing returns boolean
set instance = TrackTable[GetHandleId(GetTriggeringTrigger())]
if instance.enabled then
set object = GetTriggeringTrackable()
set tracker = Player(instance.playerIndex[GetHandleId(object)])
if GetTriggerEventId() == EVENT_GAME_TRACKABLE_TRACK then
call TriggerEvaluate(instance.onHover)
call TriggerEvaluate(anyHover)
else
call TriggerEvaluate(instance.onClick)
call TriggerEvaluate(anyClick)
endif
endif
return false
endmethod
private static method createTrack takes string modelPath, real x, real y, real z, real facing, player j returns thistype
local destructable dest = null
local thistype this = ir
local integer i = 11
local trackable tr
local player p
local string s
/* Allocate */
if this == 0 then
set ic = ic + 1
set this = ic
else
set ir = .rn
endif
/* Create platform to give the trackable a z-offset */
if z != 0 then
set dest = CreateDestructableZ(PLATFORM, x, y, z, 0, 1, 0)
endif
if j != null then
set i = GetPlayerId(j)
endif
set .x = x
set .y = y
set .z = z
set .enabled = true
set .facing = facing
set .model = modelPath
set .reg = CreateTrigger()
set .onClick = null
set .onHover = null
set .playerIndex = Table.create()
set TrackTable[GetHandleId(.reg)] = this
call TriggerAddCondition(.reg, Condition(function thistype.onInteract))
/* Create a separate trackable for each player playing */
loop
set p = Player(i)
if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p) == MAP_CONTROL_USER then
if GetLocalPlayer() == p then
set s = modelPath
else
set s = ""
endif
set tr = CreateTrackable(s, .x, .y, .facing)
call TriggerRegisterTrackableHitEvent(.reg, tr)
call TriggerRegisterTrackableTrackEvent(.reg, tr)
set .playerIndex[GetHandleId(tr)] = i
exitwhen j != null
endif
exitwhen i == 0
set i = i - 1
endloop
/* Remove the platform if it exists */
if dest != null then
call RemoveDestructable(dest)
set dest = null
endif
set p = null
set tr = null
return this
endmethod
static method create takes string modelPath, real x, real y, real z, real facing returns thistype
return thistype.createTrack(modelPath, x, y, z, facing, null)
endmethod
static method createForPlayer takes string modelPath, real x, real y, real z, real facing, player p returns thistype
if not (GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p) == MAP_CONTROL_USER) then
return 0
endif
return thistype.createTrack(modelPath, x, y, z, facing, p)
endmethod
implement Init
endstruct
/* Function Wrappers */
function CreateTrack takes string modelPath, real x, real y, real z, real facing returns Track
return Track.create(modelPath, x, y, z, facing)
endfunction
function CreateTrackForPlayer takes string modelPath, real x, real y, real z, real facing, player who returns Track
return Track.createForPlayer(modelPath, x, y, z, facing, who)
endfunction
function EnableTrackInstance takes Track instance, boolean flag returns nothing
set instance.enabled = flag
endfunction
function IsTrackInstanceEnabled takes Track instance returns boolean
return instance.enabled
endfunction
function RegisterAnyClickEvent takes code c returns nothing
call Track.registerAnyClick(c)
endfunction
function RegisterAnyHoverEvent takes code c returns nothing
call Track.registerAnyHover(c)
endfunction
function RegisterClickEvent takes Track obj, code c returns nothing
call obj.registerClick(c)
endfunction
function RegisterHoverEvent takes Track obj, code c returns nothing
call obj.registerHover(c)
endfunction
function RegisterInteractEvent takes Track obj, code c returns nothing
call obj.registerInteract(c)
endfunction
function GetTriggerTrackInstance takes nothing returns Track
return Track.instance
endfunction
function GetTriggerTrackable takes nothing returns trackable
return Track.object
endfunction
function GetTriggerTrackablePlayer takes nothing returns player
return Track.tracker
endfunction
endlibrary
library Table /* made by Bribe, special thanks to Vexorian & Nestharus, version 4.1.0.1.
One map, one hashtable. Welcome to NewTable 4.1.0.1
This newest iteration of Table introduces the new HashTable struct.
You can now instantiate HashTables which enables the use of large
parent and large child keys, just like a standard hashtable. Previously,
the user would have to instantiate a Table to do this on their own which -
while doable - is something the user should not have to do if I can add it
to this resource myself (especially if they are inexperienced).
This library was originally called NewTable so it didn't conflict with
the API of Table by Vexorian. However, the damage is done and it's too
late to change the library name now. To help with damage control, I
have provided an extension library called TableBC, which bridges all
the functionality of Vexorian's Table except for 2-D string arrays &
the ".flush(integer)" method. I use ".flush()" to flush a child hash-
table, because I wanted the API in NewTable to reflect the API of real
hashtables (I thought this would be more intuitive).
API
------------
struct Table
| static method create takes nothing returns Table
| create a new Table
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush all stored values inside of it
|
| method remove takes integer key returns nothing
| remove the value at index "key"
|
| method operator []= takes integer key, $TYPE$ value returns nothing
| assign "value" to index "key"
|
| method operator [] takes integer key returns $TYPE$
| load the value at index "key"
|
| method has takes integer key returns boolean
| whether or not the key was assigned
|
----------------
struct TableArray
| static method operator [] takes integer array_size returns TableArray
| create a new array of Tables of size "array_size"
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush and destroy it
|
| method operator size takes nothing returns integer
| returns the size of the TableArray
|
| method operator [] takes integer key returns Table
| returns a Table accessible exclusively to index "key"
*/
globals
private integer less = 0 //Index generation for TableArrays (below 0).
private integer more = 8190 //Index generation for Tables.
//Configure it if you use more than 8190 "key" variables in your map (this will never happen though).
private hashtable ht = InitHashtable()
private key sizeK
private key listK
endglobals
private struct dex extends array
static method operator size takes nothing returns Table
return sizeK
endmethod
static method operator list takes nothing returns Table
return listK
endmethod
endstruct
private struct handles extends array
method has takes integer key returns boolean
return HaveSavedHandle(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedHandle(ht, this, key)
endmethod
endstruct
private struct agents extends array
method operator []= takes integer key, agent value returns nothing
call SaveAgentHandle(ht, this, key, value)
endmethod
endstruct
//! textmacro NEW_ARRAY_BASIC takes SUPER, FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$(ht, this, key, value)
endmethod
method has takes integer key returns boolean
return HaveSaved$SUPER$(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSaved$SUPER$(ht, this, key)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//! textmacro NEW_ARRAY takes FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$Handle(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$Handle(ht, this, key, value)
endmethod
method has takes integer key returns boolean
return HaveSavedHandle(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedHandle(ht, this, key)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//Run these textmacros to include the entire hashtable API as wrappers.
//Don't be intimidated by the number of macros - Vexorian's map optimizer is
//supposed to kill functions which inline (all of these functions inline).
//! runtextmacro NEW_ARRAY_BASIC("Real", "Real", "real")
//! runtextmacro NEW_ARRAY_BASIC("Boolean", "Boolean", "boolean")
//! runtextmacro NEW_ARRAY_BASIC("String", "Str", "string")
//New textmacro to allow table.integer[] syntax for compatibility with textmacros that might desire it.
//! runtextmacro NEW_ARRAY_BASIC("Integer", "Integer", "integer")
//! runtextmacro NEW_ARRAY("Player", "player")
//! runtextmacro NEW_ARRAY("Widget", "widget")
//! runtextmacro NEW_ARRAY("Destructable", "destructable")
//! runtextmacro NEW_ARRAY("Item", "item")
//! runtextmacro NEW_ARRAY("Unit", "unit")
//! runtextmacro NEW_ARRAY("Ability", "ability")
//! runtextmacro NEW_ARRAY("Timer", "timer")
//! runtextmacro NEW_ARRAY("Trigger", "trigger")
//! runtextmacro NEW_ARRAY("TriggerCondition", "triggercondition")
//! runtextmacro NEW_ARRAY("TriggerAction", "triggeraction")
//! runtextmacro NEW_ARRAY("TriggerEvent", "event")
//! runtextmacro NEW_ARRAY("Force", "force")
//! runtextmacro NEW_ARRAY("Group", "group")
//! runtextmacro NEW_ARRAY("Location", "location")
//! runtextmacro NEW_ARRAY("Rect", "rect")
//! runtextmacro NEW_ARRAY("BooleanExpr", "boolexpr")
//! runtextmacro NEW_ARRAY("Sound", "sound")
//! runtextmacro NEW_ARRAY("Effect", "effect")
//! runtextmacro NEW_ARRAY("UnitPool", "unitpool")
//! runtextmacro NEW_ARRAY("ItemPool", "itempool")
//! runtextmacro NEW_ARRAY("Quest", "quest")
//! runtextmacro NEW_ARRAY("QuestItem", "questitem")
//! runtextmacro NEW_ARRAY("DefeatCondition", "defeatcondition")
//! runtextmacro NEW_ARRAY("TimerDialog", "timerdialog")
//! runtextmacro NEW_ARRAY("Leaderboard", "leaderboard")
//! runtextmacro NEW_ARRAY("Multiboard", "multiboard")
//! runtextmacro NEW_ARRAY("MultiboardItem", "multiboarditem")
//! runtextmacro NEW_ARRAY("Trackable", "trackable")
//! runtextmacro NEW_ARRAY("Dialog", "dialog")
//! runtextmacro NEW_ARRAY("Button", "button")
//! runtextmacro NEW_ARRAY("TextTag", "texttag")
//! runtextmacro NEW_ARRAY("Lightning", "lightning")
//! runtextmacro NEW_ARRAY("Image", "image")
//! runtextmacro NEW_ARRAY("Ubersplat", "ubersplat")
//! runtextmacro NEW_ARRAY("Region", "region")
//! runtextmacro NEW_ARRAY("FogState", "fogstate")
//! runtextmacro NEW_ARRAY("FogModifier", "fogmodifier")
//! runtextmacro NEW_ARRAY("Hashtable", "hashtable")
struct Table extends array
// Implement modules for intuitive syntax (tb.handle; tb.unit; etc.)
implement realm
implement integerm
implement booleanm
implement stringm
implement playerm
implement widgetm
implement destructablem
implement itemm
implement unitm
implement abilitym
implement timerm
implement triggerm
implement triggerconditionm
implement triggeractionm
implement eventm
implement forcem
implement groupm
implement locationm
implement rectm
implement boolexprm
implement soundm
implement effectm
implement unitpoolm
implement itempoolm
implement questm
implement questitemm
implement defeatconditionm
implement timerdialogm
implement leaderboardm
implement multiboardm
implement multiboarditemm
implement trackablem
implement dialogm
implement buttonm
implement texttagm
implement lightningm
implement imagem
implement ubersplatm
implement regionm
implement fogstatem
implement fogmodifierm
implement hashtablem
method operator handle takes nothing returns handles
return this
endmethod
method operator agent takes nothing returns agents
return this
endmethod
//set this = tb[GetSpellAbilityId()]
method operator [] takes integer key returns Table
return LoadInteger(ht, this, key) //return this.integer[key]
endmethod
//set tb[389034] = 8192
method operator []= takes integer key, Table tb returns nothing
call SaveInteger(ht, this, key, tb) //set this.integer[key] = tb
endmethod
//set b = tb.has(2493223)
method has takes integer key returns boolean
return HaveSavedInteger(ht, this, key) //return this.integer.has(key)
endmethod
//call tb.remove(294080)
method remove takes integer key returns nothing
call RemoveSavedInteger(ht, this, key) //call this.integer.remove(key)
endmethod
//Remove all data from a Table instance
method flush takes nothing returns nothing
call FlushChildHashtable(ht, this)
endmethod
//local Table tb = Table.create()
static method create takes nothing returns Table
local Table this = dex.list[0]
if this == 0 then
set this = more + 1
set more = this
else
set dex.list[0] = dex.list[this]
call dex.list.remove(this) //Clear hashed memory
endif
debug set dex.list[this] = -1
return this
endmethod
// Removes all data from a Table instance and recycles its index.
//
// call tb.destroy()
//
method destroy takes nothing returns nothing
debug if dex.list[this] != -1 then
debug call BJDebugMsg("Table Error: Tried to double-free instance: " + I2S(this))
debug return
debug endif
call this.flush()
set dex.list[this] = dex.list[0]
set dex.list[0] = this
endmethod
//! runtextmacro optional TABLE_BC_METHODS()
endstruct
//! runtextmacro optional TABLE_BC_STRUCTS()
struct TableArray extends array
//Returns a new TableArray to do your bidding. Simply use:
//
// local TableArray ta = TableArray[array_size]
//
static method operator [] takes integer array_size returns TableArray
local Table tb = dex.size[array_size] //Get the unique recycle list for this array size
local TableArray this = tb[0] //The last-destroyed TableArray that had this array size
debug if array_size <= 0 then
debug call BJDebugMsg("TypeError: Invalid specified TableArray size: " + I2S(array_size))
debug return 0
debug endif
if this == 0 then
set this = less - array_size
set less = this
else
set tb[0] = tb[this] //Set the last destroyed to the last-last destroyed
call tb.remove(this) //Clear hashed memory
endif
set dex.size[this] = array_size //This remembers the array size
return this
endmethod
//Returns the size of the TableArray
method operator size takes nothing returns integer
return dex.size[this]
endmethod
//This magic method enables two-dimensional[array][syntax] for Tables,
//similar to the two-dimensional utility provided by hashtables them-
//selves.
//
//ta[integer a].unit[integer b] = unit u
//ta[integer a][integer c] = integer d
//
//Inline-friendly when not running in debug mode
//
method operator [] takes integer key returns Table
static if DEBUG_MODE then
local integer i = this.size
if i == 0 then
call BJDebugMsg("IndexError: Tried to get key from invalid TableArray instance: " + I2S(this))
return 0
elseif key < 0 or key >= i then
call BJDebugMsg("IndexError: Tried to get key [" + I2S(key) + "] from outside TableArray bounds: " + I2S(i))
return 0
endif
endif
return this + key
endmethod
//Destroys a TableArray without flushing it; I assume you call .flush()
//if you want it flushed too. This is a public method so that you don't
//have to loop through all TableArray indices to flush them if you don't
//need to (ie. if you were flushing all child-keys as you used them).
//
method destroy takes nothing returns nothing
local Table tb = dex.size[this.size]
debug if this.size == 0 then
debug call BJDebugMsg("TypeError: Tried to destroy an invalid TableArray: " + I2S(this))
debug return
debug endif
if tb == 0 then
//Create a Table to index recycled instances with their array size
set tb = Table.create()
set dex.size[this.size] = tb
endif
call dex.size.remove(this) //Clear the array size from hash memory
set tb[this] = tb[0]
set tb[0] = this
endmethod
private static Table tempTable
private static integer tempEnd
//Avoids hitting the op limit
private static method clean takes nothing returns nothing
local Table tb = .tempTable
local integer end = tb + 0x1000
if end < .tempEnd then
set .tempTable = end
call ForForce(bj_FORCE_PLAYER[0], function thistype.clean)
else
set end = .tempEnd
endif
loop
call tb.flush()
set tb = tb + 1
exitwhen tb == end
endloop
endmethod
//Flushes the TableArray and also destroys it. Doesn't get any more
//similar to the FlushParentHashtable native than this.
//
method flush takes nothing returns nothing
debug if this.size == 0 then
debug call BJDebugMsg("TypeError: Tried to flush an invalid TableArray instance: " + I2S(this))
debug return
debug endif
set .tempTable = this
set .tempEnd = this + this.size
call ForForce(bj_FORCE_PLAYER[0], function thistype.clean)
call this.destroy()
endmethod
endstruct
//NEW: Added in Table 4.0. A fairly simple struct but allows you to do more
//than that which was previously possible.
struct HashTable extends array
//Enables myHash[parentKey][childKey] syntax.
//Basically, it creates a Table in the place of the parent key if
//it didn't already get created earlier.
method operator [] takes integer index returns Table
local Table t = Table(this)[index]
if t == 0 then
set t = Table.create()
set Table(this)[index] = t //whoops! Forgot that line. I'm out of practice!
endif
return t
endmethod
//You need to call this on each parent key that you used if you
//intend to destroy the HashTable or simply no longer need that key.
method remove takes integer index returns nothing
local Table t = Table(this)[index]
if t != 0 then
call t.destroy()
call Table(this).remove(index)
endif
endmethod
//Added in version 4.1
method has takes integer index returns boolean
return Table(this).has(index)
endmethod
//HashTables are just fancy Table indices.
method destroy takes nothing returns nothing
call Table(this).destroy()
endmethod
//Like I said above...
static method create takes nothing returns thistype
return Table.create()
endmethod
endstruct
endlibrary
library Missile /* version 2.5.1
*************************************************************************************
*
* Creating custom projectiles in Warcraft III.
*
* Major goal:
* No unessary external requirements.
* Implements code optional.
*
* Philosophy:
* I want that feature --> Compiler writes that code into your map script.
* I don't want that --> Compiler ignores that code completly.
*
* Important:
* Take yourself 2 minutes time to setup Missile correctly.
* Otherwise I can't guarantee, that Missile works the way you want.
* Once the setup is done, you can check out some examples and Missile will be easy
* to use for everyone. I promise it.
*
* Do the setup at:
*
* 1.) Import instruction
* 2.) Global configuration
* 3.) Function configuration
*
* Credits to Dirac, emjlr3, AceHart, Bribe, Wietlol,
* Nestharus, Maghteridon96, Vexorian and Zwiebelchen.
*
*************************************************************************************
*
* */ requires /*
*
* - Missile requires nothing.
*
*************************************************************************************
*
* Optional requirements listed can reduce overall code generation,
* add safety mechanisms, decrease overhead and optimize handle management.
* For a better overview I put them into blocks.
*
* I recommend to use at least one per block in your map.
*
* a) For best debug results: ( Useful )
* */ optional ErrorMessage /* github.com/nestharus/JASS/tree/master/jass/Systems/ErrorMessage
*
* b) Fatal error protection: ( Case: unit out moves of world bounds )
* - WorldBounds is safer than BoundSentinel.
* - WorldBounds adds more overhead than BoundSentinel.
* - Using none of these two forces Missile to switch from SetUnitX/Y to the SetUnitPosition native.
* */ optional WorldBounds /* githubusercontent.com/nestharus/JASS/master/jass/Systems/WorldBounds/script.j
* */ optional BoundSentinel /* wc3c.net/showthread.php?t=102576
*
* c) Handle recycling: ( Performace gain, memory management )
* - uses MissileRecylcer > Dummy > xedummy.
* */ optional MissileRecycler /* hiveworkshop.com/forums/jass-resources-412/system-missilerecycler-206086/
* */ optional Dummy /* github.com/nestharus/JASS/blob/master/jass/Systems/Dummy/Dummy.w3x
* */ optional xedummy /* wc3c.net/showthread.php?t=101150
*
* d) Unit indexing: ( Avoid an onIndex event )
* - not required for Missile. Only if you use one already.
* */ optional UnitIndexer /* github.com/nestharus/JASS/tree/master/jass/Systems/Unit%20Indexer
*
************************************************************************************
*
* 1. Import instruction
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* • Copy Missile into to your map.
* • You need a dummy unit, using Vexorians "dummy.mdx".
* This unit must use the locust and crow form ability. ( Aloc & Amrf )
* ¯¯¯¯
*
* 2. Global configuration
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Seven constants to setup!
*/
globals
/**
* Missiles are moved periodically. An interval of 1./32. is recommended.
* • Too short timeout intervals may cause performance issues.
* • Too large timeout intervals may look fishy.
*/
public constant real TIMER_TIMEOUT = 1./32.
/**
* Owner of all Missile dummies. Should be a neutral player in your map.
*/
public constant player NEUTRAL_PASSIVE = Player(bj_PLAYER_NEUTRAL_EXTRA)
/**
* Raw code of the dummy unit. Object Editor ( F6 )
* • Must be correct, otherwise missile dummies can neither be recycled nor destroyed.
* • Units of other type ids will not be thrown into the recycler bin.
*/
public constant integer DUMMY_UNIT_ID = 'e000'
/**
* The maximum collision size used in your map. If unsure use 197. ( Town hall collision )
* • Applies for all types of widgets.
* • A precise value can improve Missile's performance,
* since smaller values enumerate less widgtes per loop per missile.
*/
public constant real MAXIMUM_COLLISION_SIZE = 197.
/**
* Collision types for missiles. ( Documentation only )
* Missile decides internally each loop which type of collision is required.
* • Uses circular collision dectection for speed < collision. ( Good accuracy, best performance )
* • Uses rectangle collision for speed >= collision. ( Best accuracy, normal performance )
*/
public constant integer COLLISION_TYPE_CIRCLE = 0
public constant integer COLLISION_TYPE_RECTANGLE = 1
/**
* Determine when rectangle collision is required to detect nearby widgets.
* • The smaller the factor the earlier rectangle collision is used. ( by default 1. )
* • Formula: speed >= collision*Missile_COLLISION_ACCURACY_FACTOR
*/
public constant real COLLISION_ACCURACY_FACTOR = 1.
// Optional toogles:
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Set booleans listed below to "true" and the compiler will write
// the feature into your map. Otherwise this code is completly ignored.
// • Yay, I want that --> "true"
// • Naah that's useless for me --> "false"
/**
* USE_COLLISION_Z_FILTER enables z axis checks for widget collision. ( Adds minimal overhead )
* Use it when you need:
* • Missiles flying over or under widgets.
* • Determine between flying and walking units.
*/
public constant boolean USE_COLLISION_Z_FILTER = true
/**
* WRITE_DELAYED_MISSILE_RECYCLING enables a delayed dummy recycling system. ( Very recommended )
* Use it if:
* • You use a dummy recycling library like MissileRecycler, Dummy or xedummy.
* • You want to properly display death animations of effects added to missiles.
*/
public constant boolean WRITE_DELAYED_MISSILE_RECYCLING = true
/**
* DELAYED_MISSILE_DEATH_ANIMATION_TIME is the delay in seconds
* Missile holds back a dummy, before recycling it.
* • The time value does not have to be precise.
* • Requires WRITE_DELAYED_MISSILE_RECYCLING = true
*/
private constant real DELAYED_MISSILE_DEATH_ANIMATION_TIME = 2.
/**
* USE_DESTRUCTABLE_FILTER and USE_ITEM_FILTER are redundant constants from previous Missile versions.
* They do nothing, but remain for backwards compatibilty.
* From Missile version 1.5 on all widget collisions are always enabled.
*/
public constant boolean USE_DESTRUCTABLE_FILTER = true
public constant boolean USE_ITEM_FILTER = true
endglobals
/*
* 3. Function configuration
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Four functions to setup!
*/
/**
* GetUnitBodySize(unit) returns a fictional value for z - axis collision.
* You have two options:
* • One constant value shared over all units.
* • Dynamic values based on handle id, type id, unit user data, scaling or other parameters.
*/
function GetUnitBodySize takes unit whichUnit returns real
return 100.// Other example: return LoadReal(hash, GetHandleId(whichUnit), KEY_UNIT_BODY_SIZE)
endfunction
/**
* Same as GetUnitBodySize, but for destructables.
* Using occluder height is an idea of mine. Of course you can use your own values.
*/
function GetDestructableHeight takes destructable d returns real
return GetDestructableOccluderHeight(d)// Other example: return 100.
endfunction
/**
* Same as GetUnitBodySize, but for items.
* Again it's up to you to figure out a fictional item height.
*/
function GetItemHeight takes item i returns real
return 16.
endfunction
/**
* Unit indexers and missiles ( Only if you don't use a dummy recycling library )
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* It is most likely intended that projectiles don't run through a unit indexing process.
* ToogleUnitIndexer runs:
* • Directly before a dummy is created.
* • Directly after dummy unit creation.
*
* Please return the previous setup of your indexing tool ( enabled, disabled ),
* so Missile can properly reset it to the original state.
*/
private function ToogleUnitIndexer takes boolean enable returns boolean
local boolean prev = true//UnitIndexer.enabled
// set UnitIndexer.enabled = enable
return prev
endfunction
/**
* 4. API
* ¯¯¯¯¯¯
*/
//! novjass ( Disables the compiler until the next endnovjass )
// Custom type Missile for your projectile needs.
struct Missile extends array
// Constants:
// ==========
//
readonly static constant string ORIGIN = "origin"
// • Attach point name for fxs on dummies.
readonly static constant real HIT_BOX = (2./3.)
// • Fictional hit box for homing missiles.
// while 0 would be the toe and 1 the head of a unit.
// Available creators:
// ===================
//
static method createEx takes unit missileDummy, real impactX, real impactY, real impactZ returns Missile
// • Core creator method.
// • May launches any unit.
// • Units of type Missile_DUMMY_UNIT_ID get recycled in the end.
static method create takes real x, real y, real z, real angleInRadians, real distanceToTravel, real endZ returns Missile
// • Converts arguments to fit into createEx, then calls createEx.
static method createXYZ takes real x, real y, real z, real impactX, real impactY, real impactZ returns Missile
// • Converts arguments to fit into createEx, then calls createEx.
// Available destructors:
// ======================
//
return true
// • Core destructor.
// • Returning true in any of the interface methods of the MissileStruct module
// will destroy that instance instantly.
method destroy takes nothing returns nothing
// • Destroys the missile during the next timer callback.
method terminate takes nothing returns nothing
// • Destroys the missile instantly.
// Fields you can set and read directly:
// =====================================
//
unit source
unit target // For homing missiles.
real distance // Distance traveled.
player owner // Pseudo owner for faster onCollide evaluation. The proper dummy owner remains PLAYER_NEUTRAL_PASSIVE.
real speed // Vector lenght for missile movement in plane x / y. ( DOES NOT TAKE THE TIMER TIMEOUT IN ACCOUNT )
real acceleration
real damage
real turn // Set a turn rate for missiles.
integer data // For data transfer set and read data.
boolean recycle // Is automatically set to true, when a Missile reaches it's destination.
boolean wantDestroy // Set wantDestroy to true, to destroy a missile during the next timer callback.
// Neither collision nor collisionZ accept values below zero.
real collision // Collision size in plane x / y.
real collisionZ // Collision size in z - axis. ( deprecated )
// Fields you can only read:
// =========================
//
readonly boolean allocated
readonly unit dummy// The dummy unit of this missile.
// Position members for you needs.
readonly MissilePosition origin// Grants access to readonly members of MissilePosition,
readonly MissilePosition impact// which are "x", "y", "z", "angle", "distance", "slope" and the pitch angle "alpha".
// Furthermore method origin.move(x, y, z) and impact.move(x, y, z).
readonly real terrainZ
readonly real x
readonly real y
readonly real z
readonly real angle// Current angle in radians.
// Method operators for set and read:
// ==================================
//
method operator model= takes string modelFile returns nothing
method operator model takes nothing returns string
// • Adds an effect handle on a missile dummy to it's "origin".
// • You can read the file path.
// • For multiple effects access "this.dummy" in your struct.
method operator scale= takes real value returns nothing
method operator scale takes nothing returns real
// • Set and read the scaling of the dummy unit.
method operator curve= takes real value returns nothing
method operator curve takes nothing returns real
// • Enables curved movement for your missile. ( Pass in radians, NOT degrees )
// • Do not pass in PI/2.
method operator arc= takes real value returns nothing
method operator arc takes nothing returns real
// • Enables arcing movement for your missile. ( Pass in radians, NOT degrees )
// • Do not pass in PI/2.
// Methods for missile movement:
// =============================
//
method bounce takes nothing returns nothing
// • Moves the MissilePosition "origin" to the current missile coordinates.
// • Resets the distance traveled to 0.
method deflect takes real tx, real ty returns nothing
// • Deflect the missile towards tx, ty. Then calls bounce.
method deflectEx takes real tx, real ty, real tz returns nothing
// • Deflect the missile towards tx, ty, tz. Then calls bounce.
method flightTime2Speed takes real duration returns nothing
// • Converts a fly time to a vector lenght for member "speed".
// • Does not take acceleration into account. ( Disclaimer )
method setMovementSpeed takes real value returns nothing
// • Converts Warcraft III movement speed to a vector lenght for member "speed".
// Methods for missile collision: ( all are hashtable entries )
// ==============================
// By default a widget can only be hit once per missile.
//
method hitWidget takes widget w returns nothing
// • Saves a widget in the memory as hit by this instance.
method hasHitWidget takes widget w returns boolean
// • Returns true, if "w" has been hit by this instance.
method removeHitWidget takes widget w returns nothing
// • Removes a widget from this missile's memory for widget collision. ( Can hit "w" again )
method flushHitWidgets takes nothing returns nothing
// • Flushes a missile's memory for widget collision. ( All widgets can be hit again )
method enableHitAfter takes widget w, real seconds returns nothing
// • Automatically calls removeHitWidget(w) after "seconds" time. ( Can hit "w" again after given time )
// Module MissileStruct:
// =====================
//
module MissileLaunch // ( optional )
module MissileStruct
// • Enables the entire missile interface for that struct.
// Interface in structs: ( Must implement module MissileStruct )
// =====================
//
// • Write one, many or all of the static method below into your struct.
// • Missiles launched in this struct will run those methods, when their events fire.
//
// • All of those static methods must return a boolean.
// a) return true --> destroys the missile instance instantly.
// b) return false --> keep on flying.
// Available static method:
// ========================
//
static method onCollide takes Missile missile, unit hit returns boolean
// • Runs for units in collision range of a missile.
static method onDestructable takes Missile missile, destructable hit returns boolean
// • Runs for destructables in collision range of a missile.
static method onItem takes Missile missile, item hit returns boolean
// • Runs for items in collision range of a missile.
static method onTerrain takes Missile missile returns boolean
// • Runs when a missile collides with the terrain. ( Ground and cliffs )
static method onFinish takes Missile missile returns boolean
// • Runs only when a missile reaches it's destination.
// • However does not run, if a Missile is destroyed in another method.
static method onPeriod takes Missile missile returns boolean
// • Runs every Missile_TIMER_TIMEOUT seconds.
static method onRemove takes Missile missile returns boolean
// • Runs when a missile is destroyed.
// • Unlike onFinish, onRemove will runs ALWAYS when a missile is destroyed!!!
//
// For onRemove the returned boolean has a unique meaning:
// • Return true will recycle this missile delayed. ( Only if WRITE_DELAYED_MISSILE_RECYCLING = true )
// • Return false will recycle this missile right away.
static method launch takes Missile toLaunch returns nothing
// • Well ... Launches this Missile.
// • Missile "toLaunch" will behave as declared in the struct. ( static methods from above )
// Misc: ( From the global setup )
// =====
//
// Constants:
// ==========
//
public constant real TIMER_TIMEOUT
public constant player NEUTRAL_PASSIVE
public constant integer DUMMY_UNIT_ID
public constant real MAXIMUM_COLLISION_SIZE
public constant boolean USE_COLLISION_Z_FILTER
public constant boolean WRITE_DELAYED_MISSILE_RECYCLING
public constant boolean USE_DESTRUCTABLE_FILTER
public constant boolean USE_ITEM_FILTER
readonly static constant string ORIGIN
readonly static constant real HIT_BOX
// Functions:
// ==========
//
public function GetLocZ takes real x, real y returns real
function GetUnitBodySize takes unit whichUnit returns real
function GetDestructableHeight takes destructable d returns real
function GetItemHeight takes item i returns real
//========================================================================
// Missile system. Make changes carefully.
//========================================================================
//! endnovjass ( Enables the compiler )
// Hello and welcome to Missile.
// I wrote a guideline for every piece of code inside Missile, so you
// can easily understand how the it gets compiled and evaluated.
//
// Let's go!
globals
// Core constant handle variables of Missile.
private constant trigger CORE = CreateTrigger()
private constant trigger MOVE = CreateTrigger()
private constant timer TMR = CreateTimer()
private constant location LOC = Location(0., 0.)
private constant rect RECT = Rect(0., 0., 0., 0.)
private constant group GROUP = CreateGroup()
private constant hashtable HASH = InitHashtable()
// For starting and stopping the timer.
private integer active = 0
// Arrays for data structure.
private integer array instances
private Missile array missileList
private boolexpr array expression
private triggercondition array condition
private integer array remove
private boolean array destroying
private boolean array recycling
private integer array nextNode
private integer array prevNode
// Internal widget filter functions.
private boolexpr destFilter
private boolexpr itemFilter
private boolexpr unitFilter
endglobals
public function GetLocZ takes real x, real y returns real
call MoveLocation(LOC, x, y)
return GetLocationZ(LOC)
endfunction
// For WRITE_DELAYED_MISSILE_RECYCLING = true Missile will hold back
// dummies for DELAYED_MISSILE_DEATH_ANIMATION_TIME before they are recylced. ( Code placed in a static if )
//
//! runtextmacro optional WRITE_MISSILE_RECYCLE_BIN("WRITE_DELAYED_MISSILE_RECYCLING", "DELAYED_MISSILE_DEATH_ANIMATION_TIME")
// The code of WRITE_MISSILE_POSITION_CODE boxes a missiles position and does the required trigonometry.
//
//! runtextmacro WRITE_MISSILE_POSITION_CODE()
// Missiles structure works like a linked list with the folling methods:
// allocateCollection(), allocateNode(), insertFront(node) and remove()
//
private keyword MissileStructure
struct Missile extends array
implement MissileStructure
// Constants:
// ==========
//
// Attach point name for effects created by model=.
readonly static constant string ORIGIN = "origin"
// Set a ficitional hit box in range of 0 to 1,
// while 0 is the toe and 1 the head of a unit.
readonly static constant real HIT_BOX = (2./3.)
// DEBUG_MODE only members:
// ========================
//
// Checks for double launching. Throws an error message.
debug boolean launched
// Private members:
// ================
//
// The position of a missile using curve= does not
// match the position used by Missile's trigonometry.
// Therefore we need this member two times.
// Readable x / y / z for your needs and posX / posY for cool mathematics.
private real posX
private real posY
private real dist// distance
// Readonly members:
// =================
//
// Prevents a double free case.
readonly boolean allocated
// The dummy unit.
readonly unit dummy
// Position members for your needs.
readonly MissilePosition origin// Grants access to readonly members of MissilePosition,
readonly MissilePosition impact// which are "x", "y", "z", "angle", "distance", "slope" and "alpha".
readonly real terrainZ
readonly real x
readonly real y
readonly real z
real angle// Current angle
readonly real prevX
readonly real prevY
readonly real prevZ
// Collision detection type. ( Evaluated new in each loop )
readonly integer collisionType// Current collision type ( circular or rectangle )
// Members you can set:
// ====================
//
unit source
unit target // For homing missiles.
real distance // Distance traveled.
player owner // Pseudo owner for faster onCollide evaluation. The proper dummy owner is PLAYER_NEUTRAL_PASSIVE.
real speed // Vector lenght for missile movement in plane x / y.
real acceleration
real damage
integer data // For data transfer set and read data.
boolean recycle // Is set to true, when a Missile reaches it's destination.
real turn // Sets a turn rate for a missile.
real collision // Collision size in plane x / y.
// Setting collision z is deprecated since Missile v2.5.
method operator collisionZ= takes real value returns nothing
endmethod
method operator collisionZ takes nothing returns real
return collision
endmethod
// Operator overloading:
// =====================
//
// Special effect on the missile dummy. For multiple effect attaching, access unit "dummy" directly.
private effect attach
readonly effect sfx
private string path
private string path2
method operator attachment= takes string file returns nothing
if attach != null then
call DestroyEffect(attach)
set attach = null
endif
// null and ""
if StringLength(file) > 0 then
set attach = AddSpecialEffectTarget(file, dummy, ORIGIN)
set path2 = file
else
set path2 = null
endif
endmethod
method operator attachment takes nothing returns string
return path2
endmethod
method operator model= takes string file returns nothing
if sfx != null then
call DestroyEffect(sfx)
set sfx = null
endif
// null and ""
if StringLength(file) > 0 then
set sfx = AddSpecialEffectTarget(file, dummy, ORIGIN)
set path = file
else
set path = null
endif
endmethod
method operator model takes nothing returns string
return path
endmethod
real open
// Enables curved movement for your missile.
// Remember that the result of Tan(PI/2) is infinity.
method operator curve= takes real value returns nothing
set open = Tan(value)*origin.distance
endmethod
method operator curve takes nothing returns real
return Atan(open/origin.distance)
endmethod
real height
// Enables arcing movement for your missile.
method operator arc= takes real value returns nothing
set height = Tan(value)*origin.distance/4
endmethod
method operator arc takes nothing returns real
return Atan(4*height/origin.distance)
endmethod
private real scaling
method operator scale= takes real value returns nothing
call SetUnitScale(dummy, value, 0., 0.)
set scaling = value
endmethod
method operator scale takes nothing returns real
return scaling
endmethod
// Methods:
// ========
//
method bounce takes nothing returns nothing
call origin.move(x, y, z)
set dist = 0.
endmethod
method deflect takes real tx, real ty returns nothing
local real a = 2.*Atan2(ty - y, tx - x) + bj_PI - angle
call impact.move(x + (origin.distance - dist)*Cos(a), y + (origin.distance - dist)*Sin(a), impact.z)
call bounce()
endmethod
method deflectEx takes real tx, real ty, real tz returns nothing
call impact.move(impact.x, impact.y, tz)
call deflect(tx, ty)
endmethod
method flightTime2Speed takes real duration returns nothing
set speed = RMaxBJ(0.00000001, (origin.distance - dist)*Missile_TIMER_TIMEOUT/RMaxBJ(0.00000001, duration))
endmethod
method setMovementSpeed takes real value returns nothing
set speed = value*Missile_TIMER_TIMEOUT
endmethod
boolean wantDestroy// For "true" a missile is destroyed on the next timer callback. 100% safe.
method destroy takes nothing returns nothing
set wantDestroy = true
endmethod
// Instantly destroys a missile.
method terminate takes nothing returns nothing
if allocated then
call remove()
call impact.destroy()
call origin.destroy()
call DestroyEffect(attach)
call DestroyEffect(sfx)
call FlushChildHashtable(HASH, this)
if GetUnitTypeId(dummy) == Missile_DUMMY_UNIT_ID then
// MissileRecycler > Dummy > xe.
static if LIBRARY_MissileRecycler then
call RecycleMissile(dummy)
elseif LIBRARY_Dummy and Dummy.create.exists then
call Dummy[dummy].destroy()
elseif LIBRARY_xedummy and xedummy.release.exists then
call xedummy.release(dummy)
else
call RemoveUnit(dummy)
endif
endif
set attach = null
set sfx = null
set source = null
set target = null
set dummy = null
set owner = null
endif
endmethod
// Runs in createEx.
//! textmacro MISSILE_RESET_ALL_MEMBERS
set path = null
set speed = 0.
set acceleration = 0.
set distance = 0.
set dist = 0
set dist = 0.
set height = 0.
set turn = 0.
set open = 0.
set collision = 0.
set collisionType = 0
set stackSize = 0
set scaling = 1.
set wantDestroy = false
set recycle = false
//! endtextmacro
// Launches a dummy of your choice.
static method createEx takes unit missileDummy, real impactX, real impactY, real impactZ returns thistype
local thistype this = thistype.allocateNode()
local real originX = GetUnitX(missileDummy)
local real originY = GetUnitY(missileDummy)
local real originZ = GetUnitFlyHeight(missileDummy)
//
//! runtextmacro MISSILE_RESET_ALL_MEMBERS()
//
set origin = MissilePosition.create(originX, originY, originZ)
set impact = MissilePosition.create(impactX, impactY, impactZ)
call MissilePosition.link(origin, impact)
set posX = originX
set posY = originY
set x = originX
set y = originY
set z = originZ
set angle = origin.angle
set dummy = missileDummy
call SetUnitFlyHeight(missileDummy, originZ, 0.)
call SaveUnitHandle(HASH, this, GetHandleId(missileDummy), missileDummy)
//
static if LIBRARY_ErrorMessage then
debug call ThrowWarning(GetUnitTypeId(missileDummy) == 0, "Missile", "createEx", "missileDummy", this, "Invalid missile dummy unit ( null )!")
endif
debug set launched = false
return this
endmethod
// Freaky static if ensures these libraries really don't exist.
static if not LIBRARY_MissileRecycler and not LIBRARY_Dummy and not Dummy.create.exists and not LIBRARY_xe_dummy and not xe_dummy.new.exists then
private static method newMissileUnit takes real x, real y, real z, real face returns unit
local boolean prev = ToogleUnitIndexer(false)
set bj_lastCreatedUnit = CreateUnit(Missile_NEUTRAL_PASSIVE, Missile_DUMMY_UNIT_ID , x, y, face)
call ToogleUnitIndexer(prev)
call SetUnitX(bj_lastCreatedUnit, x)
call SetUnitY(bj_lastCreatedUnit, y)
call UnitAddAbility(bj_lastCreatedUnit, 'Amrf')
call SetUnitFlyHeight(bj_lastCreatedUnit, z, 0.)
call PauseUnit(bj_lastCreatedUnit, true)
return bj_lastCreatedUnit
endmethod
endif
// MissileRecylcer > Dummy > xe > Missile.
//! textmacro MISSILE_GET_DUMMY_FROM_LIBRARY
static if LIBRARY_MissileRecycler then
return createEx(GetRecycledMissile(x, y, z, angle*bj_RADTODEG), impactX, impactY, impactZ)
elseif LIBRARY_Dummy and Dummy.create.exists then
local Dummy dummy = Dummy.create(x, y, angle*bj_RADTODEG)
call SetUnitFlyHeight(dummy.unit, z, 0.)
return createEx(dummy.unit, impactX, impactY, impactZ)
elseif LIBRARY_xedummy and xedummy.new.exists then
set bj_lastCreatedUnit = xedummy.new(Missile_NEUTRAL_PASSIVE, x, y, angle*bj_RADTODEG)
call SetUnitFlyHeight(bj_lastCreatedUnit, z, 0.)
return createEx(bj_lastCreatedUnit, impactX, impactY, impactZ)
else
return createEx(Missile.newMissileUnit(x, y, z, angle*bj_RADTODEG), impactX, impactY, impactZ)
endif
//! endtextmacro
// Wrapper to createEx.
static method create takes real x, real y, real z, real angle, real distance, real impactZ returns thistype
local real impactX = x + distance*Cos(angle)
local real impactY = y + distance*Sin(angle)
// Get the dummy unit.
//! runtextmacro MISSILE_GET_DUMMY_FROM_LIBRARY()
endmethod
// Wrapper to createEx.
static method createXYZ takes real x, real y, real z, real impactX, real impactY, real impactZ returns thistype
local real angle = Atan2(impactY - y, impactX - x)
// Get the dummy unit.
//! runtextmacro MISSILE_GET_DUMMY_FROM_LIBRARY()
endmethod
// Missile motion takes place every Missile_TIMER_TIMEOUT
// before accessing each active struct.
static Missile temp = 0
static method move takes nothing returns boolean
local integer loops = 0 // Current iteration.
local integer limit = 150 // Set iteration border per trigger evaluation to avoid hitting the operation limit.
local thistype this = thistype.temp
local MissilePosition p
local real a
local real d
local unit u
local real newX
local real newY
local real vel
local real point
local real pitch
loop
exitwhen 0 == this or loops == limit
set p = origin
// Save previous, respectively current missile position.
set prevX = x
set prevY = y
set prevZ = z
// Evaluate the collision type.
set vel = speed
set speed = vel + acceleration
if vel < collision*Missile_COLLISION_ACCURACY_FACTOR then
set collisionType = Missile_COLLISION_TYPE_CIRCLE
else
set collisionType = Missile_COLLISION_TYPE_RECTANGLE
endif
// Update missile guidance to its intended target.
set u = target
if u != null then
if 0 == GetUnitTypeId(u) then
set target = null
else
call origin.move(x, y, z)
call impact.move(GetUnitX(u), GetUnitY(u), GetUnitFlyHeight(u) + GetUnitBodySize(u)*Missile.HIT_BOX)
set dist = 0
set height = 0
set curve = 0
endif
endif
set a = p.angle
// Update the missile facing angle depending on the turn ratio.
if 0. != turn and Cos(angle - a) < Cos(turn) then
if 0. > Sin(a - angle) then
set angle = angle - turn
else
set angle = angle + turn
endif
else
set angle = a
endif
// Update the missile position on the parabola.
set d = p.distance// origin - impact distance.
set recycle = dist + vel >= d
if recycle then// Maximum distance reached.
set point = d
set distance = distance + d - dist
else
set distance = distance + vel
set point = dist + vel
endif
set dist = point
set newX = posX + vel*Cos(angle)
set newY = posY + vel*Sin(angle)
set posX = newX
set posY = newY
// Update point(x/y) if a curving trajectory is defined.
set u = dummy
if 0. != open and target == null then
set vel = 4*open*point*(d - point)/p.square
set a = angle + bj_PI/2
set newX = newX + vel*Cos(a)
set newY = newY + vel*Sin(a)
set a = angle + Atan(-((4*open)*(2*point - d))/p.square)
else
set a = angle
endif
set x = newX
set y = newY
// Update pos z if an arc or height is set.
call MoveLocation(LOC, newX, newY)
set terrainZ = GetLocationZ(LOC)
set pitch = p.alpha
if 0. == height and 0. == pitch then
set z = p.z - terrainZ
else
set z = p.z - terrainZ + p.slope*point
if 0. != height and target == null then
set z = z + (4*height*point*(d - point)/p.square)
set pitch = pitch - Atan(((4*height)*(2*point - d))/p.square)*bj_RADTODEG
endif
endif
// Update the pitch angle of the dummy unit.
if GetUnitTypeId(u) == Missile_DUMMY_UNIT_ID then
call SetUnitAnimationByIndex(u, R2I(pitch + 90.5))
call SetUnitFacing(u, a*bj_RADTODEG)
endif
// Move the missile dummy via native.
call SetUnitFlyHeight(u, z, 0.)
// WorldBounds > BoundSentinel.
static if not LIBRARY_BoundSentinel and not LIBRARY_WorldBounds then
if RectContainsCoords(bj_mapInitialPlayableArea, newX, newY) then
call SetUnitX(u, newX)
call SetUnitY(u, newY)
endif
elseif LIBRARY_WorldBounds then
if newX < WorldBounds.maxX and newX > WorldBounds.minX and newY < WorldBounds.maxY and newY > WorldBounds.minY then
call SetUnitX(u, newX)
call SetUnitY(u, newY)
endif
else
call SetUnitX(u, newX)
call SetUnitY(u, newY)
endif
set loops = loops + 1
set this = nextNode[this]
endloop
set u = null
set thistype.temp = this
return this == 0
endmethod
// Widget collision API:
// =====================
//
// Runs automatically on widget collision.
method hitWidget takes widget w returns nothing
if w != null then
call SaveWidgetHandle(HASH, this, GetHandleId(w), w)
endif
endmethod
// All widget which have been hit return true.
method hasHitWidget takes widget w returns boolean
return HaveSavedHandle(HASH, this, GetHandleId(w))
endmethod
// Removes a widget from the missile's memory of hit widgets. ( This widget can be hit again )
method removeHitWidget takes widget w returns nothing
if w != null then
call RemoveSavedHandle(HASH, this, GetHandleId(w))
endif
endmethod
// Flushes a missile's memory for collision. ( All widgets can be hit again )
method flushHitWidgets takes nothing returns nothing
call FlushChildHashtable(HASH, this)
call hitWidget(dummy)
endmethod
// Tells missile to call removeHitWidget(w) after "seconds" time.
// Does not apply to widgets, which are already hit by this missile.
readonly integer stackSize
method enableHitAfter takes widget w, real seconds returns nothing
local integer id = GetHandleId(w)
if w != null then
if not HaveSavedInteger(HASH, this, id) then
call SaveInteger(HASH, this, id, stackSize)
call SaveInteger(HASH, this, stackSize, id)
set stackSize = stackSize + 1
endif
call SaveReal(HASH, this, id, seconds)// Set time.
endif
endmethod
method updateStack takes nothing returns nothing
local integer dex = 0
local integer id
local real time
loop
exitwhen dex == stackSize
set id = LoadInteger(HASH, this, dex)
set time = LoadReal(HASH, this, id) - Missile_TIMER_TIMEOUT
if time <= 0. or not HaveSavedHandle(HASH, this, id) then
set stackSize = stackSize - 1
set id = LoadInteger(HASH, this, stackSize)
call SaveInteger(HASH, this, dex, id)
call SaveInteger(HASH, this, id, dex)
// Enables hit.
call RemoveSavedHandle(HASH, this, id)
// Remove data from stack.
call RemoveSavedReal(HASH, this, id)
call RemoveSavedInteger(HASH, this, id)
call RemoveSavedInteger(HASH, this, stackSize)
else
call SaveReal(HASH, this, id, time)
set dex = dex + 1
endif
endloop
endmethod
// Widget collision code:
// ======================
//
private static boolean circle = true
//
// 1.) Rectangle collision for fast moving missiles with small collision radius.
//
// Runs for destructables and items in a rectangle.
// Checks if widget w is in collision range of a missile.
// Is not precise in z - axis collision.
private method isWidgetInRectangle takes widget w, real wz, real distance returns boolean
local real wx = GetWidgetX(w)
local real wy = GetWidgetY(w)
local real dz = Missile_GetLocZ(wx, wy) - terrainZ
local real dx = x - prevX
local real dy = y - prevY
local real s = (dx*(wx - prevX) + dy*(wy - prevY))/(dx*dx + dy*dy)
if s < 0. then
set s = 0.
elseif s > 1 then
set s = 1.
endif
set dx = (prevX + s*dx) - wx
set dy = (prevY + s*dy) - wy
return dx*dx + dy*dy <= distance*distance and dz + wz >= z - distance and dz <= z + distance
endmethod
//
// 2.) Circular collision detection for all other missiles.
//
// Returns true for widgets in a xyz collision range.
private method isWidgetInRange takes widget w, real wz, real distance returns boolean
local real wx = GetWidgetX(w)
local real wy = GetWidgetY(w)
local real dz = Missile_GetLocZ(wx, wy) - terrainZ
// collision in plane x and y, collision in z axis.
return IsUnitInRangeXY(dummy, wx, wy, distance) and dz + wz >= z - distance and dz <= z + distance
endmethod
//
// 3.) Action functions inside the widget enumeration thread.
//
// Runs for every enumerated destructable.
// • Directly filters out already hit destructables.
// • Distance formula based on the Pythagorean theorem.
//
private static method filterDests takes nothing returns boolean
local destructable d = GetFilterDestructable()
local boolean b = false
if not HaveSavedHandle(HASH, temp, GetHandleId(d)) then
if circle then
set b = temp.isWidgetInRange(d, GetDestructableHeight(d), temp.collision)
else
set b = temp.isWidgetInRectangle(d, GetDestructableHeight(d), temp.collision)
endif
endif
set d = null
return b
endmethod
//
// Runs for every enumerated item.
// • Directly filters out already hit items.
// • Distance formula based on the Pythagorean theorem.
// • Items have a fix collision size of 16.
//
private static method filterItems takes nothing returns boolean
local item i = GetFilterItem()
local boolean b = false
if not HaveSavedHandle(HASH, temp, GetHandleId(i)) then
if circle then // Item in missile collision size or item pathing in missile range.
set b = temp.isWidgetInRange(i, GetItemHeight(i), RMaxBJ(temp.collision, 16.))
else
set b = temp.isWidgetInRectangle(i, GetItemHeight(i), RMaxBJ(temp.collision, 16.))
endif
endif
set i = null
return b
endmethod
//
// 4.) Filter function for rectangle unit collision.
//
// Runs for every enumerated units.
// • Filters out units which are not in collision range in plane x / y.
// • Inlined and therefore a bit faster than item and destructable collision.
//
private static method filterUnits takes nothing returns boolean
local thistype this = thistype.temp
local unit u = GetFilterUnit()
local real dx
local real dy
local real s
local boolean is = false
if not HaveSavedHandle(HASH, this, GetHandleId(u)) then
set dx = x - prevX
set dy = y - prevY
set s = (dx*(GetUnitX(u) - prevX) + dy*(GetUnitY(u)- prevY))/(dx*dx + dy*dy)
if s < 0. then
set s = 0.
elseif s > 1. then
set s = 1.
endif
set is = IsUnitInRangeXY(u, prevX + s*dx, prevY + s*dy, collision)
endif
set u = null
return is
endmethod
//
// 5.) Proper rect preparation.
//
// For rectangle.
private method prepareRectRectangle takes nothing returns nothing
local real x1 = prevX
local real y1 = prevY
local real x2 = x
local real y2 = y
local real d = collision + Missile_MAXIMUM_COLLISION_SIZE
// What is min, what is max ...
if x1 < x2 then
if y1 < y2 then
call SetRect(RECT, x1 - d, y1 - d, x2 + d, y2 + d)
else
call SetRect(RECT, x1 - d, y2 - d, x2 + d, y1 + d)
endif
elseif y1 < y2 then
call SetRect(RECT, x2 - d, y1 - d, x1 + d, y2 + d)
else
call SetRect(RECT, x2 - d, y2 - d, x1 + d, y1 + d)
endif
endmethod
//
// For circular.
private method prepareRectCircle takes nothing returns nothing
local real d = collision + Missile_MAXIMUM_COLLISION_SIZE
call SetRect(RECT, x - d, y - d, x + d, y + d)
endmethod
//
// 5.) API for the MissileStruct iteration.
//
method groupEnumUnitsRectangle takes nothing returns nothing
call prepareRectRectangle()
set thistype.temp = this
call GroupEnumUnitsInRect(GROUP, RECT, unitFilter)
endmethod
//
// Prepares destructable enumeration, then runs enumDests.
method checkDestCollision takes code func returns nothing
set circle = collisionType == Missile_COLLISION_TYPE_CIRCLE
if circle then
call prepareRectCircle()
else
call prepareRectRectangle()
endif
//
set thistype.temp = this
call EnumDestructablesInRect(RECT, destFilter, func)
endmethod
//
// Prepares item enumeration, then runs enumItems.
method checkItemCollision takes code func returns nothing
set circle = collisionType == Missile_COLLISION_TYPE_CIRCLE
if circle then
call prepareRectCircle()
else
call prepareRectRectangle()
endif
//
set thistype.temp = this
call EnumItemsInRect(RECT, itemFilter, func)
endmethod
static if Missile_WRITE_DELAYED_MISSILE_RECYCLING then
method nullBefore takes nothing returns nothing
set dummy = null
endmethod
endif
// Does not check for 'Aloc' and 'Amrf' as they could be customized.
private static method onInit takes nothing returns nothing
static if LIBRARY_ErrorMessage then
debug local boolean prev = ToogleUnitIndexer(false)
debug local unit dummy = CreateUnit(Missile_NEUTRAL_PASSIVE, Missile_DUMMY_UNIT_ID, 0., 0., 0.)
debug call ToogleUnitIndexer(prev)
//
debug call ThrowError((GetUnitTypeId(dummy) != Missile_DUMMY_UNIT_ID), "Missile", "DEBUG_MISSILE", "type id", 0, "Global setup for public integer DUMMY_UNIT_ID is incorrect! This map currently can't use Missile!")
debug call ThrowError((Missile_MAXIMUM_COLLISION_SIZE < 0), "Missile", "DEBUG_MISSILE", "collision", 0, "Global setup for public real MAXIMUM_COLLISION_SIZE is incorrect, below zero! This map currently can't use Missile!")
debug call RemoveUnit(dummy)
debug set dummy = null
endif
//
set unitFilter = Filter(function thistype.filterUnits)
set destFilter = Filter(function thistype.filterDests)
set itemFilter = Filter(function thistype.filterItems)
call TriggerAddCondition(MOVE, Condition(function thistype.move))
endmethod
endstruct
// You made it to the end of Missile, but we are not finished.
// Do you remember about the data structure, the delayed recycler
// and of course our interface module "MissileStruct"
//
// This comes now!
// Debug code taken from List ( full credits to Nestharus )
private module MissileStructure
private static thistype collectionCount = 0
private static thistype nodeCount = 0
static if LIBRARY_ErrorMessage then
debug private boolean isNode
debug private boolean isCollection
endif
private thistype _list
method operator list takes nothing returns thistype
static if LIBRARY_ErrorMessage then
debug call ThrowError(this == 0, "MissileStructure", "list", "thistype", this, "Attempted To Read Null Node.")
debug call ThrowError(not isNode, "MissileStructure", "list", "thistype", this, "Attempted To Read Invalid Node.")
endif
return _list
endmethod
private thistype _next
method operator next takes nothing returns thistype
static if LIBRARY_ErrorMessage then
debug call ThrowError(this == 0, "MissileStructure", "next", "thistype", this, "Attempted To Go Out Of Bounds.")
debug call ThrowError(not isNode, "MissileStructure", "next", "thistype", this, "Attempted To Read Invalid Node.")
endif
return _next
endmethod
private thistype _prev
method operator prev takes nothing returns thistype
static if LIBRARY_ErrorMessage then
debug call ThrowError(this == 0, "MissileStructure", "prev", "thistype", this, "Attempted To Go Out Of Bounds.")
debug call ThrowError(not isNode, "MissileStructure", "prev", "thistype", this, "Attempted To Read Invalid Node.")
endif
return _prev
endmethod
private thistype _first
method operator first takes nothing returns thistype
static if LIBRARY_ErrorMessage then
debug call ThrowError(this == 0, "MissileStructure", "first", "thistype", this, "Attempted To Read Null List.")
debug call ThrowError(not isCollection, "MissileStructure", "first", "thistype", this, "Attempted To Read Invalid List.")
endif
return _first
endmethod
private thistype _last
method operator last takes nothing returns thistype
static if LIBRARY_ErrorMessage then
debug call ThrowError(this == 0, "MissileStructure", "last", "thistype", this, "Attempted To Read Null List.")
debug call ThrowError(not isCollection, "MissileStructure", "last", "thistype", this, "Attempted To Read Invalid List.")
endif
return _last
endmethod
static method allocateCollection takes nothing returns thistype
local thistype this = thistype(0)._first
if (0 == this) then
static if LIBRARY_ErrorMessage then
debug call ThrowError(collectionCount == 8191, "MissileStructure", "allocateCollection", "thistype", 0, "Overflow.")
endif
set this = collectionCount + 1
set collectionCount = this
else
set thistype(0)._first = _first
endif
static if LIBRARY_ErrorMessage then
debug set isCollection = true
endif
set _first = 0
return this
endmethod
static method allocateNode takes nothing returns thistype
local thistype this = thistype(0)._next
if (0 == this) then
static if LIBRARY_ErrorMessage then
debug call ThrowError(nodeCount == 8191, "MissileStructure", "allocateNode", "thistype", 0, "Overflow.")
endif
set this = nodeCount + 1
set nodeCount = this
else
set thistype(0)._next = _next
endif
set allocated = true
return this
endmethod
method insertFront takes thistype node returns thistype
// Extra static unique list for missile motion.
set nextNode[node] = 0
set prevNode[node] = prevNode[0]
set nextNode[prevNode[0]] = node
set prevNode[0] = node
static if LIBRARY_ErrorMessage then
debug call ThrowError(this == 0, "List", "push", "thistype", this, "Attempted To Push On To Null List.")
debug call ThrowError(not isCollection, "List", "push", "thistype", this, "Attempted To Push On To Invalid List.")
debug set node.isNode = true
endif
set node._list = this
if (_first == 0) then
set _first = node
set _last = node
set node._next = 0
else
set _first._prev = node
set node._next = _first
set _first = node
endif
set node._prev = 0
return node
endmethod
method remove takes nothing returns nothing
local thistype node = this
set this = node._list
static if LIBRARY_ErrorMessage then
debug call ThrowError(node == 0, "MissileStructure", "remove", "thistype", this, "Attempted To Remove Null Node.")
debug call ThrowError(not node.isNode, "MissileStructure", "remove", "thistype", this, "Attempted To Remove Invalid Node (" + I2S(node) + ").")
debug set node.isNode = false
endif
set node._list = 0
if (0 == node._prev) then
set _first = node._next
else
set node._prev._next = node._next
endif
if (0 == node._next) then
set _last = node._prev
else
set node._next._prev = node._prev
endif
set node._next = thistype(0)._next
set thistype(0)._next = node
set node.allocated = false
// Static unique list for missile motion.
set nextNode[prevNode[node]] = nextNode[node]
set prevNode[nextNode[node]] = prevNode[node]
endmethod
endmodule
// Boolean expressions per struct:
// ===============================
//
// Condition function for the core trigger evaluation. ( Runs for all struct using module MissileStruct )
private function MissileCreateExpression takes integer structId, code func returns nothing
set expression[structId] = Condition(func)
endfunction
// Creates a collection for a struct. ( Runs for all struct using module MissileStruct )
private function MissileCreateCollection takes integer structId returns nothing
set missileList[structId] = Missile.allocateCollection()
endfunction
// Core:
// =====
//
// Fires every Missile_TIMER_TIMEOUT.
private function Fire takes nothing returns nothing
local integer i = remove[0]
set remove[0] = 0
loop
exitwhen 0 == i
if recycling[i] then
call TriggerRemoveCondition(CORE, condition[i])
set condition[i] = null
set active = active - 1
endif
set destroying[i] = false
set recycling[i] = false
set i = remove[i]
endloop
if 0 == active then
call PauseTimer(TMR)
else
// Move all launched missiles.
set Missile.temp = nextNode[0]
set i = 0
loop
exitwhen TriggerEvaluate(MOVE)
exitwhen i == 60// Moved over 8910 missiles, something buggy happened.
set i = i + 1 // This case is impossible, hence never happens. But if I'm wrong, which also never happens
endloop // then the map 100% crashes. i == 66 will prevent the game crash and Missile will start to
// to debug itself over the next iterations.
// Access all structs using module MissileStruct.
static if DEBUG_MODE and LIBRARY_ErrorMesssage then
if not TriggerEvaluate(CORE) then
call ThrowWarning(true, "Missile", "Fire", "op limit", 0, /*
*/"You just ran into a op limit!
The op limit protection of Missile is insufficient for your map.
The code of the missile module can't run in one thread and must be splitted.
If unsure make a post in the official 'The Hive Workshop' forum thread of Missile!")
endif
else
call TriggerEvaluate(CORE)
endif
endif
endfunction
// Conditionally starts the timer.
private function StartPeriodic takes integer structId returns nothing
if 0 == instances[structId] or destroying[structId] then
if destroying[structId] then
set recycling[structId] = false
else
if 0 == active then
call TimerStart(TMR, Missile_TIMER_TIMEOUT, true, function Fire)
endif
set active = active + 1
set condition[structId] = TriggerAddCondition(CORE, expression[structId])
endif
endif
set instances[structId] = instances[structId] + 1
endfunction
// Conditionally stops the timer in the next callback.
private function StopPeriodic takes integer structId returns nothing
set instances[structId] = instances[structId] - 1
if 0 == instances[structId] and condition[structId] != null then
if not destroying[structId] and not recycling[structId] then
set destroying[structId] = true
set recycling[structId] = true
set remove[structId] = remove[0]
set remove[0] = structId
endif
endif
endfunction
// Modules:
// ========
//
// You want to place module MissileLaunch at the very top of your struct.
module MissileLaunch
static method launch takes Missile missile returns nothing
static if LIBRARY_ErrorMessage then
debug call ThrowError(missile.launched, "thistype", "launch", "missile.launched", missile, "This missile was already launched before!")
endif
debug set missile.launched = true
//
call missileList[thistype.typeid].insertFront(missile)
call StartPeriodic(thistype.typeid)
endmethod
endmodule
module MissileTerminate
// Called from missileIterate. "P" to avoid code collision.
static method missileTerminateP takes Missile node returns nothing
if node.allocated then
static if thistype.onRemove.exists then
static if Missile_WRITE_DELAYED_MISSILE_RECYCLING and RecycleBin.recycle.exists then
if thistype.onRemove(node) and GetUnitTypeId(node.dummy) == Missile_DUMMY_UNIT_ID then
call RecycleBin.recycle(node.dummy)
call node.nullBefore()
endif
else
call thistype.onRemove(node)
endif
endif
call node.terminate()
call StopPeriodic(thistype.typeid)
endif
endmethod
endmodule
// Allows you to inject missile in certain stages of the motion process.
module MissileAction
static if DEBUG_MODE then
// Runs check during compile time.
static if thistype.onMissile.exists then
Error Message from library Missile in struct thistype !
thistype.onMissile is a reserved name for Missile, once you implemented MissileStruct.
thistype.onMissile is currently not supported by library Missile.
Please delete or re-name that method.
endif
endif
static if thistype.onItem.exists then
private static method missileActionItem takes nothing returns nothing
local item i = GetEnumItem()
local Missile this = Missile.temp
if this.allocated then
call SaveItemHandle(HASH, this, GetHandleId(i), i)
if thistype.onItem(this, i) then
call missileTerminateP(this)
endif
endif
set i = null
endmethod
endif
static if thistype.onDestructable.exists then
private static method missileActionDest takes nothing returns nothing
local destructable d = GetEnumDestructable()
local Missile this = Missile.temp
if this.allocated then
call SaveDestructableHandle(HASH, this, GetHandleId(d), d)
if thistype.onDestructable(this, d) then
call missileTerminateP(this)
endif
endif
set d = null
endmethod
endif
// Runs every Missile_TIMER_TIMEOUT for this struct.
static method missileIterateP takes nothing returns boolean
local Missile this = missileList[thistype.typeid].first
local Missile node
local real collideZ
local boolean b
local unit u
loop
exitwhen 0 == this
set node = this.next// The linked list should not lose the next node.
if this.wantDestroy then
call thistype.missileTerminateP(this)
else
if this.stackSize > 0 then
call this.updateStack()
endif
// Runs unit collision.
static if thistype.onCollide.exists then
if this.allocated and 0. < this.collision then
set b = this.collisionType == Missile_COLLISION_TYPE_RECTANGLE
if b then
call this.groupEnumUnitsRectangle()
else
call GroupEnumUnitsInRange(GROUP, this.x, this.y, this.collision + Missile_MAXIMUM_COLLISION_SIZE, null)
endif
loop
set u = FirstOfGroup(GROUP)
exitwhen u == null
call GroupRemoveUnit(GROUP, u)
if not HaveSavedHandle(HASH, this, GetHandleId(u)) then
if IsUnitInRange(u, this.dummy, this.collision) or b then
// Eventually run z collision checks.
static if Missile_USE_COLLISION_Z_FILTER then
set collideZ = Missile_GetLocZ(GetUnitX(u), GetUnitY(u)) + GetUnitFlyHeight(u) - this.terrainZ
if (collideZ + GetUnitBodySize(u) >= this.z - this.collisionZ) and (collideZ <= this.z + this.collisionZ) then
// Mark as hit.
call SaveUnitHandle(HASH, this, GetHandleId(u), u)
if thistype.onCollide(this, u) then
call thistype.missileTerminateP(this)
exitwhen true
endif
endif
else
// Runs unit collision without z collision checks.
call SaveUnitHandle(HASH, this, GetHandleId(u), u)
if thistype.onCollide(this, u) then
call thistype.missileTerminateP(this)
exitwhen true
endif
endif
endif
endif
endloop
endif
endif
// Runs destructable collision.
static if thistype.onDestructable.exists then
// Check if the missile is not terminated.
if this.allocated and 0. < this.collision then
call this.checkDestCollision(function thistype.missileActionDest)
endif
endif
// Runs item collision.
static if thistype.onItem.exists then
// Check if the missile is not terminated.
if this.allocated and 0. < this.collision then
call this.checkItemCollision(function thistype.missileActionItem)
endif
endif
// Runs when the destination is reached.
if this.recycle and this.allocated then
static if thistype.onFinish.exists then
if thistype.onFinish(this) then
call thistype.missileTerminateP(this)
endif
else
call thistype.missileTerminateP(this)
endif
endif
// Runs on terrian collision.
static if thistype.onTerrain.exists then
if this.allocated and 0. > this.z and thistype.onTerrain(this) then
call missileTerminateP(this)
endif
endif
// Runs every Missile_TIMER_TIMEOUT.
static if thistype.onPeriod.exists then
if this.allocated and thistype.onPeriod(this) then
call missileTerminateP(this)
endif
endif
endif
set this = node
endloop
set u = null
static if DEBUG_MODE and LIBRARY_ErrorMessage then
return true
else
return false
endif
endmethod
endmodule
module MissileStruct
implement MissileLaunch
implement MissileTerminate
implement MissileAction
private static method onInit takes nothing returns nothing
call MissileCreateCollection(thistype.typeid)
call MissileCreateExpression(thistype.typeid, function thistype.missileIterateP)
endmethod
endmodule
// Missile position:
// =================
//
// Simple trigonometry.
//! textmacro WRITE_MISSILE_POSITION_CODE
struct MissilePosition extends array
private static integer array recycler
private static integer alloc = 0
// Readonly members you can access.
readonly real x
readonly real y
readonly real z
readonly real angle
readonly real distance
readonly real square
readonly real slope
readonly real alpha
// Creates an origin - impact link.
private thistype ref
private static method math takes thistype a, thistype b returns nothing
local real dx
local real dy
loop
set dx = b.x - a.x
set dy = b.y - a.y
set dx = dx*dx + dy*dy
set dy = SquareRoot(dx)
exitwhen dx != 0. and dy != 0.
set b.x = b.x + .01
set b.z = b.z - Missile_GetLocZ(b.x -.01, b.y) + Missile_GetLocZ(b.x, b.y)
endloop
set a.square = dx
set a.distance = dy
set a.angle = Atan2(b.y - a.y, b.x - a.x)
set a.slope = (b.z - a.z)/dy
set a.alpha = Atan(a.slope)*bj_RADTODEG
// Set b.
if b.ref == a then
set b.angle = a.angle + bj_PI
set b.distance = dy
set b.slope = -a.slope
set b.alpha = -a.alpha
set b.square = dx
endif
endmethod
static method link takes thistype a, thistype b returns nothing
set a.ref = b
set b.ref = a
call math(a, b)
endmethod
method move takes real toX, real toY, real toZ returns nothing
set x = toX
set y = toY
set z = toZ + Missile_GetLocZ(toX, toY)
if ref != this then
call math(this, ref)
endif
endmethod
method destroy takes nothing returns nothing
set recycler[this] = recycler[0]
set recycler[0] = this
endmethod
static method create takes real x, real y, real z returns MissilePosition
local thistype this = recycler[0]
if 0 == this then
set alloc = alloc + 1
set this = alloc
else
set recycler[0] = recycler[this]
endif
set ref = this
call move(x, y, z)
return this
endmethod
endstruct
//! endtextmacro
// Delayed dummy recycling:
// ========================
//
// Ensures proper fx death animations.
//! textmacro WRITE_MISSILE_RECYCLE_BIN takes DO_THIS, AFTER_TIME
static if $DO_THIS$ then
private struct RecycleBin extends array
private static constant timer t = CreateTimer()
private static integer max = 0
private static unit array dummy
private static real array time
private static method onPeriodic takes nothing returns nothing
local integer dex = 0
loop
exitwhen dex == thistype.max
set thistype.time[dex] = thistype.time[dex] - 1
if 0 >= thistype.time[dex] then
static if LIBRARY_MissileRecycler then
call RecycleMissile(thistype.dummy[dex])
elseif Dummy.create.exists and LIBRARY_Dummy then
call Dummy[thistype.dummy[dex]].destroy()
elseif LIBRARY_xedummy and xedummy.release.exists then
call xedummy.release(thistype.dummy[dex])
else
call RemoveUnit(thistype.dummy[dex])
endif
set thistype.dummy[dex] = null
set thistype.max = thistype.max - 1
set thistype.dummy[dex] = thistype.dummy[thistype.max]
set thistype.time[dex] = thistype.time[thistype.max]
set thistype.dummy[thistype.max] = null
set dex = dex - 1
if 0 == thistype.max then
call PauseTimer(thistype.t)
endif
endif
set dex = dex + 1
endloop
endmethod
static method recycle takes unit toRecycle returns nothing
if 0 == thistype.max then
call TimerStart(thistype.t, 1., true, function thistype.onPeriodic)
endif
set thistype.dummy[max] = toRecycle
set thistype.time[max] = $AFTER_TIME$ + TimerGetRemaining(thistype.t)
set thistype.max = thistype.max + 1
endmethod
endstruct
endif
//! endtextmacro
// The end!
endlibrary
library MissileRecycler initializer PreInit requires optional UnitIndexer, optional UnitDex, optional UnitIndexerGUI /*
MissileRecycler v 1.4.5.2
=========================================================================
Credits:
-------------------------------------------------------------------------
Written by Bribe
Vexorian, Anitarf and iNfraNe for the dummy.mdx model file
Nestharus for the Queue data structure and for finding that paused units
consume very few CPU resources.
=========================================================================
Introduction:
-------------------------------------------------------------------------
Recycling dummy units is important because the CreateUnit call is one of,
if not the, most processor-intensive native in the entire game. Creating
just a couple dozen dummy units in a single thread causes a visible frame
glitch for that instant. The overhead is even higher if you are using a
Unit Indexing library in the map which causes some extra evaluations per
new unit.
There are also reports of removed units leaving a little trail of RAM
surplus in their wake. I have not been able to reproduce this so I don't
know how serious it is.
I was motivated to create this system because removed units might be un-
safe in very large numbers and CreateUnit is a very heavy process.
The thing that makes this system different than others is the fact that
it considers the facing angle of the dummies being recycled, which I have
never seen another system even attempt before this. Since then,
MissileRecycler has inspired Anitarf to update XE with the same angle-retaining
capability and Nestharus has created Dummy. Considering the facing angle is
important because it takes 0.73 seconds for the unit to turn around,
which - when overlooked - looks especially weird if you are creating a unit-trail
or if you are shooting arrow-shaped objects as projectiles. For fireball effects or
effects that generally don't depend on facing angle, this system would be
a bit wasteful.
With default settings and the worst-case-scenario, it will take 0.09 seconds for
the projectile to turn to the angle you need. This is 1/8 of the normal worst case
scenario if you weren't recycling dummies considering facing. On average, it takes
roughly 0.045 seconds to turn to the angle you need (which is not noticable).
However, I have made this completely configurable and you are
able to change the values to whatever needs you have.
=========================================================================
Calibration Guide:
-------------------------------------------------------------------------
The thing that surprised me the most about this system was, no matter how
complex it turned out, it became very configurable. So I should let you
know what the constants do so you know if/how much you want to modify.
constant real DEATH_TIME = 5.0 //seconds
- Should not be less than the maximum time a death animation needs to play.
Should not be lower than .73 to ensure enough time to turn.
Should not be too high otherwise the dummies will take too long to recycle.
constant integer ANG_N = 8
- How many different angles are recognized by the system. Don't do
360 different angles because then you're going to have thousands of dummy
units stored and that's ridiculous, the game lags enough at 1000 units.
Increasing ANG_N increases realism but decreases the chance that a dummy
unit will be available to be recycled. I don't recommend making this any
lower, and the max I'd recommend would be 16.
constant integer ANG_STORAGE_MAX = 12
- How many dummy units are stored per angle. This limit is important
because you might have a spike at one point in the game where many units
are created, which could result in too high of a dummy population.
In general, I advise that the product of ANG_N x ANG_STORAGE_MAX does
not exceed 100 or 200. More than that is excessive, but you can
hypothetically have it up to 8190 if Warcraft 3's memory management
were better.
Preloads ANG_N x ANG_STORAGE_MAX dummy units. Preloading dummies is
useful as it dumps a lot of CreateUnit calls in initialization where you
won't see a frame glitch. In the 1.4 update, preloading is done 0 seconds
into the game to ensure any Indexers have already initialized.
private function ToggleIndexer takes boolean flag returns nothing
- Put what you need in here to disable/enable any indexer in your
map. if flag is true, enable indexer. If false, disable.
=========================================================================
API Guide:
-------------------------------------------------------------------------
You obviously need some functions so you can get a recycled dummy unit or
recycle it. Therefore I provide these:
function GetRecycledMissile
takes real x, real y, real z, real facing
returns unit
Returns a new dummy unit that acts as a projectile missile. The args
are simply the last three arguments you'd use for a CreateUnit call,
with the addition of a z parameter to represent the flying height -
it isn't the absolute z but relative to the ground because it uses
SetUnitFlyHeight on that value directly.
function RecycleMissile
takes unit u
returns nothing
When you are done with that dummy unit, recycle it via this function.
This function is pretty intelligent and resets that unit's animation
and its facing angle so you don't have to.
*/
//=======================================================================
// Save the map, then delete the exclaimation mark in the following line.
// Make sure that you don't have an object in your map with the rawcode
// 'dumi' and also configure the model path (war3mapImported\dummy.mdl)
// to the dummy.mdx model created by Vexorian.
///! external ObjectMerger w3u ewsp dumi unam "Missile Dummy" ufoo 0 utyp "" ubui "" uhom 1 ucol 0.01 umvt "None" umvr 1.00 utar "" uspa "" umdl "war3mapImported\dummy.mdl" umxr 0.00 umxp 0.00 ushr 0 uerd 0.00 udtm 0.00 ucbs 0.00 uble 0.00 uabi "Aloc,Amrf"
//Thanks to Vexorian that Optimizer 5.0 no longer kills natives
native UnitAlive takes unit id returns boolean
globals
//-------------------------------------------------------------------
// You must configure the dummy unit with the one created from the
// ObjectMerger statement above.
//
private constant integer DUMMY_ID = 'e000' //The rawcode of the dummy unit.
private player OWNER = Player(bj_PLAYER_NEUTRAL_EXTRA) //The owner of the dummy unit.
private constant integer ANG_N = 8 //# of indexed angles. Higher value increases realism but decreases recycle frequency.
private constant integer ANG_STORAGE_MAX = 12 //Max dummies per indexed angle. I recommend lowering this if you increase ANG_N.
private constant real DEATH_TIME = 5. //Allow the special effect on
//the unit to complete its "death" animation in this timeframe. Must
//be higher than 0.74 seconds to allow the unit time to turn. This
//number should not be lower than the maximum death-animation time of
//your missile-units' effect attachments, just to be safe.
endglobals
private function ToggleIndexer takes boolean flag returns nothing
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = flag
elseif LIBRARY_UnitIndexerGUI then
set udg_UnitIndexerEnabled = flag
elseif LIBRARY_UnitDex then
set UnitDex.Enabled = flag
endif
endfunction
globals
private constant integer ANG_VAL = 360 / ANG_N //Generate angle value from ANG_N.
private constant integer ANG_MID = ANG_VAL / 2 //The middle value of angle value.
//Misc vars
private unit array stack //Recycled dummy units.
private real array timeStamp //Prevents early recycling of units.
private integer array queueNext
private integer array queueLast
private integer recycle = 0
private timer gameTime = CreateTimer() //Used for visual continuity.
private integer array queueStack
private integer queueStackN = 0 //Used to avoid searching the queues.
endglobals
static if DEBUG_MODE then
private function Print takes string s returns nothing
//Un-comment this next line if you want to know how the system works:
//call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 999, "[MissileRecycler] " + s)
endfunction
endif
//=======================================================================
// Get a recycled dummy missile unit. If there are no recycled dummies
// that are already facing the angle you need, it creates a new dummy for
// you.
//
function GetRecycledMissile takes real x, real y, real z, real facing returns unit
local integer i = ModuloInteger(R2I(facing), 360) / ANG_VAL
local integer this = queueNext[i]
local unit u
if this != 0 and TimerGetElapsed(gameTime) >= timeStamp[this] then
//Dequeue this
set queueNext[i] = queueNext[this]
if queueNext[i] == 0 then
set queueLast[i] = i
endif
//Recycle this index
set queueLast[this] = recycle
set recycle = this
//Add queue index to available stack
set queueStack[queueStackN] = i
set queueStackN = queueStackN + 1
//Old unit will return as new
set u = stack[this]
call SetUnitFacing(u, facing)
call SetUnitUserData(u, 0)
//Reset the dummy's properties.
call SetUnitVertexColor(u, 255, 255, 255, 255)
call SetUnitAnimationByIndex(u, 90)
call SetUnitScale(u, 1, 0, 0)
//call PauseUnit(u, false) -- you can disable "resets" that you don't need to worry about.
debug call Print("Recycling")
else
debug call Print("Creating new")
call ToggleIndexer(false)
set u = CreateUnit(OWNER, DUMMY_ID, x, y, facing)
call ToggleIndexer(true)
call PauseUnit(u, true)
endif
call SetUnitX(u, x)
call SetUnitY(u, y)
call SetUnitFlyHeight(u, z, 0)
set bj_lastCreatedUnit = u
set u = null
return bj_lastCreatedUnit
endfunction
//=======================================================================
// You should recycle the dummy missile unit when its job is done.
//
function RecycleMissile takes unit u returns nothing
local integer i
local integer this = recycle
if GetUnitTypeId(u) == DUMMY_ID and UnitAlive(u) and GetUnitUserData(u) != -1 then
if queueStackN == 0 then
debug call Print("Stack is full - removing surplus unit")
call UnitApplyTimedLife(u, 'BTLF', DEATH_TIME)
return
endif
//Recycle this
set recycle = queueLast[this]
//Index the dummy unit to an available facing angle.
//Get the last vacant angle index.
set queueStackN = queueStackN - 1
set i = queueStack[queueStackN]
//Enqueue this
set queueNext[queueLast[i]] = this
set queueLast[i] = this
set queueNext[this] = 0
//Allow a time barrier for the effect to destroy/turn to complete.
set timeStamp[this] = TimerGetElapsed(gameTime) + DEATH_TIME
set stack[this] = u
call SetUnitFacing(u, i * ANG_VAL + ANG_MID)
call SetUnitOwner(u, OWNER, false)
//Prevent double-free of this unit.
call SetUnitUserData(u, -1)
debug else
debug call BJDebugMsg("[MissileRecycler] Error: Attempt to recycle invalid unit.")
endif
endfunction
//=======================================================================
// I didn't need this function after all
//
function RecycleMissileDelayed takes unit u, real r returns nothing
call RecycleMissile(u)
endfunction
//=======================================================================
// Map the dummy units to their facing angles (map below is if ANG_N is
// 4 and ANG_STORAGE_MAX is 3).
//
// angle[0] (0) - [4] [5] [6]
// angle[1] (90) - [7] [8] [9]
// angle[2] (180) - [10][11][12]
// angle[3] (270) - [13][14][15]
//
private function Init takes nothing returns nothing
local integer end
local integer i = ANG_N
local integer n = i
local integer angle
local real x = GetRectMaxX(bj_mapInitialPlayableArea)
local real y = GetRectMaxY(bj_mapInitialPlayableArea)
local unit u
call ToggleIndexer(false)
loop
set i = i - 1
set queueNext[i] = n
set angle = i * ANG_VAL + ANG_MID
set end = n + ANG_STORAGE_MAX
set queueLast[i] = end - 1
loop
set queueNext[n] = n + 1
set u = CreateUnit(OWNER, DUMMY_ID, x, y, angle)
set stack[n] = u
call PauseUnit(u, true)
call SetUnitUserData(u, -1)
set n = n + 1
exitwhen n == end
endloop
set queueNext[n - 1] = 0
exitwhen i == 0
endloop
call ToggleIndexer(true)
call TimerStart(gameTime, 1000000., false, null)
set u = null
endfunction
private function PreInit takes nothing returns nothing
static if LIBRARY_UnitIndexerGUI then
call OnUnitIndexerInitialized(function Init)
else
call Init()
endif
endfunction
endlibrary
library AngledRect
/* Illustration.
rotation
|
A(x, y) ____|____ B(x, y)
|////|////|
|////•////| height
|/////////|
D(x, y) ¯¯¯¯¯¯¯¯¯ C(x, y)
width
*/
private struct Vector
real x
real y
method destroy takes nothing returns nothing
call deallocate()
endmethod
static method create takes real x, real y returns thistype
local thistype this = allocate()
set .x = x
set .y = y
return this
endmethod
endstruct
struct AngledRect
readonly Vector A
readonly Vector B
readonly Vector C
readonly Vector D
private real d
private real a
readonly real x
readonly real y
readonly real width
readonly real height
private static thistype This
private static group Group = CreateGroup()
private method repaint takes nothing returns nothing
local real w = .width/2
local real h = .height/2
local real a
call clear()
set .d = SquareRoot(w*w+h*h)
set a = .a + Atan(w/h)
set A = Vector.create(.x + .d * Cos(a), .y + .d * Sin(a))
set a = a + bj_PI
set C = Vector.create(.x + .d * Cos(a), .y + .d * Sin(a))
set a = .a - Atan(w/h)
set B = Vector.create(.x + .d * Cos(a), .y + .d * Sin(a))
set a = a + bj_PI
set D = Vector.create(.x + .d * Cos(a), .y + .d * Sin(a))
endmethod
private method clear takes nothing returns nothing
call A.destroy()
call B.destroy()
call C.destroy()
call D.destroy()
endmethod
method destroy takes nothing returns nothing
call clear()
call deallocate()
endmethod
method operator angle= takes real a returns nothing
set .a = a*bj_DEGTORAD
call repaint()
endmethod
method operator angle takes nothing returns real
return a*bj_RADTODEG
endmethod
method move takes real x, real y returns nothing
set .x = x
set .y = y
call repaint()
endmethod
method size takes real width, real height returns nothing
set .width = width
set .height = height
call repaint()
endmethod
private static method vector takes Vector p1, Vector p2 returns Vector
return Vector.create(p2.x-p1.x, p2.y-p1.y)
endmethod
private static method dot takes Vector u, Vector v returns real
return (u.x*v.x)+(u.y*v.y)
endmethod
method containsPoint takes real x, real y returns boolean
local Vector M = Vector.create(x, y)
local Vector AM = vector(A, M)
local Vector AB = vector(A, B)
local Vector AD = vector(A, D)
local real dotAMAB = dot(AM, AB)
local real dotAMAD = dot(AM, AD)
call M.destroy()
call AM.destroy()
call AB.destroy()
call AD.destroy()
return (0 < dotAMAB and dotAMAB < dot(AB, AB)) and (0 < dotAMAD and dotAMAD < dot(AD, AD))
endmethod
method containsWidget takes widget w returns boolean
return containsPoint(GetWidgetX(w), GetWidgetY(w))
endmethod
method containsUnit takes unit u returns boolean
return containsPoint(GetUnitX(u), GetUnitY(u))
endmethod
private static method inbox takes nothing returns boolean
return This.containsUnit(GetFilterUnit())
endmethod
method enum takes group g, boolexpr filter returns nothing
local unit u
if filter == null then
set This = this
call GroupEnumUnitsInRange(g, .x, .y, .d, Filter(function thistype.inbox))
else
call GroupEnumUnitsInRange(Group, .x, .y, .d, filter)
loop
set u = FirstOfGroup(Group)
exitwhen u == null
call GroupRemoveUnit(Group, u)
if containsUnit(u) then
call GroupAddUnit(g, u)
endif
endloop
endif
endmethod
static method create takes real x, real y, real width, real height, real angle returns thistype
local thistype this = allocate()
set .x = x
set .y = y
set .a = angle*bj_DEGTORAD
set .width = width
set .height = height
call repaint()
return this
endmethod
endstruct
endlibrary
library ArrowKeyEvent /*
=========================================================================
ArrowKeyEvent version 1.1.0.0
=========================================================================
Credits:
-------------------------------------------------------------------------
- Written by Bribe.
- Earth-Fury for providing a lot of inspiration for the development of
this system (especially documentation) via his KeyAction resource.
- tooltiperror & Sgqvur for providing very helpful, constructive advice.
- SA Dashie for the functionality to enable/disable an individual module
event.
=========================================================================
Introduction:
-------------------------------------------------------------------------
Easy to use, efficient system for handling all arrow key events. It uses
arrays and GetHandleId lookups to avoid the trap of many cloned functions
that so many arrow key systems suffer from.
=========================================================================
API Guide:
-------------------------------------------------------------------------
To help centralize and make everything understandable, I originally used
the constants appointed by Blizzard (bj_KEYEVENTKEY_LEFT/RIGHT/etc). But
there was a lot of criticism over their ugliness so I made the following
constants to correspond accordingly. They have the same values as the BJ
constants, so you can use whichever is more appealing for you.
Their purpose is to be passed as arguments so you are able to query such
things as "is this key pressed" or simply to help make sense of what key
was pressed from an event response and interpret it as an integer.
constant integer ARROW_KEY_LEFT = 0
constant integer ARROW_KEY_RIGHT = 1
constant integer ARROW_KEY_DOWN = 2
constant integer ARROW_KEY_UP = 3
-------------------------------------------------------------------------
As I was developing this resource, is was mostly written in vanilla JASS.
I had since converted it to OOP syntax but it has been requested to bring
it back. I have made it available once again.
function IsArrowKeyPressed
takes player whichPlayer, integer arrowKey
returns boolean
To find out if the arrow key was pressed, you need to first ask which
player is holding down the key, and then pass an ARROW_KEY constant
to represent the key you are querying for.
function RegisterArrowKeyEvent
takes code onEvent
returns nothing
Instead of making up to 8 different functions for 8 different events,
you can use this instead. Just specify a function that you want to be
called whenever any key is pressed. For event responses, reference 1
of the following 3 functions:
function GetEventArrowKeyPlayerId
takes nothing
returns integer
This is more of an optimization benefit than not. GetTriggerPlayer()
will get you the player who pressed the key, but most of the time you
just need to know the player ID of that person.
function GetEventArrowKey
takes nothing
returns integer
Call this function to find out which key was pressed. It will return
one of the four ARROW_KEY constants, of course.
function IsEventArrowKeyPressed
takes nothing
returns boolean
This is also here more for optimization's benefit. You can certainly
use "IsArrowKeyPressed(GetEventArrowKey(GetEventArrowKeyPlayerId()))"
but this is much more convenient I must say.
-------------------------------------------------------------------------
"implement ArrowKey"
ArrowKey API is accessible as if it were part of the implementing struct
itself. As a bonus, you can create a method "onArrowKeyEvent" that gets
called automatically when any key is pressed. The method musn't be static,
because the member "this" is a player ID (to mirror the ArrowKey struct's
own API). It must take an integer as its first argument to represent the
pressed or released key. As a final argument, it must take a boolean to
determine if the key was pressed (true) or released (false).
The member "this" taken by the method is a player ID.
NEW: Each module has its own enabler of the event, either as a whole or
for an individual player(s). This is entirely due to the work done by SA Dashie.
*/
//=======================================================================
//
// System Code
//
//=======================================================================
globals
//-------------------------------------------------------------------
// Yo dawg, I herd you like constant variables so I gave you some new
// constant variables so you can have some constant variables to go
// with Blizzard's constant variables.
//
constant integer ARROW_KEY_LEFT = bj_KEYEVENTKEY_LEFT
constant integer ARROW_KEY_RIGHT = bj_KEYEVENTKEY_RIGHT
constant integer ARROW_KEY_DOWN = bj_KEYEVENTKEY_DOWN
constant integer ARROW_KEY_UP = bj_KEYEVENTKEY_UP
endglobals
//=======================================================================
// Ugly modules are needed to prevent initialization bugs.
//
private module Init
private static method onInit takes nothing returns nothing
local player p
local integer i = 12
local trigger t = .trig
loop
set i = i - 1
set p = Player(i)
if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p) == MAP_CONTROL_USER then
//Register arrow key events for playing players
call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_LEFT_DOWN)
call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_LEFT_UP)
call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_RIGHT_DOWN)
call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_RIGHT_UP)
call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_DOWN_DOWN)
call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_DOWN_UP)
call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_UP_DOWN)
call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_UP_UP)
//Run if library ArrowKey is found in the map.
//! runtextmacro optional INIT_ARROW_KEY_AA()
endif
exitwhen i == 0
endloop
//Run if library ArrowKey is found in the map.
//! runtextmacro optional INIT_ARROW_KEY_CALL_LINK()
call .registerEvent(function ArrowKey.actions)
set p = null
set t = null
endmethod
endmodule
//=======================================================================
// A central struct to handle all ArrowKey mechanics. This has its uses,
// giving you slightly more control over the inner system functionality.
//
struct ArrowKey extends array
//-------------------------------------------------------------------
// Event responses
//
readonly static integer eventKey = 0 //Arrow key that triggered the event.
readonly static boolean eventKeyPressed = false //Was the arrow key pressed?
readonly static ArrowKey eventPlayerId = 0 //The id of the player who pressed the key.
//Run if library ArrowKey is found in the map.
//! runtextmacro optional ARROW_KEY_DECLARE_ARRAYS()
//-------------------------------------------------------------------
// System variables
//
private static trigger trig = CreateTrigger() //Handles all events.
private static boolean array press //Is key pressed?
//===================================================================
// User-friendly typecasting.
//
static method operator [] takes player who returns ArrowKey
return GetPlayerId(who)
endmethod
//===================================================================
// Great for simplifying arrow key events - this function runs when
// any player presses or releases an arrow key. The code passed is
// expected to "return false".
//
static method registerEvent takes code onEvent returns nothing
call TriggerAddCondition(.trig, Filter(onEvent))
return
endmethod
//===================================================================
// Returns true if the key is pressed, false if it is released.
//
method isPressed takes integer arrow returns boolean
return press[this + arrow * 12]
endmethod
//Run if library ArrowKey is found in the map.
//! runtextmacro optional ARROW_KEY_AXIS_METHODS()
//===================================================================
// If you are running debug tests, this might come in handy.
//
static if DEBUG_MODE then
static method getKeyName takes integer arrow returns string
if arrow == ARROW_KEY_LEFT then
return "LEFT"
elseif arrow == ARROW_KEY_RIGHT then
return "RIGHT"
elseif arrow == ARROW_KEY_DOWN then
return "DOWN"
elseif arrow == ARROW_KEY_UP then
return "UP"
endif
return "--"
endmethod
endif
//===================================================================
//
// Private Components
//
//===================================================================
//===================================================================
// Key event handler.
//
private static method actions takes nothing returns nothing
local integer id = GetHandleId(GetTriggerEventId()) - 261
set .eventPlayerId = GetPlayerId(GetTriggerPlayer())
//If id is an even number, the key was pressed.
set .eventKey = id / 2
set .eventKeyPressed = .eventKey * 2 == id
set .press[.eventPlayerId + .eventKey * 12] = .eventKeyPressed
//Run if library ArrowKey is found in the map.
//! runtextmacro optional ARROW_KEY_SETUP()
endmethod
//Run if library ArrowKey is found in the map.
//! runtextmacro optional INIT_ARROW_KEY_LINK()
//Initialize the system via module
implement Init
endstruct
//=======================================================================
//
// Event Responses
//
//=======================================================================
//=======================================================================
function IsArrowKeyPressed takes player whichPlayer, integer arrowKey returns boolean
return ArrowKey[whichPlayer].isPressed(arrowKey)
endfunction
//=======================================================================
function RegisterArrowKeyEvent takes code onEvent returns nothing
call ArrowKey.registerEvent(onEvent)
endfunction
//=======================================================================
function GetEventArrowKeyPlayerId takes nothing returns integer
return ArrowKey.eventPlayerId
endfunction
//=======================================================================
function GetEventArrowKey takes nothing returns integer
return ArrowKey.eventKey
endfunction
//=======================================================================
function IsEventArrowKeyPressed takes nothing returns boolean
return ArrowKey.eventKeyPressed
endfunction
//=======================================================================
// Implementation of this module allows you to make your struct "extend"
// the ArrowKey struct. As a bonus feature, you can create a method named
// "onArrowKeyEvent" that is called whenever a key is pressed or released.
// The method needs "takes integer arrow, boolean pressed", and must be
// positioned *above* the "implement ArrowKey" statement (this way it is
// detected by the static if and doesn't compile to a function interface).
//
module ArrowKey
//Delegates are fun, you should try them out.
private delegate ArrowKey AK
boolean enabledFor //this variable added in version 1.1.
//===================================================================
// This method added in version 1.1. It disables or enables the event
// in this module for all players.
//
static method operator enabled= takes boolean flag returns nothing
local integer i = 12
loop
set i = i - 1
set thistype(i).enabledFor = flag
exitwhen i == 0
endloop
endmethod
//===================================================================
// Please call this method from *below the module implement statement
// if you know what's good for you.
//
static method operator [] takes player who returns thistype
return GetPlayerId(who)
endmethod
static if thistype.onArrowKeyEvent.exists then
private static method eventProxy takes nothing returns nothing
local thistype this = .eventPlayerId
if .enabledFor then
call .onArrowKeyEvent(.eventKey, .eventKeyPressed)
endif
endmethod
endif
private static method onInit takes nothing returns nothing
local thistype i = 12
loop
set i = i - 1
set i.AK = i //Delegates require some delegation of course.
set thistype(i).enabledFor = true //Every player active at first
exitwhen i == 0
endloop
static if thistype.onArrowKeyEvent.exists then
call ArrowKey.registerEvent(function thistype.eventProxy)
endif
endmethod
endmodule
endlibrary
/*****************************************************************************
*
* InventoryEvent v1.0.0.0
* by Bannar aka Spinnaker
*
* For intuitive inventory event handling.
*
******************************************************************************
*
* Optional requirements:
*
* RegisterPlayerUnitEvent by Bannar
* hiveworkshop.com/forums/submissions-414/snippet-registerevent-pack-250266/
*
* OrderEvent by Bribe
* hiveworkshop.com/forums/jass-resources-412/snippet-order-event-190871/
*
******************************************************************************
*
* Functions:
*
* function GetEventInventoryUnit takes nothing returns unit
* returns unit which manipulated event item
*
* function GetEventInventoryItem takes nothing returns item
* returns manupilated event item
*
* function GetEventInventorySlotFrom takes nothing returns integer
* returns slot index of manipulated item from which it was moved or used
*
* function GetEventInventorySlotTo takes nothing returns integer
* returns slot index of manipulated item to which it was moved
*
* function GetEventInventorySwapped takes nothing returns item
* returns item which was swapped with manipulated item on MOVED event if any
*
* function GetUnitItemSlot takes unit u, item it returns integer
* retrieves item index slot if any for item owning unit u
*
* function RegisterInventoryEvent takes code cb, integer ev returns nothing
* registers new event handler cb for inventory event ev
*
* function TriggerRegisterInventoryEvent takes trigger t, integer ev returns nothing
* registers event ev for trigger t
*
* function GetInvnetoryEventTrigger takes integer whichEvent returns trigger
* retrieves trigger handle for event with id whichEvent
*
******************************************************************************
*
* Events that can be used:
*
* integer InventoryEvent.MOVED
* integer InventoryEvent.USED
*
*****************************************************************************/
library InventoryEvent requires /*
*/ optional RegisterPlayerUnitEvent /*
*/ optional OrderEvent
globals
private unit eventUnit = null
private item eventItem = null
private integer eventSlotFrom = -1
private integer eventSlotTo = -1
private trigger array triggers
private real caller = 0
endglobals
function GetEventInventoryUnit takes nothing returns unit
return eventUnit
endfunction
function GetEventInventoryItem takes nothing returns item
return eventItem
endfunction
function GetEventInventorySlotFrom takes nothing returns integer
return eventSlotFrom
endfunction
function GetEventInventorySlotTo takes nothing returns integer
return eventSlotTo
endfunction
function GetEventInventorySwapped takes nothing returns item
return UnitItemInSlot(eventUnit, eventSlotTo)
endfunction
function GetUnitItemSlot takes unit u, item it returns integer
local integer i = 0
local integer size = UnitInventorySize(u)
if ( UnitHasItem(u, it) ) then
loop
if ( UnitItemInSlot(u, i) == it ) then
return i
endif
set i = i+1
exitwhen i == size
endloop
endif
return -1 // NOT_FOUND
endfunction
private function RegisterAnyUnitEvent takes playerunitevent e, code c returns nothing
static if LIBRARY_RegisterPlayerUnitEvent then
static if RPUE_VERSION_NEW then
call RegisterAnyPlayerUnitEvent(e, c)
else
call RegisterPlayerUnitEvent(e, c)
endif
else
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, e)
call TriggerAddCondition(t, Condition(c))
set t = null
endif
endfunction
private module InventoryEventInit
private static method onInit takes nothing returns nothing
static if LIBRARY_OrderEvent then
local integer i = 852002 // range from 852002 to 852013
loop
call RegisterOrderEvent(i, function thistype.onItemOrder)
set i = i+1
exitwhen i > 852013
endloop
else // MOVED is order of type TARGET_ORDER yet USED can be anyone of them
call RegisterAnyUnitEvent(EVENT_PLAYER_UNIT_ISSUED_ORDER, function thistype.onAnyOrder)
call RegisterAnyUnitEvent(EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, function thistype.onAnyOrder)
call RegisterAnyUnitEvent(EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, function thistype.onAnyOrder)
endif
set triggers[MOVED] = CreateTrigger()
set triggers[USED] = CreateTrigger()
call TriggerRegisterVariableEvent(triggers[MOVED], SCOPE_PRIVATE + "caller", EQUAL, MOVED)
call TriggerRegisterVariableEvent(triggers[USED], SCOPE_PRIVATE + "caller", EQUAL, USED)
endmethod
endmodule
struct InventoryEvent extends array
readonly static integer MOVED = 1
readonly static integer USED = 2
private static method fire takes integer ev, unit u, item it, integer slotFrom, integer slotTo returns nothing
local unit prevUnit = eventUnit
local item prevItem = eventItem
local integer prevSlotFrom = eventSlotFrom
local integer prevSlotTo = eventSlotTo
set eventUnit = u
set eventItem = it
set eventSlotFrom = slotFrom
set eventSlotTo = slotTo
set caller = ev
set caller = 0
set eventUnit = prevUnit
set eventItem = prevItem
set eventSlotFrom = prevSlotFrom
set eventSlotTo = prevSlotTo
set prevUnit = null
set prevItem = null
endmethod
private static method onItemOrder takes nothing returns nothing
local integer order = GetIssuedOrderId()
local unit u = GetTriggerUnit()
local item it = GetOrderTargetItem()
local integer slot
local integer slot2
if ( order >= 852002 and order <= 852007 ) then
set it = GetOrderTargetItem()
set slot = GetUnitItemSlot(u, it)
set slot2 = order - 852002
call fire(MOVED, u, it, slot, slot2)
else
set slot = order - 852008
set it = UnitItemInSlot(u, slot)
call fire(USED, u, it, slot, -1)
endif
set u = null
set it = null
endmethod
static if not LIBRARY_OrderEvent then
private static method onAnyOrder takes nothing returns boolean
local integer order = GetIssuedOrderId()
call BJDebugMsg("order " + GetUnitName(GetTriggerUnit())
if ( order >= 852002 and order <= 852013 ) then
call onItemOrder()
endif
return false
endmethod
endif
implement InventoryEventInit
endstruct
function RegisterInventoryEvent takes code c, integer ev returns nothing
call TriggerAddCondition(triggers[ev], Condition(c))
endfunction
function TriggerRegisterInventoryEvent takes trigger t, integer ev returns nothing
call TriggerRegisterVariableEvent(t, SCOPE_PRIVATE + "caller", EQUAL, ev)
endfunction
function GetInventoryEventTrigger takes integer whichEvent returns trigger
return triggers[whichEvent]
endfunction
endlibrary
library TimedHandles uses optional TimerUtils
/**************************************************************
*
* v1.0.5 by TriggerHappy
* ----------------------
*
* Use this to destroy a handle after X amount seconds.
*
* It's useful for things like effects where you may
* want it to be temporary, but not have to worry
* about the cleaning memory leak. By default it supports
* effects, lightning, weathereffect, items, ubersplats, and units.
*
* If you want to add your own handle types copy a textmacro line
* at the bottom and add whichever handle you want along with it's destructor.
*
* Example: //! runtextmacro TIMEDHANDLES("handle", "DestroyHandle")
*
* Installation
----------------------
* 1. Copy this script and over to your map inside a blank trigger.
* 2. If you want more efficiency copy TimerUtils over as well.
*
* API
* ----------------------
* call DestroyEffectTimed(AddSpecialEffect("effect.mdx", 0, 0), 5)
* call DestroyLightningTimed(AddLightning("CLPB", true, 0, 0, 100, 100), 5)
*
* Credits to Vexorian for TimerUtils and his help on the script.
*
**************************************************************/
globals
// If you don't want a timer to be ran each instance
// set this to true.
private constant boolean SINGLE_TIMER = true
// If you chose a single timer then this will be the speed
// at which the timer will update
private constant real UPDATE_PERIOD = 0.05
endglobals
// here you may add or remove handle types
//! runtextmacro TIMEDHANDLES("effect", "DestroyEffect")
//! runtextmacro TIMEDHANDLES("lightning", "DestroyLightning")
//! runtextmacro TIMEDHANDLES("weathereffect", "RemoveWeatherEffect")
//! runtextmacro TIMEDHANDLES("item", "RemoveItem")
//! runtextmacro TIMEDHANDLES("unit", "RemoveUnit")
//! runtextmacro TIMEDHANDLES("ubersplat", "DestroyUbersplat")
// Do not edit below this line
//! textmacro TIMEDHANDLES takes HANDLE,DESTROY
struct $HANDLE$Timed
$HANDLE$ $HANDLE$_var
static integer index = -1
static thistype array instance
static real REAL=UPDATE_PERIOD
static if SINGLE_TIMER then
static timer timer = CreateTimer()
real duration
real elapsed = 0
else static if not LIBRARY.TimerUtils then
static hashtable table = InitHashtable()
endif
method destroy takes nothing returns nothing
call $DESTROY$(this.$HANDLE$_var)
set this.$HANDLE$_var = null
static if SINGLE_TIMER then
set this.elapsed = 0
endif
call this.deallocate()
endmethod
private static method remove takes nothing returns nothing
static if SINGLE_TIMER then
local integer i = 0
local thistype this
loop
exitwhen i > thistype.index
set this = instance[i]
set this.elapsed = this.elapsed + UPDATE_PERIOD
if (this.elapsed >= this.duration) then
set instance[i] = instance[index]
set i = i - 1
set index = index - 1
call this.destroy()
if (index == -1) then
call PauseTimer(thistype.timer)
endif
endif
set i = i + 1
endloop
else
local timer t = GetExpiredTimer()
static if LIBRARY.TimerUtils then
local $HANDLE$Timed this = GetTimerData(t)
call ReleaseTimer(t)
call this.destroy()
else
local $HANDLE$Timed this = LoadInteger(table, 0, GetHandleId(t))
call DestroyTimer(t)
set t = null
call this.destroy()
endif
endif
endmethod
static method create takes $HANDLE$ h, real timeout returns $HANDLE$Timed
local $HANDLE$Timed this = $HANDLE$Timed.allocate()
static if SINGLE_TIMER then
set index = index + 1
set instance[index] = this
if (index == 0) then
call TimerStart(thistype.timer, UPDATE_PERIOD, true, function thistype.remove)
endif
set this.duration = timeout
else
static if LIBRARY.TimerUtils then
call TimerStart(NewTimerEx(this), timeout, false, function $HANDLE$timed.remove)
else
local timer t = CreateTimer()
call SaveInteger(thistype.table, 0, GetHandleId(t), this)
call TimerStart(t, timeout, false, function $HANDLE$Timed.remove)
set t = null
endif
endif
set this.$HANDLE$_var = h
return this
endmethod
endstruct
function $DESTROY$Timed takes $HANDLE$ h, real duration returns $HANDLE$Timed
return $HANDLE$Timed.create(h, duration)
endfunction
//! endtextmacro
endlibrary
library MouseUtils
static if not USE_MEMORY_HACK then
/*
-------------------
MouseUtils
- MyPad
1.0.2.0
-------------------
----------------------------------------------------------------------------
A simple snippet that allows one to
conveniently use the mouse natives
as they were meant to be...
-------------------
| API |
-------------------
struct UserMouse extends array
static method operator [] (player p) -> thistype
- Returns the player's id + 1
static method getCurEventType() -> integer
- Returns the custom event that got executed.
method operator player -> player
- Returns Player(this - 1)
readonly real mouseX
readonly real mouseY
- Returns the current mouse coordinates.
readonly method operator isMouseClicked -> boolean
- Determines whether any mouse key has been clicked,
and will return true on the first mouse key.
method isMouseButtonClicked(mousebuttontype mouseButton)
- Returns true if the mouse button hasn't been
released yet.
static method registerCode(code c, integer ev) -> triggercondition
- Lets code run upon the execution of a certain event.
- Returns a triggercondition that can be removed later.
static method unregisterCallback(triggercondition trgHndl, integer ev)
- Removes a generated triggercondition from the trigger.
functions:
GetPlayerMouseX(player p) -> real
GetPlayerMouseY(player p) -> real
- Returns the coordinates of the mouse of the player.
OnMouseEvent(code func, integer eventId) -> triggercondition
- See UserMouse.registerCode
GetMouseEventType() -> integer
- See UserMouse.getCurEventType
UnregisterMouseCallback(triggercondition t, integer eventId)
- See UserMouse.unregisterCallback
-------------------
| Credits |
-------------------
- Pyrogasm for pointing out a comparison logic flaw
in operator isMouseClicked.
- Illidan(Evil)X for the useful enum handles that
grant more functionality to this snippet.
- TriggerHappy for the suggestion to include
associated events and callbacks to this snippet.
----------------------------------------------------------------------------
*/
// Arbitrary constants
globals
constant integer EVENT_MOUSE_UP = 1024
constant integer EVENT_MOUSE_DOWN = 2048
constant integer EVENT_MOUSE_MOVE = 3072
endglobals
private module Init
private static method onInit takes nothing returns nothing
call thistype.init()
endmethod
endmodule
struct UserMouse extends array
// Determines the minimum interval that a mouse move event detector
// will be deactivated. (Globally-based)
// You can configure it to any amount you like.
private static constant real INTERVAL = 0.03125
// Determines how many times a mouse move event detector can fire
// before being deactivated. (locally-based)
// You can configure this to any integer value. (Preferably positive)
private static constant integer MOUSE_COUNT_MAX = 16
private static integer currentEventType = 0
private static integer updateCount = 0
private static timer resetTimer = null
private static trigger stateDetector = null
private static trigger array evTrigger
private static integer array mouseButtonStack
private integer mouseEventCount
private thistype next
private thistype prev
private thistype resetNext
private thistype resetPrev
private trigger posDetector
private integer mouseClickCount
readonly real mouseX
readonly real mouseY
// Converts the enum type mousebuttontype into an integer
private static method toIndex takes mousebuttontype mouseButton returns integer
return GetHandleId(mouseButton)
endmethod
static method getCurEventType takes nothing returns integer
return currentEventType
endmethod
static method operator [] takes player p returns thistype
if thistype(GetPlayerId(p) + 1).posDetector != null then
return GetPlayerId(p) + 1
endif
return 0
endmethod
method operator player takes nothing returns player
return Player(this - 1)
endmethod
method operator isMouseClicked takes nothing returns boolean
return .mouseClickCount > 0
endmethod
method isMouseButtonClicked takes mousebuttontype mouseButton returns boolean
return UserMouse.mouseButtonStack[(this - 1)*3 + UserMouse.toIndex(mouseButton)] > 0
endmethod
private static method onMouseUpdateListener takes nothing returns nothing
local thistype this = thistype(0).resetNext
set updateCount = 0
loop
exitwhen this == 0
set updateCount = updateCount + 1
set this.mouseEventCount = 0
call EnableTrigger(this.posDetector)
set this.resetNext.resetPrev = this.resetPrev
set this.resetPrev.resetNext = this.resetNext
set this = this.resetNext
endloop
if updateCount <= 0 then
call PauseTimer(resetTimer)
endif
endmethod
private static method onMouseUpOrDown takes nothing returns nothing
local thistype this = thistype[GetTriggerPlayer()]
local integer index = (this - 1)*3 + UserMouse.toIndex(BlzGetTriggerPlayerMouseButton())
if GetTriggerEventId() == EVENT_PLAYER_MOUSE_DOWN then
set this.mouseClickCount = this.mouseClickCount + 1
set UserMouse.mouseButtonStack[index] = UserMouse.mouseButtonStack[index] + 1
set currentEventType = EVENT_MOUSE_DOWN
call TriggerEvaluate(evTrigger[EVENT_MOUSE_DOWN])
else
set this.mouseClickCount = IMaxBJ(this.mouseClickCount - 1, 0)
set UserMouse.mouseButtonStack[index] = IMaxBJ(UserMouse.mouseButtonStack[index] - 1, 0)
set currentEventType = EVENT_MOUSE_UP
call TriggerEvaluate(evTrigger[EVENT_MOUSE_UP])
endif
endmethod
private static method onMouseMove takes nothing returns nothing
local thistype this = thistype[GetTriggerPlayer()]
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
if x != 0 or y != 0 then
set this.mouseX = x
set this.mouseY = y
endif
set this.mouseEventCount = this.mouseEventCount + 1
set currentEventType = EVENT_MOUSE_MOVE
call TriggerEvaluate(evTrigger[EVENT_MOUSE_MOVE])
if this.mouseEventCount >= thistype.MOUSE_COUNT_MAX then
call DisableTrigger(this.posDetector)
if thistype(0).resetNext == 0 then
call TimerStart(resetTimer, INTERVAL, true, function thistype.onMouseUpdateListener)
endif
set this.resetNext = 0
set this.resetPrev = this.resetNext.resetPrev
set this.resetPrev.resetNext = this
set this.resetNext.resetPrev = this
endif
endmethod
private static method init takes nothing returns nothing
local thistype this = 1
local player p = this.player
set resetTimer = CreateTimer()
set stateDetector = CreateTrigger()
set evTrigger[EVENT_MOUSE_UP] = CreateTrigger()
set evTrigger[EVENT_MOUSE_DOWN] = CreateTrigger()
set evTrigger[EVENT_MOUSE_MOVE] = CreateTrigger()
call TriggerAddCondition( stateDetector, Condition(function thistype.onMouseUpOrDown))
loop
exitwhen integer(this) > bj_MAX_PLAYER_SLOTS
if GetPlayerController(p) == MAP_CONTROL_USER and GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
set this.next = 0
set this.prev = thistype(0).prev
set thistype(0).prev.next = this
set thistype(0).prev = this
set this.posDetector = CreateTrigger()
call TriggerRegisterPlayerEvent( this.posDetector, p, EVENT_PLAYER_MOUSE_MOVE )
call TriggerAddCondition( this.posDetector, Condition(function thistype.onMouseMove))
call TriggerRegisterPlayerEvent( stateDetector, p, EVENT_PLAYER_MOUSE_UP )
call TriggerRegisterPlayerEvent( stateDetector, p, EVENT_PLAYER_MOUSE_DOWN )
endif
set this = this + 1
set p = this.player
endloop
endmethod
static method registerCode takes code handlerFunc, integer eventId returns triggercondition
return TriggerAddCondition(evTrigger[eventId], Condition(handlerFunc))
endmethod
static method unregisterCallback takes triggercondition whichHandler, integer eventId returns nothing
call TriggerRemoveCondition(evTrigger[eventId], whichHandler)
endmethod
implement Init
endstruct
function GetPlayerMouseX takes player p returns real
return UserMouse[p].mouseX
endfunction
function GetPlayerMouseY takes player p returns real
return UserMouse[p].mouseY
endfunction
function OnMouseEvent takes code func, integer eventId returns triggercondition
return UserMouse.registerCode(func, eventId)
endfunction
function GetMouseEventType takes nothing returns integer
return UserMouse.getCurEventType()
endfunction
function UnregisterMouseCallback takes triggercondition whichHandler, integer eventId returns nothing
call UserMouse.unregisterCallback(whichHandler, eventId)
endfunction
endif
endlibrary
library Regeneration uses TimerUtils, UnitIndexer
globals
private constant real REGENERATION_RATE = 0.2
endglobals
/*
Regeneration v1.0
by: Quilnez
Allows you to apply hp and mp regeneration on units.
Requires:
- UnitIndexer by Nestharus | hiveworkshop.com/forums/spells-569/unit-indexer-v5-3-0-1-a-260859/
- TimerUtils by Vexorian | wc3c.net/showthread.php?t=101322
API
struct Regeneration
1. Apply/add regeneration to a unit
static method apply takes unit whichUnit, boolean hp, real regenVal returns Regeneration
static method add takes unit whichUnit, boolean hp, real regenVal returns Regeneration
- boolean hp => false to apply to mp regeneration
- real regenVal => regenerated hp/hp per second
2. Get unit regeneration rate (per second)
static method get takes unit whichUnit, boolean hp returns real
3. Stop any regeneration on a unit
static method stop takes unit whichUnit returns nothing
4. Set/get unit regenerations (per second)
method operator hpRegen= takes real regenVal returns nothing
method operator mpRegen= takes real regenVal returns nothing
method operator hpRegen takes nothing returns real
method operator mpRegen takes nothing returns real
function SetUnitHPRegeneration takes unit whichUnit, real regenVal returns Regeneration
function SetUnitMPRegeneration takes unit whichUnit, real regenVal returns Regeneration
function AddUnitHPRegeneration takes unit whichUnit, real regenVal returns Regeneration
function AddUnitMPRegeneration takes unit whichUnit, real regenVal returns Regeneration
function GetUnitHPRegeneration takes unit whichUnit returns real
function GetUnitMPRegeneration takes unit whichUnit returns real
*/
native UnitAlive takes unit id returns boolean
struct Regeneration
private unit target
private Combatant combat
private timer time
private real hpInc
private real mpInc
private static thistype array Index
method destroy takes nothing returns nothing
set Index[GetUnitUserData(target)] = 0
call ReleaseTimer(time)
call deallocate()
set target = null
set time = null
endmethod
method operator hpRegen= takes real regenVal returns nothing
set hpInc = REGENERATION_RATE/1.*regenVal
endmethod
method operator mpRegen= takes real regenVal returns nothing
set mpInc = REGENERATION_RATE/1.*regenVal
endmethod
method operator hpRegen takes nothing returns real
return 1./REGENERATION_RATE*hpInc
endmethod
method operator mpRegen takes nothing returns real
return 1./REGENERATION_RATE*mpInc
endmethod
private static method onPeriodic takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
if IsUnitAlive(target) then
//set hpRegen = combat.hpRegen
//set mpRegen = combat.spRegen
if combat.hp < combat.hpMax then
set combat.hp = combat.hp + .hpInc
if combat.hp > combat.hpMax then
set combat.hp = combat.hpMax
endif
endif
if combat.sp < combat.spMax then
set combat.sp = combat.sp + .mpInc
if combat.sp > combat.spMax then
set combat.sp = combat.spMax
endif
endif
endif
endmethod
static method stop takes unit whichUnit returns nothing
call Index[GetUnitUserData(whichUnit)].destroy()
endmethod
static method get takes unit whichUnit, boolean hp returns real
if hp then
return Index[GetUnitUserData(whichUnit)].hpRegen
else
return Index[GetUnitUserData(whichUnit)].mpRegen
endif
endmethod
static method add takes unit whichUnit, boolean hp, real regenVal returns thistype
return apply(whichUnit, hp, get(whichUnit, hp)+regenVal)
endmethod
static method apply takes unit whichUnit, boolean hp, real regenVal returns thistype
local thistype this = Index[GetUnitUserData(whichUnit)]
if this == 0 then
set this = allocate()
set Index[GetUnitUserData(whichUnit)] = this
set target = whichUnit
set combat = Combatant[whichUnit]
set time = NewTimerEx(this)
call TimerStart(time, REGENERATION_RATE, true, function thistype.onPeriodic)
endif
if hp then
set hpRegen = regenVal
else
set mpRegen = regenVal
endif
return this
endmethod
private static method onDeindex takes nothing returns boolean
local thistype this = Index[GetUnitUserData(GetIndexedUnit())]
if this != 0 then
call destroy()
endif
return false
endmethod
private static method onInit takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function thistype.onDeindex), UnitIndexer.DEINDEX)
endmethod
endstruct
function SetUnitHPRegeneration takes unit whichUnit, real regenVal returns Regeneration
return Regeneration.apply(whichUnit, true, regenVal)
endfunction
function SetUnitMPRegeneration takes unit whichUnit, real regenVal returns Regeneration
return Regeneration.apply(whichUnit, false, regenVal)
endfunction
function AddUnitHPRegeneration takes unit whichUnit, real regenVal returns Regeneration
return Regeneration.add(whichUnit, true, regenVal)
endfunction
function AddUnitMPRegeneration takes unit whichUnit, real regenVal returns Regeneration
return Regeneration.add(whichUnit, false, regenVal)
endfunction
function GetUnitHPRegeneration takes unit whichUnit returns real
return Regeneration.get(whichUnit, true)
endfunction
function GetUnitMPRegeneration takes unit whichUnit returns real
return Regeneration.get(whichUnit, false)
endfunction
endlibrary
library DestructableHider initializer init
/*
by Zwiebelchen v1.3
Destructables create an enormous amount of overhead on warcraft III maps, almost the same as units, especially walkable destructables.
Thus, a large amount of destructables creates a huge drop of FPS in the game, even on fast machines, due to the poor engine of WC3.
This effect is fairly noticable at an amount of even less than 1000 destructables, which is reached very fast when using invisible platforms.
Warcraft III automaticly hides units outside the screen to save performance, however it does not do so for destructables, for unknown reasons.
The purpose of this fully automatic system is to hide all those destructables, that are currently not viewed anyway, to save a lot of processing time.
To do that, the entire map is splitted into tiles of an editable size and all destructables within those tiles are stored into a table, to allow fast access.
When a tile is viewed, all destructables on adjacent tiles will also be shown, so that moving the camera doesnt create ugly popup effects when the center of the view is on the edge of a tile.
However, there are some rules you need to consider, in order to make your map work without desyncs in multiplayer:
- never hide destructables units or players can interact with (attackable, selectable or destructable)
- hiding destructables that block pathing is safe, as hiding the destructable will not change its pathing
- hiding destructables that need to be enumed is safe; hidden destructables can be enumerated
- hiding walkable platforms is also safe, as long as you dont get a location Z for a location placed on that destructable globally; this is not 100% safe anyway, as
the returned value of GetLocationZ() is dependant on the render state of the destructable
API:
private function filt returns boolean
- add custom filter code for the automatic enumeration of destructables on map init inside
- if all destructables should be added to the system, let it return true
- example:
private function filt returns boolean
return GetDestructableMaxLife(GetFilterDestructable()) == 1
endfunction
-> automaticly adds all destructables on the map with a maximum life of 1 on map init to the system
Optional:
public function register takes destructable returns nothing
- adds a destructable to the system, also hides/shows the destructable depending on the position of the camera
public function unregister takes destructable returns nothing
- removes a destructable from the system, also unhides the destructable in case it was hidden
*/
globals
private constant boolean ENABLED = false
//==== CONFIGURABLES ====
private constant real INTERVAL = 0.5 //Update interval in seconds.
//[in multiplayer, the camera positions will only get updated every 0.05-0.1 seconds, so setting it to a lower value than 0.05 makes no sense]
//[update frequency can be much higher in single player mode!]
private constant integer DRAW_DISTANCE = 2048 //the radius around the camera target in which the tiles are considered visible; should be about the same as sight radius (not diameter) of the camera; for 3d cams, use the FarZ value
//Use multiples of 1024 for maximum efficiency on square division. Recommended value: 5120
private constant integer TILE_RESOLUTION = 15 //amount of tiles spread over DRAW_DISTANCE
//- higher resolution = more overhead to incrementing loop variables, but less amounts of destructables checked when moving the camera
//- lower resolution = less overhead to incrementing loop variables, but higher amounts of destructables checked when moving the camera
//-> Recommended value: 8-12
//==== END OF CONFIGURABLES ====
private hashtable hash = InitHashtable()
private integer columns = 0
private integer rows = 0
private integer lastrow = 0
private integer lastcolumn = 0
private integer lastid = 0
private real mapMinX = 0
private real mapMinY = 0
private constant integer TILESIZE = DRAW_DISTANCE/TILE_RESOLUTION
endglobals
private function filt takes nothing returns boolean
local integer id = GetDestructableTypeId(GetFilterDestructable())
//Add code for the enum filter of the automatic registration of destructables on map init
//example:
//return GetDestructableMaxLife(GetFilterDestructable()) == 1
//-> automaticly adds all destructables on the map with a maximum life of 1 on map init to the system
return id != 'B00J' and id != 'B035'
endfunction
public function register takes destructable d returns nothing
static if ENABLED then
local integer id = R2I((GetDestructableY(d)-mapMinY)/TILESIZE)*columns + R2I((GetDestructableX(d)-mapMinX)/TILESIZE)
local integer count = LoadInteger(hash, id, 0)+1
call SaveInteger(hash, id, 0, count)
call SaveDestructableHandle(hash, id, count, d)
call ShowDestructable(d, LoadBoolean(hash, id, -1)) //match visibility state
call SaveInteger(hash, GetHandleId(d), 0, count) //store the list position for fast lookup
endif
endfunction
public function unregister takes destructable d returns nothing
static if ENABLED then
local integer id = R2I((GetDestructableY(d)-mapMinY)/TILESIZE)*columns + R2I((GetDestructableX(d)-mapMinX)/TILESIZE)
local integer count = LoadInteger(hash, id, 0)
local integer a = LoadInteger(hash, GetHandleId(d), 0)
local destructable temp
if a < count then //move the last in list up to this slot
set temp = LoadDestructableHandle(hash, id, count)
call SaveDestructableHandle(hash, id, a, temp)
call SaveInteger(hash, GetHandleId(temp), 0, a) //update list position
set temp = null
endif
call RemoveSavedHandle(hash, id, count) //clean up the deserted slot
call SaveInteger(hash, id, 0, count-1)
call FlushChildHashtable(hash, GetHandleId(d)) //clean up list position
call ShowDestructable(d, true) //make sure its shown again in case it was hidden
endif
endfunction
private function autoregister takes nothing returns nothing
static if ENABLED then
local destructable d = GetEnumDestructable()
local integer id = R2I((GetDestructableY(d)-mapMinY)/TILESIZE)*columns + R2I((GetDestructableX(d)-mapMinX)/TILESIZE)
local integer count = LoadInteger(hash, id, 0)+1
call SaveInteger(hash, id, 0, count)
call SaveDestructableHandle(hash, id, count, d)
call ShowDestructable(d, false) //initially hide everything
call SaveInteger(hash, GetHandleId(d), 0, count) //store the list position for fast lookup
set d = null
endif
endfunction
private function EnumGrid takes integer x1, integer x2, integer y1, integer y2, boolean show returns nothing
local integer a = x1
local integer b
local integer j
local integer id
local integer count
loop
set b = y1
exitwhen a > x2
loop
exitwhen b > y2
set id = b*columns+a
call SaveBoolean(hash, id, -1, show)
set count = LoadInteger(hash, id, 0)
set j = 0
loop
exitwhen j >= count
set j = j + 1
call ShowDestructable(LoadDestructableHandle(hash, id, j), show)
endloop
set b = b + 1
endloop
set a = a + 1
endloop
endfunction
private function ChangeTiles takes integer r, integer c, integer lr, integer lc returns nothing
local integer AminX = c-TILE_RESOLUTION
local integer AmaxX = c+TILE_RESOLUTION
local integer AminY = r-TILE_RESOLUTION
local integer AmaxY = r+TILE_RESOLUTION
local integer BminX = lc-TILE_RESOLUTION
local integer BmaxX = lc+TILE_RESOLUTION
local integer BminY = lr-TILE_RESOLUTION
local integer BmaxY = lr+TILE_RESOLUTION
//border safety:
if AminX < 0 then
set AminX = 0
endif
if AminY < 0 then
set AminY = 0
endif
if BminX < 0 then
set BminX = 0
endif
if BminY < 0 then
set BminY = 0
endif
if AmaxX >= columns then
set AmaxX = columns-1
endif
if AmaxY >= rows then
set AmaxX = rows-1
endif
if BmaxX >= columns then
set BmaxX = columns-1
endif
if BmaxY >= rows then
set BmaxX = rows-1
endif
if BmaxX < AminX or AmaxX < BminX or BmaxY < AminY or AmaxY < BminY then
call EnumGrid(AminX, AmaxX, AminY, AmaxY, true)
call EnumGrid(BminX, BmaxX, BminY, BmaxY, false)
else
if c >= lc then
if c != lc then
call EnumGrid(BmaxX+1, AmaxX, AminY, AmaxY, true)
call EnumGrid(BminX, AminX-1, BminY, BmaxY, false)
endif
if AminY < BminY then
call EnumGrid(AminX, BmaxX, AmaxY+1, BmaxY, false)
call EnumGrid(AminX, BmaxX, AminY, BminY-1, true)
elseif BminY < AminY then
call EnumGrid(AminX, BmaxX, BmaxY+1, AmaxY, true)
call EnumGrid(AminX, BmaxX, BminY, AminY-1, false)
endif
else
call EnumGrid(AminX, BminX-1, AminY, AmaxY, true)
call EnumGrid(AmaxX+1, BmaxX, BminY, BmaxY, false)
if AminY < BminY then
call EnumGrid(BminX, AmaxX, AminY, BminY-1, true)
call EnumGrid(BminX, AmaxX, AmaxY+1, BmaxY, false)
elseif BminY < AminY then
call EnumGrid(BminX, AmaxX, BminY, AminY-1, false)
call EnumGrid(BminX, AmaxX, BmaxY+1, AmaxY, true)
endif
endif
endif
endfunction
private function periodic takes nothing returns nothing
local integer row = R2I((GetCameraTargetPositionY()-mapMinY)/TILESIZE)
local integer column = R2I((GetCameraTargetPositionX()-mapMinX)/TILESIZE)
local integer id = row*columns + column
if id == lastid then //only check for tiles if the camera has left the last tile
return
endif
call ChangeTiles(row, column, lastrow, lastcolumn)
set lastrow = row
set lastcolumn = column
set lastid = id
endfunction
private function init takes nothing returns nothing
static if ENABLED then
set mapMinX = GetRectMinX(bj_mapInitialPlayableArea)
set mapMinY = GetRectMinY(bj_mapInitialPlayableArea)
set lastrow = R2I((GetCameraTargetPositionY()-mapMinY)/TILESIZE)
set lastcolumn = R2I((GetCameraTargetPositionX()-mapMinX)/TILESIZE)
set rows = R2I((GetRectMaxY(bj_mapInitialPlayableArea)-mapMinY)/TILESIZE)+1
set columns = R2I((GetRectMaxX(bj_mapInitialPlayableArea)-mapMinX)/TILESIZE)+1
if lastcolumn <= columns/2 then //to make sure the game starts with a full make-visible enum of all destructables on screen
set lastcolumn = columns-1
else
set lastcolumn = 0
endif
if lastrow <= rows/2 then
set lastrow = rows-1
else
set lastrow = 0
endif
set lastid = lastrow*columns + lastcolumn
call EnumDestructablesInRect(bj_mapInitialPlayableArea, Filter(function filt), function autoregister)
call TimerStart(CreateTimer(), INTERVAL, true, function periodic)
call periodic() //to make sure the destructables on screen after the map loading process finishes are initially shown
endif
endfunction
endlibrary
//===========================================================================
//
// Screen Mouse v1.0.2
// by loktar
// -------------------------------------------------------------------------
// * Track mouse movement relative to screen
// * Note that map coordinates go from east to west (X) and south to north (Y)
// -------------------------------------------------------------------------
//
// -------
// * API *
// -------
// * boolean ScreenMouseRegisterPlayer(trigger buttonTrigger, trigger moveTrigger, player plr, boolean left, boolean right, boolean both)
// - Register mouse button and mouse move events
// - Register for left button, right button and/or both together
// - Disables moveTrigger
// - Returns false if trigger(s) are already registered, otherwise returns true
//
// * boolean SMIsLeftDown(integer playerNumber), SMIsRightDown(integer playerNumber)
// - Mouse button state for player
//
// * real SMGetDifX(integer playerNumber), SMGetDifY(integer playerNumber)
// - Difference with previous mouse position for player
// - Changes each time EVENT_PLAYER_MOUSE_MOVE is fired
//
// * real SMGetDifXs(integer playerNumber), SMGetDifYs(integer playerNumber)
// - Same as difX/difY, but only compensates for Target Distance and Field of View
//
// * real SM_distMpl
// - Multiplier for Target Distance compensation
// - Only applied if larger than current Target Distance
// - Difference/Distance*SM_distMpl
// - Default: 800
//
// * real SM_fovMpl
// - Multiplier for Field of View compensation (in Radians!)
// - Only applied if larger than current Field of View
// - Difference/FoV*SM_fovMpl
// - Default: Deg2Rad(70)
//
// * real SM_minX, SM_maxX, SM_minY, SM_maxY
// - Mouse position bounds
// - Default: Camera Bounds
//
//===========================================================================
library ScreenMouse initializer InitScreenMouse
static if not USE_MEMORY_HACK then
globals
private constant real R90 = Deg2Rad(90)
private hashtable htbTriggers = InitHashtable()
private constant key X
private constant key Y
private constant key DIFX
private constant key DIFY
private constant key DIFX_S
private constant key DIFY_S
private constant key LEFT_DOWN
private constant key RIGHT_DOWN
private constant key DO_LEFT
private constant key DO_RIGHT
private constant key DO_BOTH
real SM_minX // GetCameraBound cannot be called at init
real SM_maxX
real SM_minY
real SM_maxY
real SM_distMpl = 800
real SM_fovMpl = Deg2Rad(70)
endglobals
//===============================================================================
//===============================================================================
//===============================================================================
//==== MOUSE FUNCS ==============================================================
//===============================================================================
//==== Mouse Move ====
private function MouseMoveCndAcn takes nothing returns boolean
local real newX
local real newY
local real realTmp
local real realTmp2
local trigger trg = GetTriggeringTrigger()
local integer pId = LoadInteger(htbTriggers, GetHandleId(trg), 0)
//call BJDebugMsg("update")
call DisableTrigger(trg)
//if LoadBoolean(htbTriggers, pId, LEFT_DOWN) or LoadBoolean(htbTriggers, pId, RIGHT_DOWN) then
set newX = BlzGetTriggerPlayerMouseX()
set newY = BlzGetTriggerPlayerMouseY()
//if (newX != 0 or newY != 0) and newX >= SM_minX and newX <= SM_maxX and newY >= SM_minY and newY <= SM_maxY then // Mouse on UI gives (0, 0)
set realTmp = LoadReal(htbTriggers, pId, X)-newX
set realTmp2 = LoadReal(htbTriggers, pId, Y)-newY
call SaveReal(htbTriggers, pId, X, newX)
call SaveReal(htbTriggers, pId, Y, newY)
set newX = realTmp
set newY = realTmp2
// Compensate Distance
set realTmp = GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)
if realTmp > SM_distMpl then
set newX = newX/realTmp*SM_distMpl
set newY = newY/realTmp*SM_distMpl
endif
// Compensate FoV
set realTmp = GetCameraField(CAMERA_FIELD_FIELD_OF_VIEW)
if realTmp > SM_fovMpl then
set newX = newX/realTmp*SM_fovMpl
set newY = newY/realTmp*SM_fovMpl
endif
call SaveReal(htbTriggers, pId, DIFX_S, newX)
call SaveReal(htbTriggers, pId, DIFY_S, newY)
// Compensate Rotation
set realTmp = GetCameraField(CAMERA_FIELD_ROTATION)
set realTmp2 = newX // Save original newX for newY calculation
set newX = Cos(realTmp-R90)*(newX) + Sin(realTmp-R90)*(newY)
set newY = Cos(realTmp+R90)*(-newY) - Sin(realTmp+R90)*(-realTmp2)
// Compensate Roll
set realTmp = GetCameraField(CAMERA_FIELD_ROLL)
set realTmp2 = newX // Save original newX for newY calculation
set newX = Sin(realTmp-R90)*(-newX) + Cos(realTmp-R90)*(-newY)
set newY = Sin(realTmp+R90)*(newY) - Cos(realTmp+R90)*(realTmp2)
// Compensate AoA
set newY = Sin(-GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK))*newY
call SaveReal(htbTriggers, pId, DIFX, newX)
call SaveReal(htbTriggers, pId, DIFY, newY)
//endif
call EnableTrigger(trg)
//endif
set trg = null
return true
endfunction
//========
//==== Mouse Button ====
private function MouseBtnCndAcn takes nothing returns boolean
local mousebuttontype mouseBtn = BlzGetTriggerPlayerMouseButton()
local integer pId = GetHandleId(GetTriggeringTrigger())
local trigger moveTrg = LoadTriggerHandle(htbTriggers, pId, 1)
local boolean enable
set pId = LoadInteger(htbTriggers, pId, 0)
if GetTriggerEventId() == EVENT_PLAYER_MOUSE_DOWN then
// MOUSE_BUTTON_TYPE_MIDDLE does not fire this event as of 1.30.4
if mouseBtn == MOUSE_BUTTON_TYPE_LEFT then
call SaveBoolean(htbTriggers, pId, LEFT_DOWN, true)
elseif mouseBtn == MOUSE_BUTTON_TYPE_RIGHT then
call SaveBoolean(htbTriggers, pId, RIGHT_DOWN, true)
endif
elseif mouseBtn == MOUSE_BUTTON_TYPE_LEFT then
call SaveBoolean(htbTriggers, pId, LEFT_DOWN, false)
elseif mouseBtn == MOUSE_BUTTON_TYPE_RIGHT then
call SaveBoolean(htbTriggers, pId, RIGHT_DOWN, false)
endif
set enable = LoadBoolean(htbTriggers, pId, RIGHT_DOWN)
if LoadBoolean(htbTriggers, pId, LEFT_DOWN) then
set enable = (enable and LoadBoolean(htbTriggers, pId, DO_BOTH)) or (not enable and LoadBoolean(htbTriggers, pId, DO_LEFT))
else
set enable = enable and LoadBoolean(htbTriggers, pId, DO_RIGHT)
endif
if enable then
if not IsTriggerEnabled(moveTrg) then
call SaveReal(htbTriggers, pId, X, BlzGetTriggerPlayerMouseX())
call SaveReal(htbTriggers, pId, Y, BlzGetTriggerPlayerMouseY())
//call EnableTrigger(moveTrg)
endif
else
//call DisableTrigger(moveTrg)
endif
set moveTrg = null
return true
endfunction
//===========================================================================
//===========================================================================
//===============================================================================
//===============================================================================
//===============================================================================
//==== API FUNCS ================================================================
//===============================================================================
//==== Register events to trigger/player ====
function ScreenMouseRegisterPlayer takes trigger btnTrg, trigger moveTrg, player plr, boolean left, boolean right, boolean both returns boolean
local integer hIdBtn = GetHandleId(btnTrg)
local integer hIdMove = GetHandleId(moveTrg)
local integer pId = GetPlayerId(plr)
if HaveSavedInteger(htbTriggers, hIdBtn, 0) or HaveSavedInteger(htbTriggers, hIdMove, 0) then
return false // trigger(s) already registered
else
call SaveInteger(htbTriggers, hIdBtn, 0, pId)
call SaveTriggerHandle(htbTriggers, hIdBtn, 1, moveTrg)
call SaveInteger(htbTriggers, hIdMove, 0, pId)
call SaveBoolean(htbTriggers, pId, LEFT_DOWN, false)
call SaveBoolean(htbTriggers, pId, RIGHT_DOWN, false)
call SaveBoolean(htbTriggers, pId, DO_LEFT, left)
call SaveBoolean(htbTriggers, pId, DO_RIGHT, right)
call SaveBoolean(htbTriggers, pId, DO_BOTH, both)
//call DisableTrigger(moveTrg)
call TriggerRegisterPlayerEvent(moveTrg, plr, EVENT_PLAYER_MOUSE_MOVE)
call TriggerAddCondition(moveTrg, function MouseMoveCndAcn)
call TriggerRegisterPlayerEvent(btnTrg, plr, EVENT_PLAYER_MOUSE_DOWN)
call TriggerRegisterPlayerEvent(btnTrg, plr, EVENT_PLAYER_MOUSE_UP)
call TriggerAddCondition(btnTrg, function MouseBtnCndAcn)
return true
endif
endfunction
//========
//==== Get Left Down ====
function SMIsLeftDown takes integer playerId returns boolean
return LoadBoolean(htbTriggers, playerId, LEFT_DOWN)
endfunction
//========
//==== Get Right Down ====
function SMIsRightDown takes integer playerId returns boolean
return LoadBoolean(htbTriggers, playerId, RIGHT_DOWN)
endfunction
//========
// ==== Get difX ====
function SMGetDifX takes integer playerId returns real
return LoadReal(htbTriggers, playerId, DIFX)
endfunction
//========
// ==== Get difY ====
function SMGetDifY takes integer playerId returns real
return LoadReal(htbTriggers, playerId, DIFY)
endfunction
//========
// ==== Get difXs ====
function SMGetDifXs takes integer playerId returns real
return LoadReal(htbTriggers, playerId, DIFX_S)
endfunction
//========
// ==== Get difYs ====
function SMGetDifYs takes integer playerId returns real
return LoadReal(htbTriggers, playerId, DIFY_S)
endfunction
//===========================================================================
//===========================================================================
//===============================================================================
//===============================================================================
//===============================================================================
//==== INITIALIZER ==============================================================
//===============================================================================
private function InitScreenMouse takes nothing returns nothing
call TriggerSleepAction(0) // For GetCameraBound
// Get map bounds
set SM_minX = GetCameraBoundMinX()
set SM_maxX = GetCameraBoundMaxX()
set SM_minY = GetCameraBoundMinY()
set SM_maxY = GetCameraBoundMaxY()
endfunction
//===============================================================================
//===============================================================================
endif
endlibrary
library UIUtils requires LinkedListModule
/*********************************************************************************
*
* UI Utils v1.05
*
* Create and manage user interface in highly convenient and intuitive way!
*
* Check for update at: https://www.hiveworkshop.com/threads/320005/
*
* Features:
* • Includes several primitive frame types (texture, text, slider, etc.)
* • Compatible with custom frame definition
* • Uses pixel as measurement unit
* • Friendly UI native wrappers
* • Custom hierarchy system with in-depth inheritance control
* • Automatically prevents non-simple frame from going out of the 4:3 bounds
* • Enhanced frame pivot & anchor point feature for all-resolution support
* • Automatic create context handling
* • Extra security measures (prevents UI native related crashes out of the box)
* • Customizable full-screen mode
* • Essential default/original frames container
* • Includes all available built-in fdf files
*
* I. System requirements:
* • LinkedListModule : http://hiveworkshop.com/threads/snippet-linkedlistmodule.206552/
* • Warcraft III version 1.31+
*
* II. Installation:
* • Import LinkedListModule
* • Copy UIUtils trigger to your map
* • Go to Import Manager and import following files to your map:
* - UIUtils.toc
* - UIUtils.fdf
* • Configure the system below
* • For true fullscreen you might need to manually remove the inventory cover texture
*
* III. Credits:
* • Tasyen | UI tutorials & researches
* • Dirac | LinkedListModule
*
* IV. API - (Complete manual: https://www.hiveworkshop.com/threads/320046/)
*
* struct UIFrame */static if FOLD then /*
1. Ctor & dtor
- Let "isSimple" be "true" if it is a simple frame type
| static method create takes boolean isSimple, string frameType, UIFrame parent, real x, real y, integer level returns UIFrame
- Dispose the frame
| method destroy takes nothing returns nothing
2. Wrappers
- Set & get frame's textures
• Might not be compatible with custom frame definition
• Some only work for specific type of primitive frames
• Some might not work properly just yet (blizzard limitation)
> Default main texture
| method operator texture= takes string filePath returns nothing
| method operator texture takes nothing returns string
> Texture displayed when frame is disabled
| method operator disabledTexture= takes string filePath returns nothing
| method operator disabledTexture takes nothing returns string
> Highlighter texture
| method operator highlightTexture= takes string filePath returns nothing
| method operator highlightTexture takes nothing returns string
> Texture displayed when frame is pressed
| method operator pushedTexture= takes string filePath returns nothing
| method operator pushedTexture takes nothing returns string
> Background texture for the frame
| method operator backgroundTexture= takes string filePath returns nothing
| method operator backgroundTexture takes nothing returns string
> Border texture for the frame
| method operator borderTexture= takes string filePath returns nothing
| method operator borderTexture takes nothing returns string
- Set & get frame's parent
| method operator parent= takes UIFrame frame returns nothing
| method operator parent takes nothing returns UIFrame
- Get frame's screen space position
• Values might be affected by frame's parent anchor point
| method operator screenPosX takes nothing returns real
| method operator screenPosY takes nothing returns real
- Get frame's bounds
| method operator left takes nothing returns real
| method operator right takes nothing returns real
| method operator top takes nothing returns real
| method operator bottom takes nothing returns real
- Get frame's true (scaled) size in pixel
| method operator width takes nothing returns real
| method operator height takes nothing returns real
- Set & get frame's scale factor
> Frame's independent scale factor
| method operator localScale= takes real r returns nothing
| method operator localScale takes nothing returns real
> Frame's true scale
| method operator scale takes nothing returns real
- Set & get frame's visibility state
| method operator visible= takes boolean state returns nothing
| method operator visible takes nothing returns boolean
- Set & get frame's transparency (0-255)
| method operator opacity= takes integer amount returns nothing
| method operator opacity takes nothing returns integer
- Set & get enable state of the frame
| method operator enabled= takes boolean state returns nothing
| method operator enabled takes nothing returns boolean
- Set & get frame's self sorting/layering order
| method operator level= takes integer level returns nothing
| method operator level takes nothing returns integer
> Get frame's actual sorting/layering order
| method operator trueLevel takes nothing returns integer
- Set & get frame's text content
| method operator text= takes string str returns nothing
| method operator text takes nothing returns string
- Set & get frame's text content length limit
| method operator maxLength= takes integer length returns nothing
| method operator maxLength takes nothing returns integer
- Set frame's text color
> Use "BlzConvertColor" function to convert ARGB color
| method operator textColor= takes integer color returns nothing
- Set & get frame's model file
| method operator model= takes string filePath returns nothing
| method operator model takes nothing returns string
- Set vertex color of the model frame
> Use "BlzConvertColor" function to convert ARGB color
| method operator vertexColor= takes integer color returns nothing
- Set & get value of slider frame
| method operator value= takes real r returns nothing
| method operator value takes nothing returns real
- Step size is increment of slider bar relative to its min max value
| method operator stepSize= takes real r returns nothing
| method operator stepSize takes nothing returns real
- Set & get tooltips frame
| method operator tooltips= takes UIFrame frame returns nothing
| method operator tooltips takes nothing returns UIFrame
- Get sub-frame handle based on passed name
• Usage: tempFrame.subFrame["tempFrameText"] => returns subframe handle of "tempFrame" by name of "tempFrameText"
| method operator subFrame[] takes string name returns framehandle
- Register any event happen to the frame (click, mouse enter/leave, etc.)
• Use "UIFrame.TriggerComponent" to get the triggering frame
• Use "BlzGetTriggerFrameEvent()" function to get the event type
| method operator onAnyEvent= takes code func returns triggercondition
2. Methods
- Iterates through all child frames of the frame
• Use "UIFrame.EnumChild" to get the iterated child frame
| method forEachChild takes code func returns nothing
- Set frame's text properties
| method setTextAlignment takes textaligntype vertical, textaligntype horizontal returns nothing
| method setFont takes string fontType, real fontSize, integer flags returns nothing
- Set slider min max values
| method setMinMaxValue takes real min, real max returns nothing
- Animate frame texture
| method setSpriteAnimate takes integer primaryProp, integer flags returns nothing
- Give focus to the frame
| method setFocus takes boolean state returns nothing
- Cage mouse inside the frame's boundaries
| method cageMouse takes boolean state returns nothing
- Emulate click on the frame
| method click takes nothing returns nothing
- Force update the frame
| method refresh takes nothing returns nothing
- Modify frame's position
> Set frame's local position
| method move takes real x, real y returns nothing
> Set frame's screen position (ignores parent position)
| method moveEx takes real x, real y returns nothing
> Set frame position relative to other specified frame
| method relate takes UIFrame relative, real x, real y returns nothing
- Set dimension of the frame
| method setSize takes real width, real height returns nothing
- Set frame's anchor & pivot point
| method setPivotPoint takes real x, real y returns nothing
| method setAnchorPoint takes real x, real y returns nothing
3. Members
- Main frame handle
| readonly framehandle frame
- Set & get frame's name
| string name
- Set & get property inheritance
• Frame refresh is recommended after modifying inheritance
| boolean inheritScale
| boolean inheritOpacity
| boolean inheritVisibility
| boolean inheritEnableState
| boolean inheritPosition
| boolean inheritLevel
| boolean scalePosition
- Frame's type name
| readonly string frameType
- Frame's local space position
| readonly real localPosX
| readonly real localPosY
- Frame's anchor & pivot points
| readonly real anchorX
| readonly real anchorY
| readonly real pivotX
| readonly real pivotY
- Frame's unscaled size
| readonly real unscaledWidth
| readonly real unscaledHeight
- Get frame text font properties
| readonly integer fontFlags
| readonly real fontSize
| readonly string fontType
- Slider frame's min max value
| readonly real valueMin
| readonly real valueMax
- Create context index of the frame
| readonly integer context
- Local states of the frame
| readonly boolean visibleSelf
| readonly boolean enabledSelf
- Is the frame a simple frame type or not
| readonly boolean isSimple
- Local transparency of the frame
| readonly integer localOpacity
4. Static Members
- Representation for null frame
| readonly static UIFrame Null
- Currently iterated frame of "forEachChild" method
| readonly static UIFrame EnumChild
- Triggerer of the "onAnyEvent"
| readonly static UIFrame TriggerComponent
- Primitive frame names
| readonly static string TYPE_TEXT
| readonly static string TYPE_SIMPLE_TEXT
| readonly static string TYPE_TEXTURE
| readonly static string TYPE_SIMPLE_TEXTURE
| readonly static string TYPE_BUTTON
| readonly static string TYPE_SIMPLE_BUTTON
| readonly static string TYPE_BAR
| readonly static string TYPE_H_SLIDER
| readonly static string TYPE_V_SLIDER
*/
endif
/* struct UIUtils */static if FOLD then /*
1. Static Methods
- Calculate aspect ratio height
| static method CalcAspectRatio takes real w, real h, real aspectWidth returns integer
- Convert pixel unit to DPI and vice versa
• Usage: [value]*UIUtils.PXTODPI
[value]*UIUtils.DPITOPX
| static method operator PXTODPI takes nothing returns real
| static method operator DPITOPX takes nothing returns real
- Width of the 4:3 bound
| static method operator FrameBoundWidth takes nothing returns real
- Convert from pixel to screen x/y coordinate (in DPI unit)
| static method GetScreenPosX takes real x returns real
| static method GetScreenPosY takes real y returns real
- Force update default frames
| static method RefreshDefaultFrames takes nothing returns nothing
- Force update resolution
| static method RefreshResolution takes nothing returns nothing
- Resolution change event
| static method RegisterOnResolutionChangeEvent takes code func returns triggercondition
| static method RemoveOnResolutionChangeEvent takes triggercondition cond returns nothing
2. Static Members
- Updated after resolution change event
• Values might be async between clients
| readonly static integer ResolutionWidth
| readonly static integer ResolutionHeight
| readonly static integer AspectWidth
| readonly static integer AspectHeight
*/
endif
/* struct DefaultFrame (singleton) */static if FOLD then /*
- Origin frames
| readonly static framehandle Game
| readonly static framehandle World
| readonly static framehandle HeroBar
| readonly static framehandle array HeroButton [0 - 6]
| readonly static framehandle array HeroHPBar [0 - 6]
| readonly static framehandle array HeroMPBar [0 - 6]
| readonly static framehandle array HeroIndicator [0 - 6]
| readonly static framehandle array ItemButton [0 - 5]
| readonly static framehandle array CommandButton [0 - 11]
| readonly static framehandle array SystemButton [0 - 3]
| readonly static framehandle Portrait
| readonly static framehandle Minimap
| readonly static framehandle array MinimapButton [0 - 4]
| readonly static framehandle Tooltip
| readonly static framehandle UberTooltip
| readonly static framehandle ChatMsg
| readonly static framehandle UnitMsg
| readonly static framehandle TopMsg
- Other frames
| readonly static framehandle Console
| readonly static framehandle GoldText
| readonly static framehandle LumberText
| readonly static framehandle FoodText
| readonly static framehandle UnitNameText
| readonly static framehandle ResourceBar
| readonly static framehandle UpperButtonBar
*/
endif
/*
* V. Configurations
* */globals
// 1. TOC file path
private constant string TOC_FILE = "war3mapimported\\UIUtils.toc"
// 2. Temporary cache name
private constant string CACHE_NAME = "UIUtils.w3v"
// 3. Resolution change detection interval
private constant real RESOLUTION_CHECK_INTERVAL = 0.1
// 4. true : hides console frames on map init (full screen)
private constant boolean HIDE_CONSOLE_FRAME = true
// 5. true : frame's properties will be retained when it changes parent
private constant boolean PERSISTENT_CHILD_PROPERTIES = true
// 6. true : helps to prevent non-simple frame from going beyond the 4:3 bounds
private constant boolean REFRAIN_NON_SIMPLE_FRAME = true
// 7. Reference resolution, as which is used to design the interface
public constant integer RESOLUTION_WIDTH = 1360
public constant integer RESOLUTION_HEIGHT = 768
// 8. Configure in-game message frame
private constant boolean MESSAGE_FRAME_VISIBLE = true
private constant real MESSAGE_FRAME_ANCHOR_X = 0.5
private constant real MESSAGE_FRAME_ANCHOR_Y = 0.5
private constant real MESSAGE_FRAME_PIVOT_X = 0.5
private constant real MESSAGE_FRAME_PIVOT_Y = 0.5
private constant real MESSAGE_FRAME_POS_X = 0.0
private constant real MESSAGE_FRAME_POS_Y = 0.0
// 9. Configure in-game chat frame
private constant boolean CHAT_FRAME_VISIBLE = true
private constant real CHAT_FRAME_ANCHOR_X = 0.0
private constant real CHAT_FRAME_ANCHOR_Y = 0.0
private constant real CHAT_FRAME_PIVOT_X = 0.0
private constant real CHAT_FRAME_PIVOT_Y = 0.0
private constant real CHAT_FRAME_POS_X = 10.0
private constant real CHAT_FRAME_POS_Y = 100.0
// 10. Configure tooltips frame
private constant boolean TOOLTIPS_FRAME_VISIBLE = true
private constant real TOOLTIPS_FRAME_ANCHOR_X = 1.0
private constant real TOOLTIPS_FRAME_ANCHOR_Y = 0.0
private constant real TOOLTIPS_FRAME_PIVOT_X = 1.0
private constant real TOOLTIPS_FRAME_PIVOT_Y = 0.0
private constant real TOOLTIPS_FRAME_POS_X = -50.0
private constant real TOOLTIPS_FRAME_POS_Y = 0.0
// 11. Configure minimap frame
private constant boolean MINIMAP_FRAME_VISIBLE = false
private constant real MINIMAP_FRAME_ANCHOR_X = 1.0
private constant real MINIMAP_FRAME_ANCHOR_Y = 1.0
private constant real MINIMAP_FRAME_PIVOT_X = 1.0
private constant real MINIMAP_FRAME_PIVOT_Y = 1.0
private constant real MINIMAP_FRAME_POS_X = 0.0
private constant real MINIMAP_FRAME_POS_Y = 0.0
// 12. Configure unit portrait frame
private constant boolean PORTRAIT_FRAME_VISIBLE = false
private constant real PORTRAIT_FRAME_ANCHOR_X = 0.0
private constant real PORTRAIT_FRAME_ANCHOR_Y = 0.0
private constant real PORTRAIT_FRAME_PIVOT_X = 0.0
private constant real PORTRAIT_FRAME_PIVOT_Y = 0.0
private constant real PORTRAIT_FRAME_POS_X = 0.0
private constant real PORTRAIT_FRAME_POS_Y = 0.0
// 13. Configure other frame visibility
private constant boolean RESOURCE_FRAME_VISIBLE = false
private constant boolean CMD_BUTTON_FRAME_VISIBLE = false
endglobals
/*
* END OF DOCUMENT ----- Modify following codes on your own risk
*
*********************************************************************************/
private module DefaultFrameInit
private static method onInit takes nothing returns nothing
local integer i
set Game = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)
set World = BlzGetOriginFrame(ORIGIN_FRAME_WORLD_FRAME, 0)
set HeroBar = BlzGetOriginFrame(ORIGIN_FRAME_HERO_BAR, 0)
set Portrait = BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT, 0)
set Minimap = BlzGetOriginFrame(ORIGIN_FRAME_MINIMAP, 0)
set Tooltip = BlzGetOriginFrame(ORIGIN_FRAME_TOOLTIP, 0)
set UberTooltip = BlzGetOriginFrame(ORIGIN_FRAME_UBERTOOLTIP, 0)
set ChatMsg = BlzGetOriginFrame(ORIGIN_FRAME_CHAT_MSG, 0)
set UnitMsg = BlzGetOriginFrame(ORIGIN_FRAME_UNIT_MSG, 0)
set TopMsg = BlzGetOriginFrame(ORIGIN_FRAME_TOP_MSG, 0)
set i = 0
loop
exitwhen i > 11
set HeroButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_HERO_BUTTON, i)
set HeroHPBar[i] = BlzGetOriginFrame(ORIGIN_FRAME_HERO_HP_BAR, i)
set HeroMPBar[i] = BlzGetOriginFrame(ORIGIN_FRAME_HERO_MANA_BAR, i)
set HeroIndicator[i] = BlzGetOriginFrame(ORIGIN_FRAME_HERO_BUTTON_INDICATOR, i)
set ItemButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_ITEM_BUTTON, i)
set CommandButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON, i)
set SystemButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_SYSTEM_BUTTON, i)
set MinimapButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_MINIMAP_BUTTON, i)
set i = i + 1
endloop
set Console = BlzGetFrameByName("ConsoleUI", 0)
set GoldText = BlzGetFrameByName("ResourceBarGoldText", 0)
set LumberText = BlzGetFrameByName("ResourceBarLumberText", 0)
set FoodText = BlzGetFrameByName("ResourceBarSupplyText", 0)
set ResourceBar = BlzGetFrameByName("ResourceBarFrame", 0)
set UnitNameText = BlzGetFrameByName("SimpleNameValue", 0)
set UpperButtonBar = BlzGetFrameByName("UpperButtonBarFrame", 0)
endmethod
endmodule
private module UIUtilsInit
private static method onInit takes nothing returns nothing
local integer i
call RefreshResolution()
static if HIDE_CONSOLE_FRAME then
call BlzEnableUIAutoPosition(false)
call BlzFrameClearAllPoints(DefaultFrame.World)
call BlzFrameClearAllPoints(DefaultFrame.Console)
call BlzFrameSetAllPoints(DefaultFrame.World, DefaultFrame.Game)
call BlzFrameSetAbsPoint(DefaultFrame.Console, FRAMEPOINT_TOPRIGHT, -999.0, -999.0)
call RefreshDefaultFrames()
static if not RESOURCE_FRAME_VISIBLE then
call BlzFrameClearAllPoints(DefaultFrame.GoldText)
call BlzFrameSetAbsPoint(DefaultFrame.GoldText, FRAMEPOINT_BOTTOMLEFT, -999.0, -999.0)
call BlzFrameClearAllPoints(DefaultFrame.LumberText)
call BlzFrameSetAbsPoint(DefaultFrame.LumberText, FRAMEPOINT_BOTTOMLEFT, -999.0, -999.0)
call BlzFrameClearAllPoints(DefaultFrame.FoodText)
call BlzFrameSetAbsPoint(DefaultFrame.FoodText, FRAMEPOINT_BOTTOMLEFT, -999.0, -999.0)
call BlzFrameClearAllPoints(DefaultFrame.ResourceBar)
call BlzFrameSetAbsPoint(DefaultFrame.ResourceBar, FRAMEPOINT_BOTTOMLEFT, -999.0, -999.0)
endif
static if not CMD_BUTTON_FRAME_VISIBLE then
set i = 0
loop
exitwhen DefaultFrame.CommandButton[i] == null
call BlzFrameClearAllPoints(DefaultFrame.CommandButton[i])
call BlzFrameSetAbsPoint(DefaultFrame.CommandButton[i], FRAMEPOINT_BOTTOMLEFT, -999.0, -999.0)
set i = i + 1
endloop
endif
endif
call TimerStart(CreateTimer(), RESOLUTION_CHECK_INTERVAL, true, function thistype.CheckResolution)
endmethod
endmodule
struct DefaultFrame extends array
readonly static framehandle Game = null
readonly static framehandle World = null
readonly static framehandle HeroBar = null
readonly static framehandle array HeroButton
readonly static framehandle array HeroHPBar
readonly static framehandle array HeroMPBar
readonly static framehandle array HeroIndicator
readonly static framehandle array ItemButton
readonly static framehandle array CommandButton
readonly static framehandle array SystemButton
readonly static framehandle Portrait = null
readonly static framehandle Minimap = null
readonly static framehandle array MinimapButton
readonly static framehandle Tooltip = null
readonly static framehandle UberTooltip = null
readonly static framehandle ChatMsg = null
readonly static framehandle UnitMsg = null
readonly static framehandle TopMsg = null
readonly static framehandle Console = null
readonly static framehandle GoldText = null
readonly static framehandle LumberText = null
readonly static framehandle FoodText = null
readonly static framehandle UnitNameText = null
readonly static framehandle ResourceBar = null
readonly static framehandle UpperButtonBar = null
implement DefaultFrameInit
endstruct
private keyword AllComponents
struct UIUtils extends array
readonly static integer ResolutionWidth = RESOLUTION_WIDTH
readonly static integer ResolutionHeight = RESOLUTION_HEIGHT
readonly static real ScaleFactor = 1
private static trigger resolutionChangeTrigg = CreateTrigger()
static method CalcAspectRatio takes real w, real h, real aspectWidth returns integer
return R2I(aspectWidth*h/w+0.5)
endmethod
static method operator PXTODPI takes nothing returns real
return 0.6/ResolutionHeight
endmethod
static method operator DPITOPX takes nothing returns real
return ResolutionHeight/0.6
endmethod
static method operator FrameBoundWidth takes nothing returns real
return (ResolutionWidth-ResolutionHeight/600.*800.)/2.
endmethod
static method GetScreenPosX takes real x returns real
return (-FrameBoundWidth+x)*PXTODPI
endmethod
static method GetScreenPosY takes real y returns real
return y*PXTODPI
endmethod
static method RefreshDefaultFrames takes nothing returns nothing
static if MESSAGE_FRAME_VISIBLE then
call BlzFrameClearAllPoints(DefaultFrame.UnitMsg)
call BlzFrameSetAbsPoint(DefaultFrame.UnitMsg, FRAMEPOINT_BOTTOMLEFT,/*
*/ GetScreenPosX(MESSAGE_FRAME_POS_X+ResolutionWidth*MESSAGE_FRAME_ANCHOR_X-BlzFrameGetWidth(DefaultFrame.UnitMsg)*DPITOPX*MESSAGE_FRAME_PIVOT_X),/*
*/ GetScreenPosY(MESSAGE_FRAME_POS_Y+ResolutionHeight*MESSAGE_FRAME_ANCHOR_Y-BlzFrameGetHeight(DefaultFrame.UnitMsg)*DPITOPX*MESSAGE_FRAME_PIVOT_Y))
endif
static if CHAT_FRAME_VISIBLE then
call BlzFrameSetAbsPoint(DefaultFrame.ChatMsg, FRAMEPOINT_BOTTOMLEFT,/*
*/ GetScreenPosX(CHAT_FRAME_POS_X+ResolutionWidth*CHAT_FRAME_ANCHOR_X-BlzFrameGetWidth(DefaultFrame.ChatMsg)*DPITOPX*CHAT_FRAME_PIVOT_X),/*
*/ GetScreenPosY(CHAT_FRAME_POS_Y+ResolutionHeight*CHAT_FRAME_ANCHOR_Y-BlzFrameGetHeight(DefaultFrame.ChatMsg)*DPITOPX*CHAT_FRAME_PIVOT_Y))
endif
static if TOOLTIPS_FRAME_VISIBLE then
call BlzFrameClearAllPoints(DefaultFrame.UberTooltip)
call BlzFrameSetAbsPoint(DefaultFrame.UberTooltip, FRAMEPOINT_BOTTOMLEFT,/*
*/ GetScreenPosX(TOOLTIPS_FRAME_POS_X+ResolutionWidth*TOOLTIPS_FRAME_ANCHOR_X-BlzFrameGetWidth(DefaultFrame.UberTooltip)*DPITOPX*TOOLTIPS_FRAME_PIVOT_X),/*
*/ GetScreenPosY(TOOLTIPS_FRAME_POS_Y+ResolutionHeight*TOOLTIPS_FRAME_ANCHOR_Y-BlzFrameGetHeight(DefaultFrame.UberTooltip)*DPITOPX*TOOLTIPS_FRAME_PIVOT_Y))
endif
call BlzFrameClearAllPoints(DefaultFrame.Minimap)
static if MINIMAP_FRAME_VISIBLE then
call BlzFrameSetAbsPoint(DefaultFrame.Minimap, FRAMEPOINT_BOTTOMLEFT,/*
*/ GetScreenPosX(MINIMAP_FRAME_POS_X+ResolutionWidth*MINIMAP_FRAME_ANCHOR_X-BlzFrameGetWidth(DefaultFrame.Minimap)*DPITOPX*MINIMAP_FRAME_PIVOT_X),/*
*/ GetScreenPosY(MINIMAP_FRAME_POS_Y+ResolutionHeight*MINIMAP_FRAME_ANCHOR_Y-BlzFrameGetHeight(DefaultFrame.Minimap)*DPITOPX*MINIMAP_FRAME_PIVOT_Y))
else
call BlzFrameSetAbsPoint(DefaultFrame.Minimap, FRAMEPOINT_BOTTOMLEFT, -999.0, -999.0)
call BlzFrameSetSize(DefaultFrame.Minimap, 0.0001, 0.0001)
endif
call BlzFrameClearAllPoints(DefaultFrame.Portrait)
static if PORTRAIT_FRAME_VISIBLE then
call BlzFrameSetAbsPoint(DefaultFrame.Portrait, FRAMEPOINT_BOTTOMLEFT,/*
*/ GetScreenPosX(PORTRAIT_FRAME_POS_X+ResolutionWidth*PORTRAIT_FRAME_ANCHOR_X-BlzFrameGetWidth(DefaultFrame.Portrait)*DPITOPX*PORTRAIT_FRAME_PIVOT_X),/*
*/ GetScreenPosY(PORTRAIT_FRAME_POS_Y+ResolutionHeight*PORTRAIT_FRAME_ANCHOR_Y-BlzFrameGetHeight(DefaultFrame.Portrait)*DPITOPX*PORTRAIT_FRAME_PIVOT_Y))
else
call BlzFrameSetAbsPoint(DefaultFrame.Portrait, FRAMEPOINT_BOTTOMLEFT, -999.0, -999.0)
call BlzFrameSetSize(DefaultFrame.Portrait, 0.0001, 0.0001)
endif
endmethod
static method RefreshResolution takes nothing returns nothing
local AllComponents node
set ResolutionWidth = BlzGetLocalClientWidth()
set ResolutionHeight = BlzGetLocalClientHeight()
set ScaleFactor = I2R(ResolutionHeight)/I2R(RESOLUTION_HEIGHT)
set node = AllComponents.base.next
loop
exitwhen node.head or node == 0
if UIFrame(node).parent == UIFrame.Null then
call UIFrame(node).refresh()
endif
set node = node.next
endloop
endmethod
private static method CheckResolution takes nothing returns nothing
if BlzGetLocalClientWidth() != ResolutionWidth or BlzGetLocalClientHeight() != ResolutionHeight then
call RefreshResolution()
call RefreshDefaultFrames()
call TriggerEvaluate(resolutionChangeTrigg)
endif
endmethod
static method RegisterOnResolutionChangeEvent takes code func returns triggercondition
return TriggerAddCondition(resolutionChangeTrigg, Condition(func))
endmethod
static method RemoveOnResolutionChangeEvent takes triggercondition cond returns nothing
call TriggerRemoveCondition(resolutionChangeTrigg, cond)
endmethod
implement UIUtilsInit
endstruct
private struct UISubFrame
static UIFrame frame = 0
method operator [] takes string s returns framehandle
return BlzGetFrameByName(s, frame.context)
endmethod
endstruct
struct UIFrame extends array
implement LinkedList
string name
boolean inheritScale
boolean inheritOpacity
boolean inheritVisibility
boolean inheritEnableState
boolean inheritPosition
boolean inheritLevel
boolean scalePosition
boolean alwaysRefresh
readonly string frameType
readonly real localPosX
readonly real localPosY
readonly real anchorX
readonly real anchorY
readonly real pivotX
readonly real pivotY
readonly real unscaledWidth
readonly real unscaledHeight
readonly real valueMin
readonly real valueMax
readonly real fontSize
readonly string fontType
readonly integer fontFlags
readonly integer context
readonly boolean isSimple
readonly boolean visibleSelf
readonly boolean enabledSelf
readonly integer localOpacity
private real m_localScale
private real m_stepSize
private integer m_level
private thistype m_parent
private thistype m_childs
private thistype m_tooltips
private string mainTextureFile
private string disabledTextureFile
private string pushedTextureFile
private string highlightTextureFile
private string backgroundTextureFile
private string borderTextureFile
private string modelFile
private trigger anyEventTrigg
readonly framehandle frame
private framehandle textFrameH
private framehandle modelFrameH
private framehandle mainTextureH
private framehandle disabledTextureH
private framehandle pushedTextureH
private framehandle highlightTextureH
private framehandle backgroundTextureH
private framehandle borderTextureH
readonly static thistype Null = 0
readonly static thistype EnumChild = 0
readonly static thistype TriggerComponent = 0
readonly static string TYPE_TEXT = "UIUtilsText"
readonly static string TYPE_SIMPLE_TEXT = "UIUtilsSimpleText"
readonly static string TYPE_TEXTURE = "UIUtilsTexture"
readonly static string TYPE_SIMPLE_TEXTURE = "UIUtilsSimpleTexture"
readonly static string TYPE_BUTTON = "UIUtilsButton"
readonly static string TYPE_SIMPLE_BUTTON = "UIUtilsSimpleButton"
readonly static string TYPE_BAR = "UIUtilsBar"
readonly static string TYPE_H_SLIDER = "UIUtilsSliderH"
readonly static string TYPE_V_SLIDER = "UIUtilsSliderV"
private static trigger ExecTrigg = CreateTrigger()
private static gamecache GC
private static hashtable HT
private static method IsSimple takes string frameType, boolean isSimple returns boolean
return frameType == TYPE_SIMPLE_TEXT or frameType == TYPE_SIMPLE_TEXTURE or frameType == TYPE_BAR or isSimple and not (frameType == TYPE_TEXT or frameType == TYPE_TEXTURE or frameType == TYPE_BUTTON or frameType == TYPE_H_SLIDER or frameType == TYPE_V_SLIDER)
endmethod
private static method GetTriggerComponent takes nothing returns boolean
set TriggerComponent = LoadInteger(HT, GetHandleId(BlzGetTriggerFrame()), 0)
return false
endmethod
method operator subFrame takes nothing returns UISubFrame
set UISubFrame.frame = this
return 0
endmethod
method operator onAnyEvent= takes code func returns triggercondition
local integer i
if .anyEventTrigg == null then
set .anyEventTrigg = CreateTrigger()
set i = 1
loop
exitwhen i > 16
call BlzTriggerRegisterFrameEvent(.anyEventTrigg, .frame, ConvertFrameEventType(i))
set i = i + 1
endloop
call TriggerAddCondition(.anyEventTrigg, Condition(function thistype.GetTriggerComponent))
endif
return TriggerAddCondition(.anyEventTrigg, Condition(func))
endmethod
method operator parent= takes thistype frm returns nothing
if frm != Null then
if .m_parent != frm then
call .removeNode()
endif
call frm.m_childs.insertNode(this)
endif
static if not PERSISTENT_CHILD_PROPERTIES then
if .m_parent != Null then
set .localScale = .localScale*.m_parent.localScale
endif
set .localPosX = .screenPosX - frm.screenPosX
set .localPosY = .screenPosY - frm.screenPosY
endif
set .m_parent = frm
call refresh()
endmethod
method operator parent takes nothing returns thistype
return .m_parent
endmethod
method operator text= takes string str returns nothing
call BlzFrameSetText(.textFrameH, str)
endmethod
method operator text takes nothing returns string
return BlzFrameGetText(.textFrameH)
endmethod
method operator maxLength= takes integer length returns nothing
call BlzFrameSetTextSizeLimit(.textFrameH, length)
endmethod
method operator maxLength takes nothing returns integer
return BlzFrameGetTextSizeLimit(.textFrameH)
endmethod
method operator textColor= takes integer color returns nothing
call BlzFrameSetTextColor(.textFrameH, color)
endmethod
method operator texture= takes string filePath returns nothing
set .mainTextureFile = filePath
call BlzFrameSetTexture(.mainTextureH, filePath, 0, true)
if StringLength(.disabledTextureFile) == 0 then
set .disabledTexture = filePath
endif
if StringLength(.pushedTextureFile) == 0 then
set .pushedTexture = filePath
endif
endmethod
method operator texture takes nothing returns string
return .mainTextureFile
endmethod
method operator disabledTexture= takes string filePath returns nothing
set .disabledTextureFile = filePath
call BlzFrameSetTexture(.disabledTextureH, filePath, 0, true)
endmethod
method operator disabledTexture takes nothing returns string
return .disabledTextureFile
endmethod
method operator highlightTexture= takes string filePath returns nothing
set .highlightTextureFile = filePath
call BlzFrameSetTexture(.highlightTextureH, filePath, 0, true)
endmethod
method operator highlightTexture takes nothing returns string
return .highlightTextureFile
endmethod
method operator pushedTexture= takes string filePath returns nothing
set .pushedTextureFile = filePath
call BlzFrameSetTexture(.pushedTextureH, filePath, 0, true)
endmethod
method operator pushedTexture takes nothing returns string
return .pushedTextureFile
endmethod
method operator backgroundTexture= takes string filePath returns nothing
set .backgroundTextureFile = filePath
call BlzFrameSetTexture(.backgroundTextureH, filePath, 0, true)
endmethod
method operator backgroundTexture takes nothing returns string
return .backgroundTextureFile
endmethod
method operator borderTexture= takes string filePath returns nothing
set .borderTextureFile = filePath
call BlzFrameSetTexture(.borderTextureH, filePath, 0, true)
endmethod
method operator borderTexture takes nothing returns string
return .borderTextureFile
endmethod
method operator model= takes string filePath returns nothing
set .modelFile = filePath
call BlzFrameSetModel(.modelFrameH, filePath, 0)
endmethod
method operator model takes nothing returns string
return .modelFile
endmethod
method operator width takes nothing returns real
return .unscaledWidth*.scale
endmethod
method operator height takes nothing returns real
return .unscaledHeight*.scale
endmethod
method operator localScale= takes real r returns nothing
local thistype node = .m_childs.next
set .m_localScale = RMaxBJ(r, 0.0001)
call setSize(.unscaledWidth, .unscaledHeight)
call setFont(.fontType, .fontSize, .fontFlags)
call move(.localPosX, .localPosY)
loop
exitwhen node.head or node == 0
set node.localScale = node.localScale
call node.calcScreenPos()
set node = node.next
endloop
endmethod
method operator localScale takes nothing returns real
return .m_localScale
endmethod
method operator scale takes nothing returns real
if .parent == Null or not .inheritScale then
return .localScale
else
return .localScale*.parent.scale
endif
endmethod
method operator opacity= takes integer amount returns nothing
local thistype node = .m_childs.next
set .localOpacity = amount
call BlzFrameSetAlpha(.frame, .opacity)
loop
exitwhen node.head or node == 0
set node.opacity = node.localOpacity
set node = node.next
endloop
endmethod
method operator opacity takes nothing returns integer
if .parent == Null or not .inheritOpacity then
return .localOpacity
else
return R2I(I2R(.localOpacity)*I2R(.parent.opacity)/255.)
endif
endmethod
method operator level= takes integer level returns nothing
local thistype node = .m_childs.next
set .m_level = level
call BlzFrameSetLevel(.frame, .trueLevel)
loop
exitwhen node.head or node == 0
set node.level = node.m_level
set node = node.next
endloop
endmethod
method operator level takes nothing returns integer
return .m_level
endmethod
method operator trueLevel takes nothing returns integer
if .parent == Null or not .inheritLevel then
return .m_level
else
return .m_level+.parent.level
endif
endmethod
method operator visible= takes boolean state returns nothing
local thistype node = .m_childs.next
set .visibleSelf = state
call BlzFrameSetVisible(.frame, .visible)
loop
exitwhen node.head or node == 0
set node.visible = node.visibleSelf
set node = node.next
endloop
endmethod
method operator visible takes nothing returns boolean
if .parent == Null or not .inheritVisibility then
return .visibleSelf
else
return .visibleSelf and .parent.visible
endif
endmethod
method operator enabled= takes boolean state returns nothing
local thistype node = .m_childs.next
set .enabledSelf = state
call BlzFrameSetEnable(.frame, .enabled)
loop
exitwhen node.head or node == 0
set node.enabled = node.enabledSelf
set node = node.next
endloop
endmethod
method operator enabled takes nothing returns boolean
if .parent == Null or not .inheritEnableState then
return .enabledSelf
else
return .enabledSelf and .parent.enabled
endif
endmethod
method operator vertexColor= takes integer color returns nothing
call BlzFrameSetVertexColor(.modelFrameH, color)
endmethod
method operator value= takes real r returns nothing
call BlzFrameSetValue(.frame, r)
endmethod
method operator value takes nothing returns real
return BlzFrameGetValue(.frame)
endmethod
method operator stepSize= takes real r returns nothing
set .m_stepSize = RMaxBJ(r, 0.0001)
call BlzFrameSetStepSize(.frame, .m_stepSize)
endmethod
method operator stepSize takes nothing returns real
return .m_stepSize
endmethod
method operator tooltips= takes thistype frame returns nothing
set .m_tooltips = frame
call BlzFrameSetTooltip(.frame, frame.frame)
endmethod
method operator tooltips takes nothing returns thistype
return .m_tooltips
endmethod
method operator left takes nothing returns real
return .screenPosX-.width*.pivotX
endmethod
method operator right takes nothing returns real
return .left+.width
endmethod
method operator bottom takes nothing returns real
return .screenPosY-.height*.pivotY
endmethod
method operator top takes nothing returns real
return .bottom+.height
endmethod
private real m_screenPosX
method operator screenPosX takes nothing returns real
return .m_screenPosX
endmethod
private real m_screenPosY
method operator screenPosY takes nothing returns real
return .m_screenPosY
endmethod
private method normalizePosX takes real x returns real
return RMinBJ(RMaxBJ(x, UIUtils.FrameBoundWidth+.width*.pivotX), UIUtils.ResolutionWidth-UIUtils.FrameBoundWidth-.width*(1.-.pivotX))
endmethod
private method normalizeScaledPosX takes real x returns real
return RMinBJ(RMaxBJ(x, UIUtils.FrameBoundWidth+.width*.pivotX*UIUtils.ScaleFactor), UIUtils.ResolutionWidth-UIUtils.FrameBoundWidth-.width*(1.-.pivotX)*UIUtils.ScaleFactor)
endmethod
private method operator scaledLeft takes nothing returns real
return .scaledScreenPosX-.width*.pivotX*UIUtils.ScaleFactor
endmethod
private method operator scaledBottom takes nothing returns real
return .scaledScreenPosY-.height*.pivotY*UIUtils.ScaleFactor
endmethod
private real m_scaledScreenPosX
private method operator scaledScreenPosX takes nothing returns real
return .m_scaledScreenPosX
endmethod
private real m_scaledScreenPosY
private method operator scaledScreenPosY takes nothing returns real
return .m_scaledScreenPosY
endmethod
private method calcScreenPos takes nothing returns nothing
if .parent == Null or not .inheritPosition then
if not .isSimple then
set .m_screenPosX = normalizePosX(.localPosX+UIUtils.ResolutionWidth*.anchorX)
set .m_scaledScreenPosX = normalizeScaledPosX(.localPosX*UIUtils.ScaleFactor+UIUtils.ResolutionWidth*.anchorX)
else
set .m_screenPosX = .localPosX+UIUtils.ResolutionWidth*.anchorX
set .m_scaledScreenPosX = .localPosX*UIUtils.ScaleFactor+UIUtils.ResolutionWidth*.anchorX
endif
set .m_screenPosY = .localPosY+UIUtils.ResolutionHeight*.anchorY
set .m_scaledScreenPosY = .localPosY*UIUtils.ScaleFactor+UIUtils.ResolutionHeight*.anchorY
elseif .scalePosition then
set .m_screenPosX = .parent.left+.parent.width*.anchorX+.localPosX*.parent.scale
set .m_screenPosY = .parent.bottom+.parent.height*.anchorY+.localPosY*.parent.scale
set .m_scaledScreenPosX = .parent.scaledLeft+(.parent.width*.anchorX+.localPosX*.parent.scale)*UIUtils.ScaleFactor
set .m_scaledScreenPosY = .parent.scaledBottom+(.parent.height*.anchorY+.localPosY*.parent.scale)*UIUtils.ScaleFactor
else
set .m_screenPosX = .parent.left+.parent.width*.anchorX+.localPosX
set .m_screenPosY = .parent.bottom+.parent.height*.anchorY+.localPosY
set .m_scaledScreenPosX = .parent.scaledLeft+(.parent.width*.anchorX+.localPosX)*UIUtils.ScaleFactor
set .m_scaledScreenPosY = .parent.scaledBottom+(.parent.height*.anchorY+.localPosY)*UIUtils.ScaleFactor
endif
endmethod
method setAnchorPoint takes real x, real y returns nothing
set .anchorX = x
set .anchorY = y
call calcScreenPos()
call move(.localPosX, .localPosY)
endmethod
method setPivotPoint takes real x, real y returns nothing
set .pivotX = x
set .pivotY = y
call move(.localPosX, .localPosY)
endmethod
method setSize takes real width, real height returns nothing
set .unscaledWidth = RMaxBJ(width, 0)
set .unscaledHeight = RMaxBJ(height, 0)
call calcScreenPos()
call BlzFrameSetSize(frame, .width*UIUtils.ScaleFactor*UIUtils.PXTODPI, .height*UIUtils.ScaleFactor*UIUtils.PXTODPI)
if .pivotX + .pivotY + .anchorX + .anchorY != 0 then
call move(.localPosX, .localPosY)
endif
endmethod
method move takes real x, real y returns nothing
local thistype node = .m_childs.next
if not .alwaysRefresh and (not .visible or .opacity <= 0) then
return
endif
set .localPosX = x
set .localPosY = y
call calcScreenPos()
if not .isSimple then
set x = normalizeScaledPosX(.scaledScreenPosX-.width*.pivotX*UIUtils.ScaleFactor)
else
set x = .scaledScreenPosX-.width*.pivotX*UIUtils.ScaleFactor
endif
call BlzFrameSetAbsPoint(.frame, FRAMEPOINT_BOTTOMLEFT, UIUtils.GetScreenPosX(x), UIUtils.GetScreenPosY(.scaledScreenPosY-.height*.pivotY*UIUtils.ScaleFactor))
loop
exitwhen node.head or node == 0
call node.move(node.localPosX, node.localPosY)
set node = node.next
endloop
endmethod
method moveEx takes real x, real y returns nothing
if .parent == Null or not .inheritPosition then
call move(x, y)
else
call move((x-.parent.screenPosX)/.parent.localScale, (y-.parent.screenPosY)/.parent.localScale)
endif
endmethod
method relate takes thistype relative, real x, real y returns nothing
if .parent == Null then
call move(relative.screenPosX+x, relative.screenPosY+y)
else
call moveEx(relative.screenPosX+x, relative.screenPosY+y)
endif
endmethod
method refresh takes nothing returns nothing
set .visible = .visibleSelf
set .enabled = .enabledSelf
set .opacity = .localOpacity
set .level = .m_level
set .localScale = .localScale
call setFont(.fontType, .fontSize, .fontFlags)
endmethod
method click takes nothing returns nothing
call BlzFrameClick(.frame)
endmethod
method cageMouse takes boolean state returns nothing
call BlzFrameCageMouse(.frame, state)
endmethod
method setFocus takes boolean state returns nothing
call BlzFrameSetFocus(.frame, state)
endmethod
method setSpriteAnimate takes integer primaryProp, integer flags returns nothing
call BlzFrameSetSpriteAnimate(.frame, primaryProp, flags)
endmethod
method setMinMaxValue takes real min, real max returns nothing
set .valueMin = min
set .valueMax = max
call BlzFrameSetMinMaxValue(.frame, min, max)
endmethod
method setFont takes string fontType, real fontSize, integer flags returns nothing
set .fontSize = fontSize
set .fontType = fontType
set .fontFlags = flags
if .frameType == TYPE_SIMPLE_TEXT then
call BlzFrameSetFont(.textFrameH, fontType, fontSize*.scale, flags)
endif
endmethod
method setTextAlignment takes textaligntype vertical, textaligntype horizontal returns nothing
call BlzFrameSetTextAlignment(.textFrameH, vertical, horizontal)
endmethod
private method getSubFrame takes string name returns framehandle
local framehandle h = BlzGetFrameByName(name, .context)
if h == null then
return .frame
else
return h
endif
endmethod
method forEachChild takes code func returns nothing
local thistype node = .m_childs.next
call TriggerAddAction(ExecTrigg, func)
loop
exitwhen node.head or node == 0
set EnumChild = node
call TriggerExecute(ExecTrigg)
set node = node.next
endloop
call TriggerClearActions(ExecTrigg)
endmethod
method destroy takes nothing returns nothing
local thistype node = .m_childs.next
loop
exitwhen node.head or node == 0
call node.destroy()
set node = node.next
endloop
call BlzDestroyFrame(.frame)
call DestroyTrigger(.anyEventTrigg)
call StoreInteger(GC, name, I2S(.context), GetStoredInteger(GC, name, "0"))
call StoreInteger(GC, name, "0", .context)
call AllComponents.remove(this)
call .m_childs.flushNode()
call removeNode()
call deallocate()
set .anyEventTrigg = null
set .mainTextureH = null
set .disabledTextureH = null
set .highlightTextureH = null
set .pushedTextureH = null
set .backgroundTextureH = null
set .borderTextureH = null
set .textFrameH = null
set .modelFrameH = null
set .frame = null
set .name = null
set .frameType = null
set .m_parent = Null
set .m_childs = 0
endmethod
static method create takes boolean isSimple, string frameType, thistype parent, real x, real y, integer level returns thistype
local thistype this = allocate()
local integer tempInt
set .context = GetStoredInteger(GC, frameType, "0")
set tempInt = GetStoredInteger(GC, frameType, I2S(context))
if tempInt == 0 then
call StoreInteger(GC, frameType, "0", context+1)
else
call StoreInteger(GC, frameType, "0", tempInt)
endif
set .parent = parent
set .m_childs = createNode()
set .isSimple = IsSimple(frameType, isSimple)
if .isSimple then
set .frame = BlzCreateSimpleFrame(frameType, DefaultFrame.Game, .context)
else
set .frame = BlzCreateFrame(frameType, DefaultFrame.Game, 0, .context)
endif
set .mainTextureH = getSubFrame(frameType + "Texture")
set .disabledTextureH = getSubFrame(frameType + "Disabled")
set .highlightTextureH = getSubFrame(frameType + "Highlight")
set .pushedTextureH = getSubFrame(frameType + "Pushed")
set .backgroundTextureH = getSubFrame(frameType + "Background")
set .borderTextureH = getSubFrame(frameType + "Border")
set .textFrameH = getSubFrame(frameType + "Text")
set .modelFrameH = getSubFrame(frameType + "Model")
set .inheritScale = true
set .inheritOpacity = true
set .inheritVisibility = true
set .inheritEnableState = true
set .inheritPosition = true
set .inheritLevel = true
set .scalePosition = true
set .alwaysRefresh = true
set .unscaledWidth = BlzFrameGetWidth(.frame)*(RESOLUTION_HEIGHT/0.6)
set .unscaledHeight = BlzFrameGetHeight(.frame)*(RESOLUTION_HEIGHT/0.6)
set .frameType = frameType
set .name = frameType + I2S(.context)
set .level = level
set .visibleSelf = true
set .enabledSelf = true
set .fontType = "Fonts\\FRIZQT__.TTF"
set .fontSize = 0.013
set .fontFlags = 0
set .value = 0.0
set .localScale = 1.0
set .anchorX = 0.0
set .anchorY = 0.0
set .pivotX = 0.0
set .pivotY = 0.0
set .opacity = 255
set .mainTextureFile = ""
set .disabledTextureFile = ""
set .pushedTextureFile = ""
set .highlightTextureFile = ""
set .backgroundTextureFile = ""
set .borderTextureFile = ""
set .modelFile = ""
call move(x, y)
call setMinMaxValue(0.0, 1.0)
call AllComponents.add(this)
call SaveInteger(HT, GetHandleId(.frame), 0, this)
return this
endmethod
private static method onInit takes nothing returns nothing
set HT = InitHashtable()
set GC = InitGameCache(CACHE_NAME)
call BlzLoadTOCFile(TOC_FILE)
endmethod
endstruct
private struct AllComponents extends array
implement LinkedList
static method add takes thistype this returns nothing
call base.insertNode(this)
endmethod
static method remove takes thistype this returns nothing
call removeNode()
endmethod
endstruct
endlibrary
library UIUtils
globals
// 1. Screen resolution used to design UI
public constant real SCREEN_WIDTH = 1360.0
public constant real SCREEN_HEIGHT = 768.0
// 2. If true, it will hide console UIs on map init
private constant boolean HIDE_CONSOLE_UI = true
// 3. If true, all frames will be automatically adjusted on resolution change
private constant boolean AUTOMATIC_ADJUSTMENT = true
private constant real RESOLUTION_CHECK_INTERVAL = 0.1
// 4. If true, component's properties will be retained when it changes parent
private constant boolean PERSISTENT_CHILD_PROPERTIES = true
// 3. In-game message visibility
public constant boolean MESSAGE_FRAME_VISIBLE = true
public constant real MESSAGE_FRAME_POS_X = 200.0
public constant real MESSAGE_FRAME_POS_Y = 300.0
// 4. Chat message visibility
public constant boolean CHAT_FRAME_VISIBLE = true
public constant real CHAT_FRAME_POS_X = 10.0
public constant real CHAT_FRAME_POS_Y = 100.0
// 5. Tooltips visibility
public constant boolean TOOLTIPS_FRAME_VISIBLE = true
public constant real TOOLTIPS_FRAME_POS_X = 1075.0
public constant real TOOLTIPS_FRAME_POS_Y = 384.0
// 6. Other frame visibility
public constant boolean MINIMAP_FRAME_VISIBLE = false
public constant boolean RESOURCE_FRAME_VISIBLE = false
public constant boolean PORTRAIT_FRAME_VISIBLE = false
public constant boolean CMD_BUTTON_FRAME_VISIBLE = false
endglobals
globals
private real WidthFactor = 1.0
private real HeightFactor = 1.0
endglobals
private struct AllComponents extends array
implement LinkedList
static method add takes thistype this returns nothing
call base.insertNode(this)
endmethod
static method remove takes thistype this returns nothing
call removeNode()
endmethod
endstruct
private module INIT
private static method onInit takes nothing returns nothing
local integer i
local real x
local real y
local real yo
local real xo1
local real xo2
set FrameGameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)
set FrameWorld = BlzGetOriginFrame(ORIGIN_FRAME_WORLD_FRAME, 0)
set FrameHeroBar = BlzGetOriginFrame(ORIGIN_FRAME_HERO_BAR, 0)
set FramePortrait = BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT, 0)
set FrameMinimap = BlzGetOriginFrame(ORIGIN_FRAME_MINIMAP, 0)
set FrameTooltip = BlzGetOriginFrame(ORIGIN_FRAME_TOOLTIP, 0)
set FrameUberTooltip = BlzGetOriginFrame(ORIGIN_FRAME_UBERTOOLTIP, 0)
set FrameChatMsg = BlzGetOriginFrame(ORIGIN_FRAME_CHAT_MSG, 0)
set FrameUnitMsg = BlzGetOriginFrame(ORIGIN_FRAME_UNIT_MSG, 0)
set FrameTopMsg = BlzGetOriginFrame(ORIGIN_FRAME_TOP_MSG, 0)
set i = 0
loop
exitwhen i > 11
set FrameHeroButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_HERO_BUTTON, i)
set FrameHeroHPBar[i] = BlzGetOriginFrame(ORIGIN_FRAME_HERO_HP_BAR, i)
set FrameHeroMPBar[i] = BlzGetOriginFrame(ORIGIN_FRAME_HERO_MANA_BAR, i)
set FrameHeroIndicator[i] = BlzGetOriginFrame(ORIGIN_FRAME_HERO_BUTTON_INDICATOR, i)
set FrameItemButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_ITEM_BUTTON, i)
set FrameCommandButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON, i)
set FrameSystemButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_SYSTEM_BUTTON, i)
set FrameMinimapButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_MINIMAP_BUTTON, i)
set i = i + 1
endloop
set FrameConsoleUI = BlzGetFrameByName("ConsoleUI", 0)
set FrameGoldText = BlzGetFrameByName("ResourceBarGoldText", 0)
set FrameLumberText = BlzGetFrameByName("ResourceBarLumberText", 0)
set FrameFoodText = BlzGetFrameByName("ResourceBarSupplyText", 0)
set FrameUnitNameText = BlzGetFrameByName("SimpleNameValue", 0)
call RefreshResolution()
static if HIDE_CONSOLE_UI then
call BlzEnableUIAutoPosition(false)
call BlzFrameClearAllPoints(FrameWorld)
call BlzFrameClearAllPoints(FrameConsoleUI)
// Fit viewport to screen
call BlzFrameSetAllPoints(FrameWorld, FrameGameUI)
call BlzFrameSetAbsPoint(FrameConsoleUI, FRAMEPOINT_TOPRIGHT, XCoordToDPI(0.0), YCoordToDPI(0.0))
// Set in-game message frame position
static if MESSAGE_FRAME_VISIBLE then
call BlzFrameClearAllPoints(FrameUnitMsg)
call BlzFrameSetAbsPoint(FrameUnitMsg, FRAMEPOINT_BOTTOMLEFT, XCoordToDPI(MESSAGE_FRAME_POS_X), YCoordToDPI(MESSAGE_FRAME_POS_Y))
endif
// Set chat frame position
static if CHAT_FRAME_VISIBLE then
call BlzFrameSetAbsPoint(FrameChatMsg, FRAMEPOINT_BOTTOMLEFT, XCoordToDPI(CHAT_FRAME_POS_X), YCoordToDPI(CHAT_FRAME_POS_Y))
endif
// Set tooltips frame position
static if TOOLTIPS_FRAME_VISIBLE then
call BlzFrameClearAllPoints(FrameUberTooltip)
call BlzFrameSetAbsPoint(FrameUberTooltip, FRAMEPOINT_CENTER, XCoordToDPI(TOOLTIPS_FRAME_POS_X), YCoordToDPI(TOOLTIPS_FRAME_POS_Y))
endif
static if not MINIMAP_FRAME_VISIBLE then
call BlzFrameClearAllPoints(FrameMinimap)
call BlzFrameSetAbsPoint(FrameMinimap, FRAMEPOINT_BOTTOMLEFT, XCoordToDPI(-999.0), YCoordToDPI(-999.0))
endif
static if not RESOURCE_FRAME_VISIBLE then
call BlzFrameClearAllPoints(FrameGoldText)
call BlzFrameSetAbsPoint(FrameGoldText, FRAMEPOINT_BOTTOMLEFT, XCoordToDPI(-999.0), YCoordToDPI(-999.0))
call BlzFrameClearAllPoints(FrameLumberText)
call BlzFrameSetAbsPoint(FrameLumberText, FRAMEPOINT_BOTTOMLEFT, XCoordToDPI(-999.0), YCoordToDPI(-999.0))
call BlzFrameClearAllPoints(FrameFoodText)
call BlzFrameSetAbsPoint(FrameFoodText, FRAMEPOINT_BOTTOMLEFT, XCoordToDPI(-999.0), YCoordToDPI(-999.0))
endif
static if not PORTRAIT_FRAME_VISIBLE then
call BlzFrameClearAllPoints(FramePortrait)
call BlzFrameSetAbsPoint(FramePortrait, FRAMEPOINT_BOTTOMLEFT, XCoordToDPI(-999.0), YCoordToDPI(-999.0))
endif
static if not CMD_BUTTON_FRAME_VISIBLE then
set i = 0
loop
exitwhen FrameCommandButton[i] == null
call BlzFrameClearAllPoints(FrameCommandButton[i])
call BlzFrameSetAbsPoint(FrameCommandButton[i], FRAMEPOINT_RIGHT, XCoordToDPI(-999.0), YCoordToDPI(-999.0))
set i = i + 1
endloop
endif
endif
static if AUTOMATIC_ADJUSTMENT then
call TimerStart(CreateTimer(), RESOLUTION_CHECK_INTERVAL, true, function thistype.CheckResolution)
endif
endmethod
endmodule
struct UIUtils extends array
readonly static integer ResolutionWidth = 0
readonly static integer ResolutionHeight = 0
readonly static integer AspectWidth = 0
readonly static integer AspectHeight = 0
private static real RefAspectWorld = 5.0
private static real RefAspectWidth = 4.0
private static real RefAspectHeight = 3.0
private static real RefExtraWidth = 0.0
readonly static real MinFrameX = 0.0
readonly static real MaxFrameX = 0.0
readonly static real DPIMinX = 0.0
readonly static real DPIMaxX = 0.0
readonly static real DPIMinY = 0.0
readonly static real DPIMaxY = RefAspectHeight/RefAspectWorld
private static real PxToDPI = 0.0
readonly static framehandle FrameGameUI
readonly static framehandle FrameWorld
readonly static framehandle FrameHeroBar
readonly static framehandle array FrameHeroButton
readonly static framehandle array FrameHeroHPBar
readonly static framehandle array FrameHeroMPBar
readonly static framehandle array FrameHeroIndicator
readonly static framehandle array FrameItemButton
readonly static framehandle array FrameCommandButton
readonly static framehandle array FrameSystemButton
readonly static framehandle FramePortrait
readonly static framehandle FrameMinimap
readonly static framehandle array FrameMinimapButton
readonly static framehandle FrameTooltip
readonly static framehandle FrameUberTooltip
readonly static framehandle FrameChatMsg
readonly static framehandle FrameUnitMsg
readonly static framehandle FrameTopMsg
readonly static framehandle FrameConsoleUI
readonly static framehandle FrameGoldText
readonly static framehandle FrameLumberText
readonly static framehandle FrameFoodText
readonly static framehandle FrameUnitNameText
private static method CalcAspectRatio takes real w, real h, real aw returns integer
return R2I(aw*h/w+0.5)
endmethod
static method XCoordToDPI takes real x returns real
return x*PxToDPI/RefAspectWidth+DPIMinX
endmethod
static method YCoordToDPI takes real y returns real
return y*PxToDPI/RefAspectWidth
endmethod
static method SizeToDPI takes real size returns real
return size*PxToDPI/RefAspectWidth
endmethod
static method DPIToXCoord takes real dpi returns real
return (dpi-DPIMinX)*RefAspectWidth/PxToDPI
endmethod
static method DPIToYCoord takes real dpi returns real
return dpi*RefAspectWidth/PxToDPI
endmethod
static method DPIToSize takes real dpi returns real
return dpi*RefAspectWidth/PxToDPI
endmethod
static method RefreshResolution takes nothing returns nothing
local AllComponents node
call BJDebugMsg("refresh")
set ResolutionWidth = BlzGetLocalClientWidth()
set ResolutionHeight = BlzGetLocalClientHeight()
set WidthFactor = ResolutionWidth/SCREEN_WIDTH
set HeightFactor = ResolutionHeight/SCREEN_HEIGHT
if CalcAspectRatio(ResolutionWidth, ResolutionHeight, 4) == 3 then
set PxToDPI = RefAspectWidth/(ResolutionWidth/1024.0*1280.0)
set AspectWidth = 4
set AspectHeight = 3
set RefExtraWidth = 0.0
elseif CalcAspectRatio(ResolutionWidth, ResolutionHeight, 16) == 9 then
set PxToDPI = RefAspectWidth/(ResolutionWidth/1360.0*1280.0)
set AspectWidth = 16
set AspectHeight = 9
set RefExtraWidth = 0.525
elseif CalcAspectRatio(ResolutionWidth, ResolutionHeight, 16) == 10 then
set PxToDPI = RefAspectWidth/(ResolutionWidth/1280.0*1280.0)
set AspectWidth = 16
set AspectHeight = 10
set RefExtraWidth = 0.4
endif
set MinFrameX = RefExtraWidth*320.0
set MaxFrameX = ResolutionWidth-MinFrameX
set DPIMinX = -(RefExtraWidth/RefAspectWidth)
set DPIMaxX = RefAspectWidth/RefAspectWorld-DPIMinX
set node = AllComponents.base.next
loop
exitwhen node.head or node == 0
if UIComponent(node).parent == UIComponent.Null then
set UIComponent(node).localScale = UIComponent(node).localScale
endif
set node = node.next
endloop
endmethod
static method CalcFrameSpacing takes UIComponent from, UIComponent to, boolean topdown returns real
local real size1
local real size2
local framepointtype anchor1 = from.anchorPoint
local framepointtype anchor2 = to.anchorPoint
if topdown then
set size1 = from.height
set size2 = to.height
if anchor1 == FRAMEPOINT_TOPLEFT or anchor1 == FRAMEPOINT_TOP or anchor1 == FRAMEPOINT_TOPRIGHT then
set size1 = 0.0
elseif anchor1 == FRAMEPOINT_LEFT or anchor1 == FRAMEPOINT_CENTER or anchor1 == FRAMEPOINT_RIGHT then
set size1 = size1*0.5
endif
if anchor2 == FRAMEPOINT_BOTTOMLEFT or anchor2 == FRAMEPOINT_BOTTOM or anchor2 == FRAMEPOINT_BOTTOMRIGHT then
set size2 = 0.0
elseif anchor2 == FRAMEPOINT_LEFT or anchor2 == FRAMEPOINT_CENTER or anchor2 == FRAMEPOINT_RIGHT then
set size2 = size2*0.5
endif
else
set size1 = from.width
set size2 = to.width
if anchor1 == FRAMEPOINT_TOPRIGHT or anchor1 == FRAMEPOINT_RIGHT or anchor1 == FRAMEPOINT_BOTTOMRIGHT then
set size1 = 0.0
elseif anchor1 == FRAMEPOINT_TOP or anchor1 == FRAMEPOINT_CENTER or anchor1 == FRAMEPOINT_BOTTOM then
set size1 = size1*0.5
endif
if anchor2 == FRAMEPOINT_TOPLEFT or anchor2 == FRAMEPOINT_LEFT or anchor2 == FRAMEPOINT_BOTTOMLEFT then
set size2 = 0.0
elseif anchor2 == FRAMEPOINT_TOP or anchor2 == FRAMEPOINT_CENTER or anchor2 == FRAMEPOINT_BOTTOM then
set size2 = size2*0.5
endif
endif
return size1+size2
endmethod
private static method CheckResolution takes nothing returns nothing
if BlzGetLocalClientWidth() != ResolutionWidth or BlzGetLocalClientHeight() != ResolutionHeight then
call RefreshResolution()
endif
endmethod
implement INIT
endstruct
struct UIComponent extends array
implement LinkedList
string name
boolean inheritScale
boolean inheritOpacity
boolean inheritVisibility
boolean inheritEnableState
boolean inheritPosition
boolean inheritLevel
boolean scalePosition
readonly framehandle frame
private framehandle textFrameH
private framehandle modelFrameH
private framehandle mainTextureH
private framehandle disabledTextureH
private framehandle pushedTextureH
private framehandle highlightTextureH
private framehandle backgroundTextureH
private framehandle borderTextureH
private framepointtype anchor
readonly string frameType
readonly real localX
readonly real localY
readonly real screenX
readonly real screenY
readonly real minValue
readonly real maxValue
readonly integer context
readonly boolean visibleSelf
readonly boolean enabledSelf
readonly integer localOpacity
private integer lvl
private real localSize
private real localWidth
private real localHeight
private real step
private thistype par
private thistype child
private thistype tips
private string mainTextureFile
private string disabledTextureFile
private string pushedTextureFile
private string highlightTextureFile
private string backgroundTextureFile
private string borderTextureFile
private string modelFile
private trigger anyEventTrigg
readonly static thistype Null = 0
readonly static thistype EnumChild = 0
readonly static thistype TriggerComponent = 0
readonly static string TYPE_TEXT = "UIUtilsText"
readonly static string TYPE_SIMPLE_TEXT = "UIUtilsSimpleText"
readonly static string TYPE_TEXTURE = "UIUtilsTexture"
readonly static string TYPE_SIMPLE_TEXTURE = "UIUtilsSimpleTexture"
readonly static string TYPE_BUTTON = "UIUtilsButton"
readonly static string TYPE_SIMPLE_BUTTON = "UIUtilsSimpleButton"
readonly static string TYPE_BAR = "UIUtilsBar"
readonly static string TYPE_H_SLIDER = "UIUtilsSliderH"
readonly static string TYPE_V_SLIDER = "UIUtilsSliderV"
private static trigger ExecTrigg = CreateTrigger()
private static gamecache GC
private static hashtable HT
private static method IsSimple takes string frameType, boolean isSimple returns boolean
return frameType == TYPE_SIMPLE_TEXT or frameType == TYPE_SIMPLE_TEXTURE or frameType == TYPE_BAR or isSimple and not (frameType == TYPE_TEXT or frameType == TYPE_TEXTURE or frameType == TYPE_BUTTON or frameType == TYPE_H_SLIDER or frameType == TYPE_V_SLIDER)
endmethod
private static method GetTriggerComponent takes nothing returns boolean
set TriggerComponent = LoadInteger(HT, GetHandleId(BlzGetTriggerFrame()), 0)
return false
endmethod
method operator onAnyEvent= takes code func returns triggercondition
local integer i
if .anyEventTrigg == null then
set .anyEventTrigg = CreateTrigger()
set i = 1
loop
exitwhen i > 16
call BlzTriggerRegisterFrameEvent(.anyEventTrigg, .frame, ConvertFrameEventType(i))
set i = i + 1
endloop
call TriggerAddCondition(.anyEventTrigg, Condition(function thistype.GetTriggerComponent))
endif
return TriggerAddCondition(.anyEventTrigg, Condition(func))
endmethod
method operator anchorPoint= takes framepointtype point returns nothing
set .anchor = point
call BlzFrameClearAllPoints(.frame)
call move(.localX, .localY)
endmethod
method operator anchorPoint takes nothing returns framepointtype
return .anchor
endmethod
method operator parent= takes thistype comp returns nothing
if comp != Null then
if .par != comp then
call .removeNode()
endif
call comp.child.insertNode(this)
endif
static if not PERSISTENT_CHILD_PROPERTIES then
if .par != Null then
set .localScale = .localScale*.par.localScale
endif
set .localX = .screenX - comp.screenX
set .localY = .screenY - comp.screenY
endif
// Refresh props
set .par = comp
set .localScale = .localScale
set .visible = .visibleSelf
set .enabled = .enabledSelf
set .opacity = .localOpacity
set .level = .lvl
endmethod
method operator parent takes nothing returns thistype
return .par
endmethod
method operator text= takes string str returns nothing
call BlzFrameSetText(.textFrameH, str)
endmethod
method operator text takes nothing returns string
return BlzFrameGetText(.textFrameH)
endmethod
method operator maxLength= takes integer len returns nothing
call BlzFrameSetTextSizeLimit(.textFrameH, len)
endmethod
method operator maxLength takes nothing returns integer
return BlzFrameGetTextSizeLimit(.textFrameH)
endmethod
method operator textColor= takes integer color returns nothing
call BlzFrameSetTextColor(.textFrameH, color)
endmethod
method operator texture= takes string filePath returns nothing
set .mainTextureFile = filePath
call BlzFrameSetTexture(.mainTextureH, filePath, 0, true)
if StringLength(.disabledTextureFile) == 0 then
set .disabledTexture = filePath
endif
if StringLength(.pushedTextureFile) == 0 then
set .pushedTexture = filePath
endif
endmethod
method operator texture takes nothing returns string
return .mainTextureFile
endmethod
method operator disabledTexture= takes string filePath returns nothing
set .disabledTextureFile = filePath
call BlzFrameSetTexture(.disabledTextureH, filePath, 0, true)
endmethod
method operator disabledTexture takes nothing returns string
return .disabledTextureFile
endmethod
method operator highlightTexture= takes string filePath returns nothing
set .highlightTextureFile = filePath
call BlzFrameSetTexture(.highlightTextureH, filePath, 0, true)
endmethod
method operator highlightTexture takes nothing returns string
return .highlightTextureFile
endmethod
method operator pushedTexture= takes string filePath returns nothing
set .pushedTextureFile = filePath
call BlzFrameSetTexture(.pushedTextureH, filePath, 0, true)
endmethod
method operator pushedTexture takes nothing returns string
return .pushedTextureFile
endmethod
method operator backgroundTexture= takes string filePath returns nothing
set .backgroundTextureFile = filePath
call BlzFrameSetTexture(.backgroundTextureH, filePath, 0, true)
endmethod
method operator backgroundTexture takes nothing returns string
return .backgroundTextureFile
endmethod
method operator borderTexture= takes string filePath returns nothing
set .borderTextureFile = filePath
call BlzFrameSetTexture(.borderTextureH, filePath, 0, true)
endmethod
method operator borderTexture takes nothing returns string
return .borderTextureFile
endmethod
method operator model= takes string filePath returns nothing
set .modelFile = filePath
call BlzFrameSetModel(.modelFrameH, filePath, 0)
endmethod
method operator model takes nothing returns string
return .modelFile
endmethod
method operator vertexColor= takes integer color returns nothing
call BlzFrameSetVertexColor(.modelFrameH, color)
endmethod
method operator value= takes real r returns nothing
call BlzFrameSetValue(.frame, r)
endmethod
method operator value takes nothing returns real
return BlzFrameGetValue(.frame)
endmethod
method operator stepSize= takes real r returns nothing
set .step = RMaxBJ(r, 0.0001)
call BlzFrameSetStepSize(.frame, .step)
endmethod
method operator stepSize takes nothing returns real
return .step
endmethod
method operator localScale= takes real r returns nothing
local thistype node = .child.next
set .localSize = RMaxBJ(r, 0.0001)
call setSize(.width, .height)
call move(.localX, .localY)
loop
exitwhen node.head or node == 0
set node.localScale = node.localScale
set node = node.next
endloop
endmethod
method operator localScale takes nothing returns real
return .localSize
endmethod
method operator scale takes nothing returns real
if .parent == Null or not .inheritScale then
return .localScale
else
return .localScale * .parent.scale
endif
endmethod
method operator opacity= takes integer amount returns nothing
local thistype node = .child.next
set .localOpacity = amount
call BlzFrameSetAlpha(.frame, .opacity)
loop
exitwhen node.head or node == 0
set node.opacity = node.localOpacity
set node = node.next
endloop
endmethod
method operator opacity takes nothing returns integer
if .parent == Null or not .inheritOpacity then
return .localOpacity
else
return R2I(I2R(.localOpacity) * I2R(.parent.opacity)/255.)
endif
endmethod
method operator level= takes integer level returns nothing
local thistype node = .child.next
set .lvl = level
call BlzFrameSetLevel(.frame, .trueLevel)
loop
exitwhen node.head or node == 0
set node.level = node.lvl
set node = node.next
endloop
endmethod
method operator level takes nothing returns integer
return .lvl
endmethod
method operator trueLevel takes nothing returns integer
if .parent == Null or not .inheritLevel then
return .lvl
else
return .lvl + .parent.level
endif
endmethod
method operator tooltips= takes thistype comp returns nothing
set .tips = comp
call BlzFrameSetTooltip(.frame, comp.frame)
endmethod
method operator tooltips takes nothing returns thistype
return .tips
endmethod
method operator visible= takes boolean state returns nothing
local thistype node = .child.next
set .visibleSelf = state
call BlzFrameSetVisible(.frame, .visible)
loop
exitwhen node.head or node == 0
set node.visible = node.visibleSelf
set node = node.next
endloop
endmethod
method operator visible takes nothing returns boolean
if .parent == Null or not .inheritVisibility then
return .visibleSelf
else
return .visibleSelf and .parent.visible
endif
endmethod
method operator enabled= takes boolean state returns nothing
local thistype node = .child.next
set .enabledSelf = state
call BlzFrameSetEnable(.frame, .enabled)
loop
exitwhen node.head or node == 0
set node.enabled = node.enabledSelf
set node = node.next
endloop
endmethod
method operator enabled takes nothing returns boolean
if .parent == Null or not .inheritEnableState then
return .enabledSelf
else
return .enabledSelf and .parent.enabled
endif
endmethod
method operator width takes nothing returns real
return .localWidth
endmethod
method operator height takes nothing returns real
return .localHeight
endmethod
method setSize takes real width, real height returns nothing
set .localWidth = RMaxBJ(width, 0)
set .localHeight = RMaxBJ(height, 0)
call BlzFrameSetSize(frame, UIUtils.SizeToDPI(.localWidth*.scale*WidthFactor), UIUtils.SizeToDPI(.localHeight*.scale*WidthFactor))
endmethod
method move takes real x, real y returns nothing
local thistype node = .child.next
set .localX = x
set .localY = y
if .parent == Null or not .inheritPosition then
set .screenX = x
set .screenY = y
elseif .scalePosition then
set .screenX = .parent.screenX+.localX*.parent.scale
set .screenY = .parent.screenY+.localY*.parent.scale
else
set .screenX = .parent.screenX+.localX
set .screenY = .parent.screenY+.localY
endif
call BlzFrameSetAbsPoint(.frame, .anchor, UIUtils.XCoordToDPI(.screenX*WidthFactor), UIUtils.YCoordToDPI(.screenY*HeightFactor))
loop
exitwhen node.head or node == 0
call node.move(node.localX, node.localY)
set node = node.next
endloop
endmethod
method moveEx takes real x, real y returns nothing
if .parent == Null or not .inheritPosition then
call move(x, y)
else
call move((x-.parent.screenX)/.parent.localScale, (y-.parent.screenY)/.parent.localScale)
endif
endmethod
method relate takes thistype relative, real x, real y returns nothing
if .parent == Null then
call move(relative.screenX+x, relative.screenY+y)
else
call moveEx(relative.screenX+x, relative.screenY+y)
endif
endmethod
method click takes nothing returns nothing
call BlzFrameClick(.frame)
endmethod
method cageMouse takes boolean state returns nothing
call BlzFrameCageMouse(.frame, state)
endmethod
method setFocus takes boolean state returns nothing
call BlzFrameSetFocus(.frame, state)
endmethod
method setSpriteAnimate takes integer primaryProp, integer flags returns nothing
call BlzFrameSetSpriteAnimate(.frame, primaryProp, flags)
endmethod
method setMinMaxValue takes real min, real max returns nothing
set .minValue = min
set .maxValue = max
call BlzFrameSetMinMaxValue(.frame, min, max)
endmethod
method setFont takes string fontPath, real height, integer flags returns nothing
call BlzFrameSetFont(.textFrameH, fontPath, height, flags)
endmethod
method setTextAlignment takes textaligntype vertical, textaligntype horizontal returns nothing
call BlzFrameSetTextAlignment(.textFrameH, vertical, horizontal)
endmethod
method getSubFrame takes string name returns framehandle
return BlzGetFrameByName(name, .context)
endmethod
method forEachChild takes code func returns nothing
local thistype node = .child.next
call TriggerAddAction(ExecTrigg, func)
loop
exitwhen node.head or node == 0
set EnumChild = node
call TriggerExecute(ExecTrigg)
set node = node.next
endloop
call TriggerClearActions(ExecTrigg)
endmethod
method destroy takes nothing returns nothing
local thistype node = .child.next
loop
exitwhen node.head or node == 0
call node.destroy()
set node = node.next
endloop
call BlzDestroyFrame(.frame)
call DestroyTrigger(.anyEventTrigg)
call StoreInteger(GC, name, I2S(.context), GetStoredInteger(GC, name, "0"))
call StoreInteger(GC, name, "0", .context)
call AllComponents.remove(this)
call .child.flushNode()
call removeNode()
call deallocate()
set .anyEventTrigg = null
set .mainTextureH = null
set .disabledTextureH = null
set .highlightTextureH = null
set .pushedTextureH = null
set .backgroundTextureH = null
set .borderTextureH = null
set .textFrameH = null
set .modelFrameH = null
set .frame = null
set .name = null
set .frameType = null
set .par = Null
set .child = 0
endmethod
static method create takes boolean isSimple, string frameType, thistype par, real x, real y, integer level returns thistype
local thistype this = allocate()
local integer tempInt
set .context = GetStoredInteger(GC, frameType, "0")
set tempInt = GetStoredInteger(GC, frameType, I2S(context))
if tempInt == 0 then
call StoreInteger(GC, frameType, "0", context+1)
else
call StoreInteger(GC, frameType, "0", tempInt)
endif
set .parent = par
set .child = createNode()
if IsSimple(frameType, isSimple) then
set .frame = BlzCreateSimpleFrame(frameType, UIUtils.FrameGameUI, .context)
else
set .frame = BlzCreateFrame(frameType, UIUtils.FrameGameUI, 0, .context)
endif
set .mainTextureH = getSubFrame(frameType + "Texture")
set .disabledTextureH = getSubFrame(frameType + "Disabled")
set .highlightTextureH = getSubFrame(frameType + "Highlight")
set .pushedTextureH = getSubFrame(frameType + "Pushed")
set .backgroundTextureH = getSubFrame(frameType + "Background")
set .borderTextureH = getSubFrame(frameType + "Border")
set .textFrameH = getSubFrame(frameType + "Text")
set .modelFrameH = getSubFrame(frameType + "Model")
if .mainTextureH == null then
set .mainTextureH = .frame
endif
if .textFrameH == null then
set .textFrameH = .frame
endif
set .inheritScale = true
set .inheritOpacity = true
set .inheritVisibility = true
set .inheritEnableState = true
set .inheritPosition = true
set .inheritLevel = true
set .scalePosition = true
set .localWidth = UIUtils.DPIToSize(BlzFrameGetWidth(.frame))
set .localHeight = UIUtils.DPIToSize(BlzFrameGetHeight(.frame))
set .anchor = FRAMEPOINT_BOTTOMLEFT
set .frameType = frameType
set .name = frameType + I2S(.context)
set .level = level
set .visibleSelf = true
set .enabledSelf = true
set .value = 0.0
set .localScale = 1.0
set .opacity = 255
set .mainTextureFile = ""
set .disabledTextureFile = ""
set .pushedTextureFile = ""
set .highlightTextureFile = ""
set .backgroundTextureFile = ""
set .borderTextureFile = ""
set .modelFile = ""
call move(x, y)
call setMinMaxValue(0.0, 1.0)
call AllComponents.add(this)
call SaveInteger(HT, GetHandleId(.frame), 0, this)
return this
endmethod
private static method onInit takes nothing returns nothing
set HT = InitHashtable()
set GC = InitGameCache("UIUtils.w3v")
call BlzLoadTOCFile("war3mapimported\\UIUtils.toc")
call BlzLoadTOCFile("war3mapimported\\UIEmberCraft.toc")
endmethod
endstruct
endlibrary
library UIUtils
globals
// 1. Screen resolution used to design UI
public constant real SCREEN_WIDTH = 1360.0
public constant real SCREEN_HEIGHT = 768.0
// 2. If true, it will hide console UIs on map init
private constant boolean HIDE_CONSOLE_UI = true
// 3. In-game message position
public constant boolean MESSAGE_FRAME_VISIBLE = true
public constant real MESSAGE_FRAME_POS_X = 200.0
public constant real MESSAGE_FRAME_POS_Y = 300.0
// 4. Chat message position
public constant boolean CHAT_FRAME_VISIBLE = true
public constant real CHAT_FRAME_POS_X = 10.0
public constant real CHAT_FRAME_POS_Y = 100.0
// 5. If true, all frames will be automatically adjusted on resolution change
private constant boolean AUTOMATIC_ADJUSTMENT = true
private constant real RESOLUTION_CHECK_INTERVAL = 0.1
// 6. If true, component's properties will be retained when it changes parent
private constant boolean PERSISTENT_CHILD_PROPERTIES = true
endglobals
globals
private real WidthFactor = 1.0
private real HeightFactor = 1.0
endglobals
private struct AllComponents extends array
implement LinkedList
static method add takes thistype this returns nothing
call base.insertNode(this)
endmethod
static method remove takes thistype this returns nothing
call removeNode()
endmethod
endstruct
private module INIT
private static method onInit takes nothing returns nothing
local integer i
local real x
local real y
local real yo
local real xo1
local real xo2
set FrameGameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)
set FrameWorld = BlzGetOriginFrame(ORIGIN_FRAME_WORLD_FRAME, 0)
set FrameHeroBar = BlzGetOriginFrame(ORIGIN_FRAME_HERO_BAR, 0)
set FramePortrait = BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT, 0)
set FrameMinimap = BlzGetOriginFrame(ORIGIN_FRAME_MINIMAP, 0)
set FrameTooltip = BlzGetOriginFrame(ORIGIN_FRAME_TOOLTIP, 0)
set FrameUberTooltip = BlzGetOriginFrame(ORIGIN_FRAME_UBERTOOLTIP, 0)
set FrameChatMsg = BlzGetOriginFrame(ORIGIN_FRAME_CHAT_MSG, 0)
set FrameUnitMsg = BlzGetOriginFrame(ORIGIN_FRAME_UNIT_MSG, 0)
set FrameTopMsg = BlzGetOriginFrame(ORIGIN_FRAME_TOP_MSG, 0)
set i = 0
loop
exitwhen i > 11
set FrameHeroButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_HERO_BUTTON, i)
set FrameHeroHPBar[i] = BlzGetOriginFrame(ORIGIN_FRAME_HERO_HP_BAR, i)
set FrameHeroMPBar[i] = BlzGetOriginFrame(ORIGIN_FRAME_HERO_MANA_BAR, i)
set FrameHeroIndicator[i] = BlzGetOriginFrame(ORIGIN_FRAME_HERO_BUTTON_INDICATOR, i)
set FrameItemButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_ITEM_BUTTON, i)
set FrameCommandButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON, i)
set FrameSystemButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_SYSTEM_BUTTON, i)
set FrameMinimapButton[i] = BlzGetOriginFrame(ORIGIN_FRAME_MINIMAP_BUTTON, i)
set i = i + 1
endloop
set FrameConsoleUI = BlzGetFrameByName("ConsoleUI", 0)
set FrameGoldText = BlzGetFrameByName("ResourceBarGoldText", 0)
set FrameLumberText = BlzGetFrameByName("ResourceBarLumberText", 0)
set FrameFoodText = BlzGetFrameByName("ResourceBarSupplyText", 0)
set FrameUnitNameText = BlzGetFrameByName("SimpleNameValue", 0)
call RefreshResolution()
static if HIDE_CONSOLE_UI then
//call BlzHideOriginFrames(state)
call BlzEnableUIAutoPosition(false)
call BlzFrameClearAllPoints(FrameWorld)
call BlzFrameClearAllPoints(FrameConsoleUI)
// Fit viewport to screen
call BlzFrameSetAllPoints(FrameWorld, FrameGameUI)
call BlzFrameSetAbsPoint(FrameConsoleUI, FRAMEPOINT_TOPRIGHT, XCoordToDPI(0.0), YCoordToDPI(0.0))
// Set in-game message frame position
call BlzFrameClearAllPoints(FrameUnitMsg)
call BlzFrameSetAbsPoint(FrameUnitMsg, FRAMEPOINT_BOTTOMLEFT, XCoordToDPI(MESSAGE_FRAME_POS_X), YCoordToDPI(MESSAGE_FRAME_POS_Y))
// Set chat frame position
call BlzFrameSetAbsPoint(FrameChatMsg, FRAMEPOINT_BOTTOMLEFT, XCoordToDPI(CHAT_FRAME_POS_X), YCoordToDPI(CHAT_FRAME_POS_Y))
call BlzFrameClearAllPoints(FrameMinimap)
call BlzFrameSetAbsPoint(FrameMinimap, FRAMEPOINT_TOPRIGHT, XCoordToDPI(-999.0), YCoordToDPI(-999.0))
call BlzFrameClearAllPoints(FrameGoldText)
call BlzFrameSetAbsPoint(FrameGoldText, FRAMEPOINT_TOPRIGHT, XCoordToDPI(-999.0), YCoordToDPI(-999.0))
call BlzFrameClearAllPoints(FrameLumberText)
call BlzFrameSetAbsPoint(FrameLumberText, FRAMEPOINT_TOPRIGHT, XCoordToDPI(-999.0), YCoordToDPI(-999.0))
call BlzFrameClearAllPoints(FrameFoodText)
call BlzFrameSetAbsPoint(FrameFoodText, FRAMEPOINT_TOPRIGHT, XCoordToDPI(-999.0), YCoordToDPI(-999.0))
call BlzFrameClearAllPoints(FramePortrait)
call BlzFrameSetAbsPoint(FramePortrait, FRAMEPOINT_BOTTOMLEFT, XCoordToDPI(-999.0), YCoordToDPI(-999.0))
call BlzFrameClearAllPoints(FrameUberTooltip)
call BlzFrameSetAbsPoint(FrameUberTooltip, FRAMEPOINT_CENTER, XCoordToDPI(1075.0), YCoordToDPI(768.0/2.))
set i = 0
loop
exitwhen FrameCommandButton[i] == null
call BlzFrameClearAllPoints(FrameCommandButton[i])
// Get command buttons out of screen
call BlzFrameSetAbsPoint(FrameCommandButton[i], FRAMEPOINT_RIGHT, XCoordToDPI(-999.0), YCoordToDPI(-999.0))
set i = i + 1
endloop
endif
static if AUTOMATIC_ADJUSTMENT then
call TimerStart(CreateTimer(), RESOLUTION_CHECK_INTERVAL, true, function thistype.CheckResolution)
endif
endmethod
endmodule
struct UIUtils extends array
readonly static integer ResolutionWidth = 0
readonly static integer ResolutionHeight = 0
readonly static integer AspectWidth = 0
readonly static integer AspectHeight = 0
private static real RefAspectWorld = 5.0
private static real RefAspectWidth = 4.0
private static real RefAspectHeight = 3.0
private static real RefExtraWidth = 0.0
readonly static real MinFrameX = 0.0
readonly static real MaxFrameX = 0.0
readonly static real DPIMinX = 0.0
readonly static real DPIMaxX = 0.0
readonly static real DPIMinY = 0.0
readonly static real DPIMaxY = RefAspectHeight/RefAspectWorld
private static real PxToDPI = 0.0
readonly static framehandle FrameGameUI
readonly static framehandle FrameWorld
readonly static framehandle FrameHeroBar
readonly static framehandle array FrameHeroButton
readonly static framehandle array FrameHeroHPBar
readonly static framehandle array FrameHeroMPBar
readonly static framehandle array FrameHeroIndicator
readonly static framehandle array FrameItemButton
readonly static framehandle array FrameCommandButton
readonly static framehandle array FrameSystemButton
readonly static framehandle FramePortrait
readonly static framehandle FrameMinimap
readonly static framehandle array FrameMinimapButton
readonly static framehandle FrameTooltip
readonly static framehandle FrameUberTooltip
readonly static framehandle FrameChatMsg
readonly static framehandle FrameUnitMsg
readonly static framehandle FrameTopMsg
readonly static framehandle FrameConsoleUI
readonly static framehandle FrameGoldText
readonly static framehandle FrameLumberText
readonly static framehandle FrameFoodText
readonly static framehandle FrameUnitNameText
private static method CalcAspectRatio takes real w, real h, real aw returns integer
return R2I(aw*h/w+0.5)
endmethod
static method XCoordToDPI takes real x returns real
return x*PxToDPI/RefAspectWidth+DPIMinX
endmethod
static method YCoordToDPI takes real y returns real
return y*PxToDPI/RefAspectWidth
endmethod
static method SizeToDPI takes real r returns real
return r*PxToDPI/RefAspectWidth
endmethod
static method DPIToXCoord takes real dpi returns real
return (dpi-DPIMinX)*RefAspectWidth/PxToDPI
endmethod
static method DPIToYCoord takes real dpi returns real
return dpi*RefAspectWidth/PxToDPI
endmethod
static method DPIToSize takes real dpi returns real
return dpi*RefAspectWidth/PxToDPI
endmethod
static method RefreshResolution takes nothing returns nothing
local AllComponents node
set ResolutionWidth = BlzGetLocalClientWidth()
set ResolutionHeight = BlzGetLocalClientHeight()
set WidthFactor = ResolutionWidth/SCREEN_WIDTH
set HeightFactor = ResolutionHeight/SCREEN_HEIGHT
if CalcAspectRatio(ResolutionWidth, ResolutionHeight, 4) == 3 then
set PxToDPI = RefAspectWidth/(ResolutionWidth/1024.0*1280.0)
set AspectWidth = 4
set AspectHeight = 3
set RefExtraWidth = 0.0
elseif CalcAspectRatio(ResolutionWidth, ResolutionHeight, 16) == 9 then
set PxToDPI = RefAspectWidth/(ResolutionWidth/1360.0*1280.0)
set AspectWidth = 16
set AspectHeight = 9
set RefExtraWidth = 0.525
elseif CalcAspectRatio(ResolutionWidth, ResolutionHeight, 16) == 10 then
set PxToDPI = RefAspectWidth/(ResolutionWidth/1280.0*1280.0)
set AspectWidth = 16
set AspectHeight = 10
set RefExtraWidth = 0.4
endif
set MinFrameX = RefExtraWidth*320.0
set MaxFrameX = ResolutionWidth-MinFrameX
set DPIMinX = -(RefExtraWidth/RefAspectWidth)
set DPIMaxX = RefAspectWidth/RefAspectWorld-DPIMinX
set node = AllComponents.base.next
loop
exitwhen node.head or node == 0
if UIComponent(node).parent == UIComponent.Null then
set UIComponent(node).localScale = UIComponent(node).localScale
endif
set node = node.next
endloop
endmethod
static method CalcFrameSpacing takes UIComponent from, UIComponent to, boolean topdown returns real
local real size1
local real size2
local framepointtype anchor1 = from.anchorPoint
local framepointtype anchor2 = to.anchorPoint
if topdown then
set size1 = from.height
set size2 = to.height
if anchor1 == FRAMEPOINT_TOPLEFT or anchor1 == FRAMEPOINT_TOP or anchor1 == FRAMEPOINT_TOPRIGHT then
set size1 = 0.0
elseif anchor1 == FRAMEPOINT_LEFT or anchor1 == FRAMEPOINT_CENTER or anchor1 == FRAMEPOINT_RIGHT then
set size1 = size1*0.5
endif
if anchor2 == FRAMEPOINT_BOTTOMLEFT or anchor2 == FRAMEPOINT_BOTTOM or anchor2 == FRAMEPOINT_BOTTOMRIGHT then
set size2 = 0.0
elseif anchor2 == FRAMEPOINT_LEFT or anchor2 == FRAMEPOINT_CENTER or anchor2 == FRAMEPOINT_RIGHT then
set size2 = size2*0.5
endif
else
set size1 = from.width
set size2 = to.width
if anchor1 == FRAMEPOINT_TOPRIGHT or anchor1 == FRAMEPOINT_RIGHT or anchor1 == FRAMEPOINT_BOTTOMRIGHT then
set size1 = 0.0
elseif anchor1 == FRAMEPOINT_TOP or anchor1 == FRAMEPOINT_CENTER or anchor1 == FRAMEPOINT_BOTTOM then
set size1 = size1*0.5
endif
if anchor2 == FRAMEPOINT_TOPLEFT or anchor2 == FRAMEPOINT_LEFT or anchor2 == FRAMEPOINT_BOTTOMLEFT then
set size2 = 0.0
elseif anchor2 == FRAMEPOINT_TOP or anchor2 == FRAMEPOINT_CENTER or anchor2 == FRAMEPOINT_BOTTOM then
set size2 = size2*0.5
endif
endif
return size1+size2
endmethod
private static method CheckResolution takes nothing returns nothing
if BlzGetLocalClientWidth() != ResolutionWidth or BlzGetLocalClientHeight() != ResolutionHeight then
call RefreshResolution()
endif
endmethod
implement INIT
endstruct
struct UIComponent extends array
implement LinkedList
string name
boolean inheritScale
boolean inheritOpacity
boolean inheritVisibility
boolean inheritEnableState
boolean inheritPosition
boolean inheritLevel
boolean scalePosition
readonly framehandle frame
private framehandle textFrameH
private framehandle modelFrameH
private framehandle mainTextureH
private framehandle disabledTextureH
private framehandle pushedTextureH
private framehandle highlightTextureH
private framehandle backgroundTextureH
private framehandle borderTextureH
private framepointtype anchor
readonly string frameType
readonly real localX
readonly real localY
readonly real screenX
readonly real screenY
readonly real minValue
readonly real maxValue
readonly integer context
readonly boolean visibleSelf
readonly boolean enabledSelf
readonly integer localOpacity
private integer lvl
private real localSize
private real localWidth
private real localHeight
private real step
private thistype par
private thistype child
private thistype tips
private string mainTextureFile
private string disabledTextureFile
private string pushedTextureFile
private string highlightTextureFile
private string backgroundTextureFile
private string borderTextureFile
private string modelFile
private trigger anyEventTrigg
readonly static thistype Null = 0
readonly static thistype EnumChild = 0
readonly static thistype TriggerComponent = 0
readonly static string TYPE_TEXT = "UIUtilsText"
readonly static string TYPE_SIMPLE_TEXT = "UIUtilsSimpleText"
readonly static string TYPE_TEXTURE = "UIUtilsTexture"
readonly static string TYPE_SIMPLE_TEXTURE = "UIUtilsSimpleTexture"
readonly static string TYPE_BUTTON = "UIUtilsButton"
readonly static string TYPE_SIMPLE_BUTTON = "UIUtilsSimpleButton"
readonly static string TYPE_BAR = "UIUtilsBar"
readonly static string TYPE_H_SLIDER = "UIUtilsSliderH"
readonly static string TYPE_V_SLIDER = "UIUtilsSliderV"
private static trigger ExecTrigg = CreateTrigger()
private static gamecache GC
private static hashtable HT
private static method IsSimple takes string frameType, boolean isSimple returns boolean
return frameType == TYPE_SIMPLE_TEXT or frameType == TYPE_SIMPLE_TEXTURE or frameType == TYPE_BAR or isSimple and not (frameType == TYPE_TEXT or frameType == TYPE_TEXTURE or frameType == TYPE_BUTTON or frameType == TYPE_H_SLIDER or frameType == TYPE_V_SLIDER)
endmethod
private static method GetTriggerComponent takes nothing returns boolean
set TriggerComponent = LoadInteger(HT, GetHandleId(BlzGetTriggerFrame()), 0)
return false
endmethod
method operator onAnyEvent= takes code func returns triggercondition
local integer i
if .anyEventTrigg == null then
set .anyEventTrigg = CreateTrigger()
set i = 1
loop
exitwhen i > 16
call BlzTriggerRegisterFrameEvent(.anyEventTrigg, .frame, ConvertFrameEventType(i))
set i = i + 1
endloop
call TriggerAddCondition(.anyEventTrigg, Condition(function thistype.GetTriggerComponent))
endif
return TriggerAddCondition(.anyEventTrigg, Condition(func))
endmethod
method operator anchorPoint= takes framepointtype point returns nothing
set .anchor = point
call BlzFrameClearAllPoints(.frame)
call move(.localX, .localY)
endmethod
method operator anchorPoint takes nothing returns framepointtype
return .anchor
endmethod
method operator parent= takes thistype comp returns nothing
if comp != Null then
if .par != comp then
call .removeNode()
endif
call comp.child.insertNode(this)
endif
static if not PERSISTENT_CHILD_PROPERTIES then
if .par != Null then
set .localScale = .localScale*.par.localScale
endif
set .localX = .screenX - comp.screenX
set .localY = .screenY - comp.screenY
endif
// Refresh props
set .par = comp
set .localScale = .localScale
set .visible = .visibleSelf
set .enabled = .enabledSelf
set .opacity = .localOpacity
set .level = .lvl
endmethod
method operator parent takes nothing returns thistype
return .par
endmethod
method operator text= takes string str returns nothing
call BlzFrameSetText(.textFrameH, str)
endmethod
method operator text takes nothing returns string
return BlzFrameGetText(.textFrameH)
endmethod
method operator maxLength= takes integer len returns nothing
call BlzFrameSetTextSizeLimit(.textFrameH, len)
endmethod
method operator maxLength takes nothing returns integer
return BlzFrameGetTextSizeLimit(.textFrameH)
endmethod
method operator textColor= takes integer color returns nothing
call BlzFrameSetTextColor(.textFrameH, color)
endmethod
method operator texture= takes string filePath returns nothing
set .mainTextureFile = filePath
call BlzFrameSetTexture(.mainTextureH, filePath, 0, true)
if StringLength(.disabledTextureFile) == 0 then
set .disabledTexture = filePath
endif
if StringLength(.pushedTextureFile) == 0 then
set .pushedTexture = filePath
endif
endmethod
method operator texture takes nothing returns string
return .mainTextureFile
endmethod
method operator disabledTexture= takes string filePath returns nothing
set .disabledTextureFile = filePath
call BlzFrameSetTexture(.disabledTextureH, filePath, 0, true)
endmethod
method operator disabledTexture takes nothing returns string
return .disabledTextureFile
endmethod
method operator highlightTexture= takes string filePath returns nothing
set .highlightTextureFile = filePath
call BlzFrameSetTexture(.highlightTextureH, filePath, 0, true)
endmethod
method operator highlightTexture takes nothing returns string
return .highlightTextureFile
endmethod
method operator pushedTexture= takes string filePath returns nothing
set .pushedTextureFile = filePath
call BlzFrameSetTexture(.pushedTextureH, filePath, 0, true)
endmethod
method operator pushedTexture takes nothing returns string
return .pushedTextureFile
endmethod
method operator backgroundTexture= takes string filePath returns nothing
set .backgroundTextureFile = filePath
call BlzFrameSetTexture(.backgroundTextureH, filePath, 0, true)
endmethod
method operator backgroundTexture takes nothing returns string
return .backgroundTextureFile
endmethod
method operator borderTexture= takes string filePath returns nothing
set .borderTextureFile = filePath
call BlzFrameSetTexture(.borderTextureH, filePath, 0, true)
endmethod
method operator borderTexture takes nothing returns string
return .borderTextureFile
endmethod
method operator model= takes string filePath returns nothing
set .modelFile = filePath
call BlzFrameSetModel(.modelFrameH, filePath, 0)
endmethod
method operator model takes nothing returns string
return .modelFile
endmethod
method operator vertexColor= takes integer color returns nothing
call BlzFrameSetVertexColor(.modelFrameH, color)
endmethod
method operator value= takes real r returns nothing
call BlzFrameSetValue(.frame, r)
endmethod
method operator value takes nothing returns real
return BlzFrameGetValue(.frame)
endmethod
method operator stepSize= takes real r returns nothing
set .step = RMaxBJ(r, 0.0001)
call BlzFrameSetStepSize(.frame, .step)
endmethod
method operator stepSize takes nothing returns real
return .step
endmethod
method operator localScale= takes real r returns nothing
local thistype node = .child.next
set .localSize = RMaxBJ(r, 0.0001)
call setSize(.width, .height)
call move(.localX, .localY)
loop
exitwhen node.head or node == 0
set node.localScale = node.localScale
set node = node.next
endloop
endmethod
method operator localScale takes nothing returns real
return .localSize
endmethod
method operator scale takes nothing returns real
if .parent == Null or not .inheritScale then
return .localScale
else
return .localScale * .parent.scale
endif
endmethod
method operator opacity= takes integer amount returns nothing
local thistype node = .child.next
set .localOpacity = amount
call BlzFrameSetAlpha(.frame, .opacity)
loop
exitwhen node.head or node == 0
set node.opacity = node.localOpacity
set node = node.next
endloop
endmethod
method operator opacity takes nothing returns integer
if .parent == Null or not .inheritOpacity then
return .localOpacity
else
return R2I(I2R(.localOpacity) * I2R(.parent.opacity)/255.)
endif
endmethod
method operator level= takes integer level returns nothing
local thistype node = .child.next
set .lvl = level
call BlzFrameSetLevel(.frame, .trueLevel)
loop
exitwhen node.head or node == 0
set node.level = node.lvl
set node = node.next
endloop
endmethod
method operator level takes nothing returns integer
return .lvl
endmethod
method operator trueLevel takes nothing returns integer
if .parent == Null or not .inheritLevel then
return .lvl
else
return .lvl + .parent.level
endif
endmethod
method operator tooltips= takes thistype comp returns nothing
set .tips = comp
call BlzFrameSetTooltip(.frame, comp.frame)
endmethod
method operator tooltips takes nothing returns thistype
return .tips
endmethod
method operator visible= takes boolean state returns nothing
local thistype node = .child.next
set .visibleSelf = state
call BlzFrameSetVisible(.frame, .visible)
loop
exitwhen node.head or node == 0
set node.visible = node.visibleSelf
/*if node.visible then
call BJDebugMsg(node.name + " visible")
else
call BJDebugMsg(node.name + " not visible")
endif*/
set node = node.next
endloop
endmethod
method operator visible takes nothing returns boolean
if .parent == Null or not .inheritVisibility then
return .visibleSelf
else
return .visibleSelf and .parent.visible
endif
endmethod
method operator enabled= takes boolean state returns nothing
local thistype node = .child.next
set .enabledSelf = state
call BlzFrameSetEnable(.frame, .enabled)
loop
exitwhen node.head or node == 0
set node.enabled = node.enabledSelf
set node = node.next
endloop
endmethod
method operator enabled takes nothing returns boolean
if .parent == Null or not .inheritEnableState then
return .enabledSelf
else
return .enabledSelf and .parent.enabled
endif
endmethod
method operator width takes nothing returns real
return .localWidth
endmethod
method operator height takes nothing returns real
return .localHeight
endmethod
method setSize takes real width, real height returns nothing
set .localWidth = RMaxBJ(width, 0)
set .localHeight = RMaxBJ(height, 0)
call BlzFrameSetSize(frame, UIUtils.SizeToDPI(.localWidth*.scale*WidthFactor), UIUtils.SizeToDPI(.localHeight*.scale*WidthFactor))
endmethod
method move takes real x, real y returns nothing
local thistype node = .child.next
set .localX = x
set .localY = y
if .parent == Null or not .inheritPosition then
set .screenX = x
set .screenY = y
elseif .scalePosition then
set .screenX = .parent.screenX+.localX*.parent.scale
set .screenY = .parent.screenY+.localY*.parent.scale
else
set .screenX = .parent.screenX+.localX
set .screenY = .parent.screenY+.localY
endif
call BlzFrameSetAbsPoint(.frame, .anchor, UIUtils.XCoordToDPI(.screenX*WidthFactor), UIUtils.YCoordToDPI(.screenY*HeightFactor))
loop
exitwhen node.head or node == 0
call node.move(node.localX, node.localY)
set node = node.next
endloop
endmethod
method moveEx takes real x, real y returns nothing
if .parent == Null or not .inheritPosition then
call move(x, y)
else
call move((x-.parent.screenX)/.parent.localScale, (y-.parent.screenY)/.parent.localScale)
endif
endmethod
method relate takes thistype relative, real x, real y returns nothing
if .parent == Null then
call move(relative.screenX+x, relative.screenY+y)
else
call moveEx(relative.screenX+x, relative.screenY+y)
endif
endmethod
method click takes nothing returns nothing
call BlzFrameClick(.frame)
endmethod
method cageMouse takes boolean state returns nothing
call BlzFrameCageMouse(.frame, state)
endmethod
method setFocus takes boolean state returns nothing
call BlzFrameSetFocus(.frame, state)
endmethod
method setSpriteAnimate takes integer primaryProp, integer flags returns nothing
call BlzFrameSetSpriteAnimate(.frame, primaryProp, flags)
endmethod
method setMinMaxValue takes real min, real max returns nothing
set .minValue = min
set .maxValue = max
call BlzFrameSetMinMaxValue(.frame, min, max)
endmethod
method setFont takes string fontPath, real height, integer flags returns nothing
call BlzFrameSetFont(.textFrameH, fontPath, height, flags)
endmethod
method setTextAlignment takes textaligntype vertical, textaligntype horizontal returns nothing
call BlzFrameSetTextAlignment(.textFrameH, vertical, horizontal)
endmethod
method getSubFrame takes string name returns framehandle
return BlzGetFrameByName(name, .context)
endmethod
method forEachChild takes code func returns nothing
local thistype node = .child.next
call TriggerAddAction(ExecTrigg, func)
loop
exitwhen node.head or node == 0
set EnumChild = node
call TriggerExecute(ExecTrigg)
set node = node.next
endloop
call TriggerClearActions(ExecTrigg)
endmethod
method destroy takes nothing returns nothing
local thistype node = .child.next
loop
exitwhen node.head or node == 0
call node.destroy()
set node = node.next
endloop
call BlzDestroyFrame(.frame)
call DestroyTrigger(.anyEventTrigg)
call StoreInteger(GC, name, I2S(.context), GetStoredInteger(GC, name, "0"))
call StoreInteger(GC, name, "0", .context)
call AllComponents.remove(this)
call .child.flushNode()
call removeNode()
call deallocate()
set .anyEventTrigg = null
set .mainTextureH = null
set .disabledTextureH = null
set .highlightTextureH = null
set .pushedTextureH = null
set .backgroundTextureH = null
set .borderTextureH = null
set .textFrameH = null
set .modelFrameH = null
set .frame = null
set .name = null
set .frameType = null
set .par = Null
set .child = 0
endmethod
static method create takes boolean isSimple, string frameType, thistype par, real x, real y, integer level returns thistype
local thistype this = allocate()
local integer tempInt
set .context = GetStoredInteger(GC, frameType, "0")
set tempInt = GetStoredInteger(GC, frameType, I2S(context))
if tempInt == 0 then
call StoreInteger(GC, frameType, "0", context+1)
else
call StoreInteger(GC, frameType, "0", tempInt)
endif
set .parent = par
set .child = createNode()
if IsSimple(frameType, isSimple) then
set .frame = BlzCreateSimpleFrame(frameType, UIUtils.FrameGameUI, .context)
else
set .frame = BlzCreateFrame(frameType, UIUtils.FrameGameUI, 0, .context)
endif
set .mainTextureH = getSubFrame(frameType + "Texture")
set .disabledTextureH = getSubFrame(frameType + "Disabled")
set .highlightTextureH = getSubFrame(frameType + "Highlight")
set .pushedTextureH = getSubFrame(frameType + "Pushed")
set .backgroundTextureH = getSubFrame(frameType + "Background")
set .borderTextureH = getSubFrame(frameType + "Border")
set .textFrameH = getSubFrame(frameType + "Text")
set .modelFrameH = getSubFrame(frameType + "Model")
if .mainTextureH == null then
set .mainTextureH = .frame
endif
if .textFrameH == null then
set .textFrameH = .frame
endif
set .inheritScale = true
set .inheritOpacity = true
set .inheritVisibility = true
set .inheritEnableState = true
set .inheritPosition = true
set .inheritLevel = true
set .scalePosition = true
set .localWidth = UIUtils.DPIToSize(BlzFrameGetWidth(.frame))
set .localHeight = UIUtils.DPIToSize(BlzFrameGetHeight(.frame))
set .anchor = FRAMEPOINT_BOTTOMLEFT
set .frameType = frameType
set .name = frameType + I2S(.context)
set .level = level
set .visibleSelf = true
set .enabledSelf = true
set .value = 0.0
set .localScale = 1.0
set .opacity = 255
set .mainTextureFile = ""
set .disabledTextureFile = ""
set .pushedTextureFile = ""
set .highlightTextureFile = ""
set .backgroundTextureFile = ""
set .borderTextureFile = ""
set .modelFile = ""
call move(x, y)
call setMinMaxValue(0.0, 1.0)
call AllComponents.add(this)
call SaveInteger(HT, GetHandleId(.frame), 0, this)
return this
endmethod
private static method onInit takes nothing returns nothing
set HT = InitHashtable()
set GC = InitGameCache("UIUtils.w3v")
call BlzLoadTOCFile("war3mapimported\\UIUtils.toc")
call BlzLoadTOCFile("war3mapimported\\UIEmberCraft.toc")
endmethod
endstruct
endlibrary
library BUSChannel
////////////////////////////////////////////////////////////////////
// Boss Ultimate Spellpack Channel V1.02 //
// Author: Tank-Commander //
// Purpose: Handles spell channelling within the spellpack //
// Used for: Soul Release, Scathe, Sheer Force, Energy Spike //
// //
// Notes: //
// - Read the readme before you try modifying the config //
// - Use the "Helpful files" to help you import the system //
// //
// Credits: //
// - (Dummy.mdl) Vexorian //
// //
// If you have used this spellpack in your map, you are required //
// to give credits to Tank-Commander for the creation of it //
// If you would like to use snippets of code from this for //
// whatever, getting permission and crediting the source/linking //
// would be much appreciated. //
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// README: //
// Before modifying this spell a few things need to be //
// understood and read, this is one of those things, while //
// most modification can be considered intuitive, it still //
// helps to read through these intstructions, as they will //
// inform you about how to configure this spell to your //
// desire. //
//----------------------------------------------------------------//
// Initial importing: The variable creator trigger can be //
// imported first and if you have the correct settings (file, //
// preferences, General, automatically create unknown variables //
// checked, then when you paste in the variable creator it //
// will automatically give you all the variables you need for //
// this spell //
// //
// While the remaining object editor based data is not required //
// to function (provided they're replaced with equivelents) //
// it's recommended that they are also imported, if their data //
// value are not the same as listed in the configuration, those //
// configurables will need to be changed to work correctly //
//----------------------------------------------------------------//
// CONFIGURABLE INFORMATION/HELP: //
// //
// - Viewing data values: To see data values in the editor you //
// need to press Ctrl + D, to shift back to normal viewing //
// press it again //
// //
// - Effects: Pathnames for effects used in the spells should //
// have two "\"s throughout or the effect will not work (the //
// WE progress bar will not go away when saving, however if //
// fixed afterwards the save will still work, but the progress //
// bar will still remain until the WE is closed) //
// e.g. "units\\human\\Footman\\Footman" //
// //
// - Effect Scaling: Some effects have scale values below them //
// the scale determines the size of the effect and is expressed //
// as a real percentage (1.00 = 100%) //
// //
// - Removing Effects: to remove an effect you don't want from //
// the ability, set the model path to that of Dummy.mdl //
// //
// - Timer: Some configurables have PerSecond values, the code //
// automatically accounts for changes to the timer as to //
// maintain consistency with what the user has chosen //
// All times in the system are expressions of seconds //
// //
//----------------------------------------------------------------//
// TimerSpeed: This is the amount of time in seconds between //
// each iteration of the channel loop function //
constant function BUSCR_TimerSpeed takes nothing returns real
return 0.031250000
endfunction
//----------------------------------------------------------------//
// DummyId: This is the raw data value of the dummy unit used //
// for creating the channeling effects it's advised this unit //
// uses Dummy.mdl for optimal usage, have death type set to //
// "can't raise does not decay" and a death time long enough //
// to play all effects (about 5.00 should be long enough) for //
// all effects) //
constant function BUSCR_DummyId takes nothing returns integer
return 'e000'
endfunction
//----------------------------------------------------------------//
// AttachmentPoint: This is the location on the dummy unit where //
// effects will be placed //
constant function BUSCR_AttachmentPoint takes nothing returns string
return "origin"
endfunction
//----------------------------------------------------------------//
// GroundMinAngle: This is the minimum angle off the floor that //
// all effects are made when the caster is a ground unit //
constant function BUSCR_GroundMinAngle takes nothing returns real
return 0.1
endfunction
//----------------------------------------------------------------//
// DummyPlayer: This is the player that is given ownership of //
// all the dummy units used by the system //
constant function BUSCR_DummyPlayer takes nothing returns player
return Player(14)
endfunction
//----------------------------------------------------------------//
// END OF CONFIGURATION //
//----------------------------------------------------------------//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// RegisterChannel: This is the function used to register a new //
// type of channel (calling this function after setting up the //
// new channel will register it and allowit to be used) //
////////////////////////////////////////////////////////////////////
function BUS_RegisterChannel takes integer target returns nothing
local integer Id
if (target == 0) then
set udg_BUSCR_Counter = udg_BUSCR_Counter + 1
set Id = udg_BUSCR_Counter
else
set Id = target
endif
set udg_BUSCR_Name[Id] = StringCase(udg_BUSCR_Name[0], true)
set udg_BUSCR_Effect[Id] = udg_BUSCR_Effect[0]
set udg_BUSCR_MinAOE[Id] = udg_BUSCR_MinAOE[0]
set udg_BUSCR_MaxAOE[Id] = udg_BUSCR_MaxAOE[0]
set udg_BUSCR_AbsorbAOE[Id] = udg_BUSCR_AbsorbAOE[0]
set udg_BUSCR_MinSize[Id] = udg_BUSCR_MinSize[0]
set udg_BUSCR_MaxSize[Id] = udg_BUSCR_MaxSize[0]
set udg_BUSCR_SpawnRate[Id] = udg_BUSCR_SpawnRate[0]
set udg_BUSCR_SpawnCount[Id] = udg_BUSCR_SpawnCount[0]
set udg_BUSCR_Power[Id] = udg_BUSCR_Power[0]
set udg_BUSCR_HueRed[Id] = udg_BUSCR_HueRed[0]
set udg_BUSCR_HueGreen[Id] = udg_BUSCR_HueGreen[0]
set udg_BUSCR_HueBlue[Id] = udg_BUSCR_HueBlue[0]
set udg_BUSCR_HueAlpha[Id] = udg_BUSCR_HueAlpha[0]
set udg_BUSCR_HueSpeed[Id] = udg_BUSCR_HueSpeed[0]
endfunction
////////////////////////////////////////////////////////////////////
// GetChannelByName: This returns the Id number of the channel //
// which shares the name with the passed parameter, it can be //
// used to consistently refer to a channel without knowing the //
// order by which it was declared (allowing dynamic introduction //
// of channels //
////////////////////////////////////////////////////////////////////
function BUS_GetChannelByName takes string name returns integer
local integer iLoop = 0
set name = StringCase(name, true)
loop
set iLoop = iLoop + 1
exitwhen iLoop > udg_BUSCR_Counter
if (name == udg_BUSCR_Name[iLoop]) then
return iLoop
endif
endloop
return 0
endfunction
////////////////////////////////////////////////////////////////////
// GetZ: Used to get the Z height of a given location, used to //
// make sure that entities going over cliffs aren't incorrectly //
// moved/placed on the z plane //
////////////////////////////////////////////////////////////////////
function BUS_GetZ takes real x, real y returns real
call MoveLocation(udg_BUS_Loc, x, y)
return GetLocationZ(udg_BUS_Loc)
endfunction
////////////////////////////////////////////////////////////////////
// Function used to prevent two casts of the same channel being //
// done simultaneously //
////////////////////////////////////////////////////////////////////
function BUS_CheckChannel takes unit u returns integer
local integer Node = 0
loop
set Node = udg_BUSC_NextNode[Node]
exitwhen (udg_BUSC_Unit[Node] == u) or (Node == 0)
endloop
return Node
endfunction
////////////////////////////////////////////////////////////////////
// ChannelLoop: The function used to control the channel this //
// includes creating entities and moving them toward the caster //
// checking if they are still casting the channel and activating //
// the channel effects when it is completed //
////////////////////////////////////////////////////////////////////
function BUS_ChannelLoop takes nothing returns nothing
local integer Node = 0
local integer TempNode = 0
local integer iLoop = 0
local integer EffectCount = 0
local real x
local real x2
local real x3
local real y
local real y2
local real y3
local real z
local real z2
local real dy
local real dx
local real Angle
local real Angle2
local real Distance
local real TempReal
loop
exitwhen TempNode == 0
set TempNode = udg_BUSC_PNextNode[TempNode]
endloop
loop
set Node = udg_BUSC_NextNode[Node]
exitwhen Node == 0
set x = GetUnitX(udg_BUSC_Unit[Node])
set y = GetUnitY(udg_BUSC_Unit[Node])
set z = BUS_GetZ(x, y) + GetUnitFlyHeight(udg_BUSC_Unit[Node]) + 60
set TempNode = 0
if (udg_BUSC_CDuration[Node] > 0) then
set udg_BUSC_CDuration[Node] = udg_BUSC_CDuration[Node] - BUSCR_TimerSpeed()
if (udg_BUSC_CDelay[Node] <= BUSCR_TimerSpeed()) then
set udg_BUSC_CDelay[Node] = udg_BUSC_Delay[Node]
set iLoop = 0
loop
set iLoop = iLoop + 1
exitwhen iLoop > udg_BUSCR_SpawnCount[udg_BUSC_ChannelId[Node]]
if (udg_BUSC_PRecyclableNodes == 0) then
set udg_BUSC_PNodeNumber = udg_BUSC_PNodeNumber + 1
set TempNode = udg_BUSC_PNodeNumber
else
set udg_BUSC_PRecyclableNodes = udg_BUSC_PRecyclableNodes - 1
set TempNode = udg_BUSC_PRecycleNodes[udg_BUSC_PRecyclableNodes]
endif
set udg_BUSC_PNextNode[TempNode] = 0
set udg_BUSC_PNextNode[udg_BUSC_PPrevNode[0]] = TempNode
set udg_BUSC_PPrevNode[TempNode] = udg_BUSC_PPrevNode[0]
set udg_BUSC_PPrevNode[0] = TempNode
set Angle = GetRandomReal(0, bj_PI * 2)
if (IsUnitType(udg_BUSC_Unit[Node], UNIT_TYPE_GROUND)) then
set Angle2 = GetRandomReal(BUSCR_GroundMinAngle(), bj_PI - BUSCR_GroundMinAngle())
else
set Angle2 = GetRandomReal(-bj_PI, bj_PI)
endif
set TempReal = GetRandomReal(udg_BUSCR_MinAOE[udg_BUSC_ChannelId[Node]], udg_BUSCR_MaxAOE[udg_BUSC_ChannelId[Node]])
set Distance = Cos(Angle2) * TempReal
if Distance < 0 then
set Distance = Distance * -1
endif
set x2 = x + Distance * Cos(Angle)
set y2 = y + Distance * Sin(Angle)
set z2 = Sin(Angle2) * TempReal + z
set TempReal = GetRandomReal(udg_BUSCR_MinSize[udg_BUSC_ChannelId[Node]], udg_BUSCR_MaxSize[udg_BUSC_ChannelId[Node]])
set udg_BUSC_PCaster[TempNode] = udg_BUSC_Unit[Node]
set udg_BUSC_PXVelocity[TempNode] = 0
set udg_BUSC_PYVelocity[TempNode] = 0
set udg_BUSC_PZVelocity[TempNode] = 0
set udg_BUSC_PCurrentZ[TempNode] = z2
set udg_BUSC_PUnit[TempNode] = CreateUnit(BUSCR_DummyPlayer(), BUSCR_DummyId(), x2, y2, Angle * bj_RADTODEG + 180)
if UnitAddAbility(udg_BUSC_PUnit[TempNode], 'Amrf') and UnitRemoveAbility(udg_BUSC_PUnit[TempNode], 'Amrf') then
endif
set udg_BUSC_PCurrentEffect[TempNode] = AddSpecialEffectTarget(udg_BUSCR_Effect[udg_BUSC_ChannelId[Node]], udg_BUSC_PUnit[TempNode], BUSCR_AttachmentPoint())
call SetUnitScale(udg_BUSC_PUnit[TempNode], TempReal, 0.00, 0.00)
call SetUnitFlyHeight(udg_BUSC_PUnit[TempNode], udg_BUSC_PCurrentZ[TempNode] - BUS_GetZ(x2,y2), 0.00)
endloop
else
set udg_BUSC_CDelay[Node] = udg_BUSC_CDelay[Node] - BUSCR_TimerSpeed()
endif
if (udg_BUSC_HueChange[Node]) then
set udg_BUSC_CHueRed[Node] = udg_BUSC_CHueRed[Node] + udg_BUSC_HueChangeRed[Node]
set udg_BUSC_CHueGreen[Node] = udg_BUSC_CHueGreen[Node] + udg_BUSC_HueChangeGreen[Node]
set udg_BUSC_CHueBlue[Node] = udg_BUSC_CHueBlue[Node] + udg_BUSC_HueChangeBlue[Node]
set udg_BUSC_CHueAlpha[Node] = udg_BUSC_CHueAlpha[Node] + udg_BUSC_HueChangeAlpha[Node]
call SetUnitVertexColor(udg_BUSC_Unit[Node], udg_BUSC_CHueRed[Node], udg_BUSC_CHueGreen[Node], udg_BUSC_CHueBlue[Node], udg_BUSC_CHueAlpha[Node])
if (udg_BUSC_CChangeHueDelay[Node] < 0) then
set udg_BUSC_CChangeHueDelay[Node] = udg_BUSCR_HueSpeed[udg_BUSC_ChannelId[Node]]
set udg_BUSC_HueChangeRed[Node] = udg_BUSC_HueChangeRed[Node] * -1
set udg_BUSC_HueChangeGreen[Node] = udg_BUSC_HueChangeGreen[Node] * -1
set udg_BUSC_HueChangeBlue[Node] = udg_BUSC_HueChangeBlue[Node] * -1
set udg_BUSC_HueChangeAlpha[Node] = udg_BUSC_HueChangeAlpha[Node] * - 1
else
set udg_BUSC_CChangeHueDelay[Node] = udg_BUSC_CChangeHueDelay[Node] - BUSCR_TimerSpeed()
endif
endif
elseif (udg_BUSC_Running[Node]) then
set udg_BUS_Unit = udg_BUSC_Unit[Node]
set udg_BUS_Target = udg_BUSC_Target[Node]
set udg_BUS_X = udg_BUSC_TargetX[Node]
set udg_BUS_Y = udg_BUSC_TargetY[Node]
set udg_BUSC_Running[Node] = false
set udg_BUSC_Event = 0
set udg_BUSC_Event = udg_BUSC_Ability[Node]
endif
set TempNode = 0
set EffectCount = 0
loop
set TempNode = udg_BUSC_PNextNode[TempNode]
exitwhen TempNode == 0
if (udg_BUSC_PCaster[TempNode] == udg_BUSC_Unit[Node]) then
set x2 = GetUnitX(udg_BUSC_PUnit[TempNode])
set y2 = GetUnitY(udg_BUSC_PUnit[TempNode])
set z2 = BUS_GetZ(x2, y2) + GetUnitFlyHeight(udg_BUSC_PUnit[TempNode])
set Distance = SquareRoot((x - x2) * (x - x2) + (y - y2) * (y - y2) + (z - z2) * (z - z2))
if ((Distance < udg_BUSCR_AbsorbAOE[udg_BUSC_ChannelId[Node]]) or (not(GetUnitCurrentOrder(udg_BUSC_Unit[Node]) == udg_BUSC_Order[Node]) or udg_BUSC_Cancel[Node])) then
call DestroyEffect(udg_BUSC_PCurrentEffect[TempNode])
call UnitApplyTimedLife(udg_BUSC_PUnit[TempNode], 'BTLF', 5)
set udg_BUSC_PRecycleNodes[udg_BUSC_PRecyclableNodes] = TempNode
set udg_BUSC_PRecyclableNodes = udg_BUSC_PRecyclableNodes + 1
set udg_BUSC_PNextNode[udg_BUSC_PPrevNode[TempNode]] = udg_BUSC_PNextNode[TempNode]
set udg_BUSC_PPrevNode[udg_BUSC_PNextNode[TempNode]] = udg_BUSC_PPrevNode[TempNode]
if (udg_BUSC_NextNode[0] + udg_BUSC_NextNode[0] == 0) then
call PauseTimer(udg_BUSC_Timer)
endif
else
set EffectCount = EffectCount + 1
set dy = y - y2
set dx = x - x2
set Angle = Atan2(dy, dx)
set Angle2 = Atan2(z - z2, SquareRoot((dx * dx) + (dy * dy)))
set TempReal = udg_BUSCR_Power[udg_BUSC_ChannelId[Node]] / Distance
set udg_BUSC_PZVelocity[TempNode] = udg_BUSC_PZVelocity[TempNode] + TempReal * Sin(Angle2)
set udg_BUSC_PXVelocity[TempNode] = udg_BUSC_PXVelocity[TempNode] + TempReal * Cos(Angle) * Cos(Angle2)
set udg_BUSC_PYVelocity[TempNode] = udg_BUSC_PYVelocity[TempNode] + TempReal * Sin(Angle) * Cos(Angle2)
set udg_BUSC_PCurrentZ[TempNode] = udg_BUSC_PCurrentZ[TempNode] + udg_BUSC_PZVelocity[TempNode]
set x3 = x2 + udg_BUSC_PXVelocity[TempNode]
set y3 = y2 + udg_BUSC_PYVelocity[TempNode]
if ((udg_BUS_MapMinX <= x3) and (x3 <= udg_BUS_MapMaxX) and (udg_BUS_MapMinY <= y3)and (y3 <= udg_BUS_MapMaxY)) then
call SetUnitX(udg_BUSC_PUnit[TempNode], x3)
call SetUnitY(udg_BUSC_PUnit[TempNode], y3)
endif
call SetUnitFlyHeight(udg_BUSC_PUnit[TempNode], udg_BUSC_PCurrentZ[TempNode] - BUS_GetZ(x3,y3), 0.00)
call SetUnitAnimationByIndex(udg_BUSC_PUnit[TempNode], R2I(Atan2(udg_BUSC_PZVelocity[TempNode], SquareRoot((udg_BUSC_PXVelocity[TempNode] * udg_BUSC_PXVelocity[TempNode]) + (udg_BUSC_PYVelocity[TempNode] * udg_BUSC_PYVelocity[TempNode]))) * bj_RADTODEG + 0.5) + 90)
endif
endif
endloop
if (EffectCount == 0) and ((udg_BUSC_CDuration[Node] <= 0) or not(GetUnitCurrentOrder(udg_BUSC_Unit[Node]) == udg_BUSC_Order[Node] or udg_BUSC_Cancel[Node])) then
if (udg_BUSC_HueChange[Node]) then
call SetUnitVertexColor(udg_BUSC_Unit[Node], 255, 255, 255, 255)
endif
set udg_BUSC_RecycleNodes[udg_BUSC_RecyclableNodes] = Node
set udg_BUSC_RecyclableNodes = udg_BUSC_RecyclableNodes + 1
set udg_BUSC_NextNode[udg_BUSC_PrevNode[Node]] = udg_BUSC_NextNode[Node]
set udg_BUSC_PrevNode[udg_BUSC_NextNode[Node]] = udg_BUSC_PrevNode[Node]
if (udg_BUSC_NextNode[0] + udg_BUSC_NextNode[0] == 0) then
call PauseTimer(udg_BUSC_Timer)
endif
endif
endloop
endfunction
////////////////////////////////////////////////////////////////////
// StartChannel: Used to start a channeling effect on a spell //
// Calling this function, passing the ability Id, the unit, any //
// target unit or point, the duration of the channel and the //
// duration of the channel (as well as if the channel will //
// include a hue change) //
////////////////////////////////////////////////////////////////////
function BUS_StartChannel takes integer Id, unit u, unit Target, real x, real y, real Duration, real evt, boolean Hue returns nothing
local integer Node = 0
local real TempReal = 0
set udg_BUSC_Cancel[BUS_CheckChannel(u)] = true
if (udg_BUSC_RecyclableNodes == 0) then
set udg_BUSC_NodeNumber = udg_BUSC_NodeNumber + 1
set Node = udg_BUSC_NodeNumber
else
set udg_BUSC_RecyclableNodes = udg_BUSC_RecyclableNodes - 1
set Node = udg_BUSC_RecycleNodes[udg_BUSC_RecyclableNodes]
endif
set udg_BUSC_NextNode[Node] = 0
set udg_BUSC_NextNode[udg_BUSC_PrevNode[0]] = Node
set udg_BUSC_PrevNode[Node] = udg_BUSC_PrevNode[0]
set udg_BUSC_PrevNode[0] = Node
set udg_BUSC_ChannelId[Node] = Id
set udg_BUSC_Ability[Node] = evt
set udg_BUSC_Unit[Node] = u
set udg_BUSC_Target[Node] = Target
set udg_BUSC_TargetX[Node] = x
set udg_BUSC_TargetY[Node] = y
set udg_BUSC_Order[Node] = GetUnitCurrentOrder(u)
set udg_BUSC_Cancel[Node] = false
set udg_BUSC_Running[Node] = true
set udg_BUSC_CDuration[Node] = Duration
set udg_BUSC_Delay[Node] = 1. / udg_BUSCR_SpawnRate[Id]
set udg_BUSC_CDelay[Node] = udg_BUSC_Delay[Node]
set udg_BUSC_HueChange[Node] = Hue
set udg_BUSC_CHueRed[Node] = 255
set udg_BUSC_CHueGreen[Node] = 255
set udg_BUSC_CHueBlue[Node] = 255
set udg_BUSC_CHueAlpha[Node] = 255
set TempReal = (1 / udg_BUSCR_HueSpeed[Id]) * BUSCR_TimerSpeed()
set udg_BUSC_HueChangeRed[Node] = R2I((udg_BUSCR_HueRed[Id] - udg_BUSC_CHueRed[Node]) * TempReal)
set udg_BUSC_HueChangeGreen[Node] = R2I((udg_BUSCR_HueGreen[Id] - udg_BUSC_CHueGreen[Node]) * TempReal)
set udg_BUSC_HueChangeBlue[Node] = R2I((udg_BUSCR_HueBlue[Id] - udg_BUSC_CHueBlue[Node]) * TempReal)
set udg_BUSC_HueChangeAlpha[Node] = R2I((udg_BUSCR_HueAlpha[Id] - udg_BUSC_CHueAlpha[Node]) * TempReal)
set udg_BUSC_CChangeHueDelay[Node] = udg_BUSCR_HueSpeed[Id]
if (udg_BUSC_PrevNode[Node] == 0) then
call TimerStart(udg_BUSC_Timer, BUSCR_TimerSpeed(), true, function BUS_ChannelLoop)
endif
endfunction
////////////////////////////////////////////////////////////////////
// InitTrig BUS Channel: Sets up the map bounds and the location //
// used for getting Z locations and the timer used to run the //
// loop //
////////////////////////////////////////////////////////////////////
function InitTrig_BUS_Channel takes nothing returns nothing
set udg_BUS_Loc = Location(0,0)
set udg_BUSC_Timer = CreateTimer()
set udg_BUS_MapMaxX = GetRectMaxX(bj_mapInitialPlayableArea)
set udg_BUS_MapMinX = GetRectMinX(bj_mapInitialPlayableArea)
set udg_BUS_MapMaxY = GetRectMaxY(bj_mapInitialPlayableArea)
set udg_BUS_MapMinY = GetRectMinY(bj_mapInitialPlayableArea)
endfunction
////////////////////////////////////////////////////////////////////
// End of the system //
////////////////////////////////////////////////////////////////////
endlibrary
function InitTrig_BUS_Register_Channels takes nothing returns nothing
set udg_BUSCR_Name[0] = "LunarStrike"
set udg_BUSCR_Effect[0] = "war3mapImported\\Lunar Strike Charge.mdx"//"Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl"
set udg_BUSCR_MinAOE[0] = 175
set udg_BUSCR_MaxAOE[0] = 200.
set udg_BUSCR_AbsorbAOE[0] = 20.
set udg_BUSCR_MinSize[0] = 0.1
set udg_BUSCR_MaxSize[0] = 0.5
set udg_BUSCR_SpawnRate[0] = 20
set udg_BUSCR_SpawnCount[0] = 4
set udg_BUSCR_Power[0] = 100
set udg_BUSCR_HueRed[0] = 60
set udg_BUSCR_HueGreen[0] = 60
set udg_BUSCR_HueBlue[0] = 255
set udg_BUSCR_HueAlpha[0] = 255
set udg_BUSCR_HueSpeed[0] = 0.50
call BUS_RegisterChannel(0)
//Next Channel
set udg_BUSCR_Name[0] = "PrimalStrike"
set udg_BUSCR_Effect[0] = "war3mapImported\\Primal Strike Charge.mdx"//"Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl"
set udg_BUSCR_MinAOE[0] = 225
set udg_BUSCR_MaxAOE[0] = 225.
set udg_BUSCR_AbsorbAOE[0] = 20.
set udg_BUSCR_MinSize[0] = 0.1
set udg_BUSCR_MaxSize[0] = 1
set udg_BUSCR_SpawnRate[0] = 25
set udg_BUSCR_SpawnCount[0] = 8
set udg_BUSCR_Power[0] = 125
set udg_BUSCR_HueRed[0] = 60
set udg_BUSCR_HueGreen[0] = 60
set udg_BUSCR_HueBlue[0] = 255
set udg_BUSCR_HueAlpha[0] = 255
set udg_BUSCR_HueSpeed[0] = 0.50
call BUS_RegisterChannel(0)
//Next Channel
set udg_BUSCR_Name[0] = "Gravity"
set udg_BUSCR_Effect[0] = "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl"
set udg_BUSCR_MinAOE[0] = 500
set udg_BUSCR_MaxAOE[0] = 500.
set udg_BUSCR_AbsorbAOE[0] = 50.
set udg_BUSCR_MinSize[0] = 1.5
set udg_BUSCR_MaxSize[0] = 2.
set udg_BUSCR_SpawnRate[0] = 128
set udg_BUSCR_SpawnCount[0] = 1
set udg_BUSCR_Power[0] = 1100
set udg_BUSCR_HueRed[0] = 0
set udg_BUSCR_HueGreen[0] = 0
set udg_BUSCR_HueBlue[0] = 0
set udg_BUSCR_HueAlpha[0] = 255
set udg_BUSCR_HueSpeed[0] = 0.25
call BUS_RegisterChannel(0)
//Next Channel
set udg_BUSCR_Name[0] = "Holy Storm"
set udg_BUSCR_Effect[0] = "Abilities\\Spells\\NightElf\\Rejuvenation\\RejuvenationTarget.mdl"
set udg_BUSCR_MinAOE[0] = 200.
set udg_BUSCR_MaxAOE[0] = 250.
set udg_BUSCR_AbsorbAOE[0] = 50.
set udg_BUSCR_MinSize[0] = 0.25
set udg_BUSCR_MaxSize[0] = 0.5
set udg_BUSCR_SpawnRate[0] = 30
set udg_BUSCR_SpawnCount[0] = 2
set udg_BUSCR_Power[0] = 20
set udg_BUSCR_HueRed[0] = 255
set udg_BUSCR_HueGreen[0] = 255
set udg_BUSCR_HueBlue[0] = 0
set udg_BUSCR_HueAlpha[0] = 255
set udg_BUSCR_HueSpeed[0] = 1
call BUS_RegisterChannel(0)
endfunction
This user guide explains how to use the BUS Channel system for your own abilities.
Instructions:
1) You will need to define some channel types, to do this follow the layout of "BUS Register Channels"
- Set up all the variables which start with the acronym "BUSCR_" to the value you desire
- Follow "Channel Register Explanation" for a more in-depth coverage of this
- Do not set udg_BUSCR_HueSpeed[0] = 0 this will cause the channel to be unusable
- Make sure that they all have 0 as their index number and use the function below at the end.
call BUS_RegisterChannel(0)
- This will register your channel and give it an index number for you to refer to it by
- If you do not know its index number (they are assigned from 1+ in order of registering) use the below function
call BUS_GetChannelByName("Your Channel Name")
This is function is case insensitive
2) If you want to overwrite an existing channel or want to specify the index number specifically you can use these:
- call Bus_RegisterChannel(i) Where i is the index number you wish to register it by (i > 0)
- call BUS_RegisterChannel(BUS_GetChannelByName("Your Channel Name"))
3) If you wish to make an ability which uses the channel system and you have completed the above steps
- You need to initialise a trigger which activates when the ability begins being channeled
- You then need to initialise a trigger which activates when BUS_Event becomes equal to the ability event number
- This second trigger will only activate if the channel is completed, so interrupting and cancelling work as normal
- All abilities need a unique event number this can be any real number so long as only one ability uses it
- A completed JASS example can be found at Example 1, A completed GUI example can be found aT Example 1 & 2
- The Start channel function has many parameters that it can be passed, with quite a few of them being optional
call BUS_StartChannel(BUS_GetChannelByName("My Channel Type"), Caster, TargetUnit, TargetX., TargetY., ChannelDuration, EventNumber, HaveHueChange)
- It is not necessary to pass a Target unit, Target X or Target Y as some abilities may not have or use these things
- If the channel type requested does not exist (the string inputted is wrong) then the last defined channel will
be used by default, if you pass a number which does not correspond to any defined channel, there will be an error
so it is safer to use BUS_GetChannelByName
- Make sure the event number passed matches the event number defined to activate the right function
example 1 uses 5.00 and example 2 uses 6.00 for instance, if they used the same value then both triggers would fire
- While most parameters are self-explanatory the last one "HaveHueChange" is a bit less clear:
It is a boolean value (true/false)
It determines whether or not the caster has their hue (colour) changed while they are channeling the ability
It assumes that the caster has a color of 255/255/255/255 (Red/Green/Blue/Alpha) so if your caster is not then
you should always set this to false
4) Certain globals will have data which can be used by the event function (Example 1 first function, Example 3)
- udg_BUS_Unit Will contain the caster unit, it must be used
- udg_BUS_Target will contain the target unit, it should be null if not used
- udg_BUS_X will contain the X co-ordinate of the target point, it should be 0 if not used
- udg_BUS_Y will contain the Y co-ordinate of the target point, it should be 0 if not used
This section covers the different variables when setting up a channel and what they do
Lets take a look at the first channel from "BUS Register Channel"
set udg_BUSCR_Name[0] = "Arcane Charge"
set udg_BUSCR_Effect[0] = "Abilities\\Spells\\Human\\ManaFlare\\ManaFlareTarget.mdl"
set udg_BUSCR_MinAOE[0] = 200
set udg_BUSCR_MaxAOE[0] = 300.
set udg_BUSCR_AbsorbAOE[0] = 50.
set udg_BUSCR_MinSize[0] = 0.1
set udg_BUSCR_MaxSize[0] = 1.5
set udg_BUSCR_SpawnRate[0] = 50
set udg_BUSCR_SpawnCount[0] = 2
set udg_BUSCR_Power[0] = 60
set udg_BUSCR_HueRed[0] = 60
set udg_BUSCR_HueGreen[0] = 60
set udg_BUSCR_HueBlue[0] = 255
set udg_BUSCR_HueAlpha[0] = 255
set udg_BUSCR_HueSpeed[0] = 0.50
call BUS_RegisterChannel(0)
set udg_BUSCR_Name[0] = "Arcane Charge"
- This is the name the channel is given and used to locate it with BUS_GetChannelByName("Your Channel Name")
- Names are case insensitive so it does not matter if this is upper, lower or any mix of the few
- Remembering if there is spacing however is important
- This attribute exists as names are significantly easier to remember than ID numbers
set udg_BUSCR_Effect[0] = "Abilities\\Spells\\Human\\ManaFlare\\ManaFlareTarget.mdl"
- This is the filepath used for the effect of the channel - the particles that appear and are drawn toward the caster
- The double "\"s are important and if you are getting a string from the object editor it will only have one, be sure
to add the other ones in before you save (this may cause the progress bar to appear stuck, though correcting and
attempting to save again will work, even if it remains bugged
- Having an incorrect path may bug the system, as well as make no effect appear when you are channeling
set udg_BUSCR_MinAOE[0] = 200
set udg_BUSCR_MaxAOE[0] = 300.
- These both are very similar - they determine how far away from the caster effects may spawn
- The gap between these two values is the effective range (all effects will spawn in this range)
- Technically these can take negative values, but it is not recommended as the facing angle of effects will be wrong
set udg_BUSCR_AbsorbAOE[0] = 50.
- This is the distance from the caster that the effects must have (or be closer than) before they are destroyed
- Ideally this is close to melee range, and should be much lower then the MinAOE (effects may spawn which are
instantly removed which is essentially pointless, if they are the same)
set udg_BUSCR_MinSize[0] = 0.1
set udg_BUSCR_MaxSize[0] = 1.5
- These are scaling controls for the effects - determining the upper and lower bounds of their sizes
- They are done in terms of percentages (0.1 = 10%, 1.5 = 150%)
- Most models scale differently so you are unlikely to get the desired sizes first try if you estimate
- setting these values to negatives will invert the models (which may be desirable depending on the effect)
set udg_BUSCR_SpawnRate[0] = 50
- The spawn rate is a measure of how many sets of effects are made per second
- This is inherently limited by the timer speed used by the system (default 0.03125)
- The maximum amount of spawns per second is 32, so setting this value to 32 should reach these maximum but
due to inaccuracies in floating point numbers, it is safer to use a higher number to ensure all 32 sets are made
set udg_BUSCR_SpawnCount[0] = 2
- The spawn count is a measure of how many effects are created within each set
- Unlike the spawn rate this is not limited by the timer but rather by the Warcraft 3 engine with an approximate
maximum of 400 effects being able to be created at any given time, though to do this would cause massive amounts
of lag and lead to freezing, particularly if the spawn rate is also high
- The total amount of effects spawned can be calculated via (ChannelDuration * SpawnRate * SpawnCount) where the
duration is in seconds, so be mindful of this when setting up your channels
set udg_BUSCR_Power[0] = 60
- The power of a channel refers to how strongly the effects are pulled into the caster, the higher this value
the more visually powerful the channel looks (particularly if accompanied by a high spawn rate) conversely a
lower value leads to a more aura-like channel effect
set udg_BUSCR_HueRed[0] = 60
set udg_BUSCR_HueGreen[0] = 60
set udg_BUSCR_HueBlue[0] = 255
set udg_BUSCR_HueAlpha[0] = 255
- These values determine the Red/Green/Blue/Alpha extremes of a hue (colour) change respectively assuming the
instance of the channel is using them
- The system assumes that the default values are 255/255/255/255 respectively for any given caster, these are
the values that it will periodically oscillate to (go to and from) during a channel
- Alpha refers to the transparency of a unit, 0 leads to a completely invisible unit
set udg_BUSCR_HueSpeed[0] = 0.50
- This determines the time it takes for one oscillation to complete (go from default colours to the above hue values
- A complete oscillation is therefore double this time
- When creating a spell it is good to consider what the colour will be when the channel is over, in this case so long
as the channel duration is in complete seconds (1.00, 2.00, 3.00 etc.) then the caster will be at their original
colours when the channel is complete, conversely if ending at a half second (0.50, 1.50, 2.50, etc.) then they
will be at the extreme end of the colour change, however when a channel completes the unit is automatically
restored to default colouring, so this is only important to consider if you wish to avoid a sudden colour change
(this will still happen if the channel is cancelled)
You have reached the end of this explanation
library Memory initializer onInit requires Typecast
// Variables must be public so they have undecorated names.
globals
code teamScore // Memory array
integer index // Desired address
integer bestScore // Return value
integer teamCount // Used to crash the Jass VM. Never use this variable !!!
integer array Memory
real array RMemory
integer bytecode // Not used, it's here just to fool Jasshelper
integer array l__bytecode
integer StructAddress
integer BCCount = 12
endglobals
//# +nosemanticerror
private function BCRegister takes code func1, code func2 returns nothing
call setCode(func1)
set l__bytecode[BCCount] = 0x0E000400
set l__bytecode[BCCount+1] = Memory[l__Code/4 + 9]
call setCode(func2)
set l__bytecode[BCCount+2] = 0x11000000
set l__bytecode[BCCount+3] = Memory[l__Code/4 + 1]
set l__bytecode[BCCount+4] = 0x16000000
set l__bytecode[BCCount+5] = Memory[l__Code/4 - 1]
set BCCount = BCCount + 6
set l__bytecode[BCCount] = 0x27000000
endfunction
module Bytecode
private integer BC
static integer address
static method operator[] takes integer i returns integer
return thistype(i).BC
endmethod
static method operator[]= takes integer i, integer value returns nothing
set thistype(i).BC = value
endmethod
private static method setAddress takes nothing returns nothing
set address = Memory[address/4 + 3]
endmethod
private static method onInit takes nothing returns nothing
set thistype(8191).BC = 0 //Always allocate full size of the array
call BCRegister(function thistype.onInit, function thistype.setAddress)
endmethod
endmodule
private function Struct takes nothing returns integer
return -1
endfunction
function ReadMemory takes integer address returns integer
return Memory[address/4] //Inline-friendly
endfunction
function ReadMemoryReal takes integer address returns real
return RMemory[address/4] //Inline-friendly
endfunction
private function InitBytecode takes integer id returns nothing
set l__bytecode[8191] = 0
set l__bytecode[0] = 0x06030000 //op: 06(NEWGLOBAL), type: 03(code)
set l__bytecode[1] = id //id of name "Memory"
set l__bytecode[2] = 0x06030000 //op: 06(NEWGLOBAL), type: 03(code)
set l__bytecode[3] = id+1 //id of name "RMemory"
set l__bytecode[4] = 0x0E010300 //op: 0E(GETVAR), type: 03(code), reg: 01
set l__bytecode[5] = 0xF2D //id of variable teamScore
set l__bytecode[6] = 0x11010000 //op: 11(SETVAR), reg: 01, var: "Memory"
set l__bytecode[7] = id
set l__bytecode[8] = 0x11010000 //op: 11(SETVAR), reg: 01, var: "RMemory"
set l__bytecode[9] = id+1
set l__bytecode[10] = 0x27000000 //op: 27(RETURN)
endfunction
private function Typecast takes nothing returns nothing
local integer bytecode
endfunction
function GetStructAddress takes nothing returns integer
return StructAddress
endfunction
private module Init
/* Functions that take arguments normally can't be used as code
Experimental version of Pjass is required to disable error checking */
//# +nosemanticerror
private static method onInit takes nothing returns nothing
call setCode(function ReadMemory)
set index = l__Code/4 + 13
set teamScore = function Struct
call setCode(function MeleeTournamentFinishNowRuleA)
call setInt(1648+l__Code)
call ForForce(bj_FORCE_PLAYER[0], l__Int)
call InitBytecode(bestScore)
set StructAddress = l__bytecode
set index = StructAddress/4+3
call ForForce(bj_FORCE_PLAYER[0], l__Int)
call setInt(bestScore)
call ForForce(bj_FORCE_PLAYER[0], l__Int)
endmethod
endmodule
private struct MemInit extends array
implement Init
endstruct
//Initialize registered bytecode arrays.
private function onInit takes nothing returns nothing
call ForForce(bj_FORCE_PLAYER[0], I2C(Memory[StructAddress/4+3]+48))
endfunction
endlibrary
/* Provides detection of the game version and initializes all
version-specific addresses. Currently supported versions
are 1.26 through 1.28, windows only. My goal is to support all
versions since 1.24b at windows, and 1.26 on Mac. */
//EDIT 15/08/2017: Included experimental support for automatic address detection. Currently detects the address of JassContext in all game versions. Detection of main game class will be included in the future.
library Version initializer Init requires Memory
globals
integer GameBase
integer GameState
integer pUnitData
integer pAbilityData
integer pGameClass2
integer pMouseEnv
integer pJassContext
string PatchVersion = "|cffff0000Unknown|r"
endglobals
native DebugBreak takes integer i returns nothing
private struct BC extends array
implement Bytecode
endstruct
private function StackSearcher takes integer i, integer f returns nothing
//call BJDebugMsg("Stack Pointer: " + Int2Hex(i))
//call BJDebugMsg("Address of Init function: " + Int2Hex(f))
set i = i/4
loop
exitwhen Memory[i] == f and Memory[i+3] == 300000
set i = i+1
endloop
//call BJDebugMsg("Found stack frame of VM: " + Int2Hex(i*4))
set pJassContext = Memory[i-1]
if Memory[pJassContext/4+8] == f+888 then
//call BJDebugMsg("Found Jass Context: " + Int2Hex(pJassContext) + ". You are running on mac.")
return
endif
//call BJDebugMsg("You are running on Windows. Searching for Jass context...")
loop
set i = i-1
set pJassContext = Memory[i]
exitwhen pJassContext*65536/65536 == 0x88 and pJassContext>65536 and Memory[pJassContext/4+8] == f+888
endloop
//call BJDebugMsg("Found Jass Context: " + Int2Hex(pJassContext))
endfunction
//# +nosemanticerror
private function InitBytecode takes nothing returns nothing
call DebugBreak(0)
set BC[0] = 0x0C000400
set BC[2] = 0x13000000
set BC[4] = 0x15000000
set BC[5] = Memory[C2I(function InitBytecode)/4+5]
set BC[6] = 0x17000000
set BC[8] = 0x13000000
set BC[10] = 0x15000000
set BC[11] = 595 //R2I
set BC[12] = 0x13000000
set BC[14] = 0x0F000000
set BC[16] = 0x13000000
set BC[18] = 0x16000000
set BC[19] = Memory[C2I(function StackSearcher)/4-1]
set BC[20] = 0x27000000
endfunction
function Init26 takes nothing returns nothing
set GameBase = Memory[GetStructAddress()/4]/4-0x254418
set GameState = GameBase+0x2AD97D
set pUnitData = GameBase+0x2AD11E
set pAbilityData = GameBase+0x2ACF99
set pGameClass2 = GameBase+0x2AD3E0
endfunction
function Init27 takes nothing returns nothing
set GameBase = Memory[GetStructAddress()/4]/4-0x298ECC
set GameState = GameBase+0x2F908E
set pUnitData = GameBase+0x2FB123
set pAbilityData = GameBase+0x2FB351
set pGameClass2 = GameBase+0x2F98D4
endfunction
function Init27b takes nothing returns nothing
set GameBase = Memory[GetStructAddress()/4]/4-0x2F5C85
set GameState = GameBase+0x35A1EA
set pUnitData = GameBase+0x35C27D
set pAbilityData = GameBase+0x35C4AB
set pGameClass2 = GameBase+0x35AA2E
endfunction
function Init28 takes nothing returns nothing
set GameBase = Memory[GetStructAddress()/4]/4-0x2F8241
set GameState = GameBase+0x35CC3C
set pUnitData = GameBase+0x35ECCF
set pAbilityData = GameBase+0x35EEFD
set pGameClass2 = GameBase+0x35D480
endfunction
private function Init takes nothing returns nothing
local integer i = Memory[GetStructAddress()/4]
set i = i - Memory[i/4]
if i == 2894996 then
set PatchVersion = "1.28"
call Init28()
elseif i == 2889044 then
set PatchVersion = "1.27b"
call Init27b()
elseif i == 2586768 then
set PatchVersion = "1.27"
call Init27()
elseif i == 5205600 then
set PatchVersion = "1.26"
call Init26()
else
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 0, "|cffff0000Warning! You are playing with unsupported patch version!|r")
return
endif
set pMouseEnv = Memory[Memory[pGameClass2]/4 + 239]/4 + 196
set BC[15] = Memory[C2I(function Init)/4-1]
call InitBytecode()
call ForForce(bj_FORCE_PLAYER[0], I2C(BC.address))
endfunction
endlibrary
library Utils initializer init requires Memory, Bitwise, ObjectData
globals
constant integer DEF_ADR_ABILITY_DATA=0
constant integer DEF_ADR_ABILITY_UI=1
constant integer DEF_ADR_UNIT_DATA=2
constant integer DEF_ADR_UNIT_UI=3
constant integer DEF_ADR_ITEM_DATA=4
hashtable ObjectDataPointersTable=InitHashtable()
string array HexNumber__Chars
integer array Ascii__Ints
string array Ascii__Chars
integer pUnitUIDefAddr
integer pJassEnvAddress=0
endglobals
function GetJassContext takes integer id returns integer
return Memory[Memory[Memory[Memory[pJassEnvAddress]/4+5]/4+36]/4+id]
endfunction
function GetStringAddress takes string s returns integer
return Memory[Memory[Memory[Memory[GetJassContext(1)/4+2589]/4+2]/4+SH2I(s)*4+2]/4+7]
endfunction
function WriteNullTerminatedString takes string s, integer i_address returns nothing
set Memory[i_address/4] = GetStringAddress(s)
endfunction
/* Takes a handle from the Jass world, and returns the memory address of the corresponding native
object. Don't use non-agent handles (<1048576) with this function, or the game crashes! */
function ConvertHandle takes handle h returns integer
return Memory[Memory[Memory[Memory[GameState]/4+7]/4+103]/4 + GetHandleId(h)*3 - 0x2FFFFF]
endfunction
// Returns the base cooldown of an ability for a specified level.
function GetAbilityCooldown takes integer abil, integer level returns real
return RMemory[Memory[GetObjectData(pAbilityData, abil)+21]/4-21+level*26]
endfunction
/* This function returns the CURRENT cooldown of an ability, after it's cast. This is a per-instance
value, and so it requires an ability handle, not an ability id. Currently the only way to obtain
such a handle is the native GetSpellAbility (usable only from spell events). You can then save
that handle in a hashtable if you need */
function GetAbilityCurrentCooldown takes ability a returns real
local integer pData = Memory[ConvertHandle(a)/4+55]/4
if pData != 0 then
return RMemory[pData+1] - RMemory[Memory[pData+3]/4+16]
endif
return .0
endfunction
function GetMouseX takes nothing returns real
return RMemory[pMouseEnv]
endfunction
function GetMouseY takes nothing returns real
return RMemory[pMouseEnv+1]
endfunction
function GetMouseZ takes nothing returns real
return RMemory[pMouseEnv+2]
endfunction
function GetUnitAttackAbilityForAddress takes integer pConvertedHandle returns integer
return Memory[pConvertedHandle/4+0x1e8/4]
endfunction
function GetUnitAttackAbility takes unit u returns integer
return GetUnitAttackAbilityForAddress(ConvertHandle(u))
endfunction
function SetUnitAttackBackswing takes unit u, real r returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0x190/4]=cleanInt(realToIndex(r))
endfunction
function GetUnitAttackBackswing takes unit u returns real
return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x190/4]))
endfunction
private function init takes nothing returns nothing
set HexNumber__Chars[0]="00"
set HexNumber__Chars[1]="01"
set HexNumber__Chars[2]="02"
set HexNumber__Chars[3]="03"
set HexNumber__Chars[4]="04"
set HexNumber__Chars[5]="05"
set HexNumber__Chars[6]="06"
set HexNumber__Chars[7]="07"
set HexNumber__Chars[8]="08"
set HexNumber__Chars[9]="09"
set HexNumber__Chars[10]="0A"
set HexNumber__Chars[11]="0B"
set HexNumber__Chars[12]="0C"
set HexNumber__Chars[13]="0D"
set HexNumber__Chars[14]="0E"
set HexNumber__Chars[15]="0F"
set HexNumber__Chars[16]="10"
set HexNumber__Chars[17]="11"
set HexNumber__Chars[18]="12"
set HexNumber__Chars[19]="13"
set HexNumber__Chars[20]="14"
set HexNumber__Chars[21]="15"
set HexNumber__Chars[22]="16"
set HexNumber__Chars[23]="17"
set HexNumber__Chars[24]="18"
set HexNumber__Chars[25]="19"
set HexNumber__Chars[26]="1A"
set HexNumber__Chars[27]="1B"
set HexNumber__Chars[28]="1C"
set HexNumber__Chars[29]="1D"
set HexNumber__Chars[30]="1E"
set HexNumber__Chars[31]="1F"
set HexNumber__Chars[32]="20"
set HexNumber__Chars[33]="21"
set HexNumber__Chars[34]="22"
set HexNumber__Chars[35]="23"
set HexNumber__Chars[36]="24"
set HexNumber__Chars[37]="25"
set HexNumber__Chars[38]="26"
set HexNumber__Chars[39]="27"
set HexNumber__Chars[40]="28"
set HexNumber__Chars[41]="29"
set HexNumber__Chars[42]="2A"
set HexNumber__Chars[43]="2B"
set HexNumber__Chars[44]="2C"
set HexNumber__Chars[45]="2D"
set HexNumber__Chars[46]="2E"
set HexNumber__Chars[47]="2F"
set HexNumber__Chars[48]="30"
set HexNumber__Chars[49]="31"
set HexNumber__Chars[50]="32"
set HexNumber__Chars[51]="33"
set HexNumber__Chars[52]="34"
set HexNumber__Chars[53]="35"
set HexNumber__Chars[54]="36"
set HexNumber__Chars[55]="37"
set HexNumber__Chars[56]="38"
set HexNumber__Chars[57]="39"
set HexNumber__Chars[58]="3A"
set HexNumber__Chars[59]="3B"
set HexNumber__Chars[60]="3C"
set HexNumber__Chars[61]="3D"
set HexNumber__Chars[62]="3E"
set HexNumber__Chars[63]="3F"
set HexNumber__Chars[64]="40"
set HexNumber__Chars[65]="41"
set HexNumber__Chars[66]="42"
set HexNumber__Chars[67]="43"
set HexNumber__Chars[68]="44"
set HexNumber__Chars[69]="45"
set HexNumber__Chars[70]="46"
set HexNumber__Chars[71]="47"
set HexNumber__Chars[72]="48"
set HexNumber__Chars[73]="49"
set HexNumber__Chars[74]="4A"
set HexNumber__Chars[75]="4B"
set HexNumber__Chars[76]="4C"
set HexNumber__Chars[77]="4D"
set HexNumber__Chars[78]="4E"
set HexNumber__Chars[79]="4F"
set HexNumber__Chars[80]="50"
set HexNumber__Chars[81]="51"
set HexNumber__Chars[82]="52"
set HexNumber__Chars[83]="53"
set HexNumber__Chars[84]="54"
set HexNumber__Chars[85]="55"
set HexNumber__Chars[86]="56"
set HexNumber__Chars[87]="57"
set HexNumber__Chars[88]="58"
set HexNumber__Chars[89]="59"
set HexNumber__Chars[90]="5A"
set HexNumber__Chars[91]="5B"
set HexNumber__Chars[92]="5C"
set HexNumber__Chars[93]="5D"
set HexNumber__Chars[94]="5E"
set HexNumber__Chars[95]="5F"
set HexNumber__Chars[96]="60"
set HexNumber__Chars[97]="61"
set HexNumber__Chars[98]="62"
set HexNumber__Chars[99]="63"
set HexNumber__Chars[100]="64"
set HexNumber__Chars[101]="65"
set HexNumber__Chars[102]="66"
set HexNumber__Chars[103]="67"
set HexNumber__Chars[104]="68"
set HexNumber__Chars[105]="69"
set HexNumber__Chars[106]="6A"
set HexNumber__Chars[107]="6B"
set HexNumber__Chars[108]="6C"
set HexNumber__Chars[109]="6D"
set HexNumber__Chars[110]="6E"
set HexNumber__Chars[111]="6F"
set HexNumber__Chars[112]="70"
set HexNumber__Chars[113]="71"
set HexNumber__Chars[114]="72"
set HexNumber__Chars[115]="73"
set HexNumber__Chars[116]="74"
set HexNumber__Chars[117]="75"
set HexNumber__Chars[118]="76"
set HexNumber__Chars[119]="77"
set HexNumber__Chars[120]="78"
set HexNumber__Chars[121]="79"
set HexNumber__Chars[122]="7A"
set HexNumber__Chars[123]="7B"
set HexNumber__Chars[124]="7C"
set HexNumber__Chars[125]="7D"
set HexNumber__Chars[126]="7E"
set HexNumber__Chars[127]="7F"
set HexNumber__Chars[128]="80"
set HexNumber__Chars[129]="81"
set HexNumber__Chars[130]="82"
set HexNumber__Chars[131]="83"
set HexNumber__Chars[132]="84"
set HexNumber__Chars[133]="85"
set HexNumber__Chars[134]="86"
set HexNumber__Chars[135]="87"
set HexNumber__Chars[136]="88"
set HexNumber__Chars[137]="89"
set HexNumber__Chars[138]="8A"
set HexNumber__Chars[139]="8B"
set HexNumber__Chars[140]="8C"
set HexNumber__Chars[141]="8D"
set HexNumber__Chars[142]="8E"
set HexNumber__Chars[143]="8F"
set HexNumber__Chars[144]="90"
set HexNumber__Chars[145]="91"
set HexNumber__Chars[146]="92"
set HexNumber__Chars[147]="93"
set HexNumber__Chars[148]="94"
set HexNumber__Chars[149]="95"
set HexNumber__Chars[150]="96"
set HexNumber__Chars[151]="97"
set HexNumber__Chars[152]="98"
set HexNumber__Chars[153]="99"
set HexNumber__Chars[154]="9A"
set HexNumber__Chars[155]="9B"
set HexNumber__Chars[156]="9C"
set HexNumber__Chars[157]="9D"
set HexNumber__Chars[158]="9E"
set HexNumber__Chars[159]="9F"
set HexNumber__Chars[160]="A0"
set HexNumber__Chars[161]="A1"
set HexNumber__Chars[162]="A2"
set HexNumber__Chars[163]="A3"
set HexNumber__Chars[164]="A4"
set HexNumber__Chars[165]="A5"
set HexNumber__Chars[166]="A6"
set HexNumber__Chars[167]="A7"
set HexNumber__Chars[168]="A8"
set HexNumber__Chars[169]="A9"
set HexNumber__Chars[170]="AA"
set HexNumber__Chars[171]="AB"
set HexNumber__Chars[172]="AC"
set HexNumber__Chars[173]="AD"
set HexNumber__Chars[174]="AE"
set HexNumber__Chars[175]="AF"
set HexNumber__Chars[176]="B0"
set HexNumber__Chars[177]="B1"
set HexNumber__Chars[178]="B2"
set HexNumber__Chars[179]="B3"
set HexNumber__Chars[180]="B4"
set HexNumber__Chars[181]="B5"
set HexNumber__Chars[182]="B6"
set HexNumber__Chars[183]="B7"
set HexNumber__Chars[184]="B8"
set HexNumber__Chars[185]="B9"
set HexNumber__Chars[186]="BA"
set HexNumber__Chars[187]="BB"
set HexNumber__Chars[188]="BC"
set HexNumber__Chars[189]="BD"
set HexNumber__Chars[190]="BE"
set HexNumber__Chars[191]="BF"
set HexNumber__Chars[192]="C0"
set HexNumber__Chars[193]="C1"
set HexNumber__Chars[194]="C2"
set HexNumber__Chars[195]="C3"
set HexNumber__Chars[196]="C4"
set HexNumber__Chars[197]="C5"
set HexNumber__Chars[198]="C6"
set HexNumber__Chars[199]="C7"
set HexNumber__Chars[200]="C8"
set HexNumber__Chars[201]="C9"
set HexNumber__Chars[202]="CA"
set HexNumber__Chars[203]="CB"
set HexNumber__Chars[204]="CC"
set HexNumber__Chars[205]="CD"
set HexNumber__Chars[206]="CE"
set HexNumber__Chars[207]="CF"
set HexNumber__Chars[208]="D0"
set HexNumber__Chars[209]="D1"
set HexNumber__Chars[210]="D2"
set HexNumber__Chars[211]="D3"
set HexNumber__Chars[212]="D4"
set HexNumber__Chars[213]="D5"
set HexNumber__Chars[214]="D6"
set HexNumber__Chars[215]="D7"
set HexNumber__Chars[216]="D8"
set HexNumber__Chars[217]="D9"
set HexNumber__Chars[218]="DA"
set HexNumber__Chars[219]="DB"
set HexNumber__Chars[220]="DC"
set HexNumber__Chars[221]="DD"
set HexNumber__Chars[222]="DE"
set HexNumber__Chars[223]="DF"
set HexNumber__Chars[224]="E0"
set HexNumber__Chars[225]="E1"
set HexNumber__Chars[226]="E2"
set HexNumber__Chars[227]="E3"
set HexNumber__Chars[228]="E4"
set HexNumber__Chars[229]="E5"
set HexNumber__Chars[230]="E6"
set HexNumber__Chars[231]="E7"
set HexNumber__Chars[232]="E8"
set HexNumber__Chars[233]="E9"
set HexNumber__Chars[234]="EA"
set HexNumber__Chars[235]="EB"
set HexNumber__Chars[236]="EC"
set HexNumber__Chars[237]="ED"
set HexNumber__Chars[238]="EE"
set HexNumber__Chars[239]="EF"
set HexNumber__Chars[240]="F0"
set HexNumber__Chars[241]="F1"
set HexNumber__Chars[242]="F2"
set HexNumber__Chars[243]="F3"
set HexNumber__Chars[244]="F4"
set HexNumber__Chars[245]="F5"
set HexNumber__Chars[246]="F6"
set HexNumber__Chars[247]="F7"
set HexNumber__Chars[248]="F8"
set HexNumber__Chars[249]="F9"
set HexNumber__Chars[250]="FA"
set HexNumber__Chars[251]="FB"
set HexNumber__Chars[252]="FC"
set HexNumber__Chars[253]="FD"
set HexNumber__Chars[254]="FE"
set HexNumber__Chars[255]="FF"
set Ascii__Ints[931]=8
set Ascii__Ints[1075]=9
set Ascii__Ints[1586]=10
set Ascii__Ints[1340]=12
set Ascii__Ints[412]=13
set Ascii__Ints[198]=32
set Ascii__Ints[1979]=33
set Ascii__Ints[1313]=34
set Ascii__Ints[1003]=35
set Ascii__Ints[1264]=36
set Ascii__Ints[983]=37
set Ascii__Ints[1277]=38
set Ascii__Ints[306]=39
set Ascii__Ints[904]=40
set Ascii__Ints[934]=41
set Ascii__Ints[917]=42
set Ascii__Ints[1972]=43
set Ascii__Ints[1380]=44
set Ascii__Ints[1985]=45
set Ascii__Ints[869]=46
set Ascii__Ints[1906]=47
set Ascii__Ints[883]=48
set Ascii__Ints[1558]=49
set Ascii__Ints[684]=50
set Ascii__Ints[582]=51
set Ascii__Ints[668]=52
set Ascii__Ints[538]=53
set Ascii__Ints[672]=54
set Ascii__Ints[1173]=55
set Ascii__Ints[71]=56
set Ascii__Ints[277]=57
set Ascii__Ints[89]=58
set Ascii__Ints[1141]=59
set Ascii__Ints[39]=60
set Ascii__Ints[1171]=61
set Ascii__Ints[51]=62
set Ascii__Ints[305]=0 //fixme 63
set Ascii__Ints[0]=64
set Ascii__Ints[222]=65
set Ascii__Ints[178]=66
set Ascii__Ints[236]=67
set Ascii__Ints[184]=68
set Ascii__Ints[1295]=69
set Ascii__Ints[1390]=70
set Ascii__Ints[1276]=71
set Ascii__Ints[203]=72
set Ascii__Ints[1314]=73
set Ascii__Ints[209]=74
set Ascii__Ints[1315]=75
set Ascii__Ints[170]=76
set Ascii__Ints[1357]=77
set Ascii__Ints[1343]=78
set Ascii__Ints[1397]=79
set Ascii__Ints[1420]=80
set Ascii__Ints[1419]=81
set Ascii__Ints[1396]=82
set Ascii__Ints[1374]=83
set Ascii__Ints[1407]=84
set Ascii__Ints[499]=85
set Ascii__Ints[1465]=86
set Ascii__Ints[736]=87
set Ascii__Ints[289]=88
set Ascii__Ints[986]=89
set Ascii__Ints[38]=90
set Ascii__Ints[1230]=91
set Ascii__Ints[1636]=93
set Ascii__Ints[1416]=94
set Ascii__Ints[1917]=95
set Ascii__Ints[217]=96
set Ascii__Ints[833]=123
set Ascii__Ints[1219]=124
set Ascii__Ints[553]=125
set Ascii__Ints[58]=126
set Ascii__Chars[0]="?"
set Ascii__Chars[8]="\b"
set Ascii__Chars[9]="\t"
set Ascii__Chars[10]="\n"
set Ascii__Chars[12]="\f"
set Ascii__Chars[13]="\r"
set Ascii__Chars[32]=" "
set Ascii__Chars[33]="!"
set Ascii__Chars[34]="\""
set Ascii__Chars[35]="#"
set Ascii__Chars[36]="$"
set Ascii__Chars[37]="%"
set Ascii__Chars[38]="&"
set Ascii__Chars[39]="'"//'
set Ascii__Chars[40]="("
set Ascii__Chars[41]=")"
set Ascii__Chars[42]="*"
set Ascii__Chars[43]="+"
set Ascii__Chars[44]=","
set Ascii__Chars[45]="-"
set Ascii__Chars[46]="."
set Ascii__Chars[47]="/"
set Ascii__Chars[48]="0"
set Ascii__Chars[49]="1"
set Ascii__Chars[50]="2"
set Ascii__Chars[51]="3"
set Ascii__Chars[52]="4"
set Ascii__Chars[53]="5"
set Ascii__Chars[54]="6"
set Ascii__Chars[55]="7"
set Ascii__Chars[56]="8"
set Ascii__Chars[57]="9"
set Ascii__Chars[58]=":"
set Ascii__Chars[59]=";"
set Ascii__Chars[60]="<"
set Ascii__Chars[61]="="
set Ascii__Chars[62]=">"
set Ascii__Chars[63]="?"
set Ascii__Chars[64]="@"
set Ascii__Chars[65]="A"
set Ascii__Chars[66]="B"
set Ascii__Chars[67]="C"
set Ascii__Chars[68]="D"
set Ascii__Chars[69]="E"
set Ascii__Chars[70]="F"
set Ascii__Chars[71]="G"
set Ascii__Chars[72]="H"
set Ascii__Chars[73]="I"
set Ascii__Chars[74]="J"
set Ascii__Chars[75]="K"
set Ascii__Chars[76]="L"
set Ascii__Chars[77]="M"
set Ascii__Chars[78]="N"
set Ascii__Chars[79]="O"
set Ascii__Chars[80]="P"
set Ascii__Chars[81]="Q"
set Ascii__Chars[82]="R"
set Ascii__Chars[83]="S"
set Ascii__Chars[84]="T"
set Ascii__Chars[85]="U"
set Ascii__Chars[86]="V"
set Ascii__Chars[87]="W"
set Ascii__Chars[88]="X"
set Ascii__Chars[89]="Y"
set Ascii__Chars[90]="Z"
set Ascii__Chars[91]="["
set Ascii__Chars[92]="\\"
set Ascii__Chars[93]="]"
set Ascii__Chars[94]="^"
set Ascii__Chars[95]="_"
set Ascii__Chars[96]="`"
set Ascii__Chars[97]="a"
set Ascii__Chars[98]="b"
set Ascii__Chars[99]="c"
set Ascii__Chars[100]="d"
set Ascii__Chars[101]="e"
set Ascii__Chars[102]="f"
set Ascii__Chars[103]="g"
set Ascii__Chars[104]="h"
set Ascii__Chars[105]="i"
set Ascii__Chars[106]="j"
set Ascii__Chars[107]="k"
set Ascii__Chars[108]="l"
set Ascii__Chars[109]="m"
set Ascii__Chars[110]="n"
set Ascii__Chars[111]="o"
set Ascii__Chars[112]="p"
set Ascii__Chars[113]="q"
set Ascii__Chars[114]="r"
set Ascii__Chars[115]="s"
set Ascii__Chars[116]="t"
set Ascii__Chars[117]="u"
set Ascii__Chars[118]="v"
set Ascii__Chars[119]="w"
set Ascii__Chars[120]="x"
set Ascii__Chars[121]="y"
set Ascii__Chars[122]="z"
set Ascii__Chars[123]="{"
set Ascii__Chars[124]="|"
set Ascii__Chars[125]="}"
set Ascii__Chars[126]="~"
endfunction
endlibrary
library MemoryHack
// reserved native for call 4 integer function and return BOOLEAN value
native MergeUnits takes integer qty, integer a, integer b, integer make returns boolean
// reserved native for call 2 integer function and return BOOLEAN value (can be converted to int!)
native ConvertUnits takes integer qty, integer id returns boolean
// reserved native for call 1 integer function and return integer value
native IgnoredUnits takes integer unitid returns integer
// https://github.com/Karaulov/WarcraftIII_DLL_126-xxx (EXTRADLLNAME)
// DLL is helpful ally which makes game easire
// Basically there's no jass-way to detect whenever player leaves to rollback changes
// so DLL does it for you with "AddNewOffsetToRestore" function
// if DLL is missing global changes you did will affect whole game until it's restarted
// You can detect function which uses DLL by "GetModuleProcAddress(EXTRADLLNAME" part inside of them\
globals
integer TempInteger=0
integer Temp_GetSomeAdd1=0
integer Temp_GetSomeAdd2=0
integer DamageIncrementer=0
real array DamageValues
integer array DamageAttackTypes
integer array DamageDamageTypes
player LocalPlayer=null
hashtable TempHash=InitHashtable()
hashtable RectData = InitHashtable()
hashtable HY=InitHashtable()
boolean IsL1ch=true//used in "echo" function to display debug messages
boolean array WidescreenState
real GJ_LastDmg=0//outdated yet could be useful
integer GJ_LastDamageType=0
integer GJ_LastAttackType=0
hashtable ObjectDataPointersTable=InitHashtable()
timer SuperTextPrinter_Timer=null
hashtable AbilitiesHashtable=InitHashtable()
integer testFunctionCount = 0
integer latestAddress1 = 0
integer latestAddress2 = 0
integer array Ascii__Ints
string array Ascii__Chars
code l__Code
integer l__Int
string l__Str
boolean l__Bool
constant string dotaconfigfle="config.dota"
integer array l__Array
string array HexNumber__Chars
integer bytecode
integer array l__bytecode
integer array Memory
integer bytecodedata //used to pass data between regular code and bytecode
integer GameState
integer pointers
integer pUnitData
integer pAbilityData
constant gametype GAME_TYPE_ALL= ConvertGameType(0xFFFFFFFF)
integer array H
trigger l__library_init
// For SetUnitFlags_2 (unit+0x20)
constant integer UNIT_VISIBLED_TO_ALL = 0x10
constant integer UNIT_INVULNERABLE = 0x8
constant integer UNIT_SELECTABLE = 0x2
constant integer UNIT_HIDDEN = 0x1
constant integer UNIT_AUTOATTACK_DISABLED=0x10000000
constant integer UNIT_ILLUSION=0x40000000
// For SetUnitFlags (unit+0xD4)
//flag 0x4 causes fatal if any damage received
//flag 0x40 stands for red flash, but doesn't directly calls it
constant integer UNIT_DEAD = 0x100
//like dead hero, provides no vision, cant be selected, enemies doesn't flee when attacked by unit with this flag
constant integer UNIT_MINMAP_ICON_HIDE = 0x80000
constant integer UNIT_MINMAP_ICON_TAVERN = 0x40000
constant integer UNIT_MINMAP_ICON_GOLD = 0x20000
constant integer UNIT_MINMAP_SHAREVISIBLE = 0x10000
constant integer UNIT_STUNNED= 0x100000
constant integer UNIT_INVISIBLED = 0x1000000
constant integer UNIT_HAS_FLYING_VISION= 0x20000000
integer pCameraDefaultHeight
real array DefaultCameraHeight
// 126a 0xAB65F4
// 127a 0xBE4238
integer pGlobalPlayerClass
// 127a 0xBEC464
// 126a 0xAB4450
integer pUnitMaxSpeedConstant
integer pUnitMaxSpeedConstantD
real UnitMaxSpeedConstant
// 127a 0xBEC460
// 126a 0xAB444C
integer pUnitMinSpeedConstant
integer pUnitMinSpeedConstantD
real UnitMinSpeedConstant
// 127a 0xBEC46C
// 126a 0xAB4458
integer pBuildingMaxSpeedConstant
integer pBuildingMaxSpeedConstantD
real BuildingMaxSpeedConstant
// 127a 0xBEC468
// 126a 0xAB4454
integer pBuildingMinSpeedConstant
integer pBuildingMinSpeedConstantD
real BuildingMinSpeedConstant
integer pUnitUIDefAddr
integer pUnitDataDefAddr
integer pAbilityUIDefAddr
integer pAbilityDataDefAddr
integer pAttackSpeedLimit
real AttackSpeedLimit
integer pAttackTimeLimit
real AttackTimeLimit
integer pWar3MapJLocation=0
integer pGameClass1=0
integer pGameClass2=0
integer pGameClass3=0
integer pTimerAddr=0
integer pCGameState=0
integer pJassEnvAddress=0
integer pLightEnv=0
integer pGetModuleHandle=0
integer pGetProcAddress=0
integer GameDLL=0
integer GameVersion=0
integer pMergeUnits=0
integer pMergeUnitsOffset=0
integer pIgnoredUnits=0
integer pIgnoredUnitsOffset=0
integer pConvertUnits=0
integer pConvertUnitsOffset=0
integer pLeaderboardSetItemLabelColor=0
integer pSetHPBarColorForPlayer=0
integer pSetHPBarXScaleForPlayer=0
integer pSetHPBarYScaleForPlayer=0
integer pSetHPCustomHPBarUnit=0
integer pSetMPBarXScaleForPlayer=0
integer pSetMPBarYScaleForPlayer=0
integer pSetMPBarYOffsetForPlayer=0
integer pExportFromMpq=0
integer pGetFrameItemAddress=0
integer pGetFrameSkinAddress=0
integer pGetFrameTextAddress=0
integer pUpdateFrameText=0
integer pFrameDefClass=0
integer pConvertString=0
integer pPacketClass=0
integer pPacketSend=0
integer pPingMinimapOffset=0
integer pPingMinimapExOffset=0
integer PingMinimapUnlocker = 0
integer PingMinimapExUnlocker = 0
boolean NotLockedPingMinimap = true
boolean NotLockedPingMinimapEx = true
integer pFindWindowA=0
integer pMessageBoxA=0
integer pGetAsyncKeyState=0
integer pWritePrivateProfileStringA=0
integer pGetPrivateProfileStringA=0
integer pLoadLibraryA=0
integer pGetFileAttributesA=0
integer pVirtualAlloc=0
integer pVirtualProtect=0
integer array RJassNativesBuffer
integer RJassNativesBufferSize = 0
integer pReservedExecutableMemory=0
integer pReservedExecutableMemory2=0
integer pBitwiseOR_ExecutableMemory
boolean NeedInitBitwiseOr = true
integer pBitwiseXOR_ExecutableMemory
boolean NeedInitBitwiseXor = true
integer pBitwiseAND_ExecutableMemory
boolean NeedInitBitwiseAnd = true
integer pReservedWritableMemory
integer pReservedWritableMemory2
constant integer szReservedWritableMemory = 3000
integer pStorm279
integer pPrintText1
integer pPrintText2
integer pPrintText3
integer pGetUnitAbility
integer pGetUnitAddress
integer p_sprintf
integer pChangeFont
integer pUpdateRestoreTimer=0
integer pAddNewOffsetToRestore=0
constant string EXTRADLLNAME="DotAAllstarsHelper688.dll"
integer pReserverdIntArg1
integer pReserverdIntArg2
integer pReserverdIntArg3
integer pReserverdIntArg4
hashtable Addresses=InitHashtable()
constant integer DEF_ADR_ABILITY_DATA=0
constant integer DEF_ADR_ABILITY_UI=1
constant integer DEF_ADR_UNIT_DATA=2
constant integer DEF_ADR_UNIT_UI=3
constant integer DEF_ADR_ITEM_DATA=4
constant integer ILLUSTION_BONUS_DAMAGE_RECEIVES=0
constant integer ILLUSTION_BONUS_DAMAGE_DEALS=1
integer pOrder1_offset
integer pOrder2_offset
integer pOrder3_offset
integer pOrder4_offset
integer pOrder5_offset
integer pOrder6_offset
integer pOrder7_offset
integer pOrder8_offset
integer Order1_unlockedvalue = 0
integer Order2_unlockedvalue = 0
integer Order3_unlockedvalue = 0
integer Order4_unlockedvalue = 0
integer Order5_unlockedvalue = 0
integer Order6_unlockedvalue = 0
integer Order7_unlockedvalue = 0
integer Order8_unlockedvalue = 0
integer Order1_lockedvalue
integer Order2_lockedvalue
integer Order3_lockedvalue
integer Order4_lockedvalue
integer Order5_lockedvalue
integer Order6_lockedvalue
integer Order7_lockedvalue
integer Order8_lockedvalue
boolean IsOrder1Locked = false
boolean IsOrder2Locked = false
boolean IsOrder3Locked = false
boolean IsOrder4Locked = false
boolean IsOrder5Locked = false
boolean IsOrder6Locked = false
boolean IsOrder7Locked = false
boolean IsOrder8Locked = false
boolean FogUpdateBlocked = false
integer pUpdateFogManual=0
integer pFogUpdateBlockAddr=0
integer pFogUpdateBlockAddrOld1=0
integer pFogUpdateBlockAddrOld2=0
integer pFogUpdateBlockAddrNew1=0
integer pFogUpdateBlockAddrNew2=0
integer pGetLatestDownloadedString = 0
integer pGetDownloadStatus = 0
integer pSaveNewMapFromUrl = 0
integer pGetDownloadProgress = 0
integer pGetCurrentMapDir = 0
integer pStartAbilityCD=0
integer pSendCommandWithoutTarget
integer pMissile
integer pWindowIsActive
integer pSendHttpGetRequest = 0
integer pAllianceOutput
integer AllianceLocker = 0
boolean NotLockedAllianceOutput = true
integer pMutePlayer=0
integer pUnMutePlayer=0
integer pSetWidescreenFixState=0
integer pSetCustomFovFix=0
boolean EXTRADLLLOADED = false
integer RegionEditMode = 0
real LatestMouseX = 0.
real LatestMouseY = 0.
integer LatestSelectRect = 0
integer LatestOverRect = 0
integer gl_hRectID = 0
integer OPLimitAddress1=0
integer OPLimitAddress2=0
integer pCycloneFixCondition=0
constant integer CycloneFixCondition026a=0x808B08EB
integer CycloneFixBaseValue=0
constant integer CycloneFixCondition027a=0x458B16EB
integer pCaptionsOverTheCreeps=0
integer pPhaseShiftInvisibilityFlagByte=0
constant integer PhaseShiftInvisibilityFlagByteFixed0x26=0x00000060
constant integer PhaseShiftInvisibilityFlagByteFixed0x27=0x00000060
integer pMemcpy
integer pSearchStringValue
integer pSearchStringAddr1
integer pSearchStringAddr2
integer pReservedMemoryForUpdateFrameText
integer pSimulateAttackInstance
integer pGameTime
integer pToggleForcedSubSelection=0
integer pToggleBlockKeyAndMouseEmulation=0
integer pToggleClickHelper=0
integer pSetStunToUnitTRUE
integer pSetStunToUnitFALSE
integer pReservedMemoryForSystemTime
integer pGetLocalTime=0
integer pCommonSilence
integer pAddSilenceOnAbility
integer pRemoveSilenceFromAbility
integer pPauseUnitDisabler
integer pUpdateUnitsSpeedCurrent
integer pSendMessageToChat=0
integer pCastSilenceToTarget
integer pCastAbility=0
integer pDamageBlockIllusionCheck=0
integer pItemDropOrderTriggerFix=0
integer pFixModelCollisionSphere=0
integer pGetOrLoadFile
integer pApplyTerrainFilterDirectly=0
integer pSetMainFuncWork=0
integer pFixModelTexturePath=0
integer StoreIntegerOffset = 0
integer StoreIntegerUnlocker = 0
boolean StoreIntegerLocked = false
integer pPatchModel = 0
integer pChangeAnimationSpeed = 0
integer pSetSequenceValue = 0
integer pRedirectFile = 0
integer pReservedMemoryForMissileHandler=0
integer pReservedMemoryForDamageHandler=0
integer pUnitVtable = 0
integer pRealUnitDamageHandler = 0
integer pTriggerExecute = 0
integer pDamageTarget = 0
integer pMissileEspData = 0
integer pDamageEspData = 0
integer pMissileFuncStart = 0
integer pMissileJumpBack = 0
integer pItemDataNode=0
integer pJassLog = 0
endglobals
function Char2AsciiEx takes string s returns integer
local integer i= Ascii__Ints[StringHash(s) / 0x1F0748 + 0x3EA]
if i == 47 and s == "\\" then
set i=92
elseif i >= 65 and i <= 90 and s != Ascii__Chars[i] then
set i=i + 32
endif
return i
endfunction
function Char2Hex takes string s returns integer
local integer i= Ascii__Ints[StringHash(s) / 0x1F0748 + 0x3EA]
if i >= 48 and i <= 57 then
return i - 48
elseif i >= 65 and i <= 70 then
return i - 55
endif
return - 1
endfunction
function Ascii2CharEx takes integer i returns string
return Ascii__Chars[i]
endfunction
function Ascii__onInit takes nothing returns nothing
set Ascii__Ints[931]=8
set Ascii__Ints[1075]=9
set Ascii__Ints[1586]=10
set Ascii__Ints[1340]=12
set Ascii__Ints[412]=13
set Ascii__Ints[198]=32
set Ascii__Ints[1979]=33
set Ascii__Ints[1313]=34
set Ascii__Ints[1003]=35
set Ascii__Ints[1264]=36
set Ascii__Ints[983]=37
set Ascii__Ints[1277]=38
set Ascii__Ints[306]=39
set Ascii__Ints[904]=40
set Ascii__Ints[934]=41
set Ascii__Ints[917]=42
set Ascii__Ints[1972]=43
set Ascii__Ints[1380]=44
set Ascii__Ints[1985]=45
set Ascii__Ints[869]=46
set Ascii__Ints[1906]=47
set Ascii__Ints[883]=48
set Ascii__Ints[1558]=49
set Ascii__Ints[684]=50
set Ascii__Ints[582]=51
set Ascii__Ints[668]=52
set Ascii__Ints[538]=53
set Ascii__Ints[672]=54
set Ascii__Ints[1173]=55
set Ascii__Ints[71]=56
set Ascii__Ints[277]=57
set Ascii__Ints[89]=58
set Ascii__Ints[1141]=59
set Ascii__Ints[39]=60
set Ascii__Ints[1171]=61
set Ascii__Ints[51]=62
set Ascii__Ints[305]=0 //fixme 63
set Ascii__Ints[0]=64
set Ascii__Ints[222]=65
set Ascii__Ints[178]=66
set Ascii__Ints[236]=67
set Ascii__Ints[184]=68
set Ascii__Ints[1295]=69
set Ascii__Ints[1390]=70
set Ascii__Ints[1276]=71
set Ascii__Ints[203]=72
set Ascii__Ints[1314]=73
set Ascii__Ints[209]=74
set Ascii__Ints[1315]=75
set Ascii__Ints[170]=76
set Ascii__Ints[1357]=77
set Ascii__Ints[1343]=78
set Ascii__Ints[1397]=79
set Ascii__Ints[1420]=80
set Ascii__Ints[1419]=81
set Ascii__Ints[1396]=82
set Ascii__Ints[1374]=83
set Ascii__Ints[1407]=84
set Ascii__Ints[499]=85
set Ascii__Ints[1465]=86
set Ascii__Ints[736]=87
set Ascii__Ints[289]=88
set Ascii__Ints[986]=89
set Ascii__Ints[38]=90
set Ascii__Ints[1230]=91
set Ascii__Ints[1636]=93
set Ascii__Ints[1416]=94
set Ascii__Ints[1917]=95
set Ascii__Ints[217]=96
set Ascii__Ints[833]=123
set Ascii__Ints[1219]=124
set Ascii__Ints[553]=125
set Ascii__Ints[58]=126
set Ascii__Chars[0]="?"
set Ascii__Chars[8]="\b"
set Ascii__Chars[9]="\t"
set Ascii__Chars[10]="\n"
set Ascii__Chars[12]="\f"
set Ascii__Chars[13]="\r"
set Ascii__Chars[32]=" "
set Ascii__Chars[33]="!"
set Ascii__Chars[34]="\""
set Ascii__Chars[35]="#"
set Ascii__Chars[36]="$"
set Ascii__Chars[37]="%"
set Ascii__Chars[38]="&"
set Ascii__Chars[39]="'"//'
set Ascii__Chars[40]="("
set Ascii__Chars[41]=")"
set Ascii__Chars[42]="*"
set Ascii__Chars[43]="+"
set Ascii__Chars[44]=","
set Ascii__Chars[45]="-"
set Ascii__Chars[46]="."
set Ascii__Chars[47]="/"
set Ascii__Chars[48]="0"
set Ascii__Chars[49]="1"
set Ascii__Chars[50]="2"
set Ascii__Chars[51]="3"
set Ascii__Chars[52]="4"
set Ascii__Chars[53]="5"
set Ascii__Chars[54]="6"
set Ascii__Chars[55]="7"
set Ascii__Chars[56]="8"
set Ascii__Chars[57]="9"
set Ascii__Chars[58]=":"
set Ascii__Chars[59]=";"
set Ascii__Chars[60]="<"
set Ascii__Chars[61]="="
set Ascii__Chars[62]=">"
set Ascii__Chars[63]="?"
set Ascii__Chars[64]="@"
set Ascii__Chars[65]="A"
set Ascii__Chars[66]="B"
set Ascii__Chars[67]="C"
set Ascii__Chars[68]="D"
set Ascii__Chars[69]="E"
set Ascii__Chars[70]="F"
set Ascii__Chars[71]="G"
set Ascii__Chars[72]="H"
set Ascii__Chars[73]="I"
set Ascii__Chars[74]="J"
set Ascii__Chars[75]="K"
set Ascii__Chars[76]="L"
set Ascii__Chars[77]="M"
set Ascii__Chars[78]="N"
set Ascii__Chars[79]="O"
set Ascii__Chars[80]="P"
set Ascii__Chars[81]="Q"
set Ascii__Chars[82]="R"
set Ascii__Chars[83]="S"
set Ascii__Chars[84]="T"
set Ascii__Chars[85]="U"
set Ascii__Chars[86]="V"
set Ascii__Chars[87]="W"
set Ascii__Chars[88]="X"
set Ascii__Chars[89]="Y"
set Ascii__Chars[90]="Z"
set Ascii__Chars[91]="["
set Ascii__Chars[92]="\\"
set Ascii__Chars[93]="]"
set Ascii__Chars[94]="^"
set Ascii__Chars[95]="_"
set Ascii__Chars[96]="`"
set Ascii__Chars[97]="a"
set Ascii__Chars[98]="b"
set Ascii__Chars[99]="c"
set Ascii__Chars[100]="d"
set Ascii__Chars[101]="e"
set Ascii__Chars[102]="f"
set Ascii__Chars[103]="g"
set Ascii__Chars[104]="h"
set Ascii__Chars[105]="i"
set Ascii__Chars[106]="j"
set Ascii__Chars[107]="k"
set Ascii__Chars[108]="l"
set Ascii__Chars[109]="m"
set Ascii__Chars[110]="n"
set Ascii__Chars[111]="o"
set Ascii__Chars[112]="p"
set Ascii__Chars[113]="q"
set Ascii__Chars[114]="r"
set Ascii__Chars[115]="s"
set Ascii__Chars[116]="t"
set Ascii__Chars[117]="u"
set Ascii__Chars[118]="v"
set Ascii__Chars[119]="w"
set Ascii__Chars[120]="x"
set Ascii__Chars[121]="y"
set Ascii__Chars[122]="z"
set Ascii__Chars[123]="{"
set Ascii__Chars[124]="|"
set Ascii__Chars[125]="}"
set Ascii__Chars[126]="~"
endfunction
//library Ascii ends
//library Typecast:
function InitArray takes integer vtable returns nothing
set l__Array[4] = 0
set l__Array[1] = vtable
set l__Array[2] = -1
set l__Array[3] = -1
endfunction
function TypecastArray takes nothing returns nothing
local integer l__Array //typecast Array to integer
endfunction
function GetArrayAddress takes nothing returns integer //not really needed
loop
return l__Array
endloop
return 0
endfunction
function GetRealFromMemory takes integer i returns real
return cleanReal(indexToReal(i))
endfunction
function SetRealIntoMemory takes real r returns integer
return cleanInt(realToIndex(r))
endfunction
//library Typecast ends
//library HexNumber:
function PowI takes integer x, integer power returns integer
local integer res=1
local integer y=x
if power==0 then
return 1
endif
set power=power-1
loop
set x=x*y
set power=power-1
exitwhen power==0
endloop
return x
endfunction
function ShiftLeftForBits takes integer i, integer shiftval returns integer
return i * (PowI(2,shiftval))
endfunction
function ShiftRightForBits takes integer i, integer shiftval returns integer
return i / (PowI(2,shiftval))
endfunction
function ShiftLeftForBytes takes integer i, integer shiftval returns integer
return ShiftLeftForBits(i,shiftval * 8)
endfunction
function ShiftRightForBytes takes integer i, integer shiftval returns integer
return ShiftRightForBits(i,shiftval * 8)
endfunction
function GetByteFromInteger takes integer i, integer byteid returns integer
local integer tmpval = i
local integer retval = 0
local integer byte1 = 0
local integer byte2 = 0
local integer byte3 = 0
local integer byte4 = 0
if (tmpval < 0) then
set tmpval = BitwiseNot(tmpval)
set byte4 = 255 - ModuloInteger(tmpval,256)
set tmpval = tmpval / 256
set byte3 = 255 - ModuloInteger(tmpval,256)
set tmpval = tmpval / 256
set byte2 = 255 - ModuloInteger(tmpval,256)
set tmpval = tmpval / 256
set byte1 = 255 - tmpval
else
set byte4 = ModuloInteger(tmpval,256)
set tmpval = tmpval / 256
set byte3 = ModuloInteger(tmpval,256)
set tmpval = tmpval / 256
set byte2 = ModuloInteger(tmpval,256)
set tmpval = tmpval / 256
set byte1 = tmpval
endif
if byteid == 1 then
return byte1
elseif byteid == 2 then
return byte2
elseif byteid == 3 then
return byte3
elseif byteid == 4 then
return byte4
endif
return retval
endfunction
function CreateInteger1 takes integer byte1, integer byte2, integer byte3, integer byte4 returns integer
local integer retval = byte1
set retval = ( retval * 256 ) + byte2
set retval = ( retval * 256 ) + byte3
set retval = ( retval * 256 ) + byte4
return retval
endfunction
function CreateInteger2 takes integer byte1, integer byte2, integer byte3, integer byte4 returns integer
local integer retval = byte1
set retval = ShiftLeftForBytes(retval,1) + byte2
set retval = ShiftLeftForBytes(retval,1) + byte3
set retval = ShiftLeftForBytes(retval,1) + byte4
return retval
endfunction
function Hex2Int takes string s returns integer
local integer result= 0
local integer i= 0
local integer char
loop
set char=Char2Hex(SubString(s, i, i + 1))
exitwhen i == 8 or char == - 1
set result=result * 16 + char
set i=i + 1
endloop
return result
endfunction
function Int2Hex_FIX takes integer i returns string
set i = BitwiseNot(i)
return HexNumber__Chars[255-(i/256/256/256)] + HexNumber__Chars[255-ModuloInteger(i/256/256,256)] + HexNumber__Chars[255-ModuloInteger(i/256,256)] + HexNumber__Chars[255-ModuloInteger(i,256)]
endfunction
function Int2Hex takes integer i returns string
if (i < 0) then
return Int2Hex_FIX(i)
endif
return HexNumber__Chars[(i/256/256/256)] + HexNumber__Chars[ModuloInteger(i/256/256,256)] + HexNumber__Chars[ModuloInteger(i/256,256)] + HexNumber__Chars[ModuloInteger(i,256)]
endfunction
function HexNumber__onInit takes nothing returns nothing
set HexNumber__Chars[0]="00"
set HexNumber__Chars[1]="01"
set HexNumber__Chars[2]="02"
set HexNumber__Chars[3]="03"
set HexNumber__Chars[4]="04"
set HexNumber__Chars[5]="05"
set HexNumber__Chars[6]="06"
set HexNumber__Chars[7]="07"
set HexNumber__Chars[8]="08"
set HexNumber__Chars[9]="09"
set HexNumber__Chars[10]="0A"
set HexNumber__Chars[11]="0B"
set HexNumber__Chars[12]="0C"
set HexNumber__Chars[13]="0D"
set HexNumber__Chars[14]="0E"
set HexNumber__Chars[15]="0F"
set HexNumber__Chars[16]="10"
set HexNumber__Chars[17]="11"
set HexNumber__Chars[18]="12"
set HexNumber__Chars[19]="13"
set HexNumber__Chars[20]="14"
set HexNumber__Chars[21]="15"
set HexNumber__Chars[22]="16"
set HexNumber__Chars[23]="17"
set HexNumber__Chars[24]="18"
set HexNumber__Chars[25]="19"
set HexNumber__Chars[26]="1A"
set HexNumber__Chars[27]="1B"
set HexNumber__Chars[28]="1C"
set HexNumber__Chars[29]="1D"
set HexNumber__Chars[30]="1E"
set HexNumber__Chars[31]="1F"
set HexNumber__Chars[32]="20"
set HexNumber__Chars[33]="21"
set HexNumber__Chars[34]="22"
set HexNumber__Chars[35]="23"
set HexNumber__Chars[36]="24"
set HexNumber__Chars[37]="25"
set HexNumber__Chars[38]="26"
set HexNumber__Chars[39]="27"
set HexNumber__Chars[40]="28"
set HexNumber__Chars[41]="29"
set HexNumber__Chars[42]="2A"
set HexNumber__Chars[43]="2B"
set HexNumber__Chars[44]="2C"
set HexNumber__Chars[45]="2D"
set HexNumber__Chars[46]="2E"
set HexNumber__Chars[47]="2F"
set HexNumber__Chars[48]="30"
set HexNumber__Chars[49]="31"
set HexNumber__Chars[50]="32"
set HexNumber__Chars[51]="33"
set HexNumber__Chars[52]="34"
set HexNumber__Chars[53]="35"
set HexNumber__Chars[54]="36"
set HexNumber__Chars[55]="37"
set HexNumber__Chars[56]="38"
set HexNumber__Chars[57]="39"
set HexNumber__Chars[58]="3A"
set HexNumber__Chars[59]="3B"
set HexNumber__Chars[60]="3C"
set HexNumber__Chars[61]="3D"
set HexNumber__Chars[62]="3E"
set HexNumber__Chars[63]="3F"
set HexNumber__Chars[64]="40"
set HexNumber__Chars[65]="41"
set HexNumber__Chars[66]="42"
set HexNumber__Chars[67]="43"
set HexNumber__Chars[68]="44"
set HexNumber__Chars[69]="45"
set HexNumber__Chars[70]="46"
set HexNumber__Chars[71]="47"
set HexNumber__Chars[72]="48"
set HexNumber__Chars[73]="49"
set HexNumber__Chars[74]="4A"
set HexNumber__Chars[75]="4B"
set HexNumber__Chars[76]="4C"
set HexNumber__Chars[77]="4D"
set HexNumber__Chars[78]="4E"
set HexNumber__Chars[79]="4F"
set HexNumber__Chars[80]="50"
set HexNumber__Chars[81]="51"
set HexNumber__Chars[82]="52"
set HexNumber__Chars[83]="53"
set HexNumber__Chars[84]="54"
set HexNumber__Chars[85]="55"
set HexNumber__Chars[86]="56"
set HexNumber__Chars[87]="57"
set HexNumber__Chars[88]="58"
set HexNumber__Chars[89]="59"
set HexNumber__Chars[90]="5A"
set HexNumber__Chars[91]="5B"
set HexNumber__Chars[92]="5C"
set HexNumber__Chars[93]="5D"
set HexNumber__Chars[94]="5E"
set HexNumber__Chars[95]="5F"
set HexNumber__Chars[96]="60"
set HexNumber__Chars[97]="61"
set HexNumber__Chars[98]="62"
set HexNumber__Chars[99]="63"
set HexNumber__Chars[100]="64"
set HexNumber__Chars[101]="65"
set HexNumber__Chars[102]="66"
set HexNumber__Chars[103]="67"
set HexNumber__Chars[104]="68"
set HexNumber__Chars[105]="69"
set HexNumber__Chars[106]="6A"
set HexNumber__Chars[107]="6B"
set HexNumber__Chars[108]="6C"
set HexNumber__Chars[109]="6D"
set HexNumber__Chars[110]="6E"
set HexNumber__Chars[111]="6F"
set HexNumber__Chars[112]="70"
set HexNumber__Chars[113]="71"
set HexNumber__Chars[114]="72"
set HexNumber__Chars[115]="73"
set HexNumber__Chars[116]="74"
set HexNumber__Chars[117]="75"
set HexNumber__Chars[118]="76"
set HexNumber__Chars[119]="77"
set HexNumber__Chars[120]="78"
set HexNumber__Chars[121]="79"
set HexNumber__Chars[122]="7A"
set HexNumber__Chars[123]="7B"
set HexNumber__Chars[124]="7C"
set HexNumber__Chars[125]="7D"
set HexNumber__Chars[126]="7E"
set HexNumber__Chars[127]="7F"
set HexNumber__Chars[128]="80"
set HexNumber__Chars[129]="81"
set HexNumber__Chars[130]="82"
set HexNumber__Chars[131]="83"
set HexNumber__Chars[132]="84"
set HexNumber__Chars[133]="85"
set HexNumber__Chars[134]="86"
set HexNumber__Chars[135]="87"
set HexNumber__Chars[136]="88"
set HexNumber__Chars[137]="89"
set HexNumber__Chars[138]="8A"
set HexNumber__Chars[139]="8B"
set HexNumber__Chars[140]="8C"
set HexNumber__Chars[141]="8D"
set HexNumber__Chars[142]="8E"
set HexNumber__Chars[143]="8F"
set HexNumber__Chars[144]="90"
set HexNumber__Chars[145]="91"
set HexNumber__Chars[146]="92"
set HexNumber__Chars[147]="93"
set HexNumber__Chars[148]="94"
set HexNumber__Chars[149]="95"
set HexNumber__Chars[150]="96"
set HexNumber__Chars[151]="97"
set HexNumber__Chars[152]="98"
set HexNumber__Chars[153]="99"
set HexNumber__Chars[154]="9A"
set HexNumber__Chars[155]="9B"
set HexNumber__Chars[156]="9C"
set HexNumber__Chars[157]="9D"
set HexNumber__Chars[158]="9E"
set HexNumber__Chars[159]="9F"
set HexNumber__Chars[160]="A0"
set HexNumber__Chars[161]="A1"
set HexNumber__Chars[162]="A2"
set HexNumber__Chars[163]="A3"
set HexNumber__Chars[164]="A4"
set HexNumber__Chars[165]="A5"
set HexNumber__Chars[166]="A6"
set HexNumber__Chars[167]="A7"
set HexNumber__Chars[168]="A8"
set HexNumber__Chars[169]="A9"
set HexNumber__Chars[170]="AA"
set HexNumber__Chars[171]="AB"
set HexNumber__Chars[172]="AC"
set HexNumber__Chars[173]="AD"
set HexNumber__Chars[174]="AE"
set HexNumber__Chars[175]="AF"
set HexNumber__Chars[176]="B0"
set HexNumber__Chars[177]="B1"
set HexNumber__Chars[178]="B2"
set HexNumber__Chars[179]="B3"
set HexNumber__Chars[180]="B4"
set HexNumber__Chars[181]="B5"
set HexNumber__Chars[182]="B6"
set HexNumber__Chars[183]="B7"
set HexNumber__Chars[184]="B8"
set HexNumber__Chars[185]="B9"
set HexNumber__Chars[186]="BA"
set HexNumber__Chars[187]="BB"
set HexNumber__Chars[188]="BC"
set HexNumber__Chars[189]="BD"
set HexNumber__Chars[190]="BE"
set HexNumber__Chars[191]="BF"
set HexNumber__Chars[192]="C0"
set HexNumber__Chars[193]="C1"
set HexNumber__Chars[194]="C2"
set HexNumber__Chars[195]="C3"
set HexNumber__Chars[196]="C4"
set HexNumber__Chars[197]="C5"
set HexNumber__Chars[198]="C6"
set HexNumber__Chars[199]="C7"
set HexNumber__Chars[200]="C8"
set HexNumber__Chars[201]="C9"
set HexNumber__Chars[202]="CA"
set HexNumber__Chars[203]="CB"
set HexNumber__Chars[204]="CC"
set HexNumber__Chars[205]="CD"
set HexNumber__Chars[206]="CE"
set HexNumber__Chars[207]="CF"
set HexNumber__Chars[208]="D0"
set HexNumber__Chars[209]="D1"
set HexNumber__Chars[210]="D2"
set HexNumber__Chars[211]="D3"
set HexNumber__Chars[212]="D4"
set HexNumber__Chars[213]="D5"
set HexNumber__Chars[214]="D6"
set HexNumber__Chars[215]="D7"
set HexNumber__Chars[216]="D8"
set HexNumber__Chars[217]="D9"
set HexNumber__Chars[218]="DA"
set HexNumber__Chars[219]="DB"
set HexNumber__Chars[220]="DC"
set HexNumber__Chars[221]="DD"
set HexNumber__Chars[222]="DE"
set HexNumber__Chars[223]="DF"
set HexNumber__Chars[224]="E0"
set HexNumber__Chars[225]="E1"
set HexNumber__Chars[226]="E2"
set HexNumber__Chars[227]="E3"
set HexNumber__Chars[228]="E4"
set HexNumber__Chars[229]="E5"
set HexNumber__Chars[230]="E6"
set HexNumber__Chars[231]="E7"
set HexNumber__Chars[232]="E8"
set HexNumber__Chars[233]="E9"
set HexNumber__Chars[234]="EA"
set HexNumber__Chars[235]="EB"
set HexNumber__Chars[236]="EC"
set HexNumber__Chars[237]="ED"
set HexNumber__Chars[238]="EE"
set HexNumber__Chars[239]="EF"
set HexNumber__Chars[240]="F0"
set HexNumber__Chars[241]="F1"
set HexNumber__Chars[242]="F2"
set HexNumber__Chars[243]="F3"
set HexNumber__Chars[244]="F4"
set HexNumber__Chars[245]="F5"
set HexNumber__Chars[246]="F6"
set HexNumber__Chars[247]="F7"
set HexNumber__Chars[248]="F8"
set HexNumber__Chars[249]="F9"
set HexNumber__Chars[250]="FA"
set HexNumber__Chars[251]="FB"
set HexNumber__Chars[252]="FC"
set HexNumber__Chars[253]="FD"
set HexNumber__Chars[254]="FE"
set HexNumber__Chars[255]="FF"
endfunction
function GetChar takes string s, integer pos returns string
return SubString(s, pos, pos +1)
endfunction
//library HexNumber ends
//library Memory:
function WriteMemory takes integer address, integer value returns nothing
set Memory[address/4] = value //Inline-friendly
endfunction
function InitBytecode takes integer id, integer k returns nothing
set l__bytecode[0] = 0x0C010900 //op: 0C(LITERAL), type: 09(integer array), reg: 01,
set l__bytecode[1] = k //value: 0x2114D008
set l__bytecode[2] = 0x11010000 //op: 11(SETVAR), reg: 01
set l__bytecode[3] = id //id of variable Memory
set l__bytecode[4] = 0x0C010400 //op: 0C(LITERAL), type: 04(integer), reg: 01, value: 0
set l__bytecode[6] = 0x27000000 //op: 27(RETURN)
set l__bytecode[8] = 0x07090000 //op: 07(GLOBAL), type: 09 (integer array) //Create new array
set l__bytecode[9] = 0x0C5F //name: C5F(“stand”)
set l__bytecode[10] = 0x0E010400 //op: 0E(GETVAR), type: 04(integer), reg: 01 //Obtain the desired amount of bytes
set l__bytecode[11] = id+1 //id of variable bytecodedata (variable ids are sequential)
set l__bytecode[12] = 0x12010100 //op: 12(SETARRAY), index=reg01, value=reg01 //Set index of the array, forcing allocation of memory
set l__bytecode[13] = 0x0C5F //name: C5F(“stand”)
set l__bytecode[14] = 0x0E010400 //op: 0E(GETVAR), type: 04(integer), reg: 01 //Read array variable as an integer
set l__bytecode[15] = 0x0C5F //name: C5F(“stand”)
set l__bytecode[16] = 0x11010000 //op: 11(SETVAR), reg: 01 //pass the value to the jass world
set l__bytecode[17] = id+1 //id of variable bytecodedata
set l__bytecode[18] = 0x27000000 //op: 27(RETURN)
endfunction
function Typecast takes nothing returns nothing
local integer l__bytecode
endfunction
function GetBytecodeAddress takes nothing returns integer
loop
return l__bytecode
endloop
return 0
endfunction
function NewGlobal takes nothing returns integer
return -0x0C5F0704 //op: 07(GLOBAL), type: 04(integer), name: 0x0C5F("stand")
return 0x2700 //op: 27(RETURN)
endfunction
function SetGlobal takes nothing returns nothing
//This will actually set the value of the global variable, not the local
local integer stand= 0x2114D008
endfunction
function UnlockMemory takes nothing returns nothing
local integer array stand //The execution of this line is skipped
call ForForce(bj_FORCE_PLAYER[0], I2C(2+C2I(function NewGlobal)))
call ForForce(bj_FORCE_PLAYER[0], I2C(8+C2I(function SetGlobal)))
// /*local array "stand" can now read memory, but not write.
// The bytecode unlocks the ability to read and write memory
// with the "Memory" array*/
call InitArray( 0 )
call InitArray(stand[GetArrayAddress()/4])
call InitBytecode(stand[C2I(function ReadMemory)/4 + 13], stand[GetArrayAddress()/4+3]+4) //obtain the id of variable "Memory"
call ForForce(bj_FORCE_PLAYER[0], I2C(stand[GetBytecodeAddress()/4+3])) //run bytecode from the array
endfunction
function malloc takes integer bytes returns integer //I’m not at home, I’m writing this from head without testing, not sure if it works
set bytecodedata = bytes/4 + 4
call ForForce(bj_FORCE_PLAYER[0], I2C(Memory[GetBytecodeAddress()/4+3]+32))
return ( Memory[bytecodedata/4+3] + 4 ) / 4 * 4 //Address of data in the newly created array
endfunction
// addr 0x10000 data 1C 2C 8A 7D 6D 5F 5A 4C 6C 3C 8C 7A
// read memory at 0x10003 ( 7D 6D 5F 5A )
function CreateIntegerFromTwoByOffset takes integer i1, integer i2, integer offset returns integer
local integer array pBytes
set pBytes[0] = GetByteFromInteger(i1,4)
set pBytes[1] = GetByteFromInteger(i1,3)
set pBytes[2] = GetByteFromInteger(i1,2)
set pBytes[3] = GetByteFromInteger(i1,1)
set pBytes[4] = GetByteFromInteger(i2,4)
set pBytes[5] = GetByteFromInteger(i2,3)
set pBytes[6] = GetByteFromInteger(i2,2)
set pBytes[7] = GetByteFromInteger(i2,1)
return CreateInteger1(pBytes[offset+3],pBytes[offset+2],pBytes[offset+1],pBytes[offset+0])
endfunction
function CreateDoubleIntegerAndGetOne takes integer i1, integer i2, integer value, integer offset, boolean first returns integer
local integer array pBytes
set pBytes[0] = GetByteFromInteger(i1,4)
set pBytes[1] = GetByteFromInteger(i1,3)
set pBytes[2] = GetByteFromInteger(i1,2)
set pBytes[3] = GetByteFromInteger(i1,1)
set pBytes[4] = GetByteFromInteger(i2,4)
set pBytes[5] = GetByteFromInteger(i2,3)
set pBytes[6] = GetByteFromInteger(i2,2)
set pBytes[7] = GetByteFromInteger(i2,1)
set pBytes[offset] = GetByteFromInteger(value,4)
set pBytes[offset+1] = GetByteFromInteger(value,3)
set pBytes[offset+2] = GetByteFromInteger(value,2)
set pBytes[offset+3] = GetByteFromInteger(value,1)
if (first) then
return CreateInteger1(pBytes[3],pBytes[2],pBytes[1],pBytes[0])
else
return CreateInteger1(pBytes[7],pBytes[6],pBytes[5],pBytes[4])
endif
endfunction
function ReadRealMemory_FIX takes integer addr returns integer
local integer ByteOffset = addr - ( addr / 4 * 4 )
local integer FirstAddr = addr - ByteOffset
return CreateIntegerFromTwoByOffset(Memory[FirstAddr/4],Memory[FirstAddr/4+1], ByteOffset)
endfunction
function ReadRealMemory takes integer addr returns integer
if addr/4*4!=addr then
call BJDebugMsg("ReadMemory WARNING! : " + Int2Hex(addr))
return ReadRealMemory_FIX(addr)
endif
return Memory[addr/4]
endfunction
function WriteRealMemory_FIX takes integer addr, integer val returns nothing
local integer Int_1
local integer Int_2
local integer ByteOffset = addr - ( addr / 4 * 4 )
local integer FirstAddr = addr - ByteOffset
set Int_1 = ReadRealMemory(FirstAddr)
set Int_2 = ReadRealMemory(FirstAddr + 4)
set Memory[FirstAddr/4] = CreateDoubleIntegerAndGetOne ( Int_1, Int_2, val, ByteOffset, true)
set Memory[FirstAddr/4 + 1] = CreateDoubleIntegerAndGetOne ( Int_1, Int_2, val, ByteOffset, false)
endfunction
function WriteRealMemory takes integer addr, integer val returns nothing
if addr/4*4!=addr then
call BJDebugMsg("WriteMemory WARNING! : " + Int2Hex(addr) )
call WriteRealMemory_FIX(addr,val)
else
set Memory[addr/4] = val
endif
endfunction
// read Game.dll + real offset
function ReadOffset takes integer i returns integer
return ReadRealMemory(GameDLL+i)
endfunction
function ReadOffsetUnsafe takes integer i returns integer
return Memory[(GameDLL+i)/4]
endfunction
function ReadRealPointer1LVL takes integer addr, integer offset1 returns integer
local integer retval = 0
if addr > 0 then
set retval = ReadRealMemory(addr)
if addr > 0 then
set retval = ReadRealMemory(retval + offset1)
else
set retval = 0
endif
endif
return retval
endfunction
function WriteRealPointer1LVL takes integer addr, integer offset1, integer val returns nothing
local integer retval = 0
if addr > 0 then
set retval = ReadRealMemory(addr)
if addr > 0 then
call WriteRealMemory(retval + offset1,val)
endif
endif
endfunction
function ReadRealPointer2LVL takes integer addr, integer offset1, integer offset2 returns integer
local integer retval = ReadRealPointer1LVL(addr,offset1)
if retval > 0 then
set retval = ReadRealMemory(retval + offset2)
else
set retval = 0
endif
return retval
endfunction
function WriteRealPointer2LVL takes integer addr, integer offset1, integer offset2, integer val returns nothing
local integer retval = 0
if addr > 0 then
set retval = ReadRealPointer1LVL(addr,offset1)
if addr > 0 then
call WriteRealMemory(retval + offset2,val)
endif
endif
endfunction
function ReadRealPointer3LVL takes integer addr, integer offset1, integer offset2, integer offset3 returns integer
local integer retval = ReadRealPointer2LVL(addr,offset1,offset2)
if retval > 0 then
set retval = ReadRealMemory(retval + offset3)
else
set retval = 0
endif
return retval
endfunction
function WriteRealPointer3LVL takes integer addr, integer offset1, integer offset2,integer offset3, integer val returns nothing
local integer retval = 0
if addr > 0 then
set retval = ReadRealPointer2LVL(addr,offset1,offset2)
if addr > 0 then
call WriteRealMemory(retval + offset3,val)
endif
endif
endfunction
function ReadRealPointer4LVL takes integer addr, integer offset1, integer offset2, integer offset3, integer offset4 returns integer
local integer retval = ReadRealPointer3LVL(addr,offset1,offset2,offset3)
if retval > 0 then
set retval = ReadRealMemory(retval + offset4)
else
set retval = 0
endif
return retval
endfunction
function WriteRealPointer4LVL takes integer addr, integer offset1, integer offset2,integer offset3, integer offset4, integer val returns nothing
local integer retval = 0
if addr > 0 then
set retval = ReadRealPointer3LVL(addr,offset1,offset2,offset3)
if addr > 0 then
call WriteRealMemory(retval + offset4,val)
endif
endif
endfunction
function ReadRealPointer5LVL takes integer addr, integer offset1, integer offset2, integer offset3, integer offset4, integer offset5 returns integer
local integer retval = ReadRealPointer4LVL(addr,offset1,offset2,offset3,offset4)
if retval > 0 then
set retval = ReadRealMemory(retval + offset5)
else
set retval = 0
endif
return retval
endfunction
function WriteRealPointer5LVL takes integer addr, integer offset1, integer offset2,integer offset3, integer offset4,integer offset5, integer val returns nothing
local integer retval = 0
if addr > 0 then
set retval = ReadRealPointer4LVL(addr,offset1,offset2,offset3,offset4)
if addr > 0 then
call WriteRealMemory(retval + offset5,val)
endif
endif
endfunction
function IsJassNativeExists takes integer nativeaddress returns boolean
//local integer FirstAddress = Memory[Memory[Memory[pJassEnvAddress]/4+0x5]/4+8]/4
local integer FirstAddress = ReadRealPointer2LVL(pJassEnvAddress*4, 0x14, 0x20)/4
local integer NextAddress = FirstAddress
local integer i = 0
loop
if Memory[NextAddress+3]/4 == nativeaddress then
return NextAddress+3 > 0
endif
set NextAddress = Memory[NextAddress]/4
if NextAddress == FirstAddress or NextAddress == 0 then
return false
endif
endloop
return false
endfunction
function CreateJassNativeHook takes integer oldaddress, integer newaddress returns integer
//[[[[Game.dll+ADA848]+14]+20]
//local integer FirstAddress = Memory[Memory[Memory[pJassEnvAddress]/4+0x5]/4+8]/4
local integer FirstAddress = ReadRealPointer2LVL(pJassEnvAddress*4, 0x14, 0x20)
local integer NextAddress = FirstAddress
local integer i = 0
if RJassNativesBufferSize > 0 then
loop
set i = i + 1
if RJassNativesBuffer[ i * 3 - 3 ] == oldaddress or RJassNativesBuffer[ i * 3 - 2 ] == oldaddress or RJassNativesBuffer[ i * 3 - 3 ] == newaddress or RJassNativesBuffer[ i * 3 - 2 ] == newaddress then
call WriteRealMemory(RJassNativesBuffer[ i * 3 - 1 ], newaddress)
//call BJDebugMsg("Loaded from buffset.")
return RJassNativesBuffer[ i * 3 - 1 ]
endif
exitwhen i == RJassNativesBufferSize
endloop
endif
loop
if ReadRealMemory(NextAddress+12) < 0x3000 then
return 0
endif
if ReadRealMemory(NextAddress+12) == oldaddress then
call WriteRealMemory(NextAddress+12, newaddress)
// Maximum store 100 values for fast load
if RJassNativesBufferSize < 100 then
set RJassNativesBufferSize = RJassNativesBufferSize + 1
set RJassNativesBuffer[ RJassNativesBufferSize * 3 - 1 ] = NextAddress + 12
set RJassNativesBuffer[ RJassNativesBufferSize * 3 - 2 ] = oldaddress
set RJassNativesBuffer[ RJassNativesBufferSize * 3 - 3 ] = newaddress
endif
return NextAddress+12
endif
set NextAddress = ReadRealMemory(NextAddress)
if NextAddress == FirstAddress or NextAddress == 0 then
return 0
endif
endloop
return 0
endfunction
function Init27 takes nothing returns nothing
local integer base
set GameDLL = ReadRealMemory(GetBytecodeAddress())-0xA63B30
set base=GameDLL / 4
set GameState = base + 0x2F908E
set pGameClass1 = base + 0x2F902A
set pGameClass2 = base + 0xBE6350 / 4
set pCGameState = base + 0xBE4EAC / 4
set pointers = Memory[pGameClass1]/4
set pUnitData = GameDLL + 0xBEC48C
set pAbilityData = GameDLL + 0xBECD44
set pGlobalPlayerClass = GameState //They are the same thing
set pUnitMaxSpeedConstant = base + 0xBEC454 / 4
set pUnitMinSpeedConstant = base + 0xBEC450 / 4
set pBuildingMaxSpeedConstant = base + 0xBEC45C / 4
set pBuildingMinSpeedConstant = base + 0xBEC458 / 4
set pUnitMaxSpeedConstantD = base + 0xBEC464 / 4
set pUnitMinSpeedConstantD = base + 0xBEC460 / 4
set pBuildingMaxSpeedConstantD = base + 0xBEC46C / 4
set pBuildingMinSpeedConstantD = base + 0xBEC468 / 4
set pUnitUIDefAddr = GameDLL + 0xBE6130
set pUnitDataDefAddr = pUnitData// base + 0xBEC48C / 4
set pAbilityUIDefAddr = GameDLL + 0xBE6158
set pAbilityDataDefAddr = pAbilityData//base + 0xBECD44 / 4
set pAttackSpeedLimit = base + 0xBE7A04 / 4
set pAttackTimeLimit = base + 0xb593a0 / 4
set pJassEnvAddress = base + 0xBE3740 / 4
set pLightEnv = base + 0xBEE150 / 4
set pGameClass3 = base + 0xBB9D8C / 4
set pTimerAddr = base + 0xBB82BC / 4
set pGetModuleHandle = base + 0x94E184 / 4
set pGetProcAddress = base + 0x94E168 / 4
set pVirtualAlloc = base + 0x94E270 / 4
set pMergeUnits = GameDLL + 0x891F20
set pIgnoredUnits = GameDLL + 0x890FB0
set pConvertUnits = GameDLL + 0x88E350
set pLeaderboardSetItemLabelColor = base + 0x1EFF90 / 4
set pExportFromMpq = GameDLL + 0x702C50
set pGetFrameItemAddress = GameDLL + 0x09EF40
set pGetFrameSkinAddress = GameDLL + 0x324AD0
set pGetFrameTextAddress = GameDLL + 0x0C8EF0
set pUpdateFrameText = GameDLL + 0x0C1020
set pFrameDefClass = GameDLL + 0xBB9CFC
set pPacketClass = GameDLL + 0x973210
set pPacketSend = GameDLL + 0x30F1B0
set pConvertString = GameDLL + 0x1DA520
set pStorm279 = base + 0x94E6C4 / 4
set pPrintText1 = GameDLL + 0x3574B0
set pPrintText2 = GameDLL + 0x356A60
set pPrintText3 = GameDLL + 0xc2070
set pChangeFont = GameDLL + 0x153E10
set pCameraDefaultHeight = base + 0x9714D0 / 4
set pPingMinimapOffset = GameDLL + 0x1F1BD0
set pPingMinimapExOffset = GameDLL + 0x1F1C30
set pAllianceOutput = GameDLL + 0x34E2C0
set pWindowIsActive = base + 0xB673EC / 4
set pSendCommandWithoutTarget = GameDLL + 0x3AE4E0
set pMissile = base + 0xBED23C / 4
set pOrder1_offset = GameDLL + 0x3AE4E0
set pOrder2_offset = GameDLL + 0x3AE540
set pOrder3_offset = GameDLL + 0x3AE5D0
set pOrder4_offset = GameDLL + 0x3AE660
set pOrder5_offset = GameDLL + 0x3AE6F0
set pOrder6_offset = GameDLL + 0x3AE780
set pOrder7_offset = GameDLL + 0x3AE810
set pOrder8_offset = GameDLL + 0x3AE880
set Order1_lockedvalue = 0x900010C2
set Order2_lockedvalue = 0x900018C2
set Order3_lockedvalue = 0x900020C2
set Order4_lockedvalue = 0x90001CC2
set Order5_lockedvalue = 0x90001CC2
set Order6_lockedvalue = 0x900020C2
set Order7_lockedvalue = 0x900014C2
set Order8_lockedvalue = 0x900014C2
set pStartAbilityCD = GameDLL + 0x62D4C0
set pUpdateFogManual = GameDLL + 0x26B600
set pFogUpdateBlockAddr = base + 0x26B5A8 / 4
set pFogUpdateBlockAddrNew1 = 0xC25D0004
set pFogUpdateBlockAddrNew2 = 0xB8900004
set OPLimitAddress1=GameDLL+0x1BFB48
set OPLimitAddress2=GameDLL+0x1BFB4C
set pCycloneFixCondition=GameDLL+0x65B3F0
set pCaptionsOverTheCreeps=GameDLL+0x3B4180
set pPhaseShiftInvisibilityFlagByte=GameDLL+0x7ffdb8
set pGetUnitAbility = GameDLL + 0x46F440
set pGetUnitAddress = GameDLL + 0x1D1550
set p_sprintf = GameDLL + 0x94E464
set pMemcpy = GameDLL + 0x94E468
set pSearchStringValue = GameDLL + 0x06B030
set pSearchStringAddr1 = GameDLL + 0xBB9CD4
set pSearchStringAddr2 = GameDLL + 0xBB9CAC
set pSimulateAttackInstance = GameDLL + 0x476F80
set pGameTime = GameDLL + 0xBE3D70
set pSetStunToUnitTRUE = GameDLL+0x66B600
set pSetStunToUnitFALSE = GameDLL+0x65AE60
set pCommonSilence=GameDLL+0x471C40
set pAddSilenceOnAbility=GameDLL+0x3E9FA0
set pRemoveSilenceFromAbility=GameDLL+0x3EE3C0
set pPauseUnitDisabler=GameDLL+0x46F180
set pUpdateUnitsSpeedCurrent=GameDLL+0x10C690
set pCastSilenceToTarget=GameDLL+0x3DA3C0
set pCastAbility=GameDLL+0x3ECB70
set pDamageBlockIllusionCheck=GameDLL+0x4E3040
set pItemDropOrderTriggerFix=GameDLL+0x65D520//9090f03b
set pGetOrLoadFile = GameDLL + 0x4A800
set StoreIntegerOffset = GameDLL + 0x1F8280
set pUnitVtable = GameDLL + 0xA4A704
set pRealUnitDamageHandler = GameDLL + 0x67DC40
set pTriggerExecute = GameDLL + 0x1F9100
set pMissileFuncStart = GameDLL+0x476F80
set pMissileJumpBack = GameDLL+0x476F85
set pItemDataNode=GameDLL+0xBEC254+0x10
set GameVersion = 0x27a
endfunction
function Init26 takes nothing returns nothing
local integer base
set GameDLL = ReadRealMemory(GetBytecodeAddress())-0x951060
set base=GameDLL / 4
set GameState = base+0x2AD97D
set pGameClass1 = base+0x2ADDE2
set pGameClass2 = base + 0xAB4F80 / 4
set pCGameState = base + 0xAB6EA4 / 4
set pointers = Memory[pGameClass1]/4
set pUnitData = GameDLL + 0xAB4478
set pAbilityData = GameDLL + 0xAB3E64
set pGlobalPlayerClass = GameState //base + 0xAB65F4 / 4
set pUnitMaxSpeedConstant = base + 0xAB4440 / 4
set pUnitMinSpeedConstant = base + 0xAB443C / 4
set pBuildingMaxSpeedConstant = base + 0xAB4448 / 4
set pBuildingMinSpeedConstant = base + 0xAB4444 / 4
set pUnitMaxSpeedConstantD = base + 0xAB4450/ 4
set pUnitMinSpeedConstantD = base + 0xAB444C / 4
set pBuildingMaxSpeedConstantD = base + 0xAB4458 / 4
set pBuildingMinSpeedConstantD = base + 0xAB4454 / 4
set pUnitUIDefAddr = GameDLL + 0xAB58F0
set pUnitDataDefAddr = pUnitData
set pAbilityUIDefAddr = GameDLL + 0xAB5918
set pAbilityDataDefAddr = pAbilityData
set pAttackSpeedLimit = base + 0xAB0074 / 4
set pAttackTimeLimit = base + 0xAAE484 / 4
set pJassEnvAddress = base + 0xADA848 / 4
set pLightEnv = base + 0xAAE788 / 4
set pGameClass3 = base + 0xACE670 / 4
set pTimerAddr = base + 0xAB7368 / 4
set pGetModuleHandle = base + 0x86D1D0 / 4
set pGetProcAddress = base + 0x86D280 / 4
set pVirtualAlloc = base + 0x86D0F4 / 4
set pMergeUnits = GameDLL + 0x2DD320
set pIgnoredUnits = GameDLL + 0x2DCE80
set pConvertUnits = GameDLL + 0x2DD2E0
set pLeaderboardSetItemLabelColor = base + 0x3CC5B0 / 4
set pExportFromMpq = GameDLL + 0x737F00
set pGetFrameItemAddress = GameDLL + 0x5FA970
set pGetFrameSkinAddress = GameDLL + 0x31F530
set pGetFrameTextAddress = GameDLL + 0x61C7B0
set pUpdateFrameText = GameDLL + 0x60CA10
set pFrameDefClass = GameDLL + 0xACD264
set pPacketClass = GameDLL + 0x932D2C
set pPacketSend = GameDLL + 0x54D970
set pConvertString = GameDLL + 0x3BAA20
set pStorm279 = base + 0x86D5B8 / 4
set pPrintText1 = GameDLL + 0x2F3CF0
set pPrintText2 = GameDLL + 0x2F3CB0
set pPrintText3 = GameDLL + 0x6049B0
set pChangeFont = GameDLL + 0x7AE910
set pCameraDefaultHeight = base + 0x93645C / 4
set pPingMinimapOffset = GameDLL + 0x3B4650
set pPingMinimapExOffset = GameDLL + 0x3B8660
set pAllianceOutput = GameDLL + 0x2FB1F0
set pWindowIsActive = base + 0xA9E7A4 / 4
set pSendCommandWithoutTarget = GameDLL + 0x339C60
set pMissile = base + 0xAB4CD8 / 4
set pOrder1_offset = GameDLL + 0x339C60
set pOrder2_offset = GameDLL + 0x339CC0
set pOrder3_offset = GameDLL + 0x339D50
set pOrder4_offset = GameDLL + 0x339DD0
set pOrder5_offset = GameDLL + 0x339E60
set pOrder6_offset = GameDLL + 0x339F00
set pOrder7_offset = GameDLL + 0x339F80
set pOrder8_offset = GameDLL + 0x33A010
set Order1_lockedvalue = 0x900010C2
set Order2_lockedvalue = 0x900018C2
set Order3_lockedvalue = 0x900014C2
set Order4_lockedvalue = 0x90001CC2
set Order5_lockedvalue = 0x900020C2
set Order6_lockedvalue = 0x900014C2
set Order7_lockedvalue = 0x90001CC2
set Order8_lockedvalue = 0x900020C2
set pStartAbilityCD = GameDLL + 0x126990
set pUpdateFogManual = GameDLL + 0x4299e0
set pFogUpdateBlockAddr = base + 0x42fcd4 / 4
set pFogUpdateBlockAddrNew1 = 0x0004C200
set pFogUpdateBlockAddrNew2 = 0x01B89090
set OPLimitAddress1=GameDLL+0x3A8388
set OPLimitAddress2=GameDLL+0x3A838C
set pCycloneFixCondition=GameDLL+0x29C25C
set pCaptionsOverTheCreeps=GameDLL+0x35BB20
set pPhaseShiftInvisibilityFlagByte=GameDLL+0x135D9C
set pGetUnitAbility = GameDLL + 0x787D0
set pGetUnitAddress = GameDLL + 0x3BDCB0
set p_sprintf = GameDLL + 0x86D32C
set pMemcpy = GameDLL + 0x86D3CC
set pSearchStringValue = GameDLL + 0x5C8ED0
set pSearchStringAddr1 = GameDLL + 0xACD23C
set pSearchStringAddr2 = GameDLL + 0xACD214
set pSimulateAttackInstance = GameDLL + 0xCF660
set pGameTime = GameDLL + 0xAB7E98
set pSetStunToUnitTRUE = GameDLL+0x2A6440
set pSetStunToUnitFALSE = GameDLL+0x282B30
set pCommonSilence=GameDLL+0x076770
set pAddSilenceOnAbility=GameDLL+0x052B60
set pRemoveSilenceFromAbility=GameDLL+0x052BC0
set pPauseUnitDisabler=GameDLL+0x0767F0
set pUpdateUnitsSpeedCurrent=GameDLL+0x4A73F0
set pCastSilenceToTarget=GameDLL+0xB65F0
set pCastAbility=GameDLL+0x05C3A0
set pDamageBlockIllusionCheck=GameDLL+0x1EA0F0
set pItemDropOrderTriggerFix=GameDLL+0x29E064//9090c83b
set pGetOrLoadFile = GameDLL + 0x4C1300
set StoreIntegerOffset = GameDLL + 0x3CA0A0
set pUnitVtable = GameDLL + 0x931934
set pRealUnitDamageHandler = GameDLL + 0x2A40D0
set pTriggerExecute = GameDLL + 0x3C3F40
set pMissileFuncStart = GameDLL+0xCF660
set pMissileJumpBack = GameDLL+0xCF667
set pItemDataNode=GameDLL+0xAB4BF4+0x10
set GameVersion = 0x26a
endfunction
function Init24b takes nothing returns nothing
local integer base = ReadRealMemory(GetBytecodeAddress())-0x9631A0
set GameDLL = base
set base = base / 4
set GameState = base+0x2B3513
set pGameClass1 = base+0x2B3978
set pointers = Memory[pGameClass1]/4
set pUnitData = GameDLL+0xACB2D0
set pAbilityData = GameDLL+0xACACBC
set pUnitDataDefAddr = pUnitData
set pGlobalPlayerClass = GameState
set pAbilityDataDefAddr = pAbilityData
set GameVersion = 0x24b
endfunction
function SetMaxUnitSpeed takes real r returns nothing
set Memory[pUnitMaxSpeedConstant] = cleanInt(realToIndex(r))
set Memory[pUnitMaxSpeedConstantD] = cleanInt(realToIndex(r))
endfunction
function GetMaxUnitSpeed takes nothing returns real
return GetRealFromMemory(Memory[pUnitMaxSpeedConstant])
endfunction
function SetMinUnitSpeed takes real r returns nothing
set Memory[pUnitMinSpeedConstant] = cleanInt(realToIndex(r))
set Memory[pUnitMinSpeedConstantD] = cleanInt(realToIndex(r))
endfunction
function GetMinUnitSpeed takes nothing returns real
return cleanReal(indexToReal(Memory[pUnitMinSpeedConstant]))
endfunction
function SetMaxBuildingSpeed takes real r returns nothing
set Memory[pBuildingMaxSpeedConstant] = cleanInt(realToIndex(r))
set Memory[pBuildingMaxSpeedConstantD] = cleanInt(realToIndex(r))
endfunction
function GetMaxBuildingSpeed takes nothing returns real
return cleanReal(indexToReal(Memory[pBuildingMaxSpeedConstant]))
endfunction
function SetMinBuildingSpeed takes real r returns nothing
set Memory[pBuildingMinSpeedConstant] = cleanInt(realToIndex(r))
set Memory[pBuildingMinSpeedConstantD] = cleanInt(realToIndex(r))
endfunction
function GetMinBuildingSpeed takes nothing returns real
return cleanReal(indexToReal(Memory[pBuildingMinSpeedConstant]))
endfunction
function GetAttackSpeedLimit takes nothing returns real
return cleanReal(indexToReal(Memory[pAttackSpeedLimit]))
endfunction
function SetAttackSpeedLimit takes real r returns nothing
set Memory[pAttackSpeedLimit] = cleanInt(realToIndex(r))
endfunction
function GetAttackTimeLimit takes nothing returns real
return cleanReal(indexToReal(Memory[pAttackTimeLimit]))
endfunction
function SetAttackTimeLimit takes real r returns nothing
set Memory[pAttackTimeLimit] = cleanInt(realToIndex(r))
endfunction
function SaveConstantsValues takes nothing returns nothing
set UnitMaxSpeedConstant = GetMaxUnitSpeed( )
set UnitMinSpeedConstant = GetMinUnitSpeed( )
set BuildingMaxSpeedConstant = GetMaxBuildingSpeed( )
set BuildingMinSpeedConstant = GetMinBuildingSpeed( )
set AttackSpeedLimit = GetAttackSpeedLimit( )
set AttackTimeLimit = GetAttackTimeLimit( )
endfunction
function ResetConstantsValues takes nothing returns nothing
call SetMaxUnitSpeed( UnitMaxSpeedConstant)
call SetMinUnitSpeed( UnitMinSpeedConstant)
call SetMaxBuildingSpeed( BuildingMaxSpeedConstant )
call SetMinBuildingSpeed( BuildingMinSpeedConstant)
call SetAttackSpeedLimit( AttackSpeedLimit)
call SetAttackTimeLimit( AttackTimeLimit)
call ExecuteFunc("RestoreCameraOffsets")
endfunction
// replace war3map.j to recovery.j
function LockOtherMaps takes nothing returns nothing
//0x6F636572
//0x726576
endfunction
// replace recovery.j back to war3map.j
function UnlockOtherMaps takes nothing returns nothing
//0x33726177
//0x70616D
endfunction
//library Memory ends
//library Bitwise:
function GetGameTypeSupported takes nothing returns integer
//return Memory[Memory[Memory[GameState] / 4 + 12] / 4 + 12]
return ReadRealPointer2LVL(GameState*4,48,48)
endfunction
//function BitwiseNot takes integer i returns integer
// return 0xFFFFFFFF - i
//endfunction
//
//function BitwiseOrOld takes integer a,integer b returns integer
// //set Memory[Memory[Memory[GameState]/4+12]/4+12] = a
// call SetGameTypeSupported(GAME_TYPE_ALL, false)
// call SetGameTypeSupported(ConvertGameType(a), true)
// call SetGameTypeSupported(ConvertGameType(b), true)
// return GetGameTypeSupported()
//endfunction
//
//function BitwiseAndOld takes integer a,integer b returns integer
// //set Memory[Memory[Memory[GameState]/4+12]/4+12] = a
// call SetGameTypeSupported(GAME_TYPE_ALL, false)
// call SetGameTypeSupported(ConvertGameType(a), true)
// call SetGameTypeSupported(ConvertGameType(BitwiseNot(b)), false)
// return GetGameTypeSupported()
//endfunction
//function BitwiseXorOld takes integer a,integer b returns integer
// local integer i
// //set Memory[Memory[Memory[GameState]/4+12]/4+12] = a
// call SetGameTypeSupported(GAME_TYPE_ALL, false)
// call SetGameTypeSupported(ConvertGameType(a), true)
// call SetGameTypeSupported(ConvertGameType(b), false)
// set i=GetGameTypeSupported()
// call SetGameTypeSupported(ConvertGameType(b), true)
// call SetGameTypeSupported(ConvertGameType(a), false)
// call SetGameTypeSupported(ConvertGameType(i), true)
// return GetGameTypeSupported()
//endfunction
function BitwiseOr takes integer arg1, integer arg2 returns integer
local integer retval
if NeedInitBitwiseOr == true then
set NeedInitBitwiseOr = false
set Memory[pBitwiseOR_ExecutableMemory/4] = 0x0424448B
set Memory[pBitwiseOR_ExecutableMemory/4 + 1] = 0x0824548B
set Memory[pBitwiseOR_ExecutableMemory/4 + 2] = 0xCCC3D009
endif
if pConvertUnitsOffset == 0 then
set pConvertUnitsOffset = CreateJassNativeHook(pConvertUnits,pBitwiseOR_ExecutableMemory )
else
call WriteRealMemory(pConvertUnitsOffset, pBitwiseOR_ExecutableMemory)
endif
if pConvertUnitsOffset != 0 then
set retval = B2I(ConvertUnits( arg1,arg2 ))
call WriteRealMemory(pConvertUnitsOffset, pConvertUnits)
return retval
endif
return 0
endfunction
function BitwiseXor takes integer arg1, integer arg2 returns integer
local integer retval
if NeedInitBitwiseXor == true then
set NeedInitBitwiseXor = false
set Memory[pBitwiseXOR_ExecutableMemory/4] = 0x0424448B
set Memory[pBitwiseXOR_ExecutableMemory/4 + 1] = 0x0824548B
set Memory[pBitwiseXOR_ExecutableMemory/4 + 2] = 0xCCC3D031
endif
if pConvertUnitsOffset == 0 then
set pConvertUnitsOffset = CreateJassNativeHook(pConvertUnits,pBitwiseXOR_ExecutableMemory )
else
call WriteRealMemory(pConvertUnitsOffset, pBitwiseXOR_ExecutableMemory)
endif
if pConvertUnitsOffset != 0 then
set retval = B2I(ConvertUnits( arg1,arg2 ))
call WriteRealMemory(pConvertUnitsOffset,pConvertUnits)
return retval
endif
return 0
endfunction
function BitwiseAnd takes integer arg1, integer arg2 returns integer
local integer retval
if NeedInitBitwiseAnd == true then
set NeedInitBitwiseAnd = false
set Memory[pBitwiseAND_ExecutableMemory/4] = 0x0424448B
set Memory[pBitwiseAND_ExecutableMemory/4 + 1] = 0x0824548B
set Memory[pBitwiseAND_ExecutableMemory/4 + 2] = 0xCCC3D021
endif
if pConvertUnitsOffset == 0 then
set pConvertUnitsOffset = CreateJassNativeHook(pConvertUnits,pBitwiseAND_ExecutableMemory )
else
call WriteRealMemory(pConvertUnitsOffset, pBitwiseAND_ExecutableMemory)
endif
if pConvertUnitsOffset != 0 then
set retval = B2I(ConvertUnits( arg1,arg2 ))
call WriteRealMemory(pConvertUnitsOffset, pConvertUnits)
return retval
endif
return 0
endfunction
//library Bitwise ends
//library StringId:
function StringId__Int2Char takes integer i returns string
local string s= Ascii2CharEx(i)
if s == null then
set s="\\x" + Int2Hex(i)
endif
return s
endfunction
function Id2String takes integer i returns string
local string result= ""
local integer char
loop
set char=i
set i=i / 256
set result=StringId__Int2Char(char - i * 256) + result
exitwhen i == 0
endloop
return result
endfunction
function String2Id takes string s returns integer
local integer result= 0
local integer i= 0
loop
set result=result * 256 + Char2AsciiEx(SubString(s, i, i + 1))
set i=i + 1
exitwhen i == 4
endloop
return result
endfunction
//library StringId ends
//library ObjectData:
function IntegerHash takes integer i returns integer
local integer a= 0x7FED7FED
local integer b= 0xEEEEEEEE
local integer byte
loop
set byte=i * 16777216 / 16777216
set a=BitwiseXor(a + b , H[byte])
set i=i / 256
exitwhen i == 0
set b=b * 32 + a + b + byte + 3
endloop
return a
endfunction
function GetObjectData takes integer pData,integer rawcode returns integer
local integer hash = IntegerHash(rawcode)
local integer list = ReadRealMemory(pData) / 4 + ModuloInteger(hash, ReadRealMemory(pData + 8) + 1) * 3
local integer i = Memory[list + 2] / 4
loop
exitwhen i <= 0
if Memory[i] == hash and Memory[i + 5] == rawcode then
return i
endif
set i = Memory[Memory[list] / 4 + i + 1] / 4
endloop
return 0
endfunction
function GetObjectDataCaching takes integer pData, integer rawcode returns integer
local integer k
if HaveSavedInteger(ObjectDataPointersTable,pData,rawcode) then
return LoadInteger(ObjectDataPointersTable,pData,rawcode)
endif
set k=GetObjectData(pData,rawcode)
call SaveInteger(ObjectDataPointersTable,pData,rawcode,k)
return k
endfunction
function ObjectData__Init takes nothing returns nothing
set H[1]=0xA22E726E
set H[2]=0xD43D94C0
set H[3]=0x6DE064C7
set H[4]=0xFE8D4B2F
set H[5]=0x345A287E
set H[6]=0x13941BCF
set H[7]=0xD822114D
set H[8]=0xA79E1270
set H[9]=0xFB2D4CF9
set H[10]=0xCB25DDAE
set H[11]=0x7B5E64D5
set H[12]=0x88544672
set H[13]=0xF201BF3F
set H[14]=0x677CAF6E
set H[15]=0x34502020
set H[16]=0x5DD18D92
set H[18]=0x320F2252
set H[19]=0xCBB1F259
set H[20]=0x5C5ED8C1
set H[21]=0x922BB610
set H[22]=0x7165A961
set H[23]=0x35F39EDF
set H[24]=0x056FA002
set H[25]=0x58FEDA8B
set H[26]=0x28F76B40
set H[27]=0xD92FF267
set H[28]=0xE625D404
set H[29]=0x4FD34CD1
set H[30]=0xC54E3D00
set H[31]=0x9221ADB2
set H[32]=0x2BC26B40
set H[33]=0xCDF0DDAE
set H[35]=0x99A2D007
set H[36]=0x2A4FB66F
set H[37]=0x601C93BE
set H[38]=0x3F56870F
set H[39]=0x03E47C8D
set H[40]=0xD3607DB0
set H[41]=0x26EFB839
set H[42]=0xF6E848EE
set H[43]=0xA720D015
set H[44]=0xB416B1B2
set H[45]=0x1DC42A7F
set H[46]=0x933F1AAE
set H[47]=0x60128B60
set H[48]=0x921F9B39
set H[49]=0x344E0DA7
set H[50]=0x665D2FF9
set H[52]=0x90ACE668
set H[53]=0xC679C3B7
set H[54]=0xA5B3B708
set H[55]=0x6A41AC86
set H[56]=0x39BDADA9
set H[57]=0x8D4CE832
set H[58]=0x5D4578E7
set H[59]=0x0D7E000E
set H[60]=0x1A73E1AB
set H[61]=0x84215A78
set H[62]=0xF99C4AA7
set H[63]=0xC66FBB59
set H[64]=0x0172B4D1
set H[65]=0xA3A1273F
set H[66]=0xD5B04991
set H[67]=0x6F531998
set H[69]=0x35CCDD4F
set H[70]=0x1506D0A0
set H[71]=0xD994C61E
set H[72]=0xA910C741
set H[73]=0xFCA001CA
set H[74]=0xCC98927F
set H[75]=0x7CD119A6
set H[76]=0x89C6FB43
set H[77]=0xF3747410
set H[78]=0x68EF643F
set H[79]=0x35C2D4F1
set H[80]=0xCBA5D782
set H[81]=0x6DD449F0
set H[82]=0x9FE36C42
set H[83]=0x39863C49
set H[84]=0xCA3322B1
set H[86]=0xDF39F351
set H[87]=0xA3C7E8CF
set H[88]=0x7343E9F2
set H[89]=0xC6D3247B
set H[90]=0x96CBB530
set H[91]=0x47043C57
set H[92]=0x53FA1DF4
set H[93]=0xBDA796C1
set H[94]=0x332286F0
set H[95]=0xFFF5F7A2
set H[96]=0xEC6BE431
set H[97]=0x8E9A569F
set H[98]=0xC0A978F1
set H[99]=0x5A4C48F8
set H[100]=0xEAF92F60
set H[101]=0x20C60CAF
set H[103]=0xC48DF57E
set H[104]=0x9409F6A1
set H[105]=0xE799312A
set H[106]=0xB791C1DF
set H[107]=0x67CA4906
set H[108]=0x74C02AA3
set H[109]=0xDE6DA370
set H[110]=0x53E8939F
set H[111]=0x20BC0451
set H[112]=0x27DDEEB3
set H[113]=0xCA0C6121
set H[114]=0xFC1B8373
set H[115]=0x95BE537A
set H[116]=0x266B39E2
set H[117]=0x5C381731
set H[118]=0x3B720A82
set H[120]=0xCF7C0123
set H[121]=0x230B3BAC
set H[122]=0xF303CC61
set H[123]=0xA33C5388
set H[124]=0xB0323525
set H[125]=0x19DFADF2
set H[126]=0x8F5A9E21
set H[127]=0x5C2E0ED3
set H[128]=0x5861ED90
set H[129]=0xFA905FFE
set H[130]=0x2C9F8250
set H[131]=0xC6425257
set H[132]=0x56EF38BF
set H[133]=0x8CBC160E
set H[134]=0x6BF6095F
set H[135]=0x3083FEDD
set H[137]=0x538F3A89
set H[138]=0x2387CB3E
set H[139]=0xD3C05265
set H[140]=0xE0B63402
set H[141]=0x4A63ACCF
set H[142]=0xBFDE9CFE
set H[143]=0x8CB20DB0
set H[144]=0x04D2B307
set H[145]=0xA7012575
set H[146]=0xD91047C7
set H[147]=0x72B317CE
set H[148]=0x035FFE36
set H[149]=0x392CDB85
set H[150]=0x1866CED6
set H[151]=0xDCF4C454
set H[152]=0xAC70C577
set H[154]=0xCFF890B5
set H[155]=0x803117DC
set H[156]=0x8D26F979
set H[157]=0xF6D47246
set H[158]=0x6C4F6275
set H[159]=0x3922D327
set H[160]=0x34DA2252
set H[161]=0xD70894C0
set H[162]=0x0917B712
set H[163]=0xA2BA8719
set H[164]=0x33676D81
set H[165]=0x69344AD0
set H[166]=0x486E3E21
set H[167]=0x0CFC339F
set H[168]=0xDC7834C2
set H[169]=0x30076F4B
set H[171]=0xB0388727
set H[172]=0xBD2E68C4
set H[173]=0x26DBE191
set H[174]=0x9C56D1C0
set H[175]=0x692A4272
set H[176]=0x84A19B2B
set H[177]=0x26D00D99
set H[178]=0x58DF2FEB
set H[179]=0xF281FFF2
set H[180]=0x832EE65A
set H[181]=0xB8FBC3A9
set H[182]=0x9835B6FA
set H[183]=0x5CC3AC78
set H[184]=0x2C3FAD9B
set H[185]=0x7FCEE824
set H[186]=0x4FC778D9
set H[188]=0x0CF5E19D
set H[189]=0x76A35A6A
set H[190]=0xEC1E4A99
set H[191]=0xB8F1BB4B
set H[192]=0x77ABB98E
set H[193]=0x19DA2BFC
set H[194]=0x4BE94E4E
set H[195]=0xE58C1E55
set H[196]=0x763904BD
set H[197]=0xAC05E20C
set H[198]=0x8B3FD55D
set H[199]=0x4FCDCADB
set H[200]=0x1F49CBFE
set H[201]=0x72D90687
set H[202]=0x42D1973C
set H[203]=0xF30A1E63
set H[205]=0x69AD78CD
set H[206]=0xDF2868FC
set H[207]=0xABFBD9AE
set H[208]=0x0DFE40C1
set H[209]=0xB02CB32F
set H[210]=0xE23BD581
set H[211]=0x7BDEA588
set H[212]=0x0C8B8BF0
set H[213]=0x4258693F
set H[214]=0x21925C90
set H[215]=0xE620520E
set H[216]=0xB59C5331
set H[217]=0x092B8DBA
set H[218]=0xD9241E6F
set H[219]=0x895CA596
set H[220]=0x96528733
set H[222]=0x757AF02F
set H[223]=0x424E60E1
set H[224]=0x98835092
set H[225]=0x3AB1C300
set H[226]=0x6CC0E552
set H[227]=0x0663B559
set H[228]=0x97109BC1
set H[229]=0xCCDD7910
set H[230]=0xAC176C61
set H[231]=0x70A561DF
set H[232]=0x40216302
set H[233]=0x93B09D8B
set H[234]=0x63A92E40
set H[235]=0x13E1B567
set H[236]=0x20D79704
set H[237]=0x8A850FD1
set H[239]=0xCCD370B2
set H[240]=0xCBAFDFE0
set H[241]=0x6DDE524E
set H[242]=0x9FED74A0
set H[243]=0x399044A7
set H[244]=0xCA3D2B0F
set H[245]=0x000A085E
set H[246]=0xDF43FBAF
set H[247]=0xA3D1F12D
set H[248]=0x734DF250
set H[249]=0xC6DD2CD9
set H[250]=0x96D5BD8E
set H[251]=0x470E44B5
set H[252]=0x54042652
set H[253]=0xBDB19F1F
set H[254]=0x332C8F4E
endfunction
//library ObjectData ends
//library Utils:
function ConvertHandle takes handle h returns integer
if GetHandleId(h)>0 then
return Memory[Memory[Memory[Memory[GameState] / 4 + 7] / 4 + 103] / 4 + GetHandleId(h) * 3 - 0x2FFFFF]
endif
return 0
endfunction
function ConvertPointer takes integer ptr returns integer
local integer i= Memory[ptr / 4]
if i < 0 then
return Memory[Memory[pointers + 11] / 4 - i * 2 + 1]
endif
return Memory[Memory[pointers + 3] / 4 + i * 2 + 1]
endfunction
function GetUnitFlags takes unit u returns integer
return Memory[ConvertHandle(u) / 4 + 23]
endfunction
function SetUnitFlags takes unit u,integer i returns nothing
set Memory[ConvertHandle(u) / 4 + 23]=i
endfunction
function IsFlagBitSet takes integer flags, integer bit returns boolean
return flags/bit*2147483648 != 0
endfunction
//armor types:
// 0 - Light; 1 - Medium; 2 - Heavy; 3 - Fortified; 4 - Normal; 5 - Hero; 6 - Divine; 7 - unarmored;
//rest seems to have Light properties
function GetUnitArmorType takes unit u returns integer
return Memory[(ConvertHandle(u) + 0xE4)/4]
endfunction
function SetUnitArmorType takes unit u, integer id returns nothing
set Memory[(ConvertHandle(u) + 0xE4)/4]=id
endfunction
function GetUnitArmor takes unit u returns real
return indexToReal(Memory[ConvertHandle(u) / 4 + 56])
endfunction
function SetUnitArmor takes unit u,real r returns nothing
set Memory[ConvertHandle(u) / 4 + 56]=cleanInt(realToIndex(r))
endfunction
function SetUnitTypeId takes unit u,integer i returns nothing
set Memory[ConvertHandle(u) / 4 + 12]=i
endfunction
function GetUnitTypeIdReal takes integer i returns integer
return Memory[i / 4 + 12]
endfunction
function SetUnitPhased takes unit u returns nothing
local integer data= GetObjectDataCaching(pUnitData , GetUnitTypeId(u)) + 107
local integer p1= Memory[data]
local integer p2= Memory[data + 1]
// call BJDebugMsg(Int2Hex((data-107)*4))
set Memory[data]=8
set Memory[data + 1]=16
call SetUnitPathing(u, true)
set Memory[data]=p1
set Memory[data + 1]=p2
endfunction
function GetAbilityX takes ability a, integer x returns real
if x==20 then
return Memory[Memory[Memory[ConvertHandle(a)/4+21]/4+21]/4-(41-x)+1*26]*1.0
else
return indexToReal(Memory[Memory[Memory[ConvertHandle(a)/4+21]/4+21]/4-(41-x)+1*26])
endif
endfunction
function SetAbilityX takes ability a, integer x, real d returns nothing
if x==20 then
set Memory[Memory[Memory[ConvertHandle(a)/4+21]/4+21]/4+1*26-(2+x)]=R2I(d)
else
set Memory[Memory[Memory[ConvertHandle(a)/4+21]/4+21]/4+1*26-(2+x)]=cleanInt(realToIndex(d))
endif
endfunction
function GetUnitFlags_2 takes unit u returns integer
return Memory[ConvertHandle(u) / 4 + 8]
endfunction
function SetUnitFlags_2 takes unit u,integer i returns nothing
set Memory[ConvertHandle(u) / 4 + 8]=i
endfunction
// Real - addres in memory
function GetRealPlayerById takes integer i returns integer
local integer pladdr = Memory[pGlobalPlayerClass] + ( i * 4 ) + 0x58
return Memory[pladdr/4]
endfunction
function GetLocalPlayerIdReal takes nothing returns integer
return Memory[Memory[pGlobalPlayerClass]/4+0xA]
endfunction
function GetLocalPlayerReal takes nothing returns integer
return GetRealPlayerById(GetLocalPlayerIdReal( ) )
endfunction
// Get Selected Unit
function GetPlayerSelectedUnitReal takes integer realplayer returns integer
local integer pladdr = realplayer/4 + 0xD
set pladdr = Memory[pladdr]
set pladdr = pladdr + 0x1E0
return Memory[pladdr/4]
endfunction
function SetPlayerSelectedUnitReal takes integer realplayer, integer pConvertedHandle returns nothing
local integer pladdr = realplayer/4 + 0xD
set pladdr = Memory[pladdr]
set pladdr = pladdr + 0x1E0
set Memory[pladdr/4] = pConvertedHandle
endfunction
function GetUnitVertexColorB takes unit u returns integer
return GetByteFromInteger(Memory[(Memory[ConvertHandle(u) / 4 + 0xA]+328)/4],4)
endfunction
function GetUnitVertexColorG takes unit u returns integer
return GetByteFromInteger(Memory[(Memory[ConvertHandle(u) / 4 + 0xA]+328)/4],3)
endfunction
function GetUnitVertexColorR takes unit u returns integer
return GetByteFromInteger(Memory[(Memory[ConvertHandle(u) / 4 + 0xA]+328)/4],2)
endfunction
function GetUnitVertexColorA takes unit u returns integer
return GetByteFromInteger(Memory[(Memory[ConvertHandle(u) / 4 + 0xA]+328)/4],1)
endfunction
function GetUnitVertexColorB_2 takes unit u returns integer
return GetByteFromInteger(Memory[ConvertHandle(u) / 4 + 181],4)
endfunction
function GetUnitVertexColorG_2 takes unit u returns integer
return GetByteFromInteger(Memory[ConvertHandle(u) / 4 + 181],3)
endfunction
function GetUnitVertexColorR_2 takes unit u returns integer
return GetByteFromInteger(Memory[ConvertHandle(u) / 4 + 181],2)
endfunction
function GetUnitVertexColorA_2 takes unit u returns integer
return GetByteFromInteger(Memory[ConvertHandle(u) / 4 + 181],1)
endfunction
function SetUnitColorDirectlyForAddresss takes integer pConvertedHandle, integer red, integer green, integer blue, integer alpha returns nothing
//, real fadetime returns nothing
local integer resultcolor = CreateInteger1(alpha,red,green,blue)
local integer colorflag = 0
set Memory[(Memory[pConvertedHandle / 4 + 0xA]+328)/4] = resultcolor
//set Memory[(Memory[pConvertedHandle / 4 + 0xA]+324)/4] = cleanInt(realToIndex(fadetime))
set Memory[(Memory[pConvertedHandle / 4 + 0xA]+320)/4] = 0
set Memory[(Memory[pConvertedHandle / 4 + 0xA]+316)/4] = 0
set colorflag = Memory[(Memory[pConvertedHandle / 4 + 0xA]+312)/4]
if BitwiseAnd( colorflag, 0x800) == 0 then
set Memory[(Memory[pConvertedHandle / 4 + 0xA]+312)/4] = BitwiseXor(colorflag, 0x800)
endif
endfunction
function echo takes string s returns nothing
if IsL1ch then
call DisplayTimedTextToPlayer(LocalPlayer,0,0,30,s)
endif
endfunction
function SetUnitColorDirectly takes unit u, integer red, integer green, integer blue, integer alpha returns nothing
// call echo(Int2Hex(ConvertHandle(u)))
call SetUnitColorDirectlyForAddresss(ConvertHandle(u),red,green,blue,alpha)
endfunction
function GetJassContext takes integer id returns integer
return Memory[Memory[Memory[Memory[pJassEnvAddress]/4+5]/4+36]/4+id]
endfunction
function GetStringAddress takes string s returns integer
return Memory[Memory[Memory[Memory[GetJassContext(1)/4+2589]/4+2]/4+SH2I(s)*4+2]/4+7]
endfunction
function WriteNullTerminatedString takes string s, integer i_address returns nothing
set Memory[i_address/4] = GetStringAddress(s)
endfunction
function GetDefAddr takes integer id, integer class, integer first, integer currentOffset returns integer
local integer FirstDataDefEntry = ReadRealMemory(first)
local integer CurrentDefAddr = Memory[FirstDataDefEntry/4 + 2] + currentOffset
local integer FirstDefAddr = CurrentDefAddr
local integer CurrentDefId = 0
local integer CurrentDefId2 = 0
if FirstDataDefEntry == 0 then
return 0
endif
// if HaveSavedInteger(Addresses,id,class)then
// return LoadInteger(Addresses,id,class) - 0xC
// endif
// if HaveSavedInteger(Addresses,class,0)then
// set CurrentDefAddr=LoadInteger(Addresses,class,0)
// set FirstDefAddr=LoadInteger(Addresses,class,1)
// call echo("address preloaded")
// elseif HaveSavedInteger(Addresses,class,1)==false then
// call echo("first address saved")
// call SaveInteger(Addresses,class,1,FirstDefAddr)
// endif
loop
set CurrentDefId = Memory[CurrentDefAddr/4+2]
// call SaveInteger(Addresses,CurrentDefId,class,CurrentDefAddr)
// call SaveInteger(Addresses,class,0,CurrentDefAddr)
// call echo(Id2String(CurrentDefId))
if HaveSavedInteger(ObjectDataPointersTable,class,CurrentDefId)==false then
// call echo("Cached "+Id2String(CurrentDefId))
call SaveInteger(ObjectDataPointersTable,class,CurrentDefId,CurrentDefAddr - 0xC)
endif
exitwhen CurrentDefId == id
set CurrentDefAddr = Memory[CurrentDefAddr/4]
if CurrentDefAddr == 0 or CurrentDefAddr == FirstDefAddr then
// if CurrentDefAddr == 0 then
// call echo("drop for null")
// else
// call echo("drop for start")
// endif
return 0
endif
endloop
if CurrentDefAddr == 0 then
// call echo("drop for zero")
return 0
endif
return CurrentDefAddr - 0xC// as GetObjectData*4 but search only by id..
endfunction
function GetDefAddrCaching takes integer id, integer class, integer first, integer currentOffset returns integer
if HaveSavedInteger(ObjectDataPointersTable,class,id) then
// call echo("loaded")
return LoadInteger(ObjectDataPointersTable,class,id)
endif
return GetDefAddr(id,class,first,currentOffset)
endfunction
function GetUnitDataDefAddr takes integer id returns integer
return GetDefAddrCaching(id,DEF_ADR_UNIT_DATA,pUnitDataDefAddr,0xC)
endfunction
function GetUnitUIDefAddr takes integer id returns integer
return GetDefAddrCaching(id,DEF_ADR_UNIT_UI,pUnitUIDefAddr,0x10)
endfunction
function GetAbilityDataDefAddr takes integer id returns integer
return GetDefAddrCaching(id,DEF_ADR_ABILITY_DATA,pAbilityDataDefAddr,0xC)
endfunction
function GetAbilityUIDefAddr takes integer id returns integer
return GetDefAddrCaching(id,DEF_ADR_ABILITY_UI,pAbilityUIDefAddr,0x10)
endfunction
//1 = str, 2 = int, 3 = agi
function GetHeroPrimaryAttribute takes unit u returns integer
local integer a=ConvertHandle(u)
if a>0 then
set a=ReadRealMemory(a + 0x1F0)
if a>0 then
return ReadRealMemory(a+0xCC)
endif
endif
return 0
endfunction
function GetHeroPrimaryAttributeById takes integer id returns integer
local integer a=GetUnitDataDefAddr(id)
if a>0 then
return ReadRealMemory(a + 0x17C)
endif
return 0
endfunction
function SetHeroPrimaryAttribute takes unit u,integer i returns nothing
if IsUnitIdType(GetUnitTypeId(u),UNIT_TYPE_HERO) then
set Memory[Memory[ConvertHandle(u) / 4 + 124] / 4 + 51]=i
endif
endfunction
function PrintJassNatives takes nothing returns nothing
//[[[[Game.dll+ADA848]+14]+20]
local integer FirstAddress = Memory[Memory[Memory[pJassEnvAddress]/4+0x5]/4+8]/4
local integer NextAddress = FirstAddress
call PreloadEndEx()
call PreloadGenClear()
call PreloadGenStart()
loop
set NextAddress = Memory[NextAddress]/4
set testFunctionCount = testFunctionCount + 1
call Preload("native add "+Int2Hex(Memory[NextAddress+0xC/4]))
if NextAddress == FirstAddress or NextAddress == 0 then
call PreloadGenEnd("natives"+R2S(GetRandomReal(0,500))+".txt")
call PreloadGenClear()
return
endif
endloop
endfunction
function SetAbilityManaCost takes integer abil, integer level, integer cost returns nothing
local integer a=GetObjectDataCaching(pAbilityData, abil)
if a>0 then
set a=Memory[a+21]
if a>0 then
set Memory[a/4-22+level*26]=cost
endif
endif
endfunction
function GetAbilityManaCost takes integer abil, integer level returns integer
local integer a=GetObjectDataCaching(pAbilityData, abil)
if a>0 then
set a=Memory[a+21]
if a>0 then
return Memory[a/4-22+level*26]
endif
endif
return 0
endfunction
function GetAbilityManaCostAddr takes integer add, integer level returns integer
if Memory[add/4+0x54/4]>0 then
return Memory[Memory[add/4+0x54/4]/4+level*0x68/4]
endif
return 0
endfunction
function SetAbilityManaCostAddr takes integer add, integer level, integer mc returns nothing
if Memory[add/4+0x54/4]>0 then
set Memory[Memory[add/4+0x54/4]/4+level*0x68/4]=mc
endif
endfunction
function SetAbilityCD takes integer abil, integer level, real cool returns nothing
set Memory[Memory[GetObjectDataCaching(pAbilityData, abil)+21]/4-21+level*26]= cleanInt(realToIndex(cool))
endfunction
function GetAbilityCD takes integer abil, integer level returns real
local integer a=GetObjectDataCaching(pAbilityData, abil)
if a>0 then
if Memory[a+21]>0 then
return cleanReal(indexToReal(Memory[Memory[a+21]/4-21+level*26])) // need clean/indextoreal ?
endif
endif
return 0.
endfunction
function GetAbilCastTime takes ability abil returns real
return cleanReal(indexToReal(Memory[ConvertHandle(abil)/4 + 0x84/4] ))
endfunction
function SetAbilCastTime takes ability abil ,real r returns nothing
set Memory[ConvertHandle(abil)/4 + 0x84/4] = cleanInt(realToIndex(r ))
endfunction
function GetAbilityMaxLevel takes integer abil returns integer
local integer a
if abil==0 then
return 0
endif
set a=GetObjectDataCaching(pAbilityData, abil)
if a>0 then
return Memory[a+20]
endif
return 0
endfunction
function AddAbilityCooldown takes ability a, real seconds returns nothing
local integer pData = Memory[ConvertHandle(a)/4+55]/4
if pData != 0 then
set Memory[pData+1] = cleanInt(realToIndex(seconds+cleanReal(indexToReal(Memory[pData+1]))))
//set Memory[ConvertHandle(a)/4+45] = cleanInt(realToIndex(seconds+cleanReal(indexToReal(Memory[ConvertHandle(a)/4+45])))) This should not be modified together
endif
endfunction
function AddAbilityCooldownConverted takes integer a, real seconds returns nothing
local integer pData = Memory[a+55]/4
if pData != 0 then
set Memory[pData+1] = cleanInt(realToIndex(seconds+cleanReal(indexToReal(Memory[pData+1]))))
endif
endfunction
function AddAbilityBaseCooldown takes ability a, real seconds returns nothing
local integer pData = Memory[ConvertHandle(a)/4+45]
if pData != 0 then
set Memory[pData] = cleanInt(realToIndex(seconds))
endif
endfunction
//This value holds the base cooldown of the ability at the last time it was casted. It’s used to calculate the % of elapsed cooldown.
//This is completely irrelevant for the gameplay, it’s used only to determine which frame of the cooldown model will be displayed.
function GetAbilityCurrentCooldown takes ability a returns real
local integer pData = Memory[ConvertHandle(a)/4+55]/4
if pData != 0 then
return cleanReal(indexToReal(Memory[pData+1])) - cleanReal(indexToReal(Memory[Memory[pData+3]/4+16]))
endif
return .0
endfunction
function CopyCooldownStr takes integer from, integer to returns nothing
local integer pData = Memory[from+55]
if pData != 0 then
//if Memory[to+55]==0 then
set Memory[to+55]=pData
//set Memory[to+52]=Memory[from+52]
//set Memory[to+54]=to*4
set Memory[to+45]=Memory[from+45]
if IsFlagBitSet(Memory[to+8],512)==false then
set Memory[to+8]=Memory[to+8]+512
// call BJDebugMsg("add cd")
else
// call BJDebugMsg("already cd")
endif
//endif
endif
endfunction
function GetAbilityCurrentCooldownConverted takes integer a returns real
local integer pData = Memory[a+55]/4
if pData != 0 then
return cleanReal(indexToReal(Memory[pData+1])) - cleanReal(indexToReal(Memory[Memory[pData+3]/4+16]))
endif
return .0
endfunction
//This actually returns the timestamp, not the cooldown. To get the real cooldown you need to subtract this from the current game time.
function GetAbilityCooldownReal takes ability a returns real
local integer pData = Memory[ConvertHandle(a)/4+55]/4
if pData != 0 then
return cleanReal(indexToReal(Memory[pData+1]))
endif
return 0.
endfunction
function IsAbilityOnCooldown takes integer z returns boolean
return IsFlagBitSet(Memory[(z+0x20)/4],512)
endfunction
function SetAbilityDisabled takes integer pAbility, integer count returns nothing
set Memory[pAbility/4+15] = count //not safe unless used with PauseUnit. Button will be blacked, but current casts of that ability won’t be interrupted.
endfunction
function GetAbilityDisabledCount takes integer pAbility returns integer
return Memory[pAbility/4+15]
endfunction
function SetAbilityHidden takes integer pAbility, integer count returns nothing
set Memory[pAbility/4+16] = count //This one is 100% safe. This hides the ability button, and order can’t be issued.
endfunction
function SetAbilityDisabled2 takes integer pAbility, integer count returns nothing
set Memory[pAbility/4+17] = count //This one is used by Orb of Slow. Button is blacked, but cooldown is stil displayed.
endfunction
function GetAbilityDisabled2 takes integer pAbility returns integer
return Memory[pAbility/4+17]//This one is used by Orb of Slow. Button is blacked, but cooldown is stil displayed.
endfunction
function DisableUnitsMovement takes unit u, boolean disable returns nothing
local integer i=2
if disable==false then
set i=1
endif
call PauseUnit(u,true)
call SetAbilityDisabled(Memory[ConvertHandle( u )/4+123], i)
call PauseUnit(u,false)
endfunction
//pointer to 'Amov' is located at offset 123 of unit object, Aatk is at offset 122, and AInv is offset 124
//Hides all command buttons and sets the Ward flag. Unit will keep its current order, and player can’t give new orders
//Notice the the unit can’t be ordered with triggers as well. To issue an order you need to temporarily reenable control
function DisableUnitControl takes unit u returns nothing
local integer pUnit = ConvertHandle(u)/4
local integer flags = Memory[pUnit+146]
local integer Amov = Memory[pUnit+123]/4+16
local integer Aatk = Memory[pUnit+122]/4+16
// call echo("disabled on "+GetUnitName(u))
if not IsFlagBitSet(flags,512) then
set Memory[pUnit+146] = flags + 512
endif
if Amov != 16 then
set Memory[Amov] = Memory[Amov] + 1
endif
if Aatk != 16 then
set Memory[Aatk] = Memory[Aatk] + 1
endif
endfunction
//Removes the Ward flag and reenables Amov and Aatk
function EnableUnitControl takes unit u returns nothing
local integer pUnit = ConvertHandle(u)/4
local integer flags = Memory[pUnit+146]
local integer Amov = Memory[pUnit+123]/4+16
local integer Aatk = Memory[pUnit+122]/4+16
// call echo("enabled on "+GetUnitName(u))
if IsFlagBitSet(flags,512) then
set Memory[pUnit+146] = flags - 512
endif
if Amov != 16 and Memory[Amov]>0 then
set Memory[Amov] = Memory[Amov] - 1
endif
if Aatk != 16 and Memory[Aatk]>0 then
set Memory[Aatk] = Memory[Aatk] - 1
endif
endfunction
function SetUnitModel takes integer uiobjectaddr, string s returns nothing
call WriteNullTerminatedString(s, uiobjectaddr+0x30 )
endfunction
function SetUnitModelUF takes unit u, string s returns nothing//user-friendly
call SetUnitModel(GetUnitUIDefAddr(GetUnitTypeId(u)),s)
endfunction
function SetUnitModelUFAddress takes integer address, string s returns nothing
call SetUnitModel(address,s)
endfunction
function GetUnitAttackAbilityForAddress takes integer pConvertedHandle returns integer
return Memory[pConvertedHandle/4+0x1e8/4]
endfunction
function GetUnitAttackAbility takes unit u returns integer
return GetUnitAttackAbilityForAddress(ConvertHandle(u))
endfunction
function GetUnitMoveAbilityForAddress takes integer pConvertedHandle returns integer
return Memory[pConvertedHandle/4+0x1eC/4]
endfunction
function GetUnitMoveAbility takes unit u returns integer
return GetUnitMoveAbilityForAddress(ConvertHandle(u))
endfunction
function GetUnitHeroAbilityForAddress takes integer pConvertedHandle returns integer
return Memory[pConvertedHandle/4+0x1F0/4]
endfunction
function GetUnitHeroAbility takes unit u returns integer
return GetUnitHeroAbilityForAddress(ConvertHandle(u))
endfunction
function GetUnitBuildAbilityForAddress takes integer pConvertedHandle returns integer
return Memory[pConvertedHandle/4+0x1F4/4]
endfunction
function GetUnitBuildAbility takes unit u returns integer
return GetUnitBuildAbilityForAddress(ConvertHandle(u))
endfunction
function GetUnitInventoryAbilityForAddress takes integer pConvertedHandle returns integer
return Memory[pConvertedHandle/4+0x1F8/4]
endfunction
function GetUnitInventoryAbility takes unit u returns integer
return GetUnitInventoryAbilityForAddress(ConvertHandle(u))
endfunction
// Alternative for sub_6F4786B0 (126a)
function GetSomeAddress takes integer pAddr1 ,integer pAddr2 returns integer //I just split your function into 2, it should be working as before
local integer pOff1 = 44
if BitwiseAnd(pAddr1,pAddr2) == -1 then
return 0
endif
if pAddr1 >= 0 then
set pOff1 = 12
endif
set pOff1 = Memory[pGameClass1]/4 + pOff1/4
set pOff1 = Memory[pOff1]
if pOff1 == 0 then
return 0
endif
set pOff1 = pOff1 + 8 * pAddr1 + 4
set pOff1 = Memory[pOff1/4]
if pOff1 == 0 or Memory[pOff1/4 + 0x18/4] != pAddr2 then
return 0
endif
return pOff1
endfunction
function GetSomeAddressForAbility takes integer pAddr1 ,integer pAddr2 returns integer //Second part of GetSomeAddressForAbility
local integer pOff1 = GetSomeAddress(pAddr1,pAddr2)
if pOff1==0 or Memory[pOff1/4 + 0x20/4] != 0 then
return 0
endif
return Memory[pOff1/4+0x54/4]
endfunction
function GetSomeAddressForLocustFlags takes integer pAddr1 ,integer pAddr2 returns integer
local integer i = GetSomeAddress(pAddr1,pAddr2)
return Memory[i/4+37]
endfunction
function SetLocustFlags takes unit u, integer i returns nothing //These flags can make unit immune to truesight
local integer pOff1 = ConvertHandle(u)/4+91
set pOff1 = GetSomeAddressForLocustFlags(Memory[pOff1], Memory[pOff1+1])
set Memory[pOff1/4+13] = i
endfunction
function EnableTruesightImmunity takes unit u returns nothing
//I don’t really know what other side effects may be caused by this, at least GroupEnum is not affected
call SetLocustFlags(u, 0x08000000)
endfunction
function DisableTruesightImmunity takes unit u returns nothing
call SetLocustFlags(u, 0)
endfunction
function UnStunUnit takes unit u returns nothing
set Memory[ConvertHandle(u)/4+102] = 0
endfunction
function IsUnitStunned2 takes unit u returns boolean
return Memory[ConvertHandle(u)/4+102] > 0
endfunction
function IsUnitInvulnerable takes unit u returns boolean
local integer k
// call BJDebugMsg(GetUnitName(u))
if u==null then
return false
endif
set k=ConvertHandle(u)
if k==0 then
return false
endif
return Memory[k/4+8]/8*0x80000000 != 0
endfunction
function GetUnitInvulnerableCounter takes unit u returns integer
local integer k
if u==null then
return 0
endif
set k=ConvertHandle(u)
if k==0 then
return 0
endif
return Memory[k/4+0xE8/4]
endfunction
function SetUnitInvulnerableCounter takes unit u, integer i returns nothing
local integer k
if u==null then
return
endif
set k=ConvertHandle(u)
if k==0 then
return
endif
set Memory[k/4+0xE8/4]=i
endfunction
function GetUnitAbilityForAddresss takes integer pConvertedHandle, integer abilid returns integer
local integer pAddr1 = pConvertedHandle + 476
local integer pAddr2 = pConvertedHandle + 480
local integer pOff1 = 0
set pAddr1 = Memory[pAddr1/4]
set pAddr2 = Memory[pAddr2/4]
if pAddr1 == 0 or pAddr2 == 0 or BitwiseAnd(pAddr1,pAddr2) == -1 then
return 0
endif
set pOff1 = GetSomeAddressForAbility(pAddr1,pAddr2)
if pOff1 == 0 then
return 0
endif
loop
exitwhen pOff1 == 0
if Memory[pOff1/4+52/4] == abilid then
return pOff1
endif
set pOff1 = GetSomeAddressForAbility( Memory[pOff1/4+36/4], Memory[pOff1/4+40/4])
endloop
return pOff1
endfunction
function GetAbilityOrderID takes integer pAbility returns integer
local integer pOffset2
local integer pOffset1
if pAbility<1 then
return 0
endif
// call BJDebugMsg(Int2Hex(pAbility)+" sent")
// call PolledWait(1.)
// mov ecx,[esp+04]
// mov edx,[ecx+6C]
// cmp edx,D0142 { 852290 }
// je 0493413A
// mov eax,00000000 { 0 }
// ret
// mov ecx,[ecx]
// mov ecx,[ecx+00000308]
// call ecx
// ret
set Memory[pReservedExecutableMemory/4] = 0x04244C8B
set Memory[pReservedExecutableMemory/4 + 1] = 0x816C518B
set Memory[pReservedExecutableMemory/4 + 2] = 0x0D0142FA
set Memory[pReservedExecutableMemory/4 + 3] = 0xB8067400
set Memory[pReservedExecutableMemory/4 + 4] = 0x00000000
set Memory[pReservedExecutableMemory/4 + 5] = 0x8B098BC3
set Memory[pReservedExecutableMemory/4 + 6] = 0x00030889
set Memory[pReservedExecutableMemory/4 + 7] = 0x90E1FF00
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
endif
if pIgnoredUnitsOffset != 0 then
set pOffset2 = IgnoredUnits(pAbility)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
return pOffset2
endif
return 0
endfunction
function PrintAllUnitAbilities takes integer pConvertedHandle returns nothing
local integer pAddr1 = pConvertedHandle + 476
local integer pAddr2 = pConvertedHandle + 480
local integer pOff1 = 0
set pAddr1 = Memory[pAddr1/4]
set pAddr2 = Memory[pAddr2/4]
if pAddr1 == 0 or pAddr2 == 0 or BitwiseAnd(pAddr1,pAddr2) == -1 then
return
endif
set pOff1 = GetSomeAddressForAbility(pAddr1,pAddr2)
if pOff1 == 0 then
return
endif
loop
exitwhen pOff1 == 0
call DisplayTextToPlayer(GetLocalPlayer(),0.0,0.0,"Address:"+Int2Hex(pOff1)+". ID:"+Id2String(Memory[pOff1/4+52/4])+" name: "+GetObjectName(Memory[pOff1/4+52/4]))
set pOff1 = GetSomeAddressForAbility( Memory[pOff1/4+36/4], Memory[pOff1/4+40/4])
endloop
endfunction
//function PrintAllUnitAbilitiesOld takes integer pConvertedHandle returns nothing
// local integer pAddr1 = pConvertedHandle + 476
// local integer pAddr2 = pConvertedHandle + 480
//
// local integer pOff1 = 0
//
// set pAddr1 = Memory[pAddr1/4]
// set pAddr2 = Memory[pAddr2/4]
// if pAddr1 == 0 or pAddr2 == 0 or BitwiseAndOld(pAddr1,pAddr2) == -1 then
// return
// endif
//
// set pOff1 = GetSomeAddressForAbility(pAddr1,pAddr2)
//
// if pOff1 == 0 then
// return
// endif
//
// loop
// exitwhen pOff1 == 0
//
// call DisplayTextToPlayer(GetLocalPlayer(),0.0,0.0,"Address:"+Int2Hex(pOff1)+". ID:"+Id2String(Memory[pOff1/4+52/4])+" name: "+GetObjectName(Memory[pOff1/4+52/4]))
//
// set pOff1 = GetSomeAddressForAbility( Memory[pOff1/4+36/4], Memory[pOff1/4+40/4])
// endloop
//
//endfunction
function GetAllUnitAbilities takes unit u returns nothing
local integer pConvertedHandle=ConvertHandle(u)
local integer pAddr1 = pConvertedHandle + 476
local integer pAddr2 = pConvertedHandle + 480
local integer i=0
local integer h=GetHandleId(u)
local integer pOff1 = 0
call FlushChildHashtable(TempHash,h)
set pAddr1 = Memory[pAddr1/4]
set pAddr2 = Memory[pAddr2/4]
if pAddr1 == 0 or pAddr2 == 0 or BitwiseAnd(pAddr1,pAddr2) == -1 then
return
endif
set pOff1 = GetSomeAddressForAbility(pAddr1,pAddr2)
if pOff1 == 0 then
return
endif
loop
exitwhen pOff1 == 0
// call DisplayTextToPlayer(GetLocalPlayer(),0.0,0.0,"Address:"+Int2Hex(pOff1)+". ID:"+Id2String(Memory[pOff1/4+52/4])+" name: "+GetObjectName(Memory[pOff1/4+52/4]))
if Memory[pOff1/4+0x34/4]!='Amov' and Memory[pOff1/4+0x34/4]!='AHer' and Memory[pOff1/4+0x34/4]!='Aatk' and Memory[pOff1/4+0x34/4]!='AInv' then
call SaveInteger(TempHash,h,i,pOff1)//address
call SaveInteger(TempHash,h+1,i,Memory[pOff1/4+0x34/4])//ability id
set i=i+1
endif
set pOff1 = GetSomeAddressForAbility( Memory[pOff1/4+36/4], Memory[pOff1/4+40/4])
//facepalm
endloop
call SaveInteger(TempHash,'abil',0,i)
endfunction
function CallFastCallWith1Args takes integer pFuncFastcallAddr, integer arg1 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0xB9F68B56)
call WriteRealMemory(pReservedExecutableMemory2+4, arg1)
call WriteRealMemory(pReservedExecutableMemory2+8, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory2+12, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory2+16, 0xC35ED6FF)
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallFastCallWith2Args takes integer pFuncFastcallAddr, integer arg1, integer arg2 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0xBAF68B56)
call WriteRealMemory(pReservedExecutableMemory2+4, arg2)
call WriteRealMemory(pReservedExecutableMemory2+8, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory2+12, arg1)
call WriteRealMemory(pReservedExecutableMemory2+16, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory2+20, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory2+24, 0xC35ED6FF)
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallFastCallWith3Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
call WriteRealMemory(pReservedExecutableMemory2+4, arg3)
call WriteRealMemory(pReservedExecutableMemory2+8, 0xBAF68B90)
call WriteRealMemory(pReservedExecutableMemory2+12, arg2)
call WriteRealMemory(pReservedExecutableMemory2+16, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory2+20, arg1)
call WriteRealMemory(pReservedExecutableMemory2+24, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory2+28, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory2+32, 0xC35ED6FF)
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function FUCKINGCallWith4Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
call WriteRealMemory(pReservedExecutableMemory2+4, arg4)
call WriteRealMemory(pReservedExecutableMemory2+8, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+12, arg3)
call WriteRealMemory(pReservedExecutableMemory2+16, 0xB8F68B90)
call WriteRealMemory(pReservedExecutableMemory2+20, arg2)
call WriteRealMemory(pReservedExecutableMemory2+24, 0xBFF68B90)
call WriteRealMemory(pReservedExecutableMemory2+28, arg1)
call WriteRealMemory(pReservedExecutableMemory2+32, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory2+36, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory2+40, 0xC35ED6FF)
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallFastCallWith4Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
call WriteRealMemory(pReservedExecutableMemory2+4, arg4)
call WriteRealMemory(pReservedExecutableMemory2+8, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+12, arg3)
call WriteRealMemory(pReservedExecutableMemory2+16, 0xBAF68B90)
call WriteRealMemory(pReservedExecutableMemory2+20, arg2)
call WriteRealMemory(pReservedExecutableMemory2+24, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory2+28, arg1)
call WriteRealMemory(pReservedExecutableMemory2+32, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory2+36, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory2+40, 0xC35ED6FF)
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallFastCallWith5Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
call WriteRealMemory(pReservedExecutableMemory2+4, arg5)
call WriteRealMemory(pReservedExecutableMemory2+8, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+12, arg4)
call WriteRealMemory(pReservedExecutableMemory2+16, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+20, arg3)
call WriteRealMemory(pReservedExecutableMemory2+24, 0xBAF68B90)
call WriteRealMemory(pReservedExecutableMemory2+28, arg2)
call WriteRealMemory(pReservedExecutableMemory2+32, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory2+36, arg1)
call WriteRealMemory(pReservedExecutableMemory2+40, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory2+44, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory2+48, 0xC35ED6FF)
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallFastCallWith6Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
call WriteRealMemory(pReservedExecutableMemory2+4, arg6)
call WriteRealMemory(pReservedExecutableMemory2+8, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+12, arg5)
call WriteRealMemory(pReservedExecutableMemory2+16, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+20, arg4)
call WriteRealMemory(pReservedExecutableMemory2+24, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+28, arg3)
call WriteRealMemory(pReservedExecutableMemory2+32, 0xBAF68B90)
call WriteRealMemory(pReservedExecutableMemory2+36, arg2)
call WriteRealMemory(pReservedExecutableMemory2+40, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory2+44, arg1)
call WriteRealMemory(pReservedExecutableMemory2+48, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory2+52, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory2+56, 0xC35ED6FF)
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallFastCallWith7Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6, integer arg7 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
call WriteRealMemory(pReservedExecutableMemory2+4, arg7)
call WriteRealMemory(pReservedExecutableMemory2+8, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+12, arg6)
call WriteRealMemory(pReservedExecutableMemory2+16, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+20, arg5)
call WriteRealMemory(pReservedExecutableMemory2+24, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+28, arg4)
call WriteRealMemory(pReservedExecutableMemory2+32, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+36, arg3)
call WriteRealMemory(pReservedExecutableMemory2+40, 0xBAF68B90)
call WriteRealMemory(pReservedExecutableMemory2+44, arg2)
call WriteRealMemory(pReservedExecutableMemory2+48, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory2+52, arg1)
call WriteRealMemory(pReservedExecutableMemory2+56, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory2+60, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory2+64, 0xC35ED6FF)
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallFastCallWith8Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6, integer arg7, integer arg8 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
call WriteRealMemory(pReservedExecutableMemory2+4, arg8)
call WriteRealMemory(pReservedExecutableMemory2+8, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+12, arg7)
call WriteRealMemory(pReservedExecutableMemory2+16, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+20, arg6)
call WriteRealMemory(pReservedExecutableMemory2+24, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+28, arg5)
call WriteRealMemory(pReservedExecutableMemory2+32, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+36, arg4)
call WriteRealMemory(pReservedExecutableMemory2+40, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory2+44, arg3)
call WriteRealMemory(pReservedExecutableMemory2+48, 0xBAF68B90)
call WriteRealMemory(pReservedExecutableMemory2+52, arg2)
call WriteRealMemory(pReservedExecutableMemory2+56, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory2+60, arg1)
call WriteRealMemory(pReservedExecutableMemory2+64, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory2+68, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory2+72, 0xC35ED6FF)
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallThisCallWith1Args takes integer pFuncThiscallAddr, integer arg1 returns integer
return CallFastCallWith2Args(pFuncThiscallAddr,arg1,0)
endfunction
function CallThisCallWith2Args takes integer pFuncThiscallAddr, integer arg1, integer arg2 returns integer
return CallFastCallWith3Args(pFuncThiscallAddr,arg1,0,arg2)
endfunction
function CallThisCallWith3Args takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3 returns integer
return CallFastCallWith4Args(pFuncThiscallAddr,arg1,0,arg2,arg3)
endfunction
function CallThisCallWith4Args takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4 returns integer
return CallFastCallWith5Args(pFuncThiscallAddr,arg1,0,arg2,arg3,arg4)
endfunction
function CallThisCallWith5Args takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5 returns integer
return CallFastCallWith6Args(pFuncThiscallAddr,arg1,0,arg2,arg3,arg4,arg5)
endfunction
function CallThisCallWith6Args takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5, integer arg6 returns integer
return CallFastCallWith7Args(pFuncThiscallAddr,arg1,0,arg2,arg3,arg4,arg5,arg6)
endfunction
function CallThisCallWith7Args takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5, integer arg6, integer arg7 returns integer
return CallFastCallWith8Args(pFuncThiscallAddr,arg1,0,arg2,arg3,arg4,arg5,arg6,arg7)
endfunction
function GetUnitAbilityReal takes integer UnitAddress, integer AbilCode, integer unk1, integer unk2, integer unk3, integer unk4 returns integer
return CallThisCallWith6Args(pGetUnitAbility,UnitAddress,AbilCode,unk1,unk2, unk3, unk4)
endfunction
function GetUnitAddress takes unit u returns integer
return CallThisCallWith1Args(pGetUnitAddress, GetHandleId(u))
endfunction
function GetUnitAbility takes unit u, integer abilid returns integer
if u==null then
return 0
endif
return CallThisCallWith6Args(pGetUnitAbility,GetUnitAddress(u),abilid,0, 1, 1, 1)
endfunction
//function GetUnitAbility takes unit u, integer abilid returns integer
//
//
// if abilid == 'Aatk' then
// return GetUnitAttackAbility(u)
// endif
// if abilid == 'Amov' then
// return GetUnitMoveAbility(u)
// endif
// if abilid == 'AHer' then
// return GetUnitHeroAbility(u)
// endif
// if abilid == 'AObu' or abilid == 'AUbu' or abilid == 'ANbu' or abilid == 'AHbu' or abilid == 'AEbu' or abilid == 'AGbu' then
// return GetUnitBuildAbility(u)
// endif
// if abilid == 'AInv' then
// return GetUnitInventoryAbility(u)
// endif
//
// return GetUnitAbilityForAddresss(ConvertHandle(u),abilid)
//endfunction
function GetAbilityOrderIDbyID takes integer id returns integer
local integer a
if HaveSavedInteger(AbilitiesHashtable,id,'ordr') then
return LoadInteger(AbilitiesHashtable,id,'ordr')
endif
if id=='AHer' or id=='ANeg' or id=='Aatk' or id=='AInv' then
call SaveInteger(AbilitiesHashtable,id,'ordr',0)
return 0
endif
// call BJDebugMsg("Requested "+Int2Hex(id))
set bj_lastCreatedUnit=CreateUnit(Player(0),'e00E',0,0,0)
call UnitAddAbility(bj_lastCreatedUnit,id)
set a=GetUnitAbility(bj_lastCreatedUnit,id)
set a=GetAbilityOrderID(a)
call SaveInteger(AbilitiesHashtable,id,'ordr',a)
return a
endfunction
function GetAbilityOrderIdAny takes integer a returns integer
local integer base
if Memory[(a+0x54)/4]!=0 and Memory[(a+0x6C)/4]!=0 then
set base=Memory[(Memory[(a+0x54)/4]+0x30)/4]
// call echo(Id2String(base))
if base>0 and base!='ANcl' then
return GetAbilityOrderIDbyID(base)
// return 0
elseif base=='ANcl' then
return Memory[(a+0x124)/4]
endif
endif
return 0
endfunction
function ShowAbilityById_Main takes integer ConvertedHandle, integer d returns nothing
if ConvertedHandle!=0 then
if Memory[ConvertedHandle/4]!=0 then
set Memory[(ConvertedHandle + 0x40)/4]=Memory[(ConvertedHandle + 0x40)/4]+d
endif
endif
endfunction
function HideAbilityButton takes unit u, integer id, boolean hide returns nothing
local integer offset
if u!=null and id!=0 then
set offset=GetUnitAbility(u,id)
if offset!=0 then
if hide then
call ShowAbilityById_Main(offset,1)
else
call ShowAbilityById_Main(offset,-1)
endif
endif
endif
endfunction
function GetSpellCastpoint takes ability a returns real
return cleanReal(indexToReal(Memory[(ConvertHandle(a)+0x8C)/4]))
endfunction
function SetSpellCastpoint takes ability a, real dur returns nothing
set Memory[(ConvertHandle(a)+0x8C)/4]=cleanInt(realToIndex(dur))
endfunction
function GetSpellBackswing takes ability a returns real
return cleanReal(indexToReal(Memory[(ConvertHandle(a)+0x94)/4]))
endfunction
function SetSpellBackswing takes ability a, real dur returns nothing
set Memory[(ConvertHandle(a)+0x94)/4]=cleanInt(realToIndex(dur))
endfunction
function ToggleAbilityAutocast takes integer address, boolean on returns nothing
local integer flags
local integer flag128=0//0 if enabled
local integer flag524288=0
if address>0 then
set flags=Memory[(address+0x20)/4]
if BitwiseAnd(flags,0x80)==0 then
set flag128=0x80//not enabled
// call echo("not enabled")
// else
// call echo("enabled")
endif
if BitwiseAnd(flags,0x80000)==0 then
set flag524288=0x80000//not enabled
endif
if on and flag128>0 then
set flags=flags+flag128
elseif on==false and flag128==0 then
set flags=flags-0x80
endif
if on and flag524288>0 then
set flags=flags+flag524288
elseif on==false and flag524288==0 then
set flags=flags-0x80000
endif
set Memory[(address+0x20)/4]=flags
endif
endfunction
function SetUnitAbiltyAutocast takes unit u, integer id, boolean on returns nothing
call ToggleAbilityAutocast(GetUnitAbility(u,id),on)
endfunction
function SetUnitAttackType takes unit u, integer i, integer attacknum returns nothing
if attacknum==1 then
set Memory[(GetUnitAttackAbility(u) + 0xF4)/4]=i
elseif attacknum==2 then
set Memory[(GetUnitAttackAbility(u) + 0xF8)/4]=i
endif
endfunction
function SetUnitAttackType1 takes unit u, integer i returns nothing
call SetUnitAttackType(u,i,1)
endfunction
function SetUnitAttackType2 takes unit u, integer i returns nothing
call SetUnitAttackType(u,i,2)
endfunction
//6 = hero, 5 = chaos, 4 = magic, 3 = siege, 2 = piercing, 1 = normal, 0 = spell?
//values over 6 takes incorrect multipliers from nearby memory, do not use them
function GetUnitAttackType1 takes unit u returns integer
return Memory[GetUnitAttackAbility(u)/4 + 0xF4/4]
endfunction
function GetUnitAttackType2 takes unit u returns integer
return Memory[GetUnitAttackAbility(u)/4 + 0xF8/4]
endfunction
//unit's weapon type is melee, ranged, splash, artillery, etc
//values 1-8
// 2 = ranger, 1 = instante, 0 = melee, 5 = splash, 6 = mbounce,
function SetUnitWeaponType takes unit u, integer i returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0xDC/4]=i
endfunction
function GetUnitWeaponType takes unit u returns integer
return Memory[GetUnitAttackAbility(u)/4 + 0xDC/4]
endfunction
//setting green bonus automatically adjusts base damage to fit
function SetUnitGreenBonusDamage takes unit u, integer i returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0xAC/4]=i
endfunction
function GetUnitGreenBonusDamage takes unit u returns integer
return Memory[GetUnitAttackAbility(u)/4 + 0xAC/4]
endfunction
function AddUnitGreenBonusDamage takes unit u, integer i returns nothing
call SetUnitGreenBonusDamage(u,GetUnitGreenBonusDamage(u)+i)
endfunction
function SetUnitBaseDamage takes unit u, integer i returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0xA0/4]=i
endfunction
function GetUnitBaseDamage takes unit u returns integer
return Memory[GetUnitAttackAbility(u)/4 + 0xA0/4]
endfunction
function AddUnitBaseDamage takes unit u, integer bonus returns nothing
call SetUnitBaseDamage(u,GetUnitBaseDamage(u)+bonus)
endfunction
function SetUnitBaseAttributeDamage takes unit u, integer i returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0xA4/4]=i
endfunction
function GetUnitBaseAttributeDamage takes unit u returns integer
return Memory[GetUnitAttackAbility(u)/4 + 0xA4/4]
endfunction
function SetUnitDamageDicesSideCount takes unit u, integer i returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0x94/4]=i
endfunction
function GetUnitDamageDicesSideCount takes unit u returns integer
return Memory[GetUnitAttackAbility(u)/4 + 0x94/4]
endfunction
function SetUnitDamageDicesCount takes unit u, integer i returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0x88/4]=i
endfunction
function GetUnitDamageDicesCount takes unit u returns integer
local integer a=GetUnitAttackAbility(u)
if a>0 then
return Memory[a/4 + 0x88/4]
endif
return 0
endfunction
function SetUnitAttackRange1 takes unit u, real r returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0x258/4]=cleanInt(realToIndex(r))
endfunction
function GetUnitAttackRange1 takes unit u returns real
return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x258/4]))
endfunction
function SetUnitAttackRange2 takes unit u, real r returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0x27C/4]=cleanInt(realToIndex(r))
endfunction
function GetUnitAttackRange2 takes unit u returns real
return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x27C/4]))
endfunction
function SetUnitBAT1 takes unit u, real r returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0x158/4]=cleanInt(realToIndex(r))
endfunction
function GetUnitBAT1 takes unit u returns real
return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x158/4]))
endfunction
function SetUnitBAT2 takes unit u, real r returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0x160/4]=cleanInt(realToIndex(r))
endfunction
function GetUnitBAT2 takes unit u returns real
return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x160/4]))
endfunction
function SetUnitAttackPoint1 takes unit u, real r returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0x16C/4]=cleanInt(realToIndex(r))
endfunction
function SetUnitAttackPoint2 takes unit u, real r returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0x17C/4]=cleanInt(realToIndex(r))
endfunction
function GetUnitAttackPoint1 takes unit u returns real
return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x16C/4]))
endfunction
function GetUnitAttackPoint2 takes unit u returns real
return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x17C/4]))
endfunction
function GetUnitAttackEnabledIndex takes unit u returns integer
return Memory[GetUnitAttackAbility(u)/4 + 0x104/4]
endfunction
function SetUnitAttackBackswing takes unit u, real r returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0x190/4]=cleanInt(realToIndex(r))
endfunction
function GetUnitAttackBackswing takes unit u returns real
return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x190/4]))
endfunction
function SetUnitAttackSpeed takes unit u, real r returns nothing
set Memory[GetUnitAttackAbility(u)/4 + 0x1B0/4]=cleanInt(realToIndex(r))
endfunction
function GetUnitAttackSpeed takes unit u returns real
return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x1B0/4]))
endfunction
function AddUnitAttackSpeed takes unit u, real r returns nothing
call SetUnitAttackSpeed(u,GetUnitAttackSpeed(u)+r)
endfunction
function GetUnitAddressFloatsRelated takes integer pConvertedHandle, integer step returns integer
local integer pOffset1 = pConvertedHandle + step
local integer pOffset2 = Memory[pGameClass1]
set pOffset1 = Memory[pOffset1/4]
set pOffset2 = Memory[(pOffset2+0xC)/4]
set pOffset2 = Memory[(( pOffset1 * 8 ) + pOffset2 + 4)/4]
return pOffset2
endfunction
function SetUnitFacingInstant takes unit u, real a returns nothing
local integer pOffset2 = GetUnitAddressFloatsRelated(ConvertHandle(u),0xA0)
set Memory[Memory[(pOffset2+0x28)/4]/4 +0xA4/4]=cleanInt(realToIndex(bj_DEGTORAD*a))
endfunction
function SetUnitMaxHP4Address takes integer pConvertedHandle, real newhp returns nothing
local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xA0)
set Memory[(pOffset2+0x84)/4]=cleanInt(realToIndex(newhp))
endfunction
function SetUnitMaxMP4Address takes integer pConvertedHandle, real newmp returns nothing
local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xC0)
set Memory[(pOffset2+0x84)/4]=cleanInt(realToIndex(newmp))
endfunction
function SetUnitMaxHP takes unit u, real newhp returns nothing
call SetUnitMaxHP4Address(ConvertHandle(u),newhp)
endfunction
function SetUnitMaxMP takes unit u, real newmp returns nothing
call SetUnitMaxMP4Address(ConvertHandle(u),newmp)
endfunction
function GetUnitHPRegenForAddress takes integer pConvertedHandle returns real
local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xA0)
return cleanReal(indexToReal(Memory[(pOffset2+0x7C)/4]))
endfunction
function SetUnitXSoft takes integer pConvertedHandle, real x returns nothing
local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xA0)
set Memory[Memory[(pOffset2+0x28)/4]/4+0x54/4]=SetRealIntoMemory(x)
endfunction
function SetUnitHPRegenForAddress takes integer pConvertedHandle, real r returns nothing
local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xA0)
set Memory[(pOffset2+0x7C)/4]=cleanInt(realToIndex(r))
endfunction
function GetUnitMPRegenForAddress takes integer pConvertedHandle returns real
local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xC0)
// call echo(Int2Hex(pOffset2))
return cleanReal(indexToReal(Memory[(pOffset2+0x7C)/4]))
endfunction
function SetUnitMPRegenForAddress takes integer pConvertedHandle, real r returns nothing
local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xC0)
set Memory[(pOffset2+0x7C)/4]=cleanInt(realToIndex(r))
endfunction
function GetUnitHPRegen takes unit u returns real
return GetUnitHPRegenForAddress(ConvertHandle(u))
endfunction
function GetWidgetHPRegen takes widget u returns real
return GetUnitHPRegenForAddress(ConvertHandle(u))
endfunction
function GetUnitMPRegen takes unit u returns real
return GetUnitMPRegenForAddress(ConvertHandle(u))
endfunction
function SetUnitHPRegen takes unit u, real r returns nothing
local real curhp=GetWidgetLife(u)
if curhp>0 then
call SetUnitHPRegenForAddress(ConvertHandle(u),r)
call SetWidgetLife(u,curhp)
endif
endfunction
function AddUnitHPRegen takes unit u, real r returns nothing
local real curhp=GetWidgetLife(u)
local integer h
if curhp>0 then
set h=ConvertHandle(u)
call SetUnitHPRegenForAddress(h,r+GetUnitHPRegenForAddress(h))
call SetWidgetLife(u,curhp)
endif
endfunction
function SetUnitMPRegen takes unit u, real r returns nothing
local real curhp=GetUnitState(u,UNIT_STATE_MANA)
if GetUnitState(u,UNIT_STATE_MAX_MANA)>0 then
call SetUnitMPRegenForAddress(ConvertHandle(u),r)
call SetUnitState(u,UNIT_STATE_MANA,curhp)
endif
endfunction
function AddUnitMPRegen takes unit u, real r returns nothing
local real curhp=GetUnitState(u,UNIT_STATE_MANA)
local integer h
if GetUnitState(u,UNIT_STATE_MAX_MANA)>0 then
set h=ConvertHandle(u)
call SetUnitMPRegenForAddress(h,r+GetUnitMPRegenForAddress(h))
call SetUnitState(u,UNIT_STATE_MANA,curhp)
endif
endfunction
function SetEffectX_ForAddress takes integer pConvertedHandle, real r returns nothing
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xC0/4] = cleanInt(realToIndex(r))
endfunction
function SetEffectX takes effect e, real r returns nothing
call SetEffectX_ForAddress(ConvertHandle(e),r)
endfunction
function GetEffectX_ForAddress takes integer pConvertedHandle returns real
return cleanReal(indexToReal(Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xC0/4]))
endfunction
function GetEffectX takes effect e returns real
return GetEffectX_ForAddress(ConvertHandle(e))
endfunction
function SetEffectY_ForAddress takes integer pConvertedHandle, real r returns nothing
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xC4/4] = cleanInt(realToIndex(r))
endfunction
function SetEffectY takes effect e, real r returns nothing
call SetEffectY_ForAddress(ConvertHandle(e),r)
endfunction
function GetEffectY_ForAddress takes integer pConvertedHandle returns real
return cleanReal(indexToReal(Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xC4/4]))
endfunction
function GetEffectY takes effect e returns real
return GetEffectY_ForAddress(ConvertHandle(e))
endfunction
function SetEffectZ_ForAddress takes integer pConvertedHandle, real r returns nothing
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xC8/4] = cleanInt(realToIndex(r))
endfunction
function SetEffectZ takes effect e, real r returns nothing
call SetEffectZ_ForAddress(ConvertHandle(e),r)
endfunction
function GetEffectZ_ForAddress takes integer pConvertedHandle returns real
return cleanReal(indexToReal(Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xC8/4]))
endfunction
function GetEffectZ takes effect e returns real
return GetEffectZ_ForAddress(ConvertHandle(e))
endfunction
function SetEffectPos takes effect e, real x, real y, real z returns nothing
local integer pConvertedHandle = ConvertHandle(e)
call SetEffectX_ForAddress(pConvertedHandle,x)
call SetEffectY_ForAddress(pConvertedHandle,y)
call SetEffectZ_ForAddress(pConvertedHandle,z)
endfunction
function SetObjectColor takes handle e, integer color returns nothing
set Memory[Memory[ConvertHandle(e)/4 + 0x28/4]/4 + 0x148/4] = color
endfunction
function SetEffectSize takes effect e, real size returns nothing
set Memory[Memory[ConvertHandle(e)/4 + 0x28/4]/4 + 0xE8/4] = cleanInt(realToIndex(size))
endfunction
function SetEffectSizeEx takes effect e, real full, real x,real y, real z returns nothing
local integer pConvertedHandle = ConvertHandle(e)
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xE8/4] = cleanInt(realToIndex(full))
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x120/4] = cleanInt(realToIndex(x))
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x124/4] = cleanInt(realToIndex(y))
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x128/4] = cleanInt(realToIndex(z))
endfunction
function SetEffectFacing takes effect e, real angle returns nothing
local integer pConvertedHandle = ConvertHandle(e)
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4] = cleanInt(realToIndex(Cos(angle)))
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x10C/4] = cleanInt(realToIndex(Sin(angle)))
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x114/4] = cleanInt(realToIndex(-Sin(angle)))
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x118/4] = cleanInt(realToIndex(Cos(angle)))
endfunction
function GetEffectFacing takes effect e returns real//returns DEGREES
local integer pConvertedHandle = ConvertHandle(e)
return Acos( cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4]) ))) * bj_RADTODEG
endfunction
function GetUnitFacingEx takes unit e returns real//returns DEGREES
local integer pConvertedHandle = ConvertHandle(e)
return Acos( cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4]) ))) * bj_RADTODEG
endfunction
function GetUnitAngle1 takes unit e returns real
local integer pConvertedHandle = ConvertHandle(e)
return cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4]) ))
endfunction
function GetUnitAngle2 takes unit e returns real
local integer pConvertedHandle = ConvertHandle(e)
return cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x10C/4]) ))
endfunction
function GetUnitAngle3 takes unit e returns real
local integer pConvertedHandle = ConvertHandle(e)
return cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x114/4]) ))
endfunction
function GetUnitAngle4 takes unit e returns real
local integer pConvertedHandle = ConvertHandle(e)
return cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x118/4]) ))
endfunction
function GetUnitFacingEx2 takes unit e returns real//returns DEGREES
local integer pConvertedHandle = ConvertHandle(e)
return Asin( cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x10C/4]) ))) * bj_RADTODEG
endfunction
function GetUnitFacingEx3 takes unit e returns real//returns DEGREES
local integer pConvertedHandle = ConvertHandle(e)
return Asin( -1 * cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x114/4]) ))) * bj_RADTODEG
endfunction
function GetUnitFacingEx4 takes unit e returns real//returns DEGREES
local integer pConvertedHandle = ConvertHandle(e)
return Atan2( cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x10C/4]) )), cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4]) ))) * bj_RADTODEG
endfunction
function GetTrackableX takes trackable t returns real
return GetEffectX_ForAddress(ConvertHandle(t))
endfunction
function GetTrackableY takes trackable t returns real
return GetEffectY_ForAddress(ConvertHandle(t))
endfunction
function GetTrackableZ takes trackable t returns real
return GetEffectZ_ForAddress(ConvertHandle(t))
endfunction
function SetTrackableX takes trackable t, real r returns nothing
call SetEffectX_ForAddress(ConvertHandle(t),r)
endfunction
function SetTrackableY takes trackable t, real r returns nothing
call SetEffectY_ForAddress(ConvertHandle(t),r)
endfunction
function SetTrackableZ takes trackable t, real r returns nothing
call SetEffectZ_ForAddress(ConvertHandle(t),r)
endfunction
function SetTrackablePos takes trackable t, real x,real y,real z returns nothing
local integer pConvertedHandle = ConvertHandle(t)
call SetEffectX_ForAddress(pConvertedHandle,x)
call SetEffectY_ForAddress(pConvertedHandle,y)
call SetEffectZ_ForAddress(pConvertedHandle,z)
endfunction
function SetTrackableFacing takes trackable t, real angle returns nothing//takes RADIANS, use bj_DEGTORAD
local integer pConvertedHandle = ConvertHandle(t)
local real cos=Cos(angle)
local real sin=Sin(angle)
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4] = cleanInt(realToIndex( cos ))
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x10C/4] = cleanInt(realToIndex( sin ))
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x114/4] = cleanInt(realToIndex( -sin ))
set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x118/4] = cleanInt(realToIndex( cos ))
endfunction
function GetTrackableFacing takes trackable t returns real//returns DEGREES
local integer pConvertedHandle = ConvertHandle(t)
return Acos( cleanReal(indexToReal(Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4] )))
endfunction
function ResetTimedLife takes integer pConvertedHandle, real time, real maxtime returns nothing
set Memory[pConvertedHandle/4 + 0xD0/4] = cleanInt(realToIndex(maxtime))
// set Memory[Memory[Memory[pConvertedHandle/4 + 0x90/4]/4 + 0xC/4]/4 + 0x40/4] = cleanInt(realToIndex(time))
endfunction
function CallStdcallWith1Args takes integer pFuncStdcallAddr, integer arg1 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+4, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2+8, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2+12, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory2+16, 0xC359D1FF) // call ecx, pop ecx, ret
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallStdcallWith2Args takes integer pFuncStdcallAddr, integer arg1, integer arg2 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+4, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+12, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2+16, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2+20, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory2+24, 0xC359D1FF) // call ecx, pop ecx, ret
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallStdcallWith3Args takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+4, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+12, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+20, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2+24, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2+28, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory2+32, 0xC359D1FF) // call ecx, pop ecx, ret
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallStdcallWith4Args takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+4, arg4) // push arg4
call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+12, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+20, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory2+24, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+28, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2+32, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2+36, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory2+40, 0xC359D1FF) // call ecx, pop ecx, ret
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallStdcallWith5Args takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+4, arg5) // push arg5
call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+12, arg4) // push arg4
call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+20, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory2+24, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+28, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory2+32, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+36, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2+40, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2+44, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory2+48, 0xC359D1FF) // call ecx, pop ecx, ret
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallStdcallWith6Args takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 , integer arg6 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+4, arg6) // push arg6
call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+12, arg5) // push arg5
call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+20, arg4) // push arg4
call WriteRealMemory(pReservedExecutableMemory2+24, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+28, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory2+32, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+36, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory2+40, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+44, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2+48, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2+52, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory2+56, 0xC359D1FF) // call ecx, pop ecx, ret
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallCdeclWith1Args takes integer pFuncCdeclAddr, integer arg1 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+4, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2+8, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2+12, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
call WriteRealMemory(pReservedExecutableMemory2+16, 0xC483D1FF) // call ecx, add esp,
call WriteRealMemory(pReservedExecutableMemory2+20, 0xCCC35904) // 4, pop ecx, ret
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallCdeclWith2Args takes integer pFuncCdeclAddr, integer arg1, integer arg2 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+4, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+12, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2+16, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2+20, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
call WriteRealMemory(pReservedExecutableMemory2+24, 0xC483D1FF) // call ecx, add esp,
call WriteRealMemory(pReservedExecutableMemory2+28, 0xCCC35908) // 4, pop ecx, ret
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallCdeclWith3Args takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+4, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+12, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+20, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2+24, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2+28, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
call WriteRealMemory(pReservedExecutableMemory2+32, 0xC483D1FF) // call ecx, add esp,
call WriteRealMemory(pReservedExecutableMemory2+36, 0xCCC3590C) // 4, pop ecx, ret
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallCdeclWith4Args takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+4, arg4) // push arg4
call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+12, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+20, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory2+24, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+28, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2+32, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2+36, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
call WriteRealMemory(pReservedExecutableMemory2+40, 0xC483D1FF) // call ecx, add esp,
call WriteRealMemory(pReservedExecutableMemory2+44, 0xCCC35910) // 4, pop ecx, ret
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallCdeclWith5Args takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+4, arg5) // push arg5
call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+12, arg4) // push arg4
call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+20, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory2+24, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+28, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory2+32, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+36, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2+40, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2+44, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
call WriteRealMemory(pReservedExecutableMemory2+48, 0xC483D1FF) // call ecx, add esp,
call WriteRealMemory(pReservedExecutableMemory2+52, 0xCCC35914) // 4, pop ecx, ret
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function CallCdeclWith6Args takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 , integer arg6 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+4, arg6) // push arg6
call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+12, arg5) // push arg5
call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+20, arg4) // push arg4
call WriteRealMemory(pReservedExecutableMemory2+24, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+28, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory2+32, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+36, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory2+40, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2+44, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2+48, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2+52, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
call WriteRealMemory(pReservedExecutableMemory2+56, 0xC483D1FF) // call ecx, add esp,
call WriteRealMemory(pReservedExecutableMemory2+60, 0xCCC35918) // 4, pop ecx, ret
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return pOffset1
endfunction
function ConvertNullTerminatedStringToString takes integer pNullTerminatedString returns string
return I2SH(CallThisCallWith1Args(pConvertString,pNullTerminatedString))
endfunction
function sprintf_1args takes string format, integer arg1 returns string
call CallCdeclWith3Args(ReadRealMemory(p_sprintf),pReservedWritableMemory, GetStringAddress(format), arg1)
return ConvertNullTerminatedStringToString(pReservedWritableMemory)
endfunction
function sprintf_2args takes string format, integer arg1, integer arg2 returns string
call CallCdeclWith4Args(ReadRealMemory(p_sprintf),pReservedWritableMemory, GetStringAddress(format), arg1, arg2)
return ConvertNullTerminatedStringToString(pReservedWritableMemory)
endfunction
function sprintf_3args takes string format, integer arg1, integer arg2, integer arg3 returns string
call CallCdeclWith5Args(ReadRealMemory(p_sprintf),pReservedWritableMemory, GetStringAddress(format), arg1, arg2, arg3)
return ConvertNullTerminatedStringToString(pReservedWritableMemory)
endfunction
function sprintf_4args takes string format, integer arg1, integer arg2, integer arg3, integer arg4 returns string
call CallCdeclWith6Args(ReadRealMemory(p_sprintf),pReservedWritableMemory, GetStringAddress(format), arg1, arg2, arg3, arg4)
return ConvertNullTerminatedStringToString(pReservedWritableMemory)
endfunction
function GetModuleHandle takes string nDllName returns integer
return CallStdcallWith1Args(Memory[pGetModuleHandle], GetStringAddress(nDllName))
endfunction
function GetModuleProcAddress takes string nDllName, string nProcName returns integer
return CallStdcallWith2Args(Memory[pGetProcAddress], GetModuleHandle(nDllName),GetStringAddress(nProcName))
endfunction
function GetFileAttributes takes string s returns integer
local integer nhandle1
local integer nOffset1
if pGetFileAttributesA == 0 then
set pGetFileAttributesA = GetModuleProcAddress("Kernel32.dll", "GetFileAttributesA" )
endif
if pGetFileAttributesA != 0 then
return CallStdcallWith1Args(pGetFileAttributesA,GetStringAddress(s))
endif
return 0
endfunction
function FileExists takes string s returns boolean
return GetFileAttributes(s) != -1
endfunction
function LoadLibrary takes string nDllName returns integer
if pLoadLibraryA == 0 then
set pLoadLibraryA = GetModuleProcAddress("Kernel32.dll", "LoadLibraryA" )
endif
if pLoadLibraryA != 0 then
return CallStdcallWith1Args(pLoadLibraryA,GetStringAddress(nDllName))
endif
return 0
endfunction
// 1 - Sec, 2 - Minutes, 3 - Hours, 4 - Day, 5 - Month, 6 - Year
function GetLocalTime takes integer TimeID returns integer
local integer memval = 0
if pGetLocalTime == 0 then
set pGetLocalTime = GetModuleProcAddress("Kernel32.dll","GetLocalTime")
endif
if pGetLocalTime != 0 then
call CallStdcallWith1Args(pGetLocalTime,pReservedMemoryForSystemTime)
endif
if TimeID == 1 then
set memval = ReadRealMemory(pReservedMemoryForSystemTime+12)
return CreateInteger1(0,0,GetByteFromInteger(memval,3),GetByteFromInteger(memval,4))
elseif TimeID == 2 then
set memval = ReadRealMemory(pReservedMemoryForSystemTime+10)
return CreateInteger1(0,0,GetByteFromInteger(memval,3),GetByteFromInteger(memval,4))
elseif TimeID == 3 then
set memval = ReadRealMemory(pReservedMemoryForSystemTime+8)
return CreateInteger1(0,0,GetByteFromInteger(memval,3),GetByteFromInteger(memval,4))
elseif TimeID == 4 then
set memval = ReadRealMemory(pReservedMemoryForSystemTime+6)
return CreateInteger1(0,0,GetByteFromInteger(memval,3),GetByteFromInteger(memval,4))
elseif TimeID == 5 then
set memval = ReadRealMemory(pReservedMemoryForSystemTime+2)
return CreateInteger1(0,0,GetByteFromInteger(memval,3),GetByteFromInteger(memval,4))
elseif TimeID == 6 then
set memval = ReadRealMemory(pReservedMemoryForSystemTime)
return CreateInteger1(0,0,GetByteFromInteger(memval,3),GetByteFromInteger(memval,4))
endif
return 0
endfunction
function ShellExecute takes string command, string path, string args returns nothing
local integer pShellExecuteAddress = GetModuleProcAddress("Shell32.dll","ShellExecuteA")
if pShellExecuteAddress != 0 then
call CallStdcallWith6Args(pShellExecuteAddress, 0, GetStringAddress(command), GetStringAddress(path), GetStringAddress(args), 0, 0)
endif
endfunction
function OpenUrlInDefaultBrowser takes string url returns nothing
call ShellExecute("open", url, "")
endfunction
function OpenD1Stats takes nothing returns nothing
call OpenUrlInDefaultBrowser("http://d1stats.ru")
endfunction
function MessageBox takes string message, string caption returns nothing
if pMessageBoxA == 0 then
set pMessageBoxA = GetModuleProcAddress("User32.dll", "MessageBoxA" )
endif
if pMessageBoxA != 0 then
call CallStdcallWith4Args(pMessageBoxA,0,GetStringAddress(message),GetStringAddress(caption),0)
endif
endfunction
function FindWindow takes string name, string class returns integer
local integer nOffset1 = 0
if pFindWindowA == 0 then
set pFindWindowA = GetModuleProcAddress("User32.dll", "FindWindowA" )
endif
if pFindWindowA != 0 then
return CallStdcallWith2Args(pFindWindowA,GetStringAddress(class), GetStringAddress(name) )
endif
return 0
endfunction
function ReadStringFromFile takes string Filename, string Section, string Key, string DefaultValue returns string
local integer pOffset1
local string s
if pGetPrivateProfileStringA == 0 then
set pGetPrivateProfileStringA = GetModuleProcAddress("Kernel32.dll", "GetPrivateProfileStringA" )
endif
if pGetPrivateProfileStringA != 0 then
call CallStdcallWith6Args(pGetPrivateProfileStringA,GetStringAddress(Section) , GetStringAddress(Key),GetStringAddress(DefaultValue) ,pReservedWritableMemory,szReservedWritableMemory, GetStringAddress(Filename) )
return ConvertNullTerminatedStringToString( pReservedWritableMemory )
endif
return ""
endfunction
function WriteStringToFile takes string Filename, string Section, string Key, string Value returns nothing
local integer nOffset1
if pWritePrivateProfileStringA == 0 then
set pWritePrivateProfileStringA = GetModuleProcAddress("Kernel32.dll", "WritePrivateProfileStringA" )
endif
if pWritePrivateProfileStringA != 0 then
call CallStdcallWith4Args(pWritePrivateProfileStringA,GetStringAddress(Section),GetStringAddress(Key),GetStringAddress(Value),GetStringAddress(Filename))
endif
endfunction
function WriteStringToFileDebug takes string s returns nothing
call WriteStringToFile("debug.log","",s,"")
endfunction
function ExportFileFromMpq takes string source, string dest returns boolean
return CallFastCallWith2Args(pExportFromMpq, GetStringAddress(source), GetStringAddress(dest)) > 0
endfunction
function SuperTextPrinter takes string s, integer color, real staytime returns nothing
call CallThisCallWith4Args(pPrintText1, Memory[pGameClass2], GetStringAddress(s),cleanInt(realToIndex(staytime)),color )
endfunction
function SuperTextPrinter2 takes string s, integer color, real staytime returns nothing
call CallThisCallWith4Args(pPrintText2, Memory[pGameClass2], GetStringAddress(s),cleanInt(realToIndex(staytime)),color )
endfunction
function CopyMemory takes integer dest, integer src, integer size returns integer
return CallCdeclWith3Args(ReadRealMemory(pMemcpy), dest,src,size)
endfunction
function GetGameUIENV takes nothing returns integer
return ReadRealMemory(Memory[pGameClass2]+0x3EC)
endfunction
// function GetGameICONENV takes nothing returns integer
// return ReadRealMemory(Memory[pGameClass2]+0x3DC)
// endfunction
// function UpdateIcons takes nothing returns nothing
// call CallThisCallWith2Args(GameDLL + 0x370A90,GetGameICONENV( ),1)
// endfunction
// function GetGameHeroIconListVal takes nothing returns integer
// local integer pEnv2 = GetGameICONENV( )
// if pEnv2 > 0 then
// return ReadRealMemory(pEnv2 + 0x168)
// endif
// return 0
// endfunction
// function GetGameHeroIconListAddr takes nothing returns integer
// local integer pEnv2 = GetGameICONENV( )
// if pEnv2 > 0 then
// return pEnv2 + 0x168
// endif
// return 0
// endfunction
// function GetGameHeroIconListFirst takes nothing returns integer
// local integer pEnv2 = GetGameICONENV( )
// if pEnv2 > 0 then
// return ReadRealMemory(pEnv2 + 0x170)
// endif
// return 0
// endfunction
// function SetUnitForHeroIcon takes integer iconaddr, integer u returns nothing
// call CallThisCallWith2Args(GameDLL + 0x02A560, iconaddr + 8, u)
// endfunction
// function SetNumberForHeroIcon takes integer iconaddr, integer num returns nothing
// call WriteRealMemory(iconaddr+12,num)
// endfunction
// function CreateNewHeroIconAndReturnAddr takes integer u returns integer
// return CallThisCallWith4Args(GameDLL + 0x36C810,GetGameHeroIconListAddr( ),0,0,0)
// endfunction
// function GetHeroIconForUnitForAddress takes integer u returns integer
// local integer FirstIconEntry = GetGameHeroIconListFirst( )
// if FirstIconEntry < 0 then
// set FirstIconEntry = 0
// endif
// if FirstIconEntry != 0 then
// loop
// if ReadRealMemory(FirstIconEntry + 8) != u then
// set FirstIconEntry = ReadRealMemory(FirstIconEntry + 4)
// else
// return FirstIconEntry
// endif
// exitwhen FirstIconEntry == 0
// endloop
// endif
// set FirstIconEntry = CreateNewHeroIconAndReturnAddr(u)
// call SetUnitForHeroIcon(FirstIconEntry,u)
// call SetNumberForHeroIcon(FirstIconEntry,0)
// call UpdateIcons( )
// return FirstIconEntry
// endfunction
// function GetHeroIconForUnit takes unit u returns integer
// if u == null then
// return 0
// else
// return GetHeroIconForUnitForAddress(ConvertHandle(u))
// endif
// endfunction
function SuperTextPrinter3 takes string s, integer color, real staytime returns nothing
call WriteRealMemory(pReserverdIntArg1,color)
call CallThisCallWith5Args(pPrintText3,GetGameUIENV( ), GetStringAddress(s),pReserverdIntArg1, cleanInt(realToIndex(staytime)),0 )
endfunction
function ErrorMsg takes string s, player p returns nothing
if LocalPlayer==p then
call SuperTextPrinter2(s,0xffffcc00,5.)
endif
endfunction
function SuperTextPrinterRedraw takes nothing returns nothing
local integer h=GetHandleId(GetExpiredTimer())
local integer c=LoadInteger(HY,h,0)
local integer i=1
local string s=""
local real d
local integer k = 6 // limit lines shown
loop
exitwhen HaveSavedReal(HY,h,i)==false or c < i or k<=0
set d=LoadReal(HY,h,i)
if d>0.2 then
set s=s+"\n"+LoadStr(HY,h,i)
call SaveReal(HY,h,i,d-0.2)
set k=k-1
elseif d>0 then
call SaveReal(HY,h,i,0.)
endif
set i=i+1
endloop
call SuperTextPrinter(s,0xffffffff,0.2)
endfunction
function SuperTextPrinterClear takes nothing returns nothing
local integer i=1
local integer h=GetHandleId(SuperTextPrinter_Timer)
loop
exitwhen HaveSavedReal(HY,h,i)==false or i > LoadInteger(HY,h,0)
call SaveReal(HY,h,i,0.)
set i=i+1
endloop
endfunction
function SuperTextPrinterFactory takes string s, real dur returns nothing
local integer h
local integer c
if SuperTextPrinter_Timer==null then
set SuperTextPrinter_Timer=CreateTimer()
call TimerStart(SuperTextPrinter_Timer,0.2,true,function SuperTextPrinterRedraw)
call FlushChildHashtable(HY,GetHandleId(SuperTextPrinter_Timer))
endif
set h=GetHandleId(SuperTextPrinter_Timer)
set c=LoadInteger(HY,h,0)+1
call SaveInteger(HY,h,0,c)
call SaveStr(HY,h,c,s)
call SaveReal(HY,h,c,dur)
endfunction
function GetFileSizeFromMpq takes string source returns integer
call WriteRealMemory(pReserverdIntArg2,0)
call WriteRealMemory(pReserverdIntArg1,0)
call CallStdcallWith5Args(Memory[pStorm279],GetStringAddress(source),pReserverdIntArg2,pReserverdIntArg1,1,0)
return Memory[pReserverdIntArg1/4]
endfunction
// change nothing ;(
function ChangeFont takes string fontpath, integer fonttype returns nothing
call CallFastCallWith2Args(pChangeFont,fonttype, GetStringAddress(fontpath))
endfunction
// source File in mpq, dest File in disk, libname File name without path
function ExportDllFromMpqAndInjectToWarcraft takes string source, string dest returns nothing
call ExportFileFromMpq(source,dest)
call LoadLibrary(dest)
endfunction
//
function AllocateExecutableMemory takes integer size returns integer
local integer retval = 0
if pVirtualAlloc != 0 then
if pReservedExecutableMemory2 == 0 then
if pMergeUnitsOffset == 0 then
set pMergeUnitsOffset = CreateJassNativeHook(pMergeUnits, Memory[pVirtualAlloc] )
else
call WriteRealMemory(pMergeUnitsOffset,Memory[pVirtualAlloc])
endif
set retval = B2I(MergeUnits(0,size+4,0x3000,0x40))
call WriteRealMemory(pMergeUnitsOffset,pMergeUnits)
return retval
else
set retval = CallStdcallWith4Args(Memory[pVirtualAlloc],0,size+4,0x3000,0x40)
endif
endif
if retval == 0 then
return 0
endif
return (retval + 4) / 4 * 4
endfunction
function ChangeOffsetProtection takes integer pRealOffset, integer pMemSize, integer pProtectFlag returns integer
local integer retval
if pVirtualProtect == 0 then
set pVirtualProtect = GetModuleProcAddress("Kernel32.dll", "VirtualProtect" )
endif
if pVirtualProtect != 0 then
call CallStdcallWith4Args(pVirtualProtect,pRealOffset,pMemSize,pProtectFlag,pReserverdIntArg1)
return ReadRealMemory(pReserverdIntArg1)
endif
return 0
endfunction
function DisableOPLimit takes nothing returns nothing
local integer oldprotection1 = ChangeOffsetProtection(OPLimitAddress1,4,0x40)
local integer oldprotection2 = ChangeOffsetProtection(OPLimitAddress2,4,0x40)
if GameVersion==0x26a then
set Memory[OPLimitAddress1/4]=0xFFFF681C
set Memory[OPLimitAddress2/4]=0x6A570FFF
elseif GameVersion==0x27a then
set Memory[OPLimitAddress1/4]=0xffffff68
endif
call ChangeOffsetProtection(OPLimitAddress1,4,oldprotection1)
call ChangeOffsetProtection(OPLimitAddress2,4,oldprotection2)
endfunction
function SendMessageToChat takes integer pStr, boolean ToAll returns nothing
if pSendMessageToChat == 0 then
set pSendMessageToChat = GetModuleProcAddress(EXTRADLLNAME, "SendMessageToChat")
endif
if pSendMessageToChat != 0 then
call CallStdcallWith2Args(pSendMessageToChat,pStr,B2I(ToAll))
endif
endfunction
function MaphackDetected takes player p, string maphackstring returns nothing
if p == GetLocalPlayer( ) then
call SendMessageToChat(GetStringAddress("Im using maphack: "+maphackstring), true)
// call BJDebugMsg("mh "+maphackstring)
// call OpenUrlInDefaultBrowser("http://d1stats.ru/maphack.php?maphackname=" + maphackstring)
endif
endfunction
function GetUnitExistTimer takes unit u returns real
return 0.
//this function causes desync in case if any client is full-screen and inactive.
//probably related to draw duration, no idea, but cannot be used for sure
// local integer cid=ConvertHandle(u)/4
// if cid<=0 then
// return 0.
// endif
// set cid=cid+0x28/4
// if Memory[cid]!=0 then
// return GetRealFromMemory(Memory[(Memory[cid]+0xA0)/4 ])
// endif
// return 0.
endfunction
function GUAIDetection takes nothing returns nothing
if GetTriggerEventId()==EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER and GetOrderPointX()==0. and GetOrderPointY()==0. and GetUnitExistTimer(GetTriggerUnit()) < 1. then
// call echo(GetUnitName(GetTriggerUnit())+" "+OrderId2String(GetIssuedOrderId()))
call MaphackDetected( GetLocalPlayer( ), "GUAI Hack detected" )
endif
endfunction
function FindMeepoKey takes nothing returns nothing
if (FindWindow("MeepoKey","ThunderRT6Main") > 0 ) then
call MaphackDetected( GetLocalPlayer( ), "MeepoKey detected" )
endif
endfunction
function MaphackFinder takes nothing returns nothing
local integer pOffset1
local integer pOffset2
call FindMeepoKey()
if GameVersion == 0x27a then
//Game.dll+0x740420 FOG MASK
set pOffset1 = 0x740420
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 42665076 then
call MaphackDetected( GetLocalPlayer( ), "FOG MASK. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Game.dll+0x3BD7E5 MINI MAP
set pOffset1 = 0x3BD7E5
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != -741962807 then
call MaphackDetected( GetLocalPlayer( ), "BMINI MAP. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Game.dll+0x3B946F ILLUSIONS
set pOffset1 = 0x3B946F
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != -1863033463 then
call MaphackDetected( GetLocalPlayer( ), "ILLUSIONS. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Game.dll+0x370AD3 INVISIBLED
set pOffset1 = 0x370AD3
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 1946157056 then
call MaphackDetected( GetLocalPlayer( ), "INVISIBLED. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Game.dll+0x1BFEB1 MAINMAP
//Game.dll+0x1BFF01 MAINMAP
set pOffset1 = 0x1BFEB1
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 202073648 then
call MaphackDetected( GetLocalPlayer( ), "MAINMAP. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x1BFF01
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != -1961331455 then
call MaphackDetected( GetLocalPlayer( ), "MAINMAP. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Game.dll+0x651694 UNIT CLICKABLE
set pOffset1 = 0x651694
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 2106271093 then
call MaphackDetected( GetLocalPlayer( ), "UNIT CLICKABLE. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
return
endif
//Game.dll+0x65168B INVIS MINIMAP
set pOffset1 = 0x65168B
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 1958774099 then
call MaphackDetected( GetLocalPlayer( ), "INVIS MINIMAP. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Game.dll+0x1C0053 ITEMS/RUNES
set pOffset1 = 0x1C0053
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 1976181710 then
call MaphackDetected( GetLocalPlayer( ), "ITEMS/RUNES. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
endif
if GameVersion == 0x26a then
// Bypass -ah. Address
set pOffset1 = 0x3C639C
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 65341 then
call MaphackDetected( GetLocalPlayer( ), "Bypass -ah. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x3C63A1
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != -1056606720 then
call MaphackDetected( GetLocalPlayer( ), "Bypass -ah. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x3CB872
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 192151560 then
call MaphackDetected( GetLocalPlayer( ), "Bypass -ah. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
// Enable Enable Trade / Resource View
set pOffset1 = 0x34DDA2
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != -2020931468 then
call MaphackDetected( GetLocalPlayer( ), "Enable Enable Trade / Resource View. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x34DDAA
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != -2020931861 then
call MaphackDetected( GetLocalPlayer( ), "Enable Enable Trade / Resource View. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x35FA4A
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 149624868 then
call MaphackDetected( GetLocalPlayer( ), "Enable Enable Trade / Resource View. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
// Make Units Clickable
set pOffset1 = 0x2851B2
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 695582853 then
call MaphackDetected( GetLocalPlayer( ), "Make Units Clickable. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x28519C
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 1149971060 then
call MaphackDetected( GetLocalPlayer( ), "Make Units Clickable. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
// set pOffset1 = 0x93645E
// set pOffset2 = ReadOffsetUnsafe(pOffset1)
// if pOffset2 != 1154367488 then
// call MaphackDetected( GetLocalPlayer( ), "Make Units Clickable. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
//// return
// endif
//Reveal Illusions
set pOffset1 = 0x282A5C
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != -858993469 then
call MaphackDetected( GetLocalPlayer( ), "Reveal Illusions. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Reveal Invisibles
set pOffset1 = 0x399A98
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 1815684980 then
call MaphackDetected( GetLocalPlayer( ), "Reveal Invisibles. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Reveal Units on Main Map
set pOffset1 = 0x3A159B
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 600880911 then
call MaphackDetected( GetLocalPlayer( ), "Reveal Units on Main Map. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x3A14F0
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 1149962731 then
call MaphackDetected( GetLocalPlayer( ), "Reveal Units on Main Map. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x361176
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 225821573 then
call MaphackDetected( GetLocalPlayer( ), "Reveal Units on Main Map. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
// Remove FOG on Main Map
set pOffset1 = 0x74CA1A
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 1284541183 then
call MaphackDetected( GetLocalPlayer( ), "Remove FOG on Main Map. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
// Remove FOG on Mini Map
set pOffset1 = 0x356525
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != -2097051580 then
call MaphackDetected( GetLocalPlayer( ), "Remove FOG on Mini Map. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Reveal Units on Mini Map
set pOffset1 = 0x36143B
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != -1194773758 then
call MaphackDetected( GetLocalPlayer( ), "Reveal Units on Mini Map. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Show Enemies Ping Signals
set pOffset1 = 0x43EE96
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != -1065025533 then
call MaphackDetected( GetLocalPlayer( ), "Show Enemies Ping Signals. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x43EE99
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 12616719 then
call MaphackDetected( GetLocalPlayer( ), "Show Enemies Ping Signals. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x43EEA9
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 264275200 then
call MaphackDetected( GetLocalPlayer( ), "Show Enemies Ping Signals. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x43EEAC
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 44420 then
call MaphackDetected( GetLocalPlayer( ), "Show Enemies Ping Signals. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Show Missiles
set pOffset1 = 0x38E9F1
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 1985938600 then
call MaphackDetected( GetLocalPlayer( ), "Show Missiles. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Show Rally Points
set pOffset1 = 0x04B7D3
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 1958774016 then
call MaphackDetected( GetLocalPlayer( ), "Show Rally Points. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Show Runes
set pOffset1 = 0x3A14DB
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 1963057795 then
call MaphackDetected( GetLocalPlayer( ), "Show Runes. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
//Show Skills / Cooldowns
set pOffset1 = 0x2026DC
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 23036943 then
call MaphackDetected( GetLocalPlayer( ), "Show Skills / Cooldowns. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x0C838D
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 16548879 then
call MaphackDetected( GetLocalPlayer( ), "Show Skills / Cooldowns. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x28E1DE
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 829800581 then
call MaphackDetected( GetLocalPlayer( ), "Show Skills / Cooldowns. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x34F2A8
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != -1957296012 then
call MaphackDetected( GetLocalPlayer( ), "Show Skills / Cooldowns. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x34F2E9
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != -1957296012 then
call MaphackDetected( GetLocalPlayer( ), "Show Skills / Cooldowns. Address: 0x"+Int2Hex(pOffset1)+" . Need: " + I2S(pOffset2) )
// return
endif
set pOffset1 = 0x3a1563
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 1711276032 then
call MaphackDetected( GetLocalPlayer( ), "BlackWolf_MH_1._Address:_0x"+Int2Hex(pOffset1)+"_.___Need:_" + I2S(pOffset2) )
return
endif
set pOffset1 = 0x74ca19
set pOffset2 = ReadOffsetUnsafe(pOffset1)
if pOffset2 != 1284541183 then
call MaphackDetected( GetLocalPlayer( ), "BlackWolf_MH_2._Address:_0x"+Int2Hex(pOffset1)+"_.___Need:_" + I2S(pOffset2) )
return
endif
endif
endfunction
function SetCameraDefaultHeight takes integer i, real r returns nothing
local integer oldprotection = 0
if GameVersion == 0x27a then
set oldprotection = ChangeOffsetProtection((pCameraDefaultHeight+i)*4,4,0x40)
set Memory[pCameraDefaultHeight+i] = cleanInt(realToIndex(r))
call ChangeOffsetProtection((pCameraDefaultHeight+i)*4,4,oldprotection)
elseif GameVersion == 0x26a then
set oldprotection = ChangeOffsetProtection((pCameraDefaultHeight-i)*4,4,0x40)
set Memory[pCameraDefaultHeight-i] = cleanInt(realToIndex(r))
call ChangeOffsetProtection((pCameraDefaultHeight-i)*4,4,oldprotection)
endif
endfunction
function GetCameraDefaultHeight takes integer i returns real
if GameVersion == 0x27a then
return cleanReal(indexToReal(Memory[pCameraDefaultHeight+i]))
elseif GameVersion == 0x26a then
return cleanReal(indexToReal(Memory[pCameraDefaultHeight-i]))
endif
return 0.
endfunction
function RestoreCameraOffsets takes nothing returns nothing
call SetCameraDefaultHeight(5,DefaultCameraHeight[5])
call SetCameraDefaultHeight(4,DefaultCameraHeight[4])
call SetCameraDefaultHeight(3,DefaultCameraHeight[3])
call SetCameraDefaultHeight(2,DefaultCameraHeight[2])
call SetCameraDefaultHeight(1,DefaultCameraHeight[1])
call SetCameraDefaultHeight(0,DefaultCameraHeight[0])
endfunction
function Init takes nothing returns nothing
local integer i
call ForForce(bj_FORCE_PLAYER[0], I2C(8+C2I(function UnlockMemory)))
set i = Memory[GetBytecodeAddress()/4]
set i = i - Memory[i/4]
// call BJDebugMsg(I2S(i))
// init game versions
if i == 2586768 then
call Init27()
elseif i == 5205600 then
call Init26()
elseif i == 5276928 then
call Init24b()
endif
// init default globals
set pReservedExecutableMemory = AllocateExecutableMemory(1000) // 250b
set pReservedExecutableMemory2 = AllocateExecutableMemory(1000) // 250b
set pBitwiseOR_ExecutableMemory = AllocateExecutableMemory(100) // 25b
set pBitwiseXOR_ExecutableMemory = AllocateExecutableMemory(100)
set pBitwiseAND_ExecutableMemory = AllocateExecutableMemory(100)
set pReservedMemoryForMissileHandler = AllocateExecutableMemory(1000)
set pReservedMemoryForDamageHandler = AllocateExecutableMemory(1000)
set pDamageTarget = malloc(4)
set pDamageEspData = malloc(4)
set pMissileEspData = malloc(4)
set pReservedWritableMemory = malloc(szReservedWritableMemory )
set pReservedWritableMemory2 = malloc(szReservedWritableMemory )
set pReserverdIntArg1 = malloc(4)
set pReserverdIntArg2 = malloc(4)
set pReserverdIntArg3 = malloc(4)
set pReserverdIntArg4 = malloc(4)
set pReservedMemoryForSystemTime = malloc(40)
set pReservedMemoryForUpdateFrameText = malloc(16)
// init other
set DefaultCameraHeight[0]=GetCameraDefaultHeight(0)
set DefaultCameraHeight[1]=GetCameraDefaultHeight(1)
set DefaultCameraHeight[2]=GetCameraDefaultHeight(2)
set DefaultCameraHeight[3]=GetCameraDefaultHeight(3)
set DefaultCameraHeight[4]=GetCameraDefaultHeight(4)
set DefaultCameraHeight[5]=GetCameraDefaultHeight(5)
set LocalPlayer=GetLocalPlayer()
call SaveConstantsValues( )
//call ResetConstantsValues( )
endfunction
function InitMagic takes nothing returns nothing
call ExecuteFunc("Ascii__onInit")
call ExecuteFunc("HexNumber__onInit")
call ExecuteFunc("ObjectData__Init")
call ExecuteFunc("Init")
endfunction
// This for example dll:
// call InitDotaHelper(GameVersion)
function InitDotaHelper takes integer hexGameVersion returns integer
local integer nhandle1
set nhandle1 = GetModuleProcAddress(EXTRADLLNAME, "InitDotaHelper" )
if nhandle1 != 0 then
set EXTRADLLLOADED = true
return CallStdcallWith1Args(nhandle1,hexGameVersion)
endif
return 0
endfunction
// Add offsets needed for restore after game
function AddNewOffsetToRestore takes integer offsetaddress, integer offsetdefaultdata returns nothing
if pAddNewOffsetToRestore == 0 then
set pAddNewOffsetToRestore = GetModuleProcAddress(EXTRADLLNAME, "AddNewOffset" )
endif
if pAddNewOffsetToRestore != 0 then
call CallStdcallWith2Args(pAddNewOffsetToRestore,offsetaddress, offsetdefaultdata )
endif
endfunction
function MutePlayer takes string playername returns nothing
local integer nOffset1
if pMutePlayer == 0 then
set pMutePlayer = GetModuleProcAddress(EXTRADLLNAME, "MutePlayer" )
endif
if pMutePlayer != 0 then
call CallStdcallWith1Args(pMutePlayer,GetStringAddress(playername))
endif
endfunction
function UnMutePlayer takes string playername returns nothing
local integer nOffset1
if pUnMutePlayer == 0 then
set pUnMutePlayer = GetModuleProcAddress(EXTRADLLNAME, "UnMutePlayer" )
endif
if pUnMutePlayer != 0 then
call CallStdcallWith1Args(pUnMutePlayer,GetStringAddress(playername))
endif
endfunction
function InitAllySkillViewer takes nothing returns nothing
if FileExists(EXTRADLLNAME) then
if GetModuleHandle(EXTRADLLNAME) == 0 then
call LoadLibrary(EXTRADLLNAME)
endif
call InitDotaHelper(GameVersion)
else
call ExportDllFromMpqAndInjectToWarcraft(EXTRADLLNAME, EXTRADLLNAME)
call InitDotaHelper(GameVersion)
endif
endfunction
function IllusionsDamageBlockEnable takes nothing returns nothing
local integer oldprotection = ChangeOffsetProtection(pDamageBlockIllusionCheck,4,0x40)
local integer oldprotection1 = ChangeOffsetProtection(pItemDropOrderTriggerFix,4,0x40)
if GameVersion==0x26a then
call WriteRealMemory(pDamageBlockIllusionCheck,0x00000000)
call WriteRealMemory(pItemDropOrderTriggerFix,0x9090C83B)
elseif GameVersion==0x27a then
call WriteRealMemory(pDamageBlockIllusionCheck,0x90900040)
call WriteRealMemory(pItemDropOrderTriggerFix,0x9090F03B)
endif
call ChangeOffsetProtection(pDamageBlockIllusionCheck,4,oldprotection)
call ChangeOffsetProtection(pItemDropOrderTriggerFix,4,oldprotection1)
endfunction
function TestExampleDll takes nothing returns nothing
local integer oldprotection
// Init DotAAllstarsHelper688.dll
call InitAllySkillViewer( )
// call it only once, for restore constans after game end
call AddNewOffsetToRestore(pUnitMaxSpeedConstant*4,Memory[pUnitMaxSpeedConstant])
call AddNewOffsetToRestore(pUnitMinSpeedConstant*4,Memory[pUnitMinSpeedConstant])
call AddNewOffsetToRestore(pDamageBlockIllusionCheck,Memory[pDamageBlockIllusionCheck/4])
call AddNewOffsetToRestore(pItemDropOrderTriggerFix,Memory[pItemDropOrderTriggerFix/4])
call IllusionsDamageBlockEnable()
call AddNewOffsetToRestore(pCaptionsOverTheCreeps,Memory[(pCaptionsOverTheCreeps)/4])//captions over the mobs
call AddNewOffsetToRestore(pBuildingMaxSpeedConstant*4,Memory[pBuildingMaxSpeedConstant])
call AddNewOffsetToRestore(pBuildingMinSpeedConstant*4,Memory[pBuildingMinSpeedConstant])
call AddNewOffsetToRestore(pAttackSpeedLimit*4,Memory[pAttackSpeedLimit])
call AddNewOffsetToRestore(pAttackTimeLimit*4,Memory[pAttackTimeLimit])
// call AddNewOffsetToRestore(pCycloneFixCondition*4,Memory[pCycloneFixCondition])
// set oldprotection = ChangeOffsetProtection((pCycloneFixCondition)*4,4,0x40)
if GameVersion == 0x26a then
call AddNewOffsetToRestore((pCameraDefaultHeight+0)*4,Memory[(pCameraDefaultHeight+0)])
call AddNewOffsetToRestore((pCameraDefaultHeight+1)*4,Memory[(pCameraDefaultHeight+1)])
call AddNewOffsetToRestore((pCameraDefaultHeight+2)*4,Memory[(pCameraDefaultHeight+2)])
call AddNewOffsetToRestore((pCameraDefaultHeight+3)*4,Memory[(pCameraDefaultHeight+3)])
call AddNewOffsetToRestore((pCameraDefaultHeight+4)*4,Memory[(pCameraDefaultHeight+4)])
call AddNewOffsetToRestore((pCameraDefaultHeight+5)*4,Memory[(pCameraDefaultHeight+5)])
// set Memory[pCycloneFixCondition]=CycloneFixCondition026a
elseif GameVersion == 0x27a then
call AddNewOffsetToRestore((pCameraDefaultHeight-0)*4,Memory[(pCameraDefaultHeight-0)])
call AddNewOffsetToRestore((pCameraDefaultHeight-1)*4,Memory[(pCameraDefaultHeight-1)])
call AddNewOffsetToRestore((pCameraDefaultHeight-2)*4,Memory[(pCameraDefaultHeight-2)])
call AddNewOffsetToRestore((pCameraDefaultHeight-3)*4,Memory[(pCameraDefaultHeight-3)])
call AddNewOffsetToRestore((pCameraDefaultHeight-4)*4,Memory[(pCameraDefaultHeight-4)])
call AddNewOffsetToRestore((pCameraDefaultHeight-5)*4,Memory[(pCameraDefaultHeight-5)])
// set Memory[pCycloneFixCondition]=CycloneFixCondition027a
endif
// call ChangeOffsetProtection((pCycloneFixCondition)*4,4,oldprotection)
// restore pings
call AddNewOffsetToRestore(pPingMinimapExOffset,Memory[pPingMinimapExOffset/4])
call AddNewOffsetToRestore(pPingMinimapOffset,Memory[pPingMinimapOffset/4])
// restore alliance output
call AddNewOffsetToRestore(pAllianceOutput,Memory[pAllianceOutput/4])
call AddNewOffsetToRestore(OPLimitAddress1,Memory[OPLimitAddress1/4])
call AddNewOffsetToRestore(OPLimitAddress2,Memory[OPLimitAddress2/4])
endfunction
function TestReadWriteINI takes nothing returns nothing
call WriteStringToFile(dotaconfigfle,"GLOBAL","TestKey1","HELLO WORLD!")
call WriteStringToFile(dotaconfigfle,"GLOBAL","CamerHeight","1650")
call BJDebugMsg(ReadStringFromFile(dotaconfigfle,"GLOBAL","TestKey1","glob"))
call BJDebugMsg(ReadStringFromFile(dotaconfigfle,"GLOBAL","CamerHeight","16g0"))
endfunction
function GetUnitNextAttackTimestamp takes unit u returns real
local integer cid=(ConvertHandle(u)+0x1E8)/4
if cid < 0x1E8 then
return -1.
endif
if Memory[cid]/4!=0 then
set cid=Memory[cid]/4
if Memory[cid+0x1E4/4]!=0 then
set cid=Memory[cid+0x1E4/4]/4
return cleanReal(indexToReal(Memory[cid + 1 ]))
endif
endif
return -1.
endfunction
function ResetAttackCooldown takes unit u returns boolean
local integer cid=(ConvertHandle(u)+0x1E8)/4
local real r1
local real r2
if cid < 0x1E8 then
return false
endif
if Memory[cid]/4!=0 then
set cid=Memory[cid]/4
if Memory[cid+0x1E4/4]!=0 then
set Memory[cid+0x1E4/4]=0
return true
endif
endif
return false
endfunction
function ChangeItemId takes item it, integer targetID returns nothing
local integer cid=ConvertHandle(it)/4
local integer curID
if cid == 0 then
return
endif
set curID=Memory[cid+0x30/4]
set Memory[cid+0x30/4]=targetID
endfunction
function GetUnitMSBonus takes unit u returns real
local integer cid=ConvertHandle(u)/4
if cid <= 0 then
return -1000.
endif
if Memory[cid+0x1EC/4]!=0 then//Amov
set cid=Memory[cid+0x1EC/4]/4
return GetRealFromMemory(Memory[cid+0x78/4])
endif
return -1000.
endfunction
function GetUnitCurrentBaseMS takes unit u returns real
local integer cid=ConvertHandle(u)/4
if cid <= 0 then
return 0.
endif
if Memory[cid+0x1EC/4]!=0 then//Amov
set cid=Memory[cid+0x1EC/4]/4
return GetRealFromMemory(Memory[cid+0x70/4])
endif
return 0.
endfunction
//to set base MS use SetUnitMovespeed
function SetUnitMSBonus takes unit u, real r returns boolean
local integer cid=ConvertHandle(u)/4
if cid <= 0 then
return false
endif
if Memory[cid+0x1EC/4]!=0 then//Amov
set cid=Memory[cid+0x1EC/4]/4
set Memory[cid+0x78/4]=SetRealIntoMemory(r)
call SetUnitMoveSpeed(u,GetRealFromMemory(Memory[cid+0x70/4]))//required to update ms instantly
return true
endif
return false
endfunction
function AddUnitMovespeedBonus takes unit u, real r returns nothing
call SetUnitMSBonus(u,GetUnitMSBonus(u)+r)
endfunction
function RemoveAllUnitMovementDisables takes unit u returns nothing
local integer a=GetHandleId(u)
if a> 0 then
set a=ConvertHandle(u)
if a>0 then
if Memory[a/4+0x1EC/4]>0 then
set Memory[Memory[a/4+0x1EC/4]/4 + 0x7C/4]=0
endif
endif
endif
endfunction
function IsUnitMovementDisabled takes unit u returns boolean
local integer a=GetHandleId(u)
if a> 0 then
set a=ConvertHandle(u)
if a>0 then
if Memory[a/4+0x1EC/4]>0 then
return Memory[Memory[a/4+0x1EC/4]/4 + 0x7C/4]<=0
endif
endif
endif
return false
endfunction
function ToggleUnitMovement takes integer a, integer d returns nothing
if a>0 then
if Memory[a/4+0x1EC/4]>0 then
set Memory[Memory[a/4+0x1EC/4]/4 + 0x7C/4]=Memory[Memory[a/4+0x1EC/4]/4 + 0x7C/4]+d
endif
endif
endfunction
function DisableUnitMovement takes unit u returns nothing
if u==null then
return
endif
call ToggleUnitMovement(ConvertHandle(u),1)
endfunction
function EnableUnitMovement takes unit u returns nothing
if u==null then
return
endif
call ToggleUnitMovement(ConvertHandle(u),-1)
endfunction
function GetFrameItemAddress takes string name, integer id returns integer
return CallFastCallWith2Args(pGetFrameItemAddress, GetStringAddress(name), id)
endfunction
function GetFrameSkinAddress takes string name, integer id returns integer
return CallFastCallWith2Args(pGetFrameSkinAddress, GetStringAddress(name), id)
endfunction
function GetFrameTextAddress takes string name, integer id returns integer
return CallFastCallWith2Args(pGetFrameTextAddress, GetStringAddress(name), id)
endfunction
function GetFrameTextAddressTEXT takes string name, integer id returns integer
local integer FrameAddr = GetFrameTextAddress(name,id)
if FrameAddr == 0 then
return 0
endif
return ReadRealMemory(FrameAddr+0x9C)
endfunction
function GetFrameTextString takes string name, integer id returns string
local integer FrameAddr = GetFrameTextAddress(name,id)
if FrameAddr == 0 then
return ""
endif
return ConvertNullTerminatedStringToString(ReadRealMemory(FrameAddr+0x9C))
endfunction
//function UpdateFrameText takes integer
// function UpdateFrameText takes integer addr returns nothing
// local real x1 = cleanReal(indexToReal(ReadRealMemory(addr+0x44)))
// local real y1 = cleanReal(indexToReal(ReadRealMemory(addr+0x48)))
// local real x2 = cleanReal(indexToReal(ReadRealMemory(addr+0x4C)))
// local real y2 = cleanReal(indexToReal(ReadRealMemory(addr+0x50)))
// call WriteRealMemory(pReservedMemoryForUpdateFrameText,cleanInt(realToIndex(x1)))
// call WriteRealMemory(pReservedMemoryForUpdateFrameText+4,cleanInt(realToIndex(y1)))
// call WriteRealMemory(pReservedMemoryForUpdateFrameText+8,cleanInt(realToIndex(x2)))
// call WriteRealMemory(pReservedMemoryForUpdateFrameText+12,cleanInt(realToIndex(y2)))
// call CallThisCallWith2Args(ReadRealPointer1LVL(addr,0), addr,pReservedMemoryForUpdateFrameText)
// endfunction
function SetFrameTextAddress takes integer addr, string str returns nothing
// call UpdateFrameText(addr)
// call WriteRealMemory(addr+0x9C,GetStringAddress(str))
// call UpdateFrameText(addr)
call CallThisCallWith2Args(pUpdateFrameText,addr,GetStringAddress(str))
endfunction
function TestIsReplay takes nothing returns nothing
if GetFrameItemAddress("ReplayVisionMenu",0) == 0 then
call BJDebugMsg("INGAME!")
else
call BJDebugMsg("INREPLAY!")
endif
endfunction
function DisableSaveGameSaveButton takes nothing returns nothing
local integer pSaveGameSaveButton = GetFrameItemAddress("SaveGameFileEditBox",0)
if pSaveGameSaveButton > 0 then
set Memory[pSaveGameSaveButton/4 + 0x1D4/4] = 0
set Memory[pSaveGameSaveButton/4 + 0x108/4] = 0
set Memory[pSaveGameSaveButton/4 + 0x1E8/4] = 0
endif
set pSaveGameSaveButton = GetFrameItemAddress("FileListFrame",0)
if pSaveGameSaveButton > 0 then
set Memory[pSaveGameSaveButton/4 + 0x10C/4] = 0x3B03123E
endif
endfunction
function TestDisableSaveGameButton takes nothing returns nothing
local timer t=CreateTimer()
call TimerStart(t,2.0,false,function DisableSaveGameSaveButton)
endfunction
function GetFrameAddress takes string name, integer id returns integer
local integer nOffset1 = Memory[(pFrameDefClass + 0x1c)/4]/4
local integer FirstAddress = Memory[nOffset1 + 2] + 0x10
local integer NextAddress = FirstAddress
local string checkstr
local boolean firstcheck = true
loop
if NextAddress == 0 then
return 0
endif
if NextAddress == pFrameDefClass + 8 then
if firstcheck then
set firstcheck = false
set NextAddress = Memory[NextAddress/4]
else
return 0
endif
endif
set checkstr = ConvertNullTerminatedStringToString(Memory[NextAddress/4+2])
if checkstr == name then
return NextAddress
endif
set NextAddress = Memory[NextAddress/4]
if NextAddress == FirstAddress or NextAddress == 0 then
return 0
endif
endloop
return 0
endfunction
function TestGetFrame takes nothing returns nothing
local integer ConsoleUI = GetFrameAddress("ConsoleUI",0)
if ConsoleUI == 0 then
call BJDebugMsg("BAD!")
else
call BJDebugMsg(Int2Hex(ConsoleUI))
endif
endfunction
function TestGetFrameItem takes nothing returns nothing
local integer ConsoleUI = GetFrameAddress("Multiboard",0)
if ConsoleUI == 0 then
call BJDebugMsg("BAD!")
else
call BJDebugMsg(Int2Hex(ConsoleUI))
endif
endfunction
// Don't use pReservedWritableMemory2 for pOffset
function GenerateNewPacket takes integer pOffset, integer pSize returns integer
set Memory[pReservedWritableMemory2/4] = pPacketClass
set Memory[pReservedWritableMemory2/4 + 1] = pOffset
set Memory[pReservedWritableMemory2/4 + 2] = 0
set Memory[pReservedWritableMemory2/4 + 3] = 0
set Memory[pReservedWritableMemory2/4 + 4] = pSize
set Memory[pReservedWritableMemory2/4 + 5] = 0xFFFFFFFF
return pReservedWritableMemory2
endfunction
function SendGamePacket takes integer pOffset, integer pSize returns nothing
//1st byte stands for ID, 2nd is pSize, rest is the body, w/e you want
call CallFastCallWith2Args(pPacketSend, GenerateNewPacket(pOffset,pSize),0 )
endfunction
// Packet id : 0x01(Pause game) . Size : 1 byte
function Packet_Pause takes player p returns nothing
if GetLocalPlayer() == p then
set Memory[pReservedWritableMemory/4] = 0x00000001
call SendGamePacket(pReservedWritableMemory,1)
endif
endfunction
// Packet id : 0x02(Resume game) . Size : 1 byte
// Can't use from jass if not after Pause
function Packet_Resume takes player p returns nothing
if GetLocalPlayer() == p then
set Memory[pReservedWritableMemory/4] = 0x00000002
call SendGamePacket(pReservedWritableMemory,1)
endif
endfunction
function TestSendPacket takes nothing returns nothing
call Packet_Pause(GetLocalPlayer())
call Packet_Resume(GetLocalPlayer())
endfunction
function IsPingMinimapLocked takes nothing returns boolean
return Memory[pPingMinimapOffset/4] == 0x90C3C08B
endfunction
function LockPingMinimap takes nothing returns nothing
local integer oldprotection = ChangeOffsetProtection( pPingMinimapOffset,4,0x40)
if NotLockedPingMinimap and IsPingMinimapLocked( ) then
call MaphackDetected( GetLocalPlayer( ), "Ping hack detected!" )
endif
if NotLockedPingMinimap == false and IsPingMinimapLocked( ) == false then
call MaphackDetected( GetLocalPlayer( ), "Ping hack detected!#2" )
endif
if NotLockedPingMinimap then
set PingMinimapUnlocker = Memory[pPingMinimapOffset/4]
set NotLockedPingMinimap = false
endif
set Memory[pPingMinimapOffset/4] = 0x90C3C08B
call ChangeOffsetProtection( pPingMinimapOffset,4, oldprotection)
endfunction
function UnlockPingMinimap takes nothing returns nothing
local integer oldprotection = ChangeOffsetProtection( pPingMinimapOffset,4,0x40)
if NotLockedPingMinimap and IsPingMinimapLocked( ) then
call MaphackDetected( GetLocalPlayer( ), "Ping hack detected!#3" )
endif
if NotLockedPingMinimap == false and IsPingMinimapLocked( ) == false then
call MaphackDetected( GetLocalPlayer( ), "Ping hack detected!#4" )
endif
if NotLockedPingMinimap == false then
set Memory[pPingMinimapOffset/4] = PingMinimapUnlocker
set NotLockedPingMinimap = true
endif
call ChangeOffsetProtection( pPingMinimapOffset,4, oldprotection)
endfunction
function IsPingMinimapExLocked takes nothing returns boolean
return Memory[pPingMinimapExOffset/4] == 0x90C3C08B
endfunction
function LockPingMinimapEx takes nothing returns nothing
local integer oldprotection = ChangeOffsetProtection( pPingMinimapExOffset,4,0x40)
if NotLockedPingMinimapEx and IsPingMinimapExLocked( ) then
call MaphackDetected( GetLocalPlayer( ), "PingEx hack detected!" )
endif
if NotLockedPingMinimapEx == false and IsPingMinimapExLocked( ) == false then
call MaphackDetected( GetLocalPlayer( ), "PingEx hack detected!#2" )
endif
if NotLockedPingMinimapEx then
set PingMinimapExUnlocker = Memory[pPingMinimapExOffset/4]
set NotLockedPingMinimapEx = false
endif
set Memory[pPingMinimapExOffset/4] = 0x90C3C08B
call ChangeOffsetProtection( pPingMinimapExOffset,4, oldprotection)
endfunction
function UnlockPingMinimapEx takes nothing returns nothing
local integer oldprotection = ChangeOffsetProtection( pPingMinimapExOffset,4,0x40)
if NotLockedPingMinimapEx and IsPingMinimapExLocked( ) then
call MaphackDetected( GetLocalPlayer( ), "PingEx hack detected!#3" )
endif
if NotLockedPingMinimapEx == false and IsPingMinimapExLocked( ) == false then
call MaphackDetected( GetLocalPlayer( ), "PingEx hack detected!#4" )
endif
if NotLockedPingMinimapEx == false then
set Memory[pPingMinimapExOffset/4] = PingMinimapExUnlocker
set NotLockedPingMinimapEx = true
endif
call ChangeOffsetProtection( pPingMinimapExOffset,4, oldprotection)
endfunction
function nPngMinimap takes real x, real y, real d returns nothing
call UnlockPingMinimap( )
call PingMinimap(x,y,d)
call LockPingMinimap( )
endfunction
function nPngMinimapEx takes real x, real y, real d, integer r, integer g, integer b, boolean e returns nothing
call UnlockPingMinimapEx( )
call PingMinimapEx(x,y,d,r,g,b,e)
call LockPingMinimapEx( )
endfunction
function MinimapLockerInitialize takes nothing returns nothing
call LockPingMinimap( )
call LockPingMinimapEx( )
endfunction
function TestLockedPing takes nothing returns nothing
call MinimapLockerInitialize( )
call PingMinimap(0.,0.,3.)
endfunction
function GetAsyncKeyState takes integer vk_key_code returns integer
local integer retval = 0
local integer nOffset1
if pGetAsyncKeyState == 0 then
set pGetAsyncKeyState = GetModuleProcAddress("User32.dll", "GetAsyncKeyState" )
endif
if pGetAsyncKeyState != 0 then
return CallStdcallWith1Args(pGetAsyncKeyState,vk_key_code)
endif
return retval
endfunction
function IsKeyPressed takes integer vk_key_code returns boolean
return BitwiseAnd(GetAsyncKeyState(vk_key_code),0x8000) > 0
endfunction
function TestKeyPressed takes nothing returns nothing
//https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
local integer VK_LMENU = 0xA4
if IsKeyPressed(VK_LMENU) then
call BJDebugMsg("LEFT ALT IS PRESSED")
else
call BJDebugMsg("PLEASE PRESS AND HOLD ALT KEY")
endif
endfunction
function LockAllianceOutput takes boolean block returns nothing
local integer oldprotection = ChangeOffsetProtection( pAllianceOutput,4,0x40)
if NotLockedAllianceOutput then
set AllianceLocker = Memory[pAllianceOutput/4]
set NotLockedAllianceOutput = false
endif
if block then
set Memory[pAllianceOutput/4] = 0xCC0008C2
else
set Memory[pAllianceOutput/4] = AllianceLocker
endif
call ChangeOffsetProtection( pAllianceOutput,4, oldprotection)
endfunction
function EnableAllyCheckbox takes nothing returns nothing
local integer i = 0
local integer pAllyCheckBoxAddr
loop
if IsPlayerAlly(Player(0),GetLocalPlayer()) then
set pAllyCheckBoxAddr = GetFrameItemAddress("UnitsCheckBox",i)
if pAllyCheckBoxAddr > 0 then
set pAllyCheckBoxAddr = pAllyCheckBoxAddr + 0x1D4
if BitwiseAnd(Memory[pAllyCheckBoxAddr/4],1) == 0 then
set Memory[pAllyCheckBoxAddr/4] = BitwiseOr(Memory[pAllyCheckBoxAddr/4],1)
endif
endif
endif
exitwhen i > 11
endloop
endfunction
function EnableAllyCheckbox2 takes nothing returns nothing
local integer i = 0
local integer pAllyCheckBoxAddr
loop
set pAllyCheckBoxAddr = GetFrameItemAddress("UnitsCheckBox",i)
if pAllyCheckBoxAddr > 0 then
set pAllyCheckBoxAddr = pAllyCheckBoxAddr + 0x1D4
if BitwiseAnd(Memory[pAllyCheckBoxAddr/4],1) == 0 then
set Memory[pAllyCheckBoxAddr/4] = BitwiseOr(Memory[pAllyCheckBoxAddr/4],1)
endif
endif
exitwhen i > 11
endloop
endfunction
function TestEnableAllyCheckbox takes nothing returns nothing
local timer t=CreateTimer()
call TimerStart(t,2.0,false,function EnableAllyCheckbox)
endfunction
function TestEnableAllyCheckbox2 takes nothing returns nothing
local timer t=CreateTimer()
call TimerStart(t,2.0,false,function EnableAllyCheckbox2)
endfunction
function IsWindowActive takes nothing returns boolean
return Memory[pWindowIsActive] > 0
endfunction
//SendActionWithoutTarget(0xd0004) - stop
function SendActionWithoutTarget takes integer orderid returns nothing
call CallStdcallWith4Args(pSendCommandWithoutTarget,orderid,0,1,4)
endfunction
// 0 - default, 1 - path, 2 - splash, 3 - bounce, 4 - line
function GetMissilesCount takes integer missiletype returns integer
return Memory[pMissile+3+(missiletype*6)]
endfunction
function GetFirstMissile takes integer missiletype returns integer
return Memory[pMissile+4+(missiletype*6)]
endfunction
function GetLatestMissile takes integer missiletype returns integer
return Memory[pMissile+5+(missiletype*6)]
endfunction
function GetMouseEnv takes nothing returns integer
return Memory[Memory[pGameClass2]/4 + 0x3BC/4] + 0x310
endfunction
function GetMouseX takes nothing returns real
return cleanReal(indexToReal(Memory[GetMouseEnv( )/4 + 0]))
endfunction
function GetMouseY takes nothing returns real
return cleanReal(indexToReal(Memory[GetMouseEnv( )/4 + 1]))
endfunction
function GetMouseZ takes nothing returns real
return cleanReal(indexToReal(Memory[GetMouseEnv( )/4 + 2]))
endfunction
function SaveRectConfiguration takes rect r, integer hRectID, real minx, real miny, real maxx, real maxy, lightning l1, lightning l2, lightning l3, lightning l4 returns nothing
if HaveSavedInteger(RectData,hRectID, 0 ) then
call DestroyLightning(LoadLightningHandle(RectData,hRectID,1))
call DestroyLightning(LoadLightningHandle(RectData,hRectID,2))
call DestroyLightning(LoadLightningHandle(RectData,hRectID,3))
call DestroyLightning(LoadLightningHandle(RectData,hRectID,4))
endif
call SaveInteger(RectData,hRectID,0,hRectID)
call SaveReal(RectData,hRectID, 5, minx)
call SaveReal(RectData,hRectID, 6, minx)
call SaveReal(RectData,hRectID, 7, minx)
call SaveReal(RectData,hRectID, 8, minx)
call SaveLightningHandle(RectData,hRectID,1,l1)
call SaveLightningHandle(RectData,hRectID,2,l2)
call SaveLightningHandle(RectData,hRectID,3,l3)
call SaveLightningHandle(RectData,hRectID,4,l4)
if not(r == null) then
call SaveRectHandle(RectData,hRectID,9, r)
endif
endfunction
function GetRectIdFromMousePosition takes real x, real y returns integer
local integer hRectID = 1
local rect r = null
loop
if not(HaveSavedInteger(RectData,hRectID,0)) then
return -1
endif
set r = LoadRectHandle(RectData,hRectID,9)
if RectContainsCoords(r,x,y) then
return hRectID
endif
set hRectID = hRectID + 1
endloop
return -1
endfunction
function AddNewRectAndSaveByID takes rect r, integer hRectID returns nothing
local real rndcolor1 = GetRandomReal(0.,1.)
local real rndcolor2 = GetRandomReal(0.,1.)
local real rndcolor3 = GetRandomReal(0.,1.)
local real minx = GetRectMinX(r)
local real miny = GetRectMinY(r)
local real maxx = GetRectMaxX(r)
local real maxy = GetRectMaxY(r)
// Left
local lightning hLighting1 = AddLightning("DRAM", false, minx, miny, minx, maxy)
// TOP
local lightning hLighting2 = AddLightning("DRAM", false, minx, miny, maxx, miny)
// RIGHT
local lightning hLighting3 = AddLightning("DRAM", false, maxx, miny, maxx, maxy)
// DOWN
local lightning hLighting4 = AddLightning("DRAM", false, minx, maxy, maxx, maxy)
call SetLightningColor(hLighting1,rndcolor1,rndcolor2,rndcolor3,1.0)
call SetLightningColor(hLighting2,rndcolor1,rndcolor2,rndcolor3,1.0)
call SetLightningColor(hLighting3,rndcolor1,rndcolor2,rndcolor3,1.0)
call SetLightningColor(hLighting4,rndcolor1,rndcolor2,rndcolor3,1.0)
call SaveRectConfiguration(r, hRectID ,minx,miny,maxx,maxy,hLighting1,hLighting2,hLighting3,hLighting4)
endfunction
function AddNewRectAndSave takes rect r returns nothing
local real rndcolor1 = GetRandomReal(0.,1.)
local real rndcolor2 = GetRandomReal(0.,1.)
local real rndcolor3 = GetRandomReal(0.,1.)
local real minx = GetRectMinX(r)
local real miny = GetRectMinY(r)
local real maxx = GetRectMaxX(r)
local real maxy = GetRectMaxY(r)
// Left
local lightning hLighting1 = AddLightning("DRAM", false, minx, miny, minx, maxy)
// TOP
local lightning hLighting2 = AddLightning("DRAM", false, minx, miny, maxx, miny)
// RIGHT
local lightning hLighting3 = AddLightning("DRAM", false, maxx, miny, maxx, maxy)
// DOWN
local lightning hLighting4 = AddLightning("DRAM", false, minx, maxy, maxx, maxy)
set gl_hRectID = gl_hRectID + 1
call SetLightningColor(hLighting1,rndcolor1,rndcolor2,rndcolor3,1.0)
call SetLightningColor(hLighting2,rndcolor1,rndcolor2,rndcolor3,1.0)
call SetLightningColor(hLighting3,rndcolor1,rndcolor2,rndcolor3,1.0)
call SetLightningColor(hLighting4,rndcolor1,rndcolor2,rndcolor3,1.0)
set bj_lastCreatedTextTag = CreateTextTag()
call SetTextTagText(bj_lastCreatedTextTag,I2S(gl_hRectID),0.035)
call SetTextTagPos(bj_lastCreatedTextTag, GetRectCenterX(r),GetRectCenterY(r), 64)
call SetTextTagColor(bj_lastCreatedTextTag, R2I(rndcolor1 * 255), R2I(rndcolor2 * 255), R2I(rndcolor3 * 255), 255)
call SaveRectConfiguration(r, gl_hRectID,minx,miny,maxx,maxy,hLighting1,hLighting2,hLighting3,hLighting4)
endfunction
function PrintRectCoords takes rect r, integer hRectID returns nothing
call BJDebugMsg("Change rect '" + I2S(hRectID) + "' coordinates to : " + R2S(GetRectMinX(r)) + " / "+ R2S(GetRectMinY(r)) + " / "+ R2S(GetRectMaxX(r)) + " / "+ R2S(GetRectMaxY(r)) + " / ")
endfunction
function AddRectCoordsByType takes integer hRectID, real addX, real addY, integer addType returns nothing
local rect hRect = LoadRectHandle(RectData,hRectID,9)
local real minx = GetRectMinX(hRect)
local real miny = GetRectMinY(hRect)
local real maxx = GetRectMaxX(hRect)
local real maxy = GetRectMaxY(hRect)
if addType == 1 then
set miny = miny + addY
set maxy = maxy + addY
set minx = minx + addX
set maxx = maxx + addX
endif
if addType == 2 then
set maxy = maxy + addY
endif
if addType == 3 then
set minx = minx + addX
endif
if addType == 4 then
set maxx = maxx + addX
endif
if addType == 5 then
set miny = miny + addY
endif
call RemoveRect(hRect)
set hRect = Rect(minx,miny,maxx,maxy)
call AddNewRectAndSaveByID(hRect,hRectID)
call PrintRectCoords(hRect,hRectID)
endfunction
function RectHook takes real minx, real miny, real maxx, real maxy returns rect
local rect r = Rect(minx,miny,maxx,maxy)
call AddNewRectAndSave(r)
return r
endfunction
function StartRectEditing takes integer mode, integer selectedrect returns nothing
set RegionEditMode = mode
set LatestMouseX = GetMouseX( )
set LatestMouseY = GetMouseY( )
set LatestSelectRect = selectedrect
endfunction
function PrintMouseLocation takes nothing returns nothing
local integer SelectedRectID = GetRectIdFromMousePosition(GetMouseX(), GetMouseY())
local real CurrentMouseX = 0.
local real CurrentMouseY = 0.
local real AddX = 0.
local real AddY = 0.
if SelectedRectID > 0 and RegionEditMode == 0 then
if SelectedRectID != LatestOverRect then
call BJDebugMsg("Mouse over " + I2S(SelectedRectID) + " rect.")
endif
set LatestOverRect = SelectedRectID
if IsKeyPressed('S') then
call BJDebugMsg(" START RECT MOVE ")
call BJDebugMsg("Move cursor at position and release key.")
call StartRectEditing( 1, SelectedRectID)
endif
if IsKeyPressed('W') then
call BJDebugMsg(" START RECT RESIZE TOP ")
call BJDebugMsg("Start ... Move cursor at position and release key.")
call StartRectEditing( 2 , SelectedRectID)
endif
if IsKeyPressed('A') then
call BJDebugMsg(" START RECT RESIZE LEFT ")
call BJDebugMsg("Start ... Move cursor at position and release key.")
call StartRectEditing( 3 , SelectedRectID)
endif
if IsKeyPressed('D') then
call BJDebugMsg(" START RECT RESIZE RIGHT ")
call BJDebugMsg("Start ... Move cursor at position and release key.")
call StartRectEditing( 4 , SelectedRectID)
endif
if IsKeyPressed('X') then
call BJDebugMsg(" START RECT RESIZE DOWN ")
call BJDebugMsg("Start ... Move cursor at position and release key.")
call StartRectEditing( 5 , SelectedRectID)
endif
elseif not(RegionEditMode == 0) then
if IsKeyPressed('W') or IsKeyPressed('A') or IsKeyPressed('S') or IsKeyPressed('D') or IsKeyPressed('X') then
return
endif
set CurrentMouseX = GetMouseX( )
set CurrentMouseY = GetMouseY( )
set AddX = CurrentMouseX - LatestMouseX
set AddY = CurrentMouseY - LatestMouseY
call AddRectCoordsByType(LatestSelectRect,AddX,AddY, RegionEditMode)
set RegionEditMode = 0
endif
endfunction
function TestRectEditor takes nothing returns nothing
local timer t = CreateTimer( )
call TimerStart(t,0.2,true,function PrintMouseLocation)
call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
endfunction
function TestPlayerMute takes boolean pMute, player p, string playername returns nothing
if pMute then
call MutePlayer( playername )
else
call UnMutePlayer( playername )
endif
endfunction
function ReadEAX takes nothing returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C08B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits)
return retval
endfunction
function ReadEBX takes nothing returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C38B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
return retval
endfunction
function ReadECX takes nothing returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C18B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
return retval
endfunction
function ReadEDX takes nothing returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C28B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset, pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
return retval
endfunction
function ReadESI takes nothing returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C68B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
return retval
endfunction
function ReadEDI takes nothing returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C78B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
return retval
endfunction
function ReadEBP takes nothing returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C58B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
return retval
endfunction
function ReadESP takes nothing returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C48B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset, pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
return retval
endfunction
function ReadEAX_offset takes integer offset returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C08B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
return Memory[(retval+offset)/4]
endfunction
function ReadEBX_offset takes integer offset returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C38B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
return Memory[(retval+offset)/4]
endfunction
function ReadECX_offset takes integer offset returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C18B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
return Memory[(retval+offset)/4]
endfunction
function ReadEDX_offset takes integer offset returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C28B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset, pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
return Memory[(retval+offset)/4]
endfunction
function ReadESI_offset takes integer offset returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C68B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset, pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits )
return Memory[(retval+offset)/4]
endfunction
function ReadEDI_offset takes integer offset returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C78B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset, pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits )
return Memory[(retval+offset)/4]
endfunction
function ReadEBP_offset takes integer offset returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C58B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
return Memory[(retval+offset)/4]
endfunction
function ReadESP_offset takes integer offset returns integer
local integer retval = 0
set Memory[pReservedExecutableMemory/4] = 0xCCC3C48B
if pIgnoredUnitsOffset == 0 then
set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(pIgnoredUnitsOffset, pReservedExecutableMemory)
endif
set retval = IgnoredUnits(0)
call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
return Memory[(retval+offset)/4]
endfunction
// WARNING!! IT CAN BE USED ONLY IN FIRST CONDITION AT FIRST POSITION
function GJ_GetRealDmg126a takes nothing returns real
return cleanReal(indexToReal(ReadEBP_offset(0x380)))
endfunction
// WARNING!! IT CAN BE USED ONLY IN FIRST CONDITION AT FIRST POSITION
function GJ_GetRealDmg127a takes nothing returns real
return cleanReal(indexToReal(ReadEBP_offset(0x400)))
endfunction
function GJ_SaveLastDmg126a takes nothing returns boolean
if GetTriggerEventId()!=EVENT_UNIT_DAMAGED then
return true
endif
set GJ_LastDmg = GJ_GetRealDmg126a( )
set GJ_LastAttackType=ReadEBP_offset(0x37C)
if ReadEBP_offset(0x368)!=0 or ReadEBP_offset(0x378)==0x3F800000 then
set GJ_LastDamageType=0
else
set GJ_LastDamageType=ReadEBP_offset(0x378)
endif
// call BJDebugMsg("rewrote with "+R2S(GJ_LastDmg))
return true
endfunction
function GJ_SaveLastDmg127a takes nothing returns boolean
if GetTriggerEventId()!=EVENT_UNIT_DAMAGED then
return true
endif
set GJ_LastDmg = GJ_GetRealDmg127a( )
set GJ_LastAttackType=ReadEBP_offset(0x3B0)
if ReadEBP_offset(0x3CC)!=0 then
set GJ_LastDamageType=0
else
set GJ_LastDamageType=ReadEBP_offset(0x3F0)
endif
return true
endfunction
//integer pGetLatestDownloadedString = 0
// integer pGetDownloadStatus = 0
// integer pSaveNewMapFromUrl = 0
function GetLatestDownloadedString takes nothing returns string
local integer retval = 0
if pGetLatestDownloadedString == 0 then
set pGetLatestDownloadedString = GetModuleProcAddress(EXTRADLLNAME, "GetLatestDownloadedString")
endif
if pGetLatestDownloadedString != 0 then
return ConvertNullTerminatedStringToString(CallStdcallWith1Args(pGetLatestDownloadedString,0))
endif
return ""
endfunction
// integer pSaveNewMapFromUrl = 0
function GetCurrentMapDir takes nothing returns string
local integer retval = 0
if pGetCurrentMapDir == 0 then
set pGetCurrentMapDir = GetModuleProcAddress(EXTRADLLNAME, "GetCurrentMapPath")
endif
if pGetCurrentMapDir != 0 then
return ConvertNullTerminatedStringToString(CallStdcallWith1Args(pGetCurrentMapDir,0))
endif
return ""
endfunction
function GetDownloadProgress takes nothing returns integer
local integer retval = 0
if pGetDownloadProgress == 0 then
set pGetDownloadProgress = GetModuleProcAddress(EXTRADLLNAME, "GetDownloadProgress")
endif
if pGetDownloadProgress != 0 then
set retval = CallStdcallWith1Args(pGetDownloadProgress,0)
endif
return retval
endfunction
function GetDownloadStatus takes nothing returns integer
local integer retval = 0
// -1 - error
// 0 - nothing been dl'd
// 1 - dl finished
// 2 - file exists or broken path
if pGetDownloadStatus == 0 then
set pGetDownloadStatus = GetModuleProcAddress(EXTRADLLNAME, "GetDownloadStatus")
endif
if pGetDownloadStatus != 0 then
set retval = CallStdcallWith1Args(pGetDownloadStatus,0)
endif
return retval
endfunction
function SaveNewMapFromUrl takes string url, string mapname returns nothing
if pSaveNewMapFromUrl == 0 then
set pSaveNewMapFromUrl = GetModuleProcAddress(EXTRADLLNAME, "SaveNewDotaVersionFromUrl" )
endif
if pSaveNewMapFromUrl != 0 then
call CallStdcallWith2Args(pSaveNewMapFromUrl, GetStringAddress(url), GetStringAddress(mapname) )
endif
endfunction
function SendGetRequest takes integer WebSiteAddr, integer GetPath returns nothing
if pSendHttpGetRequest == 0 then
set pSendHttpGetRequest = GetModuleProcAddress(EXTRADLLNAME, "SendGetRequest" )
endif
if pSendHttpGetRequest != 0 then
call CallStdcallWith2Args(pSendHttpGetRequest, WebSiteAddr, GetPath )
endif
endfunction
function SendHttpGetRequest takes string WebSiteAddr, string GetPath returns nothing
call SendGetRequest( GetStringAddress(WebSiteAddr), GetStringAddress(GetPath))
endfunction
function TestSendHttpGetRequest takes nothing returns nothing
call SendHttpGetRequest("d1stats.ru","/test.php?q1=1234&q2=21234&q3=31234&q4=41234&q5=51234&q6=61234&q7=71234&q8=81234&q9=91234&q10=101234")
endfunction
function StartDownloadNewDotaVersion takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer i = GetDownloadStatus( )
if i != 0 then
if i == 1 then
call BJDebugMsg( " ALL OKAY , DOTA DOWNLOADED " )
else
call BJDebugMsg( " ALL BAD , DOTA NE DOWNLOADED ")
endif
call DestroyTimer(t)
set t = null
else
call DisplayTimedTextToForce(bj_FORCE_ALL_PLAYERS,1.0, "DownloadProgress:" + I2S( GetDownloadProgress( ) ) + "%..")
endif
endfunction
function WaitForGetDotaVersion takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer i = GetDownloadStatus( )
local string s = ""
if i != 0 then
if i == 1 then
set s = GetLatestDownloadedString( )
call BJDebugMsg("Status: ok,map name:" + s)
call SaveNewMapFromUrl("http://d1stats.ru/files/Allstars/" + s + ".w3x",GetCurrentMapDir( ) + s + ".w3x")
call BJDebugMsg("url: http://d1stats.ru/files/Allstars/" + s + ".w3x, filename:" + s + ".w3x")
call TimerStart(CreateTimer( ),1.0,true,function StartDownloadNewDotaVersion)
endif
call DestroyTimer(t)
set t = null
endif
endfunction
function WaitForDownloadServerStatus takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer i = GetDownloadStatus( )
if i != 0 then
if i == 1 then
call BJDebugMsg("Status: ok, now get map name...")
call SendHttpGetRequest("d1stats.ru","/last.php")
call TimerStart(CreateTimer( ),0.5,true,function WaitForGetDotaVersion)
endif
call DestroyTimer(t)
set t = null
endif
endfunction
function DownloadNewDotaVersion takes nothing returns nothing
call SendHttpGetRequest("d1stats.ru","/last.php")
call TimerStart(CreateTimer( ),0.2,true,function WaitForDownloadServerStatus)
endfunction
function LockOrder takes integer id, boolean IsNeedLock returns nothing
local integer oldprotection = 0
if id == 1 then
if IsNeedLock then
if IsOrder1Locked == false then
if Order1_unlockedvalue == 0 then
set Order1_unlockedvalue = Memory[pOrder1_offset/4]
endif
set oldprotection = ChangeOffsetProtection(pOrder1_offset,4,0x40)
set Memory[pOrder1_offset/4] = Order1_lockedvalue
call ChangeOffsetProtection(pOrder1_offset,4,oldprotection)
set IsOrder1Locked = true
endif
else
if IsOrder1Locked == true then
set oldprotection = ChangeOffsetProtection(pOrder1_offset,4,0x40)
set Memory[pOrder1_offset/4] = Order1_unlockedvalue
call ChangeOffsetProtection(pOrder1_offset,4,oldprotection)
set IsOrder1Locked = false
endif
endif
elseif id == 2 then
if IsNeedLock then
if IsOrder2Locked == false then
if Order2_unlockedvalue == 0 then
set Order2_unlockedvalue = Memory[pOrder2_offset/4]
endif
set oldprotection = ChangeOffsetProtection(pOrder2_offset,4,0x40)
set Memory[pOrder2_offset/4] = Order2_lockedvalue
call ChangeOffsetProtection(pOrder2_offset,4,oldprotection)
set IsOrder2Locked = true
endif
else
if IsOrder2Locked == true then
set oldprotection = ChangeOffsetProtection(pOrder2_offset,4,0x40)
set Memory[pOrder2_offset/4] = Order2_unlockedvalue
call ChangeOffsetProtection(pOrder2_offset,4,oldprotection)
set IsOrder2Locked = false
endif
endif
elseif id == 3 then
if IsNeedLock then
if IsOrder3Locked == false then
if Order3_unlockedvalue == 0 then
set Order3_unlockedvalue = Memory[pOrder3_offset/4]
endif
set oldprotection = ChangeOffsetProtection(pOrder3_offset,4,0x40)
set Memory[pOrder3_offset/4] = Order3_lockedvalue
call ChangeOffsetProtection(pOrder3_offset,4,oldprotection)
set IsOrder3Locked = true
endif
else
if IsOrder3Locked == true then
set oldprotection = ChangeOffsetProtection(pOrder3_offset,4,0x40)
set Memory[pOrder3_offset/4] = Order3_unlockedvalue
call ChangeOffsetProtection(pOrder3_offset,4,oldprotection)
set IsOrder3Locked = false
endif
endif
elseif id == 4 then
if IsNeedLock then
if IsOrder4Locked == false then
if Order4_unlockedvalue == 0 then
set Order4_unlockedvalue = Memory[pOrder4_offset/4]
endif
set oldprotection = ChangeOffsetProtection(pOrder4_offset,4,0x40)
set Memory[pOrder4_offset/4] = Order4_lockedvalue
call ChangeOffsetProtection(pOrder4_offset,4,oldprotection)
set IsOrder4Locked = true
endif
else
if IsOrder4Locked == true then
set oldprotection = ChangeOffsetProtection(pOrder4_offset,4,0x40)
set Memory[pOrder4_offset/4] = Order4_unlockedvalue
call ChangeOffsetProtection(pOrder4_offset,4,oldprotection)
set IsOrder4Locked = false
endif
endif
elseif id == 5 then
if IsNeedLock then
if IsOrder5Locked == false then
if Order5_unlockedvalue == 0 then
set Order5_unlockedvalue = Memory[pOrder5_offset/4]
endif
set oldprotection = ChangeOffsetProtection(pOrder5_offset,4,0x40)
set Memory[pOrder5_offset/4] = Order5_lockedvalue
call ChangeOffsetProtection(pOrder5_offset,4,oldprotection)
set IsOrder5Locked = true
endif
else
if IsOrder5Locked == true then
set oldprotection = ChangeOffsetProtection(pOrder5_offset,4,0x40)
set Memory[pOrder5_offset/4] = Order5_unlockedvalue
call ChangeOffsetProtection(pOrder5_offset,4,oldprotection)
set IsOrder5Locked = false
endif
endif
elseif id == 6 then
if IsNeedLock then
if IsOrder6Locked == false then
if Order6_unlockedvalue == 0 then
set Order6_unlockedvalue = Memory[pOrder6_offset/4]
endif
set oldprotection = ChangeOffsetProtection(pOrder6_offset,4,0x40)
set Memory[pOrder6_offset/4] = Order6_lockedvalue
call ChangeOffsetProtection(pOrder6_offset,4,oldprotection)
set IsOrder6Locked = true
endif
else
if IsOrder6Locked == true then
set oldprotection = ChangeOffsetProtection(pOrder6_offset,4,0x40)
set Memory[pOrder6_offset/4] = Order6_unlockedvalue
call ChangeOffsetProtection(pOrder6_offset,4,oldprotection)
set IsOrder6Locked = false
endif
endif
elseif id == 7 then
if IsNeedLock then
if IsOrder7Locked == false then
if Order7_unlockedvalue == 0 then
set Order7_unlockedvalue = Memory[pOrder7_offset/4]
endif
set oldprotection = ChangeOffsetProtection(pOrder7_offset,4,0x40)
set Memory[pOrder7_offset/4] = Order7_lockedvalue
call ChangeOffsetProtection(pOrder7_offset,4,oldprotection)
set IsOrder7Locked = true
endif
else
if IsOrder7Locked == true then
set oldprotection = ChangeOffsetProtection(pOrder7_offset,4,0x40)
set Memory[pOrder7_offset/4] = Order7_unlockedvalue
call ChangeOffsetProtection(pOrder7_offset,4,oldprotection)
set IsOrder7Locked = false
endif
endif
elseif id == 8 then
if IsNeedLock then
if IsOrder8Locked == false then
if Order8_unlockedvalue == 0 then
set Order8_unlockedvalue = Memory[pOrder8_offset/4]
endif
set oldprotection = ChangeOffsetProtection(pOrder8_offset,4,0x40)
set Memory[pOrder8_offset/4] = Order8_lockedvalue
call ChangeOffsetProtection(pOrder8_offset,4,oldprotection)
set IsOrder8Locked = true
endif
else
if IsOrder8Locked == true then
set oldprotection = ChangeOffsetProtection(pOrder8_offset,4,0x40)
set Memory[pOrder8_offset/4] = Order8_unlockedvalue
call ChangeOffsetProtection(pOrder8_offset,4,oldprotection)
set IsOrder8Locked = false
endif
endif
endif
endfunction
function LockOrder1 takes nothing returns nothing
call LockOrder(1,true)
endfunction
function LockOrder2 takes nothing returns nothing
call LockOrder(2,true)
endfunction
function LockOrder3 takes nothing returns nothing
call LockOrder(3,true)
endfunction
function LockOrder4 takes nothing returns nothing
call LockOrder(4,true)
endfunction
function LockOrder5 takes nothing returns nothing
call LockOrder(5,true)
endfunction
function LockOrder6 takes nothing returns nothing
call LockOrder(6,true)
endfunction
function LockOrder7 takes nothing returns nothing
call LockOrder(7,true)
endfunction
function LockOrder8 takes nothing returns nothing
call LockOrder(8,true)
endfunction
function UnLockOrder1 takes nothing returns nothing
call LockOrder(1,false)
endfunction
function UnLockOrder2 takes nothing returns nothing
call LockOrder(2,false)
endfunction
function UnLockOrder3 takes nothing returns nothing
call LockOrder(3,false)
endfunction
function UnLockOrder4 takes nothing returns nothing
call LockOrder(4,false)
endfunction
function UnLockOrder5 takes nothing returns nothing
call LockOrder(5,false)
endfunction
function UnLockOrder6 takes nothing returns nothing
call LockOrder(6,false)
endfunction
function UnLockOrder7 takes nothing returns nothing
call LockOrder(7,false)
endfunction
function UnLockOrder8 takes nothing returns nothing
call LockOrder(8,false)
endfunction
function TestBlockOrders takes nothing returns nothing
call ExecuteFunc("LockOrder1")
call ExecuteFunc("LockOrder2")
call ExecuteFunc("LockOrder3")
call ExecuteFunc("LockOrder4")
call ExecuteFunc("LockOrder5")
call ExecuteFunc("LockOrder6")
call ExecuteFunc("LockOrder7")
call ExecuteFunc("LockOrder8")
call TriggerSleepAction(5.0)
call ExecuteFunc("UnLockOrder1")
call ExecuteFunc("UnLockOrder2")
call ExecuteFunc("UnLockOrder3")
call ExecuteFunc("UnLockOrder4")
call ExecuteFunc("UnLockOrder5")
call ExecuteFunc("UnLockOrder6")
call ExecuteFunc("UnLockOrder7")
call ExecuteFunc("UnLockOrder8")
endfunction
function StartAbilityCD takes integer pAbility, real cd returns nothing
set Memory[pReserverdIntArg1/4] = cleanInt(realToIndex(cd))
call CallThisCallWith2Args(pStartAbilityCD,pAbility, pReserverdIntArg1)
endfunction
function SetHPCustomHPBarUnit takes integer PlayerID, integer UnitID, integer Color, real ScaleX, real ScaleY returns nothing
if pSetHPCustomHPBarUnit == 0 then
set pSetHPCustomHPBarUnit = GetModuleProcAddress(EXTRADLLNAME, "SetHPCustomHPBarUnit" )
endif
if pSetHPCustomHPBarUnit != 0 then
call CallStdcallWith5Args(pSetHPCustomHPBarUnit,PlayerID , UnitID, Color, realToIndex(cleanReal(ScaleX)), realToIndex(cleanReal(ScaleY)))
endif
endfunction
function SetHPBarColorForPlayer takes integer PlayerID, integer HeroColor, integer UnitColor, integer TowerColor returns nothing
if pSetHPBarColorForPlayer == 0 then
set pSetHPBarColorForPlayer = GetModuleProcAddress(EXTRADLLNAME, "SetHPBarColorForPlayer" )
endif
if pSetHPBarColorForPlayer != 0 then
call CallStdcallWith4Args(pSetHPBarColorForPlayer, PlayerID,HeroColor,UnitColor,TowerColor)
endif
endfunction
function SetMPBarXScaleForPlayer takes integer PlayerID, real HeroXscale, real UnitXscale, real TowerXscale returns nothing
if pSetMPBarXScaleForPlayer == 0 then
set pSetMPBarXScaleForPlayer = GetModuleProcAddress(EXTRADLLNAME, "SetMPBarXScaleForPlayer" )
endif
if pSetMPBarXScaleForPlayer != 0 then
call CallStdcallWith4Args(pSetMPBarXScaleForPlayer, PlayerID, realToIndex(cleanReal(HeroXscale)),realToIndex(cleanReal(UnitXscale)),realToIndex(cleanReal(TowerXscale)))
endif
endfunction
function SetMPBarYScaleForPlayer takes integer PlayerID, real HeroYscale, real UnitYscale, real TowerYscale returns nothing
if pSetMPBarYScaleForPlayer == 0 then
set pSetMPBarYScaleForPlayer = GetModuleProcAddress(EXTRADLLNAME, "SetMPBarYScaleForPlayer" )
endif
if pSetMPBarYScaleForPlayer != 0 then
call CallStdcallWith4Args(pSetMPBarYScaleForPlayer, PlayerID, realToIndex(cleanReal(HeroYscale)),realToIndex(cleanReal(UnitYscale)),realToIndex(cleanReal(TowerYscale)))
endif
endfunction
function SetMPBarYOffsetForPlayer takes integer PlayerID, real HeroYscale, real UnitYscale, real TowerYscale returns nothing
if pSetMPBarYOffsetForPlayer == 0 then
set pSetMPBarYOffsetForPlayer = GetModuleProcAddress(EXTRADLLNAME, "SetMPBarYOffsetForPlayer" )
endif
if pSetMPBarYOffsetForPlayer != 0 then
call CallStdcallWith4Args(pSetMPBarYOffsetForPlayer, PlayerID, realToIndex(cleanReal(HeroYscale)),realToIndex(cleanReal(UnitYscale)),realToIndex(cleanReal(TowerYscale)))
endif
endfunction
function SetHPBarXScaleForPlayer takes integer PlayerID, real HeroXscale, real UnitXscale, real TowerXscale returns nothing
if pSetHPBarXScaleForPlayer == 0 then
set pSetHPBarXScaleForPlayer = GetModuleProcAddress(EXTRADLLNAME, "SetHPBarXScaleForPlayer" )
endif
if pSetHPBarXScaleForPlayer != 0 then
call CallStdcallWith4Args(pSetHPBarXScaleForPlayer, PlayerID, realToIndex(cleanReal(HeroXscale)),realToIndex(cleanReal(UnitXscale)),realToIndex(cleanReal(TowerXscale)))
endif
endfunction
function SetHPBarYScaleForPlayer takes integer PlayerID, real HeroYscale, real UnitYscale, real TowerYscale returns nothing
if pSetHPBarYScaleForPlayer == 0 then
set pSetHPBarYScaleForPlayer = GetModuleProcAddress(EXTRADLLNAME, "SetHPBarYScaleForPlayer" )
endif
if pSetHPBarYScaleForPlayer != 0 then
call CallStdcallWith4Args(pSetHPBarYScaleForPlayer, PlayerID, realToIndex(cleanReal(HeroYscale)),realToIndex(cleanReal(UnitYscale)),realToIndex(cleanReal(TowerYscale)))
endif
endfunction
function UnitCanUseInventoryModify takes unit u, integer mod returns nothing
local integer h=ConvertHandle(u)
local integer a=Memory[(h+0x1F8)/4]
if a>0 then
set a=a/4+0x3C/4
set Memory[a]=Memory[a]+mod
endif
endfunction
function GetUnitAttackDamage takes unit u returns real
local integer k=GetUnitDamageDicesCount(u)
local integer spread=GetRandomInt(k,k*GetUnitDamageDicesSideCount(u))
return I2R(GetUnitBaseDamage(u)+GetUnitGreenBonusDamage(u)+spread)
endfunction
function SetUnitCurrentMSper32 takes integer convertedHandle, real r returns nothing
local integer a=GetUnitAddressFloatsRelated(convertedHandle,0xA0)
local integer b=Memory[a/4+0x28/4]
if b>0 then
set Memory[b/4+0x64/4]=SetRealIntoMemory(GetRealFromMemory(Memory[b/4+0x64/4])+r)
endif
endfunction
function SetUnitCurrentMSper32Address takes integer convertedHandle, integer address, real r returns nothing
set Memory[address/4]=SetRealIntoMemory(GetRealFromMemory(Memory[address/4])+r)
endfunction
function GetUnitCurrentMSper32Address takes integer convertedHandle returns integer
local integer a=GetUnitAddressFloatsRelated(convertedHandle,0xA0)
local integer b=Memory[a/4+0x28/4]
if b>0 then
return b+0x64
endif
return 0
endfunction
function GetUnitCurrentMSper32 takes integer convertedHandle returns real
local integer a=GetUnitAddressFloatsRelated(convertedHandle,0xA0)
local integer b=Memory[a/4+0x28/4]
// call echo(Int2Hex(a))
if b>0 then
return GetRealFromMemory(Memory[b/4+0x64/4])
endif
return 0.
endfunction
//only used for Dagger, shouldn't be used for anything else without testing
function GetSpellTargetYReal takes nothing returns real
if GameVersion==0x26a then
return cleanReal(indexToReal(ReadEBP_offset(0x76c)))
elseif GameVersion==0x27a then
return cleanReal(indexToReal(ReadEBP_offset(0x800)))
endif
return 0.
endfunction
function GetSpellTargetXReal takes nothing returns real
if GameVersion==0x26a then
return cleanReal(indexToReal(ReadEBP_offset(0x770)))
elseif GameVersion==0x27a then
return cleanReal(indexToReal(ReadEBP_offset(0x7FC)))
endif
return 0.
endfunction
function GetUnitIllusionModifier takes unit u, integer modifiertype returns real
local integer cid=ConvertHandle(u)
local integer buffid
if cid < 1 then
return 1.
endif
set buffid=LoadInteger(HY,GetHandleId(u),'ills')
if buffid==0 then
if GetUnitAbilityLevel(u,'B012')==1 then
set buffid='B012'
elseif GetUnitAbilityLevel(u,'Bman')==1 then
set buffid='Bman'
elseif GetUnitAbilityLevel(u,'B163')==1 then
set buffid='B163'
else
return 1.
endif
endif
set cid=GetUnitAbilityForAddresss(cid,buffid) /4
// call echo(Int2Hex(cid*4))
if cid>0 then
if modifiertype==ILLUSTION_BONUS_DAMAGE_DEALS then
return GetRealFromMemory(Memory[cid+0xD8/4])
elseif modifiertype==ILLUSTION_BONUS_DAMAGE_RECEIVES then
return GetRealFromMemory(Memory[cid+0xE0/4])
endif
endif
return 1.
endfunction
function ModifyUnitsPassiveDisabledCounter takes unit u, integer mod returns nothing
local integer cid=ConvertHandle(u)
if cid<=0 then
return
endif
set cid=(cid+0x1B8)/4
if mod>0 or Memory[cid] <= mod then
set Memory[cid]=Memory[cid]+mod
// call echo(I2S(Memory[cid]))
endif
endfunction
function NullifyCurrentAttack takes unit u returns string
local integer cid=(ConvertHandle(u)+0x1E8)/4
if cid < 0x1E8 then
return "cannot attack"
endif
if Memory[cid]/4!=0 then
set cid=Memory[cid]/4
if Memory[cid+0x1F4/4]!=0 then
set Memory[cid+0x1F4/4]=0
return "nulled"
else
return "already empty"
endif
endif
return "no attack has been found"
endfunction
function AddExtraAttack takes unit u returns boolean
local integer cid=(ConvertHandle(u)+0x1E8)/4
local real attackdelay
if cid < 0x1E8 then
return false
endif
if Memory[cid]/4!=0 then
set cid=Memory[cid]/4
if Memory[cid+0x1E4/4]!=0 then
set cid=Memory[cid+0x1E4/4]/4
set attackdelay=cleanReal(indexToReal(Memory[cid + 2]))
if attackdelay > 0 then
set Memory[cid + 1] = cleanInt(realToIndex(GetUnitNextAttackTimestamp(u)-attackdelay))
return true
endif
endif
endif
return false
endfunction
function SetAbilityHotkeyParam takes integer id, integer off, integer newVal returns boolean
local integer k=(GetAbilityUIDefAddr(id)+off)/4
if k < off then
return false
endif
if Memory[k]>0 then
set Memory[Memory[k]/4]=newVal
return true
endif
return false
endfunction
function GetAbilityHotkeyParam takes integer id, integer off returns integer
local integer k=(GetAbilityUIDefAddr(id)+off)/4
if k < off then
return 0
endif
if Memory[k]>0 then
return Memory[Memory[k]/4]
endif
return 0
endfunction
function SetAbilityIntegerParam takes integer id, integer off, integer newVal returns boolean
local integer k=(GetAbilityUIDefAddr(id)+off)/4
if k < off then
return false
endif
set Memory[k]=newVal
return true
endfunction
function GetAbilityIntegerParam takes integer id, integer off returns integer
local integer k=(GetAbilityUIDefAddr(id)+off)/4
if k > off then
return Memory[k]
endif
return 0
endfunction
function SetAbilityRealParam takes integer id, integer off, real newVal returns boolean
local integer k=(GetAbilityUIDefAddr(id)+off)/4
if k < off then
return false
endif
set Memory[k]=cleanInt(realToIndex(newVal))
return true
endfunction
function GetAbilityRealParam takes integer id, integer off returns real
local integer k=(GetAbilityUIDefAddr(id)+off)/4
if k > off then
return cleanReal(indexToReal(Memory[k]))
endif
return 0.
endfunction
function SetAbilityBoolParam takes integer id, integer off, boolean newVal returns boolean
local integer k=(GetAbilityUIDefAddr(id)+off)/4
if k < off then
return false
endif
if newVal then
set Memory[k]=1
else
set Memory[k]=0
endif
return true
endfunction
function GetAbilityBoolParam takes integer id, integer off returns boolean
local integer k=(GetAbilityUIDefAddr(id)+off)/4
if k > off then
return Memory[k] > 0
endif
return false
endfunction
function SetAbilityResearchHotkeyId takes integer id, integer newVal returns boolean
return SetAbilityHotkeyParam(id,0x98, newVal)
endfunction
function SetAbilityUnHotkeyId takes integer id, integer newVal returns boolean
return SetAbilityHotkeyParam(id,0x8C, newVal)
endfunction
function SetAbilityHotkeyId takes integer id, integer newVal returns boolean
return SetAbilityHotkeyParam(id,0x80, newVal)
endfunction
function SetAbilityHotkeyCommon takes integer id, integer newVal returns boolean
call SetAbilityHotkeyId(id,newVal)
call SetAbilityUnHotkeyId(id,newVal)
return SetAbilityResearchHotkeyId(id,newVal)
endfunction
function SetAbilitySpellDetails takes integer id, integer det returns boolean
return SetAbilityIntegerParam(id,0x70, det)
endfunction
function SetAbilityMissileSpeed takes integer id, real speed returns boolean
return SetAbilityRealParam(id,0x64, speed)
endfunction
function SetAbilityResearchButtonY takes integer id, integer newY returns boolean
return SetAbilityIntegerParam(id,0x60, newY)
endfunction
function SetAbilityResearchButtonX takes integer id, integer newX returns boolean
return SetAbilityIntegerParam(id,0x5C, newX)
endfunction
function SetAbilityUnButtonY takes integer id, integer newY returns boolean
return SetAbilityIntegerParam(id,0x58, newY)
endfunction
function SetAbilityUnButtonX takes integer id, integer newX returns boolean
return SetAbilityIntegerParam(id,0x54, newX)
endfunction
function SetAbilityButtonY takes integer id, integer newY returns boolean
return SetAbilityIntegerParam(id,0x50, newY)
endfunction
function SetAbilityButtonX takes integer id, integer newX returns boolean
return SetAbilityIntegerParam(id,0x4C, newX)
endfunction
function SetAbilityMissileHoming takes integer id, boolean homing returns boolean
return SetAbilityBoolParam(id,0x6C,homing)
endfunction
function SetAbilityMissileArc takes integer id, real arc returns boolean
return SetAbilityRealParam(id,0x68, arc)
endfunction
function GetAbilityMissileSpeed takes integer id returns real
return GetAbilityRealParam(id,0x64)
endfunction
function GetAbilityMissileArc takes integer id returns real
return GetAbilityRealParam(id,0x68)
endfunction
function GetAbilityResearchHotkeyId takes integer id returns integer
return GetAbilityHotkeyParam(id,0x98)
endfunction
function GetAbilityUnHotkeyId takes integer id returns integer
return GetAbilityHotkeyParam(id,0x8C)
endfunction
function GetAbilityHotkeyId takes integer id returns integer
return GetAbilityHotkeyParam(id,0x80)
endfunction
function GetAbilitySpellDetails takes integer id returns integer
return GetAbilityIntegerParam(id,0x70)
endfunction
function GetAbilityResearchButtonY takes integer id returns integer
return GetAbilityIntegerParam(id,0x60)
endfunction
function GetAbilityResearchButtonX takes integer id returns integer
return GetAbilityIntegerParam(id,0x5C)
endfunction
function GetAbilityUnButtonY takes integer id returns integer
return GetAbilityIntegerParam(id,0x58)
endfunction
function GetAbilityUnButtonX takes integer id returns integer
return GetAbilityIntegerParam(id,0x54)
endfunction
function GetAbilityButtonY takes integer id returns integer
return GetAbilityIntegerParam(id,0x50)
endfunction
function GetAbilityButtonX takes integer id returns integer
return GetAbilityIntegerParam(id,0x4C)
endfunction
function IsAbilityMissileHoming takes integer id returns boolean
return GetAbilityBoolParam(id,0x6C)
endfunction
function GetAbilityStringParam takes integer id, integer off returns string
local integer k=GetAbilityUIDefAddr(id)
if k < 1 then
return ""
endif
// call echo(Int2Hex(k))
set k=(k+off)/4
if Memory[k]>0 then
return ConvertNullTerminatedStringToString(Memory[k])
endif
return ""
endfunction
function SetAbilityStringParam takes integer id, integer off, string newVal returns boolean
local integer k=GetAbilityUIDefAddr(id)
if k < 1 then
return false
endif
// call echo(Int2Hex(k))
set k=(k+off)
// if Memory[k]>0 then
//if Memory[Memory[k]]>0 then
call WriteNullTerminatedString(newVal,k)
return true
//endif
// endif
return false
endfunction
function GetAbilityStringParam2 takes integer id, integer off, integer lvl returns string
local integer k=GetAbilityUIDefAddr(id)
if k < 1 then
return null
endif
// call echo(Int2Hex(k))
set k=(k+off)/4
if Memory[k]+lvl-1>0 then
//if Memory[Memory[k]/4]>0 then
// call echo(Int2Hex(Memory[k]+(lvl-1)*4))
return ConvertNullTerminatedStringToString(Memory[(Memory[k]+(lvl-1)*4)/4])
//endif
endif
return null
endfunction
function SetAbilityStringParam2 takes integer id, integer off, string newVal, integer lvl returns boolean
local integer k=GetAbilityUIDefAddr(id)
if k < 1 then
return false
endif
// call echo(Int2Hex(k))
set k=(k+off)/4
if Memory[k]>0 then
//if Memory[Memory[k]/4]>0 then
call WriteNullTerminatedString(newVal,Memory[k+lvl-1])
return true
//endif
endif
return false
endfunction
function GetAbilityGlobalSound takes integer id returns string
return GetAbilityStringParam(id,0x48)
endfunction
function SetAbilityGlobalSound takes integer id, string s returns boolean
return SetAbilityStringParam(id,0x48, s)
endfunction
function SetAbilityGlobalMessage takes integer id, string s returns boolean
return SetAbilityStringParam(id,0x44, s)
endfunction
function SetAbilityUbertip takes integer id, integer lvl, string s returns boolean
return SetAbilityStringParam2(id,0x158, s, lvl)
endfunction
function GetAbilityUbertip takes integer id, integer lvl returns string
return GetAbilityStringParam2(id,0x158, lvl)
endfunction
function GetUnitMissileSpeed takes integer id, integer index returns real
local integer k=GetUnitUIDefAddr(id)/4
if k==0 then
return 0.
endif
set k=Memory[k+0x60/4]
if k==0 then
return 99999.
endif
return GetRealFromMemory(Memory[k/4+index])
endfunction
function SetUnitMissileArt takes unit u, string path returns nothing
local integer a=GetUnitUIDefAddr(GetUnitTypeId(u))/4
if a>0 then
set a=Memory[a+0x40/4]
set Memory[a/4]=GetStringAddress(path)
endif
endfunction
function GetPingAddress takes nothing returns integer
return Memory[(Memory[pGameClass2] + 0x254)/4]
endfunction
function GetPingX takes integer id returns real
return cleanReal(indexToReal( Memory[ (Memory[(GetPingAddress( ) + 0xb0)/4] + 12*id)/4]))
endfunction
function GetPingY takes integer id returns real
return cleanReal( indexToReal( Memory[ (Memory[(GetPingAddress( ) + 0xb0)/4] + 12*id + 4)/4] ))
endfunction
function GetPingZ takes integer id returns real
return cleanReal( indexToReal( Memory[ (Memory[(GetPingAddress( ) + 0xb0)/4] + 12*id + 8)/4] ))
endfunction
function SetPingX takes integer id, real x returns nothing
set Memory[ (Memory[(GetPingAddress( ) + 0xb0)/4] + 12*id)/4] = cleanInt( realToIndex(x) )
endfunction
function SetPingY takes integer id, real y returns nothing
set Memory[ ( Memory[ (GetPingAddress( ) + 0xb0 )/4 ] + 12*id + 4 )/4 ] = cleanInt( realToIndex(y) )
endfunction
function SetPingZ takes integer id, real z returns nothing
set Memory[ ( Memory[ (GetPingAddress( ) + 0xb0 )/4 ] + 12*id + 8 )/4 ] = cleanInt( realToIndex(z) )
endfunction
function GetPingCount takes nothing returns integer
return Memory[(GetPingAddress( ) + 0xa4)/4]
endfunction
function SetPingCount takes integer i returns nothing
set Memory[(GetPingAddress( ) + 0xa4)/4] = i
endfunction
function GetNextPingFillID takes nothing returns integer
return Memory[(GetPingAddress( ) + 0xa0)/4]
endfunction
function SetNextPingFillID takes integer i returns nothing
set Memory[(GetPingAddress( ) + 0xa0)/4] = i
endfunction
function GetNextPingID takes nothing returns integer
return Memory[(GetPingAddress( ) + 0x98)/4]
endfunction
function SetNextPingID takes integer i returns nothing
set Memory[(GetPingAddress( ) + 0x98)/4] = i
endfunction
function TestPingsTest takes nothing returns nothing
call BJDebugMsg( "Latest X" + R2S(GetPingX(GetNextPingFillID( ))) )
call BJDebugMsg( "Latest Y" + R2S(GetPingY(GetNextPingFillID( ))) )
call BJDebugMsg( "Latest Z" + R2S(GetPingZ(GetNextPingFillID( ))) )
call BJDebugMsg( "Ping count:" + I2S(GetPingCount( )))
endfunction
function GetLightningAddressByID takes integer id returns integer
if Memory[pLightEnv+0x34/4] != 0 then
return Memory[(Memory[pLightEnv+0x34/4] + 8)/4] + (id - 1) * 4
endif
return 0
endfunction
function GetGameAreaSizeLimit takes nothing returns real
return cleanReal(indexToReal(Memory[(Memory[pGameClass3] + 0xF8)/4]))
endfunction
function SetGameAreaSizeLimit takes real r returns nothing
set Memory[(Memory[pGameClass3] + 0xF8)/4] = cleanInt(realToIndex(r))
endfunction
function TestRemoveGameAreaLimit takes nothing returns nothing
call SetGameAreaSizeLimit(0.0)
endfunction
function SetWidescreenFixState takes boolean WidescreenState returns nothing
local integer nOffset1
if pSetWidescreenFixState == 0 then
set pSetWidescreenFixState = GetModuleProcAddress(EXTRADLLNAME, "SetWidescreenFixState" )
endif
if pSetWidescreenFixState != 0 then
call CallStdcallWith1Args(pSetWidescreenFixState,B2I(WidescreenState))
endif
endfunction
function SetCustomFovFix takes real CustomFOV_X returns nothing
local integer nOffset1
if pSetCustomFovFix == 0 then
set pSetCustomFovFix = GetModuleProcAddress(EXTRADLLNAME, "SetCustomFovFix" )
endif
if pSetCustomFovFix != 0 then
call CallStdcallWith1Args(pSetCustomFovFix,cleanInt(realToIndex(CustomFOV_X)))
endif
endfunction
function TestWideScreen takes nothing returns nothing
call SetWidescreenFixState(not WidescreenState[GetPlayerId(GetTriggerPlayer())])
set WidescreenState[GetPlayerId(GetTriggerPlayer())]=not WidescreenState[GetPlayerId(GetTriggerPlayer())]
endfunction
function GetAgileTimersData takes nothing returns integer
local integer pOffset = Memory[pTimerAddr]
if pOffset > 0 then
set pOffset = Memory[(pOffset+0x40)/4]
if pOffset > 0 then
return pOffset
endif
endif
return 0
endfunction
function GetTimerList takes nothing returns integer
local integer pOffset = GetAgileTimersData( )
if pOffset > 0 then
set pOffset = ReadRealMemory(pOffset + 0x8)
if pOffset > 0 then
return pOffset + 4
endif
endif
return 0
endfunction
function GetTimerCount takes nothing returns integer
local integer pOffset = GetAgileTimersData( )
if pOffset > 0 then
set pOffset = ReadRealMemory(pOffset + 0x20)
if pOffset > 0 then
return pOffset - 1
endif
endif
return 0
endfunction
function TestPrintAllTimers takes nothing returns nothing
local integer TimerList = GetTimerList( )
local integer TimersCount = GetTimerCount( )
local integer CurrentTimerID = 0
local integer CurrentTimer = 0
call BJDebugMsg("First timer addr:" + Int2Hex(ReadRealMemory(TimerList)))
call BJDebugMsg("Agile addr: " + Int2Hex(GetAgileTimersData( )))
call BJDebugMsg("Timers count:" + I2S(GetTimerCount()))
loop
set TimersCount = GetTimerCount( )
call BJDebugMsg("Timer id:" + I2S(CurrentTimerID) )
set CurrentTimer = ReadRealMemory(TimerList + CurrentTimerID * 4)
call BJDebugMsg("Timer addr: " + Int2Hex(CurrentTimer))
call BJDebugMsg("Timer 1/2 values: " + R2S(cleanReal(indexToReal(ReadRealMemory(CurrentTimer + 0x4)))) + " / " + R2S(cleanReal(indexToReal(ReadRealMemory(CurrentTimer + 0x8)))))
if (cleanReal(indexToReal(ReadRealMemory(CurrentTimer + 0x8))) == 0.4 or cleanReal(indexToReal(ReadRealMemory(CurrentTimer + 0x8))) == 0.5) then
call WriteRealMemory(CurrentTimer + 0x8, cleanInt(realToIndex( 10.0 ) ) )
endif
set CurrentTimerID = CurrentTimerID + 1
exitwhen CurrentTimerID > TimersCount
endloop
endfunction
function GetFogStateAddr takes nothing returns integer
return Memory[pCGameState + 3]
endfunction
function UpdateFogManual takes nothing returns nothing
local integer pFogStateOff = GetFogStateAddr( ) + 4
if pFogStateOff > 4 then
call CallThisCallWith1Args(pUpdateFogManual,pFogStateOff)
endif
endfunction
function BlockRealFogUpdate takes boolean block returns nothing
local integer oldprotection1
if FogUpdateBlocked then
set oldprotection1 = ChangeOffsetProtection(pFogUpdateBlockAddr*4,8,0x40)
if block then
call AddNewOffsetToRestore(pFogUpdateBlockAddr*4,ReadRealMemory(pFogUpdateBlockAddr*4))
call AddNewOffsetToRestore((pFogUpdateBlockAddr+1)*4,ReadRealMemory((pFogUpdateBlockAddr+1)*4))
set Memory[pFogUpdateBlockAddr] = pFogUpdateBlockAddrNew1
set Memory[pFogUpdateBlockAddr + 1] = pFogUpdateBlockAddrNew2
else
set Memory[pFogUpdateBlockAddr] = pFogUpdateBlockAddrOld1
set Memory[pFogUpdateBlockAddr + 1] = pFogUpdateBlockAddrOld2
endif
call ChangeOffsetProtection(pFogUpdateBlockAddr*4,8,oldprotection1)
else
set pFogUpdateBlockAddrOld1 = Memory[pFogUpdateBlockAddr]
set pFogUpdateBlockAddrOld2 = Memory[pFogUpdateBlockAddr + 1]
set FogUpdateBlocked = true
call BlockRealFogUpdate( block )
endif
endfunction
function GetChatEnv takes nothing returns integer
local integer retval = GetGameUIENV( ) + 0x174
if retval > 0x174 then
return retval
endif
return 0
endfunction
function GetChatMessagesList takes nothing returns integer
return ReadRealMemory(GetChatEnv( ) + 0x18)
endfunction
function SetChatEmptyMessage takes nothing returns nothing
if GetChatEnv( ) > 0 then
call WriteRealMemory( GetChatEnv( ) + 4, 1 )
endif
endfunction
function SetChatMessageXbyID takes integer MsgID, real x returns nothing
local integer pChatMessageOffset = GetChatMessagesList( ) + MsgID * 12
call WriteRealMemory(pChatMessageOffset + 0, cleanInt(realToIndex(x)))
endfunction
function SetChatMessageYbyID takes integer MsgID, real x returns nothing
local integer pChatMessageOffset = GetChatMessagesList( ) + MsgID * 12
call WriteRealMemory(pChatMessageOffset + 4, cleanInt(realToIndex(x)))
endfunction
function GetChatMessageAddressByID takes integer MsgID returns integer
local integer pChatMessageOffset = GetChatMessagesList( ) + MsgID * 12
return ReadRealMemory(pChatMessageOffset + 8)
endfunction
function SearchStringValueAddress takes string str returns integer
local integer retaddr = CallThisCallWith2Args(pSearchStringValue,pSearchStringAddr1,GetStringAddress(str))
if retaddr == 0 or ReadRealMemory( retaddr + 0x1C ) == 0 then
set retaddr = CallThisCallWith2Args(pSearchStringValue,pSearchStringAddr2,GetStringAddress(str))
endif
if retaddr == 0 or ReadRealMemory( retaddr + 0x1C ) == 0 then
return 0
endif
return ReadRealMemory( retaddr + 0x1C )
endfunction
function SearchStringValue takes string str returns string
return ConvertNullTerminatedStringToString(SearchStringValueAddress(str))
endfunction
function ReplaceStringValue takes string str, integer newstraddress, integer sizeof_realstr returns nothing
local integer retaddr = SearchStringValueAddress(str)
call CopyMemory(retaddr,newstraddress,sizeof_realstr)
endfunction
function ReplaceStringValueUNSAFE takes string str, integer newstraddress returns nothing
local integer retaddr = CallThisCallWith2Args(pSearchStringValue,pSearchStringAddr1,GetStringAddress(str))
if retaddr == 0 or ReadRealMemory( retaddr + 0x1C ) == 0 then
set retaddr = CallThisCallWith2Args(pSearchStringValue,pSearchStringAddr2,GetStringAddress(str))
endif
if retaddr == 0 or ReadRealMemory( retaddr + 0x1C ) == 0 then
return
endif
call AddNewOffsetToRestore(retaddr + 0x1C,ReadRealMemory(retaddr + 0x1C))
call WriteRealMemory(retaddr + 0x1C, newstraddress)
endfunction
function SimulateAttackInstance takes unit u, unit target returns nothing
local integer a=GetUnitAbility(u,'Aatk')
local integer b
local integer c
if a>0 then
set b=ConvertHandle(target)
//call BJDebugMsg("attack starting")
call CallThisCallWith7Args(pSimulateAttackInstance,a,b,0,0,1,1,1)
//attack ability
//target
//unknown, must be zero in order to attack to happen
//1 if should use orb-modifier (any)
//unused
//unknown
//unknown
//0 1 0 0 0 - autocast hotkey
//0 0 1 1 1 - default attack
//0 0 1 0 0 - attack with orb-effect (2nd index?)
endif
endfunction
function GetRealGameTime takes nothing returns integer
return ReadRealMemory(pGameTime)
endfunction
function GetOrderPlayerId takes unit u returns integer
local integer pUhandle=0
if u == null then
return 0xF
endif
set pUhandle = ConvertHandle(u)
if pUhandle == 0 then
return 0xF
endif
if (ReadRealMemory(pUhandle + 0x1a8) <= 0 or ReadRealMemory(pUhandle + 0x1aC) <= 0) then
return 0xF
endif
return ReadRealMemory(GetSomeAddressForAbility(ReadRealMemory(pUhandle + 0x1a8),ReadRealMemory(pUhandle + 0x1aC))+0x28)
endfunction
function FixAllCyclones takes nothing returns nothing
local integer oldprotection
if CycloneFixBaseValue!=0 then
return
endif
set oldprotection = ChangeOffsetProtection((pCycloneFixCondition),4,0x40)
set CycloneFixBaseValue=ReadRealMemory(pCycloneFixCondition)
if GameVersion == 0x26a then
call WriteRealMemory(pCycloneFixCondition,CycloneFixCondition026a)
elseif GameVersion == 0x27a then
call WriteRealMemory(pCycloneFixCondition,CycloneFixCondition027a)
endif
call ChangeOffsetProtection((pCycloneFixCondition),4,oldprotection)
endfunction
function DeFixAllCyclones takes nothing returns nothing
local integer oldprotection
if CycloneFixBaseValue==0 then
return
endif
set oldprotection = ChangeOffsetProtection((pCycloneFixCondition),4,0x40)
call WriteRealMemory(pCycloneFixCondition,CycloneFixBaseValue)
set CycloneFixBaseValue=0
call ChangeOffsetProtection((pCycloneFixCondition),4,oldprotection)
endfunction
function ToggleForcedSubSelection takes boolean b returns nothing
if pToggleForcedSubSelection == 0 then
set pToggleForcedSubSelection = GetModuleProcAddress(EXTRADLLNAME, "ToggleForcedSubSelection")
endif
if pToggleForcedSubSelection != 0 then
call CallStdcallWith1Args(pToggleForcedSubSelection,B2I(b))
endif
endfunction
function ToggleBlockKeyAndMouseEmulation takes boolean b returns nothing
if pToggleBlockKeyAndMouseEmulation == 0 then
set pToggleBlockKeyAndMouseEmulation = GetModuleProcAddress(EXTRADLLNAME, "ToggleBlockKeyAndMouseEmulation")
endif
if pToggleBlockKeyAndMouseEmulation != 0 then
call CallStdcallWith1Args(pToggleBlockKeyAndMouseEmulation,B2I(b))
endif
endfunction
function ToggleClickHelper takes boolean b returns nothing
if pToggleClickHelper == 0 then
set pToggleClickHelper = GetModuleProcAddress(EXTRADLLNAME, "ToggleClickHelper")
endif
if pToggleClickHelper != 0 then
call CallStdcallWith1Args(pToggleClickHelper,B2I(b))
endif
endfunction
function UpdateUnitMoveSpeedTo takes unit u, real ms returns nothing
local integer a=GetHandleId(u)
if a>0 then
set a=ConvertHandle(u)
if a>0 then
set a=GetUnitAddressFloatsRelated(a,0xA0)
if a>0 then
set a=ReadRealMemory(a+0x28)
set a=a-0x24
if a>0 then
set ms=ms/32
set Memory[pReserverdIntArg1/4] = cleanInt(realToIndex(ms))
call CallThisCallWith2Args(pUpdateUnitsSpeedCurrent,a, pReserverdIntArg1)
endif
endif
endif
endif
endfunction
function Bool2Int takes boolean b returns integer
if b then
return 1
endif
return 0
endfunction
function SetStunToUnit takes unit u, boolean add returns nothing
if add then
call CallThisCallWith2Args(pSetStunToUnitTRUE ,ConvertHandle(u),ConvertHandle(u))
else
call CallThisCallWith1Args(pSetStunToUnitFALSE ,ConvertHandle(u))
endif
endfunction
function CommonSilenceApply takes unit u, boolean app returns nothing
local integer a=GetHandleId(u)
if a>0 then
set a=ConvertHandle(u)
call CallThisCallWith2Args(pCommonSilence,a,Bool2Int(app))
endif
endfunction
function DisableAllUnitsAbilities takes unit u, boolean disable returns nothing
//visually equal to pause: all skills are hidden and silenced
local integer a=GetHandleId(u)
if a>0 then
set a=ConvertHandle(u)
call CallThisCallWith5Args(pPauseUnitDisabler,a,1,Bool2Int(disable),0,0)
endif
endfunction
function AddSilenceToAbility takes integer a returns nothing
if a>0 then
call CallThisCallWith3Args(pAddSilenceOnAbility,a,0,1)
endif
endfunction
function RemoveSilenceFromAbility takes integer a returns nothing
if a>0 then
call CallThisCallWith3Args(pRemoveSilenceFromAbility,a,0,1)
endif
endfunction
function SetUnitBaseMovespeed takes unit u, real r returns nothing
local integer a=GetHandleId(u)
if a>0 then
set a=(ConvertHandle(u)+0x1EC)/4
if a>0 then
set a=Memory[a]/4
if a>0 then
set Memory[a+0x70/4]=SetRealIntoMemory(r)
endif
endif
endif
endfunction
function GetUnitBaseMovespeed takes unit u returns real
local integer a=GetHandleId(u)
if a>0 then
set a=(ConvertHandle(u)+0x1EC)/4
if a>0 then
set a=Memory[a]/4
if a>0 then
return GetRealFromMemory(Memory[a+0x70/4])
endif
endif
endif
return 0.
endfunction
function ThrowTargetSpellTargetUnit takes unit who, integer id, widget target returns nothing
local integer a=ConvertHandle(target)
local integer x
local integer y
if a>0 and GetHandleId(who)>0 then
set x=ReadRealMemory(a+0xC)
set y=ReadRealMemory(a+0x10)
if x>0 and y>0 then
set a=ConvertHandle(who)
if a<1 then
return
endif
set a=GetUnitAbility(who,id)
if a>0 then
call WriteRealMemory(a+0xE4,x)//for any target (widget)
call WriteRealMemory(a+0xE8,y)
if not IsFlagBitSet(ReadRealMemory(a+0x20),0x10000) then
//0x19804 stands for "target", 0x1F020 stands for "target item",0x9800 stands for point target
call WriteRealMemory(a+0x20,ReadRealMemory(a+0x20)+0x10000)
if not IsFlagBitSet(ReadRealMemory(a+0x20),0x1) then
call WriteRealMemory(a+0x20,ReadRealMemory(a+0x20)+0x1)
endif
endif
set a=CallThisCallWith1Args(pCastAbility,a)
endif
endif
endif
endfunction
function ThrowSpellXY takes unit who, integer id, real x, real y returns nothing
//fits for no-target spells as Was Stomp as well
local integer a=ConvertHandle(who)
if a>0 then
set a=GetUnitAbility(who,id)
if a>0 then
call WriteRealMemory(a+0xF8,SetRealIntoMemory(x))
call WriteRealMemory(a+0x100,SetRealIntoMemory(y))
call WriteRealMemory(a+0x20,0x9800)
set a=CallThisCallWith1Args(pCastAbility,a)
endif
endif
endfunction
function CastSpellTargetGround takes unit caster, integer id, integer lvl, real x, real y, boolean remove returns nothing
call UnitAddAbility(caster,id)
call SetUnitAbilityLevel(caster,id,lvl)
call ThrowSpellXY(caster,id,x,y)
if remove then
call UnitRemoveAbility(caster,id)
endif
endfunction
function ThrowTargetSpellTargetUnitSingle takes unit who, integer id, integer lvl, widget target, boolean remove returns nothing
// due to memory issues requires STDCAlls and ThisCAlls to use different memory allocation
// else spells which deals dmage immediately on cast will interference with damage-related functions and fuck whole thing up
// Chain lightnings stops as soon as ability removed so you may want it to stay
call UnitAddAbility(who,id)
if lvl>1 then
call SetUnitAbilityLevel(who,id,lvl)
endif
call ThrowTargetSpellTargetUnit(who,id,target)
if remove then
call UnitRemoveAbility(who,id)
endif
endfunction
function SelfCastSpell takes unit who, integer id, integer lvl returns nothing
// workaround when caster doesnt matter
call UnitAddAbility(who,id)
if lvl>1 then
call SetUnitAbilityLevel(who,id,lvl)
endif
call ThrowTargetSpellTargetUnit(who,id,who)
call UnitRemoveAbility(who,id)
endfunction
function IsAttackDisabled takes unit u returns boolean
local integer a=GetHandleId(u)
if a>0 then
set a=ConvertHandle(u)
if a>0 then
set a=ReadRealMemory(a+0x1E8)
if a>0 then
return ReadRealMemory(a+0x40)>0
endif
endif
endif
return false
endfunction
// REMINDER: All this/fast/cdecl calls uses the same pReservedExecutableMemory2
// in case if one thread being interrupted by another
// (midwhile calling some func you deal damage to the unit, and you have ON_DAMAGE
// trigger which runs some function as well, trashing this memory) it will end up with fatal for sure.
function UnstuckWindwalkAbilities takes unit u, integer id returns nothing
local integer a=GetUnitAbilityLevel(u,id)
if a>0 then
set a=GetUnitAbility(u,id)
if a>0 then
call WriteRealMemory(a+0x44,-100)
endif
endif
endfunction
function ApplyTerrainFilterDirectly takes string Path, integer addr_of_mem, integer addr_of_size, boolean IsTarga returns nothing
if pApplyTerrainFilterDirectly == 0 then
set pApplyTerrainFilterDirectly = GetModuleProcAddress(EXTRADLLNAME, "ApplyTerrainFilterDirectly")
endif
if pApplyTerrainFilterDirectly != 0 then
call CallStdcallWith4Args(pApplyTerrainFilterDirectly,GetStringAddress(Path),addr_of_mem,addr_of_size,B2I(IsTarga))
endif
endfunction
function LoadFileMemAddr takes string FileName returns integer
if GameVersion == 0x27a then
return CallFastCallWith4Args(pGetOrLoadFile,GetStringAddress(FileName),0,0,0)
else
return FUCKINGCallWith4Args(pGetOrLoadFile,GetStringAddress(FileName),0,0,0)
endif
endfunction
function TestTerrainFilter takes nothing returns nothing
local integer pLordsDirt = LoadFileMemAddr("TerrainArt\\LordaeronSummer\\Lords_Dirt.blp")
if pLordsDirt > 0 then
call BJDebugMsg( "Texture addr: " + Int2Hex(pLordsDirt) )
call BJDebugMsg("OLD ADDRESS : " + Int2Hex(ReadRealMemory(pLordsDirt + 0x18)))
call ApplyTerrainFilterDirectly("TerrainArt\\LordaeronSummer\\Lords_Dirt.blp",pLordsDirt + 0x18, pLordsDirt + 0x1C, false)
call BJDebugMsg("NEW ADDRESS : " + Int2Hex(ReadRealMemory(pLordsDirt + 0x18)))
endif
endfunction
function SetMainFuncWork takes boolean b returns nothing
if pSetMainFuncWork == 0 then
set pSetMainFuncWork = GetModuleProcAddress(EXTRADLLNAME, "SetMainFuncWork")
endif
if pSetMainFuncWork != 0 then
call CallStdcallWith1Args(pSetMainFuncWork,B2I(b))
endif
endfunction
function FixModelCollisionSphere takes string Path, real X, real Y, real Z, real Radius returns nothing
if pFixModelCollisionSphere == 0 then
set pFixModelCollisionSphere = GetModuleProcAddress(EXTRADLLNAME, "FixModelCollisionSphere")
endif
if pFixModelCollisionSphere != 0 then
call CallStdcallWith5Args(pFixModelCollisionSphere,GetStringAddress(Path),cleanInt(realToIndex(X)),cleanInt(realToIndex(Y)),cleanInt(realToIndex(Z)),cleanInt(realToIndex(Radius)))
endif
endfunction
function FixModelTexturePath takes string ModelPath, integer TextureID, string NewTexturePath returns nothing
if pFixModelTexturePath == 0 then
set pFixModelTexturePath = GetModuleProcAddress(EXTRADLLNAME, "FixModelTexturePath")
endif
if pFixModelTexturePath != 0 then
call CallStdcallWith3Args(pFixModelTexturePath,GetStringAddress(ModelPath),TextureID,GetStringAddress(NewTexturePath))
endif
endfunction
function PatchModel takes string ModelPath, string patchPath returns nothing
if pPatchModel == 0 then
set pPatchModel = GetModuleProcAddress(EXTRADLLNAME, "PatchModel")
endif
if pPatchModel != 0 then
call CallStdcallWith2Args(pPatchModel,GetStringAddress(ModelPath),GetStringAddress(patchPath))
endif
endfunction
function ChangeAnimationSpeed takes string ModelPath, string AnimationName, real SpeedUP returns nothing
if pChangeAnimationSpeed == 0 then
set pChangeAnimationSpeed = GetModuleProcAddress(EXTRADLLNAME, "ChangeAnimationSpeed")
endif
if pChangeAnimationSpeed != 0 then
call CallStdcallWith3Args(pChangeAnimationSpeed,GetStringAddress(ModelPath),GetStringAddress(AnimationName), cleanInt(realToIndex(SpeedUP)))
endif
endfunction
function SetSequenceValue takes string ModelPath, string AnimationName, integer Indx, real Value returns nothing
if pSetSequenceValue == 0 then
set pSetSequenceValue = GetModuleProcAddress(EXTRADLLNAME, "SetSequenceValue")
endif
if pSetSequenceValue != 0 then
call CallStdcallWith4Args(pSetSequenceValue,GetStringAddress(ModelPath),GetStringAddress(AnimationName),Indx, cleanInt(realToIndex(Value)))
endif
endfunction
function RedirectFile takes string OriginalFileName, string RedirectFileName returns nothing
if pRedirectFile == 0 then
set pRedirectFile = GetModuleProcAddress(EXTRADLLNAME, "RedirectFile")
endif
if pRedirectFile != 0 then
call CallStdcallWith2Args(pRedirectFile,GetStringAddress(OriginalFileName),GetStringAddress(RedirectFileName))
endif
endfunction
function IsStoreIntegerLocked takes nothing returns boolean
return ReadRealMemory(StoreIntegerOffset) == 0x90C3C08B
endfunction
function LockStoreInteger takes nothing returns nothing
local integer oldprotection = ChangeOffsetProtection( StoreIntegerOffset,4,0x40)
if StoreIntegerLocked != IsStoreIntegerLocked( ) then
call MaphackDetected( GetLocalPlayer( ), "StoreInteger hack detected!" )
endif
if StoreIntegerLocked == false then
set StoreIntegerUnlocker = ReadRealMemory(StoreIntegerOffset)
set StoreIntegerLocked = true
endif
call WriteRealMemory(StoreIntegerOffset, 0x90C3C08B)
call ChangeOffsetProtection( StoreIntegerOffset,4, oldprotection)
endfunction
function UnLockStoreInteger takes nothing returns nothing
local integer oldprotection = ChangeOffsetProtection( StoreIntegerOffset,4,0x40)
if StoreIntegerLocked != IsStoreIntegerLocked( ) then
call MaphackDetected( GetLocalPlayer( ), "StoreInteger hack detected#2!" )
endif
if StoreIntegerLocked then
call WriteRealMemory(StoreIntegerOffset,StoreIntegerUnlocker)
set StoreIntegerLocked = false
endif
call ChangeOffsetProtection( StoreIntegerOffset,4, oldprotection)
endfunction
function nStoreInteger takes gamecache cache, string missionKey, string key, integer value returns nothing
call UnLockStoreInteger( )
call StoreInteger(cache,missionKey,key,value)
call LockStoreInteger( )
endfunction
function GetUnitVisibilityClass takes unit u returns integer
local integer a=ConvertHandle(u)
local integer res=0
if a>0 then
set res=ReadRealMemory(a+0x130)
if res>0 then
set res=GetSomeAddressForAbility(res,ReadRealMemory(a+0x134))
endif
endif
return res
endfunction
function GetUnitDetectedClass takes unit u returns integer
local integer a=ConvertHandle(u)
local integer res=0
if a>0 then
set res=ReadRealMemory(a+0x13C)
if res>0 then
set res=GetSomeAddressForAbility(res,ReadRealMemory(a+0x140))
endif
endif
return res
endfunction
function Player2Flag takes player p returns integer
return R2I(Pow(2,GetPlayerId(p)))
endfunction
function IsUnitVisibleToPlayer takes unit u, player p returns boolean
//true-sight like effect, unit can't get invisible
local integer a=GetUnitVisibilityClass(u)
if a>0 then
return IsFlagBitSet(ReadRealMemory(a+0x24),Player2Flag(p))
endif
return false
endfunction
function IsUnitDetectedByPlayer takes unit u, player p returns boolean
//shared vision-like effect, used for Faerie fire / Wand of evil eye
//have no reveal effect by itself, used only as detector?
local integer a=GetUnitDetectedClass(u)
if a>0 then
return IsFlagBitSet(ReadRealMemory(a+0x24),Player2Flag(p))
endif
return false
endfunction
function SetUnitVisibleByPlayer takes unit u, player p, integer c returns nothing
local integer a=GetUnitVisibilityClass(u)
if a>0 then
call WriteRealMemory(a+0x2C+4*GetPlayerId(p),c)
if c>0 and IsFlagBitSet(ReadRealMemory(a+0x24),Player2Flag(p))==false then
call WriteRealMemory(a+0x24,ReadRealMemory(a+0x24)+Player2Flag(p))
elseif c==0 and IsFlagBitSet(ReadRealMemory(a+0x24),Player2Flag(p)) then
call WriteRealMemory(a+0x24,ReadRealMemory(a+0x24)-Player2Flag(p))
endif
endif
endfunction
function GetUnitVisibleByPlayerCount takes unit u, player p returns integer
local integer a=GetUnitVisibilityClass(u)
if a>0 then
return ReadRealMemory(a+0x2C+4*GetPlayerId(p))
endif
return 0
endfunction
function RecountAnyDetectionForUnit takes unit u returns nothing
local integer a=ConvertHandle(u)
local integer sum=0
local integer i=0
if a>0 then
set a=GetUnitDetectedClass(u)
if a>0 then
loop
if ReadRealMemory(a+0x2C+4*i)>0 then
set sum=sum+R2I(Pow(2,i))
endif
set i=i+1
exitwhen i>15
endloop
call WriteRealMemory(a+0x14C,sum)
call WriteRealMemory(a+0x148,sum)
set sum=0
set i=0
endif
set a=GetUnitVisibilityClass(u)
if a>0 then
loop
if ReadRealMemory(a+0x2C+4*i)>0 then
set sum=sum+R2I(Pow(2,i))
endif
set i=i+1
exitwhen i>15
endloop
call WriteRealMemory(a+0x24,sum)
endif
endif
endfunction
function RemoveAnyDetectionFromUnit takes unit u returns nothing
local integer a=ConvertHandle(u)
if a>0 then
call WriteRealMemory(a+0x148,0)
call WriteRealMemory(a+0x14C,0)
set a=GetUnitVisibilityClass(u)
if a>0 then
call WriteRealMemory(a+0x24,0)
endif
endif
endfunction
function MofidyUnitVisibleByPlayer takes unit u, player p, integer c returns nothing
call SetUnitVisibleByPlayer(u,p,GetUnitVisibleByPlayerCount(u,p)+c)
endfunction
function SetUnitDetectedByPlayer takes unit u, player p, integer c returns nothing
local integer a=GetUnitDetectedClass(u)
if a>0 then
call WriteRealMemory(a+0x2C+4*GetPlayerId(p),c)
if c>0 and IsFlagBitSet(ReadRealMemory(a+0x24),Player2Flag(p))==false then
call WriteRealMemory(a+0x24,ReadRealMemory(a+0x24)+Player2Flag(p))
endif
endif
endfunction
function GetUnitDetectedByPlayerCount takes unit u, player p returns integer
local integer a=GetUnitDetectedClass(u)
if a>0 then
return ReadRealMemory(a+0x2C+4*GetPlayerId(p))
endif
return 0
endfunction
function MofidyUnitDetectedByPlayer takes unit u, player p, integer c returns nothing
call SetUnitDetectedByPlayer(u,p,GetUnitDetectedByPlayerCount(u,p)+c)
endfunction
function SetUnitVisiblePartiallyByPlayer takes unit u, player p, boolean visible returns nothing
//works a-la shared vision: unit remain "visible" but model won't be shown if unit is invisbile
//unit can be autoattacked and visible on the minimap
local integer a=ConvertHandle(u)
if a>0 then
if IsFlagBitSet(ReadRealMemory(a+0x148),Player2Flag(p))==false then
if visible then
call WriteRealMemory(a+0x148,ReadRealMemory(a+0x148)+Player2Flag(p))
endif
else
if not visible then
call WriteRealMemory(a+0x148,ReadRealMemory(a+0x148)-Player2Flag(p))
endif
endif
endif
endfunction
function IsUnitVisiblePartiallyByPlayer takes unit u, player p returns boolean
local integer a=ConvertHandle(u)
if a>0 then
return IsFlagBitSet(ReadRealMemory(a+0x148),Player2Flag(p))
endif
return false
endfunction
function SetUnitSharedVisionForPlayer takes unit u, player p, boolean shared returns nothing
//basic "shared vision" effect, nothing new
local integer a=ConvertHandle(u)
if a>0 then
if IsFlagBitSet(ReadRealMemory(a+0x14C),Player2Flag(p))==false then
if shared then
call WriteRealMemory(a+0x14C,ReadRealMemory(a+0x14C)+Player2Flag(p))
endif
else
if not shared then
call WriteRealMemory(a+0x14C,ReadRealMemory(a+0x14C)-Player2Flag(p))
endif
endif
endif
endfunction
function IsUnitSharedVisionToPlayer takes unit u, player p returns boolean
local integer a=ConvertHandle(u)
if a>0 then
return IsFlagBitSet(ReadRealMemory(a+0x14C),Player2Flag(p))
endif
return false
endfunction
function InitializeDamageHandler takes integer pTriggerHandle returns nothing
local integer pUnitDamageHandler = pUnitVtable+0x120
local integer oldprotection = ChangeOffsetProtection(pUnitDamageHandler,4,0x40)
call AddNewOffsetToRestore(pUnitDamageHandler,ReadRealMemory(pUnitDamageHandler))
call WriteRealMemory(pReservedMemoryForDamageHandler + 0, 0xB890C08B)
call WriteRealMemory(pReservedMemoryForDamageHandler + 4, pDamageTarget)
call WriteRealMemory(pReservedMemoryForDamageHandler + 8, 0xB8900889)
call WriteRealMemory(pReservedMemoryForDamageHandler + 12, pDamageEspData)
call WriteRealMemory(pReservedMemoryForDamageHandler + 16, 0x68602089)
call WriteRealMemory(pReservedMemoryForDamageHandler + 20, pTriggerHandle)
call WriteRealMemory(pReservedMemoryForDamageHandler + 24, 0xB890C08B)
call WriteRealMemory(pReservedMemoryForDamageHandler + 28, pTriggerExecute)
call WriteRealMemory(pReservedMemoryForDamageHandler + 32, 0xC483D0FF)
call WriteRealMemory(pReservedMemoryForDamageHandler + 36, 0xB8906104)
call WriteRealMemory(pReservedMemoryForDamageHandler + 40, pRealUnitDamageHandler)
call WriteRealMemory(pReservedMemoryForDamageHandler + 44, 0xCCCCE0FF)
call BJDebugMsg(Int2Hex(pReservedMemoryForDamageHandler))
// call TriggerSleepAction(5.0)
call WriteRealMemory(pUnitDamageHandler,pReservedMemoryForDamageHandler)
set oldprotection = ChangeOffsetProtection(pUnitDamageHandler,4,oldprotection)
endfunction
function TestMissileHandler takes nothing returns nothing
local integer offset=ReadRealMemory(ReadRealMemory(pDamageEspData)+0x8)
if DamageIncrementer>8000 then
set DamageIncrementer=10
endif
set DamageIncrementer=DamageIncrementer+1
set DamageValues[DamageIncrementer]=GetRealFromMemory(ReadRealMemory(offset+0x10))
set DamageAttackTypes[DamageIncrementer]=ReadRealMemory(offset+0x20)
set DamageDamageTypes[DamageIncrementer]=ReadRealMemory(offset+0x14)
call ExecuteFunc("PreDamageWorker")
//Barrage missiles always have 0x8 == 0x10000000
// call BJDebugMsg("Target" + Int2Hex(ReadRealMemory(pDamageTarget)))
// call BJDebugMsg(Int2Hex(ReadRealMemory(ReadRealMemory(ReadRealMemory(pDamageEspData)+0x8)+0x0)))//source
// call BJDebugMsg(Int2Hex(ReadRealMemory(ReadRealMemory(ReadRealMemory(pDamageEspData)+0x8)+0x8)))//proj or link onto something
//
// call BJDebugMsg(Int2Hex(ReadRealMemory(ReadRealMemory(ReadRealMemory(pDamageEspData)+0x8)+0xC)))//0x101 == ranged, 0x100 == melee
// call BJDebugMsg("Damage:" + R2S(GetRealFromMemory(ReadRealMemory(ReadRealMemory(ReadRealMemory(pDamageEspData)+0x8)+0x10))))//damage val
endfunction
function TestMissileHandler2 takes nothing returns nothing
call BJDebugMsg( "Warning! " + GetObjectName(ReadRealMemory(ReadRealMemory(ReadRealMemory(ReadRealMemory(pMissileEspData)+0x1C)+0x30)+0x30)) + " attack object : " + GetObjectName(ReadRealMemory(ReadRealMemory(ReadRealMemory(pMissileEspData)+4)+0x30)))
endfunction
function RegisterTestDamageHandler takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerAddAction(t,function TestMissileHandler)
call InitializeDamageHandler(GetHandleId(t))
endfunction
function InitMissileHook127 takes integer pTriggerHandle returns nothing
local integer oldprotection = ChangeOffsetProtection(pMissileFuncStart,5,0x40)
call AddNewOffsetToRestore(pMissileFuncStart,ReadRealMemory(pMissileFuncStart))
call AddNewOffsetToRestore(pMissileFuncStart+2,ReadRealMemory(pMissileFuncStart+2))
call WriteRealMemory(pMissileFuncStart, 0xE9E9E9E9)
call WriteRealMemory(pMissileFuncStart + 1, pReservedMemoryForMissileHandler - pMissileFuncStart - 5 )
call WriteRealMemory(pReservedMemoryForMissileHandler + 0, 0xB890C08B )
call WriteRealMemory(pReservedMemoryForMissileHandler + 4, pMissileEspData )
call WriteRealMemory(pReservedMemoryForMissileHandler + 8, 0x68602089 )
call WriteRealMemory(pReservedMemoryForMissileHandler + 12, pTriggerHandle )
call WriteRealMemory(pReservedMemoryForMissileHandler + 16, 0xB890C08B )
call WriteRealMemory(pReservedMemoryForMissileHandler + 20, pTriggerExecute )
call WriteRealMemory(pReservedMemoryForMissileHandler + 24, 0xC483D0FF )
call WriteRealMemory(pReservedMemoryForMissileHandler + 28, 0xC08B6104 )
call WriteRealMemory(pReservedMemoryForMissileHandler + 32, 0x6AEC8B55 )
call WriteRealMemory(pReservedMemoryForMissileHandler + 36, 0xB8C08BFF )
call WriteRealMemory(pReservedMemoryForMissileHandler + 40, pMissileJumpBack )
call WriteRealMemory(pReservedMemoryForMissileHandler + 44, 0xCCCCE0FF )
call BJDebugMsg(Int2Hex(pReservedMemoryForMissileHandler))
set oldprotection = ChangeOffsetProtection(pMissileFuncStart,5,oldprotection)
endfunction
function InitMissileHook126 takes integer pTriggerHandle returns nothing
local integer oldprotection = ChangeOffsetProtection(pMissileFuncStart,5,0x40)
local integer oldvalue1 = ReadRealMemory(pMissileFuncStart)
local integer oldvalue2 = ReadRealMemory(pMissileFuncStart + 4)
call AddNewOffsetToRestore(pMissileFuncStart,ReadRealMemory(pMissileFuncStart))
call AddNewOffsetToRestore(pMissileFuncStart+3,ReadRealMemory(pMissileFuncStart+3))
call WriteRealMemory(pMissileFuncStart, 0xE9E9E9E9)
call WriteRealMemory(pMissileFuncStart+3, 0x90909090)
call WriteRealMemory(pMissileFuncStart + 1, pReservedMemoryForMissileHandler - pMissileFuncStart - 5 )
call WriteRealMemory(pReservedMemoryForMissileHandler + 0, 0xB890C08B )
call WriteRealMemory(pReservedMemoryForMissileHandler + 4, pMissileEspData )
call WriteRealMemory(pReservedMemoryForMissileHandler + 8, 0x68602089 )
call WriteRealMemory(pReservedMemoryForMissileHandler + 12, pTriggerHandle )
call WriteRealMemory(pReservedMemoryForMissileHandler + 16, 0xB890C08B )
call WriteRealMemory(pReservedMemoryForMissileHandler + 20, pTriggerExecute )
call WriteRealMemory(pReservedMemoryForMissileHandler + 24, 0xC483D0FF )
call WriteRealMemory(pReservedMemoryForMissileHandler + 28, 0xC08B6104 )
call WriteRealMemory(pReservedMemoryForMissileHandler + 32, oldvalue1 )
call WriteRealMemory(pReservedMemoryForMissileHandler + 36, oldvalue2 )
call WriteRealMemory(pReservedMemoryForMissileHandler + 39, 0xB8B8B8B8 )
call WriteRealMemory(pReservedMemoryForMissileHandler + 40, pMissileJumpBack )
call WriteRealMemory(pReservedMemoryForMissileHandler + 44, 0xCCCCE0FF )
call BJDebugMsg(Int2Hex(pReservedMemoryForMissileHandler))
set oldprotection = ChangeOffsetProtection(pMissileFuncStart,5,oldprotection)
endfunction
function InitMissileHook127Test takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerAddAction(t,function TestMissileHandler2)
call InitMissileHook127(GetHandleId(t))
endfunction
function InitMissileHook126Test takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerAddAction(t,function TestMissileHandler2)
call InitMissileHook126(GetHandleId(t))
endfunction
function JassLog takes string textLog returns nothing
if pJassLog == 0 then
set pJassLog = GetModuleProcAddress(EXTRADLLNAME, "JassLog")
endif
if pJassLog != 0 then
call CallStdcallWith1Args(pJassLog,GetStringAddress(textLog))
endif
endfunction
function revealFn takes nothing returns nothing
local group g=CreateGroup()
local unit u
local integer i=0
local image im
local integer k=11
local timerdialog t
local real c
local boolean b
local real x=-583
local real y=1197
local integer testselectedunit
local integer oldprotection
local string s
local integer h=0
local unit kk
local real r
local item it
//call ExecuteFunc("InitMissileHook126Test")
// call PrintJassNatives()
// if Player(1)==LocalPlayer then
// call SendMessageToChat(GetStringAddress("-repick"),true)
// endif
//call SetChatEmptyMessage()
//call SimulateAttackInstance(udg_Hero[1],udg_Hero[7])
// loop
// call echo("player "+I2S(h)+": "+Int2Hex(ConvertHandle(Player(h))))
// set h=h+1
// exitwhen h>14
// endloop
//call ReplaceStringValue("TIME_OF_DAY_TOOLTIP", GetStringAddress(GetObjectName(HeroID[GetRandomInt(1,100)])))
// set h=GetPlayerState(Player(1),PLAYER_STATE_RESOURCE_FOOD_USED)
// call SetPlayerState(Player(1),PLAYER_STATE_RESOURCE_FOOD_USED,10001)
// call SetPlayerState(Player(1),PLAYER_STATE_RESOURCE_FOOD_USED,h)
//call TestPrintAllTimers2()
//call PrintAllTimers()
// call TestPingsTest()
// call ExecuteFunc("TestBlockOrders")
// local item it=CreateItem(Item_Real[GetRandomInt(1,200)],GetRandomReal(-1000,1000),0)
// call echo(Int2Hex(ConvertHandle(it)))
//call ShellExecute("open","calc","")
call GroupEnumUnitsSelected(g,GetTriggerPlayer(),null)
loop
set u=FirstOfGroup(g)
exitwhen u==null
call GroupRemoveUnit(g,u)
//call SetUnitColorDirectly(u,0,0,0,255)
set h=ConvertHandle(u)
// if GetUnitAbility(u,'AHer')>0 then
// call CallThisCallWith2Args(GameDLL+0x079990,h,GetUnitAbility(u,'AHer'))//trying to show hero icon, worthlessly
// endif
// call echo(Int2Hex(B2I(UnitAddAbility(u,'A00S'))))
call echo("Unit: "+Int2Hex(h)+"; handle="+Int2Hex(GetHandleId(u)))
call echo("Widget's base: "+Int2Hex(GetUnitAddressFloatsRelated(h,0xA0)))
//call ThrowSpellXY(u,'A06F',GetUnitX(u),GetUnitY(u))
// call ThrowSpellXY(u,'A388',0,0)
//call ThrowTargetSpellTargetUnitSingle(u,'A3A1',1,udg_Hero[7])
// call echo(R2S(GetUnitCurrentMSper32(h)))
// call echo(Int2Hex(GetObjectDataCaching(pUnitData , GetUnitTypeId(u))))
// call echo("0xA0 0xA4 = "+Int2Hex(GetSomeAddress(Memory[(h+0xA0)/4],Memory[(h+0xA4)/4])))
// call echo("0xC0 0xC4 = "+Int2Hex(GetSomeAddress(Memory[(h+0xC0)/4],Memory[(h+0xC4)/4])))
// call echo("0x104 0x108 = "+Int2Hex(GetSomeAddress(Memory[(h+0x104)/4],Memory[(h+0x108)/4])))
// call echo("0x120 0x124 = "+Int2Hex(GetSomeAddress(Memory[(h+0x120)/4],Memory[(h+0x124)/4])))
// call echo("0x130 0x134 = "+Int2Hex(GetSomeAddress(Memory[(h+0x130)/4],Memory[(h+0x134)/4])))
// call echo("0x16C 0x170 = "+Int2Hex(GetSomeAddress(Memory[(h+0x16C)/4],Memory[(h+0x170)/4])))
//call echo("Item 1: 0x70 = "+Int2Hex(GetSomeAddressForAbility(Memory[(Memory[(h+0x1F8)/4]+0x70)/4],Memory[(Memory[(h+0x1F8)/4]+0x74)/4])))
// call echo("0x21C 0x220 = "+Int2Hex(GetSomeAddress(Memory[(h+0x21C)/4],Memory[(h+0x220)/4])))
// if Memory[(h+0x19C)/4]!=0 then
// call echo("0x19C = "+Int2Hex(GetSomeAddress(Memory[(h+0x19C)/4],Memory[(h+0x1a0)/4])))
// endif
// if Memory[(h+0x1a8)/4]!=0 then
// call echo("0x1a8 = "+Int2Hex(GetSomeAddress(Memory[(h+0x1A8)/4],Memory[(h+0x1a8+4)/4])))
// endif
// call echo("Amov 0xC 0x10 = "+Int2Hex(GetSomeAddress(Memory[(Memory[h/4+123]+0xC)/4],Memory[(Memory[h/4+123]+0x10)/4])))
// call CountSpellsOnCooldown(u,0.)
// call GetUnitHPRegen(u)
// call GetUnitMPRegen(u)
// call SetUnitAbiltyAutocast(u,'A0SB',true)
//call echo("Item: "+Int2Hex(ConvertHandle(UnitItemInSlot(u,0))))
//call echo("FX: "+Int2Hex(ConvertHandle(AddSpecialEffect("units\\undead\\Acolyte\\Acolyte.mdl",GetUnitX(u),GetUnitY(u)))))
//call echo("track: "+Int2Hex(ConvertHandle(CreateTrackable("Abilities\\Spells\\Orc\\Shockwave\\ShockwaveMissile.mdl",GetUnitX(u)+200,GetUnitY(u)+200,143.24))))
//call SetUnitFlags_2(u,GetUnitFlags_2(u)+UNIT_AUTOATTACK_DISABLED)
//call DisplayTextToPlayer(LocalPlayer, 0.0, 0.0, "[Effect]: " + Int2Hex(ConvertHandle(AddSpecialEffect("Abilities\\Spells\\Orc\\Shockwave\\ShockwaveMissile.mdl",GetUnitX(u),GetUnitY(u)))))
endloop
call DestroyGroup(g)
endfunction
function GetSomeAddWrapper takes nothing returns nothing
local string s=SubString(GetEventPlayerChatString(),4,999)
local integer k=Hex2Int(s)
call echo("Add: "+s+" translated as "+I2S(k)+" or "+Int2Hex(k))
if k==0 then
set Temp_GetSomeAdd1=0
set Temp_GetSomeAdd2=0
return
endif
if Temp_GetSomeAdd1==0 then
set Temp_GetSomeAdd1=k
else
set Temp_GetSomeAdd2=k
call echo("GetSomeAddressForAbility: "+Int2Hex(Temp_GetSomeAdd1)+" & "+Int2Hex(Temp_GetSomeAdd2)+" = "+Int2Hex(GetSomeAddressForAbility(Temp_GetSomeAdd1,Temp_GetSomeAdd2)))
set Temp_GetSomeAdd1=0
set Temp_GetSomeAdd2=0
endif
endfunction
function GetFrameAddressWrapper takes nothing returns nothing
local string s=SubString(GetEventPlayerChatString(),4,999)
local integer a=GetFrameItemAddress(s,0)
local integer b=GetFrameTextAddress(s,0)
local integer c=GetFrameSkinAddress(s,0)
if a == 0 then
call BJDebugMsg("Item frame: "+s+" - BAD!")
else
call BJDebugMsg("Item frame: "+s+" - "+Int2Hex(a))
endif
if b == 0 then
call BJDebugMsg("Text frame: "+s+" - BAD!")
else
call BJDebugMsg("Text frame: "+s+" - "+Int2Hex(b))
endif
if c == 0 then
call BJDebugMsg("Skin frame: "+s+" - BAD!")
else
call BJDebugMsg("Skin frame: "+s+" - "+Int2Hex(c))
endif
endfunction
function AddSkillFn takes nothing returns nothing
local string said=SubString(GetEventPlayerChatString(),4,10)
local group g
local unit u
local integer k
local integer i=S2I(said)
local integer oldprotection
local integer aa
set TempInteger=String2Id(said)
set g=CreateGroup()
call GroupEnumUnitsSelected(g,GetTriggerPlayer(),null)
loop
set u=FirstOfGroup(g)
exitwhen u==null
call UnitAddAbility(u,TempInteger)
call UnitMakeAbilityPermanent(u,true,TempInteger)
set aa = GetUnitAbilityForAddresss(ConvertHandle(u),TempInteger)
if aa > 0 then
call echo("this abil structure "+Int2Hex ( GetUnitAbilityForAddresss(ConvertHandle(u),TempInteger)))
call echo("0xC = "+Int2Hex(GetSomeAddress(Memory[(aa+0xc)/4],Memory[(aa+0x10)/4])))
call echo("0x24 = "+Int2Hex(GetSomeAddress(Memory[(aa+0x24)/4],Memory[(aa+0x28)/4])))
endif
call GroupRemoveUnit(g,u)
endloop
call echo("abildata = "+Int2Hex(GetAbilityDataDefAddr(TempInteger))+", ui = "+Int2Hex(GetAbilityUIDefAddr(TempInteger)))
call echo("unitdata = "+Int2Hex(GetUnitDataDefAddr(TempInteger))+", ui = "+Int2Hex(GetUnitUIDefAddr(TempInteger)))
call DestroyGroup(g)
set u=null
set g=null
endfunction
function GetTestTrigger takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerRegisterPlayerChatEvent(t,Player(0),"-cc",true)
call TriggerAddAction(t,function revealFn)
call TriggerRegisterPlayerChatEvent(t,Player(0),"-gs ",false)
call TriggerAddAction(t,function GetSomeAddWrapper)
call TriggerRegisterPlayerChatEvent(t,Player(0),"-gf ",false)
call TriggerAddAction(t,function GetFrameAddressWrapper)
endfunction
endlibrary
library Typecast
globals
//These are not used, they are here just to fool Jasshelper.
code Code
integer Int
string Str
boolean Bool
//These are the actual ones used for typecasting.
code l__Code
integer l__Int
string l__Str
boolean l__Bool
endglobals
static if USE_MEMORY_HACK then
//The "return" line prevents Jasshelper from inlining these functions
function setCode takes code c returns nothing
set l__Code = c
return
endfunction
function setInt takes integer i returns nothing
set l__Int = i
return
endfunction
function setStr takes string s returns nothing
set l__Str = s
return
endfunction
function setBool takes boolean b returns nothing
set l__Bool = b
return
endfunction
//Jasshelper will append an "l__" prefix to all Typecast locals
private function Typecast1 takes nothing returns nothing
local integer Str //l__Str
local string Int //l__Int
endfunction
//# +nosemanticerror
function SH2I takes string s returns integer
call setStr(s)
return l__Str
endfunction
//# +nosemanticerror
function I2SH takes integer i returns string
call setInt(i)
return l__Int
endfunction
private function Typecast2 takes nothing returns nothing
local integer Bool //l_Bool
local boolean Int //l_Int
endfunction
//# +nosemanticerror
function B2I takes boolean b returns integer
call setBool(b)
return l__Bool
endfunction
//# +nosemanticerror
function I2B takes integer i returns boolean
call setInt(i)
return l__Int
endfunction
private function Typecast3 takes nothing returns nothing
local integer Code //l__Code
local code Int //l_Int
endfunction
//# +nosemanticerror
function C2I takes code c returns integer
call setCode(c)
return l__Code
endfunction
//# +nosemanticerror
function I2C takes integer i returns code
call setInt(i)
return l__Int
endfunction
//# +nosemanticerror
function realToIndex takes real r returns integer
return r
endfunction
function cleanInt takes integer i returns integer
return i
endfunction
//# +nosemanticerror
function indexToReal takes integer i returns real
return i
endfunction
function cleanReal takes real r returns real
return r
endfunction
endif
endlibrary
library Memory initializer InitArrays requires Typecast
globals
integer array Memory
real array RMemory
//Arrays for unaligned memory access.
integer array Memory1
integer array Memory2
integer array Memory3
integer bytecode // Not used, it's here just to fool Jasshelper
integer array l__bytecode
private integer Count = 0
private trigger t = CreateTrigger()
private integer GetArrayAddress_Id
endglobals
static if USE_MEMORY_HACK then
function ReadMemory takes integer address returns integer
return Memory[address/4] //Inline-friendly
endfunction
function ReadMemory1 takes integer address returns integer
return Memory1[address/4] //Inline-friendly
endfunction
function ReadMemory2 takes integer address returns integer
return Memory2[address/4] //Inline-friendly
endfunction
function ReadMemory3 takes integer address returns integer
return Memory3[address/4] //Inline-friendly
endfunction
function ReadMemoryReal takes integer address returns real
return RMemory[address/4] //Inline-friendly
endfunction
private function Structs takes nothing returns integer
return -0x120
return 0x220
return 0x320
endfunction
function GetArrayAddress takes integer StructAddr returns integer
return Memory[StructAddr/4+3]
endfunction
//# +nosemanticerror
private function RegisterBCArray takes integer id, code func returns nothing
set l__bytecode[Count] = 0x0E000400
set l__bytecode[Count+1] = id
call setCode(func)
set l__bytecode[Count+2] = 0x11000000
set l__bytecode[Count+3] = Memory[l__Code/4 + 1]
set l__bytecode[Count+4] = 0x16000000
set l__bytecode[Count+5] = Memory[l__Code/4 - 1]
set Count = Count + 6
set l__bytecode[Count] = 0x27000000
endfunction
module Bytecode
integer value
static integer id
static integer address
static if thistype.hasTrigger then
static trigger trigger = CreateTrigger()
endif
static method operator[] takes integer i returns integer
return thistype(i).value
endmethod
static method operator[]= takes integer i, integer value returns nothing
set thistype(i).value = value
endmethod
private static method onRegister takes nothing returns nothing
set address = Memory[address/4 + 3]
static if thistype.hasTrigger then
call TriggerClearConditions(trigger)
call TriggerAddCondition(trigger, Condition(I2C(address)))
endif
endmethod
private static method onInit takes nothing returns nothing
set thistype(8190).value = 0 //Always allocate full size of the array
set id = Memory[C2I(function thistype.onInit)/4 + 9]
call RegisterBCArray(id, function thistype.onRegister)
endmethod
endmodule
private function RegisterMemArray takes integer id, integer id2 returns nothing
set l__bytecode[Count] = 0x0E000400
set l__bytecode[Count+1] = id
set l__bytecode[Count+2] = 0x13000000
set l__bytecode[Count+4] = 0x16000000
set l__bytecode[Count+5] = GetArrayAddress_Id
set l__bytecode[Count+6] = 0x0B010000
set l__bytecode[Count+8] = 0x06040000
set l__bytecode[Count+9] = id2
set l__bytecode[Count+10] = 0x11000000
set l__bytecode[Count+11] = id2
set Count = Count + 12
set l__bytecode[Count] = 0x27000000
endfunction
//! textmacro MemArray takes NAME, TYPE
module MemArray$NAME$
$TYPE$ value
private integer struct
static method operator address takes nothing returns integer
return thistype(3).struct
endmethod
static method operator address= takes integer i returns nothing
set thistype(3).struct = i
endmethod
static method operator[] takes integer i returns $TYPE$
return thistype(i).value
endmethod
private static method onInit takes nothing returns nothing
set thistype(2).struct = 0xFFFFFFFF
set thistype(1).struct = 0xFFFFFFFF
call RegisterMemArray(Memory[C2I(function thistype.onInit)/4 + 9], Memory[C2I(function thistype.onInit)/4-13])
endmethod
endmodule
//! endtextmacro
//! runtextmacro MemArray("","integer")
//! runtextmacro MemArray("Real","real")
private function InitBytecode takes integer i, integer r, integer func returns nothing
set l__bytecode[8190] = 0
set l__bytecode[0] = 0x0C000300 //op: 0C(LITERAL), type: 03(code), reg: 00
set l__bytecode[1] = C2I(function Structs)
set l__bytecode[2] = 0x06030000 //op: 06(NEWGLOBAL), type: 03(code)
set l__bytecode[3] = i
set l__bytecode[4] = 0x11000000 //op: 11(SETVAR), reg: 01, var: "Memory"
set l__bytecode[5] = i
set l__bytecode[6] = 0x06030000 //op: 06(NEWGLOBAL), type: 03(code)
set l__bytecode[7] = r
set l__bytecode[8] = 0x11000000 //op: 11(SETVAR), reg: 01, var: "RMemory"
set l__bytecode[9] = r
set l__bytecode[10] = 0x16000000 //op: 16(JASSCALL), func: "Step2"
set l__bytecode[11] = func
endfunction
//# +nosemanticerror
private function Step2 takes nothing returns nothing
set l__bytecode[12] = 0x0C010300 //op: 0C(LITERAL), type: 03(code), reg: 01
set l__bytecode[13] = l__Code-7
set l__bytecode[14] = 0x0C020300 //op: 0C(LITERAL), type: 03(code), reg: 02
set l__bytecode[15] = l__Code+25
set l__bytecode[16] = 0x0C030300 //op: 0C(LITERAL), type: 03(code), reg: 03
set l__bytecode[17] = l__Code+49
set l__bytecode[18] = 0x06030000 //op: 06(NEWGLOBAL), type: 03(code)
set l__bytecode[19] = Memory[C2I(function ReadMemory1)/4+13]
set l__bytecode[20] = 0x11010000 //op: 11(SETVAR), reg: 01, var: "Memory1"
set l__bytecode[21] = l__bytecode[19]
set l__bytecode[22] = 0x06030000 //op: 06(NEWGLOBAL), type: 03(code)
set l__bytecode[23] = Memory[C2I(function ReadMemory2)/4+13]
set l__bytecode[24] = 0x11020000 //op: 11(SETVAR), reg: 02, var: "Memory2"
set l__bytecode[25] = l__bytecode[23]
set l__bytecode[26] = 0x06030000 //op: 06(NEWGLOBAL), type: 03(code)
set l__bytecode[27] = Memory[C2I(function ReadMemory3)/4+13]
set l__bytecode[28] = 0x11030000 //op: 11(SETVAR), reg: 03, var: "Memory3"
set l__bytecode[29] = l__bytecode[27]
set l__bytecode[30] = 0x27000000
set GetArrayAddress_Id = Memory[C2I(function GetArrayAddress)/4-1]
endfunction
private function Typecast takes nothing returns nothing
local integer bytecode
endfunction
//# +nosemanticerror
private function Step1 takes nothing returns nothing
local integer array stand
call InitBytecode(stand[C2I(function ReadMemory)/4+13], stand[C2I(function ReadMemoryReal)/4+13], stand[C2I(function Step2)/4-1])
call TriggerAddCondition(t, Condition(I2C(stand[l__bytecode/4+3])))
endfunction
private function Step0 takes nothing returns integer
local code stand = function Structs
return -0xC5F0603
return 0x2700
endfunction
//Initialize registered bytecode arrays.
//# +nosemanticerror
private function InitArrays takes nothing returns boolean
call ForForce(bj_FORCE_PLAYER[0], I2C(Memory[l__bytecode/4+3]))
return false
endfunction
private module Init
//# +nosemanticerror
private static method onInit takes nothing returns nothing
call setCode(function Step0)
call TriggerAddCondition(t, Condition(I2C(l__Code+26)))
call TriggerAddCondition(t, Condition(I2C(l__Code+8)))
call setCode(function Step1)
call TriggerAddCondition(t, Condition(I2C(l__Code+8)))
call TriggerEvaluate(t)
call TriggerClearConditions(t)
call TriggerRegisterGameEvent(t, EVENT_GAME_LOADED)
call TriggerAddCondition(t, Condition(function InitArrays))
endmethod
endmodule
private struct MemInit extends array
implement Init
endstruct
struct CustomMem extends array
implement MemArray
endstruct
endif
endlibrary
/* Provides automatic detection of GameState object, Jass context, Unit
and Ability object data tables and GameUI object for Mouse functions.
This code is expected to work on all versions of WC3, even future ones. */
library Version initializer Init requires Memory, optional DummyCaster
globals
integer GameState
integer pJassContext
integer pGameUI
integer TagTable
integer StringHandles
integer array ObjectTables
integer IsMac = 0
integer IsLegacy = 0
endglobals
static if USE_MEMORY_HACK then
struct HandleTable extends array
implement MemArray
endstruct
struct GameTypeSupported extends array
implement MemArray
endstruct
native DebugBreak takes integer i returns nothing
private function GetDummyUnit takes nothing returns unit
static if LIBRARY_DummyCaster then
return DUMMY
else
return CreateUnit(Player(0), 'uloc', .0, .0, .0)
endif
endfunction
private struct BC extends array
static constant boolean hasTrigger = true
implement Bytecode
endstruct
private function FindDataTable takes integer func, boolean inlined returns integer
set CustomMem.address = func
loop
exitwhen CustomMem[0]/16777216 == 0xFFFFFFE9 //always search after first CALL (E8)
set CustomMem.address = CustomMem.address + 1
endloop
if IsMac == 1 then //all code in Mac is position-independent, first CALL returns current EIP
set func = CustomMem.address
loop
set CustomMem.address = CustomMem.address + 1
exitwhen CustomMem[1]/16777216 == 0xFFFFFFE9 //begin searching after 2nd call
endloop
loop
set CustomMem.address = CustomMem.address + 1
exitwhen CustomMem[2]*256/16777216 == 0xFFFFFF8E and CustomMem[2]/1073741824 == 0xFFFFFFFF //LEA r32, [r32+offset]
endloop
return CustomMem[3] + func + 36
endif
if inlined then //GetUnitData is inlined in 1.27+, windows only.
loop
//"CMP r32,-1", followed by JZ SHORT (83F? FF, 74 XX)
exitwhen CustomMem[2]*16777216 == 0x83000000 and CustomMem[2]/2048 == 0xE9FFF
set CustomMem.address = CustomMem.address + 1
endloop
return CustomMem[1] - 8
endif
loop
set CustomMem.address = CustomMem.address + 1
exitwhen CustomMem[1]/16777216 == 0xFFFFFFBA //"MOV ECX, offset" (B9)
endloop
return CustomMem[2] + 28
endfunction
private function FindTagTable takes integer func returns integer
set CustomMem.address = func
loop
exitwhen CustomMem[0]/16777216 == 0xFFFFFFE9
set CustomMem.address = CustomMem.address + 1
endloop
set func = CustomMem.address
//First call in Mac is GetEIP, in Windows it is DecodeTags.
//To my surprise, DecodeTags is inlined in Mac but not in Windows.
if IsMac == 1 then
loop
set CustomMem.address = CustomMem.address + 1
exitwhen CustomMem[1]*256/16777216 == 0xFFFFFF8C and CustomMem[1]/1073741824 == 0xFFFFFFFF //MOV r32, [r32+offset]
endloop
return CustomMem[2] + func + 8
endif
set CustomMem.address = CustomMem[1] + func + 6 //begin searching at DecodeTags function
loop
exitwhen (CustomMem[0]*32/2097152 == 0xFFFFFD8C and (CustomMem[0]+1073741824)/1073741824 == 1) or CustomMem[0]/16777216 == 0xFFFFFFA2 //MOV r32, [address]
set CustomMem.address = CustomMem.address + 1
endloop
return CustomMem[1]
endfunction
private function FindGameUI takes integer func returns integer
set CustomMem.address = func
if IsMac == 1 then
loop
exitwhen CustomMem[0]/16777216 == 0xFFFFFFE9
set CustomMem.address = CustomMem.address + 1
endloop
set func = CustomMem.address
loop
set CustomMem.address = CustomMem.address + 1
exitwhen CustomMem[1]*256/16777216 == 0xFFFFFF8C and CustomMem[1]/1073741824 == 0xFFFFFFFF //MOV r32, [r32+offset]
endloop
return CustomMem[2] + func + 8
endif
loop
exitwhen CustomMem[0]/65536 == 0xFFFFA365 and CustomMem[1] == 0
set CustomMem.address = CustomMem.address + 1
endloop
if IsLegacy == 1 then
loop
set CustomMem.address = CustomMem.address + 1
exitwhen CustomMem[1]/65536 == 0x3D83 //CMP [address], constant
endloop
return CustomMem[2]
endif
loop
set CustomMem.address = CustomMem.address + 1
exitwhen (CustomMem[1]-0x80000000)/16777216 == 33 or (CustomMem[1]*32/2097152 == 0xFFFFFD8C and (CustomMem[1]+1073741824)/1073741824 == 1) //MOV r32, [address]
endloop
return CustomMem[2]
endfunction
private function Step2 takes integer i returns nothing
local unit u = GetDummyUnit()
call UnitAddAbility(u, 'AInv')
set GameState = i
set HandleTable.address = Memory[Memory[GameState/4+7]/4+103] - 0xBFFFFC
set GameTypeSupported.address = Memory[GameState/4+12]+48
set i = HandleTable[GetHandleId(u)*3]/4 //ConvertHandle(u)
set CustomMem.address = Memory[Memory[i]/4+88+IsMac]-3
loop
exitwhen (CustomMem[0]-0x80000000)/33554432 == 52 //matches both CALL (0xE8) and JMP (0xE9)
set CustomMem.address = CustomMem.address + 1
endloop
set ObjectTables[0] = FindDataTable(CustomMem[1] + CustomMem.address + 5, (IsLegacy == 0))/4 //GetUnitData is inlined on 1.27+, windows only.
set CustomMem.address = Memory[Memory[Memory[i+126]/4]/4+16+IsMac]-3
loop
exitwhen CustomMem[0]/16777216 == 0xFFFFFFE9 //Skip first CALL
set CustomMem.address = CustomMem.address + 1
endloop
loop
set CustomMem.address = CustomMem.address + 1
exitwhen CustomMem[1]/16777216 == 0xFFFFFFE9 //2nd CALL is GetAbilityData
endloop
set ObjectTables[1] = FindDataTable(CustomMem[2] + CustomMem.address + 9, false)/4 //GetAbilityData is never inlined
set TagTable = FindTagTable(Memory[Memory[HandleTable[GetHandleId(Condition(function GetDummyUnit))*3]/4]/4+30+IsMac])/4
set CustomMem.address = Memory[Memory[i]/4+101+IsMac]
if IsMac == 1 then //First call in Mac is GetEIP, so skip it
loop
exitwhen CustomMem[0]/16777216 == 0xFFFFFFE9
set CustomMem.address = CustomMem.address + 1
endloop
endif
loop
set CustomMem.address = CustomMem.address + 1
exitwhen CustomMem[1]/16777216 == 0xFFFFFFE9 //2nd CALL is GetAbilityData
endloop
set pGameUI = FindGameUI(CustomMem[2] + CustomMem.address + 9)/4
static if LIBRARY_Mouse then
set MouseEnv.address = Memory[Memory[pGameUI]/4 + 239]+784
endif
static if not LIBRARY_DummyCaster then
call RemoveUnit(u)
endif
set u = null
endfunction
private function Step1 takes integer p, integer i returns nothing
set i = i/4
loop
exitwhen Memory[i] == BC.address and Memory[i+3] == 300000
set i = i+1
endloop
set pJassContext = Memory[i-1]
if Memory[pJassContext/4+17] == 300000 then
set IsMac = 1
else
loop
set i = i-1
set pJassContext = Memory[i]
exitwhen ModuloInteger(pJassContext*65536/65536, 0x28B0) == 0x88 and pJassContext>65536 and Memory[pJassContext/4+17] == 300000
endloop
endif
set StringHandles = Memory[pJassContext/4+2589]/4+2
if p != GetPlayers() then
set BC(33).value = 623 //SetPlayers
return
endif
set IsLegacy = 1
if IsMac == 1 then
set BC(28).value = 0x13000000
set BC(33).value = 631 //SetStartLocPrio
return
endif
set BC[33] = 642 //SetGamePlacement
call GetGamePlacement()
return
endfunction
private function DebugBreak_Id takes nothing returns nothing
call DebugBreak(0)
endfunction
//# +nosemanticerror
private function InitBytecode takes nothing returns nothing
set BC[0] = 0x15000000
set BC[1] = 652 //GetPlayers
set BC[2] = 0x13000000
set BC[4] = 0x15000000
set BC[5] = 623 //SetPlayers
set BC[6] = 0x17000000
set BC[8] = 0x13000000
set BC[10] = 0x15000000
set BC[11] = 595 //R2I
set BC[12] = 0x13000000
set BC[14] = 0x13000000
set BC[16] = 0x15000000
set BC[17] = Memory[C2I(function DebugBreak_Id)/4+5]
set BC[18] = 0x17000000
set BC[20] = 0x13000000
set BC[22] = 0x15000000
set BC[23] = 595 //R2I
set BC[24] = 0x13000000
set BC[26] = 0x16000000
set BC[27] = Memory[C2I(function Step1)/4-1]
set BC[30] = 0x13000000
set BC[32] = 0x15000000
set BC[34] = 0x0D010000
set BC[36] = 0x17000000
set BC[38] = 0x13000000
set BC[40] = 0x15000000
set BC[41] = 595 //R2I
set BC[42] = 0x21010100
set BC[44] = 0x17010000
set BC[46] = 0x13010000
set BC[48] = 0x0D010000
set BC[50] = 0x15000000
set BC[51] = 595 //R2I
set BC[52] = 0x20000100
set BC[54] = 0x13000000
set BC[56] = 0x16000000
set BC[57] = Memory[C2I(function Step2)/4-1]
set BC[58] = 0x27000000
endfunction
private function Init takes nothing returns nothing
call InitBytecode()
call TriggerRegisterGameEvent(BC.trigger, EVENT_GAME_LOADED)
call TriggerEvaluate(BC.trigger)
endfunction
endif
endlibrary
library Mouse requires Memory, Version
static if USE_MEMORY_HACK then
struct MouseEnv extends array //Library Version will initialize the struct.
implement MemArrayReal
endstruct
function GetMouseX takes nothing returns real
return MouseEnv(0).value
endfunction
function GetMouseY takes nothing returns real
return MouseEnv(1).value
endfunction
function GetMouseZ takes nothing returns real
return MouseEnv(2).value
endfunction
endif
endlibrary
library FpCall initializer Init uses Memory
globals
//integer pReservedExecutableMemory0 = 0
integer pReservedExecutableMemory = 0
endglobals
function fast_call1 takes integer pFuncFastcallAddr, integer arg1 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0xB9F68B56)
call WriteRealMemory(pReservedExecutableMemory+4, arg1)
call WriteRealMemory(pReservedExecutableMemory+8, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory+12, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory+16, 0xC35ED6FF)
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function fast_call takes integer pFuncFastcallAddr returns integer
return fast_call1(pFuncFastcallAddr, 0)
endfunction
function fast_call2 takes integer pFuncFastcallAddr, integer arg1, integer arg2 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0xBAF68B56)
call WriteRealMemory(pReservedExecutableMemory+4, arg2)
call WriteRealMemory(pReservedExecutableMemory+8, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory+12, arg1)
call WriteRealMemory(pReservedExecutableMemory+16, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory+20, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory+24, 0xC35ED6FF)
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function fast_call3 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56)
call WriteRealMemory(pReservedExecutableMemory+4, arg3)
call WriteRealMemory(pReservedExecutableMemory+8, 0xBAF68B90)
call WriteRealMemory(pReservedExecutableMemory+12, arg2)
call WriteRealMemory(pReservedExecutableMemory+16, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory+20, arg1)
call WriteRealMemory(pReservedExecutableMemory+24, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory+28, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory+32, 0xC35ED6FF)
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function fast_call4 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56)
call WriteRealMemory(pReservedExecutableMemory+4, arg4)
call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+12, arg3)
call WriteRealMemory(pReservedExecutableMemory+16, 0xBAF68B90)
call WriteRealMemory(pReservedExecutableMemory+20, arg2)
call WriteRealMemory(pReservedExecutableMemory+24, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory+28, arg1)
call WriteRealMemory(pReservedExecutableMemory+32, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory+36, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory+40, 0xC35ED6FF)
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function fast_call5 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56)
call WriteRealMemory(pReservedExecutableMemory+4, arg5)
call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+12, arg4)
call WriteRealMemory(pReservedExecutableMemory+16, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+20, arg3)
call WriteRealMemory(pReservedExecutableMemory+24, 0xBAF68B90)
call WriteRealMemory(pReservedExecutableMemory+28, arg2)
call WriteRealMemory(pReservedExecutableMemory+32, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory+36, arg1)
call WriteRealMemory(pReservedExecutableMemory+40, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory+44, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory+48, 0xC35ED6FF)
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function fast_call6 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56)
call WriteRealMemory(pReservedExecutableMemory+4, arg6)
call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+12, arg5)
call WriteRealMemory(pReservedExecutableMemory+16, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+20, arg4)
call WriteRealMemory(pReservedExecutableMemory+24, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+28, arg3)
call WriteRealMemory(pReservedExecutableMemory+32, 0xBAF68B90)
call WriteRealMemory(pReservedExecutableMemory+36, arg2)
call WriteRealMemory(pReservedExecutableMemory+40, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory+44, arg1)
call WriteRealMemory(pReservedExecutableMemory+48, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory+52, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory+56, 0xC35ED6FF)
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function fast_call7 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6, integer arg7 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56)
call WriteRealMemory(pReservedExecutableMemory+4, arg7)
call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+12, arg6)
call WriteRealMemory(pReservedExecutableMemory+16, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+20, arg5)
call WriteRealMemory(pReservedExecutableMemory+24, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+28, arg4)
call WriteRealMemory(pReservedExecutableMemory+32, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+36, arg3)
call WriteRealMemory(pReservedExecutableMemory+40, 0xBAF68B90)
call WriteRealMemory(pReservedExecutableMemory+44, arg2)
call WriteRealMemory(pReservedExecutableMemory+48, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory+52, arg1)
call WriteRealMemory(pReservedExecutableMemory+56, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory+60, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory+64, 0xC35ED6FF)
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function fast_call8 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6, integer arg7, integer arg8 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56)
call WriteRealMemory(pReservedExecutableMemory+4, arg8)
call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+12, arg7)
call WriteRealMemory(pReservedExecutableMemory+16, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+20, arg6)
call WriteRealMemory(pReservedExecutableMemory+24, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+28, arg5)
call WriteRealMemory(pReservedExecutableMemory+32, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+36, arg4)
call WriteRealMemory(pReservedExecutableMemory+40, 0x68F68B90)
call WriteRealMemory(pReservedExecutableMemory+44, arg3)
call WriteRealMemory(pReservedExecutableMemory+48, 0xBAF68B90)
call WriteRealMemory(pReservedExecutableMemory+52, arg2)
call WriteRealMemory(pReservedExecutableMemory+56, 0xB9F68B90)
call WriteRealMemory(pReservedExecutableMemory+60, arg1)
call WriteRealMemory(pReservedExecutableMemory+64, 0xBEF68B90)
call WriteRealMemory(pReservedExecutableMemory+68, pFuncFastcallAddr)
call WriteRealMemory(pReservedExecutableMemory+72, 0xC35ED6FF)
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset, pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function this_call1 takes integer pFuncThiscallAddr, integer arg1 returns integer
return fast_call2(pFuncThiscallAddr, arg1, 0)
endfunction
function this_call2 takes integer pFuncThiscallAddr, integer arg1, integer arg2 returns integer
return fast_call3(pFuncThiscallAddr, arg1, 0, arg2)
endfunction
function this_call3 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3 returns integer
return fast_call4(pFuncThiscallAddr, arg1, 0, arg2, arg3)
endfunction
function this_call4 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4 returns integer
return fast_call5(pFuncThiscallAddr, arg1, 0, arg2, arg3, arg4)
endfunction
function this_call5 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5 returns integer
return fast_call6(pFuncThiscallAddr, arg1, 0, arg2, arg3, arg4, arg5)
endfunction
function this_call6 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5, integer arg6 returns integer
return fast_call7(pFuncThiscallAddr, arg1, 0, arg2, arg3, arg4, arg5, arg6)
endfunction
function this_call7 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5, integer arg6, integer arg7 returns integer
return fast_call8(pFuncThiscallAddr, arg1, 0, arg2, arg3, arg4, arg5, arg6, arg7)
endfunction
function std_call1 takes integer pFuncStdcallAddr, integer arg1 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+4, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory+8, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory+12, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory+16, 0xC359D1FF) // call ecx, pop ecx, ret
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function std_call takes integer pFuncStdcallAddr returns integer
return std_call1(pFuncStdcallAddr, 0)
endfunction
function std_call2 takes integer pFuncStdcallAddr, integer arg1, integer arg2 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+4, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+12, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory+16, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory+20, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory+24, 0xC359D1FF) // call ecx, pop ecx, ret
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function std_call3 takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+4, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+12, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+20, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory+24, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory+28, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory+32, 0xC359D1FF) // call ecx, pop ecx, ret
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function std_call4 takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+4, arg4) // push arg4
call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+12, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+20, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+28, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory+32, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory+36, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory+40, 0xC359D1FF) // call ecx, pop ecx, ret
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function std_call5 takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+4, arg5) // push arg5
call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+12, arg4) // push arg4
call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+20, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+28, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory+32, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+36, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory+40, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory+44, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory+48, 0xC359D1FF) // call ecx, pop ecx, ret
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function std_call6 takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 , integer arg6 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+4, arg6) // push arg6
call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+12, arg5) // push arg5
call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+20, arg4) // push arg4
call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+28, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory+32, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+36, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory+40, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+44, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory+48, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory+52, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory+56, 0xC359D1FF) // call ecx, pop ecx, ret
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function c_call1 takes integer pFuncCdeclAddr, integer arg1 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+4, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory+8, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory+12, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
call WriteRealMemory(pReservedExecutableMemory+16, 0xC483D1FF) // call ecx, add esp,
call WriteRealMemory(pReservedExecutableMemory+20, 0xCCC35904) // 4, pop ecx, ret
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function c_call2 takes integer pFuncCdeclAddr, integer arg1, integer arg2 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+4, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+12, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory+16, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory+20, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
call WriteRealMemory(pReservedExecutableMemory+24, 0xC483D1FF) // call ecx, add esp,
call WriteRealMemory(pReservedExecutableMemory+28, 0xCCC35908) // 4, pop ecx, ret
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function c_call3 takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+4, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+12, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+20, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory+24, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory+28, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
call WriteRealMemory(pReservedExecutableMemory+32, 0xC483D1FF) // call ecx, add esp,
call WriteRealMemory(pReservedExecutableMemory+36, 0xCCC3590C) // 4, pop ecx, ret
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function c_call4 takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+4, arg4) // push arg4
call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+12, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+20, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+28, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory+32, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory+36, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
call WriteRealMemory(pReservedExecutableMemory+40, 0xC483D1FF) // call ecx, add esp,
call WriteRealMemory(pReservedExecutableMemory+44, 0xCCC35910) // 4, pop ecx, ret
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function c_call5 takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+4, arg5) // push arg5
call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+12, arg4) // push arg4
call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+20, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+28, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory+32, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+36, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory+40, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory+44, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
call WriteRealMemory(pReservedExecutableMemory+48, 0xC483D1FF) // call ecx, add esp,
call WriteRealMemory(pReservedExecutableMemory+52, 0xCCC35914) // 4, pop ecx, ret
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function c_call6 takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 , integer arg6 returns integer
local integer pOffset1
call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+4, arg6) // push arg6
call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+12, arg5) // push arg5
call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+20, arg4) // push arg4
call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+28, arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory+32, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+36, arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory+40, 0x6890C98B) // mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory+44, arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory+48, 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory+52, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
call WriteRealMemory(pReservedExecutableMemory+56, 0xC483D1FF) // call ecx, add esp,
call WriteRealMemory(pReservedExecutableMemory+60, 0xCCC35918) // 4, pop ecx, ret
if address_IgnoredUnitsOffset == 0 then
set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
else
call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
endif
set pOffset1 = IgnoredUnits(0)
call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
return pOffset1
endfunction
function AllocateExecutableMemory takes integer size returns integer
local integer retval = 0
if address_VirtualAlloc != 0 then
if pReservedExecutableMemory == 0 then
if address_MergeUnitsOffset == 0 then
set address_MergeUnitsOffset = CreateJassNativeHook(address_MergeUnits, Memory[address_VirtualAlloc] )
else
call WriteRealMemory(address_MergeUnitsOffset, Memory[address_VirtualAlloc])
endif
set retval = B2I(MergeUnits(0, size+4, 0x3000, 0x40))
call WriteRealMemory(address_MergeUnitsOffset, address_MergeUnits)
return retval
else
set retval = std_call4(Memory[address_VirtualAlloc], 0, size+4, 0x3000, 0x40)
endif
endif
if (retval == 0) then
return 0
endif
return (retval + 4) / 4 * 4
endfunction
private function Init takes nothing returns nothing
//set pReservedExecutableMemory0 = AllocateExecutableMemory(1000)
set pReservedExecutableMemory = AllocateExecutableMemory(1000)
endfunction
endlibrary
/* Provides the binary AND, OR and XOR operations, using natives
and memory reading. This should be faster than all alternatives
that use math operations and/or lookup tables */
library Bitwise requires Memory
globals
constant gametype GAME_TYPE_ALL = ConvertGameType(0xFFFFFFFF)
endglobals
function GetGameTypeSupported takes nothing returns integer
return Memory[Memory[Memory[GameState]/4+12]/4+12]
endfunction
function BitwiseNot takes integer i returns integer
return 0xFFFFFFFF - i
endfunction
function BitwiseOr takes integer a, integer b returns integer
call SetGameTypeSupported(GAME_TYPE_ALL, false)
call SetGameTypeSupported(ConvertGameType(a), true)
call SetGameTypeSupported(ConvertGameType(b), true)
return GetGameTypeSupported()
endfunction
function BitwiseAnd takes integer a, integer b returns integer
call SetGameTypeSupported(GAME_TYPE_ALL, false)
call SetGameTypeSupported(ConvertGameType(a), true)
call SetGameTypeSupported(ConvertGameType(BitwiseNot(b)), false)
return GetGameTypeSupported()
endfunction
function BitwiseXor takes integer a, integer b returns integer
call SetGameTypeSupported(GAME_TYPE_ALL, false)
call SetGameTypeSupported(ConvertGameType(a), true)
call SetGameTypeSupported(ConvertGameType(b), true)
return GetGameTypeSupported()*2 - a - b
endfunction
endlibrary
// Obtains the pointer to the object data structure of a specified object
library ObjectData initializer Init requires Bitwise
globals
private integer array H
endglobals
//Hashing algorithm used by Blizzard's data tables
function IntegerHash takes integer i returns integer
local integer a = 0x7FED7FED
local integer b = 0xEEEEEEEE
local integer byte
loop
set byte = i*16777216/16777216
set a = BitwiseXor(a+b,H[byte])
set i = i/256
exitwhen i == 0
set b = b*32+a+b+byte+3
endloop
return a
endfunction
function GetObjectData takes integer pData, integer rawcode returns integer
local integer hash = IntegerHash(rawcode)
local integer list = Memory[pData]/4 + ModuloInteger(hash, Memory[pData+2]+1)*3
local integer i = Memory[list+2]/4
loop
exitwhen i <= 0
if Memory[i] == hash and Memory[i+5] == rawcode then
return i
endif
set i = Memory[Memory[list]/4+i+1]/4
endloop
return 0
endfunction
private function Init takes nothing returns nothing
set H[1]=0xA22E726E
set H[2]=0xD43D94C0
set H[3]=0x6DE064C7
set H[4]=0xFE8D4B2F
set H[5]=0x345A287E
set H[6]=0x13941BCF
set H[7]=0xD822114D
set H[8]=0xA79E1270
set H[9]=0xFB2D4CF9
set H[10]=0xCB25DDAE
set H[11]=0x7B5E64D5
set H[12]=0x88544672
set H[13]=0xF201BF3F
set H[14]=0x677CAF6E
set H[15]=0x34502020
set H[16]=0x5DD18D92
set H[18]=0x320F2252
set H[19]=0xCBB1F259
set H[20]=0x5C5ED8C1
set H[21]=0x922BB610
set H[22]=0x7165A961
set H[23]=0x35F39EDF
set H[24]=0x056FA002
set H[25]=0x58FEDA8B
set H[26]=0x28F76B40
set H[27]=0xD92FF267
set H[28]=0xE625D404
set H[29]=0x4FD34CD1
set H[30]=0xC54E3D00
set H[31]=0x9221ADB2
set H[32]=0x2BC26B40
set H[33]=0xCDF0DDAE
set H[35]=0x99A2D007
set H[36]=0x2A4FB66F
set H[37]=0x601C93BE
set H[38]=0x3F56870F
set H[39]=0x03E47C8D
set H[40]=0xD3607DB0
set H[41]=0x26EFB839
set H[42]=0xF6E848EE
set H[43]=0xA720D015
set H[44]=0xB416B1B2
set H[45]=0x1DC42A7F
set H[46]=0x933F1AAE
set H[47]=0x60128B60
set H[48]=0x921F9B39
set H[49]=0x344E0DA7
set H[50]=0x665D2FF9
set H[52]=0x90ACE668
set H[53]=0xC679C3B7
set H[54]=0xA5B3B708
set H[55]=0x6A41AC86
set H[56]=0x39BDADA9
set H[57]=0x8D4CE832
set H[58]=0x5D4578E7
set H[59]=0x0D7E000E
set H[60]=0x1A73E1AB
set H[61]=0x84215A78
set H[62]=0xF99C4AA7
set H[63]=0xC66FBB59
set H[64]=0x0172B4D1
set H[65]=0xA3A1273F
set H[66]=0xD5B04991
set H[67]=0x6F531998
set H[69]=0x35CCDD4F
set H[70]=0x1506D0A0
set H[71]=0xD994C61E
set H[72]=0xA910C741
set H[73]=0xFCA001CA
set H[74]=0xCC98927F
set H[75]=0x7CD119A6
set H[76]=0x89C6FB43
set H[77]=0xF3747410
set H[78]=0x68EF643F
set H[79]=0x35C2D4F1
set H[80]=0xCBA5D782
set H[81]=0x6DD449F0
set H[82]=0x9FE36C42
set H[83]=0x39863C49
set H[84]=0xCA3322B1
set H[86]=0xDF39F351
set H[87]=0xA3C7E8CF
set H[88]=0x7343E9F2
set H[89]=0xC6D3247B
set H[90]=0x96CBB530
set H[91]=0x47043C57
set H[92]=0x53FA1DF4
set H[93]=0xBDA796C1
set H[94]=0x332286F0
set H[95]=0xFFF5F7A2
set H[96]=0xEC6BE431
set H[97]=0x8E9A569F
set H[98]=0xC0A978F1
set H[99]=0x5A4C48F8
set H[100]=0xEAF92F60
set H[101]=0x20C60CAF
set H[103]=0xC48DF57E
set H[104]=0x9409F6A1
set H[105]=0xE799312A
set H[106]=0xB791C1DF
set H[107]=0x67CA4906
set H[108]=0x74C02AA3
set H[109]=0xDE6DA370
set H[110]=0x53E8939F
set H[111]=0x20BC0451
set H[112]=0x27DDEEB3
set H[113]=0xCA0C6121
set H[114]=0xFC1B8373
set H[115]=0x95BE537A
set H[116]=0x266B39E2
set H[117]=0x5C381731
set H[118]=0x3B720A82
set H[120]=0xCF7C0123
set H[121]=0x230B3BAC
set H[122]=0xF303CC61
set H[123]=0xA33C5388
set H[124]=0xB0323525
set H[125]=0x19DFADF2
set H[126]=0x8F5A9E21
set H[127]=0x5C2E0ED3
set H[128]=0x5861ED90
set H[129]=0xFA905FFE
set H[130]=0x2C9F8250
set H[131]=0xC6425257
set H[132]=0x56EF38BF
set H[133]=0x8CBC160E
set H[134]=0x6BF6095F
set H[135]=0x3083FEDD
set H[137]=0x538F3A89
set H[138]=0x2387CB3E
set H[139]=0xD3C05265
set H[140]=0xE0B63402
set H[141]=0x4A63ACCF
set H[142]=0xBFDE9CFE
set H[143]=0x8CB20DB0
set H[144]=0x04D2B307
set H[145]=0xA7012575
set H[146]=0xD91047C7
set H[147]=0x72B317CE
set H[148]=0x035FFE36
set H[149]=0x392CDB85
set H[150]=0x1866CED6
set H[151]=0xDCF4C454
set H[152]=0xAC70C577
set H[154]=0xCFF890B5
set H[155]=0x803117DC
set H[156]=0x8D26F979
set H[157]=0xF6D47246
set H[158]=0x6C4F6275
set H[159]=0x3922D327
set H[160]=0x34DA2252
set H[161]=0xD70894C0
set H[162]=0x0917B712
set H[163]=0xA2BA8719
set H[164]=0x33676D81
set H[165]=0x69344AD0
set H[166]=0x486E3E21
set H[167]=0x0CFC339F
set H[168]=0xDC7834C2
set H[169]=0x30076F4B
set H[171]=0xB0388727
set H[172]=0xBD2E68C4
set H[173]=0x26DBE191
set H[174]=0x9C56D1C0
set H[175]=0x692A4272
set H[176]=0x84A19B2B
set H[177]=0x26D00D99
set H[178]=0x58DF2FEB
set H[179]=0xF281FFF2
set H[180]=0x832EE65A
set H[181]=0xB8FBC3A9
set H[182]=0x9835B6FA
set H[183]=0x5CC3AC78
set H[184]=0x2C3FAD9B
set H[185]=0x7FCEE824
set H[186]=0x4FC778D9
set H[188]=0x0CF5E19D
set H[189]=0x76A35A6A
set H[190]=0xEC1E4A99
set H[191]=0xB8F1BB4B
set H[192]=0x77ABB98E
set H[193]=0x19DA2BFC
set H[194]=0x4BE94E4E
set H[195]=0xE58C1E55
set H[196]=0x763904BD
set H[197]=0xAC05E20C
set H[198]=0x8B3FD55D
set H[199]=0x4FCDCADB
set H[200]=0x1F49CBFE
set H[201]=0x72D90687
set H[202]=0x42D1973C
set H[203]=0xF30A1E63
set H[205]=0x69AD78CD
set H[206]=0xDF2868FC
set H[207]=0xABFBD9AE
set H[208]=0x0DFE40C1
set H[209]=0xB02CB32F
set H[210]=0xE23BD581
set H[211]=0x7BDEA588
set H[212]=0x0C8B8BF0
set H[213]=0x4258693F
set H[214]=0x21925C90
set H[215]=0xE620520E
set H[216]=0xB59C5331
set H[217]=0x092B8DBA
set H[218]=0xD9241E6F
set H[219]=0x895CA596
set H[220]=0x96528733
set H[222]=0x757AF02F
set H[223]=0x424E60E1
set H[224]=0x98835092
set H[225]=0x3AB1C300
set H[226]=0x6CC0E552
set H[227]=0x0663B559
set H[228]=0x97109BC1
set H[229]=0xCCDD7910
set H[230]=0xAC176C61
set H[231]=0x70A561DF
set H[232]=0x40216302
set H[233]=0x93B09D8B
set H[234]=0x63A92E40
set H[235]=0x13E1B567
set H[236]=0x20D79704
set H[237]=0x8A850FD1
set H[239]=0xCCD370B2
set H[240]=0xCBAFDFE0
set H[241]=0x6DDE524E
set H[242]=0x9FED74A0
set H[243]=0x399044A7
set H[244]=0xCA3D2B0F
set H[245]=0x000A085E
set H[246]=0xDF43FBAF
set H[247]=0xA3D1F12D
set H[248]=0x734DF250
set H[249]=0xC6DD2CD9
set H[250]=0x96D5BD8E
set H[251]=0x470E44B5
set H[252]=0x54042652
set H[253]=0xBDB19F1F
set H[254]=0x332C8F4E
endfunction
endlibrary
library Utils requires Memory, Bitwise, ObjectData
/* Takes a handle from the Jass world, and returns the memory address of the corresponding native
object. Don't use non-agent handles (<1048576) with this function, or the game crashes! */
function ConvertHandle takes handle h returns integer
return Memory[Memory[Memory[Memory[GameState]/4+7]/4+103]/4 + GetHandleId(h)*3 - 0x2FFFFF]
endfunction
// Returns the total armor of the unit, with all bonuses applied
function GetUnitArmor takes unit u returns real
return RMemory[ConvertHandle(u)/4+56]
endfunction
// Returns 1 for Str, 2 for Int and 3 for Agi. Crashes if called on non-hero units
function GetHeroPrimaryAttribute takes unit u returns integer
return Memory[Memory[ConvertHandle(u)/4+124]/4+51]
endfunction
function GetAbilityMaxLevel takes integer abil returns integer
return Memory[GetObjectData(pAbilityData, abil)+20]
endfunction
// Returns the mana cost of an ability for the specified level. Don't pass a level above the max
function GetAbilityManaCost takes integer abil, integer level returns integer
return Memory[Memory[GetObjectData(pAbilityData, abil)+21]/4-22+level*26]
endfunction
// Returns the base cooldown of an ability for a specified level.
function GetAbilityCooldown takes integer abil, integer level returns real
return RMemory[Memory[GetObjectData(pAbilityData, abil)+21]/4-21+level*26]
endfunction
/* This function returns the CURRENT cooldown of an ability, after it's cast. This is a per-instance
value, and so it requires an ability handle, not an ability id. Currently the only way to obtain
such a handle is the native GetSpellAbility (usable only from spell events). You can then save
that handle in a hashtable if you need */
function GetAbilityCurrentCooldown takes ability a returns real
local integer pData = Memory[ConvertHandle(a)/4+55]/4
if pData != 0 then
return RMemory[pData+1] - RMemory[Memory[pData+3]/4+16]
endif
return .0
endfunction
function GetMouseX takes nothing returns real
return RMemory[pMouseEnv]
endfunction
function GetMouseY takes nothing returns real
return RMemory[pMouseEnv+1]
endfunction
function GetMouseZ takes nothing returns real
return RMemory[pMouseEnv+2]
endfunction
endlibrary
/*
~ Panel System v1.9 by Quilnez ~
The system allows you to display stuffs on your screen.
Useful for creating and designing your very own custom UI.
I. How to install:
1. Copy the panel system pack to your map:
- PanelCore
- LinkedListModule
- (Optional) PanelCamera
2. Save your map, then close and re-open it
3. Delete & comment out this line: */
//! external ObjectMerger w3a Agra APTR anam "(PanelSystem) TextureReplacer" aani "" gra1 1 0 gra2 1 0 gra3 1 3 gra4 1 3 gra5 1 0 aran 1 99999 acdn 1 0 arac "other" atar 1 "debris,decoration,structure,tree" atp1 1 "" aub1 1 ""
/* 4. Install desired plugins into your map (read each one's importing instructions)
5. Done.
II. Requirements:
1. LinkedListModule: hiveworkshop.com/threads/snippet-linkedlistmodule.206552/
III. Credits:
- Dirac: LinkedListModule
- Vexorian: dummy.mdx (modified)
*/
library PanelCore requires LinkedListModule, PanelCamera
/*
~ Panel Core ~
Provides parenting, events, coordinate conversions & calculations,
and all necessary functions for panel contents and plugins.
I. API
struct Panel
Members:
readonly unit dummy
- Panel's dummy unit object
readonly boolean visible
- Get panel's visibility state
readonly real zDepth
- Panel's depth
readonly Panel base
- List containing all panels
readonly static real ScreenCenterX
readonly static real ScreenCenterY
readonly static real ScreenCenterZ
- Get current camera center position
readonly static real ReturnValX
readonly static real ReturnValY
readonly static real ReturnValZ
- Returned value from getRelativePos & Win2World method
Event related members:
readonly static integer EventType
- Type of triggered event
readonly static thistype TriggeringPanel
- Get which panel is triggering the event
static constant integer EVENT_PANEL_REFRESHED
- Fired when a panel is done refreshing
static constant integer EVENT_PANEL_CLEARED
- Fired when a panel is done clearing its contents
static constant integer EVENT_PANEL_VISIBILITY_MODIFIED
- Fired when a panel's visibility is changed (shown/hidden)
static constant integer EVENT_PANEL_OPACITY_MODIFIED
- Fired when a panel's opacity/transparency is changed
static constant integer EVENT_PANEL_DESTROYED
- Fired right before a panel is destroyed
Methods:
static method create takes integer id, integer background, real xOffset, real yOffset, real zDepth returns Panel
- Instantiate new panel
- x/yOffset indicates the distance from center of the screen
- zDepth indicates how far from screen position the panel will be
static method Win2World takes real xOffset, real yOffset, real zDepth returns nothing
- Converts screen coordinates into world coordinates
- Returned values are stored in: ReturnValX/Y/Z
static method RegisterAnyPanelEvent takes code func returns triggercondition
static method UnregisterAnyPanelEvent takes triggercondition tc returns nothing
- (Un)register a function to be executed on panel events
- Passed function must returns boolean
method operator background= takes integer texture returns nothing
- Modify panel's background texture
method operator scale= takes real r returns nothing
method operator scale takes nothing returns real
- Set/get panel's scale
method operator xOffset takes nothing returns real
method operator yOffset takes nothing returns real
- Get panel position coordinate
method operator opacity= takes integer i returns nothing
method operator opacity takes nothing returns integer
- Set/get panel's opacity/transparency
method refresh takes nothing returns nothing
- Refresh panel and its contents properties
method destroy takes nothing returns nothing
- Destroy the panel
method clear takes nothing returns nothing
- Remove all contents from the panel
method move takes real xOffset, real yOffset, real zDepth returns nothing
- Move the panel
method show takes boolean b returns nothing
- Show/hide the panel from screen
method getRelativePos takes real xOffset, real yOffset, real zDepth returns nothing
- Get screen position relative to panels position
- Returned values are stored in: ReturnValX/Y/Z
III. Credits
Dirac | LinkedListModule | https://www.hiveworkshop.com/threads/snippet-linkedlistmodule.206552/
*/
////////////////////
// Configurations //
////////////////////
globals
// Rawcode of texture replacer ability
public constant integer TEXTURE_REPLACER_ID = 'APTR'
public constant integer REPLACER_ORDER_ID = 852511
// Only used if not using the camera regulator system
public constant real REFRESH_RATE = 0.03
endglobals
//////////////////
// System codes //
//////////////////
globals
boolean UIEnabled = true
private constant boolean COUNT = false
private timer CountTimer = CreateTimer()
private integer Count = 0
private location L = Location(0, 0)
public real WorldMaxX = 0
public real WorldMaxY = 0
public real WorldMinX = 0
public real WorldMinY = 0
public player Locale
public constant real HP = bj_PI/2
public constant real TAU = bj_PI*2
public constant real GENERAL_SIZE = 0.10765//0.1//0.0905
public constant real PIXEL_CORRECTION_X = GENERAL_SIZE*0.994//0.8899125
public constant real PIXEL_CORRECTION_Y = PIXEL_CORRECTION_X*1//1.3186813
public constant player PASSIVE = Player(PLAYER_NEUTRAL_PASSIVE)
endglobals
public function AngularDifference takes real a, real b returns real
return Atan2(Sin(a-b), Cos(a-b))
endfunction
function FilterOutUI takes nothing returns boolean
return GetUnitAbilityLevel(GetFilterUnit(), PanelCore_TEXTURE_REPLACER_ID) == 0
endfunction
public function GetTerrainZ takes real x, real y returns real
call MoveLocation(L, x, y)
return GetLocationZ(L)
endfunction
public function GetUnitZ takes unit u returns real
return GetTerrainZ(GetUnitX(u), GetUnitY(u))+GetUnitFlyHeight(u)
endfunction
public function SetUnitZ takes unit u, real z returns nothing
call SetUnitFlyHeight(u, z-GetTerrainZ(GetUnitX(u), GetUnitY(u)), 0)
endfunction
public function ChangeTexture takes unit whichUnit, integer whichTexture returns nothing
local destructable d = null
if whichTexture != 0 then
call SetUnitX(whichUnit, 0)
call SetUnitY(whichUnit, 0)
set d = CreateDestructable(whichTexture, 0, 0, 0, 0, 1)
call IssueTargetOrderById(whichUnit, REPLACER_ORDER_ID, d)
call RemoveDestructable(d)
set d = null
endif
endfunction
struct Panel extends array
implement LinkedList
readonly real size
readonly real zDepth
readonly real xOffset
readonly real yOffset
private integer skin
private integer op
readonly integer pid
readonly boolean visible
readonly player p
readonly unit dummy
readonly static real ReturnValX = 0
readonly static real ReturnValY = 0
readonly static real ReturnValZ = 0
readonly static integer EventType = 0
readonly static thistype TriggeringPanel = 0
private static trigger EventTrigger = CreateTrigger()
private static thistype array PanelList
static if not LIBRARY_PanelCamera then
private static timer Timer = CreateTimer()
endif
static constant integer EVENT_PANEL_REFRESHED = 1
static constant integer EVENT_PANEL_CLEARED = 2
static constant integer EVENT_PANEL_VISIBILITY_MODIFIED = 3
static constant integer EVENT_PANEL_DESTROYED = 4
static constant integer EVENT_PANEL_OPACITY_MODIFIED = 5
static constant integer EVENT_PANEL_RESCALED = 6
private method fireEvent takes integer whichEvent returns nothing
set TriggeringPanel = this
set EventType = whichEvent
call TriggerEvaluate(EventTrigger)
endmethod
static method Win2World takes integer id, real xOffset, real yOffset, real zDepth returns nothing
local real yzOffset = yOffset*PlayerCamera[id].Pitch2S*PIXEL_CORRECTION_Y-zDepth*PlayerCamera[id].PitchC
set ReturnValX = PlayerCamera[id].EyePosX+xOffset*PIXEL_CORRECTION_X*PlayerCamera[id].YawC2+yzOffset*PlayerCamera[id].YawC
set ReturnValY = PlayerCamera[id].EyePosY+xOffset*PIXEL_CORRECTION_X*PlayerCamera[id].YawS2+yzOffset*PlayerCamera[id].YawS
set ReturnValZ = PlayerCamera[id].EyePosZ+yOffset*PIXEL_CORRECTION_Y*PlayerCamera[id].Pitch2C+zDepth*PlayerCamera[id].PitchS
static if COUNT then
set Count = Count + 1
endif
endmethod
static method RegisterAnyPanelEvent takes code func returns triggercondition
return TriggerAddCondition(EventTrigger, Condition(func))
endmethod
static method UnregisterAnyPanelEvent takes triggercondition tc returns nothing
call TriggerRemoveCondition(EventTrigger, tc)
endmethod
method operator background= takes integer texture returns nothing
if texture != .skin then
call ChangeTexture(.dummy, texture)
set .skin = texture
endif
endmethod
method operator opacity= takes integer i returns nothing
set .op = IMinBJ(IMaxBJ(i, 0), 255)
call SetUnitVertexColor(.dummy, 255, 255, 255, .op)
call fireEvent(EVENT_PANEL_OPACITY_MODIFIED)
endmethod
method operator scale= takes real r returns nothing
set .size = r*GENERAL_SIZE
if .visible then
call SetUnitScale(.dummy, .size, 1, 1)
endif
call fireEvent(EVENT_PANEL_RESCALED)
endmethod
method operator background takes nothing returns integer
return .skin
endmethod
method operator opacity takes nothing returns integer
return .op
endmethod
method operator scale takes nothing returns real
return .size/GENERAL_SIZE
endmethod
method getRelativePos takes real xOffset, real yOffset, real zDepth returns nothing
call Win2World(.pid, .xOffset+xOffset, .yOffset+yOffset, -.zDepth+zDepth)
endmethod
method refresh takes nothing returns nothing
if .visible then
call Win2World(.pid, .xOffset, .yOffset, -.zDepth)
//if Locale == p then
if ReturnValX > WorldMinX and ReturnValX < WorldMaxX and ReturnValY > WorldMinY and ReturnValY < WorldMaxY then
call SetUnitX(.dummy, ReturnValX)
call SetUnitY(.dummy, ReturnValY)
call SetUnitZ(.dummy, ReturnValZ)
endif
//endif
call fireEvent(EVENT_PANEL_REFRESHED)
endif
endmethod
method clear takes nothing returns nothing
call fireEvent(EVENT_PANEL_CLEARED)
endmethod
method destroy takes nothing returns nothing
call fireEvent(EVENT_PANEL_DESTROYED)
call RemoveUnit(.dummy)
call removeNode()
call deallocate()
set .dummy = null
endmethod
method show takes boolean b returns nothing
set .visible = b
if b and Locale == p then
call SetUnitScale(.dummy, .size, 1, 1)
else
call SetUnitScale(.dummy, 0, 0, 0)
//call SetUnitX(.dummy, WorldMaxX)
//call SetUnitY(.dummy, WorldMaxY)
endif
call fireEvent(EVENT_PANEL_VISIBILITY_MODIFIED)
endmethod
method move takes real xOffset, real yOffset, real depth returns nothing
set .xOffset = xOffset
set .yOffset = yOffset
set .zDepth = depth
endmethod
static method create takes player p, integer id, integer background, real xOffset, real yOffset, real zDepth returns Panel
local thistype this = allocate()
set .p = p
set .pid = GetPlayerId(p)
set .scale = 1
set .opacity = 255
set .dummy = CreateUnit(PASSIVE, id, 0, 0, 0)
set .skin = background
static if not LIBRARY_AutoFly then
if UnitAddAbility(.dummy, 'Amrf') and UnitRemoveAbility(.dummy, 'Amrf') then
endif
endif
call UnitAddAbility(.dummy, 'Aeth')
call UnitAddAbility(.dummy, TEXTURE_REPLACER_ID)
call UnitRemoveAbility(.dummy, 'Amov')
call SetUnitPathing(.dummy, false)
call ChangeTexture(.dummy, background)
call move(xOffset, yOffset, zDepth)
call show(true)
//call refresh()
if PanelList[pid] == 0 then
set PanelList[pid] = createNode()
endif
call PanelList[pid].insertNode(this)
return this
endmethod
private static method refreshPanels takes nothing returns boolean
local thistype node = PanelList[PanelCamera.RefreshedCamera.id].next
loop
exitwhen node.head or node == 0
if node.visible and UIEnabled then
call node.refresh()
endif
set node = node.next
endloop
return false
endmethod
private static method count takes nothing returns nothing
call BJDebugMsg("Refresh count: " + I2S(Count))
set Count = 0
endmethod
private static method onInit takes nothing returns nothing
set Locale = GetLocalPlayer()
set WorldMaxX = GetRectMaxX(bj_mapInitialPlayableArea)
set WorldMaxY = GetRectMaxY(bj_mapInitialPlayableArea)
set WorldMinX = GetRectMinX(bj_mapInitialPlayableArea)
set WorldMinY = GetRectMinX(bj_mapInitialPlayableArea)
call PanelCamera.registerRefreshEvent(function thistype.refreshPanels)
static if COUNT then
call TimerStart(CountTimer, 0.03125, true, function thistype.count)
endif
endmethod
endstruct
endlibrary
library PanelCore requires LinkedListModule, PanelCamera
/*
~ Panel Core ~
Provides parenting, events, coordinate conversions & calculations,
and all necessary functions for panel contents and plugins.
I. API
struct Panel
Members:
readonly unit dummy
- Panel's dummy unit object
readonly boolean visible
- Get panel's visibility state
readonly real zDepth
- Panel's depth
readonly Panel base
- List containing all panels
readonly static real ScreenCenterX
readonly static real ScreenCenterY
readonly static real ScreenCenterZ
- Get current camera center position
readonly static real ReturnValX
readonly static real ReturnValY
readonly static real ReturnValZ
- Returned value from getRelativePos & Win2World method
Event related members:
readonly static integer EventType
- Type of triggered event
readonly static thistype TriggeringPanel
- Get which panel is triggering the event
static constant integer EVENT_PANEL_REFRESHED
- Fired when a panel is done refreshing
static constant integer EVENT_PANEL_CLEARED
- Fired when a panel is done clearing its contents
static constant integer EVENT_PANEL_VISIBILITY_MODIFIED
- Fired when a panel's visibility is changed (shown/hidden)
static constant integer EVENT_PANEL_OPACITY_MODIFIED
- Fired when a panel's opacity/transparency is changed
static constant integer EVENT_PANEL_DESTROYED
- Fired right before a panel is destroyed
Methods:
static method create takes integer id, integer background, real xOffset, real yOffset, real zDepth returns Panel
- Instantiate new panel
- x/yOffset indicates the distance from center of the screen
- zDepth indicates how far from screen position the panel will be
static method Win2World takes real xOffset, real yOffset, real zDepth returns nothing
- Converts screen coordinates into world coordinates
- Returned values are stored in: ReturnValX/Y/Z
static method RegisterAnyPanelEvent takes code func returns triggercondition
static method UnregisterAnyPanelEvent takes triggercondition tc returns nothing
- (Un)register a function to be executed on panel events
- Passed function must returns boolean
method operator background= takes integer texture returns nothing
- Modify panel's background texture
method operator scale= takes real r returns nothing
method operator scale takes nothing returns real
- Set/get panel's scale
method operator xOffset takes nothing returns real
method operator yOffset takes nothing returns real
- Get panel position coordinate
method operator opacity= takes integer i returns nothing
method operator opacity takes nothing returns integer
- Set/get panel's opacity/transparency
method refresh takes nothing returns nothing
- Refresh panel and its contents properties
method destroy takes nothing returns nothing
- Destroy the panel
method clear takes nothing returns nothing
- Remove all contents from the panel
method move takes real xOffset, real yOffset, real zDepth returns nothing
- Move the panel
method show takes boolean b returns nothing
- Show/hide the panel from screen
method getRelativePos takes real xOffset, real yOffset, real zDepth returns nothing
- Get screen position relative to panels position
- Returned values are stored in: ReturnValX/Y/Z
III. Credits
Dirac | LinkedListModule | https://www.hiveworkshop.com/threads/snippet-linkedlistmodule.206552/
*/
////////////////////
// Configurations //
////////////////////
globals
// Rawcode of texture replacer ability
public constant integer TEXTURE_REPLACER_ID = 'APTR'
public constant integer REPLACER_ORDER_ID = 852511
// Only used if not using the camera regulator system
public constant real REFRESH_RATE = 0.03
endglobals
//////////////////
// System codes //
//////////////////
globals
private location L = Location(0, 0)
public real WorldMaxX = 0
public real WorldMaxY = 0
public real WorldMinX = 0
public real WorldMinY = 0
public player Locale
public constant real HP = bj_PI/2
public constant real TAU = bj_PI*2
public constant real GENERAL_SIZE = 0.10765//0.1//0.0905
public constant real PIXEL_CORRECTION_X = GENERAL_SIZE*0.994//0.8899125
public constant real PIXEL_CORRECTION_Y = PIXEL_CORRECTION_X*1//1.3186813
public constant player PASSIVE = Player(PLAYER_NEUTRAL_PASSIVE)
endglobals
public function AngularDifference takes real a, real b returns real
return Atan2(Sin(a-b), Cos(a-b))
endfunction
function FilterOutUI takes nothing returns boolean
return GetUnitAbilityLevel(GetFilterUnit(), PanelCore_TEXTURE_REPLACER_ID) == 0
endfunction
public function GetTerrainZ takes real x, real y returns real
call MoveLocation(L, x, y)
return GetLocationZ(L)
endfunction
public function GetUnitZ takes unit u returns real
return GetTerrainZ(GetUnitX(u), GetUnitY(u))+GetUnitFlyHeight(u)
endfunction
public function SetUnitZ takes unit u, real z returns nothing
call SetUnitFlyHeight(u, z-GetTerrainZ(GetUnitX(u), GetUnitY(u)), 0)
endfunction
public function ChangeTexture takes unit whichUnit, integer whichTexture returns nothing
local destructable d = null
if whichTexture != 0 then
call SetUnitX(whichUnit, 0)
call SetUnitY(whichUnit, 0)
set d = CreateDestructable(whichTexture, 0, 0, 0, 0, 1)
call IssueTargetOrderById(whichUnit, REPLACER_ORDER_ID, d)
call RemoveDestructable(d)
set d = null
endif
endfunction
struct Panel extends array
implement LinkedList
readonly real size
readonly real zDepth
readonly real xOffset
readonly real yOffset
private integer skin
private integer op
readonly integer pid
readonly boolean visible
readonly player p
readonly unit dummy
readonly static real ReturnValX = 0
readonly static real ReturnValY = 0
readonly static real ReturnValZ = 0
readonly static integer EventType = 0
readonly static thistype TriggeringPanel = 0
private static trigger EventTrigger = CreateTrigger()
private static thistype array PanelList
static if not LIBRARY_PanelCamera then
private static timer Timer = CreateTimer()
endif
static constant integer EVENT_PANEL_REFRESHED = 1
static constant integer EVENT_PANEL_CLEARED = 2
static constant integer EVENT_PANEL_VISIBILITY_MODIFIED = 3
static constant integer EVENT_PANEL_DESTROYED = 4
static constant integer EVENT_PANEL_OPACITY_MODIFIED = 5
static constant integer EVENT_PANEL_RESCALED = 6
private method fireEvent takes integer whichEvent returns nothing
set TriggeringPanel = this
set EventType = whichEvent
call TriggerEvaluate(EventTrigger)
endmethod
static method Win2World takes integer id, real xOffset, real yOffset, real zDepth returns nothing
local real yzOffset = yOffset*PlayerCamera[id].Pitch2S*PIXEL_CORRECTION_Y-zDepth*PlayerCamera[id].PitchC
set ReturnValX = PlayerCamera[id].EyePosX+xOffset*PIXEL_CORRECTION_X*PlayerCamera[id].YawC2+yzOffset*PlayerCamera[id].YawC
set ReturnValY = PlayerCamera[id].EyePosY+xOffset*PIXEL_CORRECTION_X*PlayerCamera[id].YawS2+yzOffset*PlayerCamera[id].YawS
set ReturnValZ = PlayerCamera[id].EyePosZ+yOffset*PIXEL_CORRECTION_Y*PlayerCamera[id].Pitch2C+zDepth*PlayerCamera[id].PitchS
endmethod
static method RegisterAnyPanelEvent takes code func returns triggercondition
return TriggerAddCondition(EventTrigger, Condition(func))
endmethod
static method UnregisterAnyPanelEvent takes triggercondition tc returns nothing
call TriggerRemoveCondition(EventTrigger, tc)
endmethod
method operator background= takes integer texture returns nothing
if texture != .skin then
call ChangeTexture(.dummy, texture)
set .skin = texture
endif
endmethod
method operator opacity= takes integer i returns nothing
set .op = IMinBJ(IMaxBJ(i, 0), 255)
call SetUnitVertexColor(.dummy, 255, 255, 255, .op)
call fireEvent(EVENT_PANEL_OPACITY_MODIFIED)
endmethod
method operator scale= takes real r returns nothing
set .size = r*GENERAL_SIZE
if .visible then
call SetUnitScale(.dummy, .size, 1, 1)
endif
call fireEvent(EVENT_PANEL_RESCALED)
endmethod
method operator background takes nothing returns integer
return .skin
endmethod
method operator opacity takes nothing returns integer
return .op
endmethod
method operator scale takes nothing returns real
return .size/GENERAL_SIZE
endmethod
method getRelativePos takes real xOffset, real yOffset, real zDepth returns nothing
call Win2World(.pid, .xOffset+xOffset, .yOffset+yOffset, .zDepth+zDepth)
endmethod
method refresh takes nothing returns nothing
if .visible then
call Win2World(.pid, .xOffset, .yOffset, .zDepth)
if ReturnValX > WorldMinX and ReturnValX < WorldMaxX and ReturnValY > WorldMinY and ReturnValY < WorldMaxY then
call SetUnitX(.dummy, ReturnValX)
call SetUnitY(.dummy, ReturnValY)
call SetUnitZ(.dummy, ReturnValZ)
endif
call fireEvent(EVENT_PANEL_REFRESHED)
endif
endmethod
method clear takes nothing returns nothing
call fireEvent(EVENT_PANEL_CLEARED)
endmethod
method destroy takes nothing returns nothing
call fireEvent(EVENT_PANEL_DESTROYED)
call RemoveUnit(.dummy)
call removeNode()
call deallocate()
set .dummy = null
endmethod
method show takes boolean b returns nothing
set .visible = b
if b then
if Locale == p then
call SetUnitScale(.dummy, .size, 1, 1)
else
call SetUnitScale(.dummy, 0, 0, 0)
endif
else
call SetUnitScale(.dummy, 0, 0, 0)
call SetUnitX(.dummy, WorldMaxX)
call SetUnitY(.dummy, WorldMaxY)
endif
call fireEvent(EVENT_PANEL_VISIBILITY_MODIFIED)
endmethod
method move takes real xOffset, real yOffset, real zDepth returns nothing
set .xOffset = xOffset
set .yOffset = yOffset
set .zDepth = -zDepth
endmethod
static method create takes player p, integer id, integer background, real xOffset, real yOffset, real zDepth returns Panel
local thistype this = allocate()
set .p = p
set .pid = GetPlayerId(p)
set .scale = 1
set .opacity = 255
set .dummy = CreateUnit(PASSIVE, id, 0, 0, 0)
set .skin = background
static if not LIBRARY_AutoFly then
if UnitAddAbility(.dummy, 'Amrf') and UnitRemoveAbility(.dummy, 'Amrf') then
endif
endif
call UnitAddAbility(.dummy, 'Aeth')
call UnitAddAbility(.dummy, TEXTURE_REPLACER_ID)
call UnitRemoveAbility(.dummy, 'Amov')
call SetUnitPathing(.dummy, false)
call ChangeTexture(.dummy, background)
call move(xOffset, yOffset, zDepth)
call show(true)
call refresh()
if PanelList[pid] == 0 then
set PanelList[pid] = createNode()
endif
call PanelList[pid].insertNode(this)
return this
endmethod
private static method refreshPanels takes nothing returns boolean
local thistype node = PanelList[PanelCamera.RefreshedCamera.id].next
loop
exitwhen node.head or node == 0
if node.visible then
call node.refresh()
endif
set node = node.next
endloop
return false
endmethod
private static method onInit takes nothing returns nothing
set Locale = GetLocalPlayer()
set WorldMaxX = GetRectMaxX(bj_mapInitialPlayableArea)
set WorldMaxY = GetRectMaxY(bj_mapInitialPlayableArea)
set WorldMinX = GetRectMinX(bj_mapInitialPlayableArea)
set WorldMinY = GetRectMinX(bj_mapInitialPlayableArea)
call PanelCamera.registerRefreshEvent(function thistype.refreshPanels)
endmethod
endstruct
endlibrary
library LinkedListModule /* v2.3.1
Easy implementation of linked lists into structs.
***********************************************************************
*
* module LinkedList
*
* - Implement at the top of your struct, must extend array
*
* thistype next
* thistype prev
* boolean head
*
* readonly static thistype base
* - Precreated head, useful for non-dynamic lists.
*
* static method allocate takes nothing returns thistype
* method deallocate takes nothing returns nothing
*
* static method createNode takes nothing returns thistype
* - Allocates a new node pointing towards itself.
* - These nodes are considered "heads" therefore it's head
* - boolean member is set to true.
* method insertNode takes thistype toInsert returns thistype
* - Inserts the instance before the node.
* method removeNode takes nothing returns nothing
* - Removes the node from the list.
* method clearNode takes nothing returns nothing
* - Deallocates all the instances within the node's range.
* method flushNode takes nothing returns nothing
* - Clears and deallocates the node.
*
* module LinkedListLite
* - Only has the members and the allocation methods.
* - To be used with the provided textmacros.
*
* textmacro LINKED_LIST_HEAD takes node
* - Turns the node into a head.
* textmacro LINKED_LIST_INSERT takes node, toInsert
* - Inserts the instance before the node.
* textmacro LINKED_LIST_REMOVE takes node
* - Removes the node from the list.
* textmacro LINKED_LIST_CLEAR takes node
* - Deallocates all the instances within the node's range.
* textmacro LINKED_LIST_FLUSH takes node
* - Clears and deallocates the node.
* textmacro LINKED_LIST_MERGE takes nodeA, nodeB
* - Merges two lists together (Don't merge loose nodes!)
*
**********************************************************************/
module LinkedListLite
private static integer instanceCount = 0
thistype next
thistype prev
boolean head
static method allocate takes nothing returns thistype
local thistype this = thistype(0).prev
if this==0 then
debug if instanceCount==8190 then
debug call BJDebugMsg("[LinkedList] Error: attempted to allocate too many instances.")
debug return 0
debug endif
set instanceCount = instanceCount+1
return instanceCount
endif
set thistype(0).prev = prev
return this
endmethod
method deallocate takes nothing returns nothing
set this.prev=thistype(0).prev
set thistype(0).prev=this
set this.head=false
endmethod
endmodule
module LinkedList
implement LinkedListLite
static method operator base takes nothing returns thistype
return 8190
endmethod
static method createNode takes nothing returns thistype
local thistype this=allocate()
//! runtextmacro LINKED_LIST_HEAD("this")
return this
endmethod
method clearNode takes nothing returns nothing
//! runtextmacro LINKED_LIST_CLEAR("this")
endmethod
method flushNode takes nothing returns nothing
//! runtextmacro LINKED_LIST_FLUSH("this")
endmethod
method insertNode takes thistype toInsert returns nothing
//! runtextmacro LINKED_LIST_INSERT("this","toInsert")
endmethod
method removeNode takes nothing returns nothing
//! runtextmacro LINKED_LIST_REMOVE("this")
endmethod
private static method onInit takes nothing returns nothing
set thistype(8190).next = 8190
set thistype(8190).prev = 8190
set thistype(8190).head = true
endmethod
static if DEBUG_MODE then
method print takes nothing returns nothing
local string s=""
local thistype exit=this
loop
set s=s+I2S(this)
set this = next
exitwhen this==exit
set s = s+" - "
endloop
call BJDebugMsg("[ "+s+" ]")
endmethod
endif
endmodule
//! textmacro LINKED_LIST_HEAD takes node
set $node$.next = this
set $node$.prev = this
set $node$.head = true
//! endtextmacro
//! textmacro LINKED_LIST_CLEAR takes node
if $node$!=$node$.next then
set $node$.next.prev = thistype(0).prev
set thistype(0).prev = $node$.prev
set $node$.next = $node$
set $node$.prev = $node$
endif
//! endtextmacro
//! textmacro LINKED_LIST_FLUSH takes node
set $node$.next.prev = thistype(0).prev
set thistype(0).prev = $node$
set $node$.head = false
//! endtextmacro
//! textmacro LINKED_LIST_INSERT takes node, toInsert
set $node$.prev.next = $toInsert$
set $toInsert$.prev = $node$.prev
set $node$.prev = $toInsert$
set $toInsert$.next = $node$
//! endtextmacro
//! textmacro LINKED_LIST_REMOVE takes node
set $node$.prev.next = $node$.next
set $node$.next.prev = $node$.prev
//! endtextmacro
//! textmacro LINKED_LIST_MERGE takes nodeA, nodeB
set $nodeA$.next.prev = $nodeB$.prev
set $nodeB$.prev.next = $nodeA$.next
set $nodeA$.next = $nodeB$
set $nodeB$.prev = $nodeA$
//! endtextmacro
endlibrary
library PanelCamera
globals
// Minimum value difference that will be processed by the system
// Must be a positive value
private constant real TOLERANCE = 0.1
// Lower value makes the camera looks smoother but will cause the system
// to work significantly harder
public constant real INTERVAL = 0.03
// Maximum number of rendering level at zero Z Offset
public constant integer LAYER_COUNT = 50
endglobals
globals
public real DeltaZ = 0
public constant real HP = bj_PI/2
public constant real TAU = bj_PI*2
public constant real R270 = bj_PI+HP
public constant real LEVEL_GAP = 0.005
public constant real CAMERA_GAP = 99.975+LEVEL_GAP*LAYER_COUNT
private constant player PASSIVE = Player(PLAYER_NEUTRAL_PASSIVE)
PanelCamera array PlayerCamera
endglobals
private module InitModule
private static method onInit takes nothing returns nothing
call init()
endmethod
endmodule
public function AngularDifference takes real a, real b returns real
return Atan2(Sin(a-b), Cos(a-b))
endfunction
private function AngularDifferenceAbs takes real a, real b returns real
return RAbsBJ(AngularDifference(a, b))
endfunction
struct PanelCamera
readonly real LocX
readonly real LocY
readonly real ZOffset
readonly real TargetDistance
readonly real Rotation
readonly real AngleOfAttack
private real LocXTarget
private real LocYTarget
private real TargetDistanceTarget
private real RotationTarget
private real AngleOfAttackTarget
private real ZOffsetTarget
private real LocXRate
private real LocYRate
private real ZOffsetRate
private real TargetDistanceRate
private real RotationRate
private real AngleOfAttackRate
readonly real EyePosX
readonly real EyePosY
readonly real EyePosZ
readonly real YawC
readonly real YawS
readonly real YawC2
readonly real YawS2
readonly real PitchC
readonly real PitchS
readonly real Pitch2C
readonly real Pitch2S
private boolean updateUI
private boolean updateProjection
private timer time
private unit dummy
readonly player p
readonly integer id
readonly boolean enabled
private static player Locale
readonly static thistype RefreshedCamera = 0
private static trigger EventTrigg = CreateTrigger()
private method updateEyePos takes nothing returns nothing
local real d
local real x = .LocX
local real y = .LocY
local real x2
local real y2
local real cd = .TargetDistance-CAMERA_GAP
local real cz = .ZOffset+DeltaZ
local real yaw
local real pitch
if updateProjection then
set yaw = .Rotation
set pitch = .AngleOfAttack
if pitch < R270 and pitch > HP then
set yaw = bj_PI+yaw
set pitch = bj_PI-pitch
endif
set pitch = (pitch-AngularDifference(pitch, R270)*2)-bj_PI
set YawC = Cos(yaw)
set YawS = Sin(yaw)
set YawC2 = Cos(yaw-HP)
set YawS2 = Sin(yaw-HP)
set PitchC = Cos(pitch)
set PitchS = Sin(pitch)
set pitch = AngularDifference(pitch-HP, R270)
set Pitch2C = Cos(pitch)
set Pitch2S = Sin(pitch)
endif
set d = cd*PitchC
set EyePosX = x-d*YawC
set EyePosY = y-d*YawS
set EyePosZ = cz+cd*PitchS
set RefreshedCamera = this
call TriggerEvaluate(EventTrigg)
set RefreshedCamera = 0
endmethod
method refresh takes nothing returns nothing
if updateUI or updateProjection then
call updateEyePos()
endif
if Locale == .p then
call SetCameraField(CAMERA_FIELD_ROLL, 0, 0)
call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, bj_CAMERA_DEFAULT_FOV, 0)
call SetCameraField(CAMERA_FIELD_ROTATION, Rotation*bj_RADTODEG, 0)
call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, AngleOfAttack*bj_RADTODEG, 0)
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, TargetDistance, 0)
call SetCameraField(CAMERA_FIELD_ZOFFSET, ZOffset, 0)
call SetCameraTargetController(dummy, LocX, LocY, false)
/*if updateUI or updateProjection then
call PanCameraToTimed(LocX, LocY, 0)
else
call PanCameraToTimed(LocX, LocY, 5)
endif*/
endif
endmethod
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetPlayerTechMaxAllowed(PASSIVE, GetHandleId(t))
set updateUI = false
set updateProjection = false
if Rotation != RotationTarget then
if Cos(Rotation-RotationTarget) <= Cos(RotationRate) then
if Sin(RotationTarget-Rotation) >= 0 then
set Rotation = Rotation + RotationRate
else
set Rotation = Rotation - RotationRate
endif
else
set Rotation = RotationTarget
endif
set updateUI = true
set updateProjection = true
endif
if AngleOfAttack != AngleOfAttackTarget then
if Cos(AngleOfAttack-AngleOfAttackTarget) <= Cos(AngleOfAttackRate) then
if Sin(AngleOfAttackTarget-AngleOfAttack) >= 0 then
set AngleOfAttack = AngleOfAttack + AngleOfAttackRate
else
set AngleOfAttack = AngleOfAttack - AngleOfAttackRate
endif
else
set AngleOfAttack = AngleOfAttackTarget
endif
set updateUI = true
set updateProjection = true
endif
if TargetDistance != TargetDistanceTarget then
if RAbsBJ(TargetDistance-TargetDistanceTarget) <= RAbsBJ(TargetDistanceRate) then
set TargetDistance = TargetDistanceTarget
else
set TargetDistance = TargetDistance + TargetDistanceRate
endif
set updateUI = true
set updateProjection = true
endif
if ZOffset != ZOffsetTarget then
if RAbsBJ(ZOffset-ZOffsetTarget) <= RAbsBJ(ZOffsetRate) then
set ZOffset = ZOffsetTarget
else
set ZOffset = ZOffset + ZOffsetRate
endif
set updateUI = true
set updateProjection = true
endif
if LocX != LocXTarget then
if RAbsBJ(LocX-LocXTarget) <= RAbsBJ(LocXRate) then
set LocX = LocXTarget
else
set LocX = LocX + LocXRate
endif
set updateUI = true
endif
if LocY != LocYTarget then
if RAbsBJ(LocY-LocYTarget) <= RAbsBJ(LocYRate) then
set LocY = LocYTarget
else
set LocY = LocY + LocYRate
endif
set updateUI = true
endif
set t = null
endmethod
method move takes real x, real y, real duration returns nothing
local boolean updateX = RAbsBJ(LocX-x) > TOLERANCE
local boolean updateY = RAbsBJ(LocY-y) > TOLERANCE
if updateX or updateY then
if duration <= 0 then
set LocX = x
set LocY = y
set LocXTarget = x
set LocYTarget = y
set updateUI = true
else
if updateX then
set LocXTarget = x
set LocXRate = (x-LocX)/duration*INTERVAL
endif
if updateY then
set LocYTarget = y
set LocYRate = (y-LocY)/duration*INTERVAL
endif
endif
endif
endmethod
method setField takes camerafield whichField, real value, real duration returns nothing
if whichField == CAMERA_FIELD_ROTATION then
if AngularDifferenceAbs(Rotation, value*bj_DEGTORAD) > TOLERANCE*bj_DEGTORAD then
set RotationTarget = value*bj_DEGTORAD
if duration <= 0 then
set Rotation = RotationTarget
set updateProjection = true
else
set RotationRate = AngularDifferenceAbs(Rotation, RotationTarget)/duration*INTERVAL
endif
endif
elseif whichField == CAMERA_FIELD_ANGLE_OF_ATTACK then
if AngularDifferenceAbs(AngleOfAttack, value*bj_DEGTORAD) > TOLERANCE*bj_DEGTORAD then
set AngleOfAttackTarget = value*bj_DEGTORAD
if duration <= 0 then
set AngleOfAttack = AngleOfAttackTarget
set updateProjection = true
else
set AngleOfAttackRate = AngularDifferenceAbs(AngleOfAttack, AngleOfAttackTarget)/duration*INTERVAL
endif
endif
elseif whichField == CAMERA_FIELD_TARGET_DISTANCE then
if RAbsBJ(TargetDistance-value) > TOLERANCE then
set TargetDistanceTarget = value
if duration <= 0 then
set TargetDistance = value
set updateProjection = true
else
set TargetDistanceRate = (value-TargetDistance)/duration*INTERVAL
endif
endif
elseif whichField == CAMERA_FIELD_ZOFFSET then
if RAbsBJ(ZOffset-value) > TOLERANCE then
set ZOffsetTarget = value
if duration <= 0 then
set ZOffset = value
set updateProjection = true
else
set ZOffsetRate = (value-ZOffset)/duration*INTERVAL
endif
endif
endif
endmethod
method applyCameraSetup takes camerasetup whichSetup, boolean doPan, real duration returns nothing
call setField(CAMERA_FIELD_ANGLE_OF_ATTACK, CameraSetupGetField(whichSetup, CAMERA_FIELD_ANGLE_OF_ATTACK), duration)
call setField(CAMERA_FIELD_FARZ, CameraSetupGetField(whichSetup, CAMERA_FIELD_FARZ), duration)
call setField(CAMERA_FIELD_FIELD_OF_VIEW, CameraSetupGetField(whichSetup, CAMERA_FIELD_FIELD_OF_VIEW), duration)
call setField(CAMERA_FIELD_ROLL, CameraSetupGetField(whichSetup, CAMERA_FIELD_ROLL), duration)
call setField(CAMERA_FIELD_ROTATION, CameraSetupGetField(whichSetup, CAMERA_FIELD_ROTATION), duration)
call setField(CAMERA_FIELD_TARGET_DISTANCE, CameraSetupGetField(whichSetup, CAMERA_FIELD_TARGET_DISTANCE), duration)
call setField(CAMERA_FIELD_ZOFFSET, CameraSetupGetField(whichSetup, CAMERA_FIELD_ZOFFSET), duration)
if doPan then
call move(CameraSetupGetDestPositionX(whichSetup), CameraSetupGetDestPositionY(whichSetup), duration)
endif
endmethod
method enable takes boolean b returns nothing
if b != .enabled then
set .enabled = b
if b then
call TimerStart(.time, INTERVAL, true, function thistype.onTick)
else
call PauseTimer(.time)
endif
endif
endmethod
// privatize dtor
private method destroy takes nothing returns nothing
call deallocate()
endmethod
// privatize ctor
private static method create takes player p returns thistype
local thistype this = allocate()
set .p = p
set .id = GetPlayerId(p)
set .time = CreateTimer()
call SetPlayerTechMaxAllowed(PASSIVE, GetHandleId(.time), this)
set .LocX = GetStartLocationX(GetPlayerStartLocation(p))
set .LocY = GetStartLocationY(GetPlayerStartLocation(p))
set .ZOffset = 0
set .TargetDistance = bj_CAMERA_DEFAULT_DISTANCE
set .Rotation = bj_CAMERA_DEFAULT_ROTATION*bj_DEGTORAD
set .AngleOfAttack = bj_CAMERA_DEFAULT_AOA*bj_DEGTORAD
set .LocXTarget = .LocX
set .LocYTarget = .LocY
set .TargetDistanceTarget = .TargetDistance
set .RotationTarget = .Rotation
set .AngleOfAttackTarget = .AngleOfAttack
set .ZOffsetTarget = .ZOffset
set .dummy = CreateUnit(PASSIVE, 'hpea', 0, 0, 0)
call SetUnitPathing(.dummy, false)
call PauseUnit(.dummy, true)
call ShowUnit(.dummy, false)
call SetUnitX(.dummy, 0)
call SetUnitY(.dummy, 0)
call SetCameraTargetController(.dummy, .LocX, .LocY, false)
call enable(true)
return this
endmethod
static method registerRefreshEvent takes code func returns triggercondition
return TriggerAddCondition(EventTrigg, Condition(func))
endmethod
private static method init takes nothing returns nothing
local integer i = 0
call SetCameraPosition(0, 0)
set DeltaZ = GetCameraTargetPositionZ()
set Locale = GetLocalPlayer()
loop
exitwhen i > 11
set PlayerCamera[i] = create(Player(i))
set i = i + 1
endloop
endmethod
implement InitModule
endstruct
endlibrary
library PanelModel requires PanelCore
/*
~ Panel Model Plugin ~
Allows to add model files into panels.
I. How to import:
1. Copy "PanelModel" trigger to your map.
2. Export "PanelModelDummy.mdx" in import manager to your map.
3. Save your map, then close and reopen it.
4. Delete/comment out this line: */
///! external ObjectMerger w3u hfoo hPSD unsf "PanelModelDummy" unam "" umdl "war3mapImported\PanelModelDummy.mdl" ubdg 1 uabi "Aloc" uble 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" uaen "" udea "" umvt "float" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
/* 5. Done.
II. API
struct PanelModel
Members:
boolean transformAxis
- If true, the model's coordinate will be rescaled based on it's parent size
readonly unit dummy
- Model's dummy unit object
readonly real xOffset
readonly real yOffset
- x/y offset of the model
readonly boolean visible
- Model's current visibility state
readonly Panel parent
- Panel that's containing the model
readonly static thistype array List
- A list containing models in a specific Panel
- Takes the desired Panel (parent) instance as index
Methods:
static method create takes Panel parent, string path, real xOffset, real yOffset, integer level returns thistype
- Add a model into a Panel
method operator modelPath= takes string path returns nothing
- Change the model file
method operator level takes nothing returns integer
- Get model's rendering level
method operator scale= takes real r returns nothing
method operator scale takes nothing returns real
- Set/get model size
method refresh takes nothing returns nothing
- Refresh model screen position
method destroy takes nothing returns nothing
- Delete and remove the model from its parents collection
method move takes real xOffset, real yOffset, integer level returns nothing
- Move the model to new screen coordinate
method show takes boolean b returns nothing
- Modify text tag's visibility
*/
////////////////////
// Configurations //
////////////////////
globals
// Billboarded dummy unit dummy ID
private constant integer DUMMY_ID = 'e00V'
// No need to modify
private constant string ATTACH_POINT = "origin"
endglobals
//////////////////
// System codes //
//////////////////
struct PanelModel extends array
implement LinkedList
boolean transformAxis
readonly effect model
readonly unit dummy
readonly real xOffset
readonly real yOffset
private real zOffset
private real size
private boolean pvisible
readonly boolean visible
readonly Panel parent
readonly static thistype array List
method operator modelPath= takes string path returns nothing
call DestroyEffect(.model)
set .model = AddSpecialEffectTarget(path, .dummy, ATTACH_POINT)
endmethod
method operator scale= takes real r returns nothing
set .size = r*PanelCore_GENERAL_SIZE
if .visible and .parent.visible then
if PanelCore_Locale == .parent.p then
call SetUnitScale(.dummy, .size*.parent.scale, 1, 1)
else
call SetUnitScale(.dummy, 0, 0, 0)
endif
endif
endmethod
method operator level takes nothing returns integer
return R2I(.zOffset/PanelCamera_LEVEL_GAP)
endmethod
method operator scale takes nothing returns real
return .size/PanelCore_GENERAL_SIZE
endmethod
method destroy takes nothing returns nothing
call DestroyEffect(.model)
call RemoveUnit(.dummy)
call removeNode()
call deallocate()
set .dummy = null
set .model = null
endmethod
method refresh takes nothing returns nothing
if .visible and .parent.visible then
if .transformAxis then
call .parent.getRelativePos(.xOffset*.parent.scale, .yOffset*.parent.scale, .zOffset)
else
call .parent.getRelativePos(.xOffset, .yOffset, .zOffset)
endif
//if PanelCore_Locale == .parent.p then
if Panel.ReturnValX > PanelCore_WorldMinX and Panel.ReturnValX < PanelCore_WorldMaxX and Panel.ReturnValY > PanelCore_WorldMinY and Panel.ReturnValY < PanelCore_WorldMaxY then
call SetUnitX(.dummy, Panel.ReturnValX)
call SetUnitY(.dummy, Panel.ReturnValY)
call PanelCore_SetUnitZ(.dummy, Panel.ReturnValZ)
endif
//endif
endif
endmethod
method move takes real xOffset, real yOffset, integer level returns nothing
set .xOffset = xOffset
set .yOffset = yOffset
set .zOffset = PanelCamera_LEVEL_GAP*level
endmethod
method show takes boolean b returns nothing
if b != .visible then
set .visible = b
if b and .parent.visible then
if PanelCore_Locale == .parent.p then
call SetUnitScale(.dummy, .size*.parent.scale, 1, 1)
else
call SetUnitScale(.dummy, 0, 0, 0)
endif
else
call SetUnitScale(.dummy, 0, 0, 0)
call SetUnitX(.dummy, PanelCore_WorldMaxX)
call SetUnitY(.dummy, PanelCore_WorldMaxY)
endif
endif
endmethod
static method create takes Panel parent, string path, real xOffset, real yOffset, integer level returns thistype
local thistype this = allocate()
set .parent = parent
set .scale = 1
set .visible = false
set .dummy = CreateUnit(PanelCore_PASSIVE, DUMMY_ID, 0, 0, 0)
set .model = AddSpecialEffectTarget(path, .dummy, ATTACH_POINT)
set .transformAxis = true
static if not LIBRARY_AutoFly then
if UnitAddAbility(.dummy, 'Amrf') and UnitRemoveAbility(.dummy, 'Amrf') then
endif
endif
call UnitAddAbility(.dummy, 'Aeth')
call UnitRemoveAbility(.dummy, 'Amov')
call SetUnitPathing(.dummy, false)
call move(xOffset, yOffset, level)
call show(true)
//call refresh()
if List[parent] == 0 then
set List[parent] = createNode()
endif
call List[parent].insertNode(this)
return this
endmethod
private static method onPanelEvent takes nothing returns boolean
local thistype node
if List[Panel.TriggeringPanel] != 0 then
set node = List[Panel.TriggeringPanel].next
loop
exitwhen node.head or node == 0
if Panel.EventType == Panel.EVENT_PANEL_REFRESHED then
call node.refresh()
elseif Panel.EventType == Panel.EVENT_PANEL_RESCALED then
if node.visible and node.parent.visible then
call SetUnitScale(node.dummy, node.size*node.parent.scale, 1, 1)
endif
elseif Panel.EventType == Panel.EVENT_PANEL_CLEARED or Panel.EventType == Panel.EVENT_PANEL_DESTROYED then
call node.destroy()
elseif Panel.EventType == Panel.EVENT_PANEL_VISIBILITY_MODIFIED then
if node.visible and node.parent.visible then
if PanelCore_Locale == node.parent.p then
call SetUnitScale(node.dummy, node.size*node.parent.scale, 1, 1)
else
call SetUnitScale(node.dummy, 0, 0, 0)
endif
else
call SetUnitScale(node.dummy, 0, 0, 0)
call SetUnitX(node.dummy, PanelCore_WorldMaxX)
call SetUnitY(node.dummy, PanelCore_WorldMaxY)
endif
endif
set node = node.next
endloop
if Panel.EventType == Panel.EVENT_PANEL_DESTROYED and List[Panel.TriggeringPanel] != 0 then
call List[Panel.TriggeringPanel].flushNode()
set List[Panel.TriggeringPanel] = 0
endif
endif
return false
endmethod
private static method onInit takes nothing returns nothing
call Panel.RegisterAnyPanelEvent(function thistype.onPanelEvent)
endmethod
endstruct
endlibrary
library PanelModel requires PanelCore
/*
~ Panel Model Plugin ~
Allows to add model files into panels.
I. How to import:
1. Copy "PanelModel" trigger to your map.
2. Export "PanelModelDummy.mdx" in import manager to your map.
3. Save your map, then close and reopen it.
4. Delete/comment out this line: */
///! external ObjectMerger w3u hfoo hPSD unsf "PanelModelDummy" unam "" umdl "war3mapImported\PanelModelDummy.mdl" ubdg 1 uabi "Aloc" uble 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" uaen "" udea "" umvt "float" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
/* 5. Done.
II. API
struct PanelModel
Members:
boolean transformAxis
- If true, the model's coordinate will be rescaled based on it's parent size
readonly unit dummy
- Model's dummy unit object
readonly real xOffset
readonly real yOffset
- x/y offset of the model
readonly boolean visible
- Model's current visibility state
readonly Panel parent
- Panel that's containing the model
readonly static thistype array List
- A list containing models in a specific Panel
- Takes the desired Panel (parent) instance as index
Methods:
static method create takes Panel parent, string path, real xOffset, real yOffset, integer level returns thistype
- Add a model into a Panel
method operator modelPath= takes string path returns nothing
- Change the model file
method operator level takes nothing returns integer
- Get model's rendering level
method operator scale= takes real r returns nothing
method operator scale takes nothing returns real
- Set/get model size
method refresh takes nothing returns nothing
- Refresh model screen position
method destroy takes nothing returns nothing
- Delete and remove the model from its parents collection
method move takes real xOffset, real yOffset, integer level returns nothing
- Move the model to new screen coordinate
method show takes boolean b returns nothing
- Modify text tag's visibility
*/
////////////////////
// Configurations //
////////////////////
globals
// Billboarded dummy unit dummy ID
private constant integer DUMMY_ID = 'e00V'
// No need to modify
private constant string ATTACH_POINT = "origin"
endglobals
//////////////////
// System codes //
//////////////////
struct PanelModel extends array
implement LinkedList
boolean transformAxis
readonly effect model
readonly unit dummy
readonly real xOffset
readonly real yOffset
private real zOffset
private real size
private boolean pvisible
readonly boolean visible
readonly Panel parent
readonly static thistype array List
method operator modelPath= takes string path returns nothing
call DestroyEffect(.model)
set .model = AddSpecialEffectTarget(path, .dummy, ATTACH_POINT)
endmethod
method operator scale= takes real r returns nothing
set .size = r*PanelCore_GENERAL_SIZE
if .visible and .parent.visible then
if PanelCore_Locale == .parent.p then
call SetUnitScale(.dummy, .size*.parent.scale, 1, 1)
else
call SetUnitScale(.dummy, 0, 0, 0)
endif
endif
endmethod
method operator level takes nothing returns integer
return R2I(.zOffset/PanelCamera_LEVEL_GAP)
endmethod
method operator scale takes nothing returns real
return .size/PanelCore_GENERAL_SIZE
endmethod
method destroy takes nothing returns nothing
call DestroyEffect(.model)
call RemoveUnit(.dummy)
call removeNode()
call deallocate()
set .dummy = null
set .model = null
endmethod
method refresh takes nothing returns nothing
if .visible and .parent.visible then
if .transformAxis then
call .parent.getRelativePos(.xOffset*.parent.scale, .yOffset*.parent.scale, .zOffset)
else
call .parent.getRelativePos(.xOffset, .yOffset, .zOffset)
endif
//if PanelCore_Locale == .parent.p then
if Panel.ReturnValX > PanelCore_WorldMinX and Panel.ReturnValX < PanelCore_WorldMaxX and Panel.ReturnValY > PanelCore_WorldMinY and Panel.ReturnValY < PanelCore_WorldMaxY then
call SetUnitX(.dummy, Panel.ReturnValX)
call SetUnitY(.dummy, Panel.ReturnValY)
call PanelCore_SetUnitZ(.dummy, Panel.ReturnValZ)
endif
//endif
endif
endmethod
method move takes real xOffset, real yOffset, integer level returns nothing
set .xOffset = xOffset
set .yOffset = yOffset
set .zOffset = PanelCamera_LEVEL_GAP*level
endmethod
method show takes boolean b returns nothing
if b != .visible then
set .visible = b
if b and .parent.visible then
if PanelCore_Locale == .parent.p then
call SetUnitScale(.dummy, .size*.parent.scale, 1, 1)
else
call SetUnitScale(.dummy, 0, 0, 0)
endif
else
call SetUnitScale(.dummy, 0, 0, 0)
call SetUnitX(.dummy, PanelCore_WorldMaxX)
call SetUnitY(.dummy, PanelCore_WorldMaxY)
endif
endif
endmethod
static method create takes Panel parent, string path, real xOffset, real yOffset, integer level returns thistype
local thistype this = allocate()
set .parent = parent
set .scale = 1
set .visible = false
set .dummy = CreateUnit(PanelCore_PASSIVE, DUMMY_ID, 0, 0, 0)
set .model = AddSpecialEffectTarget(path, .dummy, ATTACH_POINT)
set .transformAxis = true
static if not LIBRARY_AutoFly then
if UnitAddAbility(.dummy, 'Amrf') and UnitRemoveAbility(.dummy, 'Amrf') then
endif
endif
call UnitAddAbility(.dummy, 'Aeth')
call UnitRemoveAbility(.dummy, 'Amov')
call SetUnitPathing(.dummy, false)
call move(xOffset, yOffset, level)
call show(true)
//call refresh()
if List[parent] == 0 then
set List[parent] = createNode()
endif
call List[parent].insertNode(this)
return this
endmethod
private static method onPanelEvent takes nothing returns boolean
local thistype node
if List[Panel.TriggeringPanel] != 0 then
set node = List[Panel.TriggeringPanel].next
loop
exitwhen node.head or node == 0
if Panel.EventType == Panel.EVENT_PANEL_REFRESHED then
call node.refresh()
elseif Panel.EventType == Panel.EVENT_PANEL_RESCALED then
if node.visible and node.parent.visible then
call SetUnitScale(node.dummy, node.size*node.parent.scale, 1, 1)
endif
elseif Panel.EventType == Panel.EVENT_PANEL_CLEARED or Panel.EventType == Panel.EVENT_PANEL_DESTROYED then
call node.destroy()
elseif Panel.EventType == Panel.EVENT_PANEL_VISIBILITY_MODIFIED then
if node.visible and node.parent.visible then
if PanelCore_Locale == node.parent.p then
call SetUnitScale(node.dummy, node.size*node.parent.scale, 1, 1)
else
call SetUnitScale(node.dummy, 0, 0, 0)
endif
else
call SetUnitScale(node.dummy, 0, 0, 0)
call SetUnitX(node.dummy, PanelCore_WorldMaxX)
call SetUnitY(node.dummy, PanelCore_WorldMaxY)
endif
endif
set node = node.next
endloop
if Panel.EventType == Panel.EVENT_PANEL_DESTROYED and List[Panel.TriggeringPanel] != 0 then
call List[Panel.TriggeringPanel].flushNode()
set List[Panel.TriggeringPanel] = 0
endif
endif
return false
endmethod
private static method onInit takes nothing returns nothing
call Panel.RegisterAnyPanelEvent(function thistype.onPanelEvent)
endmethod
endstruct
endlibrary
library PanelModel requires PanelCore
/*
~ Panel Model Plugin ~
Allows to add model files into panels.
I. How to import:
1. Copy "PanelModel" trigger to your map.
2. Export "PanelModelDummy.mdx" in import manager to your map.
3. Save your map, then close and reopen it.
4. Delete/comment out this line: */
///! external ObjectMerger w3u hfoo hPSD unsf "PanelModelDummy" unam "" umdl "war3mapImported\PanelModelDummy.mdl" ubdg 1 uabi "Aloc" uble 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" uaen "" udea "" umvt "float" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
/* 5. Done.
II. API
struct PanelModel
Members:
boolean transformAxis
- If true, the model's coordinate will be rescaled based on it's parent size
readonly unit dummy
- Model's dummy unit object
readonly real xOffset
readonly real yOffset
- x/y offset of the model
readonly boolean visible
- Model's current visibility state
readonly Panel parent
- Panel that's containing the model
readonly static thistype array List
- A list containing models in a specific Panel
- Takes the desired Panel (parent) instance as index
Methods:
static method create takes Panel parent, string path, real xOffset, real yOffset, integer level returns thistype
- Add a model into a Panel
method operator modelPath= takes string path returns nothing
- Change the model file
method operator level takes nothing returns integer
- Get model's rendering level
method operator scale= takes real r returns nothing
method operator scale takes nothing returns real
- Set/get model size
method refresh takes nothing returns nothing
- Refresh model screen position
method destroy takes nothing returns nothing
- Delete and remove the model from its parents collection
method move takes real xOffset, real yOffset, integer level returns nothing
- Move the model to new screen coordinate
method show takes boolean b returns nothing
- Modify text tag's visibility
*/
////////////////////
// Configurations //
////////////////////
globals
// Billboarded dummy unit dummy ID
private constant integer DUMMY_ID = 'e00V'
// No need to modify
private constant string ATTACH_POINT = "origin"
endglobals
//////////////////
// System codes //
//////////////////
struct PanelModel extends array
implement LinkedList
boolean transformAxis
readonly effect model
readonly unit dummy
readonly real xOffset
readonly real yOffset
private real zOffset
private real size
private boolean pvisible
readonly boolean visible
readonly Panel parent
readonly static thistype array List
method operator modelPath= takes string path returns nothing
call DestroyEffect(.model)
set .model = AddSpecialEffectTarget(path, .dummy, ATTACH_POINT)
endmethod
method operator scale= takes real r returns nothing
set .size = r*PanelCore_GENERAL_SIZE
if .visible and .parent.visible then
if PanelCore_Locale == .parent.p then
call SetUnitScale(.dummy, .size*.parent.scale, 1, 1)
else
call SetUnitScale(.dummy, 0, 0, 0)
endif
endif
endmethod
method operator level takes nothing returns integer
return R2I(.zOffset/PanelCamera_LEVEL_GAP)
endmethod
method operator scale takes nothing returns real
return .size/PanelCore_GENERAL_SIZE
endmethod
method destroy takes nothing returns nothing
call DestroyEffect(.model)
call RemoveUnit(.dummy)
call removeNode()
call deallocate()
set .dummy = null
set .model = null
endmethod
method refresh takes nothing returns nothing
if .visible and .parent.visible then
if .transformAxis then
call .parent.getRelativePos(.xOffset*.parent.scale, .yOffset*.parent.scale, .zOffset)
else
call .parent.getRelativePos(.xOffset, .yOffset, .zOffset)
endif
//if PanelCore_Locale == .parent.p then
if Panel.ReturnValX > PanelCore_WorldMinX and Panel.ReturnValX < PanelCore_WorldMaxX and Panel.ReturnValY > PanelCore_WorldMinY and Panel.ReturnValY < PanelCore_WorldMaxY then
call SetUnitX(.dummy, Panel.ReturnValX)
call SetUnitY(.dummy, Panel.ReturnValY)
call PanelCore_SetUnitZ(.dummy, Panel.ReturnValZ)
endif
//endif
endif
endmethod
method move takes real xOffset, real yOffset, integer level returns nothing
set .xOffset = xOffset
set .yOffset = yOffset
set .zOffset = PanelCamera_LEVEL_GAP*level
endmethod
method show takes boolean b returns nothing
set .visible = b
if b and .parent.visible then
if PanelCore_Locale == .parent.p then
call SetUnitScale(.dummy, .size*.parent.scale, 1, 1)
call ShowUnit(.dummy, true)
else
call SetUnitScale(.dummy, 0, 0, 0)
call ShowUnit(.dummy, false)
endif
else
call SetUnitScale(.dummy, 0, 0, 0)
call SetUnitX(.dummy, PanelCore_WorldMaxX)
call SetUnitY(.dummy, PanelCore_WorldMaxY)
call ShowUnit(.dummy, false)
endif
endmethod
static method create takes Panel parent, string path, real xOffset, real yOffset, integer level returns thistype
local thistype this = allocate()
set .parent = parent
set .scale = 1
set .visible = false
set .dummy = CreateUnit(PanelCore_PASSIVE, DUMMY_ID, 0, 0, 0)
set .model = AddSpecialEffectTarget(path, .dummy, ATTACH_POINT)
set .transformAxis = true
static if not LIBRARY_AutoFly then
if UnitAddAbility(.dummy, 'Amrf') and UnitRemoveAbility(.dummy, 'Amrf') then
endif
endif
call UnitAddAbility(.dummy, 'Aeth')
call UnitRemoveAbility(.dummy, 'Amov')
call SetUnitPathing(.dummy, false)
call move(xOffset, yOffset, level)
call show(true)
//call refresh()
if List[parent] == 0 then
set List[parent] = createNode()
endif
call List[parent].insertNode(this)
return this
endmethod
private static method onPanelEvent takes nothing returns boolean
local thistype node
if List[Panel.TriggeringPanel] != 0 then
set node = List[Panel.TriggeringPanel].next
loop
exitwhen node.head or node == 0
if Panel.EventType == Panel.EVENT_PANEL_REFRESHED then
call node.refresh()
elseif Panel.EventType == Panel.EVENT_PANEL_RESCALED then
set node.scale = node.scale
elseif Panel.EventType == Panel.EVENT_PANEL_CLEARED or Panel.EventType == Panel.EVENT_PANEL_DESTROYED then
call node.destroy()
elseif Panel.EventType == Panel.EVENT_PANEL_VISIBILITY_MODIFIED then
call node.show(node.visible)
endif
set node = node.next
endloop
if Panel.EventType == Panel.EVENT_PANEL_DESTROYED and List[Panel.TriggeringPanel] != 0 then
call List[Panel.TriggeringPanel].flushNode()
set List[Panel.TriggeringPanel] = 0
endif
endif
return false
endmethod
private static method onInit takes nothing returns nothing
call Panel.RegisterAnyPanelEvent(function thistype.onPanelEvent)
endmethod
endstruct
endlibrary
library PanelPlatform requires PanelCore
/*
~ Panel Platform Plugin ~
Allows to add platform objects into panels.
I. How to import:
1. Copy "PanelPlatform" trigger to your map.
2. Done.
II. API
struct PanelPlatform
Members:
boolean transformAxis
- If true, the platform's coordinate will be rescaled based on it's parent size
readonly unit dummy
- Platform's dummy unit object
readonly real xOffset
readonly real yOffset
- x/y offset of the platform
readonly integer red
readonly integer green
readonly integer blue
readonly integer alpha
- Platform's color channels
readonly boolean visible
- Platform's visibility state
readonly Panel parent
- Panel that's containing the platform
readonly static thistype array List
- A list containing platforms in a specific Panel
- Takes the desired Panel (parent) instance as index
Methods:
static method create takes Panel parent, integer id, integer texture, real xOffset, real yOffset, integer level returns thistype
- Add a platform into a Panel
method operator texture= takes integer i returns nothing
- Change the platform texture
method operator level takes nothing returns integer
- Get platform's rendering level
method operator scale= takes real r returns nothing
method operator scale takes nothing returns real
- Get/set platform's size
method refresh takes nothing returns nothing
- Refresh platform screen position
method destroy takes nothing returns nothing
- Delete and remove the model from its parents collection
method move takes real xOffset, real yOffset returns nothing
- Move the platform to a new screen coordinate
method show takes boolean b returns nothing
- Modify platform's visibility state
method setColor takes integer r, integer g, integer b, integer a returns nothing
- Modify platform's vertex colors
*/
//////////////////
// System codes //
//////////////////
struct PanelPlatform extends array
implement LinkedList
boolean transformAxis
readonly unit dummy
readonly real xOffset
readonly real yOffset
private real zOffset
private real size
readonly integer red
readonly integer green
readonly integer blue
readonly integer alpha
private integer skin
readonly boolean visible
readonly Panel parent
readonly static thistype array List
method operator texture= takes integer i returns nothing
if i != .skin then
set .skin = i
call PanelCore_ChangeTexture(.dummy, i)
endif
endmethod
method operator scale= takes real r returns nothing
set .size = r*PanelCore_GENERAL_SIZE
if .visible and .parent.visible then
if PanelCore_Locale == .parent.p then
call SetUnitScale(.dummy, .size*.parent.scale, 1, 1)
else
call SetUnitScale(.dummy, 0, 0, 0)
endif
endif
endmethod
method operator texture takes nothing returns integer
return .skin
endmethod
method operator level takes nothing returns integer
return R2I(.zOffset/PanelCamera_LEVEL_GAP)
endmethod
method operator scale takes nothing returns real
return .size/PanelCore_GENERAL_SIZE
endmethod
method destroy takes nothing returns nothing
call RemoveUnit(.dummy)
call removeNode()
call deallocate()
set .dummy = null
endmethod
method refresh takes nothing returns nothing
if .visible and .parent.visible then
if .transformAxis then
call .parent.getRelativePos(.xOffset*.parent.scale, .yOffset*.parent.scale, .zOffset)
else
call .parent.getRelativePos(.xOffset, .yOffset, .zOffset)
endif
//if PanelCore_Locale == .parent.p then
if Panel.ReturnValX > PanelCore_WorldMinX and Panel.ReturnValX < PanelCore_WorldMaxX and Panel.ReturnValY > PanelCore_WorldMinY and Panel.ReturnValY < PanelCore_WorldMaxY then
call SetUnitX(.dummy, Panel.ReturnValX)
call SetUnitY(.dummy, Panel.ReturnValY)
call PanelCore_SetUnitZ(.dummy, Panel.ReturnValZ)
endif
//endif
endif
endmethod
method move takes real xOffset, real yOffset, integer level returns nothing
set .xOffset = xOffset
set .yOffset = yOffset
set .zOffset = PanelCamera_LEVEL_GAP*level
endmethod
method setColor takes integer r, integer g, integer b, integer a returns nothing
set .red = IMinBJ(IMaxBJ(r, 0), 255)
set .green = IMinBJ(IMaxBJ(g, 0), 255)
set .blue = IMinBJ(IMaxBJ(b, 0), 255)
set .alpha = IMinBJ(IMaxBJ(a, 0), 255)
call SetUnitVertexColor(.dummy, .red, .green, .blue, R2I(.alpha*.parent.opacity/255.))
endmethod
method show takes boolean b returns nothing
if b != .visible then
set .visible = b
if b and .parent.visible then
if PanelCore_Locale == .parent.p then
call SetUnitScale(.dummy, .size*.parent.scale, 1, 1)
else
call SetUnitScale(.dummy, 0, 0, 0)
endif
else
call SetUnitScale(.dummy, 0, 0, 0)
call SetUnitX(.dummy, PanelCore_WorldMaxX)
call SetUnitY(.dummy, PanelCore_WorldMaxY)
endif
endif
endmethod
static method create takes Panel parent, integer id, integer texture, real xOffset, real yOffset, integer level returns thistype
local thistype this = allocate()
set .parent = parent
set .scale = 1
set .visible = false
set .dummy = CreateUnit(PanelCore_PASSIVE, id, 0, 0, 0)
set .skin = texture
set .transformAxis = true
static if not LIBRARY_AutoFly then
if UnitAddAbility(.dummy, 'Amrf') and UnitRemoveAbility(.dummy, 'Amrf') then
endif
endif
call UnitAddAbility(.dummy, 'Aeth')
call UnitAddAbility(.dummy, PanelCore_TEXTURE_REPLACER_ID)
call UnitRemoveAbility(.dummy, 'Amov')
call SetUnitPathing(.dummy, false)
call setColor(255, 255, 255, 255)
call PanelCore_ChangeTexture(.dummy, texture)
call move(xOffset, yOffset, level)
call show(true)
//call refresh()
if List[parent] == 0 then
set List[parent] = createNode()
endif
call List[parent].insertNode(this)
return this
endmethod
private static method onPanelEvent takes nothing returns boolean
local thistype node
if List[Panel.TriggeringPanel] != 0 then
set node = List[Panel.TriggeringPanel].next
loop
exitwhen node.head or node == 0
if Panel.EventType == Panel.EVENT_PANEL_REFRESHED then
call node.refresh()
elseif Panel.EventType == Panel.EVENT_PANEL_RESCALED then
if node.visible and node.parent.visible then
call SetUnitScale(node.dummy, node.size*node.parent.scale, 1, 1)
endif
elseif Panel.EventType == Panel.EVENT_PANEL_CLEARED or Panel.EventType == Panel.EVENT_PANEL_DESTROYED then
call node.destroy()
elseif Panel.EventType == Panel.EVENT_PANEL_VISIBILITY_MODIFIED then
if node.visible and node.parent.visible then
if PanelCore_Locale == node.parent.p then
call SetUnitScale(node.dummy, node.size*node.parent.scale, 1, 1)
else
call SetUnitScale(node.dummy, 0, 0, 0)
endif
else
call SetUnitScale(node.dummy, 0, 0, 0)
call SetUnitX(node.dummy, PanelCore_WorldMaxX)
call SetUnitY(node.dummy, PanelCore_WorldMaxY)
endif
elseif Panel.EventType == Panel.EVENT_PANEL_OPACITY_MODIFIED then
call node.setColor(node.red, node.green, node.blue, R2I(node.alpha*node.parent.opacity/255.))
endif
set node = node.next
endloop
if Panel.EventType == Panel.EVENT_PANEL_DESTROYED and List[Panel.TriggeringPanel] != 0 then
call List[Panel.TriggeringPanel].flushNode()
set List[Panel.TriggeringPanel] = 0
endif
endif
return false
endmethod
private static method onInit takes nothing returns nothing
call Panel.RegisterAnyPanelEvent(function thistype.onPanelEvent)
endmethod
endstruct
endlibrary
library PanelPlatform requires PanelCore
/*
~ Panel Platform Plugin ~
Allows to add platform objects into panels.
I. How to import:
1. Copy "PanelPlatform" trigger to your map.
2. Done.
II. API
struct PanelPlatform
Members:
boolean transformAxis
- If true, the platform's coordinate will be rescaled based on it's parent size
readonly unit dummy
- Platform's dummy unit object
readonly real xOffset
readonly real yOffset
- x/y offset of the platform
readonly integer red
readonly integer green
readonly integer blue
readonly integer alpha
- Platform's color channels
readonly boolean visible
- Platform's visibility state
readonly Panel parent
- Panel that's containing the platform
readonly static thistype array List
- A list containing platforms in a specific Panel
- Takes the desired Panel (parent) instance as index
Methods:
static method create takes Panel parent, integer id, integer texture, real xOffset, real yOffset, integer level returns thistype
- Add a platform into a Panel
method operator texture= takes integer i returns nothing
- Change the platform texture
method operator level takes nothing returns integer
- Get platform's rendering level
method operator scale= takes real r returns nothing
method operator scale takes nothing returns real
- Get/set platform's size
method refresh takes nothing returns nothing
- Refresh platform screen position
method destroy takes nothing returns nothing
- Delete and remove the model from its parents collection
method move takes real xOffset, real yOffset returns nothing
- Move the platform to a new screen coordinate
method show takes boolean b returns nothing
- Modify platform's visibility state
method setColor takes integer r, integer g, integer b, integer a returns nothing
- Modify platform's vertex colors
*/
//////////////////
// System codes //
//////////////////
struct PanelPlatform extends array
implement LinkedList
boolean transformAxis
readonly unit dummy
readonly real xOffset
readonly real yOffset
private real zOffset
private real size
readonly integer red
readonly integer green
readonly integer blue
readonly integer alpha
private integer skin
readonly boolean visible
readonly Panel parent
readonly static thistype array List
method operator texture= takes integer i returns nothing
if i != .skin then
set .skin = i
call PanelCore_ChangeTexture(.dummy, i)
endif
endmethod
method operator scale= takes real r returns nothing
set .size = r*PanelCore_GENERAL_SIZE
if .visible and .parent.visible then
if PanelCore_Locale == .parent.p then
call SetUnitScale(.dummy, .size*.parent.scale, 1, 1)
else
call SetUnitScale(.dummy, 0, 0, 0)
endif
endif
endmethod
method operator texture takes nothing returns integer
return .skin
endmethod
method operator level takes nothing returns integer
return R2I(.zOffset/PanelCamera_LEVEL_GAP)
endmethod
method operator scale takes nothing returns real
return .size/PanelCore_GENERAL_SIZE
endmethod
method destroy takes nothing returns nothing
call RemoveUnit(.dummy)
call removeNode()
call deallocate()
set .dummy = null
endmethod
method refresh takes nothing returns nothing
if .visible and .parent.visible then
if .transformAxis then
call .parent.getRelativePos(.xOffset*.parent.scale, .yOffset*.parent.scale, .zOffset)
else
call .parent.getRelativePos(.xOffset, .yOffset, .zOffset)
endif
//if PanelCore_Locale == .parent.p then
if Panel.ReturnValX > PanelCore_WorldMinX and Panel.ReturnValX < PanelCore_WorldMaxX and Panel.ReturnValY > PanelCore_WorldMinY and Panel.ReturnValY < PanelCore_WorldMaxY then
call SetUnitX(.dummy, Panel.ReturnValX)
call SetUnitY(.dummy, Panel.ReturnValY)
call PanelCore_SetUnitZ(.dummy, Panel.ReturnValZ)
endif
//endif
endif
endmethod
method move takes real xOffset, real yOffset, integer level returns nothing
set .xOffset = xOffset
set .yOffset = yOffset
set .zOffset = PanelCamera_LEVEL_GAP*level
endmethod
method setColor takes integer r, integer g, integer b, integer a returns nothing
set .red = IMinBJ(IMaxBJ(r, 0), 255)
set .green = IMinBJ(IMaxBJ(g, 0), 255)
set .blue = IMinBJ(IMaxBJ(b, 0), 255)
set .alpha = IMinBJ(IMaxBJ(a, 0), 255)
call SetUnitVertexColor(.dummy, .red, .green, .blue, R2I(.alpha*.parent.opacity/255.))
endmethod
method show takes boolean b returns nothing
if b != .visible then
set .visible = b
if b and .parent.visible then
if PanelCore_Locale == .parent.p then
call SetUnitScale(.dummy, .size*.parent.scale, 1, 1)
else
call SetUnitScale(.dummy, 0, 0, 0)
endif
else
call SetUnitScale(.dummy, 0, 0, 0)
call SetUnitX(.dummy, PanelCore_WorldMaxX)
call SetUnitY(.dummy, PanelCore_WorldMaxY)
endif
endif
endmethod
static method create takes Panel parent, integer id, integer texture, real xOffset, real yOffset, integer level returns thistype
local thistype this = allocate()
set .parent = parent
set .scale = 1
set .visible = false
set .dummy = CreateUnit(PanelCore_PASSIVE, id, 0, 0, 0)
set .skin = texture
set .transformAxis = true
static if not LIBRARY_AutoFly then
if UnitAddAbility(.dummy, 'Amrf') and UnitRemoveAbility(.dummy, 'Amrf') then
endif
endif
call UnitAddAbility(.dummy, 'Aeth')
call UnitAddAbility(.dummy, PanelCore_TEXTURE_REPLACER_ID)
call UnitRemoveAbility(.dummy, 'Amov')
call SetUnitPathing(.dummy, false)
call setColor(255, 255, 255, 255)
call PanelCore_ChangeTexture(.dummy, texture)
call move(xOffset, yOffset, level)
call show(true)
//call refresh()
if List[parent] == 0 then
set List[parent] = createNode()
endif
call List[parent].insertNode(this)
return this
endmethod
private static method onPanelEvent takes nothing returns boolean
local thistype node
if List[Panel.TriggeringPanel] != 0 then
set node = List[Panel.TriggeringPanel].next
loop
exitwhen node.head or node == 0
if Panel.EventType == Panel.EVENT_PANEL_REFRESHED then
call node.refresh()
elseif Panel.EventType == Panel.EVENT_PANEL_RESCALED then
if node.visible and node.parent.visible then
call SetUnitScale(node.dummy, node.size*node.parent.scale, 1, 1)
endif
elseif Panel.EventType == Panel.EVENT_PANEL_CLEARED or Panel.EventType == Panel.EVENT_PANEL_DESTROYED then
call node.destroy()
elseif Panel.EventType == Panel.EVENT_PANEL_VISIBILITY_MODIFIED then
if node.visible and node.parent.visible then
if PanelCore_Locale == node.parent.p then
call SetUnitScale(node.dummy, node.size*node.parent.scale, 1, 1)
else
call SetUnitScale(node.dummy, 0, 0, 0)
endif
else
call SetUnitScale(node.dummy, 0, 0, 0)
call SetUnitX(node.dummy, PanelCore_WorldMaxX)
call SetUnitY(node.dummy, PanelCore_WorldMaxY)
endif
elseif Panel.EventType == Panel.EVENT_PANEL_OPACITY_MODIFIED then
call node.setColor(node.red, node.green, node.blue, R2I(node.alpha*node.parent.opacity/255.))
endif
set node = node.next
endloop
if Panel.EventType == Panel.EVENT_PANEL_DESTROYED and List[Panel.TriggeringPanel] != 0 then
call List[Panel.TriggeringPanel].flushNode()
set List[Panel.TriggeringPanel] = 0
endif
endif
return false
endmethod
private static method onInit takes nothing returns nothing
call Panel.RegisterAnyPanelEvent(function thistype.onPanelEvent)
endmethod
endstruct
endlibrary
library PanelPlatform requires PanelCore
/*
~ Panel Platform Plugin ~
Allows to add platform objects into panels.
I. How to import:
1. Copy "PanelPlatform" trigger to your map.
2. Done.
II. API
struct PanelPlatform
Members:
boolean transformAxis
- If true, the platform's coordinate will be rescaled based on it's parent size
readonly unit dummy
- Platform's dummy unit object
readonly real xOffset
readonly real yOffset
- x/y offset of the platform
readonly integer red
readonly integer green
readonly integer blue
readonly integer alpha
- Platform's color channels
readonly boolean visible
- Platform's visibility state
readonly Panel parent
- Panel that's containing the platform
readonly static thistype array List
- A list containing platforms in a specific Panel
- Takes the desired Panel (parent) instance as index
Methods:
static method create takes Panel parent, integer id, integer texture, real xOffset, real yOffset, integer level returns thistype
- Add a platform into a Panel
method operator texture= takes integer i returns nothing
- Change the platform texture
method operator level takes nothing returns integer
- Get platform's rendering level
method operator scale= takes real r returns nothing
method operator scale takes nothing returns real
- Get/set platform's size
method refresh takes nothing returns nothing
- Refresh platform screen position
method destroy takes nothing returns nothing
- Delete and remove the model from its parents collection
method move takes real xOffset, real yOffset returns nothing
- Move the platform to a new screen coordinate
method show takes boolean b returns nothing
- Modify platform's visibility state
method setColor takes integer r, integer g, integer b, integer a returns nothing
- Modify platform's vertex colors
*/
//////////////////
// System codes //
//////////////////
struct PanelPlatform extends array
implement LinkedList
boolean transformAxis
readonly unit dummy
readonly real xOffset
readonly real yOffset
private real zOffset
private real size
readonly integer red
readonly integer green
readonly integer blue
readonly integer alpha
private integer skin
readonly boolean visible
readonly Panel parent
readonly static thistype array List
method operator texture= takes integer i returns nothing
if i != .skin then
set .skin = i
call PanelCore_ChangeTexture(.dummy, i)
endif
endmethod
method operator scale= takes real r returns nothing
set .size = r*PanelCore_GENERAL_SIZE
if .visible and .parent.visible then
if PanelCore_Locale == .parent.p then
call SetUnitScale(.dummy, .size*.parent.scale, 1, 1)
else
call SetUnitScale(.dummy, 0, 0, 0)
endif
endif
endmethod
method operator texture takes nothing returns integer
return .skin
endmethod
method operator level takes nothing returns integer
return R2I(.zOffset/PanelCamera_LEVEL_GAP)
endmethod
method operator scale takes nothing returns real
return .size/PanelCore_GENERAL_SIZE
endmethod
method destroy takes nothing returns nothing
call RemoveUnit(.dummy)
call removeNode()
call deallocate()
set .dummy = null
endmethod
method refresh takes nothing returns nothing
if .visible and .parent.visible then
if .transformAxis then
call .parent.getRelativePos(.xOffset*.parent.scale, .yOffset*.parent.scale, .zOffset)
else
call .parent.getRelativePos(.xOffset, .yOffset, .zOffset)
endif
//if PanelCore_Locale == .parent.p then
if Panel.ReturnValX > PanelCore_WorldMinX and Panel.ReturnValX < PanelCore_WorldMaxX and Panel.ReturnValY > PanelCore_WorldMinY and Panel.ReturnValY < PanelCore_WorldMaxY then
call SetUnitX(.dummy, Panel.ReturnValX)
call SetUnitY(.dummy, Panel.ReturnValY)
call PanelCore_SetUnitZ(.dummy, Panel.ReturnValZ)
endif
//endif
endif
endmethod
method move takes real xOffset, real yOffset, integer level returns nothing
set .xOffset = xOffset
set .yOffset = yOffset
set .zOffset = PanelCamera_LEVEL_GAP*level
endmethod
method setColor takes integer r, integer g, integer b, integer a returns nothing
set .red = IMinBJ(IMaxBJ(r, 0), 255)
set .green = IMinBJ(IMaxBJ(g, 0), 255)
set .blue = IMinBJ(IMaxBJ(b, 0), 255)
set .alpha = IMinBJ(IMaxBJ(a, 0), 255)
call SetUnitVertexColor(.dummy, .red, .green, .blue, R2I(.alpha*.parent.opacity/255.))
endmethod
method show takes boolean b returns nothing
set .visible = b
if b and .parent.visible then
if PanelCore_Locale == .parent.p then
call SetUnitScale(.dummy, .size*.parent.scale, 1, 1)
call ShowUnit(.dummy, true)
else
call SetUnitScale(.dummy, 0, 0, 0)
call ShowUnit(.dummy, false)
endif
else
call SetUnitScale(.dummy, 0, 0, 0)
call SetUnitX(.dummy, PanelCore_WorldMaxX)
call SetUnitY(.dummy, PanelCore_WorldMaxY)
call ShowUnit(.dummy, false)
endif
endmethod
static method create takes Panel parent, integer id, integer texture, real xOffset, real yOffset, integer level returns thistype
local thistype this = allocate()
set .parent = parent
set .visible = false
set .dummy = CreateUnit(PanelCore_PASSIVE, id, 0, 0, 0)
set .skin = texture
set .transformAxis = true
static if not LIBRARY_AutoFly then
if UnitAddAbility(.dummy, 'Amrf') and UnitRemoveAbility(.dummy, 'Amrf') then
endif
endif
call UnitAddAbility(.dummy, 'Aeth')
call UnitAddAbility(.dummy, PanelCore_TEXTURE_REPLACER_ID)
call UnitRemoveAbility(.dummy, 'Amov')
call SetUnitPathing(.dummy, false)
call setColor(255, 255, 255, 255)
call PanelCore_ChangeTexture(.dummy, texture)
call move(xOffset, yOffset, level)
call show(true)
set .scale = 1
//call refresh()
if List[parent] == 0 then
set List[parent] = createNode()
endif
call List[parent].insertNode(this)
return this
endmethod
private static method onPanelEvent takes nothing returns boolean
local thistype node
if List[Panel.TriggeringPanel] != 0 then
set node = List[Panel.TriggeringPanel].next
loop
exitwhen node.head or node == 0
if Panel.EventType == Panel.EVENT_PANEL_REFRESHED then
call node.refresh()
elseif Panel.EventType == Panel.EVENT_PANEL_RESCALED then
set node.scale = node.size
elseif Panel.EventType == Panel.EVENT_PANEL_CLEARED or Panel.EventType == Panel.EVENT_PANEL_DESTROYED then
call node.destroy()
elseif Panel.EventType == Panel.EVENT_PANEL_VISIBILITY_MODIFIED then
call node.show(node.visible)
elseif Panel.EventType == Panel.EVENT_PANEL_OPACITY_MODIFIED then
call node.setColor(node.red, node.green, node.blue, R2I(node.alpha*node.parent.opacity/255.))
endif
set node = node.next
endloop
if Panel.EventType == Panel.EVENT_PANEL_DESTROYED and List[Panel.TriggeringPanel] != 0 then
call List[Panel.TriggeringPanel].flushNode()
set List[Panel.TriggeringPanel] = 0
endif
endif
return false
endmethod
private static method onInit takes nothing returns nothing
call Panel.RegisterAnyPanelEvent(function thistype.onPanelEvent)
endmethod
endstruct
endlibrary
library PanelTextTag requires PanelCore, optional ZLibrary
/*
~ Panel Text Tag Plugin ~
Allows to add text tags into panels.
I. How to import:
1. Copy "PanelTextTag" trigger to your map.
2. Export "PanelTextTagDummy.mdx" in import manager to your map.
3. Save your map, then close and reopen it.
4. Delete/comment out this line: */
///! external ObjectMerger w3u hfoo hPTD unsf "PanelTextTagDummy" unam "" umdl "war3mapImported\PanelTextTagDummy.mdl" ubdg 1 uabi "Aloc" uble 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" uaen "" udea "" umvt "float" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
/* 5. Done.
II. API
struct PanelTextTag
Members:
boolean transformAxis
- If true, the text tag's coordinate will be rescaled based on it's parent size
readonly real xOffset
readonly real yOffset
- x/y offset of the text tag
readonly integer red
readonly integer green
readonly integer blue
readonly integer alpha
- Text tag's color channels
readonly string text
readonly real size
- Text tag's current text & size
readonly boolean visible
- Text tag's current visibility state
readonly Panel parent
- Panel that's containing the text tag
readonly static thistype array List
- A list containing text tags in a specific Panel
- Takes the desired Panel (parent) instance as index
Methods:
static method create takes Panel parent, string s, real size, real xOffset, real yOffset returns thistype
- Add a text tag into a panel
method refresh takes nothing returns nothing
- Refresh text tag screen position
method destroy takes nothing returns nothing
- Delete and remove the text tag from its parents collection
method move takes real xOffset, real yOffset returns nothing
- Move the text tag to a new screen coordinate
method show takes boolean b returns nothing
- Modify text tag's visibility
method setText takes string s, real size returns nothing
- Change the text tag's text and size
method setColor takes integer red, integer green, integer blue, integer alpha returns nothing
- Change the text tag's color
*/
////////////////////
// Configurations //
////////////////////
globals
private constant integer DUMMY_ID = 'e00X'
private constant real ZOFFSET = -14.8
endglobals
//////////////////
// System codes //
//////////////////
struct PanelTextTag extends array
implement LinkedList
boolean transformAxis
private texttag tag
readonly real xOffset
readonly real yOffset
readonly integer red
readonly integer green
readonly integer blue
readonly integer alpha
readonly string text
readonly real size
private boolean pvisible
readonly boolean visible
readonly Panel parent
readonly static thistype array List
private static unit ZPlacer
private static player LocalPlayer
method destroy takes nothing returns nothing
call DestroyTextTag(.tag)
call removeNode()
call deallocate()
set .tag = null
endmethod
method refresh takes nothing returns nothing
if .visible and .parent.visible then
if .transformAxis then
call .parent.getRelativePos(.xOffset*.parent.scale, .yOffset*.parent.scale, 0)
else
call .parent.getRelativePos(.xOffset, .yOffset, 0)
endif
if PanelCore_Locale == .parent.p then
if Panel.ReturnValX > PanelCore_WorldMinX and Panel.ReturnValX < PanelCore_WorldMaxX and Panel.ReturnValY > PanelCore_WorldMinY and Panel.ReturnValY < PanelCore_WorldMaxY then
call SetUnitX(ZPlacer, Panel.ReturnValX)
call SetUnitY(ZPlacer, Panel.ReturnValY)
call PanelCore_SetUnitZ(ZPlacer, Panel.ReturnValZ)
call SetTextTagPosUnit(.tag, ZPlacer, ZOFFSET)
endif
endif
endif
endmethod
method show takes boolean b returns nothing
if b != .visible then
set .visible = b
call SetTextTagVisibility(.tag, b and .parent.visible and PanelCore_Locale == .parent.p)
endif
endmethod
method move takes real xOffset, real yOffset returns nothing
set .xOffset = xOffset
set .yOffset = yOffset
endmethod
method setText takes string s, real size returns nothing
set .text = s
set .size = size
call SetTextTagText(.tag, .text, .size*.parent.scale)
endmethod
method setColor takes integer red, integer green, integer blue, integer alpha returns nothing
set .red = red
set .green = green
set .blue = blue
set .alpha = alpha
call SetTextTagColor(.tag, .red, .green, .blue, R2I(.alpha*.parent.opacity/255.))
endmethod
static method create takes Panel parent, string s, real size, real xOffset, real yOffset returns thistype
local thistype this = allocate()
set .parent = parent
if PanelCore_Locale == parent.p then
set .tag = CreateTextTag()
else
set .tag = null
endif
set .visible = false
set .transformAxis = true
call SetTextTagPermanent(.tag, true)
call setText(s, size)
call setColor(255, 255, 255, 255)
call move(xOffset, yOffset)
call show(true)
//call refresh()
if List[parent] == 0 then
set List[parent] = createNode()
endif
call List[parent].insertNode(this)
return this
endmethod
private static method onPanelEvent takes nothing returns boolean
local thistype node
if List[Panel.TriggeringPanel] != 0 then
set node = List[Panel.TriggeringPanel].next
loop
exitwhen node.head or node == 0
if Panel.EventType == Panel.EVENT_PANEL_REFRESHED then
call node.refresh()
elseif Panel.EventType == Panel.EVENT_PANEL_RESCALED then
call SetTextTagText(node.tag, node.text, node.size*node.parent.scale)
elseif Panel.EventType == Panel.EVENT_PANEL_CLEARED or Panel.EventType == Panel.EVENT_PANEL_DESTROYED then
call node.destroy()
elseif Panel.EventType == Panel.EVENT_PANEL_VISIBILITY_MODIFIED then
call SetTextTagVisibility(node.tag, node.visible and node.parent.visible)
elseif Panel.EventType == Panel.EVENT_PANEL_OPACITY_MODIFIED then
call SetTextTagColor(node.tag, node.red, node.green, node.blue, R2I(node.alpha*node.parent.opacity/255.))
endif
set node = node.next
endloop
if Panel.EventType == Panel.EVENT_PANEL_DESTROYED and List[Panel.TriggeringPanel] != 0 then
call List[Panel.TriggeringPanel].flushNode()
set List[Panel.TriggeringPanel] = 0
endif
endif
return false
endmethod
private static method onInit takes nothing returns nothing
set ZPlacer = CreateUnit(PanelCore_PASSIVE, DUMMY_ID, 0, 0, 0)
static if not LIBRARY_AutoFly then
if UnitAddAbility(ZPlacer, 'Amrf') and UnitRemoveAbility(ZPlacer, 'Amrf') then
endif
endif
call UnitAddAbility(ZPlacer, 'Aeth')
call UnitAddAbility(ZPlacer, PanelCore_TEXTURE_REPLACER_ID)
call SetUnitPathing(ZPlacer, false)
call PauseUnit(ZPlacer, true)
call Panel.RegisterAnyPanelEvent(function thistype.onPanelEvent)
endmethod
endstruct
endlibrary
library PanelTextEx requires PanelCore, PanelPlatform, Ascii
/*
~ Panel TextEx Plugin ~
Allows to add texts with custom font font into panels.
TextEx is more powerful that TextTag, it allows you to have
many font fonts with "indefinite" length and amount limit.
Also it appears much smoother than TextTag. However, it's
a lot heavier both in terms of storage and computation.
It's highly recommended not to use too much of it.
I. Requirements:
- (plugin) PanelCore |
- (plugin) PanelPlatform |
- (required) Ascii | https://www.hiveworkshop.com/threads/snippet-ascii.190746/
II. How to import:
1. Copy "PanelTextEx" trigger to your map.
2. Export "PanelTextExDummy.mdx" in import manager to your map.
3. Save your map, then close and reopen it.
4. Delete/comment out this line: */
////! external ObjectMerger w3u hfoo hTED unsf "PanelTextExDummy" unam "" umdl "war3mapImported\PanelTextExDummy.mdl" ubdg 1 uabi "Aloc" uble 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" uaen "" udea "" umvt "float" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
/* 5. Done.
III. API
struct PanelTextEx
Members:
readonly real width
- Total width of the whole text in pixel
readonly real xOffset
readonly real yOffset
- Position of the text
readonly string font
- Text's font font
readonly integer length
- Number of characters in the text
readonly integer level
- Rendering level of the text
readonly Panel parent
- Panel that's containing the text
readonly static thistype array List
- A list containing TextEx's in a specific Panel
- Takes the desired Panel (parent) instance as index
Methods:
static method create takes Panel parent, string text, string font, real xOffset, real yOffset, integer level returns thistype
- Add new TextEx to a panel
method operator visible takes nothing returns boolean
- Get text's current visibility state
method operator red takes nothing returns integer
method operator green takes nothing returns integer
method operator blue takes nothing returns integer
method operator alpha takes nothing returns integer
- Get text's color channels
method operator scale takes nothing returns real
method operator scale= takes real r returns nothing
- Get/set text size
method operator transformAxis= takes boolean b returns nothing
- If true, the text's coordinate will be rescaled based on it's parent size
method setText takes string text, string font returns nothing
- Change the text and its font font
method refresh takes nothing returns nothing
- Refresh text screen position
method destroy takes nothing returns nothing
- Remove the text from its container
method move takes real xOffset, real yOffset, integer level returns nothing
- Move the text to different coordinate and level
method setColor takes integer r, integer g, integer b, integer a returns nothing
- Modify text's color and transparency
method show takes boolean b returns nothing
- Show/hide the text
*/
////////////////////
// Configurations //
////////////////////
globals
// Platform object for display characters
private constant integer DUMMY_ID = 'e00W'
// Space character width in pixel
private constant real SPACE_WIDTH = 8.0 // px
// Default spacing between characters
private constant real CHAR_GAP = 1.0
endglobals
//////////////////
// System codes //
//////////////////
private module InitModule
private static method onInit takes nothing returns nothing
call init()
endmethod
endmodule
struct PanelTextExChar extends array
implement LinkedList
string char
real width
real height
real depth
PanelPlatform plat
method operator xOffset takes nothing returns real
return .plat.xOffset
endmethod
method operator yOffset takes nothing returns real
return .plat.yOffset
endmethod
method operator visible takes nothing returns boolean
return .plat.visible
endmethod
method show takes boolean b returns nothing
call .plat.show(b)
endmethod
endstruct
struct PanelTextEx extends array
implement LinkedList
private real size
readonly real width
readonly real height
readonly real depth
readonly real xOffset
readonly real yOffset
readonly string text
readonly integer font
readonly integer length
readonly integer level
readonly boolean visible
readonly Panel parent
readonly PanelTextExChar chars
readonly static thistype array List
readonly static hashtable FontData = InitHashtable()
private method getCharTexture takes string s returns integer
return LoadInteger(FontData, font + 0, Char2Ascii(s))
endmethod
public method getCharWidth takes string s returns real
return LoadReal(FontData, font + 1, Char2Ascii(s))
endmethod
private method getCharHeight takes string s returns real
return LoadReal(FontData, font + 2, Char2Ascii(s))
endmethod
private method getCharDepth takes string s returns real
return LoadReal(FontData, font + 3, Char2Ascii(s))
endmethod
static method getStringWidth takes string s, integer font returns real
local real result = 0
local string sub
local integer i = 0
local integer exit = StringLength(s)
loop
exitwhen i == exit
set sub = SubString(s, i, i+1)
set result = result + LoadReal(FontData, font + 1, Char2Ascii(s))
endloop
return result
endmethod
method operator red takes nothing returns integer
return .chars.next.plat.red
endmethod
method operator green takes nothing returns integer
return .chars.next.plat.green
endmethod
method operator blue takes nothing returns integer
return .chars.next.plat.blue
endmethod
method operator alpha takes nothing returns integer
return .chars.next.plat.alpha
endmethod
method operator scale takes nothing returns real
return .size
endmethod
method operator scale= takes real r returns nothing
set .width = .width * (r/.size)
set .height = .height * (r/.size)
set .depth = .depth * (r/.size)
set .size = r
call refresh()
endmethod
method operator transformAxis= takes boolean b returns nothing
local PanelTextExChar c = .chars.next
loop
exitwhen c.head or c == 0
if c.plat != 0 then
set c.plat.transformAxis = b
endif
set c = c.next
endloop
endmethod
method refresh takes nothing returns nothing
local PanelTextExChar c = .chars.next
local real xOffset = .xOffset
local real offset
loop
exitwhen c.head or c == 0
set offset = c.width*.size
if c.char != " " then
set c.plat.scale = .size
call c.plat.move(xOffset+offset/2, .yOffset, .level)
call c.plat.refresh()
endif
set xOffset = xOffset+offset+CHAR_GAP
set c = c.next
endloop
endmethod
method clear takes nothing returns nothing
local PanelTextExChar c = .chars.next
loop
exitwhen c.head or c == 0
if c.plat != 0 then
call c.plat.destroy()
set c.plat = 0
endif
set c = c.next
endloop
call chars.clearNode()
endmethod
method destroy takes nothing returns nothing
call clear()
call chars.flushNode()
call removeNode()
call deallocate()
endmethod
method move takes real xOffset, real yOffset, integer level returns nothing
set .xOffset = xOffset
set .yOffset = yOffset
set .level = level
//call refresh()
endmethod
method setColor takes integer r, integer g, integer b, integer a returns nothing
local PanelTextExChar c = .chars.next
loop
exitwhen c.head or c == 0
if c.plat != 0 then
call c.plat.setColor(r, g, b, a)
endif
set c = c.next
endloop
endmethod
method show takes boolean b returns nothing
local PanelTextExChar c
set .visible = b
set c = .chars.next
loop
exitwhen c.head or c == 0
if c.plat != 0 then
call c.plat.show(b and c.char != " ")
endif
set c = c.next
endloop
endmethod
private method setComponentChar takes PanelTextExChar c, string s returns nothing
if c.plat == 0 then
set c.plat = PanelPlatform.create(.parent, DUMMY_ID, 0, 0, 0, level)
endif
if s == " " then
set c.char = " "
set c.width = SPACE_WIDTH
set c.height = 0.0
set c.depth = 0.0
call c.plat.show(false)
else
set c.char = s
set c.width = getCharWidth(s)
set c.height = getCharHeight(s)
set c.depth = getCharDepth(s)
set c.plat.texture = getCharTexture(s)
call c.plat.show(.visible)
endif
set .width = .width+(c.width*.size)+CHAR_GAP
if c.height > .height then
set .height = c.height*.size
endif
if c.depth > .depth then
set .depth = c.depth*.size
endif
endmethod
private method initText takes nothing returns nothing
local integer i = 0
local string s
local PanelTextExChar c
set c = .chars.next
loop
exitwhen c.head or c == 0
if i < .length then
set s = SubString(.text, i, i+1)
call setComponentChar(c, s)
else
set c.char = " "
call c.plat.show(false)
endif
set c = c.next
set i = i + 1
endloop
loop
exitwhen i >= .length
set s = SubString(.text, i, i+1)
set c = PanelTextExChar.allocate()
call setComponentChar(c, s)
call .chars.insertNode(c)
set i = i + 1
endloop
set .width = .width-CHAR_GAP
endmethod
method setText takes string text, integer font returns nothing
if .text != text then
set .text = text
set .font = font
set .length = StringLength(text)
set .width = 0
set .height = 0
set .depth = 0
call initText()
endif
endmethod
static method create takes Panel parent, string text, integer font, real xOffset, real yOffset, integer level returns thistype
local thistype this = allocate()
set .parent = parent
set .size = 1
set .xOffset = xOffset
set .yOffset = yOffset
set .level = level
set .text = text
set .font = font
set .visible = true
set .length = StringLength(text)
set .chars = PanelTextExChar.createNode()
set .width = 0
set .height = 0
set .depth = 0
call initText()
if List[parent] == 0 then
set List[parent] = createNode()
endif
call List[parent].insertNode(this)
return this
endmethod
private static method onPanelEvent takes nothing returns boolean
local thistype node
if List[Panel.TriggeringPanel] != 0 then
set node = List[Panel.TriggeringPanel].next
loop
exitwhen node.head or node == 0
if Panel.EventType == Panel.EVENT_PANEL_CLEARED or Panel.EventType == Panel.EVENT_PANEL_DESTROYED then
call node.destroy()
endif
set node = node.next
endloop
if Panel.EventType == Panel.EVENT_PANEL_DESTROYED and List[Panel.TriggeringPanel] != 0 then
call List[Panel.TriggeringPanel].flushNode()
set List[Panel.TriggeringPanel] = 0
endif
endif
return false
endmethod
private static method init takes nothing returns nothing
local string s
local integer asc
call Panel.RegisterAnyPanelEvent(function PanelTextEx.onPanelEvent)
implement PanelTextExFontData
endmethod
implement InitModule
endstruct
// Font data stuffs
globals
public integer FontIndex = 0
endglobals
//! textmacro DefineFontStyle takes FONT
globals
integer FONTSTYLE_$FONT$ = -1
endglobals
//! endtextmacro
//! textmacro InitFontObject takes FONT, CHAR, INDEX, CODE, WIDTH, HEIGHT, DEPTH
if FONTSTYLE_$FONT$ == -1 then
set FONTSTYLE_$FONT$ = PanelTextEx_FontIndex
set PanelTextEx_FontIndex = PanelTextEx_FontIndex + 4
endif
if "$CHAR$" == "''" then // symbol " breaks textmacro
set asc = Char2Ascii("\"")
else
set asc = Char2Ascii("$CHAR$")
endif
call SaveInteger(FontData, FONTSTYLE_$FONT$ + 0, asc, '$CODE$$INDEX$')
call SaveReal (FontData, FONTSTYLE_$FONT$ + 1, asc, $WIDTH$)
call SaveReal (FontData, FONTSTYLE_$FONT$ + 2, asc, $HEIGHT$)
call SaveReal (FontData, FONTSTYLE_$FONT$ + 3, asc, $DEPTH$)
//! endtextmacro
//! textmacro CreateFontObject takes FONT, INDEX, CODE, FILEPATH, EXTENSION
//! external ObjectMerger w3b YTlb $CODE$$INDEX$ bnam "($FONT$) Char $INDEX$" bfxr -1 bfil ".mdl" boch 0 btxf "$FILEPATH$$INDEX$$EXTENSION$" btxi 33 bsel 0 bgsc 0 bshd "" barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
endlibrary
library PanelTextEx requires PanelCore, PanelPlatform, Ascii
/*
~ Panel TextEx Plugin ~
Allows to add texts with custom font font into panels.
TextEx is more powerful that TextTag, it allows you to have
many font fonts with "indefinite" length and amount limit.
Also it appears much smoother than TextTag. However, it's
a lot heavier both in terms of storage and computation.
It's highly recommended not to use too much of it.
I. Requirements:
- (plugin) PanelCore |
- (plugin) PanelPlatform |
- (required) Ascii | https://www.hiveworkshop.com/threads/snippet-ascii.190746/
II. How to import:
1. Copy "PanelTextEx" trigger to your map.
2. Export "PanelTextExDummy.mdx" in import manager to your map.
3. Save your map, then close and reopen it.
4. Delete/comment out this line: */
////! external ObjectMerger w3u hfoo hTED unsf "PanelTextExDummy" unam "" umdl "war3mapImported\PanelTextExDummy.mdl" ubdg 1 uabi "Aloc" uble 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" uaen "" udea "" umvt "float" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
/* 5. Done.
III. API
struct PanelTextEx
Members:
readonly real width
- Total width of the whole text in pixel
readonly real xOffset
readonly real yOffset
- Position of the text
readonly string font
- Text's font font
readonly integer length
- Number of characters in the text
readonly integer level
- Rendering level of the text
readonly Panel parent
- Panel that's containing the text
readonly static thistype array List
- A list containing TextEx's in a specific Panel
- Takes the desired Panel (parent) instance as index
Methods:
static method create takes Panel parent, string text, string font, real xOffset, real yOffset, integer level returns thistype
- Add new TextEx to a panel
method operator visible takes nothing returns boolean
- Get text's current visibility state
method operator red takes nothing returns integer
method operator green takes nothing returns integer
method operator blue takes nothing returns integer
method operator alpha takes nothing returns integer
- Get text's color channels
method operator scale takes nothing returns real
method operator scale= takes real r returns nothing
- Get/set text size
method operator transformAxis= takes boolean b returns nothing
- If true, the text's coordinate will be rescaled based on it's parent size
method setText takes string text, string font returns nothing
- Change the text and its font font
method refresh takes nothing returns nothing
- Refresh text screen position
method destroy takes nothing returns nothing
- Remove the text from its container
method move takes real xOffset, real yOffset, integer level returns nothing
- Move the text to different coordinate and level
method setColor takes integer r, integer g, integer b, integer a returns nothing
- Modify text's color and transparency
method show takes boolean b returns nothing
- Show/hide the text
*/
////////////////////
// Configurations //
////////////////////
globals
// Platform object for display characters
private constant integer DUMMY_ID = 'e00W'
// Space character width in pixel
private constant real SPACE_WIDTH = 8.0 // px
// Default spacing between characters
private constant real CHAR_GAP = 1.0
endglobals
//////////////////
// System codes //
//////////////////
private module InitModule
private static method onInit takes nothing returns nothing
call init()
endmethod
endmodule
struct PanelTextExChar extends array
implement LinkedList
string char
real width
real height
real depth
PanelPlatform plat
method operator xOffset takes nothing returns real
return .plat.xOffset
endmethod
method operator yOffset takes nothing returns real
return .plat.yOffset
endmethod
method operator visible takes nothing returns boolean
return .plat.visible
endmethod
method show takes boolean b returns nothing
call .plat.show(b)
endmethod
endstruct
struct PanelTextEx extends array
implement LinkedList
private real size
readonly real width
readonly real height
readonly real depth
readonly real xOffset
readonly real yOffset
readonly string text
readonly integer font
readonly integer length
readonly integer level
readonly boolean visible
readonly Panel parent
readonly PanelTextExChar chars
readonly static thistype array List
readonly static hashtable FontData = InitHashtable()
private method getCharTexture takes string s returns integer
return LoadInteger(FontData, font + 0, Char2Ascii(s))
endmethod
public method getCharWidth takes string s returns real
return LoadReal(FontData, font + 1, Char2Ascii(s))
endmethod
private method getCharHeight takes string s returns real
return LoadReal(FontData, font + 2, Char2Ascii(s))
endmethod
private method getCharDepth takes string s returns real
return LoadReal(FontData, font + 3, Char2Ascii(s))
endmethod
static method getStringWidth takes string s, integer font returns real
local real result = 0
local string sub
local integer i = 0
local integer exit = StringLength(s)
loop
exitwhen i == exit
set sub = SubString(s, i, i+1)
set result = result + LoadReal(FontData, font + 1, Char2Ascii(s))
endloop
return result
endmethod
method operator red takes nothing returns integer
return .chars.next.plat.red
endmethod
method operator green takes nothing returns integer
return .chars.next.plat.green
endmethod
method operator blue takes nothing returns integer
return .chars.next.plat.blue
endmethod
method operator alpha takes nothing returns integer
return .chars.next.plat.alpha
endmethod
method operator scale takes nothing returns real
return .size
endmethod
method operator scale= takes real r returns nothing
set .size = r
call refresh()
endmethod
method operator transformAxis= takes boolean b returns nothing
local PanelTextExChar c = .chars.next
loop
exitwhen c.head
if c.plat != 0 then
set c.plat.transformAxis = b
endif
set c = c.next
endloop
endmethod
method refresh takes nothing returns nothing
local PanelTextExChar c = .chars.next
local real xOffset = .xOffset
local real offset
set .width = 0
set .height = 0
set .depth = 0
loop
exitwhen c.head
set offset = c.width*.size
if c.plat != 0 then
set c.plat.scale = .size
call c.plat.move(xOffset+offset/2, .yOffset, .level)
call c.plat.refresh()
endif
set xOffset = xOffset+offset+CHAR_GAP
set .width = .width+offset+CHAR_GAP
if c.height > .height then
set .height = c.height*.size
endif
if c.depth > .depth then
set .depth = c.depth*.size
endif
set c = c.next
endloop
set .width = .width-CHAR_GAP
endmethod
method clear takes nothing returns nothing
local PanelTextExChar c = .chars.next
loop
exitwhen c.head
if c.plat != 0 then
call c.plat.destroy()
endif
set c = c.next
endloop
call chars.clearNode()
endmethod
method destroy takes nothing returns nothing
call clear()
call chars.flushNode()
call removeNode()
call deallocate()
endmethod
method move takes real xOffset, real yOffset, integer level returns nothing
set .xOffset = xOffset
set .yOffset = yOffset
set .level = level
call refresh()
endmethod
method setColor takes integer r, integer g, integer b, integer a returns nothing
local PanelTextExChar c = .chars.next
loop
exitwhen c.head
if c.plat != 0 then
call c.plat.setColor(r, g, b, a)
endif
set c = c.next
endloop
endmethod
method show takes boolean b returns nothing
local PanelTextExChar c
set .visible = b
set c = .chars.next
loop
exitwhen c.head
if c.plat != 0 then
call c.plat.show(b)
endif
set c = c.next
endloop
endmethod
private method initText takes nothing returns nothing
local integer i = 0
local string s
local real xOffset = .xOffset
local real yOffset
local real offset
local PanelTextExChar c
set .width = 0
set .height = 0
set .depth = 0
loop
exitwhen i == .length
set s = SubString(.text, i, i+1)
set c = PanelTextExChar.allocate()
if s == " " then
set c.char = " "
set c.width = SPACE_WIDTH
set c.height = 0.0
set c.depth = 0.0
set offset = c.width*.size
set c.plat = 0
else
set c.char = s
set c.width = getCharWidth(s)
set c.height = getCharHeight(s)
set c.depth = getCharDepth(s)
set offset = c.width*.size
set c.plat = PanelPlatform.create(.parent, DUMMY_ID, getCharTexture(s), xOffset+offset/2, .yOffset, level)
call c.plat.show(.visible)
endif
set xOffset = xOffset+offset+CHAR_GAP
set .width = .width+offset+CHAR_GAP
if c.height > .height then
set .height = c.height*.size
endif
if c.depth > .depth then
set .depth = c.depth*.size
endif
call .chars.insertNode(c)
set i = i + 1
endloop
set .width = .width-CHAR_GAP
endmethod
method setText takes string text, integer font returns nothing
if .text != text then
call clear()
set .text = text
set .font = font
set .length = StringLength(text)
call initText()
endif
endmethod
static method create takes Panel parent, string text, integer font, real xOffset, real yOffset, integer level returns thistype
local thistype this = allocate()
set .parent = parent
set .size = 1
set .xOffset = xOffset
set .yOffset = yOffset
set .level = level
set .text = text
set .font = font
set .visible = true
set .length = StringLength(text)
set .chars = PanelTextExChar.createNode()
call initText()
if List[parent] == 0 then
set List[parent] = createNode()
endif
call List[parent].insertNode(this)
return this
endmethod
private static method onPanelEvent takes nothing returns boolean
local thistype node
if List[Panel.TriggeringPanel] != 0 then
set node = List[Panel.TriggeringPanel].next
loop
exitwhen node.head
if Panel.EventType == Panel.EVENT_PANEL_CLEARED or Panel.EventType == Panel.EVENT_PANEL_DESTROYED then
call node.destroy()
endif
set node = node.next
endloop
if Panel.EventType == Panel.EVENT_PANEL_DESTROYED and List[Panel.TriggeringPanel] != 0 then
call List[Panel.TriggeringPanel].flushNode()
set List[Panel.TriggeringPanel] = 0
endif
endif
return false
endmethod
private static method init takes nothing returns nothing
local string s
local integer asc
call Panel.RegisterAnyPanelEvent(function PanelTextEx.onPanelEvent)
implement PanelTextExFontData
endmethod
implement InitModule
endstruct
// Font data stuffs
globals
public integer FontIndex = 0
endglobals
//! textmacro DefineFontStyle takes FONT
globals
integer FONTSTYLE_$FONT$ = -1
endglobals
//! endtextmacro
//! textmacro InitFontObject takes FONT, CHAR, INDEX, CODE, WIDTH, HEIGHT, DEPTH
if FONTSTYLE_$FONT$ == -1 then
set FONTSTYLE_$FONT$ = PanelTextEx_FontIndex
set PanelTextEx_FontIndex = PanelTextEx_FontIndex + 4
endif
if "$CHAR$" == "''" then // symbol " breaks textmacro
set asc = Char2Ascii("\"")
else
set asc = Char2Ascii("$CHAR$")
endif
call SaveInteger(FontData, FONTSTYLE_$FONT$ + 0, asc, '$CODE$$INDEX$')
call SaveReal (FontData, FONTSTYLE_$FONT$ + 1, asc, $WIDTH$)
call SaveReal (FontData, FONTSTYLE_$FONT$ + 2, asc, $HEIGHT$)
call SaveReal (FontData, FONTSTYLE_$FONT$ + 3, asc, $DEPTH$)
//! endtextmacro
//! textmacro CreateFontObject takes FONT, INDEX, CODE, FILEPATH, EXTENSION
//! external ObjectMerger w3b YTlb $CODE$$INDEX$ bnam "($FONT$) Char $INDEX$" bfxr -1 bfil ".mdl" boch 0 btxf "$FILEPATH$$INDEX$$EXTENSION$" btxi 33 bsel 0 bgsc 0 bshd "" barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
endlibrary
//! runtextmacro DefineFontStyle("FrizQTShaded")
module PanelTextExFontData
//! runtextmacro InitFontObject ("FrizQTShaded", "A", "0", "FS0", "37.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "B", "1", "FS0", "27.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "C", "2", "FS0", "31.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "D", "3", "FS0", "32.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "E", "4", "FS0", "24.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "F", "5", "FS0", "20.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "G", "6", "FS0", "33.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "H", "7", "FS0", "34.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "I", "8", "FS0", "10.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "J", "9", "FS0", "14.0", "15.0", "31.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "K", "10", "FS", "31.0", "15.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "L", "11", "FS", "24.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "M", "12", "FS", "46.0", "15.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "N", "13", "FS", "34.0", "15.0", "21.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "O", "14", "FS", "39.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "P", "15", "FS", "25.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "Q", "16", "FS", "46.0", "16.0", "29.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "R", "17", "FS", "31.0", "15.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "S", "18", "FS", "25.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "T", "19", "FS", "28.0", "16.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "U", "20", "FS", "32.0", "15.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "V", "21", "FS", "32.0", "15.0", "21.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "W", "22", "FS", "48.0", "15.0", "21.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "X", "23", "FS", "35.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "Y", "24", "FS", "31.0", "16.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "Z", "25", "FS", "30.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "a", "26", "FS", "25.0", "6.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "b", "27", "FS", "25.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "c", "28", "FS", "24.0", "6.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "d", "29", "FS", "27.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "e", "30", "FS", "25.0", "6.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "f", "31", "FS", "18.0", "16.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "g", "32", "FS", "30.0", "6.0", "32.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "h", "33", "FS", "25.0", "16.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "i", "34", "FS", "9.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "j", "35", "FS", "11.0", "15.0", "31.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "k", "36", "FS", "24.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "l", "37", "FS", "8.0", "16.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "m", "38", "FS", "41.0", "6.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "n", "39", "FS", "25.0", "6.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "o", "40", "FS", "27.0", "6.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "p", "41", "FS", "27.0", "6.0", "30.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "q", "42", "FS", "27.0", "5.0", "30.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "r", "43", "FS", "15.0", "6.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "s", "44", "FS", "21.0", "6.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "t", "45", "FS", "16.0", "13.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "u", "46", "FS", "25.0", "6.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "v", "47", "FS", "28.0", "6.0", "21.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "w", "48", "FS", "41.0", "6.0", "21.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "x", "49", "FS", "28.0", "5.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "y", "50", "FS", "28.0", "5.0", "30.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "z", "51", "FS", "25.0", "5.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "1", "52", "FS", "15.0", "17.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "2", "53", "FS", "27.0", "16.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "3", "54", "FS", "25.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "4", "55", "FS", "30.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "5", "56", "FS", "25.0", "15.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "6", "57", "FS", "27.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "7", "58", "FS", "25.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "8", "59", "FS", "28.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "9", "60", "FS", "27.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "0", "61", "FS", "27.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "!", "62", "FS", "8.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "@", "63", "FS", "35.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "#", "64", "FS", "30.0", "15.0", "19.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "$", "65", "FS", "23.0", "19.0", "24.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "%", "66", "FS", "33.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "^", "67", "FS", "24.0", "15.0", "0.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "&", "68", "FS", "39.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "*", "69", "FS", "18.0", "15.0", "2.0")
//! runtextmacro InitFontObject ("FrizQTShaded", ")", "70", "FS", "11.0", "15.0", "27.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "(", "71", "FS", "12.0", "15.0", "27.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "-", "72", "FS", "17.0", "1.0", "9.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "=", "73", "FS", "23.0", "4.0", "8.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "_", "74", "FS", "26.0", "0.0", "26.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "+", "75", "FS", "23.0", "10.0", "14.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "]", "76", "FS", "12.0", "15.0", "27.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "[", "77", "FS", "12.0", "15.0", "27.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "}", "78", "FS", "12.0", "15.0", "27.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "{", "79", "FS", "12.0", "15.0", "27.0")
//! runtextmacro InitFontObject ("FrizQTShaded", ";", "80", "FS", "8.0", "4.0", "25.0")
//! runtextmacro InitFontObject ("FrizQTShaded", ":", "81", "FS", "7.0", "4.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "'", "82", "FS", "6.0", "15.0", "0.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "''","83", "FS", "13.0", "15.0", "0.0")
//! runtextmacro InitFontObject ("FrizQTShaded", ",", "84", "FS", "8.0", "0.0", "25.0")
//! runtextmacro InitFontObject ("FrizQTShaded", ".", "85", "FS", "7.0", "0.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "/", "86", "FS", "21.0", "15.0", "26.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "\\","87", "FS", "21.0", "15.0", "26.0")
//! runtextmacro InitFontObject ("FrizQTShaded", ">", "88", "FS", "23.0", "11.0", "15.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "<", "89", "FS", "23.0", "11.0", "15.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "?", "90", "FS", "20.0", "16.0", "20.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "|", "91", "FS", "5.0", "15.0", "28.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "`", "92", "FS", "13.0", "17.0", "0.0")
//! runtextmacro InitFontObject ("FrizQTShaded", "~", "93", "FS", "25.0", "19.0", "0.0")
endmodule
//! runtextmacro CreateFontObject ("FrizQTShaded", "0", "FS0", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "1", "FS0", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "2", "FS0", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "3", "FS0", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "4", "FS0", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "5", "FS0", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "6", "FS0", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "7", "FS0", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "8", "FS0", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "9", "FS0", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "10", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "11", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "12", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "13", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "14", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "15", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "16", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "17", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "18", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "19", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "20", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "21", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "22", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "23", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "24", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "25", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "26", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "27", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "28", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "29", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "30", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "31", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "32", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "33", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "34", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "35", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "36", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "37", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "38", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "39", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "40", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "41", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "42", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "43", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "44", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "45", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "46", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "47", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "48", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "49", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "50", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "51", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "52", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "53", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "54", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "55", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "56", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "57", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "58", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "59", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "60", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "61", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "62", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "63", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "64", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "65", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "66", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "67", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "68", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "69", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "70", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "71", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "72", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "73", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "74", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "75", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "76", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "77", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "78", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "79", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "80", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "81", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "82", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "83", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "84", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "85", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "86", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "87", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "88", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "89", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "90", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "91", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "92", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
//! runtextmacro CreateFontObject ("FrizQTShaded", "93", "FS", "war3mapImported\FrizQTShadedFontChar", ".blp")
library DamageCalculator
private keyword INITS
struct DamageCalculator extends array
static integer SkillId
static integer SkillLevel
static integer CharLevel
static integer TargetId
static real TargDef
static real DmgBase
static real DmgAdd
static real ExpBase
static real MaxDmg
static real MaxDmgFact
static real Const1
static real LevelExp
static real LevelFact
private static method CalcDamage takes nothing returns real
local real rate = DmgBase + DmgAdd*SkillLevel
if rate < DmgBase+DmgAdd then
set rate = DmgBase+DmgAdd
endif
return rate+Pow(ExpBase, rate)*(Const1-(Const1*(rate/MaxDmg)*MaxDmgFact))*(I2R(CharLevel-1)/100.)+(LevelFact*(Pow(LevelExp, CharLevel)*CharLevel))
endmethod
private static method onChat takes nothing returns nothing
local string s = GetEventPlayerChatStringMatched()
local real dmg
if (s == "out") then
set dmg = CalcDamage()
set result = 0
set dmg = (dmg-TargDef*1.5)
if dmg < 0 then
set dmg = 0
endif
call BJDebugMsg("Output damage: " + R2S(dmg))
elseif (s == "id") then
set SkillId = S2I(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
elseif (s == "lvl") then
set SkillLevel = S2I(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
elseif (s == "clvl") then
set CharLevel = S2I(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
elseif (s == "tid") then
set TargetId = S2I(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
elseif (s == "base") then
set DmgBase = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
elseif (s == "rate") then
set DmgAdd = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
elseif (s == "exp") then
set ExpBase = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
elseif (s == "dmgx") then
set MaxDmg = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
elseif (s == "dmgf") then
set MaxDmgFact = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
elseif (s == "cnst") then
set Const1 = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
elseif (s == "lexp") then
set LevelExp = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
elseif (s == "lfct") then
set LevelFact = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
elseif (s == "tdef") then
set TargDef = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
endif
endmethod
implement INITS
endstruct
private module INITS
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( t, Player(0), "out", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "id", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "lvl", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "clvl", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "tid", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "tdef", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "base", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "rate", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "exp", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "dmgx", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "dmgf", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "cnst", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "lexp", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "lfct", false )
call TriggerAddAction( t, function thistype.onChat )
endmethod
endmodule
endlibrary
scope ModDummy
private keyword INITS
struct ModDummy extends array
static integer Level = 1
static real HP = 1
static real PAtk = 1
static real PAtkMax = 2
static real MAtk = 1
static real MAtkMax = 2
static real PDef = 1
static real MDef = 0.6
private static method onChat takes nothing returns nothing
local boolean b = false
local string s = GetEventPlayerChatStringMatched()
local Combatant c
local integer i
local ItemObject obj
if (s == "#lvl") then
set Level = S2I(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
set b = true
elseif (s == "#hp") then
set HP = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
set b = true
elseif (s == "#pdm") then
set PAtk = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
set b = true
elseif (s == "#pdx") then
set PAtkMax = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
set b = true
elseif (s == "#mdm") then
set MAtk = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
set b = true
elseif (s == "#mdx") then
set MAtkMax = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
set b = true
elseif (s == "#pa") then
set PDef = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
set b = true
elseif (s == "#ma") then
set MDef = S2R(SubString(GetEventPlayerChatString(), StringLength(s) + 1, 99))
set b = true
elseif (s == "#in") then
call BJDebugMsg("====================================")
call BJDebugMsg("Level: " + I2S(Level))
call BJDebugMsg("HP: " + R2S(HP))
call BJDebugMsg("P.Atk: " + R2S(PAtk) + " - " + R2S(PAtkMax))
call BJDebugMsg("M.Atk: " + R2S(MAtk) + " - " + R2S(MAtkMax))
call BJDebugMsg("P.Def: " + R2S(PDef))
call BJDebugMsg("M.Def: " + R2S(MDef))
endif
if b then
call Combatant[gg_unit_h002_0010].destroy()
call IndexCreep(gg_unit_h002_0010)
set c = Combatant[gg_unit_h002_0010]
set c.hpMax = HP
set c.physicDmgMin = PAtk
set c.physicDmgMax = PAtkMax
set c.magicDmgMin = MAtk
set c.magicDmgMax = MAtkMax
set c.physicDefense = PDef
set c.magicDefense = MDef
call AdjustCreepStrength(c, Level)
call BJDebugMsg("====================================")
call BJDebugMsg("Level: " + I2S(Level))
call BJDebugMsg("HP: " + R2S(c.hpMax))
call BJDebugMsg("P.Atk: " + R2S(c.physicDmgMin) + " - " + R2S(c.physicDmgMax))
call BJDebugMsg("M.Atk: " + R2S(c.magicDmgMin) + " - " + R2S(c.magicDmgMax))
call BJDebugMsg("P.Def: " + R2S(c.physicDefense))
call BJDebugMsg("M.Def: " + R2S(c.magicDefense))
endif
endmethod
implement INITS
endstruct
private module INITS
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterPlayerChatEvent( t, Player(0), "#lvl", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "#hp", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "#pdm", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "#pdx", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "#mdm", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "#mdx", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "#pa", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "#ma", false )
call TriggerRegisterPlayerChatEvent( t, Player(0), "#in", false )
call TriggerAddAction( t, function thistype.onChat )
endmethod
endmodule
endscope
scope SMTest
private keyword INITS
struct SMTest extends array
static real ScreenX = 0
static real ScreenY = 0
private static method onMove takes nothing returns nothing
call ClearTextMessages()
set ScreenX = ScreenX + SMGetDifX(0)
set ScreenY = ScreenY + SMGetDifY(0)
call BJDebugMsg("x: " + R2S(ScreenX) + " | y: " + R2S(ScreenY))
endmethod
implement INITS
endstruct
private module INITS
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
local trigger t2 = CreateTrigger()
call ScreenMouseRegisterPlayer(t, t2, Player(0), true, true, true )
//call TriggerAddAction(t2, function SMTest.onMove )
call TimerStart(CreateTimer(), 0.03, true, function SMTest.onMove)
endmethod
endmodule
endscope
scope TextTagCounter
globals
private integer Ct = 0
endglobals
private function OnCreate takes nothing returns nothing
set Ct = Ct + 1
call BJDebugMsg("(Create) Created texttag: " + I2S(Ct))
endfunction
private function OnDestroy takes texttag tag returns nothing
set Ct = Ct - 1
call BJDebugMsg("(Destroy) Created texttag: " + I2S(Ct))
endfunction
hook CreateTextTag OnCreate
hook DestroyTextTag OnDestroy
endscope
scope DebugItemObj
globals
endglobals
private function OnRemove takes unit u returns nothing
if GetUnitTypeId(u) == 'e02F' then
call BJDebugMsg("Remove item: " + ItemObject[u].id.name)
endif
endfunction
private function OnKill takes unit u returns nothing
if GetUnitTypeId(u) == 'e02F' then
call BJDebugMsg("Kill item: " + ItemObject[u].id.name)
endif
endfunction
hook RemoveUnit OnRemove
hook KillUnit OnKill
endscope
library_once NoDesync
function Trig_desync_fuck_u_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer id = GetIssuedOrderId()
local player p = GetTriggerPlayer()
if (GetUnitAbilityLevel(u, PanelCore_TEXTURE_REPLACER_ID) > 0 or GetUnitAbilityLevel(GetOrderTargetUnit(), PanelCore_TEXTURE_REPLACER_ID) > 0) then
call DisplayTimedTextToPlayer(Locale, 0, 0, 0, "order " + GetUnitName(GetTriggerUnit()) + " of " +GetPlayerName(GetOwningPlayer(GetTriggerUnit())) + " by " + GetPlayerName(p) + " to " + OrderId2String(GetIssuedOrderId()))
endif
if id != 851973 and id != 852511 and (GetUnitAbilityLevel(u, PanelCore_TEXTURE_REPLACER_ID) > 0 or GetUnitAbilityLevel(GetOrderTargetUnit(), PanelCore_TEXTURE_REPLACER_ID) > 0) then
call PauseUnit(u, true)
call PauseUnit(u, false)
call IssueImmediateOrderById(u, 851973)
endif
set u = null
endfunction
function InitTrig_AntiDesync takes nothing returns nothing
set gg_trg_AntiDesync = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(gg_trg_AntiDesync, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerRegisterAnyUnitEventBJ(gg_trg_AntiDesync, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
call TriggerAddAction(gg_trg_AntiDesync, function Trig_desync_fuck_u_Actions)
endfunction
endlibrary
library Skill initializer init
/*
Create new skill procedures:
- Create skill & icon object
- Register skill props
- Create calculation formula at calculation lib
- Register skill tooltips parameters at Tooltip library
*/
globals
PlayerSkill array Skills
PlayerSkill array PlayerSkillData[4][100]
integer array PassiveSkillLevelReq[3][6]
public integer SkillCount = 0
integer ORDER_ATTACK_SKILL = 0
integer ORDER_STOP_SKILL = 0
integer ORDER_MOVE_SKILL = 0
endglobals
private module InitSkillData
if /* Guardian */ true then
// 1. Death Blow
set this = create()
set name = "Death Blow"
set cooldown[0] = 4.0
set cooldown[1] = 4.0
set cooldown[2] = 4.0
set cooldown[3] = 4.0
set cooldown[4] = 4.0
set cooldown[5] = 4.0
set cooldown[6] = 4.0
set cooldown[7] = 4.0
set cooldown[8] = 4.0
set cooldown[9] = 4.0
set cooldown[10] = 4.0
set cooldown[11] = 4.0
set cooldown[12] = 4.0
set cooldown[13] = 4.0
set cooldown[14] = 4.0
set cooldown[15] = 4.0
set manacost[0] = 10.0
set manacost[1] = 10.0
set manacost[2] = 10.0
set manacost[3] = 10.0
set manacost[4] = 15.0
set manacost[5] = 15.0
set manacost[6] = 15.0
set manacost[7] = 20.0
set manacost[8] = 20.0
set manacost[9] = 20.0
set manacost[10] = 25.0
set manacost[11] = 25.0
set manacost[12] = 25.0
set manacost[13] = 30.0
set manacost[14] = 30.0
set manacost[15] = 30.0
set active = true
set icon = 'B017'
set class = 'h004'
set subclass = 0
set category = 1
set levelReq = 1
set tier = 1
set target = "Enemy"
set description = "Slams the ground and deals @ physical damage to surrounding enemies and causes @ seconds stun."
set mutation[0] = "Stun duration is increased to 1.5 seconds."
set mutation[1] = "Stun duration is increased to 2 seconds."
set mutation[2] = "Stun duration is increased to 2.5 seconds."
// 2. Rapid Attack
set this = create()
set name = "Rapid Attack"
set cooldown[0] = 60.0
set cooldown[1] = 60.0
set cooldown[2] = 60.0
set cooldown[3] = 60.0
set cooldown[4] = 60.0
set cooldown[5] = 60.0
set cooldown[6] = 60.0
set cooldown[7] = 60.0
set cooldown[8] = 60.0
set cooldown[9] = 60.0
set cooldown[10] = 60.0
set cooldown[11] = 60.0
set cooldown[12] = 60.0
set cooldown[13] = 60.0
set cooldown[14] = 60.0
set cooldown[15] = 60.0
set manacost[0] = 10.0
set manacost[1] = 10.0
set manacost[2] = 10.0
set manacost[3] = 10.0
set manacost[4] = 10.0
set manacost[5] = 20.0
set manacost[6] = 20.0
set manacost[7] = 20.0
set manacost[8] = 20.0
set manacost[9] = 20.0
set manacost[10] = 30.0
set manacost[11] = 30.0
set manacost[12] = 30.0
set manacost[13] = 30.0
set manacost[14] = 30.0
set manacost[15] = 40.0
set active = true
set icon = 'B02R'
set class = 'h004'
set subclass = 0
set category = 2
set levelReq = 5
set tier = 2
set target = "Self"
set description = "Increases attack rate by @ for @ seconds."
set mutation[0] = "Duration is increased to 20 seconds."
set mutation[1] = "Duration is increased to 25 seconds."
set mutation[2] = "Duration is increased to 30 seconds."
// 3. Taunt
set this = create()
set name = "Taunt"
set cooldown[0] = 16.0
set cooldown[1] = 16.0
set cooldown[2] = 16.0
set cooldown[3] = 16.0
set cooldown[4] = 16.0
set cooldown[5] = 16.0
set cooldown[6] = 16.0
set cooldown[7] = 16.0
set cooldown[8] = 16.0
set cooldown[9] = 16.0
set cooldown[10] = 16.0
set cooldown[11] = 16.0
set cooldown[12] = 16.0
set cooldown[13] = 16.0
set cooldown[14] = 16.0
set cooldown[15] = 16.0
set manacost[0] = 20.0
set manacost[1] = 20.0
set manacost[2] = 20.0
set manacost[3] = 20.0
set manacost[4] = 20.0
set manacost[5] = 30.0
set manacost[6] = 30.0
set manacost[7] = 30.0
set manacost[8] = 30.0
set manacost[9] = 30.0
set manacost[10] = 40.0
set manacost[11] = 40.0
set manacost[12] = 40.0
set manacost[13] = 40.0
set manacost[14] = 40.0
set manacost[15] = 50.0
set active = true
set icon = 'B02S'
set class = 'h004'
set subclass = 0
set category = 1
set levelReq = 15
set tier = 3
set target = "Enemy"
set description = "Instantly raises threat level by @ points toward surrounding enemies.@"
set mutation[0] = "Conveys 5 seconds fear. Adds 10% miss chance to taunted units."
set mutation[1] = "Fear miss chance is increased to 20%."
set mutation[2] = "Fear miss chance is increased to 30%."
// 4. Solidify
set this = create()
set name = "Solidify"
set cooldown[0] = 60.0
set cooldown[1] = 60.0
set cooldown[2] = 60.0
set cooldown[3] = 60.0
set cooldown[4] = 60.0
set cooldown[5] = 60.0
set cooldown[6] = 60.0
set cooldown[7] = 60.0
set cooldown[8] = 60.0
set cooldown[9] = 60.0
set cooldown[10] = 60.0
set cooldown[11] = 60.0
set cooldown[12] = 60.0
set cooldown[13] = 60.0
set cooldown[14] = 60.0
set cooldown[15] = 60.0
set manacost[0] = 22.0
set manacost[1] = 22.0
set manacost[2] = 24.0
set manacost[3] = 26.0
set manacost[4] = 28.0
set manacost[5] = 30.0
set manacost[6] = 32.0
set manacost[7] = 34.0
set manacost[8] = 36.0
set manacost[9] = 38.0
set manacost[10] = 40.0
set manacost[11] = 42.0
set manacost[12] = 44.0
set manacost[13] = 46.0
set manacost[14] = 48.0
set manacost[15] = 50.0
set active = true
set icon = 'B02T'
set class = 'h004'
set subclass = 0
set category = 2
set levelReq = 30
set tier = 4
set target = "Self"
set description = "Increases physical defense by @ and block chance by @%.@ Lasts for 60 seconds."
set mutation[0] = "Reflects missiles at 5% chance dealing 50% damage."
set mutation[1] = "Reflects missiles at 10% chance dealing 75% damage."
set mutation[2] = "Reflects missiles at 15% chance dealing 100% damage."
// 5. Force Barrier
set this = create()
set name = "Force Barrier"
set cooldown[0] = 90.0
set cooldown[1] = 90.0
set cooldown[2] = 90.0
set cooldown[3] = 90.0
set cooldown[4] = 90.0
set cooldown[5] = 80.0
set cooldown[6] = 80.0
set cooldown[7] = 80.0
set cooldown[8] = 80.0
set cooldown[9] = 80.0
set cooldown[10] = 70.0
set cooldown[11] = 70.0
set cooldown[12] = 70.0
set cooldown[13] = 70.0
set cooldown[14] = 70.0
set cooldown[15] = 60.0
set manacost[0] = 60.0
set manacost[1] = 60.0
set manacost[2] = 65.0
set manacost[3] = 65.0
set manacost[4] = 70.0
set manacost[5] = 70.0
set manacost[6] = 75.0
set manacost[7] = 75.0
set manacost[8] = 80.0
set manacost[9] = 80.0
set manacost[10] = 85.0
set manacost[11] = 85.0
set manacost[12] = 90.0
set manacost[13] = 90.0
set manacost[14] = 95.0
set manacost[15] = 95.0
set active = true
set icon = 'B02U'
set class = 'h004'
set subclass = 0
set category = 1
set levelReq = 45
set tier = 5
set target = "Ally"
set description = "Grants defensive barrier for self and half for nearby allies. Absorbs total of @ damage for 60 seconds."
set mutation[0] = "Cooldown is reduced to 80 seconds."
set mutation[1] = "Cooldown is reduced to 70 seconds."
set mutation[2] = "Cooldown is reduced to 60 seconds."
// 6. Menacing Presence
set this = create()
set name = "Menacing Presence"
set active = false
set icon = 'B02V'
set class = 'h004'
set subclass = 0
set category = 3
set levelReq = 1
set tier = 6
set target = "Enemy"
set description = "Raises threat level toward nearby enemies by @ points per second."
// 7. Foritification
set this = create()
set name = "Foritification"
set active = false
set icon = 'B02W'
set class = 'h004'
set subclass = 0
set category = 3
set levelReq = 7
set tier = 7
set target = "Self"
set description = "Adds @ fortitude attribute bonus."
// 8. Excellent Recovery
set this = create()
set name = "Excellent Recovery"
set active = false
set icon = 'B02X'
set class = 'h004'
set subclass = 0
set category = 3
set levelReq = 15
set tier = 8
set target = "Self"
set description = "Gives @ health regenereation bonus and amplifies healing effects by @%."
endif
if /* Royalty */ true then
// 9. Double Crash
set this = create()
set name = "Double Crash"
set cooldown[0] = 0.0
set cooldown[1] = 0.0
set cooldown[2] = 0.0
set cooldown[3] = 0.0
set cooldown[4] = 0.0
set cooldown[5] = 0.0
set cooldown[6] = 0.0
set cooldown[7] = 0.0
set cooldown[8] = 0.0
set cooldown[9] = 0.0
set cooldown[10] = 0.0
set cooldown[11] = 0.0
set cooldown[12] = 0.0
set cooldown[13] = 0.0
set cooldown[14] = 0.0
set cooldown[15] = 0.0
set manacost[0] = 5.0
set manacost[1] = 5.0
set manacost[2] = 6.0
set manacost[3] = 7.0
set manacost[4] = 8.0
set manacost[5] = 9.0
set manacost[6] = 10.0
set manacost[7] = 11.0
set manacost[8] = 12.0
set manacost[9] = 13.0
set manacost[10] = 14.0
set manacost[11] = 15.0
set manacost[12] = 16.0
set manacost[13] = 17.0
set manacost[14] = 18.0
set manacost[15] = 19.0
set active = true
set icon = 'B00O'
set class = 'h004'
set subclass = 1
set category = 1
set levelReq = 1
set tier = 1
set target = "Enemy"
set description = "Performs a double slashing attacks dealing @% physical damage each."
set mutation[0] = "Has 5% interruption chance."
set mutation[1] = "Has 10% interruption chance."
set mutation[2] = "Has 15% interruption chance."
// 10. Counter Attack
set this = create()
set name = "Counter Stance"
set cooldown[0] = 30.0
set cooldown[1] = 30.0
set cooldown[2] = 30.0
set cooldown[3] = 30.0
set cooldown[4] = 30.0
set cooldown[5] = 30.0
set cooldown[6] = 30.0
set cooldown[7] = 30.0
set cooldown[8] = 30.0
set cooldown[9] = 30.0
set cooldown[10] = 30.0
set cooldown[11] = 30.0
set cooldown[12] = 30.0
set cooldown[13] = 30.0
set cooldown[14] = 30.0
set cooldown[15] = 30.0
set manacost[0] = 15.0
set manacost[1] = 15.0
set manacost[2] = 15.0
set manacost[3] = 15.0
set manacost[4] = 15.0
set manacost[5] = 20.5
set manacost[6] = 20.5
set manacost[7] = 20.5
set manacost[8] = 20.5
set manacost[9] = 20.5
set manacost[10] = 25.0
set manacost[11] = 25.0
set manacost[12] = 25.0
set manacost[13] = 25.0
set manacost[14] = 25.0
set manacost[15] = 30.5
set active = true
set icon = 'B02Y'
set class = 'h004'
set subclass = 1
set category = 2
set levelReq = 5
set tier = 2
set target = "Self"
set description = "Gives @% chance to perform counter attack against melee attacker, dealing @% physical damage. Lasts for @ seconds."
set mutation[0] = "Deals 75% physical damage."
set mutation[1] = "Deals 100% physical damage."
set mutation[2] = "Deals 125% physical damage."
// 11. Valiant Charge
set this = create()
set name = "Valiant Charge"
set cooldown[0] = 6.0
set cooldown[1] = 6.0
set cooldown[2] = 6.0
set cooldown[3] = 6.0
set cooldown[4] = 6.0
set cooldown[5] = 6.0
set cooldown[6] = 6.0
set cooldown[7] = 6.0
set cooldown[8] = 6.0
set cooldown[9] = 6.0
set cooldown[10] = 6.0
set cooldown[11] = 6.0
set cooldown[12] = 6.0
set cooldown[13] = 6.0
set cooldown[14] = 6.0
set cooldown[15] = 6.0
set manacost[0] = 20.0
set manacost[1] = 20.0
set manacost[2] = 21.0
set manacost[3] = 22.0
set manacost[4] = 23.0
set manacost[5] = 24.0
set manacost[6] = 25.0
set manacost[7] = 26.0
set manacost[8] = 27.0
set manacost[9] = 28.0
set manacost[10] = 29.0
set manacost[11] = 30.0
set manacost[12] = 31.0
set manacost[13] = 32.0
set manacost[14] = 33.0
set manacost[15] = 34.0
set active = true
set icon = 'B02Z'
set class = 'h004'
set subclass = 1
set category = 1
set levelReq = 15
set tier = 3
set target = "None"
set description = "Violently charges forward. Deals @ damage to enemies in line. Knocks struck enemies @ meter away@."
set mutation[0] = "Conveys 1 second stun to struck enemies."
set mutation[1] = "Charge distance is increased by 3 meter."
set mutation[2] = "Conveys 2 seconds stun to struck enemies."
// 12. Holy Shield
set this = create()
set name = "Holy Shield"
set cooldown[0] = 25.0
set cooldown[1] = 25.0
set cooldown[2] = 25.0
set cooldown[3] = 25.0
set cooldown[4] = 25.0
set cooldown[5] = 25.0
set cooldown[6] = 25.0
set cooldown[7] = 25.0
set cooldown[8] = 25.0
set cooldown[9] = 25.0
set cooldown[10] = 25.0
set cooldown[11] = 25.0
set cooldown[12] = 25.0
set cooldown[13] = 25.0
set cooldown[14] = 25.0
set cooldown[15] = 25.0
set manacost[0] = 30.0
set manacost[1] = 30.0
set manacost[2] = 30.0
set manacost[3] = 30.0
set manacost[4] = 30.0
set manacost[5] = 40.0
set manacost[6] = 40.0
set manacost[7] = 40.0
set manacost[8] = 40.0
set manacost[9] = 40.0
set manacost[10] = 50.0
set manacost[11] = 50.0
set manacost[12] = 50.0
set manacost[13] = 50.0
set manacost[14] = 50.0
set manacost[15] = 60.0
set active = true
set icon = 'B030'
set class = 'h004'
set subclass = 1
set category = 2
set levelReq = 30
set tier = 4
set target = "Ally"
set description = "Increases nearby allies' physical defense by @@. Lasts for @ seconds."
set mutation[0] = "Also increases magic defense."
set mutation[1] = "Also increases elemental resistance."
set mutation[2] = "Also increases attack power."
// 13. Piercing Jab
set this = create()
set name = "Piercing Jab"
set cooldown[0] = 8.0
set cooldown[1] = 8.0
set cooldown[2] = 8.0
set cooldown[3] = 8.0
set cooldown[4] = 8.0
set cooldown[5] = 8.0
set cooldown[6] = 8.0
set cooldown[7] = 8.0
set cooldown[8] = 8.0
set cooldown[9] = 8.0
set cooldown[10] = 8.0
set cooldown[11] = 8.0
set cooldown[12] = 8.0
set cooldown[13] = 8.0
set cooldown[14] = 8.0
set cooldown[15] = 8.0
set manacost[0] = 51.0
set manacost[1] = 52.0
set manacost[2] = 53.0
set manacost[3] = 54.0
set manacost[4] = 55.0
set manacost[5] = 56.0
set manacost[6] = 57.0
set manacost[7] = 58.0
set manacost[8] = 59.0
set manacost[9] = 60.0
set manacost[10] = 61.0
set manacost[11] = 62.0
set manacost[12] = 63.0
set manacost[13] = 64.0
set manacost[14] = 65.0
set manacost[15] = 66.0
set active = true
set icon = 'B031'
set class = 'h004'
set subclass = 1
set category = 1
set levelReq = 45
set tier = 5
set target = "Enemy"
set description = "A fierce jab into the air creating a piercing condensed air that deals @% physical damage to enemies in line within @ meter away."
set mutation[0] = "Distance is increased to 11.25 meter."
set mutation[1] = "Distance is increased to 12.5 meter."
set mutation[2] = "Distance is increased to 13.75 meter."
// 14. Protection Vigor
set this = create()
set name = "Protection Vigor"
set active = false
set icon = 'B034'
set class = 'h004'
set subclass = 1
set category = 3
set levelReq = 1
set tier = 6
set target = "Self"
set description = "Distributes @% of worn shield's defense into physical damage."
// 15. Unholy Strength
set this = create()
set name = "Unholy Strength"
set active = false
set icon = 'B032'
set class = 'h004'
set subclass = 1
set category = 3
set levelReq = 7
set tier = 7
set target = "Self"
set description = "Adds @ strength attribute bonus."
// 16. Divine Resistance
set this = create()
set name = "Divine Resistance"
set active = false
set icon = 'B033'
set class = 'h004'
set subclass = 1
set category = 3
set levelReq = 15
set tier = 8
set target = "Self"
set description = "Adds @ resistance toward fire, earth, water, and wind elements."
endif
if /* Dark Knight */ true then
// 17. Darkness Claw
set this = create()
set name = "Darkness Claw"
set cooldown[0] = 3.0
set cooldown[1] = 3.0
set cooldown[2] = 3.0
set cooldown[3] = 3.0
set cooldown[4] = 3.0
set cooldown[5] = 3.0
set cooldown[6] = 3.0
set cooldown[7] = 3.0
set cooldown[8] = 3.0
set cooldown[9] = 3.0
set cooldown[10] = 3.0
set cooldown[11] = 3.0
set cooldown[12] = 3.0
set cooldown[13] = 3.0
set cooldown[14] = 3.0
set cooldown[15] = 3.0
set manacost[0] = 8.0
set manacost[1] = 8.0
set manacost[2] = 8.0
set manacost[3] = 8.0
set manacost[4] = 8.0
set manacost[5] = 8.0
set manacost[6] = 8.0
set manacost[7] = 8.0
set manacost[8] = 8.0
set manacost[9] = 8.0
set manacost[10] = 10.0
set manacost[11] = 10.0
set manacost[12] = 10.0
set manacost[13] = 10.0
set manacost[14] = 10.0
set manacost[15] = 12.0
set active = true
set icon = 'B05J'
set class = 'h004'
set subclass = 2
set category = 1
set levelReq = 1
set tier = 1
set target = "Enemy"
set description = "Slashes all enemies in line dealing @% physic damage."
set mutation[0] = "Slash distance is increased by 5 m."
set mutation[1] = "Creates 2 projectiles."
set mutation[2] = "Creates 3 projectiles."
// 18. Vampiric Groan
set this = create()
set name = "Vampiric Groan"
set cooldown[0] = 12.0
set cooldown[1] = 12.0
set cooldown[2] = 12.0
set cooldown[3] = 12.0
set cooldown[4] = 12.0
set cooldown[5] = 12.0
set cooldown[6] = 12.0
set cooldown[7] = 12.0
set cooldown[8] = 12.0
set cooldown[9] = 12.0
set cooldown[10] = 12.0
set cooldown[11] = 12.0
set cooldown[12] = 12.0
set cooldown[13] = 12.0
set cooldown[14] = 12.0
set cooldown[15] = 12.0
set manacost[0] = 15.0
set manacost[1] = 15.0
set manacost[2] = 15.0
set manacost[3] = 15.0
set manacost[4] = 15.0
set manacost[5] = 20.0
set manacost[6] = 20.0
set manacost[7] = 20.0
set manacost[8] = 20.0
set manacost[9] = 20.0
set manacost[10] = 25.0
set manacost[11] = 25.0
set manacost[12] = 25.0
set manacost[13] = 25.0
set manacost[14] = 25.0
set manacost[15] = 30.0
set active = true
set icon = 'B05K'
set class = 'h004'
set subclass = 2
set category = 1
set levelReq = 5
set tier = 2
set target = "Enemy"
set description = "Absorbs surrounding enemies' health by @ points per second@. Only @ targets can be affected at once."
set mutation[0] = "Also absorbs mana."
set mutation[1] = "Maximum target is increased to 5 units."
set mutation[2] = "Maximum target is increased to 6 units."
// 19. Dreadful Howl
set this = create()
set name = "Dreadful Howl"
set cooldown[0] = 10.0
set cooldown[1] = 10.0
set cooldown[2] = 10.0
set cooldown[3] = 10.0
set cooldown[4] = 10.0
set cooldown[5] = 10.0
set cooldown[6] = 10.0
set cooldown[7] = 10.0
set cooldown[8] = 10.0
set cooldown[9] = 10.0
set cooldown[10] = 10.0
set cooldown[11] = 10.0
set cooldown[12] = 10.0
set cooldown[13] = 10.0
set cooldown[14] = 10.0
set cooldown[15] = 10.0
set manacost[0] = 10.0
set manacost[1] = 10.0
set manacost[2] = 10.0
set manacost[3] = 10.0
set manacost[4] = 10.0
set manacost[5] = 15.0
set manacost[6] = 15.0
set manacost[7] = 15.0
set manacost[8] = 15.0
set manacost[9] = 15.0
set manacost[10] = 20.0
set manacost[11] = 20.0
set manacost[12] = 20.0
set manacost[13] = 20.0
set manacost[14] = 20.0
set manacost[15] = 25.0
set active = true
set icon = 'B05N'
set class = 'h004'
set subclass = 2
set category = 1
set levelReq = 15
set tier = 3
set target = "Enemy"
set description = "Reduces nearby enemies' accuracy by @%, physical defense by @, and magic defense by @. Lasts for @ seconds."
set mutation[0] = "Duration is increased to 7 seconds."
set mutation[1] = "Duration is increased to 10 seconds."
set mutation[2] = "Duration is increased to 15 seconds."
// 20. Spectra Vortex
set this = create()
set name = "Spectra Vortex"
set cooldown[0] = 60.0
set cooldown[1] = 60.0
set cooldown[2] = 60.0
set cooldown[3] = 60.0
set cooldown[4] = 60.0
set cooldown[5] = 60.0
set cooldown[6] = 60.0
set cooldown[7] = 60.0
set cooldown[8] = 60.0
set cooldown[9] = 60.0
set cooldown[10] = 60.0
set cooldown[11] = 60.0
set cooldown[12] = 60.0
set cooldown[13] = 60.0
set cooldown[14] = 60.0
set cooldown[15] = 60.0
set manacost[0] = 50.0
set manacost[1] = 50.0
set manacost[2] = 50.0
set manacost[3] = 50.0
set manacost[4] = 50.0
set manacost[5] = 60.0
set manacost[6] = 60.0
set manacost[7] = 60.0
set manacost[8] = 60.0
set manacost[9] = 60.0
set manacost[10] = 70.0
set manacost[11] = 70.0
set manacost[12] = 70.0
set manacost[13] = 70.0
set manacost[14] = 70.0
set manacost[15] = 80.0
set active = true
set icon = 'B05L'
set class = 'h004'
set subclass = 2
set category = 1
set levelReq = 30
set tier = 4
set target = "Enemy"
set description = "Projects a Specter as manifestation of depravity. The Specter possesses @% of master's physic damage and has splashing magic attacks. Has @ seconds lifespan."
set mutation[0] = "Duration is increased to 50 seconds."
set mutation[1] = "Duration is increased to 55 seconds."
set mutation[2] = "Duration is increased to 60 seconds."
// 21. Nightmare Fall
set this = create()
set name = "Nightmare Fall"
set cooldown[0] = 13.0
set cooldown[1] = 13.0
set cooldown[2] = 13.0
set cooldown[3] = 13.0
set cooldown[4] = 13.0
set cooldown[5] = 13.0
set cooldown[6] = 13.0
set cooldown[7] = 13.0
set cooldown[8] = 13.0
set cooldown[9] = 13.0
set cooldown[10] = 13.0
set cooldown[11] = 13.0
set cooldown[12] = 13.0
set cooldown[13] = 13.0
set cooldown[14] = 13.0
set cooldown[15] = 13.0
set manacost[0] = 50.0
set manacost[1] = 50.0
set manacost[2] = 50.0
set manacost[3] = 50.0
set manacost[4] = 50.0
set manacost[5] = 60.0
set manacost[6] = 60.0
set manacost[7] = 60.0
set manacost[8] = 60.0
set manacost[9] = 60.0
set manacost[10] = 70.0
set manacost[11] = 70.0
set manacost[12] = 70.0
set manacost[13] = 70.0
set manacost[14] = 70.0
set manacost[15] = 80.0
set active = true
set icon = 'B05M'
set class = 'h004'
set subclass = 2
set category = 1
set levelReq = 45
set tier = 5
set target = "Enemy"
set description = "Calls forth @ wandering pillars of darkflame. Dealing @ damage per second to struck enemies."
set mutation[0] = "Summons 5 pillars."
set mutation[1] = "Summons 6 pillars."
set mutation[2] = "Summons 7 pillars."
// 22. Corrupted Blade
set this = create()
set name = "Corrupted Blade"
set active = false
set icon = 'B05O'
set class = 'h004'
set subclass = 2
set category = 3
set levelReq = 1
set tier = 6
set target = "Enemy"
set description = "Reduces damaged unit's physical defense by @ for 10 seconds."
// 23. Dark Arts
set this = create()
set name = "Dark Arts"
set active = false
set icon = 'B05P'
set class = 'h004'
set subclass = 2
set category = 3
set levelReq = 7
set tier = 7
set target = "Self"
set description = "Adds @ wisdom attribute bonus and enhance physical damage by @%."
// 24. Soulbound
set this = create()
set name = "Soulbound"
set active = false
set icon = 'B05Q'
set class = 'h004'
set subclass = 2
set category = 3
set levelReq = 15
set tier = 8
set target = "Enemy"
set description = "Absorbs @% of any killed enemy's max health point to heal self."
endif
if /* Huntress */ true then
// 25. Bouncing Glaive
set this = create()
set name = "Bouncing Glaive"
set cooldown[0] = 0.5
set cooldown[1] = 0.5
set cooldown[2] = 0.5
set cooldown[3] = 0.5
set cooldown[4] = 0.5
set cooldown[5] = 0.5
set cooldown[6] = 0.5
set cooldown[7] = 0.5
set cooldown[8] = 0.5
set cooldown[9] = 0.5
set cooldown[10] = 0.5
set cooldown[11] = 0.5
set cooldown[12] = 0.5
set cooldown[13] = 0.5
set cooldown[14] = 0.5
set cooldown[15] = 0.5
set manacost[0] = 5.0
set manacost[1] = 6.0
set manacost[2] = 7.0
set manacost[3] = 8.0
set manacost[4] = 9.0
set manacost[5] = 10.0
set manacost[6] = 11.0
set manacost[7] = 12.0
set manacost[8] = 13.0
set manacost[9] = 14.0
set manacost[10] = 15.0
set manacost[11] = 16.0
set manacost[12] = 17.0
set manacost[13] = 18.0
set manacost[14] = 19.0
set manacost[15] = 20.0
set active = true
set icon = 'B06W'
set class = 'h00C'
set subclass = 0
set category = 1
set levelReq = 1
set tier = 1
set target = "Enemy"
set description = "Throws a glaive that bounces between enemies @ times and deals @ damage each."
set mutation[0] = "The glaive bounces 3 times."
set mutation[1] = "The glaive bounces 4 times."
set mutation[2] = "The glaive bounces 5 times."
// 26. Shadow Meld
set this = create()
set name = "Shadow Meld"
set cooldown[0] = 25.0
set cooldown[1] = 25.0
set cooldown[2] = 25.0
set cooldown[3] = 25.0
set cooldown[4] = 25.0
set cooldown[5] = 25.0
set cooldown[6] = 25.0
set cooldown[7] = 25.0
set cooldown[8] = 25.0
set cooldown[9] = 25.0
set cooldown[10] = 25.0
set cooldown[11] = 25.0
set cooldown[12] = 25.0
set cooldown[13] = 25.0
set cooldown[14] = 25.0
set cooldown[15] = 25.0
set manacost[0] = 10.0
set manacost[1] = 10.0
set manacost[2] = 10.0
set manacost[3] = 10.0
set manacost[4] = 10.0
set manacost[5] = 13.0
set manacost[6] = 13.0
set manacost[7] = 13.0
set manacost[8] = 13.0
set manacost[9] = 13.0
set manacost[10] = 16.0
set manacost[11] = 16.0
set manacost[12] = 16.0
set manacost[13] = 16.0
set manacost[14] = 16.0
set manacost[15] = 20.0
set active = true
set icon = 'B062'
set class = 'h00C'
set subclass = 0
set category = 1
set levelReq = 5
set tier = 2
set target = "Self"
set description = "Becomes invisible@. Adds @ bonus damage to the first strike. Lasts for 30 seconds."
set mutation[0] = "Increases movespeed by 5%."
set mutation[1] = "Increases movespeed by 10%."
set mutation[2] = "Increases movespeed by 15%."
// 27. Tranquilizer
set this = create()
set name = "Tranquilizer"
set cooldown[0] = 11.0
set cooldown[1] = 11.0
set cooldown[2] = 11.0
set cooldown[3] = 11.0
set cooldown[4] = 11.0
set cooldown[5] = 11.0
set cooldown[6] = 11.0
set cooldown[7] = 11.0
set cooldown[8] = 11.0
set cooldown[9] = 11.0
set cooldown[10] = 11.0
set cooldown[11] = 11.0
set cooldown[12] = 11.0
set cooldown[13] = 11.0
set cooldown[14] = 11.0
set cooldown[15] = 11.0
set manacost[0] = 5.0
set manacost[1] = 5.0
set manacost[2] = 5.0
set manacost[3] = 5.0
set manacost[4] = 5.0
set manacost[5] = 5.0
set manacost[6] = 5.0
set manacost[7] = 5.0
set manacost[8] = 5.0
set manacost[9] = 5.0
set manacost[10] = 5.0
set manacost[11] = 5.0
set manacost[12] = 5.0
set manacost[13] = 5.0
set manacost[14] = 5.0
set manacost[15] = 5.0
set active = true
set icon = 'B063'
set class = 'h00C'
set subclass = 0
set category = 1
set levelReq = 15
set tier = 3
set target = "Enemy"
set description = "Fires a tranquilizing arrow that lulls the victim for @ seconds. Hitting the victim @will dispel the effect."
set mutation[0] = "Takes 2 hits to wake tranquilized units."
set mutation[1] = "Takes 3 hits to wake tranquilized units."
set mutation[2] = "Takes 4 hits to wake tranquilized units."
// 28. Snare Traps
set this = create()
set name = "Snare Trap"
set cooldown[0] = 10.0
set cooldown[1] = 10.0
set cooldown[2] = 10.0
set cooldown[3] = 10.0
set cooldown[4] = 10.0
set cooldown[5] = 10.0
set cooldown[6] = 10.0
set cooldown[7] = 10.0
set cooldown[8] = 10.0
set cooldown[9] = 10.0
set cooldown[10] = 10.0
set cooldown[11] = 10.0
set cooldown[12] = 10.0
set cooldown[13] = 10.0
set cooldown[14] = 10.0
set cooldown[15] = 10.0
set manacost[0] = 11.0
set manacost[1] = 11.0
set manacost[2] = 12.0
set manacost[3] = 13.0
set manacost[4] = 14.0
set manacost[5] = 15.0
set manacost[6] = 16.0
set manacost[7] = 17.0
set manacost[8] = 18.0
set manacost[9] = 19.0
set manacost[10] = 20.0
set manacost[11] = 21.0
set manacost[12] = 22.0
set manacost[13] = 23.0
set manacost[14] = 24.0
set manacost[15] = 25.0
set active = true
set icon = 'B064'
set class = 'h00C'
set subclass = 0
set category = 1
set levelReq = 30
set tier = 4
set target = "Enemy"
set description = "Sets a snaring trap at the target location. Instantly sprung if thrown at a unit. Slows captured units movespeed by @%@ for @ seconds. The trap lasts for @ seconds."
set mutation[0] = "Also reduces accuracy."
set mutation[1] = "Trap lifespan is extended to 120 seconds."
set mutation[2] = "Disables ranged units."
// 29. Ferocious Hail
set this = create()
set name = "Ferocious Hail"
set cooldown[0] = 8.0
set cooldown[1] = 8.0
set cooldown[2] = 8.0
set cooldown[3] = 8.0
set cooldown[4] = 8.0
set cooldown[5] = 8.0
set cooldown[6] = 8.0
set cooldown[7] = 8.0
set cooldown[8] = 8.0
set cooldown[9] = 8.0
set cooldown[10] = 8.0
set cooldown[11] = 8.0
set cooldown[12] = 8.0
set cooldown[13] = 8.0
set cooldown[14] = 8.0
set cooldown[15] = 8.0
set manacost[0] = 40.0
set manacost[1] = 40.0
set manacost[2] = 40.0
set manacost[3] = 40.0
set manacost[4] = 40.0
set manacost[5] = 40.0
set manacost[6] = 40.0
set manacost[7] = 40.0
set manacost[8] = 40.0
set manacost[9] = 40.0
set manacost[10] = 40.0
set manacost[11] = 40.0
set manacost[12] = 40.0
set manacost[13] = 40.0
set manacost[14] = 40.0
set manacost[15] = 40.0
set active = true
set icon = 'B065'
set class = 'h00C'
set subclass = 0
set category = 1
set levelReq = 45
set tier = 5
set target = "Enemy"
set description = "Barrages over the target area with hail of arrows dealing @ damage per second@. Has @ meter area of effect radius."
set mutation[0] = "Also applies slow."
set mutation[1] = "Area of effect radius is increased to 3 meter."
set mutation[2] = "Also reduces physic armor."
// 30. Silent Step
set this = create()
set name = "Silent Step"
set active = false
set icon = 'B066'
set class = 'h00C'
set subclass = 0
set category = 3
set levelReq = 1
set tier = 6
set target = "Enemy"
set description = "Reduces monster aggro range by @ meter."
// 31. Alacrity
set this = create()
set name = "Alacrity"
set active = false
set icon = 'B067'
set class = 'h00C'
set subclass = 0
set category = 3
set levelReq = 7
set tier = 7
set target = "Self"
set description = "Adds @ dexterity attribute bonus."
// 32. Poison Coating
set this = create()
set name = "Poison Coating"
set active = false
set icon = 'B068'
set class = 'h00C'
set subclass = 0
set category = 3
set levelReq = 15
set tier = 8
set target = "Self"
set description = "Gives @% chance to apply poison on attacks. Deals @ damage per second for 5 seconds."
endif
if /* Ranger */ true then
// 33. Quick shot
set this = create()
set name = "Quick Shot"
set cooldown[0] = 4.0
set cooldown[1] = 4.0
set cooldown[2] = 4.0
set cooldown[3] = 4.0
set cooldown[4] = 4.0
set cooldown[5] = 3.0
set cooldown[6] = 3.0
set cooldown[7] = 3.0
set cooldown[8] = 3.0
set cooldown[9] = 3.0
set cooldown[10] = 2.0
set cooldown[11] = 2.0
set cooldown[12] = 2.0
set cooldown[13] = 2.0
set cooldown[14] = 2.0
set cooldown[15] = 2.0
set manacost[0] = 5.0
set manacost[1] = 6.0
set manacost[2] = 7.0
set manacost[3] = 8.0
set manacost[4] = 9.0
set manacost[5] = 10.0
set manacost[6] = 11.0
set manacost[7] = 12.0
set manacost[8] = 13.0
set manacost[9] = 14.0
set manacost[10] = 15.0
set manacost[11] = 16.0
set manacost[12] = 17.0
set manacost[13] = 18.0
set manacost[14] = 19.0
set manacost[15] = 23.0
set active = true
set icon = 'B061'
set class = 'h00C'
set subclass = 1
set category = 1
set levelReq = 1
set tier = 1
set target = "Enemy"
set description = "Swiftly attacks @ dealing @% physical damage each."
set mutation[0] = "Cooldown is reduced to 3 seconds."
set mutation[1] = "Cooldown is reduced to 2 seconds."
set mutation[2] = "Performs one additional attack."
// 34. Fast Reload
set this = create()
set name = "Fast Reload"
set cooldown[0] = 60.0
set cooldown[1] = 60.0
set cooldown[2] = 60.0
set cooldown[3] = 60.0
set cooldown[4] = 60.0
set cooldown[5] = 60.0
set cooldown[6] = 60.0
set cooldown[7] = 60.0
set cooldown[8] = 60.0
set cooldown[9] = 60.0
set cooldown[10] = 60.0
set cooldown[11] = 60.0
set cooldown[12] = 60.0
set cooldown[13] = 60.0
set cooldown[14] = 60.0
set cooldown[15] = 60.0
set manacost[0] = 10.0
set manacost[1] = 10.0
set manacost[2] = 10.0
set manacost[3] = 10.0
set manacost[4] = 10.0
set manacost[5] = 15.0
set manacost[6] = 15.0
set manacost[7] = 15.0
set manacost[8] = 15.0
set manacost[9] = 15.0
set manacost[10] = 20.0
set manacost[11] = 20.0
set manacost[12] = 20.0
set manacost[13] = 20.0
set manacost[14] = 20.0
set manacost[15] = 25.0
set active = true
set icon = 'B06X'
set class = 'h00C'
set subclass = 1
set category = 2
set levelReq = 5
set tier = 2
set target = "Self"
set description = "Increases attack rate by @ for @ seconds."
set mutation[0] = "Duration is increased to 90 seconds."
set mutation[1] = "Duration is increased to 120 seconds."
set mutation[2] = "Duration is increased to 150 seconds."
// 35. Summon Wolf
set this = create()
set name = "Summon Wolf"
set cooldown[0] = 60.0
set cooldown[1] = 60.0
set cooldown[2] = 60.0
set cooldown[3] = 60.0
set cooldown[4] = 60.0
set cooldown[5] = 60.0
set cooldown[6] = 60.0
set cooldown[7] = 60.0
set cooldown[8] = 60.0
set cooldown[9] = 60.0
set cooldown[10] = 60.0
set cooldown[11] = 60.0
set cooldown[12] = 60.0
set cooldown[13] = 60.0
set cooldown[14] = 60.0
set cooldown[15] = 60.0
set manacost[0] = 15.0
set manacost[1] = 15.0
set manacost[2] = 15.0
set manacost[3] = 15.0
set manacost[4] = 15.0
set manacost[5] = 15.0
set manacost[6] = 15.0
set manacost[7] = 15.0
set manacost[8] = 15.0
set manacost[9] = 15.0
set manacost[10] = 15.0
set manacost[11] = 15.0
set manacost[12] = 15.0
set manacost[13] = 15.0
set manacost[14] = 15.0
set manacost[15] = 15.0
set active = true
set icon = 'B06Y'
set class = 'h00C'
set subclass = 1
set category = 1
set levelReq = 15
set tier = 3
set target = "None"
set description = "Summons a companion wolf with @ - @ damage and @ health points.@"
set mutation[0] = "Grants Critical Strike ability that gives 15% chance to deal 150% damage."
set mutation[1] = "Critical chance is increased to 20%."
set mutation[2] = "Critical chance is increased to 25%."
// 36. Acute Sight
set this = create()
set name = "Acute Sight"
set cooldown[0] = 30.0
set cooldown[1] = 30.0
set cooldown[2] = 30.0
set cooldown[3] = 30.0
set cooldown[4] = 30.0
set cooldown[5] = 30.0
set cooldown[6] = 30.0
set cooldown[7] = 30.0
set cooldown[8] = 30.0
set cooldown[9] = 30.0
set cooldown[10] = 30.0
set cooldown[11] = 30.0
set cooldown[12] = 30.0
set cooldown[13] = 30.0
set cooldown[14] = 30.0
set cooldown[15] = 30.0
set manacost[0] = 15.0
set manacost[1] = 15.0
set manacost[2] = 15.0
set manacost[3] = 15.0
set manacost[4] = 15.0
set manacost[5] = 20.0
set manacost[6] = 20.0
set manacost[7] = 20.0
set manacost[8] = 20.0
set manacost[9] = 20.0
set manacost[10] = 25.0
set manacost[11] = 25.0
set manacost[12] = 25.0
set manacost[13] = 25.0
set manacost[14] = 25.0
set manacost[15] = 30.0
set active = true
set icon = 'B06Z'
set class = 'h00C'
set subclass = 1
set category = 2
set levelReq = 30
set tier = 4
set target = "Self"
set description = "Increases accuracy by @@ for 30 seconds."
set mutation[0] = "Also increases critical chance."
set mutation[1] = "Also increases interruption chance."
set mutation[2] = "Also increases physic damage."
// 37. Primal Strike
set this = create()
set name = "Primal Strike"
set cooldown[0] = 9.0
set cooldown[1] = 9.0
set cooldown[2] = 9.0
set cooldown[3] = 9.0
set cooldown[4] = 9.0
set cooldown[5] = 9.0
set cooldown[6] = 9.0
set cooldown[7] = 9.0
set cooldown[8] = 9.0
set cooldown[9] = 9.0
set cooldown[10] = 9.0
set cooldown[11] = 9.0
set cooldown[12] = 9.0
set cooldown[13] = 9.0
set cooldown[14] = 9.0
set cooldown[15] = 7.0
set manacost[0] = 31.0
set manacost[1] = 32.0
set manacost[2] = 72.0
set manacost[3] = 73.0
set manacost[4] = 74.0
set manacost[5] = 75.0
set manacost[6] = 76.0
set manacost[7] = 77.0
set manacost[8] = 78.0
set manacost[9] = 79.0
set manacost[10] = 80.0
set manacost[11] = 81.0
set manacost[12] = 82.0
set manacost[13] = 83.0
set manacost[14] = 84.0
set manacost[15] = 85.0
set active = true
set icon = 'B070'
set class = 'h00C'
set subclass = 1
set category = 1
set levelReq = 45
set tier = 5
set target = "Enemy"
set description = "Fires a highly concentrated shot dealing @% damage to a single target@."
set mutation[0] = "Applies knockback."
set mutation[1] = "Maximum distance is increased by 5 meter."
set mutation[2] = "Cooldown is reduced to 7 seconds."
// 38. Extended Range
set this = create()
set name = "Extended Range"
set active = false
set icon = 'B071'
set class = 'h00C'
set subclass = 1
set category = 3
set levelReq = 1
set tier = 6
set target = "Self"
set description = "Increases attack range by @ meter."
// 39. Catlike Reflex
set this = create()
set name = "Catlike Reflex"
set active = false
set icon = 'B072'
set class = 'h00C'
set subclass = 1
set category = 3
set levelReq = 7
set tier = 7
set target = "Self"
set description = "Increases evasion by @."
// 40. Compact Bolt
set this = create()
set name = "Compact Bolt"
set active = false
set icon = 'B073'
set class = 'h00C'
set subclass = 1
set category = 3
set levelReq = 15
set tier = 8
set target = "Self"
set description = "Uses a special bolt that has increased damage based on distance traveled. Increases damage by @ for every one meter."
endif
if /* Lune Archer */ true then
// 41. Triple Shard
set this = create()
set name = "Triple Shard"
set cooldown[0] = 7.0
set cooldown[1] = 7.0
set cooldown[2] = 7.0
set cooldown[3] = 7.0
set cooldown[4] = 7.0
set cooldown[5] = 7.0
set cooldown[6] = 7.0
set cooldown[7] = 7.0
set cooldown[8] = 7.0
set cooldown[9] = 7.0
set cooldown[10] = 7.0
set cooldown[11] = 7.0
set cooldown[12] = 7.0
set cooldown[13] = 7.0
set cooldown[14] = 7.0
set cooldown[15] = 5.0
set manacost[0] = 9.0
set manacost[1] = 10.0
set manacost[2] = 11.0
set manacost[3] = 12.0
set manacost[4] = 13.0
set manacost[5] = 14.0
set manacost[6] = 15.0
set manacost[7] = 16.0
set manacost[8] = 17.0
set manacost[9] = 18.0
set manacost[10] = 19.0
set manacost[11] = 20.0
set manacost[12] = 21.0
set manacost[13] = 22.0
set manacost[14] = 23.0
set manacost[15] = 24.0
set active = true
set icon = 'B074'
set class = 'h00C'
set subclass = 2
set category = 1
set levelReq = 1
set tier = 1
set target = "Enemy"
set description = "Launches @ projectiles. Deals @ physic damage to enemies in a cone."
set mutation[0] = "Max distance is increased by 2 meter."
set mutation[1] = "Launches 4 projectiles."
set mutation[2] = "Cooldown is reduced to 5 seconds."
// 42. Illusory Incarnation
set this = create()
set name = "Illusory Incarnation"
set cooldown[0] = 20.0
set cooldown[1] = 20.0
set cooldown[2] = 20.0
set cooldown[3] = 20.0
set cooldown[4] = 20.0
set cooldown[5] = 20.0
set cooldown[6] = 20.0
set cooldown[7] = 20.0
set cooldown[8] = 20.0
set cooldown[9] = 20.0
set cooldown[10] = 20.0
set cooldown[11] = 20.0
set cooldown[12] = 20.0
set cooldown[13] = 20.0
set cooldown[14] = 20.0
set cooldown[15] = 20.0
set manacost[0] = 15.0
set manacost[1] = 15.0
set manacost[2] = 15.0
set manacost[3] = 15.0
set manacost[4] = 15.0
set manacost[5] = 20.0
set manacost[6] = 20.0
set manacost[7] = 20.0
set manacost[8] = 20.0
set manacost[9] = 20.0
set manacost[10] = 25.0
set manacost[11] = 25.0
set manacost[12] = 25.0
set manacost[13] = 25.0
set manacost[14] = 25.0
set manacost[15] = 30.0
set active = true
set icon = 'B075'
set class = 'h00C'
set subclass = 2
set category = 1
set levelReq = 5
set tier = 2
set target = "None"
set description = "Creates @ illusion@ of self replication. @ illusion deals @% damage and takes @% damage. Lasts for @ seconds."
set mutation[0] = "Duration is extended to 45 seconds."
set mutation[1] = "Duration is extended to 60 seconds."
set mutation[2] = "Creates 3 illusions."
// 43. Lucid Beam
set this = create()
set name = "Lucid Beam"
set cooldown[1] = 0.0
set cooldown[1] = 0.0
set cooldown[2] = 0.0
set cooldown[3] = 0.0
set cooldown[4] = 0.0
set cooldown[5] = 0.0
set cooldown[6] = 0.0
set cooldown[7] = 0.0
set cooldown[8] = 0.0
set cooldown[9] = 0.0
set cooldown[10] = 0.0
set cooldown[11] = 0.0
set cooldown[12] = 0.0
set cooldown[13] = 0.0
set cooldown[14] = 0.0
set cooldown[15] = 0.0
set manacost[0] = 8.0
set manacost[1] = 8.0
set manacost[2] = 9.0
set manacost[3] = 10.0
set manacost[4] = 11.0
set manacost[5] = 12.0
set manacost[6] = 13.0
set manacost[7] = 14.0
set manacost[8] = 15.0
set manacost[9] = 16.0
set manacost[10] = 17.0
set manacost[11] = 18.0
set manacost[12] = 19.0
set manacost[13] = 20.0
set manacost[14] = 21.0
set manacost[15] = 22.0
set active = true
set icon = 'B076'
set class = 'h00C'
set subclass = 2
set category = 1
set levelReq = 15
set tier = 3
set target = "Enemy"
set description = "Emits piercing beam of intense heat. Causing @ damage per second to enemies in a line@. Channeling."
set mutation[0] = "Applies minor knockback."
set mutation[1] = "Ray distance is doubled."
set mutation[2] = "Conveys 1 second silence."
// 44. Force Wall
set this = create()
set name = "Force Wall"
set cooldown[0] = 16.0
set cooldown[1] = 16.0
set cooldown[2] = 16.0
set cooldown[3] = 16.0
set cooldown[4] = 16.0
set cooldown[5] = 16.0
set cooldown[6] = 16.0
set cooldown[7] = 16.0
set cooldown[8] = 16.0
set cooldown[9] = 16.0
set cooldown[10] = 16.0
set cooldown[11] = 16.0
set cooldown[12] = 16.0
set cooldown[13] = 16.0
set cooldown[14] = 16.0
set cooldown[15] = 16.0
set manacost[0] = 23.0
set manacost[1] = 23.0
set manacost[2] = 24.0
set manacost[3] = 25.0
set manacost[4] = 26.0
set manacost[5] = 27.0
set manacost[6] = 28.0
set manacost[7] = 29.0
set manacost[8] = 30.0
set manacost[9] = 31.0
set manacost[10] = 32.0
set manacost[11] = 33.0
set manacost[12] = 34.0
set manacost[13] = 35.0
set manacost[14] = 36.0
set manacost[15] = 37.0
set active = true
set icon = 'B077'
set class = 'h00C'
set subclass = 2
set category = 1
set levelReq = 30
set tier = 4
set target = "None"
set description = "Creates a force wall around the caster that only allow allies to walk through.@ Has @ meter radius and lasts for @ seconds."
set mutation[0] = "Gives 25% chance to reflect ranged unit attacks at 50% damage."
set mutation[1] = "Radius is increased by 2 meter. Missile reflect chance is increased to 35%."
set mutation[2] = "Deals periodic damage to units touching the barrier."
// 45. Lunar Strike
set this = create()
set name = "Lunar Strike"
set cooldown[0] = 13.0
set cooldown[1] = 13.0
set cooldown[2] = 13.0
set cooldown[3] = 13.0
set cooldown[4] = 13.0
set cooldown[5] = 13.0
set cooldown[6] = 13.0
set cooldown[7] = 13.0
set cooldown[8] = 13.0
set cooldown[9] = 13.0
set cooldown[10] = 13.0
set cooldown[11] = 13.0
set cooldown[12] = 13.0
set cooldown[13] = 13.0
set cooldown[14] = 13.0
set cooldown[15] = 13.0
set manacost[0] = 50.0
set manacost[1] = 50.0
set manacost[2] = 50.0
set manacost[3] = 50.0
set manacost[4] = 50.0
set manacost[5] = 55.0
set manacost[6] = 55.0
set manacost[7] = 55.0
set manacost[8] = 55.0
set manacost[9] = 55.0
set manacost[10] = 60.0
set manacost[11] = 60.0
set manacost[12] = 60.0
set manacost[13] = 60.0
set manacost[14] = 60.0
set manacost[15] = 65.0
set active = true
set icon = 'B078'
set class = 'h00C'
set subclass = 2
set category = 1
set levelReq = 45
set tier = 5
set target = "Enemy"
set description = "Unleash a piercing strike of magic projectile dealing @ damage to enemies in line.@"
set mutation[0] = "Gives 10% chance to create an illusion of struck enemies."
set mutation[1] = "Gives 20% chance to create an illusion of struck enemies."
set mutation[2] = "Gives 30% chance to create an illusion of struck enemies."
// 46. Mirage
set this = create()
set name = "Mirage"
set active = false
set icon = 'B079'
set class = 'h00C'
set subclass = 2
set category = 3
set levelReq = 1
set tier = 6
set target = "Self and self illusions"
set description = "Gives @% chance to perform additional attack dealing @% damage. Also affects self illusions."
// 47. Elune's Grace
set this = create()
set name = "Elune's Grace"
set active = false
set icon = 'B07B'
set class = 'h00C'
set subclass = 2
set category = 3
set levelReq = 7
set tier = 7
set target = "Self"
set description = "Increases mana regeneration by @."
// 48. Embodiment
set this = create()
set name = "Embodiment"
set active = false
set icon = 'B07A'
set class = 'h00C'
set subclass = 2
set category = 3
set levelReq = 15
set tier = 8
set target = "Illusions"
set description = "Enhance illusions' durability by extending lifespan by @ seconds and reducing damage taken by @%."
endif
if /* Control Skill */ true then
// i. Order Attack
set this = create()
set ORDER_ATTACK_SKILL = this
set name = "Order Attack"
set cooldown[1] = 1.0
set manacost[1] = 0.0
set lifecost[1] = 0.0
set active = true
set icon = 'B07C'
set class = 0
set subclass = 0
set category = 4
set levelReq = 0
set tier = 0
set target = "Summoned units"
set description = "Orders subordinates to attack target."
// ii. Order Stop
set this = create()
set ORDER_STOP_SKILL = this
set name = "Order Stop"
set cooldown[1] = 1.0
set manacost[1] = 0.0
set lifecost[1] = 0.0
set active = true
set icon = 'B07D'
set class = 0
set subclass = 0
set category = 4
set levelReq = 0
set tier = 0
set target = "Summoned units"
set description = "Orders subordinates to stop attacking."
// iii. Order Guard
set this = create()
set ORDER_MOVE_SKILL = this
set name = "Order Guard"
set cooldown[1] = 1.0
set manacost[1] = 0.0
set lifecost[1] = 0.0
set active = true
set icon = 'B08G'
set class = 0
set subclass = 0
set category = 4
set levelReq = 0
set tier = 0
set target = "Summoned units"
set description = "Orders subordinates to move and guard the target location."
endif
endmodule
struct SkillData
real array manacost[16]
real array lifecost[16]
real array cooldown[16]
string array mutation[3]
real array masteryAdd[16]
boolean active
integer class
integer subclass
integer category
integer levelReq
integer tier
integer icon
string name
string target
string description
static integer EmptyCount = 1
static integer LastId = 0
static method create takes nothing returns thistype
set SkillCount = SkillCount + 1
return allocate()
endmethod
static method InitSkills takes nothing returns nothing
local thistype this
implement InitSkillData
endmethod
endstruct
struct PlayerSkill extends array
SkillData id
integer level
integer pid
real mastery
boolean learnable
SkillRow row
implement LinkedList
static constant integer ACTIVE = 1
static constant integer BUFF = 2
static constant integer PASSIVE = 3
static constant integer FUNCTION = 4
method addMastery takes nothing returns nothing
if RectContainsUnit(gg_rct_Dungeon_Area, MainUnit[pid]) then
if id.category == 1 or id.category == 2 then
if id.masteryAdd[level] <= 0 then
set id.masteryAdd[level] = MasteryGrowthRate[id.tier]*(RMaxBJ(id.cooldown[level], 3.0)/MasteryGrowthTime[level])
endif
call row.setMastery(mastery + id.masteryAdd[level]*SKILL_MASTERY_RATE)
if Tooltips1[pid].control.visible and Tooltips1[pid].skill == this then
call Tooltips1[pid].setSkill(Tooltips1[pid].skill)
endif
endif
endif
endmethod
endstruct
function EvaluateSkillList takes integer id returns nothing
local SkillData data
local SkillRow node = CharacterWindow_SkillRows[id][CharacterWindow_SkillTabIndex[id]].first
local PlayerSkill skill
loop
exitwhen node == 0
set skill = PlayerSkillData[id][node.id]
set data = skill.id
call node.setLevel(skill.level)
if SkillPoint[id] > 0 and node.background.visible and Level[id] >= data.levelReq and ((skill.level == 0 and not CharacterWindow_TierLearned[id][data.tier]) or (skill.level > 0 and not data.active and skill.level < MAXIMUM_PASSIVE_SKILL_LEVEL and Level[id] >= PassiveSkillLevelReq[data.tier-6][skill.level+1])) then
call node.plus.show(true)
call node.plus.refresh()
set node.learnable = true
set skill.learnable = true
else
call node.plus.show(false)
set node.learnable = false
set skill.learnable = false
endif
if skill.level > 0 then
call node.icon.setColor(255, 255, 255, 255)
else
call node.icon.setColor(50, 50, 50, 255)
endif
set node = node.next
endloop
if Tooltips1[id].control.visible then
if Tooltips1[id].skill != 0 then
call Tooltips1[id].setSkill(Tooltips1[id].skill)
endif
endif
endfunction
function RegisterPlayerSkill takes integer id, SkillData data returns PlayerSkill
local PlayerSkill node = 0
set node = PlayerSkill.allocate()
set node.id = data
set node.level = 0
set node.mastery = 0.
set PlayerSkillData[id][data] = node
call Skills[id].insertNode(node)
return node
endfunction
function Learn takes integer id, integer skill returns integer
local PlayerSkill node = PlayerSkillData[id][skill]
if node != 0 then
set node.level = node.level + 1
if (skill == 15) then
call AddAttPoints(id, 0, 4 + node.level)
elseif (skill == 7) then
call AddAttPoints(id, 3, 4 + node.level)
elseif (skill == 14) and node.level == 1 then
call ProtectionVigor.create(MainUnit[id])
elseif (skill == 23) then
if node.level == 1 then
call DarkArts.create(MainUnit[id])
endif
call AddAttPoints(id, 2, 4 + node.level)
elseif (skill == 6) and node.level == 1 then
call MenacingPresence.create(MainUnit[id])
call Fighter[id].applyBuff(6, 0, null)
elseif (skill == 24) then
call Fighter[id].applyBuff(12, 0, null)
elseif (skill == 22) then
call Fighter[id].removeBuff(9)
call Fighter[id].applyBuff(9, 0, AddSpecialEffectTarget("war3mapImported\\Sweep_Astral_" + I2S(node.level) + "_med.mdx", MainUnit[id], "weapon"))
elseif (skill == 16) then
set Fighter[id].fireElementResist = Fighter[id].fireElementResist + 5 + 2 * node.level
set Fighter[id].waterElementResist = Fighter[id].waterElementResist + 5 + 2 * node.level
set Fighter[id].earthElementResist = Fighter[id].earthElementResist + 5 + 2 * node.level
set Fighter[id].windElementResist = Fighter[id].windElementResist + 5 + 2 * node.level
elseif (skill == 8) then
set Fighter[id].hpRegen = Fighter[id].hpRegen + 2
call Fighter[id].applyBuff(5, 0, null)
elseif (skill == 47) then
call AddAttPoints(id, 2, 4 + node.level)
elseif (skill == 31) then
call AddAttPoints(id, 1, 4 + node.level)
elseif (skill == 38) then
set Fighter[id].attackRange = Fighter[id].attackRange + 64.
elseif (skill == 39) then
set Fighter[id].evasionRate = Fighter[id].evasionRate + 0.05
elseif (skill == 40) then // Compact bolt
if node.level == 1 then
set Fighter[id].missile = "war3mapImported\\NightelfOwlRangerMissile.mdx"
endif
call Fighter[id].applyBuff(18, 0, null)
elseif (skill == 30) then // Silent Step
call Fighter[id].applyBuff(20, 0, null)
elseif (skill == 31) then // Alacrity
call AddAttPoints(id, 3, 4 + node.level)
elseif (skill == 32) then // Poison Coating
call Fighter[id].applyBuff(19, 0, null)
elseif (skill == 46) then // Afterimage
call Afterimage.register(Fighter[id], id)
elseif (skill == 47) then // Elune's Grace
set Fighter[id].spRegen = Fighter[id].spRegen + 0.5
endif
//set SavingPlayerID = id
//call ExecuteFunc("CreateNewSaveThreadEx")
endif
return node.level
endfunction
function AddSkillPoint takes integer id, integer amount returns nothing
set SkillPoint[id] = SkillPoint[id] + amount
if SkillPoint[id] < 0 then
set SkillPoint[id] = 0
elseif SkillPoint[id] > 100 then
set SkillPoint[id] = 99
endif
call UnitModifySkillPoints(LearnerShortcut[id], SkillPoint[id]-GetHeroSkillPoints(LearnerShortcut[id]))
call EvaluateSkillList(id)
if SkillPoint[id] > 0 then
call CharacterWindow_SkillNotifBG[id].show(true)
call CharacterWindow_SkillNotifText[id].show(true)
call CharacterWindow_SkillNotifText[id].setText(I2S(SkillPoint[id]), FONTSTYLE_FrizQTShaded)
call CharacterWindow_SkillNotifText[id].move(CharacterWindow_SkillNotifBG[id].xOffset-CharacterWindow_SkillNotifText[id].width/2., CharacterWindow_SkillNotifBG[id].yOffset, CharacterWindow_SkillNotifText[id].level)
call CharacterWindow_SkillNotifBG[id].refresh()
call CharacterWindow_SkillNotifText[id].refresh()
else
call CharacterWindow_SkillNotifBG[id].show(false)
call CharacterWindow_SkillNotifText[id].show(false)
endif
if AttributePoint[id] > 0 or SkillPoint[id] > 0 then
if UnitRemoveAbility(Controller[id], 'A006') and UnitAddAbility(Controller[id], 'A00C') then
endif
elseif AttributePoint[id] < 1 and SkillPoint[id] < 1 then
if UnitRemoveAbility(Controller[id], 'A00C') and UnitAddAbility(Controller[id], 'A006') then
endif
endif
endfunction
private function init takes nothing returns nothing
local integer i = 0
local trigger t = CreateTrigger()
loop
exitwhen i > 3
set Skills[i] = PlayerSkill.createNode()
set i = i + 1
endloop
endfunction
endlibrary
library BuffLib initializer init
private function init takes nothing returns nothing
local Buff bff
// 1. Stunned
if (true) then
set bff = Buff.create()
set bff.name = "Stunned"
set bff.description = "Unable to move and attack."
set bff.icon = 'B048'
endif
// 2. Counter Attack
if (true) then
set bff = Buff.create()
set bff.name = "Counter Attack"
set bff.description = "Chance to dodge and counter an attack."
set bff.icon = 'B049'
endif
// 3. Holy Shield
if (true) then
set bff = Buff.create()
set bff.name = "Holy Shield"
set bff.description = "Increased physical defense."
set bff.icon = 'B04A'
endif
// 4. Force Barrier
if (true) then
set bff = Buff.create()
set bff.name = "Force Barrier"
set bff.description = "Protected from limited amount of damage."
set bff.icon = 'B05D'
endif
// 5. Excellent Recovery
if (true) then
set bff = Buff.create()
set bff.name = "Excellent Recovery"
set bff.description = "Amplify healing effects."
set bff.icon = 'B05E'
endif
// 6. Menacing Presence
if (true) then
set bff = Buff.create()
set bff.name = "Menacing Presence"
set bff.description = "Continously raises threat level towards nearby enemies."
set bff.icon = 'B05G'
endif
// 7. Rapid Attack
if (true) then
set bff = Buff.create()
set bff.name = "Rapid Attack"
set bff.description = "Increased attack rate."
set bff.icon = 'B05H'
endif
// 8. Solidify
if (true) then
set bff = Buff.create()
set bff.name = "Solidify"
set bff.description = "Increased physical defense and block rate."
set bff.icon = 'B05I'
endif
// 9. Corrupted Blade
if (true) then
set bff = Buff.create()
set bff.name = "Corrupted Blade"
set bff.description = "Reduces armor of attacked unit."
set bff.icon = 'B05R'
endif
// 10. Corruption
if (true) then
set bff = Buff.create()
set bff.name = "Corruption"
set bff.description = "Reduced armor."
set bff.icon = 'B05S'
endif
// 11. Dreadful Howl
if (true) then
set bff = Buff.create()
set bff.name = "Dreadful Howl"
set bff.description = "Reduced armor and attack damage."
set bff.icon = 'B05T'
endif
// 12. Soulbound
if (true) then
set bff = Buff.create()
set bff.name = "Soulbound"
set bff.description = "Absorbs life energy of killed units."
set bff.icon = 'B05U'
endif
// 13. Poison Attack
if (true) then
set bff = Buff.create()
set bff.name = "Poison Attack"
set bff.description = "Inflitct poison on attacks."
set bff.icon = 'B05Z'
endif
// 14. Poisoned
if (true) then
set bff = Buff.create()
set bff.name = "Poisoned"
set bff.description = "Takes DPS and slowed movement."
set bff.icon = 'B060'
endif
// 15. Tranquilized
if (true) then
set bff = Buff.create()
set bff.name = "Tranquilized"
set bff.description = "Unable to move and attack."
set bff.icon = 'B063'
endif
// 16. Fast Reload
if (true) then
set bff = Buff.create()
set bff.name = "Fast Reload"
set bff.description = "Attack rate is increased."
set bff.icon = 'B06X'
endif
// 17. Acute Sight
if (true) then
set bff = Buff.create()
set bff.name = "Acute Sight"
set bff.description = "Being affected by Acute Sight."
set bff.icon = 'B06Z'
endif
// 18. Compact Bolt
if (true) then
set bff = Buff.create()
set bff.name = "Compact Bolt"
set bff.description = "Amplifies normal attack damage based on distance to target."
set bff.icon = 'B073'
endif
// 19. Poison Coating
if (true) then
set bff = Buff.create()
set bff.name = "Poison Coating"
set bff.description = "Give chances to apply poison on attacks."
set bff.icon = 'B068'
endif
// 20. Silent Step
if (true) then
set bff = Buff.create()
set bff.name = "Silent Step"
set bff.description = "Reduces monster aggro range."
set bff.icon = 'B066'
endif
// 21. Snare Trap
if (true) then
set bff = Buff.create()
set bff.name = "Snare Trap"
set bff.description = "Immobilized."
set bff.icon = 'B07J'
endif
// 22. Lucid Beam
if (true) then
set bff = Buff.create()
set bff.name = "Lucid Beam"
set bff.description = "Affected by Lucid Beam."
set bff.icon = 'B076'
endif
// 23. Taunt Fear
if (true) then
set bff = Buff.create()
set bff.name = "Taunt"
set bff.description = "Extra chance to miss attacks."
set bff.icon = 'B02S'
endif
// 24. Ferocious Hail
if (true) then
set bff = Buff.create()
set bff.name = "Ferocious Hail"
set bff.description = "Being affected by Ferocious Hail."
set bff.icon = 'B065'
endif
// 25. Illusion
if (true) then
set bff = Buff.create()
set bff.name = "Illusion"
set bff.description = "This unit is an illusion."
set bff.icon = 'B075'
endif
// 26. Shadow Meld
if (true) then
set bff = Buff.create()
set bff.name = "Shadow Meld"
set bff.description = "Invisible to enemies."
set bff.icon = 'B062'
endif
// 27. Burn
if (true) then
set bff = Buff.create()
set bff.name = "Burn"
set bff.description = "Takes damage every second."
set bff.icon = 'B094'
endif
// 28. Cold
if (true) then
set bff = Buff.create()
set bff.name = "Cold"
set bff.description = "Slowed movement and attack speed."
set bff.icon = 'B095'
endif
// 29. Corrosion
if (true) then
set bff = Buff.create()
set bff.name = "Corrosion"
set bff.description = "Reduced physic and magic armor."
set bff.icon = 'B096'
endif
// 30. Poison Coating (Target)
if (true) then
set bff = Buff.create()
set bff.name = "Poisoned"
set bff.description = "Takes damage per second."
set bff.icon = 'B068'
endif
endfunction
globals
constant integer BUFF_VARIATION_COUNT = 30
endglobals
endlibrary
library CalculationLib uses GameConstants
globals
public integer LevelOffset = 0
endglobals
private function MinLevel takes integer level returns integer
return IMaxBJ(level, 1)
endfunction
private function MaxLevel takes PlayerSkill skill returns integer
if skill.row.id.active then
return MAXIMUM_ACTIVE_SKILL_LEVEL
else
return MAXIMUM_PASSIVE_SKILL_LEVEL
endif
endfunction
function SummonWolfMinDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][35]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 6
local real b2 /*Value at skill level 1 char level 100*/ = 347
local real t1 /*Value at skill level max char level 1*/ = 36
local real t2 /*Value at skill level max char level 100*/ = 738
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function SummonWolfMaxDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][35]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 9
local real b2 /*Value at skill level 1 char level 100*/ = 387
local real t1 /*Value at skill level max char level 1*/ = 45
local real t2 /*Value at skill level max char level 100*/ = 822
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function SummonWolfHealth takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][35]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 345
local real b2 /*Value at skill level 1 char level 100*/ = 3213
local real t1 /*Value at skill level max char level 1*/ = 557
local real t2 /*Value at skill level max char level 100*/ = 9201
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function SummonWolfPhysicDef takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][35]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 1
local real b2 /*Value at skill level 1 char level 100*/ = 324
local real t1 /*Value at skill level max char level 1*/ = 10
local real t2 /*Value at skill level max char level 100*/ = 576
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function SummonWolfMagicDef takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][35]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 0
local real b2 /*Value at skill level 1 char level 100*/ = 121
local real t1 /*Value at skill level max char level 1*/ = 4
local real t2 /*Value at skill level max char level 100*/ = 213
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function SummonWolfCriticalChance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][35]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 0.
elseif rate < 10 then
return 0.15
elseif rate < 15 then
return 0.2
else
return 0.25
endif
return 0.
endfunction
function SummonWolfModel takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][35]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 'h022'
elseif rate < 10 then
return 'h025'
elseif rate < 15 then
return 'h026'
else
return 'h027'
endif
return 'h022'
endfunction
function AcuteSightAccuracy takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][36]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.1+0.02*rate
endfunction
function AcuteSightCriticalChance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][36]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.04+0.01*rate
endfunction
function AcuteSightInterruption takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][36]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.05+0.02*rate
endfunction
function AcuteSightDamageBonus takes integer pid returns real
return 0.05
endfunction
function TranquilizerDuration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][27]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 10.0+1.5*rate
endfunction
function TranquilizerReqHitCount takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][27]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 1
elseif rate < 10 then
return 2
elseif rate < 15 then
return 3
else
return 4
endif
return 1
endfunction
function SilentStepAggroRange takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][30]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 50.+40.*rate
endfunction
function BouncingGlaiveBounceCount takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][25]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 2
elseif rate < 10 then
return 3
elseif rate < 15 then
return 4
else
return 5
endif
return 2
endfunction
function BouncingGlaiveDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][25]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 20
local real b2 /*Value at skill level 1 char level 100*/ = 745
local real t1 /*Value at skill level max char level 1*/ = 41
local real t2 /*Value at skill level max char level 100*/ = 840
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function FericiousHailRadius takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][29]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 10 then
return 128.
else
return 192.
endif
return 128.
endfunction
function FericiousHailPhysicArmor takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][29]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 1
local real b2 /*Value at skill level 1 char level 100*/ = 29
local real t1 /*Value at skill level max char level 1*/ = 4
local real t2 /*Value at skill level max char level 100*/ = 129
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function FericiousHailSlow takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][29]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.1+0.02*rate
endfunction
function FericiousHailDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][29]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 15
local real b2 /*Value at skill level 1 char level 100*/ = 470
local real t1 /*Value at skill level max char level 1*/ = 45
local real t2 /*Value at skill level max char level 100*/ = 593
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function SnareTrapTrapDuration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][28]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 10 then
return 60.
else
return 120.
endif
return 60.
endfunction
function SnareTrapNetDuration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][28]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 3.5+rate*0.1
endfunction
function SnareTrapMovespeedReduction takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][28]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.3+rate*0.01
endfunction
function SnareTrapAccuracyReduction takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][28]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return rate*0.02
endfunction
function DreadfulHowlAccuracyReduction takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][19]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return rate*0.015
endfunction
function DreadfulHowlPhysicArmorReduction takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][19]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 2
local real b2 /*Value at skill level 1 char level 100*/ = 39
local real t1 /*Value at skill level max char level 1*/ = 7
local real t2 /*Value at skill level max char level 100*/ = 150
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function DreadfulHowlMagicArmorReduction takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][19]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 1
local real b2 /*Value at skill level 1 char level 100*/ = 21
local real t1 /*Value at skill level max char level 1*/ = 3.5
local real t2 /*Value at skill level max char level 100*/ = 74
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function DreadfulHowlDuration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][19]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 5.
elseif rate < 10 then
return 7.
elseif rate < 15 then
return 10.
else
return 15.
endif
return 5.
endfunction
function IllusoryIncarnationDuration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][42]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 30.
elseif rate < 10 then
return 45.
else
return 60.
endif
return 30.
endfunction
function IllusoryIncarnationCount takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][42]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 15 then
return 2
else
return 3
endif
return 2
endfunction
function IllusoryIncarnationDamageDealt takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][42]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.2 + 0.01*rate
endfunction
function IllusoryIncarnationDamageTaken takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][42]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 3.25 - 0.05*rate
endfunction
function QuickShotAttackCount takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][33]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 15 then
return 2
else
return 3
endif
return 2
endfunction
function QuickShotDamagePercent takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][33]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.6 + 0.02*rate
endfunction
function TripleShardCount takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][41]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 10 then
return 3
else
return 4
endif
return 3
endfunction
function TripleShardDistance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][41]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 100.
else
return 228.
endif
return 100.
endfunction
function TripleShardDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][41]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 25
local real b2 /*Value at skill level 1 char level 100*/ = 680
local real t1 /*Value at skill level max char level 1*/ = 41
local real t2 /*Value at skill level max char level 100*/ = 784
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function ExtendedRangeBonus takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][38]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 64.*rate
endfunction
function CatlikeReflexEvasion takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][39]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.05*rate
endfunction
function DoubleCrashInterruption takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][9]
local integer rate = (skill.level+LevelOffset)
if rate < 5 then
return 0.
elseif rate < 10 then
return 0.05
elseif rate < 15 then
return 0.1
else
return 0.15
endif
return 0.
endfunction
function DoubleCrashDamagePercent takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][9]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.4 + 0.02*rate
endfunction
function CounterAttackDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][10]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 0.5
elseif rate < 10 then
return 0.75
elseif rate < 15 then
return 1.
else
return 1.25
endif
return 0.5
endfunction
function CounterAttackTriggerChance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][10]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.05 + 0.01*rate
endfunction
function CounterAttackDuration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][10]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 30.+rate
endfunction
function CorruptedBladePhysicArmorReduction takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][22]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 1
local real b2 /*Value at skill level 1 char level 100*/ = 23
local real t1 /*Value at skill level max char level 1*/ = 5
local real t2 /*Value at skill level max char level 100*/ = 81
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function DeathBlowDamageAmount takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][1]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 29
local real b2 /*Value at skill level 1 char level 100*/ = 455
local real t1 /*Value at skill level max char level 1*/ = 51
local real t2 /*Value at skill level max char level 100*/ = 613
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function DeathBlowStunDuration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][1]
local integer rate = (skill.level+LevelOffset)
if rate < 5 then
return 1.
elseif rate < 10 then
return 1.5
elseif rate < 15 then
return 2.
else
return 2.5
endif
return 1.
endfunction
function DeathBlowArea takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][1]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 256.
endfunction
function PoisonCoatingChance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][32]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.05+0.02*rate
endfunction
function PoisonCoatingDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][32]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 4
local real b2 /*Value at skill level 1 char level 100*/ = 421
local real t1 /*Value at skill level max char level 1*/ = 13
local real t2 /*Value at skill level max char level 100*/ = 505
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function CompactBoltDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][40]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 0.75
local real b2 /*Value at skill level 1 char level 100*/ = 2.25
local real t1 /*Value at skill level max char level 1*/ = 1.05
local real t2 /*Value at skill level max char level 100*/ = 3.5
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function FastReloadSpeedBonus takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][34]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.05+0.012*rate
endfunction
function FastReloadDuration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][34]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 60.
elseif rate < 10 then
return 90.
elseif rate < 15 then
return 120.
else
return 150.
endif
return 60.
endfunction
function RapidAttackSpeedBonus takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][2]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.08+0.015*rate
endfunction
function RapidAttackSpeedDuration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][2]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 15.
elseif rate < 10 then
return 20.
elseif rate < 15 then
return 25.
else
return 30.
endif
return 15.
endfunction
function TauntThreatAmount takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][3]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 55
local real b2 /*Value at skill level 1 char level 100*/ = 3007
local real t1 /*Value at skill level max char level 1*/ = 156
local real t2 /*Value at skill level max char level 100*/ = 5301
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function TauntMissChance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][3]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 0.
elseif rate < 10 then
return 0.1
elseif rate < 15 then
return 0.2
else
return 0.3
endif
return 0.
endfunction
function SolidifyReflectChance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][4]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 0.
elseif rate < 10 then
return 0.05
elseif rate < 15 then
return 0.1
else
return 0.15
endif
return 0.
endfunction
function SolidifyReflectDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][4]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 0.
elseif rate < 10 then
return 0.5
elseif rate < 15 then
return 0.75
else
return 1.
endif
return 0.
endfunction
function SolidifyPhysicArmor takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][4]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 4
local real b2 /*Value at skill level 1 char level 100*/ = 50
local real t1 /*Value at skill level max char level 1*/ = 10
local real t2 /*Value at skill level max char level 100*/ = 170
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function SolidifyBlockBonus takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][4]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.1 + 0.02*rate
endfunction
function MenacingPressenceThreatAmount takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][6]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 13
local real b2 /*Value at skill level 1 char level 100*/ = 208
local real t1 /*Value at skill level max char level 1*/ = 32
local real t2 /*Value at skill level max char level 100*/ = 665
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function ForceBarrierAmount takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][5]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return Fighter[pid].hpMax * (0.4 + 0.07*rate)
endfunction
function UnholyStrengthBonusAmount takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][15]
local integer rate = (skill.level+LevelOffset)
local integer i = 0
local integer bonus = 0
if rate < 1 then
set rate = 1
endif
loop
exitwhen i == rate
set bonus = bonus + (5 + i)
set i = i + 1
endloop
return bonus
endfunction
function AlacrityBonusAmount takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][31]
local integer rate = (skill.level+LevelOffset)
local integer i = 0
local integer bonus = 0
if rate < 1 then
set rate = 1
endif
loop
exitwhen i == rate
set bonus = bonus + (5 + i)
set i = i + 1
endloop
return bonus
endfunction
function FortificationBonusAmount takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][7]
local integer rate = (skill.level+LevelOffset)
local integer i = 0
local integer bonus = 0
if rate < 1 then
set rate = 1
endif
loop
exitwhen i == rate
set bonus = bonus + (5 + i)
set i = i + 1
endloop
return bonus
endfunction
function ExcellentRecoveryRegeneration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][8]
local integer rate = (skill.level+LevelOffset)
local integer i = 0
local real bonus = 0
if rate < 1 then
set rate = 1
endif
loop
exitwhen i == rate
set bonus = bonus + 2
set i = i + 1
endloop
return bonus
endfunction
function ExcellentRecoveryAmplification takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][8]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.15*rate
endfunction
function HolyShieldPhysicArmor takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][12]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 3
local real b2 /*Value at skill level 1 char level 100*/ = 50
local real t1 /*Value at skill level max char level 1*/ = 12
local real t2 /*Value at skill level max char level 100*/ = 220
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function HolyShieldMagicArmor takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][12]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 1
local real b2 /*Value at skill level 1 char level 100*/ = 25
local real t1 /*Value at skill level max char level 1*/ = 6
local real t2 /*Value at skill level max char level 100*/ = 100
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function HolyShieldResistance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][12]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 1
local real b2 /*Value at skill level 1 char level 100*/ = 15
local real t1 /*Value at skill level max char level 1*/ = 5
local real t2 /*Value at skill level max char level 100*/ = 45
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function HolyShieldDamageBonus takes integer pid returns real
return 0.05
endfunction
function HolyShieldDuration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][12]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 20.+rate
endfunction
function NightmareFallDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][21]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 15
local real b2 /*Value at skill level 1 char level 100*/ = 451
local real t1 /*Value at skill level max char level 1*/ = 45
local real t2 /*Value at skill level max char level 100*/ = 597
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function NightmareFallPillarCount takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][21]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 4
elseif rate < 10 then
return 5
elseif rate < 15 then
return 6
else
return 7
endif
return 4
endfunction
function VampiricGroanHealthSteal takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][18]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 15
local real b2 /*Value at skill level 1 char level 100*/ = 250
local real t1 /*Value at skill level max char level 1*/ = 45
local real t2 /*Value at skill level max char level 100*/ = 503
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function VampiricGroanManaSteal takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][18]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 5
local real b2 /*Value at skill level 1 char level 100*/ = 15
local real t1 /*Value at skill level max char level 1*/ = 10
local real t2 /*Value at skill level max char level 100*/ = 30
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function VampiricGroanMaxTarget takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][18]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 4
elseif rate < 10 then
return 4
elseif rate < 15 then
return 5
else
return 6
endif
return 4
endfunction
function PrimalStrikeDamageAmount takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][37]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 1.1+0.06*rate
endfunction
function PrimalStrikeKnockback takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][37]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 96.+16.*rate
endfunction
function PrimalStrikeDistanceBonus takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][37]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 10 then
return 200.
else
return 520.
endif
return 200.
endfunction
function AeroJabDamageAmount takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][13]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 1.+0.05*rate
endfunction
function AeroJabDistance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][13]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 640.
elseif rate < 10 then
return 720.
elseif rate < 15 then
return 800.
else
return 880.
endif
return 640.
endfunction
function AeroJabVFX takes integer pid returns string
local PlayerSkill skill = PlayerSkillData[pid][13]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return "war3mapImported\\Piercing_Jab_1.mdx"
elseif rate < 10 then
return "war3mapImported\\Piercing_Jab_2.mdx"
elseif rate < 15 then
return "war3mapImported\\Piercing_Jab_3.mdx"
else
return "war3mapImported\\Piercing_Jab_4.mdx"
endif
return "war3mapImported\\Piercing_Jab_1.mdx"
endfunction
function ProtectionVigorPercentage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][14]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return (0.02+0.02*rate)
endfunction
function DivineResistanceBonus takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][16]
local integer rate = (skill.level+LevelOffset)
local integer i = 0
local integer bonus = 0
if rate < 1 then
set rate = 1
endif
loop
exitwhen i == rate
set bonus = bonus + (5 + 2 * i)
set i = i + 1
endloop
return bonus
endfunction
function DarkArtsPercentage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][23]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.04+0.04*rate
endfunction
function DarkArtsWisdomAmount takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][23]
local integer rate = (skill.level+LevelOffset)
local integer i = 0
local integer bonus = 0
if rate < 1 then
set rate = 1
endif
loop
exitwhen i == rate
set bonus = bonus + (5 + i)
set i = i + 1
endloop
return bonus
endfunction
function DarknessClawPercentage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][17]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 1.4+0.04*rate
endfunction
function SpectraVortexDuration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][20]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 45.
elseif rate < 10 then
return 50.
elseif rate < 15 then
return 55.
else
return 60.
endif
return 45.
endfunction
function SpectraVortexPercentage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][20]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.3+0.07*rate
endfunction
function SoulboundCount takes integer pid returns integer
local PlayerSkill skill = PlayerSkillData[pid][24]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return rate
endfunction
function SoulboundPercentage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][24]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.03*rate
endfunction
function LucidBeamDistance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][43]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 10 then
return 400.
else
return 800.
endif
return 400.
endfunction
function LucidBeamVFX takes integer pid returns string
local PlayerSkill skill = PlayerSkillData[pid][43]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 10 then
return "war3mapImported\\Lightning_Beam.mdx"
else
return "war3mapImported\\Lightning_Beam_800.mdx"
endif
return "war3mapImported\\Lightning_Beam.mdx"
endfunction
function LucidBeamDamageAmount takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][43]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 35
local real b2 /*Value at skill level 1 char level 100*/ = 380
local real t1 /*Value at skill level max char level 1*/ = 53
local real t2 /*Value at skill level max char level 100*/ = 535
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function ForceWallReflectChance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][44]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 0.
elseif rate < 10 then
return 0.25
else
return 0.35
endif
return 0.
endfunction
function ForceWallRadius takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][44]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 10 then
return 256.
else
return 384.
endif
return 256.
endfunction
function ForceWallDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][44]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 15
local real b2 /*Value at skill level 1 char level 100*/ = 261
local real t1 /*Value at skill level max char level 1*/ = 21
local real t2 /*Value at skill level max char level 100*/ = 333
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function ForceWallDuration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][44]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 7.0+0.25*rate
endfunction
function LunarStrikeDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][45]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 27
local real b2 /*Value at skill level 1 char level 100*/ = 732
local real t1 /*Value at skill level max char level 1*/ = 36
local real t2 /*Value at skill level max char level 100*/ = 830
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function LunarStrikeIllusionChance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][45]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 0.
elseif rate < 10 then
return 0.1
elseif rate < 15 then
return 0.2
else
return 0.3
endif
return 0.
endfunction
function AfterimageChance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][46]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.05+0.02*rate
endfunction
function AfterimageDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][46]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.2+0.03*rate
endfunction
function ElunesGraceRegeneration takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][47]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.5*rate
endfunction
function EmbodimentLifespanBonus takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][48]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 2.5*rate
endfunction
function EmbodimentDamageTakenBonus takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][48]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 0.05*rate
endfunction
function ShadowMeldSpeedBonus takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][26]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 0.
elseif rate < 10 then
return 0.05
elseif rate < 15 then
return 0.1
else
return 0.15
endif
return 0.
endfunction
function ShadowMeldDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][26]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 20
local real b2 /*Value at skill level 1 char level 100*/ = 521
local real t1 /*Value at skill level max char level 1*/ = 29
local real t2 /*Value at skill level max char level 100*/ = 600
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function ValiantChargeDamage takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][11]
local integer maxLevel = MaxLevel(skill)
local real b1 /*Value at skill level 1 char level 1*/ = 43
local real b2 /*Value at skill level 1 char level 100*/ = 550
local real t1 /*Value at skill level max char level 1*/ = 66
local real t2 /*Value at skill level max char level 100*/ = 803
local real f = CalculateSkillLevelFactor(MinLevel(skill.level + LevelOffset), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, Level[pid])
endfunction
function ValiantChargeKnockback takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][11]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
return 64.+12.*rate
endfunction
function ValiantChargeStun takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][11]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 5 then
return 0.
elseif rate < 15 then
return 1.0
else
return 2.0
endif
return 0.
endfunction
function ValiantChargeDistance takes integer pid returns real
local PlayerSkill skill = PlayerSkillData[pid][11]
local integer rate = (skill.level+LevelOffset)
if rate < 1 then
set rate = 1
endif
if rate < 10 then
return 384.
else
return 576.
endif
return 384.
endfunction
function CorrosionPhysicArmorReduction takes integer tier, integer level returns real
local integer maxLevel = 5
local real b1 /*Value at tier level 1 char level 1*/ = 4
local real b2 /*Value at tier level 1 char level 100*/ = 62
local real t1 /*Value at tier level max char level 1*/ = 24
local real t2 /*Value at tier level max char level 100*/ = 85
local real f = CalculateSkillLevelFactor(MinLevel(tier), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, level)
endfunction
function CorrosionMagicArmorReduction takes integer tier, integer level returns real
local integer maxLevel = 5
local real b1 /*Value at tier level 1 char level 1*/ = 2
local real b2 /*Value at tier level 1 char level 100*/ = 31
local real t1 /*Value at tier level max char level 1*/ = 12
local real t2 /*Value at tier level max char level 100*/ = 42.5
local real f = CalculateSkillLevelFactor(MinLevel(tier), maxLevel)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
return b + CalculateCharLevelValue(t, level)
endfunction
endlibrary
library SoundEffects initializer init
globals
RSound DeathBlow
RSound DeathBlowJump
RSound AeroJab
RSound DarknessClaw
RSound LucidBeam
RSound LucidBeamHit
RSound BouncingGlaiveLaunch
RSound BouncingGlaiveHit
RSound NightmareFallCastSfx
RSound NightmareFallLoopSfx
RSound ShadowMeldSfx
RSound PrimalStrikeCastSfx
RSound PrimalStrikeLaunchSfx
RSound LunarStrikeCastSfx
RSound LunarStrikeLaunchSfx
RSound ValiantChargeSfx
RSound array ValiantChargeHitSfx
RSound array ViciousHailSfx
endglobals
private function init takes nothing returns nothing
set ValiantChargeSfx = RSound.create("war3mapImported\\ValiantChargeSfx.wav", true, true, 12700, 12700)
set ValiantChargeHitSfx[0] = RSound.create("Sound\\Units\\Combat\\MetalHeavyBashMetal1.wav", true, true, 12700, 12700)
set ValiantChargeHitSfx[1] = RSound.create("Sound\\Units\\Combat\\MetalHeavyBashMetal2.wav", true, true, 12700, 12700)
set ValiantChargeHitSfx[2] = RSound.create("Sound\\Units\\Combat\\MetalHeavyBashMetal3.wav", true, true, 12700, 12700)
set DeathBlow = RSound.create("war3mapImported\\DeathBlow.wav", true, true, 12700, 12700)
set DeathBlowJump = RSound.create("war3mapImported\\DeathBlowJump.wav", true, true, 12700, 12700)
set AeroJab = RSound.create("war3mapImported\\AeroJab.wav", true, true, 12700, 12700)
set DarknessClaw = RSound.create("war3mapImported\\Darkness Claw.wav", true, true, 12700, 12700)
set LucidBeam = RSound.create("war3mapImported\\moonbeam3.wav", true, true, 12700, 12700)
set LucidBeamHit = RSound.create("war3mapImported\\moonbeamhit3.wav", true, true, 12700, 12700)
set BouncingGlaiveLaunch = RSound.create("Abilities\\Weapons\\SentinelMissile\\HuntressMissileLaunch.wav", true, true, 12700, 12700)
set BouncingGlaiveHit = RSound.create("Sound\\Units\\Combat\\MetalLightSliceFlesh3.wav", true, true, 12700, 12700)
set NightmareFallCastSfx = RSound.create("war3mapImported\\nightmarefallcast.wav", true, true, 12700, 12700)
set NightmareFallLoopSfx = RSound.create("war3mapImported\\nightmarefallloop.wav", true, true, 12700, 12700)
set ViciousHailSfx[0] = RSound.create("Abilities\\Weapons\\ColdArrow\\ColdArrow1.wav", true, true, 12700, 12700)
set ViciousHailSfx[1] = RSound.create("Abilities\\Weapons\\ColdArrow\\ColdArrow2.wav", true, true, 12700, 12700)
set ViciousHailSfx[2] = RSound.create("Abilities\\Weapons\\ColdArrow\\ColdArrow3.wav", true, true, 12700, 12700)
set ShadowMeldSfx = RSound.create("Abilities\\Spells\\NightElf\\ShadowMeld\\ShadowMeld1.wav", true, true, 12700, 12700)
set PrimalStrikeCastSfx = RSound.create("war3mapImported\\PrimalStrikeCharge.wav", true, true, 12700, 12700)
set PrimalStrikeLaunchSfx = RSound.create("war3mapImported\\PrimalStrikeLaunch.wav", true, true, 12700, 12700)
set LunarStrikeCastSfx = RSound.create("war3mapImported\\LunarStrikeCharge.wav", true, true, 12700, 12700)
set LunarStrikeLaunchSfx = RSound.create("war3mapImported\\LunarStrikeLaunch.wav", true, true, 12700, 12700)
endfunction
endlibrary
library GenericAbilities
//! textmacro GenericSkillLib
struct ShockMissile
Combatant c
unit dummy
effect sfx
group targets
timer t
real delay
real damage
real distance
real x
real y
real a
real at
private static constant real MIN_DIST = 800.
private static constant real MAX_DIST = 1600.
private static constant real MIN_DELAY = 0.075
private static constant real MAX_DELAY = 0.5
private static constant real TURN_RATE = 10.0*bj_DEGTORAD
private static constant real TURN_MIN = 45.0*bj_DEGTORAD
private static constant real TURN_MAX = 180.0*bj_DEGTORAD
private static constant real SPEED = 30.0
private static constant real COLLISION = 64.0
private static group Group = CreateGroup()
method destroy takes nothing returns nothing
call RecycleMissile(.dummy)
//call UnitApplyTimedLife(.dummy, 'BTLF', 5.0)
call DestroyEffect(.sfx)
call DestroyGroup(.targets)
call ReleaseTimer(.t)
call deallocate()
set .targets = null
set .dummy = null
set .sfx = null
set .t = null
endmethod
static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local unit fog
local real dmg
local Combatant c2
if .distance > SPEED then
if .delay > 0.03125 then
set .delay = .delay - 0.03125
else
set .delay = GetRandomReal(MIN_DELAY, MAX_DELAY)
set .at = .a + GetRandomReal(TURN_MIN, TURN_MAX) * GetRandomInt(-1, 1)
endif
// Adjust missile's angle to the target
if Cos(.a-.at) < Cos(TURN_RATE) then
if Sin(.at-.a) >= 0 then
set .a = .a + TURN_RATE
else
set .a = .a - TURN_RATE
endif
else
set .a = .at
endif
set .x = .x + SPEED*Cos(.a)
set .y = .y + SPEED*Sin(.a)
set .distance = .distance - SPEED
if .x > WorldBounds.minX and .x < WorldBounds.maxX and .y > WorldBounds.minY and .y < WorldBounds.maxY then
call SetUnitX(.dummy, .x)
call SetUnitY(.dummy, .y)
call GroupEnumUnitsInRange(Group, .x, .y, COLLISION, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, .c.owner) and IsUnitAlive(fog) and not IsUnitInGroup(fog, .targets) then
call GroupAddUnit(.targets, fog)
set c2 = Combatant[fog]
if not c2.isInvulnerable then
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\ShockTarget.mdx", fog, "chest"))
set dmg = CalculateConstantDamage(c, c2, .damage, true)*0.05
call Damage(c.u, fog, dmg, false, false, false)
endif
endif
endloop
else
call destroy()
endif
else
call destroy()
endif
set t = null
endmethod
static method create takes Combatant c, real x, real y, real a, real damage, unit t, string model returns thistype
local thistype this = allocate()
set .c = c
set .targets = CreateGroup()
set .dummy = GetRecycledMissile(x, y, 0, a)
set .sfx = AddSpecialEffectTarget(model, .dummy, "origin")
set .damage = damage
set .a = a * bj_DEGTORAD
set .at = .a
set .x = x
set .y = y
set .distance = GetRandomReal(MIN_DIST, MAX_DIST)
set .delay = GetRandomReal(MIN_DELAY, MAX_DELAY)
set .t = NewTimerEx(this)
call GroupAddUnit(.targets, t)
call TimerStart(.t, 0.03125, true, function thistype.onTick)
return this
endmethod
endstruct
struct Invisibility extends array
static Buff array CurrentBuff
static timer array Expiration
static unit Caster
static method isInvisible takes Combatant c returns boolean
return Expiration[c] != null
endmethod
static method invisBuff takes Combatant c returns Buff
return CurrentBuff[c]
endmethod
static method reveal takes Combatant c returns nothing
call c.removeBuff(CurrentBuff[c])
call ReleaseTimer(Expiration[c])
call UnitRemoveAbility(c.u, 'B000')
set Expiration[c] = null
endmethod
static method onExpire takes nothing returns nothing
call reveal(GetTimerData(GetExpiredTimer()))
endmethod
static method apply takes Combatant c, Buff b, real duration, effect sfx returns nothing
if Expiration[c] != null then
call reveal(c)
endif
set CurrentBuff[c] = b
set Expiration[c] = NewTimerEx(c)
call c.applyBuff(b, duration, sfx)
call SetUnitOwner(Caster, c.owner, false)
call IssueTargetOrderById(Caster, ORDER_invisibility, c.u)
call TimerStart(Expiration[c], duration, false, function thistype.onExpire)
endmethod
private static method onInit takes nothing returns nothing
set Caster = CreateUnit(PASSIVE, 'e000', WorldBounds.maxX, WorldBounds.maxY, 0)
call SetUnitPathing(Caster, false)
call UnitAddAbility(Caster, 'A008')
endmethod
endstruct
struct ReflectMissile extends array
Combatant target
Buff b
real amount
real factor
static real array TotalAmount
implement LinkedList
static method getDamageFactor takes Combatant c returns real
local real total = 0
local thistype node = base.next
loop
exitwhen node.head or node == 0
if node.target == c then
set total = total + node.factor
endif
set node = node.next
endloop
return total
endmethod
method remove takes nothing returns nothing
set TotalAmount[.target] = TotalAmount[.target] - .amount
call removeNode()
call deallocate()
endmethod
static method cleanse takes Combatant c, Buff b returns nothing
local thistype node = base.next
loop
exitwhen node.head or node == 0
if node.target == c and node.b == b then
call node.remove()
endif
set node = node.next
endloop
endmethod
static method create takes Combatant c, Buff b, real amount, real factor returns thistype
local thistype this = allocate()
set .b = b
set .target = c
set .amount = amount
set .factor = factor
set TotalAmount[c] = TotalAmount[c] + amount
call base.insertNode(this)
return this
endmethod
endstruct
// Adds miss chance
struct Blindness extends array
Combatant target
Buff b
real amount
static real array TotalAmount
implement LinkedList
method remove takes nothing returns nothing
set TotalAmount[.target] = TotalAmount[.target] - .amount
call removeNode()
call deallocate()
endmethod
static method cleanse takes Combatant c, Buff b returns nothing
local thistype node = base.next
loop
exitwhen node.head or node == 0
if node.target == c and node.b == b then
call node.remove()
endif
set node = node.next
endloop
endmethod
static method create takes Combatant c, Buff b, real amount returns thistype
local thistype this = allocate()
set .b = b
set .target = c
set .amount = amount
set TotalAmount[c] = TotalAmount[c] + amount
call base.insertNode(this)
return this
endmethod
endstruct
struct PeriodicDamage extends array
Combatant source
Combatant target
Buff b
real amount
real duration
real interval
timer time
string hitSfx
string hitSfxPt
implement LinkedList
method remove takes nothing returns nothing
call ReleaseTimer(.time)
call removeNode()
call deallocate()
set .time = null
set .b = 0
endmethod
static method cleanse takes Combatant c, Buff b returns nothing
local thistype node = base.next
loop
exitwhen node.head or node == 0
if node.target == c and node.b == b then
call node.remove()
endif
set node = node.next
endloop
endmethod
static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
set .duration = .duration - .interval
call Damage(source.u, target.u, .amount, false, false, false)
if .duration <= 0 then
call .remove()
endif
set t = null
endmethod
static method create takes unit source, unit target, real amount, real interval, real duration, Buff b returns thistype
local thistype this = allocate()
set .b = b
set .source = Combatant[source]
set .target = Combatant[target]
set .amount = amount
set .duration = duration
set .interval = interval
set .time = NewTimerEx(this)
set .hitSfx = ""
call TimerStart(.time, interval, true, function thistype.onTick)
call base.insertNode(this)
return this
endmethod
endstruct
struct DamageBlock extends array
Combatant c
Buff b
real amount
implement LinkedList
method remove takes nothing returns nothing
call removeNode()
call deallocate()
call .c.removeBuff(.b)
set .c.dmgProtection = .c.dmgProtection - .amount
set .amount = 0
endmethod
static method damage takes Combatant c, real amount returns nothing
local thistype node = base.next
loop
exitwhen node.head or node == 0
if node.c == c then
if node.amount >= amount then
set node.amount = node.amount - amount
set amount = 0
else
set amount = amount - node.amount
set node.amount = 0
endif
if (node.amount <= 0) then
call node.remove()
endif
if (amount <= 0) then
return
endif
endif
set node = node.next
endloop
endmethod
static method cleanse takes Combatant c, Buff b returns nothing
local thistype node = base.next
loop
exitwhen node.head or node == 0
if node.c == c and node.b == b then
call node.remove()
endif
set node = node.next
endloop
endmethod
static method create takes unit u, real amount, real duration, Buff b returns thistype
local thistype this
local Combatant c = Combatant[u]
call cleanse(c, b)
set this = allocate()
set .c = c
set .b = b
set .amount = amount
set .c.dmgProtection = .c.dmgProtection + .amount
call base.insertNode(this)
return this
endmethod
endstruct
struct StatusBonus extends array
Combatant c
Buff b
real amount
integer stat
implement LinkedList
method remove takes nothing returns nothing
if stat == 1 then
set .c.physicDefense = .c.physicDefense - .amount
elseif stat == 2 then
set .c.attackRate = .c.attackRate + .amount
elseif stat == 3 then
set .c.blockRate = .c.blockRate - .amount
elseif stat == 4 then
set .c.magicDefense = .c.magicDefense - .amount
elseif stat == 5 then
set .c.accuracy = .c.accuracy - .amount
elseif stat == 6 then
call SetUnitMoveSpeed(.c.u, GetUnitMoveSpeed(.c.u) - .amount)
elseif stat == 7 then
set .c.physicDmgMax = .c.physicDmgMax - .amount
set .c.physicDmgMin = .c.physicDmgMin - .amount
elseif stat == 8 then
set .c.magicDmgMax = .c.magicDmgMax - .amount
set .c.magicDmgMin = .c.magicDmgMin - .amount
elseif stat == 9 then
set .c.fireElementResist = .c.fireElementResist - .amount
elseif stat == 10 then
set .c.waterElementResist = .c.waterElementResist - .amount
elseif stat == 11 then
set .c.earthElementResist = .c.earthElementResist - .amount
elseif stat == 12 then
set .c.windElementResist = .c.windElementResist - .amount
elseif stat == 13 then
set .c.criticalRate = .c.criticalRate - .amount
elseif stat == 14 then
set .c.interrupt = .c.interrupt - .amount
endif
call removeNode()
call deallocate()
endmethod
static method cleanse takes Combatant c, Buff b returns nothing
local thistype node = base.next
loop
exitwhen node.head or node == 0
if node.c == c and node.b == b then
call node.remove()
endif
set node = node.next
endloop
endmethod
static method create takes unit u, integer stat, real amount, real duration, Buff b returns thistype
local thistype this
local Combatant c = Combatant[u]
set this = allocate()
set .c = c
set .b = b
set .stat = stat
set .amount = amount
if stat == 1 then
set .c.physicDefense = .c.physicDefense + .amount
elseif stat == 2 then
set .c.attackRate = .c.attackRate - .amount
elseif stat == 3 then
set .c.blockRate = .c.blockRate + .amount
elseif stat == 4 then
set .c.magicDefense = .c.magicDefense + .amount
elseif stat == 5 then
set .c.accuracy = .c.accuracy + .amount
elseif stat == 6 then
call SetUnitMoveSpeed(.c.u, GetUnitMoveSpeed(.c.u) + .amount)
elseif stat == 7 then
set .c.physicDmgMax = .c.physicDmgMax + .amount
set .c.physicDmgMin = .c.physicDmgMin + .amount
elseif stat == 8 then
set .c.magicDmgMax = .c.magicDmgMax + .amount
set .c.magicDmgMin = .c.magicDmgMin + .amount
elseif stat == 9 then
set .c.fireElementResist = .c.fireElementResist + .amount
elseif stat == 10 then
set .c.waterElementResist = .c.waterElementResist + .amount
elseif stat == 11 then
set .c.earthElementResist = .c.earthElementResist + .amount
elseif stat == 12 then
set .c.windElementResist = .c.windElementResist + .amount
elseif stat == 13 then
set .c.criticalRate = .c.criticalRate + .amount
elseif stat == 14 then
set .c.interrupt = .c.interrupt + .amount
endif
call base.insertNode(this)
return this
endmethod
endstruct
struct Fly
unit u
real vel
real z
timer t
static thistype array Index
static method operator [] takes unit u returns thistype
return Index[GetUnitUserData(u)]
endmethod
method destroy takes nothing returns nothing
set Index[GetUnitUserData(.u)] = 0
call ReleaseTimer(.t)
call deallocate()
set .t = null
set .u = null
endmethod
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
if UnitAlive(.u) then
set .z = .z + .vel
call PanelCore_SetUnitZ(.u, .z)
else
call destroy()
endif
set t = null
endmethod
static method create takes unit u, real vel returns thistype
local thistype this = allocate()
set .u = u
set .vel = vel
set .z = PanelCore_GetUnitZ(u)
set Index[GetUnitUserData(u)] = this
set .t = NewTimerEx(this)
call TimerStart(.t, 0.03125, true, function thistype.onTick)
return this
endmethod
endstruct
struct Jump
unit u
real vel
real sz
real z
static real Gravity = 5.
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
set .vel = .vel - Gravity
set .z = .z + .vel
if (.z < .sz) then
call PanelCore_SetUnitZ(.u, .sz)
call ReleaseTimer(t)
call deallocate()
set .u = null
else
call PanelCore_SetUnitZ(.u, .z)
endif
set t = null
endmethod
static method create takes unit u, real vel returns thistype
local thistype this = allocate()
set .u = u
set .vel = vel
set .sz = PanelCore_GetUnitZ(u)
set .z = sz
call TimerStart(NewTimerEx(this), 0.03125, true, function thistype.onTick)
return this
endmethod
endstruct
struct Grow
unit u
real target
real size
real rate
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
set .size = .size + .rate
call SetUnitScale(.u, .size, .size, .size)
if (not IsUnitAlive(.u) or .size > RAbsBJ(.target)) then
call Combatant[.u].destroy()
call RemoveUnit(.u)
call ReleaseTimer(t)
call deallocate()
set .u = null
endif
set t = null
endmethod
static method create takes unit whichUnit, real start, real target, real rate returns thistype
local thistype this = allocate()
set .size = start
set .target = target
set .rate = rate
set .u = whichUnit
call TimerStart(NewTimerEx(this), 0.03125, true, function thistype.onTick)
return this
endmethod
endstruct
struct Fade
unit u
integer r
integer g
integer b
real alpha
real rate
timer t
static thistype array Index
method destroy takes nothing returns nothing
set Index[GetUnitUserData(.u)] = 0
call ReleaseTimer(.t)
call deallocate()
set .u = null
set .t = null
endmethod
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
set .alpha = .alpha + .rate
call SetUnitVertexColor(.u, .r, .g, .b, R2I(.alpha))
if .rate < 0 then
if (.alpha <= 0) then
call destroy()
endif
else
if (.alpha >= 255) then
call destroy()
endif
endif
set t = null
endmethod
static method create takes unit whichUnit, real start, real rate returns thistype
local thistype this = allocate()
local integer data = GetUnitUserData(whichUnit)
if Index[data] > 0 then
call Index[data].destroy()
endif
set .u = whichUnit
set .r = 255
set .g = 255
set .b = 255
set .alpha = start
set .rate = rate
set Index[data] = this
call SetUnitVertexColor(.u, .r, .g, .b, R2I(start))
set .t = NewTimerEx(this)
call TimerStart(.t, 0.03125, true, function thistype.onTick)
return this
endmethod
endstruct
struct FadingDecay
unit u
integer r
integer g
integer b
real alpha
real rate
boolean remove
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
set .alpha = .alpha - .rate
call SetUnitVertexColor(.u, .r, .g, .b, R2I(.alpha))
if (.alpha <= 0) then
call Combatant[.u].destroy()
if (.remove) then
call RemoveUnit(.u)
else
call KillUnit(.u)
endif
call ReleaseTimer(t)
call deallocate()
set .u = null
endif
set t = null
endmethod
static method create takes unit whichUnit, real start, real rate returns thistype
local thistype this = allocate()
set .r = 255
set .g = 255
set .b = 255
set .alpha = start
set .rate = rate
set .u = whichUnit
set .remove = true
call TimerStart(NewTimerEx(this), 0.03125, true, function thistype.onTick)
return this
endmethod
endstruct
struct Knockback
Missile target
real dist
real dist2
real spd
real dly
boolean sfx
static method onPeriod takes Missile missile returns boolean
local thistype this = missile.data
local boolean b
if (.dist <= 0) then
set missile.speed = missile.speed * 0.7
else
set .dist = .dist - missile.speed
if (.sfx) then
set .dly = .dly + 0.03215
if (.dly >= 0.1) then
set .dly = 0
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl", missile.x, missile.y))
endif
endif
endif
return not IsUnitAlive(missile.dummy) or not IsTerrainWalkable(missile.x, missile.y) or missile.speed <= .spd*0.25 or .dist2 < .spd or .spd > .dist2
endmethod
implement MissileStruct
static method create takes unit whichUnit, real a, real distance, real speed, boolean sfx returns thistype
local thistype this = 0
local real y
local boolean b
if GetUnitAbilityLevel(whichUnit, 'Amov') > 0 then
set y = GetUnitY(whichUnit)
call SetUnitY(whichUnit, y+200)
set b = IsTerrainWalkable(GetUnitX(whichUnit), y)
call SetUnitY(whichUnit, y)
if b then
set this = allocate()
set .target = Missile.createEx(whichUnit, GetUnitX(whichUnit) + 10000 * Cos(a), GetUnitY(whichUnit) + 10000 * Sin(a), GetUnitFlyHeight(whichUnit))
set .target.speed = speed
set .target.data = this
set .dist = distance
set .dist2 = distance
set .spd = speed
set .sfx = sfx
set .dly = 0
call launch(.target)
endif
endif
return this
endmethod
endstruct
struct CompanionAI
Combatant master
Combatant pet
Combatant target
integer id
string sfx
real combatModeDur
real wanderDelay
timer time
effect selection
static real MAX_AGGRO_RANGE = 800
static real MAX_DISTANCE_FROM_MASTER = 200
static real MIN_WANDER_DELAY = 1
static real MAX_WANDER_DELAY = 5
static real IDLE_THRESHOLD = 15
static real FOLLOW_DISTANCE = 100
private static thistype array Index
private static integer Count = 0
static method operator [] takes unit u returns thistype
return Index[Combatant[u]]
endmethod
static method removeWithId takes Combatant master, integer id returns nothing
local group gr = CreateGroup()
local unit fog
local thistype ai
loop
set fog = FirstOfGroup(master.subordinate)
exitwhen fog == null
call GroupRemoveUnit(master.subordinate, fog)
call GroupAddUnit(gr, fog)
set ai = thistype[fog]
if ai > 0 then
if ai.id == id then
call GroupRemoveUnit(gr, fog)
call ai.destroy()
endif
endif
endloop
call DestroyGroup(master.subordinate)
set master.subordinate = gr
set gr = null
endmethod
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local boolean isMoving
local boolean masterMoving
local real a
local real d
local real x
local real y
local real x2
local real y2
local real xt
local real yt
local unit fog
local Combatant c
if UnitAlive(.pet.u) and IsUnitAlive(.master.u) then
if not IsUnitPaused(.pet.u) then
set isMoving = GetUnitCurrentOrder(.pet.u) == ORDER_move
set masterMoving = GetUnitCurrentOrder(.master.u) == ORDER_move
set x = GetUnitX(.pet.u)
set y = GetUnitY(.pet.u)
set x2 = GetUnitX(.master.u)
set y2 = GetUnitY(.master.u)
if .combatModeDur > 0 and masterMoving then
set .combatModeDur = .combatModeDur - 0.1
if .combatModeDur <= 0 then
set .target = 0
endif
endif
if .wanderDelay > 0 and not isMoving then
set .wanderDelay = .wanderDelay - 0.1
endif
if .target == 0 or not IsUnitAlive(.target.u) then
set .target = 0
call GroupEnumUnitsInRange(Group, x2, y2, MAX_AGGRO_RANGE, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, .master.owner) and IsUnitVisible(fog, .master.owner) and IsUnitAlive(fog) then
set c = Combatant[fog]
if not c.isInvulnerable and GetUnitAbilityLevel(fog, 'Amov') > 0 then
set .target = c
exitwhen true
endif
endif
endloop
endif
if not isMoving or .combatModeDur > 0 then
if (not masterMoving or .combatModeDur > 0) and .target > 0 then
if IsUnitInRangeXY(.target.u, x2, y2, MAX_AGGRO_RANGE) and IsUnitVisible(.target.u, .master.owner) then
if .combatModeDur <= 0 then
if IsUnitInRangeXY(.target.u, x2, y2, MAX_DISTANCE_FROM_MASTER) then
call .pet.follow(.target.u)
else
set a = Atan2(GetUnitY(.target.u)-y2, GetUnitX(.target.u)-x2)
set xt = x2 + MAX_DISTANCE_FROM_MASTER * Cos(a)
set yt = y2 + MAX_DISTANCE_FROM_MASTER * Sin(a)
if not IsUnitInRangeXY(.pet.u, xt, yt, IDLE_THRESHOLD) then
call .pet.move(xt, yt)
else
call SetUnitFacing(.pet.u, a*bj_RADTODEG)
endif
endif
else
if IsUnitInRangeXY(.target.u, x, y, .pet.attackRange * 0.75) then
set a = Atan2(GetUnitY(.target.u)-y, GetUnitX(.target.u)-x)
call SetUnitFacing(.pet.u, a*bj_RADTODEG)
call .pet.attack()
elseif not isMoving then
set xt = GetUnitX(.target.u)
set yt = GetUnitY(.target.u)
call .pet.move(xt, yt)
endif
endif
else
set .target = 0
endif
else
if not masterMoving then
if .wanderDelay <= 0 then
set a = GetRandomReal(-bj_PI, bj_PI)
set d = GetRandomReal(100, MAX_DISTANCE_FROM_MASTER)
call .pet.move(x2 + d * Cos(a), y2 + d * Sin(a))
set .wanderDelay = GetRandomReal(MIN_WANDER_DELAY, MAX_WANDER_DELAY)
endif
elseif not isMoving then
set a = (GetUnitFacing(.master.u) + 180) * bj_DEGTORAD
call .pet.move(x2 + FOLLOW_DISTANCE * Cos(a), y2 + FOLLOW_DISTANCE * Sin(a))
endif
endif
endif
endif
elseif not .pet.noRemove then
call destroy()
elseif not IsUnitPaused(.pet.u) then
call .pet.kill()
endif
set t = null
endmethod
method destroy takes nothing returns nothing
local unit u = .pet.u
set Count = Count - 1
if StringLength(.sfx) > 0 then
call DestroyEffect(AddSpecialEffect(.sfx, GetUnitX(u), GetUnitY(u)))
endif
call GroupRemoveUnit(.master.subordinate, u)
call GroupRemoveUnit(PlayerUnits, u)
call .pet.destroy()
call RemoveUnit(u)
call ReleaseTimer(.time)
call DestroyEffect(.selection)
call deallocate()
set .time = null
set .selection = null
set Index[.pet] = 0
set Index[.master] = 0
set .master = 0
set .id = 0
set u = null
endmethod
static method create takes Combatant master, Combatant pet returns thistype
local thistype this = allocate()
local string s = ""
set Count = Count + 1
set .master = master
set .pet = pet
set .target = 0
set .combatModeDur = 0
set .id = 0
set .sfx = ""
if Locale == master.owner then
set s = "war3mapImported\\SelectionGreen.mdx"
else
set s = "war3mapImported\\SelectionPlayer" + I2S(master.pid) + ".mdx"
endif
set .selection = AddSpecialEffectTarget(s, .pet.u, "origin")
set Index[pet] = this
set Index[master] = this
call GroupAddUnit(.master.subordinate, pet.u)
set .time = NewTimerEx(this)
call TimerStart(.time, 0.1, true, function thistype.onTick)
return this
endmethod
endstruct
struct HumanoidAI
Combatant master
Combatant human
Combatant target
integer id
string sfx
real combatModeDur
real wanderDelay
timer time
effect selection
static real MAX_AGGRO_RANGE = 800
static real MAX_DISTANCE_FROM_MASTER = 400
static real MIN_WANDER_DELAY = 5
static real MAX_WANDER_DELAY = 10
static real FOLLOW_DISTANCE = 100
private static thistype array Index
private static integer Count = 0
static method operator [] takes unit whichUnit returns thistype
return Index[Combatant[whichUnit]]
endmethod
static method removeWithId takes Combatant master, integer id returns nothing
local group gr = CreateGroup()
local unit fog
local thistype ai
loop
set fog = FirstOfGroup(master.subordinate)
exitwhen fog == null
call GroupRemoveUnit(master.subordinate, fog)
call GroupAddUnit(gr, fog)
set ai = thistype[fog]
if ai > 0 then
if ai.id == id then
call GroupRemoveUnit(gr, fog)
call ai.destroy()
endif
endif
endloop
call DestroyGroup(master.subordinate)
set master.subordinate = gr
set gr = null
endmethod
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local boolean isMoving
local boolean masterMoving
local real a
local real d
local real x
local real y
local real x2
local real y2
local real xt
local real yt
local unit fog
local Combatant c
if UnitAlive(.human.u) and IsUnitAlive(.master.u) then
if not IsUnitPaused(.human.u) then
set isMoving = GetUnitCurrentOrder(.human.u) == ORDER_move
set masterMoving = GetUnitCurrentOrder(.master.u) == ORDER_move
set x = GetUnitX(.human.u)
set y = GetUnitY(.human.u)
set x2 = GetUnitX(.master.u)
set y2 = GetUnitY(.master.u)
if .combatModeDur > 0 and (.target == 0 or not IsUnitAlive(.target.u)) then
set .target = 0
call GroupEnumUnitsInRange(Group, x2, y2, MAX_AGGRO_RANGE, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, .master.owner) and IsUnitVisible(fog, .master.owner) and IsUnitAlive(fog) then
set c = Combatant[fog]
if not c.isInvulnerable and GetUnitAbilityLevel(fog, 'Amov') > 0 then
set .target = c
exitwhen true
endif
endif
endloop
endif
if .combatModeDur > 0 and masterMoving then
set .combatModeDur = .combatModeDur - 0.1
if .combatModeDur <= 0 then
set .target = 0
endif
endif
if .wanderDelay > 0 and not isMoving then
set .wanderDelay = .wanderDelay - 0.1
endif
if .combatModeDur > 0 and IsUnitAlive(.target.u) then
if IsUnitInRangeXY(.target.u, x2, y2, MAX_AGGRO_RANGE) and IsUnitVisible(.target.u, .master.owner) then
if IsUnitInRangeXY(.target.u, x, y, .human.attackRange) then
set a = Atan2(GetUnitY(.target.u)-y, GetUnitX(.target.u)-x)
call SetUnitFacing(.human.u, a*bj_RADTODEG)
call .human.attack()
elseif not isMoving then
set xt = GetUnitX(.target.u)
set yt = GetUnitY(.target.u)
call .human.move(xt, yt)
endif
else
set .target = 0
endif
else
if not masterMoving then
if .wanderDelay <= 0 then
set a = GetRandomReal(-bj_PI, bj_PI)
set d = GetRandomReal(100, MAX_DISTANCE_FROM_MASTER)
call .human.move(x2 + d * Cos(a), y2 + d * Sin(a))
set .wanderDelay = GetRandomReal(MIN_WANDER_DELAY, MAX_WANDER_DELAY)
endif
elseif not isMoving then
set a = (GetUnitFacing(.master.u) + 180) * bj_DEGTORAD
call .human.move(x2 + FOLLOW_DISTANCE * Cos(a), y2 + FOLLOW_DISTANCE * Sin(a))
endif
endif
endif
elseif not .human.noRemove then
call destroy()
elseif not IsUnitPaused(.human.u) then
call .human.kill()
endif
set t = null
endmethod
method destroy takes nothing returns nothing
local unit u = .human.u
set Count = Count - 1
if StringLength(.sfx) > 0 then
call DestroyEffect(AddSpecialEffect(.sfx, GetUnitX(u), GetUnitY(u)))
endif
call GroupRemoveUnit(.master.subordinate, u)
call GroupRemoveUnit(PlayerUnits, u)
call .human.destroy()
call RemoveUnit(u)
call ReleaseTimer(.time)
call DestroyEffect(.selection)
call deallocate()
set .time = null
set .selection = null
set Index[.human] = 0
set Index[.master] = 0
set .master = 0
set .id = 0
set u = null
endmethod
static method create takes Combatant master, Combatant human returns thistype
local thistype this = allocate()
local string s = ""
set Count = Count + 1
set .master = master
set .human = human
set .target = 0
set .combatModeDur = 0
set .id = 0
set .sfx = ""
if Locale == master.owner then
set s = "war3mapImported\\SelectionGreen.mdx"
else
set s = "war3mapImported\\SelectionPlayer" + I2S(master.pid) + ".mdx"
endif
set .selection = AddSpecialEffectTarget(s, .human.u, "origin")
set Index[human] = this
set Index[master] = this
call GroupAddUnit(.master.subordinate, human.u)
set .time = NewTimerEx(this)
call TimerStart(.time, 0.1, true, function thistype.onTick)
return this
endmethod
endstruct
struct AmplifyDamage extends array
static boolean array IsRegistered
static real array Dealt
static real array Taken
static method remove takes Combatant c returns nothing
set IsRegistered[c] = false
set Dealt[c] = 1.
set Taken[c] = 1.
endmethod
static method amplify takes Combatant c, real dealt, real taken returns nothing
set IsRegistered[c] = true
set Dealt[c] = dealt
set Taken[c] = taken
endmethod
endstruct
struct Illusion extends array
static method copy takes Combatant c, player owner, real dmgDealt, real dmgTaken returns Combatant
local Combatant c2 = Combatant.create(CreateUnit(owner, GetUnitTypeId(c.u), GetUnitX(c.u), GetUnitY(c.u), GetUnitFacing(c.u)))
call UnitAddAbility(c2.u, 'Aloc')
call UnitRemoveAbility(c2.u, 'Aloc')
call ShowUnit(c2.u, false)
call ShowUnit(c2.u, true)
call UnitAddAbility(c2.u, 'Amrf')
call UnitRemoveAbility(c2.u, 'Amrf')
call UnitAddAbility(c2.u, 'Aeth')
call SetUnitPathing(c2.u, false)
call AmplifyDamage.amplify(c2, dmgDealt, dmgTaken)
set c2.isIllusion = true
set c2.level = c.level
set c2.dropQuality = 0
set c2.noRemove = false
set c2.hitsToKill = false
set c2.destructible = false
set c2.ignoreDamage = false
set c2.melee = false
set c2.missileHoming = c.missileHoming
set c2.missilePiercing = c.missilePiercing
set c2.missile = c.missile
set c2.missileCollision = c.missileCollision
set c2.missileScale = c.missileScale
set c2.missileSpeed = c.missileSpeed
set c2.missileArch = c.missileArch
set c2.missileTurn = c.missileTurn
set c2.missileXY = c.missileXY
set c2.missileZ = c.missileZ
set c2.dmgAoE = c.dmgAoE
set c2.attackRadius = c.attackRadius
set c2.attackRange = c.attackRange
set c2.dmgPoint = c.dmgPoint
set c2.attackRateDef = c.attackRateDef
set c2.attackRate = c.attackRate
set c2.physicDmgMin = c.physicDmgMin
set c2.physicDmgMax = c.physicDmgMax
set c2.physicDefense = c.physicDefense
set c2.magicDmgMin = c.magicDmgMin
set c2.magicDmgMax = c.magicDmgMax
set c2.magicDefense = c.magicDefense
set c2.criticalRate = c.criticalRate
set c2.criticalPower = c.criticalPower
set c2.blockRate = c.blockRate
set c2.evasionRate = c.evasionRate
set c2.knockback = c.knockback
set c2.knockbackResist = c.knockbackResist
set c2.interrupt = c.interrupt
set c2.interruptResist = c.interruptResist
set c2.stun = c.stun
set c2.stunResist = c.stunResist
set c2.hp = c.hp
set c2.hpMax = c2.hp
set c2.hpRegen = 0.0
set c2.sp = 0
set c2.spMax = 0
set c2.spRegen = 0
set c2.xpMultiplier = 0.0
set c2.wType = c.wType
return c2
endmethod
endstruct
//! endtextmacro
endlibrary
library KoboldSpawner uses TimerUtils, CreepLib, DungeonGeneration
private keyword INITS
struct KoboldSpawner
integer limit
unit u
real x
real y
private static method spawn takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local Combatant com
local integer i
local unit c
if IsUnitAlive(u) then
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] and IsUnitAlive(MainUnit[i]) and IsUnitInRange(MainUnit[i], .u, 1000.) and IsUnitVisible(MainUnit[i], CREEP_PLAYER) and not Fighter[i].isInvulnerable then
set .limit = .limit - 1
set c = CreateUnit(CREEP_PLAYER, 'h00Q', x, y, GetRandomReal(0, 359))
call IndexCreep(c)
call UnitAddAbility(c, 'Aloc')
call UnitRemoveAbility(c, 'Aloc')
call ShowUnit(c, false)
call ShowUnit(c, true)
set com = Combatant[c]
call AdjustCreepStrength(com, DungeonLevel)
set com.xpMultiplier = 0.0
set com.dropQuality = -1
set CreepAI[c].target = null
call CreepAI[c].switchTarget(MainUnit[i])
exitwhen true
endif
set i = i + 1
endloop
if .limit > 0 then
call TimerStart(t, GetRandomReal(2, 5), false, function thistype.spawn)
endif
else
//call KoboldNestDeathSound.play(0, 0, 0, 135)
call ReleaseTimer(t)
call deallocate()
set u = null
endif
set t = null
endmethod
static method create takes unit u returns thistype
local thistype this = allocate()
set .limit = GetRandomInt(5, 10)
set .u = u
set .x = GetUnitX(u)
set .y = GetUnitY(u)
call TimerStart(NewTimerEx(this), GetRandomReal(1, 3), false, function thistype.spawn)
return this
endmethod
implement INITS
endstruct
private module INITS
private static method onInit takes nothing returns nothing
endmethod
endmodule
endlibrary
library DryadEnchantress uses TimerUtils, PanelCore, MiniHealthBar, CombatSystem
public struct AreaHeal extends array
private static group Group = CreateGroup()
private static real Interval = 0.5
private static timer array Timer
private static method onPeriodic takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
local Combatant c2
local unit fog
local real amount
if IsUnitAlive(c.u) and c.sp >= 40 and c.hp < c.hpMax and not c.isStunned and not c.isSilenced then
set c.sp = c.sp - 40
set amount = c.hpMax*0.05
call GroupEnumUnitsInRange(Group, GetUnitX(c.u), GetUnitY(c.u), 600, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if UnitAlive(fog) and GetOwningPlayer(fog) == CREEP_PLAYER then
set c2 = Combatant[fog]
if c2.hp < c2.hpMax then
call DamageText_Show(I2S(R2I(amount)), 0, fog, HEAL_R, HEAL_G, HEAL_B, TEXTTAG_NORMAL_SIZE)
set c2.hp = c2.hp + amount
if c2.hp > c2.hpMax then
set c2.hp = c2.hpMax
endif
call MiniHealthBar_Show(Locale, c2, c2.hp/c2.hpMax)
call DestroyEffectTimed(AddSpecialEffectTarget("Abilities\\Spells\\Human\\Heal\\HealTarget.mdl", fog, "origin"), 2.0)
endif
endif
endloop
else
call Stop(c)
endif
set t = null
endmethod
public static method cast takes Combatant c returns nothing
call IssueImmediateOrder(c.u, "stop")
call SetUnitAnimation(c.u, "channel")
set Timer[c] = NewTimerEx(c)
call TimerStart(Timer[c], 1, true, function thistype.onPeriodic)
endmethod
private static method Stop takes Combatant c returns nothing
call ReleaseTimer(Timer[c])
set Timer[c] = null
call IssueImmediateOrder(c.u, "stop")
call SetUnitAnimation(c.u, "stand")
set CreepAI[c.u].channeling = false
endmethod
private static method OnDeath takes nothing returns boolean
local Combatant c = Combatant[GetTriggerUnit()]
if c.owner == CREEP_PLAYER and Timer[c] != null then
call Stop(c)
endif
return false
endmethod
private static method OnOrder takes nothing returns boolean
local Combatant c
if GetIssuedOrderId() == OrderId("stop") then
set c = Combatant[GetTriggerUnit()]
if c.owner == CREEP_PLAYER and Timer[c] != null then
call Stop(c)
endif
endif
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(t, Condition(function thistype.OnDeath))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerAddCondition(t, Condition(function thistype.OnOrder))
set t = null
endmethod
endstruct
endlibrary
library SludgeMonsterSplit uses CreepLib
globals
trigger SludgeSplitTrigger = null
endglobals
private function split takes nothing returns boolean
local unit u
local Combatant c = Combatant[GetTriggerUnit()]
local Combatant c2
local integer i = 3
loop
exitwhen i <= 0
set u = CreateUnit(CREEP_PLAYER, 'h02Z', GetUnitX(c.u), GetUnitY(c.u), GetUnitFacing(c.u))
call UnitAddAbility(u, 'Aloc')
call UnitRemoveAbility(u, 'Aloc')
call ShowUnit(u, false)
call ShowUnit(u, true)
call UnitAddAbility(u, 'Amrf')
call UnitRemoveAbility(u, 'Amrf')
set c2 = Combatant.create(u)
call CreepAI.create(u)
set c2.dropQuality = 0
set c2.noRemove = false
set c2.hitsToKill = false
set c2.destructible = false
set c2.ignoreDamage = false
set c2.melee = false
set c2.missileHoming = true
set c2.missilePiercing = false
set c2.missile = "Abilities\\Weapons\\SludgeMissile\\SludgeMissile.mdl"
set c2.missileCollision = 50.0
set c2.missileScale = 0.5
set c2.missileSpeed = 25.0
set c2.missileArch = 20.*bj_DEGTORAD
set c2.missileTurn = 1.5*bj_DEGTORAD
set c2.missileXY = 50
set c2.missileZ = 40
set c2.dmgAoE = 0
set c2.attackRadius = 45.0*bj_DEGTORAD
set c2.attackRange = 800.0
set c2.dmgPoint = 0.3
set c2.attackRateDef = 1.5
set c2.attackRate = c2.attackRateDef
set c2.physicDmgMin = 7
set c2.physicDmgMax = 15
set c2.physicDefense = 12.
set c2.magicDmgMin = 0
set c2.magicDmgMax = 0
set c2.magicDefense = 0.
set c2.criticalRate = 0.05
set c2.criticalPower = 0.75
set c2.blockRate = 0
set c2.evasionRate = 0
set c2.knockback = 0.0
set c2.knockbackResist = 0.0
set c2.interrupt = 0.0
set c2.interruptResist = 1.0
set c2.stun = 0.0
set c2.stunResist = 1.0
set c2.hp = 200.0
set c2.hpMax = c2.hp
set c2.hpRegen = 5.0
set c2.sp = 0
set c2.spMax = 0
set c2.spRegen = 0
set c2.xpMultiplier = 1
set c2.wType = WEAPON_TYPE_WHOKNOWS
call AdjustCreepStrength(c2, DungeonLevel)
set i = i - 1
endloop
set u = null
return false
endfunction
public function Reset takes nothing returns nothing
call DestroyTrigger(SludgeSplitTrigger)
set SludgeSplitTrigger = CreateTrigger()
call TriggerAddCondition(SludgeSplitTrigger, Condition(function split))
endfunction
endlibrary
library GargoyleStatue uses TimerUtils, CreepLib, DungeonGeneration
private keyword INITS
struct GargoyleStatue
unit u
real x
real y
private static method detect takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local Combatant com
local integer i
local unit c
if IsUnitAlive(u) then
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] and IsUnitAlive(MainUnit[i]) and IsUnitInRangeXY(MainUnit[i], .x, .y, 300.) and IsUnitVisible(MainUnit[i], CREEP_PLAYER) and not Fighter[i].isInvulnerable then
set c = CreateUnit(CREEP_PLAYER, 'h00U', .x, .y, GetUnitFacing(.u))
call UnitAddAbility(c, 'Aloc')
call UnitRemoveAbility(c, 'Aloc')
call ShowUnit(c, false)
call ShowUnit(c, true)
call SetUnitPathing(c, false)
call SetUnitState(c, UNIT_STATE_LIFE, GetUnitState(.u, UNIT_STATE_LIFE))
call SetUnitAnimationByIndex(c, 8)
call QueueUnitAnimation(c, "stand")
call SetUnitX(c, .x)
call SetUnitY(c, .y)
call PanelCore_SetUnitZ(c, 2400)
call GargoyleMorph.create(c, MainUnit[i])
call RemoveUnit(.u)
call ReleaseTimer(t)
call deallocate()
set .u = null
exitwhen true
endif
set i = i + 1
endloop
else
call ReleaseTimer(t)
call deallocate()
set u = null
endif
set t = null
endmethod
static method create takes unit u returns thistype
local thistype this = allocate()
set .u = u
set .x = GetUnitX(u)
set .y = GetUnitY(u)
call TimerStart(NewTimerEx(this), 0.1, true, function thistype.detect)
return this
endmethod
implement INITS
endstruct
private module INITS
private static method onInit takes nothing returns nothing
endmethod
endmodule
endlibrary
library GargoyleMorph uses TimerUtils, CreepLib, DungeonGeneration, CombatSystem
private keyword INITS
struct GargoyleMorph
Combatant c
CreepAI ai
unit u
unit t
real a
real sa
real x
real y
real z
real mSpd
real rSpd
real cSpd
real sx
real sy
real sz
real delay
boolean attacked
boolean returning
boolean cooldown
boolean starting
static thistype array Index
static constant real TURN_RATE = 2*bj_DEGTORAD
static constant real ACCELERATION = 0.5
static constant real DEACCELERATION = 0.25
static constant real WANDER_Z = 64
private static method revertForm takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local unit u
set u = CreateUnit(CREEP_PLAYER, 'h00T', .sx, .sy, .sa)
call UnitAddAbility(u, 'Aloc')
call UnitRemoveAbility(u, 'Aloc')
call ShowUnit(u, false)
call ShowUnit(u, true)
call UnitAddAbility(u, 'Amrf')
call UnitRemoveAbility(u, 'Amrf')
call SetUnitPathing(u, false)
call SetUnitX(u, .x)
call SetUnitY(u, .y)
call SetUnitState(u, UNIT_STATE_LIFE, .c.hp/.c.hpMax * GetUnitState(u, UNIT_STATE_MAX_LIFE))
call PanelCore_SetUnitZ(u, 2400)
//call UnitRemoveAbility(u, 'Amov')
call GargoyleStatue.create(u)
call .c.destroy()
call RemoveUnit(.u)
call ReleaseTimer(t)
call deallocate()
set .t = null
set .u = null
set u = null
set t = null
endmethod
private static method animate takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local Combatant com
local integer i
local unit c
local real targA
local real tHeight
local real tx
local real ty
local real damage
if IsUnitAlive(u) then
if starting then
set .z = .z + mSpd
call SetUnitFlyHeight(.u, .z, 0)
if .z > .sz + 300 then
call SetUnitAnimationByIndex(.u, 2)
set .a = Atan2(GetUnitY(.t) - .y, GetUnitX(.t) - .x)
set starting = false
call IndexCreep(.u)
set .c = Combatant[.u]
set .ai = CreepAI[.u]
set .ai.enabled = false
call .ai.switchTarget(.t)
set .attacked = false
call CreepSfx_alert(.c)
call AdjustCreepStrength(.c, DungeonLevel)
set .c.hp = .c.hpMax*(GetUnitState(u, UNIT_STATE_LIFE)/GetUnitState(u, UNIT_STATE_MAX_LIFE))
call .c.invulnerable(0, 3, null)
endif
elseif returning then
if .cSpd > .rSpd then
set .cSpd = .cSpd - DEACCELERATION
if .cSpd < rSpd then
set .cSpd = rSpd
endif
elseif .cSpd < .rSpd then
set .cSpd = .cSpd + ACCELERATION
if .cSpd > rSpd then
set .cSpd = rSpd
endif
endif
if .z > .sz then
set .z = .z - cSpd
if .z < .sz then
set .z = .sz
endif
elseif .z < .sz then
set .z = .z + cSpd
if .z > .sz then
set .z = .sz
endif
endif
set targA = Atan2(.sy - .y, .sx - .x)
if TURN_RATE > 0 and Cos(.a-targA) < Cos(TURN_RATE) then
if Sin(targA-.a) >= 0 then
set .a = .a + TURN_RATE
else
set .a = .a - TURN_RATE
endif
else
set .a = targA
endif
set .x = GetUnitX(.u) + .cSpd * Cos(.a)
set .y = GetUnitY(.u) + .cSpd * Sin(.a)
call SetUnitX(.u, .x)
call SetUnitY(.u, .y)
call SetUnitFacing(.u, .a*bj_RADTODEG)
call SetUnitFlyHeight(.u, .z, 0)
if IsUnitInRangeXY(.u, .sx, .sy, .cSpd) then
call SetUnitX(.u, .sx)
call SetUnitY(.u, .sy)
call SetUnitFlyHeight(.u, .sz, 0)
call SetUnitFacing(.u, .sa)
call SetUnitAnimationByIndex(.u, 6)
call .ai.destroy()
call TimerStart(t, 10.0, false, function thistype.revertForm)
endif
elseif cooldown then
if .z > WANDER_Z then
set .z = .z - cSpd
if .z < WANDER_Z then
set .z = WANDER_Z
endif
elseif .z < WANDER_Z then
set .z = .z + cSpd
if .z > WANDER_Z then
set .z = WANDER_Z
endif
endif
if .cSpd > .mSpd then
set .cSpd = .cSpd - DEACCELERATION
if .cSpd <= mSpd then
set .cSpd = mSpd
set .a = Atan2(GetUnitY(.t) - .y, GetUnitX(.t) - .x)
call SetUnitFacing(.u, .a*bj_RADTODEG)
set .a = .a + bj_PI
endif
elseif .cSpd < .mSpd then
set .cSpd = .cSpd + ACCELERATION
if .cSpd > mSpd then
set .cSpd = mSpd
endif
else
if delay > 0.03 then
set delay = delay - 0.03
endif
if ModuloReal(delay, 1) < 0.03 then
set .a = Atan2(GetUnitY(.t) - .y, GetUnitX(.t) - .x)
call SetUnitFacing(.u, .a*bj_RADTODEG)
set .a = .a + bj_PI
endif
endif
set .x = GetUnitX(.u) + .cSpd * Cos(.a)
set .y = GetUnitY(.u) + .cSpd * Sin(.a)
call SetUnitX(.u, .x)
call SetUnitY(.u, .y)
call SetUnitFlyHeight(.u, .z, 0)
if delay <= 0.9 then
call CreepSfx_attack(.c)
set .attacked = false
call SetUnitAnimationByIndex(.u, 2)
set .a = Atan2(GetUnitY(.t) - .y, GetUnitX(.t) - .x)
set cooldown = false
set delay = 0
endif
else
if IsUnitAlive(.t) and IsUnitVisible(.t, .c.owner) and IsUnitInRangeXY(.u, .sx, .sy, SquareRoot(CREEP_MAX_CHASE_DISTANCE)) then
set cSpd = cSpd + ACCELERATION
if cSpd > rSpd then
set cSpd = rSpd
endif
set tx = GetUnitX(.t)
set ty = GetUnitY(.t)
set targA = Atan2(ty - .y, tx - .x)
if TURN_RATE > 0 and Cos(.a-targA) < Cos(TURN_RATE) then
if Sin(targA-.a) >= 0 then
set .a = .a + TURN_RATE
else
set .a = .a - TURN_RATE
endif
else
set .a = targA
endif
set .x = GetUnitX(.u) + .cSpd * Cos(.a)
set .y = GetUnitY(.u) + .cSpd * Sin(.a)
set tHeight = RMaxBJ(GetUnitFlyHeight(.t), WANDER_Z)
if .z > tHeight then
set .z = .z - cSpd
if .z < tHeight then
set .z = tHeight
endif
elseif .z < tHeight then
set .z = .z + cSpd
if .z > tHeight then
set .z = tHeight
endif
endif
call SetUnitX(.u, .x)
call SetUnitY(.u, .y)
call SetUnitFlyHeight(.u, .z, 0)
call SetUnitFacing(.u, .a*bj_RADTODEG)
if RAbsBJ(.z - tHeight) < cSpd then
if IsUnitInRangeXY(.u, tx, ty, .c.attackRange) then
set cooldown = true
set delay = .c.attackRateDef
set cSpd = 0
set .a = .a + bj_PI
// Deal damage
set damage = CombatSystem_CalculateDamage(.c, Combatant[.t])
call CombatSystem_Damage(.u, .t, damage, true, true, true)
if .ai.target != null then
set .t = .ai.target
endif
elseif IsUnitInRangeXY(.u, tx, ty, 200) and not .attacked then
call SetUnitAnimationByIndex(.u, 4)
call QueueUnitAnimation(.u, "stand")
set .attacked = true
elseif RAbsBJ(PanelCore_AngularDifference(.a, targA)) > PanelCore_HP/4 then
set cooldown = true
set delay = .c.attackRateDef
call SetUnitAnimationByIndex(.u, 3)
set .t = .ai.target
endif
endif
else
call .c.invulnerable(0, 3600, null)
set .rSpd = .rSpd / 2
set returning = true
call .ai.abort()
endif
endif
else
call .ai.abort()
call ReleaseTimer(t)
call deallocate()
set .t = null
set .u = null
endif
set t = null
endmethod
static method create takes unit u, unit target returns thistype
local thistype this = allocate()
set .u = u
set .sa = GetUnitFacing(u)
set .a = .sa*bj_DEGTORAD
set .x = GetUnitX(u)
set .y = GetUnitY(u)
set .z = GetUnitFlyHeight(u)
set .sx = .x
set .sy = .y
set .sz = .z
set .mSpd = (125 * 0.03)
set .rSpd = (450 * 0.03)
set .cSpd = 0
set .delay = 0
set .t = target
set .starting = true
set .returning = false
set .cooldown = false
call TimerStart(NewTimerEx(this), 0.03, true, function thistype.animate)
return this
endmethod
implement INITS
endstruct
private module INITS
private static method onInit takes nothing returns nothing
endmethod
endmodule
endlibrary
library KnightSkills
//! textmacro SkillLib
globals
effect array HolyShieldEffect
integer array DoubleCrashAnimDex
real array AeroJabDirection
endglobals
struct ValiantCharge extends array
static real array SoundDelay
static real array Angle
static real array Distance
static real array Damage
static real array Stun
static real array Knock
static group array HitGroup
static effect array DashSfx
static effect array Light
static constant real SPEED = 60.0
static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
local Combatant c2
local real x
local real y
local real x2
local real y2
local real damage
local boolean play
local unit fog
if Distance[c] > 0 and IsUnitAlive(c.u) then
if SoundDelay[c] > 0 then
set SoundDelay[c] = SoundDelay[c] - 0.03125
endif
call CameraShaker_StartV(c.pid, 5, 0.5)
set Distance[c] = Distance[c] - SPEED
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
set x2 = x + SPEED * Cos(Angle[c])
set y2 = y + SPEED * Sin(Angle[c])
set play = false
call GroupEnumUnitsInRange(Group, x2, y2, 100, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, c.owner) and IsUnitAlive(fog) and not IsUnitInGroup(fog, HitGroup[c]) then
call GroupAddUnit(HitGroup[c], fog)
set c2 = Combatant[fog]
if not c2.isInvulnerable then
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\Valiant_Target.mdx", fog, "chest"))
if Stun[c] > 0 then
call c2.applyStun(1, Stun[c], AddSpecialEffectTarget("Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl", fog, "overhead"))
endif
call Knockback.create(fog, Angle[c], Knock[c], GENERAL_KNOCKBACK_SPEED, true)
set damage = CalculateConstantDamage(c, c2, Damage[c], true)
call Damage(c.u, fog, damage, false, false, false)
set play = true
endif
endif
endloop
if not IsTerrainWalkable(x2, y2) then
set Distance[c] = 0
call SetUnitX(c.u, x)
call SetUnitY(c.u, y)
else
call SetUnitX(c.u, x2)
call SetUnitY(c.u, y2)
endif
if play and SoundDelay[c] <= 0 then
set SoundDelay[c] = 0.1
call ValiantChargeHitSfx[GetRandomInt(0, 2)].play(x, y, PanelCore_GetUnitZ(c.u), 150)
endif
else
call c.mobilize(0)
call TimerStart(c.attackTimer, 0.25, false, function Combatant.resetTimer)
if IsUnitAlive(c.u) then
call SetUnitAnimation(c.u, "stand")
call SetUnitTimeScale(c.u, 1.)
endif
call DestroyEffect(Light[c])
call DestroyEffect(DashSfx[c])
call DestroyGroup(HitGroup[c])
call AddSpecialEffect("war3mapImported\\Valiant_End.mdx", GetUnitX(c.u), GetUnitY(c.u))
call ReleaseTimer(t)
set HitGroup[c] = null
set DashSfx[c] = null
set Light[c] = null
endif
set t = null
endmethod
static method start takes Combatant c returns nothing
local unit u
call ValiantChargeSfx.play(GetUnitX(c.u), GetUnitY(c.u), PanelCore_GetUnitZ(c.u), 200)
set HitGroup[c] = CreateGroup()
set Angle[c] = GetUnitFacing(c.u)*bj_DEGTORAD
set Distance[c] = ValiantChargeDistance(c.pid)
set Damage[c] = ValiantChargeDamage(c.pid)
set Stun[c] = ValiantChargeStun(c.pid)
set Knock[c] = ValiantChargeKnockback(c.pid)
set DashSfx[c] = AddSpecialEffectTarget("war3mapImported\\Valiant_Charge.mdx", c.u, "origin")
set Light[c] = AddSpecialEffectTarget("war3mapImported\\LightOrange30.mdx", c.u, "origin")
// Create shockwave
set u = CreateUnit(c.owner, 'e000', GetUnitX(c.u)+Distance[c]*Cos(Angle[c]), GetUnitY(c.u)+Distance[c]*Sin(Angle[c]), Angle[c]*bj_RADTODEG)
static if not LIBRARY_AutoFly then
if UnitAddAbility(u, 'Amrf') and UnitRemoveAbility(u, 'Amrf') then
endif
endif
call PanelCore_SetUnitZ(u, PanelCore_GetUnitZ(c.u))
call SetUnitScale(u, 0.5, 0.5, 0.5)
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\ValiantChargeShockwave.mdx", u, "origin"))
call UnitApplyTimedLife(u, 'BTLF', 5)
//call SetUnitAnimationByIndex(c.u, 6)
call SetUnitAnimationByIndex(c.u, 7)
call SetUnitTimeScale(c.u, 8.)
call TimerStart(c.attackTimer, 3600, false, function Combatant.resetTimer)
call TimerStart(NewTimerEx(c), 0.03125, true, function thistype.onTick)
call c.immobilize(0, 3600, null)
set u = null
endmethod
endstruct
struct NightmareFallPillar
Combatant c
unit dummy
unit dummy2
effect pillar
effect nova
effect blast
effect light
real x
real y
real z
real a
real tx
real ty
real delay
real dur
real speed
real damage
real damageDelay
timer t
static real TURN_RATE = 4 * bj_DEGTORAD
method destroy takes nothing returns nothing
call ReleaseTimer(.t)
//call FadingDecay.create(.dummy, 255, 7.96875)
call DestroyEffect(.pillar)
call DestroyEffect(.nova)
call DestroyEffect(.blast)
call DestroyEffect(.light)
call DestroyEffectTimed(AddSpecialEffect("war3mapImported\\ShivasWrath.mdx", .x, .y), 0.5)
call RemoveUnit(.dummy)
call UnitApplyTimedLife(.dummy2, 'BTLF', 5)
call deallocate()
set .dummy = null
set .dummy2 = null
set .pillar = null
set .nova = null
set .blast = null
set .light = null
set .t = null
endmethod
static method onPeriodic takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local real dist
local real ang
local real a
local real dmg
local unit fog
local Combatant c2
set .dur = .dur - 0.03125
if (dur > 0) then
set .delay = .delay - 0.03125
if (delay <= 0) then
set .delay = GetRandomReal(0.5, 1.5)
set dist = GetRandomReal(-400, 400)
set ang = GetRandomReal(-bj_PI, bj_PI)
set .tx = .x + dist * Cos(ang)
set .ty = .y + dist * Sin(ang)
call NightmareFallLoopSfx.play(.x, .y, .z, 100)
endif
if (dur > 6.25 and .speed > 3) then
set .speed = .speed - 0.21875
else
set .speed = 3
endif
set a = Atan2(.ty-.y, .tx-.x)
if TURN_RATE > 0 and Cos(.a-a) < Cos(TURN_RATE) then
if Sin(a-.a) >= 0 then
set .a = .a + TURN_RATE
else
set .a = .a - TURN_RATE
endif
else
set .a = a
endif
set .x = .x + .speed * Cos(.a)
set .y = .y + .speed * Sin(.a)
call SetUnitX(.dummy, .x)
call SetUnitY(.dummy, .y)
call SetUnitX(.dummy2, .x)
call SetUnitY(.dummy2, .y)
set .damageDelay = .damageDelay - 0.03125
if .damageDelay <= 0 then
set .damageDelay = 0.5
call GroupEnumUnitsInRange(Group, .x, .y, 150, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, c.owner) and IsUnitAlive(fog) then
set c2 = Combatant[fog]
if not c2.isInvulnerable then
set dmg = CalculateConstantDamage(c, c2, .damage, true)*0.5
call Damage(c.u, fog, dmg, false, false, false)
endif
endif
endloop
endif
else
call destroy()
endif
set t = null
endmethod
static method create takes Combatant c, real a returns thistype
local thistype this = allocate()
set .c = c
set .x = GetUnitX(c.u)
set .y = GetUnitY(c.u)
set .z = PanelCore_GetUnitZ(c.u)
set .dummy = CreateUnit(c.owner, 'e000', .x, .y, 0)
set .dummy2 = CreateUnit(c.owner, 'e000', .x, .y, 0)
set .pillar = AddSpecialEffectTarget("war3mapImported\\DarkLightning.mdx", .dummy, "origin")
set .nova = AddSpecialEffectTarget("war3mapImported\\ShivasWrathLoop.mdx", .dummy, "origin")
set .blast = AddSpecialEffectTarget("war3mapImported\\Miasma.MDX", .dummy, "origin")
set .light = AddSpecialEffectTarget("war3mapImported\\LightPurple60.mdx", .dummy2, "overhead")
set .a = a
set .tx = .x + 400 * Cos(a)
set .ty = .y + 400 * Sin(a)
set .delay = 0.75
set .speed = 10
set .dur = 7
set .damageDelay = 0
set .damage = NightmareFallDamage(c.pid)
//call SetUnitScale(.dummy, 0.5, 0.5, 0.5)
set .t = NewTimerEx(this)
call TimerStart(.t, 0.03125, true, function thistype.onPeriodic)
return this
endmethod
endstruct
struct SoulboundMissile
Missile missile
Combatant c
//effect glow
effect light
static unit array Target
static method onRemove takes Missile missile returns boolean
local thistype this = missile.data
//call RemoveUnit(missile.dummy)
//call DestroyEffect(.glow)
//call DestroyEffect(.light)
call UnitApplyTimedLife(missile.dummy, 'BTLF', 5.0)
//set .glow = null
//set .light = null
return true
endmethod
static method onPeriod takes Missile missile returns boolean
if missile.turn < 15*bj_DEGTORAD then
set missile.turn = missile.turn+0.03125*bj_DEGTORAD
endif
return not IsUnitAlive(thistype(missile.data).c.u)
endmethod
static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = missile.data
call missile.hitWidget(hit)
if hit == .c.u and IsUnitAlive(hit) then
call DamageText_Show(I2S(R2I(missile.damage)), 0, hit, HEAL_R, HEAL_G, HEAL_B, TEXTTAG_NORMAL_SIZE)
set .c.hp = .c.hp + missile.damage
if .c.hp > .c.hpMax then
set .c.hp = .c.hpMax
endif
call DestroyEffectTimed(AddSpecialEffectTarget("war3mapImported\\SoulboundHeal2.mdx", .c.u, "origin"), 5)
return true
endif
return false
endmethod
implement MissileStruct
static method create takes Combatant com returns thistype
local thistype this
local real a
local real x
local real y
local real z
local unit m
local integer count = SoulboundCount(com.pid)
set this = allocate()
set c = com
set x = GetUnitX(Target[c])
set y = GetUnitY(Target[c])
set a = Atan2(y-GetUnitY(c.u), x-GetUnitX(c.u))+GetRandomReal(-PanelCore_HP/2., PanelCore_HP/2.)
set z = GetUnitFlyHeight(Target[c])
set .missile = Missile.create(x, y, z+30, a, 9999999, GetUnitFlyHeight(com.u)+30)
set .missile.source = c.u
set .missile.owner = c.owner
set .missile.model = "war3mapImported\\SoulboundMissile.mdl"
set .missile.speed = 15
set .missile.turn = 5*bj_DEGTORAD
set .missile.arc = 60*bj_DEGTORAD
set .missile.target = c.u
set .missile.damage = Combatant[Target[c]].hpMax*0.03*count
set .missile.scale = 0.15
set .missile.collision = 5
set .missile.data = this
//set .light = AddSpecialEffectTarget("war3mapImported\\LightPurple30.mdx", m, "origin")
//set .glow = AddSpecialEffectTarget("war3mapImported\\GlowSoulbound.mdx", m, "origin")
call launch(.missile)
set m = null
set Target[c] = null
return this
endmethod
endstruct
struct VampiricGroanMissile
Missile missile
Combatant c
real scale
real rate
real health
real mana
static unit array Target
static method onRemove takes Missile missile returns boolean
call KillUnit(missile.dummy)
return false
endmethod
static method onPeriod takes Missile missile returns boolean
local thistype this = missile.data
if missile.turn < 15*bj_DEGTORAD then
set missile.turn = missile.turn+0.03125*bj_DEGTORAD
endif
if .scale > 0.25 then
set .scale = .scale - .rate
if .scale < 0.25 then
set .scale = 0.25
endif
set missile.scale = .scale
endif
return false
endmethod
static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = missile.data
local unit fog
local group gr
call missile.hitWidget(hit)
if hit == .c.u then
if IsUnitAlive(hit) then
//call CustomTextTag(I2S(R2I(.health)), 0, hit, HEAL_R, HEAL_G, HEAL_B, TEXTTAG_NORMAL_SIZE)
set c.hp = c.hp + .health
if c.hp > c.hpMax then
set c.hp = c.hpMax
endif
set c.sp = c.sp + .mana
if c.sp > c.spMax then
set c.sp = c.spMax
endif
endif
return true
endif
return false
endmethod
implement MissileStruct
static method create takes Combatant com, real hp, real mp returns thistype
local thistype this = allocate()
local real a
local real x
local real y
local real z
local unit m
local real dx
local real dy
set c = com
set x = GetUnitX(Target[c])
set y = GetUnitY(Target[c])
set dx = GetUnitX(Target[c])-x
set dy = GetUnitY(Target[c])-y
set .scale = 2.5
set .rate = 9 * 0.03125
set .health = hp
set .mana = mp
set a = Atan2(GetUnitY(c.u)-y, GetUnitX(c.u)-x)
set z = GetUnitFlyHeight(Target[c])
set .missile = Missile.create(x, y, z+30, a, 9999999, GetUnitFlyHeight(com.u)+30)
set .missile.source = c.u
set .missile.owner = c.owner
set .missile.model = "war3mapImported\\SoulboundMissile.mdl"
set .missile.speed = 30
set .missile.turn = 5*bj_DEGTORAD
set .missile.arc = 60*bj_DEGTORAD
set .missile.target = c.u
set .missile.damage = 0
set .missile.collision = 5
set .missile.scale = .scale
set .missile.data = this
call launch(.missile)
set Target[c] = null
set m = null
return this
endmethod
endstruct
struct VampiricGroan extends array
static integer array MaxTarget
static real array HPSteal
static real array MPSteal
static real array Duration
static effect array Gfx
static real INTERVAL = 1.0
static method onPeriod takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
local Combatant c2
local unit fog
local integer count = 0
set Duration[c] = Duration[c] - INTERVAL
if IsUnitAlive(c.u) and Duration[c] > 0 then
call GroupEnumUnitsInRange(Group, GetUnitX(c.u), GetUnitY(c.u), 650, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null or count >= MaxTarget[c]
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, c.owner) and IsUnitAlive(fog) and GetUnitAbilityLevel(fog, 'Amov') > 0 then
set count = count + 1
set VampiricGroanMissile.Target[c] = fog
call Damage(c.u, fog, HPSteal[c], false, false, false)
if Level[c] >= 5 then
set c2 = Combatant[fog]
if c2.sp > MPSteal[c] then
set c2.sp = c2.sp - MPSteal[c]
if c2.sp < 0 then
set c2.sp = 0
endif
call VampiricGroanMissile.create(c, HPSteal[c], MPSteal[c])
else
call VampiricGroanMissile.create(c, HPSteal[c], 0)
endif
else
call VampiricGroanMissile.create(c, HPSteal[c], 0)
endif
endif
endloop
call GroupClear(Group)
set fog = null
else
call DestroyEffect(Gfx[c])
call ReleaseTimer(t)
set Gfx[c] = null
endif
set t = null
endmethod
static method create takes Combatant c returns thistype
local PlayerSkill skill = PlayerSkillData[c.pid][18]
set Duration[c] = 3.5
set MaxTarget[c] = VampiricGroanMaxTarget(c.pid)
set HPSteal[c] = VampiricGroanHealthSteal(c.pid)
if skill.level >= 5 then
set MPSteal[c] = VampiricGroanManaSteal(c.pid)
else
set MPSteal[c] = 0
endif
if Gfx[c] != null then
call DestroyEffect(Gfx[c])
endif
set Gfx[c] = AddSpecialEffectTarget("war3mapImported\\VoodooAuraReverse.mdx", c.u, "origin")
call TimerStart(NewTimerEx(c), INTERVAL, true, function thistype.onPeriod)
return 0
endmethod
endstruct
struct SpectraVortexMissile
Missile missile
Combatant c
real distance
static unit array SpectraUnit
static unit array SpectraTarget
static real array DamageMin
static real array DamageMax
static method onRemove takes Missile missile returns boolean
local Combatant c2
local thistype this = missile.data
local real damage
local unit fog
call ResetDummy.reset(missile.dummy)
call GroupEnumUnitsInRange(Group, missile.x, missile.y, 200, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, c.owner) and IsUnitAlive(fog) then
set c2 = Combatant[fog]
if not c2.isInvulnerable then
set damage = CalculateConstantDamage(c, c2, missile.damage, false)
call Damage(missile.source, fog, damage, false, false, false)
endif
endif
endloop
return true
endmethod
static method onPeriod takes Missile missile returns boolean
set thistype(missile.data).distance = thistype(missile.data).distance + missile.speed
return thistype(missile.data).distance >= 700
endmethod
static method onCollide takes Missile missile, unit hit returns boolean
call missile.hitWidget(hit)
return IsUnitEnemy(hit, missile.owner) and IsUnitAlive(hit)
endmethod
implement MissileStruct
static method create takes nothing returns thistype
local timer t = GetExpiredTimer()
local Combatant com = GetTimerData(t)
local thistype this
local real a
local real x
local real y
local real z
local unit m
if IsUnitAlive(SpectraUnit[com]) and IsUnitAlive(SpectraTarget[com]) then
set this = allocate()
set c = com
set a = GetUnitFacing(SpectraUnit[c])*bj_DEGTORAD
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
set z = GetUnitFlyHeight(c.u)
set m = CreateUnit(c.owner, 'e000', x, y, a * bj_RADTODEG)
static if not LIBRARY_AutoFly then
if UnitAddAbility(m, 'Amrf') and UnitRemoveAbility(m, 'Amrf') then
endif
endif
call SetUnitFlyHeight(m, z+150, 0)
set x = x + 700 * Cos(a)
set y = y + 700 * Sin(a)
set .missile = Missile.createEx(m, x, y, z+30)
set .missile.model = "war3mapImported\\DarknessBomb.mdl"
set .missile.source = c.u
set .missile.owner = c.owner
set .missile.speed = 35
set .missile.turn = 5*bj_DEGTORAD
set .missile.target = SpectraTarget[c]
set .missile.damage = GetRandomReal(DamageMin[c], DamageMax[c])
set .missile.collision = 100
set .missile.data = this
set .distance = 0
call launch(.missile)
set SpectraUnit[c] = null
set SpectraTarget[c] = null
set m = null
endif
call ReleaseTimer(t)
set t = null
return this
endmethod
endstruct
struct SpectraVortex
Combatant c
real dur
real change
real delay
real dmgMin
real dmgMax
boolean moving
unit dummy
unit target
static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local unit closest
local unit fog
local real dist
local real a
local real x
local real y
local real dx
local real dy
set .dur = .dur - 0.03125
if .delay > 0 then
set .delay = .delay - 0.03125
endif
if dur > 0 and IsUnitAlive(.c.u) then
set x = GetUnitX(.c.u)
set y = GetUnitY(.c.u)
call SetUnitX(.dummy, x)
call SetUnitY(.dummy, y)
call PanelCore_SetUnitZ(.dummy, PanelCore_GetUnitZ(.c.u)+50)
if .target == null then
set dist = 700*700
set closest = null
call GroupEnumUnitsInRange(Group, x, y, 700, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, c.owner) and IsUnitAlive(fog) then
set dx = GetUnitX(fog)-x
set dy = GetUnitY(fog)-y
if dx*dx+dy*dy < dist then
if not Combatant[fog].isInvulnerable then
set closest = fog
set dist = dx*dx+dy*dy
endif
endif
endif
endloop
set .target = closest
if .target == null then
call SetUnitFacing(.dummy, GetUnitFacing(.c.u))
endif
set closest = null
else
if Combatant[.target].hp > 0 and IsUnitInRangeXY(.target, x, y, 700) then
set .change = .change + 0.03125
if .change < 5 then
set a = Atan2(GetUnitY(.target)-y, GetUnitX(.target)-x)
call SetUnitFacing(.dummy, a*bj_RADTODEG)
if .delay <= 0 and RAbsBJ(PanelCore_AngularDifference(GetUnitFacing(.dummy)*bj_DEGTORAD, a)) < 30*bj_DEGTORAD then
set .delay = 2.25
call SetUnitAnimationByIndex(.dummy, 4)
call QueueUnitAnimation(.dummy, "ready")
call QueueUnitAnimation(.dummy, "ready")
call QueueUnitAnimation(.dummy, "stand")
set SpectraVortexMissile.SpectraUnit[.c] = .dummy
set SpectraVortexMissile.SpectraTarget[.c] = .target
set SpectraVortexMissile.DamageMin[.c] = .dmgMin
set SpectraVortexMissile.DamageMax[.c] = .dmgMax
call TimerStart(NewTimerEx(.c), 0.5, false, function SpectraVortexMissile.create)
endif
else
set .change = 0
set .target = null
endif
else
set .target = null
set SpectraVortexMissile.SpectraTarget[.c] = null
call SetUnitAnimation(.dummy, "stand")
endif
endif
else
call KillUnit(.dummy)
call ReleaseTimer(t)
call deallocate()
set .dummy = null
endif
set t = null
endmethod
static method create takes Combatant c returns thistype
local thistype this = allocate()
local real dmg = c.randomPhysicDamage * SpectraVortexPercentage(c.pid)
set .c = c
set .dur = SpectraVortexDuration(c.pid)
set .delay = 1.25
set .change = 0
set .moving = false
set .target = null
set .dmgMin = dmg * 0.85
set .dmgMax = dmg * 1.15
set .dummy = CreateUnit(c.owner, 'e01C', GetUnitX(c.u), GetUnitY(c.u), GetUnitFacing(c.u))
static if not LIBRARY_AutoFly then
if UnitAddAbility(.dummy, 'Amrf') and UnitRemoveAbility(.dummy, 'Amrf') then
endif
endif
call PanelCore_SetUnitZ(.dummy, PanelCore_GetUnitZ(c.u)+50)
call SetUnitPathing(.dummy, false)
call SetUnitAnimationByIndex(.dummy, 6)
call QueueUnitAnimation(.dummy, "stand")
call TimerStart(NewTimerEx(this), 0.03125, true, function thistype.onTick)
return this
endmethod
endstruct
struct MenacingPresence
Combatant c
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local unit fog
local real amount
if c.hp > 0 then
set amount = MenacingPressenceThreatAmount(c.pid)
call GroupEnumUnitsInRange(Group, GetUnitX(c.u), GetUnitY(c.u), 800, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, c.owner) and IsUnitAlive(fog) then
if GetOwningPlayer(fog) == CREEP_PLAYER then
call CreepAI[fog].damage(c, amount)
endif
endif
endloop
endif
set t = null
endmethod
static method create takes unit u returns thistype
local thistype this = allocate()
set .c = Combatant[u]
call TimerStart(NewTimerEx(this), 1, true, function thistype.onTick)
return this
endmethod
endstruct
struct ProtectionVigor
Combatant c
real physicBonus
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local PlayerSkill skill
set c.physicDmgMin = c.physicDmgMin - physicBonus
set c.physicDmgMax = c.physicDmgMax - physicBonus
set skill = PlayerSkillData[c.pid][14]
set physicBonus = CharacterWindow_SlotObject[c.pid][Items.RIGHT_HAND].physicDefense*ProtectionVigorPercentage(c.pid)
set c.physicDmgMin = c.physicDmgMin + physicBonus
set c.physicDmgMax = c.physicDmgMax + physicBonus
set t = null
endmethod
static method create takes unit u returns thistype
local thistype this = allocate()
set .c = Combatant[u]
set physicBonus = 0
call TimerStart(NewTimerEx(this), 3, true, function thistype.onTick)
return this
endmethod
endstruct
struct DarkArts
Combatant c
real amount
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
set c.physicDmgMin = c.physicDmgMin - amount
set c.physicDmgMax = c.physicDmgMax - amount
set amount = (c.physicDmgMin+c.physicDmgMax)/2*DarkArtsPercentage(c.pid)
set c.physicDmgMin = c.physicDmgMin + amount
set c.physicDmgMax = c.physicDmgMax + amount
set t = null
endmethod
static method create takes unit u returns thistype
local thistype this = allocate()
set .c = Combatant[u]
set .amount = 0
call TimerStart(NewTimerEx(this), 3, true, function thistype.onTick)
return this
endmethod
endstruct
struct AeroJabWind
player p
integer count
real x
real y
real z
real a
private static method onTimeout takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local unit u
set .count = .count - 1
set .x = .x + 32 * Cos(.a)
set .y = .y + 32 * Sin(.a)
set u = CreateUnit(.p, 'e018', .x, .y, .a*bj_RADTODEG-90)
static if not LIBRARY_AutoFly then
if UnitAddAbility(u, 'Amrf') and UnitRemoveAbility(u, 'Amrf') then
endif
endif
call PanelCore_SetUnitZ(u, .z+100)
call FadingDecay.create(u, 600, 10)
call Grow.create(u, 0, 15, 0.2)
if (.count <= 0) then
call ReleaseTimer(t)
call deallocate()
endif
set t = null
endmethod
static method create takes player p, real x, real y, real z, real a returns thistype
local thistype this = allocate()
set .p = p
set .x = x
set .y = y
set .z = z
set .a = a
set .count = R2I(AeroJabDistance(GetPlayerId(p))/32.)
call TimerStart(NewTimerEx(this), 0.05, true, function thistype.onTimeout)
return this
endmethod
endstruct
struct DeathBlowRock
Missile missile
real sz
real alpha
static method onRemove takes Missile missile returns boolean
call RemoveUnit(missile.dummy)
return false
endmethod
static method onPeriod takes Missile missile returns boolean
local thistype this = missile.data
set .alpha = .alpha - 15
call SetUnitVertexColor(missile.dummy, 255, 255, 255, R2I(.alpha))
return .alpha <= 0
endmethod
static method onFinish takes Missile missile returns boolean
set missile.speed = 0
return false
endmethod
implement MissileStruct
static method create takes unit whichUnit, real a returns thistype
local thistype this = allocate()
local player p = GetOwningPlayer(whichUnit)
local real x
local real y
local real z = GetUnitFlyHeight(whichUnit)
local real d
local unit m
set d = GetRandomReal(100, 300)
set x = GetUnitX(whichUnit) + d * Cos(a)
set y = GetUnitY(whichUnit) + d * Sin(a)
set m = CreateUnit(p, 'e015', x, y, a * bj_RADTODEG)
call SetUnitScale(m, GetRandomReal(0.15, 0.3), 1, 1)
call SetUnitTimeScale(m, 2)
static if not LIBRARY_AutoFly then
if UnitAddAbility(m, 'Amrf') and UnitRemoveAbility(m, 'Amrf') then
endif
endif
set d = GetRandomReal(300, 600)
set x = x + d * Cos(a)
set y = y + d * Sin(a)
set .missile = Missile.createEx(m, x, y, z)
set .missile.source = whichUnit
set .missile.owner = p
set .missile.speed = GetRandomReal(5, 15)
set .missile.arc = GetRandomReal(45, 75)*bj_DEGTORAD
set .missile.data = this
set .alpha = 500
call launch(.missile)
set m = null
return this
endmethod
endstruct
struct DarknessClawMissile
unit trail
effect trailSfx
effect lightSfx
real dmg
Missile missile
Combatant c
real alpha
static method onRemove takes Missile missile returns boolean
local thistype this = missile.data
call RemoveUnit(missile.dummy)
call DestroyEffect(.trailSfx)
call DestroyEffect(.lightSfx)
call UnitApplyTimedLife(.trail, 'BTLF', 5)
set .trail = null
set .trailSfx = null
return false
endmethod
static method onPeriod takes Missile missile returns boolean
local thistype this = missile.data
set .alpha = .alpha - 35
call SetUnitVertexColor(missile.dummy, 255, 255, 255, R2I(.alpha))
call SetUnitX(.trail, missile.x)
call SetUnitY(.trail, missile.y)
return .alpha <= 0
endmethod
static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = missile.data
local real damage
call missile.hitWidget(hit)
if IsUnitEnemy(hit, missile.owner) and IsUnitAlive(hit) and not Combatant[hit].isInvulnerable then
set damage = CalculateConstantDamage(c, Combatant[hit], missile.damage, true)*.dmg
call Damage(missile.source, hit, damage, true, true, true)
//call DestroyEffectTimed(AddSpecialEffectTarget("war3mapImported\\LascerateNoSound.mdx", hit, "chest"), 1.0)
endif
return false
endmethod
implement MissileStruct
static method create takes unit whichUnit, real x, real y returns thistype
local thistype this = allocate()
local player p = GetOwningPlayer(whichUnit)
local real a = GetUnitFacing(whichUnit)*bj_DEGTORAD
local real z = GetUnitFlyHeight(whichUnit)
local unit m
local PlayerSkill skill = PlayerSkillData[GetPlayerId(p)][17]
set c = Combatant[whichUnit]
set m = CreateUnit(p, 'e01B', x, y, a * bj_RADTODEG)
call SetUnitColor(m, PLAYER_COLOR_PURPLE)
static if not LIBRARY_AutoFly then
if UnitAddAbility(m, 'Amrf') and UnitRemoveAbility(m, 'Amrf') then
endif
endif
call SetUnitFlyHeight(m, z+60, 0)
set x = x + 1500 * Cos(a)
set y = y + 1500 * Sin(a)
set .dmg = DarknessClawPercentage(c.pid)
set .missile = Missile.createEx(m, x, y, z+60)
set .missile.source = whichUnit
set .missile.owner = p
set .missile.speed = 30
set .missile.damage = c.randomPhysicDamage
set .missile.collision = 100
set .missile.data = this
if skill.level >= 5 then
set .alpha = 1140
else
set .alpha = 820
endif
call launch(.missile)
set .trail = CreateUnit(p, 'e000', x, y, a * bj_RADTODEG)
call SetUnitColor(.trail, PLAYER_COLOR_PURPLE)
static if not LIBRARY_AutoFly then
if UnitAddAbility(.trail, 'Amrf') and UnitRemoveAbility(.trail, 'Amrf') then
endif
endif
call SetUnitFlyHeight(.trail, z+10, 0)
set .trailSfx = AddSpecialEffectTarget("war3mapImported\\DarknessClawTrail.mdx", .trail, "origin")
set .lightSfx = AddSpecialEffectTarget("war3mapImported\\LightPurple60.mdx", .trail, "origin")
set m = null
return this
endmethod
endstruct
struct DoubleCrashMissile
Missile missile
Combatant c
real sz
real alpha
real interrupt
boolean factor
real dmg
static method onRemove takes Missile missile returns boolean
call RemoveUnit(missile.dummy)
return false
endmethod
static method onPeriod takes Missile missile returns boolean
local thistype this = missile.data
set .sz = .sz * 1.25
set .alpha = .alpha - 80
call SetUnitVertexColor(missile.dummy, 255, 255, 255, R2I(.alpha))
call SetUnitScale(missile.dummy, .sz, .sz, .sz)
return .alpha <= 0
endmethod
static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = missile.data
local real damage
local real a
call missile.hitWidget(hit)
if IsUnitEnemy(hit, missile.owner) and IsUnitAlive(hit) and not Combatant[hit].isInvulnerable then
set a = Atan2(GetUnitY(hit)-missile.y, GetUnitX(hit)-missile.x)
if RAbsBJ(PanelCore_AngularDifference(missile.angle, a)) < 90*bj_DEGTORAD then
set damage = CalculateConstantDamage(c, Combatant[hit], missile.damage, true)*.dmg
set StealHP = false
set StealSP = false
call Damage(missile.source, hit, damage, true, true, true)
if GetRandomReal(0.000, 1.000) <= .interrupt then
call Combatant[hit].interruption()
endif
//call DestroyEffectTimed(AddSpecialEffectTarget("war3mapImported\\LascerateNoSound.mdx", hit, "chest"), 1.0)
endif
endif
return false
endmethod
implement MissileStruct
static method create takes unit whichUnit returns thistype
local thistype this = allocate()
local player p = GetOwningPlayer(whichUnit)
local real a = GetUnitFacing(whichUnit)*bj_DEGTORAD
local real x
local real y
local real z = GetUnitFlyHeight(whichUnit)
local unit m
set c = Combatant[whichUnit]
set x = GetUnitX(whichUnit)
set y = GetUnitY(whichUnit)
if DoubleCrashAnimDex[c] == 3 then
set m = CreateUnit(p, 'e013', x, y, a * bj_RADTODEG)
else
set m = CreateUnit(p, 'e010', x, y, a * bj_RADTODEG)
endif
call SetUnitColor(m, PLAYER_COLOR_LIGHT_GRAY)
static if not LIBRARY_AutoFly then
if UnitAddAbility(m, 'Amrf') and UnitRemoveAbility(m, 'Amrf') then
endif
endif
call SetUnitFlyHeight(m, z+60, 0)
set x = x + 1500 * Cos(a)
set y = y + 1500 * Sin(a)
set .missile = Missile.createEx(m, x, y, z+60)
set .missile.source = whichUnit
set .missile.owner = p
set .missile.speed = 15
set .missile.damage = c.randomPhysicDamage
set .missile.collision = 150
set .missile.data = this
set .alpha = 270
set .sz = 3
set .interrupt = DoubleCrashInterruption(c.pid)
set .factor = true
if factor then
set .dmg = DoubleCrashDamagePercent(c.pid)
else
set .dmg = CounterAttackDamage(c.pid)
endif
call launch(.missile)
set m = null
return this
endmethod
endstruct
private function DoubleCrashDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
local real f
local real x
local real y
local real dp
local real damage
local unit fog
if IsUnitAlive(c.u) then
call CameraShaker_StartH(c.pid, 10, 0.1)
call DoubleCrashMissile.create(c.u)
call SwingSounds[GetRandomInt(0, 2)].play(GetUnitX(c.u), GetUnitY(c.u), PanelCore_GetUnitZ(c.u), 100)
if DoubleCrashAnimDex[c] == 20 then
set dp = c.dmgPoint*(c.attackRate/c.attackRateDef)/1.5
call SetUnitTimeScale(c.u, c.attackRateDef/c.attackRate*1.5)
set DoubleCrashAnimDex[c] = 24
call SetUnitAnimationByIndex(c.u, DoubleCrashAnimDex[c])
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, c.attackRate/1.5, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, dp, false, function DoubleCrashDamage)
call c.immobilize(0, dp, null)
else
call SetUnitTimeScale(c.u, 1.0)
call TimerStart(c.launchTimer, 0, false, null)
endif
endif
set t = null
endfunction
function DoubleCrashCast takes Combatant c returns nothing
local real dp
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
set dp = c.dmgPoint*(c.attackRate/c.attackRateDef)/1.5
call SetUnitTimeScale(c.u, c.attackRateDef/c.attackRate*1.5)
set DoubleCrashAnimDex[c] = 20
call SetUnitAnimationByIndex(c.u, DoubleCrashAnimDex[c])
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, c.attackRate/1.5, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, dp, false, function DoubleCrashDamage)
call c.immobilize(0, dp, null)
endif
endif
endfunction
private function DarknessClawDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
local real f
local real x
local real y
local real z
local real a
local real dp
local real damage
local unit fog
local PlayerSkill skill
if IsUnitAlive(c.u) then
call CameraShaker_StartV(c.pid, 10, 0.2)
set skill = PlayerSkillData[c.pid][17]
set a = GetUnitFacing(c.u) * bj_DEGTORAD
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
if skill.level >= 15 then
call DarknessClawMissile.create(c.u, x, y)
call DarknessClawMissile.create(c.u, x + 128*Cos(a+PanelCore_HP), y + 128*Sin(a+PanelCore_HP))
call DarknessClawMissile.create(c.u, x + 128*Cos(a-PanelCore_HP), y + 128*Sin(a-PanelCore_HP))
elseif skill.level >= 10 then
call DarknessClawMissile.create(c.u, x + 64*Cos(a+PanelCore_HP), y + 64*Sin(a+PanelCore_HP))
call DarknessClawMissile.create(c.u, x + 64*Cos(a-PanelCore_HP), y + 64*Sin(a-PanelCore_HP))
else
call DarknessClawMissile.create(c.u, x, y)
endif
set z = PanelCore_GetUnitZ(c.u)
call DarknessClaw.play(x, y, z, 180)
call SwingSounds[GetRandomInt(0, 2)].play(x, y, z, 100)
call SetUnitTimeScale(c.u, 1.0)
call TimerStart(c.launchTimer, 0, false, null)
endif
set t = null
endfunction
function DarknessClawCast takes Combatant c returns nothing
local real dp
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
set dp = c.dmgPoint*(c.attackRate/c.attackRateDef)
call SetUnitTimeScale(c.u, c.attackRateDef/c.attackRate)
call SetUnitAnimationByIndex(c.u, 18)
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, c.attackRate, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, dp, false, function DarknessClawDamage)
call c.immobilize(0, dp, null)
endif
endif
endfunction
private function DeathBlowDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
local Combatant c2
local real x
local real y
local real x2
local real y2
local real a
local real damage
local real dmg
local real stun
local real accuracy
local integer i
local integer j
local unit u
local unit fog
if IsUnitAlive(c.u) then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
set a = (GetUnitFacing(c.u)-45)*bj_DEGTORAD
set i = 0
loop
exitwhen i > 8
set x2 = x + 100*Cos(a)
set y2 = y + 100*Sin(a)
set u = CreateUnit(c.owner, 'e014', x2, y2, a * bj_RADTODEG - 45)
call SetUnitScale(u, 0.75, 1, 1)
set FadingDecay.create(u, 750., 5.).remove = false
set j = GetRandomInt(1, 3)
loop
exitwhen j == 0
call DeathBlowRock.create(c.u, a+GetRandomReal(-bj_PI, bj_PI)/4)
set j = j - 1
endloop
set a = a + 45*bj_DEGTORAD
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] and IsUnitInRange(c.u, MainUnit[i], 600) then
call CameraShaker_StartV(i, 20, 1.0)
endif
set i = i + 1
endloop
call SetUnitTimeScale(c.u, 1)
call DestroyEffect(AddSpecialEffect("war3mapImported\\NewDirtEXNofire.mdx", x, y))
call DeathBlow.play(x, y, PanelCore_GetUnitZ(c.u), 150)
set stun = DeathBlowStunDuration(c.pid)
set dmg = DeathBlowDamageAmount(c.pid)
set accuracy = c.accuracy
set c.accuracy = 999
call GroupEnumUnitsInRange(Group, x, y, DeathBlowArea(c.pid), null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, c.owner) and IsUnitAlive(fog) then
set c2 = Combatant[fog]
if not c2.isInvulnerable then
set damage = CalculateConstantDamage(c, c2, dmg, true)
call Damage(c.u, fog, damage, false, false, false)
if c2.hp > 0 then
call Knockback.create(fog, Atan2(GetUnitY(fog)-y, GetUnitX(fog)-x), 200.0, GENERAL_KNOCKBACK_SPEED, true)
call c2.applyStun(1, stun, AddSpecialEffectTarget("Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl", fog, "overhead"))
endif
endif
endif
endloop
set c.accuracy = accuracy
set u = null
endif
set t = null
endfunction
function DeathBlowCast takes Combatant c returns nothing
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
call SetUnitTimeScale(c.u, 1)
call SetUnitAnimationByIndex(c.u, 22)
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, c.attackRate*1.25, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, c.dmgPoint*1.25, false, function DeathBlowDamage)
call c.immobilize(0, c.dmgPoint, null)
call Jump.create(c.u, 50)
call DeathBlowJump.play(GetUnitX(c.u), GetUnitY(c.u), PanelCore_GetUnitZ(c.u), 150)
endif
endif
endfunction
function TauntCast takes Combatant c returns nothing
local real x
local real y
local real amount
local real chance
local unit fog
local Combatant c2
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
call c.disarm(0, 1.5, null)
call c.immobilize(0, 1.5, null)
call SetUnitAnimationByIndex(c.u, 21)
call QueueUnitAnimation(c.u, "stand")
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
set amount = TauntThreatAmount(c.pid)
call DestroyEffectTimed(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\BattleRoar\\RoarCaster.mdl", c.u, "origin"), 3)
call GroupEnumUnitsInRange(Group, x, y, 325, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, c.owner) and IsUnitAlive(fog) then
if GetOwningPlayer(fog) == CREEP_PLAYER then
call CreepAI[fog].damage(c.pid, amount)
set chance = TauntMissChance(c.pid)
if chance > 0 then
set c2 = Combatant[fog]
call Blindness.create(c2, 23, chance)
call c2.applyBuff(23, 5., AddSpecialEffectTarget("war3mapImported\\FearEffect2.mdx", fog, "overhead"))
endif
endif
endif
endloop
endif
endif
endfunction
private function CounterAttackDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
local PlayerSkill skill
call CameraShaker_StartV(c.pid, 10, 0.2)
call CameraShaker_StartH(c.pid, 10, 0.2)
set skill = PlayerSkillData[c.pid][10]
call c.applyBuff(2, 60*skill.level, AddSpecialEffectTarget("war3mapImported\\SpiralAura.mdx", c.u, "origin"))
call ReleaseTimer(t)
set t = null
endfunction
function CounterAttackCast takes Combatant c returns nothing
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isStunned and not c.isAttacking and not c.isSilenced then
call TimerStart(NewTimerEx(c), 1.1, false, function CounterAttackDamage)
call DestroyEffectTimed(AddSpecialEffectTarget("war3mapImported\\Retribution.mdx", c.u, "origin"), 1.0)
call c.disarm(0, 1, null)
call c.immobilize(0, 1, null)
call SetUnitAnimationByIndex(c.u, 2)
call QueueUnitAnimation(c.u, "stand")
endif
endif
endfunction
function HolyShieldCast takes Combatant c returns nothing
local unit fog
local integer pid
local real x
local real y
local real arm
local real marm
local real elm
local real dmg
local real dur
local PlayerSkill skill
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isStunned and not c.isAttacking and not c.isSilenced then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
call DestroyEffect(AddSpecialEffect("war3mapImported\\LionSong.mdx", x, y))
call c.disarm(0, 1, null)
call c.immobilize(0, 1, null)
call StatusBonus.cleanse(c, 3)
call SetUnitAnimationByIndex(c.u, 2)
call QueueUnitAnimation(c.u, "stand")
set skill = PlayerSkillData[c.pid][12]
set arm = HolyShieldPhysicArmor(c.pid)
set dur = HolyShieldDuration(c.pid)
if skill.level >= 15 then
set dmg = HolyShieldDamageBonus(c.pid)
endif
if skill.level >= 10 then
set elm = HolyShieldResistance(c.pid)
endif
if skill.level >= 5 then
set marm = HolyShieldMagicArmor(c.pid)
endif
call GroupEnumUnitsInRange(Group, x, y, 1000, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitAlly(fog, c.owner) and IsUnitAlive(fog) then
set pid = GetPlayerId(GetOwningPlayer(fog))
if (pid < 4) then
call StatusBonus.cleanse(Combatant[fog], 3)
call StatusBonus.create(fog, 1, arm, dur, 3)
if skill.level >= 15 then
call StatusBonus.create(fog, 7, (c.physicDmgMax+c.physicDmgMin)/2 * dmg, dur, 3)
call StatusBonus.create(fog, 8, (c.magicDmgMax+c.magicDmgMin)/2 * dmg, dur, 3)
endif
if skill.level >= 10 then
call StatusBonus.create(fog, 9, elm, dur, 3)
call StatusBonus.create(fog, 10, elm, dur, 3)
call StatusBonus.create(fog, 11, elm, dur, 3)
call StatusBonus.create(fog, 12, elm, dur, 3)
endif
if skill.level >= 5 then
call StatusBonus.create(fog, 4, marm, dur, 3)
endif
call Combatant[fog].applyBuff(3, dur, AddSpecialEffectTarget("war3mapImported\\HolyShield Seal.mdx", fog, "overhead"))
endif
endif
endloop
endif
endif
endfunction
private function AeroJabReset takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
call c.mobilize(0)
call SetUnitTimeScale(c.u, 1)
set t = null
endfunction
private function AeroJabDealDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
local Combatant c2
local real x
local real y
local real damage
local real dist
local real dmg
local real pctg
local unit fog
local AngledRect rct
set dist = AeroJabDistance(c.pid)
set dmg = c.randomPhysicDamage
set pctg = AeroJabDamageAmount(c.pid)
set x = GetUnitX(c.u) + dist/2. * Cos(AeroJabDirection[c])
set y = GetUnitY(c.u) + dist/2. * Sin(AeroJabDirection[c])
set rct = AngledRect.create(x, y, 300, dist, AeroJabDirection[c]*bj_RADTODEG)
call ReleaseTimer(t)
call rct.enum(Group, Filter(function FilterOutUI))
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, c.owner) and IsUnitAlive(fog) then
set c2 = Combatant[fog]
if not c2.isInvulnerable then
set damage = CalculateConstantDamage(c, c2, dmg, true)*pctg
call Damage(c.u, fog, damage, false, false, true)
/*if c2.hp > 0 then
call Knockback.create(fog, AeroJabDirection[c], 320.0, GENERAL_KNOCKBACK_SPEED, true)
endif*/
endif
endif
endloop
call rct.destroy()
set t = null
endfunction
private function AeroJabDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
local real x
local real y
local unit u
local real dist
call CameraShaker_StartH(c.pid, 10, 0.5)
call CameraShaker_StartV(c.pid, 10, 0.5)
set dist = AeroJabDistance(c.pid)
set u = CreateUnit(c.owner, 'e000', GetUnitX(c.u), GetUnitY(c.u), AeroJabDirection[c]*bj_RADTODEG)
call DestroyEffect(AddSpecialEffectTarget(AeroJabVFX(c.pid), u, "origin"))
call UnitApplyTimedLife(u, 'BTLF', 5)
/*set x = GetUnitX(c.u) + dist * Cos(AeroJabDirection[c])
set y = GetUnitY(c.u) + dist * Sin(AeroJabDirection[c])
set u = CreateUnit(c.owner, 'e019', x, y, AeroJabDirection[c]*bj_RADTODEG-90)
static if not LIBRARY_AutoFly then
if UnitAddAbility(u, 'Amrf') and UnitRemoveAbility(u, 'Amrf') then
endif
endif
call SetUnitScale(u, dist/1600., 1, 1)
call PanelCore_SetUnitZ(u, PanelCore_GetUnitZ(c.u)+100)
call UnitApplyTimedLife(u, 'BTLF', 5)*/
call TimerStart(c.launchTimer, 0.25, false, function AeroJabReset)
call TimerStart(NewTimerEx(c), 0.1, false, function AeroJabDealDamage)
set u = null
set t = null
endfunction
function AeroJabCast takes Combatant c, real a returns nothing
local real x
local real y
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
set AeroJabDirection[c] = a
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
call SetUnitTimeScale(c.u, 1)
call SetUnitAnimationByIndex(c.u, 17)
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, c.attackRate*1.25, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, 0.25, false, function AeroJabDamage)
call c.immobilize(0, 3600, null)
//call AeroJab.play(x, y, PanelCore_GetUnitZ(c.u), 150)
//call AeroJabWind.create(c.owner, x, y, PanelCore_GetUnitZ(c.u), AeroJabDirection[c])
endif
endif
endfunction
function ForceBarrierCast takes Combatant c returns nothing
local unit fog
local integer pid
local real x
local real y
local real amount
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isStunned and not c.isAttacking and not c.isSilenced then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
call DestroyEffect(AddSpecialEffect("war3mapImported\\Encourage.mdx", x, y))
call c.disarm(0, 1.5, null)
call c.immobilize(0, 1.5, null)
call SetUnitAnimationByIndex(c.u, 27)
call QueueUnitAnimation(c.u, "stand")
set amount = ForceBarrierAmount(c.pid)
call GroupEnumUnitsInRange(Group, x, y, 1000, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitAlly(fog, c.owner) and IsUnitAlive(fog) then
set pid = GetPlayerId(GetOwningPlayer(fog))
if pid < 4 then
if fog == c.u then
call DamageBlock.create(fog, amount, 60, 4)
call Combatant[fog].applyBuff(4, 60, AddSpecialEffectTarget("war3mapImported\\SacredShield.mdx", fog, "origin"))
else
call DamageBlock.create(fog, amount/2, 60, 4)
call Combatant[fog].applyBuff(4, 60, AddSpecialEffectTarget("war3mapImported\\SacredShield.mdx", fog, "origin"))
endif
endif
endif
endloop
endif
endif
endfunction
function RapidAttackCast takes Combatant c returns nothing
local real x
local real y
local real dur
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isStunned and not c.isAttacking and not c.isSilenced then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\PeterifyVer.2.mdx", c.u, "chest"))
call c.disarm(0, 1, null)
call c.immobilize(0, 1, null)
call SetUnitAnimationByIndex(c.u, 2)
call QueueUnitAnimation(c.u, "stand")
set dur = RapidAttackSpeedDuration(c.pid)
call StatusBonus.cleanse(c, 7)
call StatusBonus.create(c.u, 2, RapidAttackSpeedBonus(c.pid), dur, 7)
call c.applyBuff(7, dur, AddSpecialEffectTarget("war3mapImported\\CircleOutBuff.mdx", c.u, "origin"))
endif
endif
endfunction
function SolidifyCast takes Combatant c returns nothing
local real x
local real y
local real reflect
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isStunned and not c.isAttacking and not c.isSilenced then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\BlinkCaster.mdx", c.u, "hand right"))
call c.disarm(0, 1, null)
call c.immobilize(0, 1, null)
call SetUnitAnimationByIndex(c.u, 2)
call QueueUnitAnimation(c.u, "stand")
call StatusBonus.cleanse(c, 8)
call ReflectMissile.cleanse(c, 8)
call StatusBonus.create(c.u, 1, SolidifyPhysicArmor(c.pid), 60, 8)
call StatusBonus.create(c.u, 3, SolidifyBlockBonus(c.pid), 60, 8)
set reflect = SolidifyReflectChance(c.pid)
if reflect > 0 then
call ReflectMissile.create(c, 8, reflect, SolidifyReflectDamage(c.pid))
endif
call c.applyBuff(8, 60, AddSpecialEffectTarget("war3mapImported\\MegaShield2.mdx", c.u, "hand right"))
endif
endif
endfunction
function DreadfulHowlCast takes Combatant c returns nothing
local Combatant c2
local unit fog
local integer pid
local real x
local real y
local real physic
local real magic
local real acc
local real dur
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isStunned and not c.isAttacking and not c.isSilenced then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
call DestroyEffect(AddSpecialEffect("war3mapImported\\CallOfAggression.mdx", x, y))
call c.disarm(0, 1, null)
call c.immobilize(0, 1, null)
call StatusBonus.cleanse(c, 11)
call SetUnitAnimationByIndex(c.u, 21)
call QueueUnitAnimation(c.u, "stand")
set physic = -DreadfulHowlPhysicArmorReduction(c.pid)
set magic = -DreadfulHowlMagicArmorReduction(c.pid)
set acc = -DreadfulHowlAccuracyReduction(c.pid)
set dur = DreadfulHowlDuration(c.pid)
call GroupEnumUnitsInRange(Group, x, y, 600, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, c.owner) and IsUnitAlive(fog) then
set c2 = Combatant[fog]
if c2.attackRateDef > 0 then
call StatusBonus.cleanse(c2, 11)
call StatusBonus.create(fog, 1, physic, dur, 11)
call StatusBonus.create(fog, 4, magic, dur, 11)
call StatusBonus.create(fog, 5, acc, dur, 11)
call c2.applyBuff(11, dur, AddSpecialEffectTarget("war3mapImported\\EmpathicBond.mdx", fog, "chest"))
endif
endif
endloop
endif
endif
endfunction
function SpectraVortexCast takes Combatant c returns nothing
local real x
local real y
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isStunned and not c.isAttacking and not c.isSilenced then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
//call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\HowlOfTerror\\HowlCaster.mdl", x, y))
call c.disarm(0, 1, null)
call c.immobilize(0, 1, null)
call SetUnitAnimationByIndex(c.u, 2)
call QueueUnitAnimation(c.u, "stand")
call SpectraVortex.create(c)
endif
endif
endfunction
function NightmareFallCast takes Combatant c returns nothing
local real x
local real y
local integer i
local real r
local integer ct
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isStunned and not c.isAttacking and not c.isSilenced then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
call NightmareFallCastSfx.play(x, y, PanelCore_GetUnitZ(c.u), 180)
call DestroyEffect(AddSpecialEffect("war3mapImported\\DarkChakraExplosion.mdx", x, y))
call DestroyEffect(AddSpecialEffect("war3mapImported\\DarkChakraExplosion.mdx", x, y))
call DestroyEffect(AddSpecialEffect("war3mapImported\\DarkChakraExplosion.mdx", x, y))
call c.disarm(0, 1, null)
call c.immobilize(0, 1, null)
call SetUnitAnimationByIndex(c.u, 2)
call QueueUnitAnimation(c.u, "stand")
set ct = NightmareFallPillarCount(c.pid)
set i = 0
set r = PanelCore_TAU / ct
loop
exitwhen i == ct
call NightmareFallPillar.create(c, i * r)
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] and IsUnitInRange(c.u, MainUnit[i], 500) then
call CameraShaker_StartH(i, 20, 1.0)
call CameraShaker_StartV(i, 20, 1.0)
endif
set i = i + 1
endloop
endif
endif
endfunction
function VampiricGroanCast takes Combatant c returns nothing
local real x
local real y
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isStunned and not c.isAttacking and not c.isSilenced then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\Arcane Explosion.mdx", c.u, "overhead"))
call SetUnitAnimation(c.u, "victory")
call QueueUnitAnimation(c.u, "stand")
call c.immobilize(0, 1, null)
call c.disarm(0, 1, null)
call VampiricGroan.create(c)
endif
endif
endfunction
private function ValiantChargeDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
if IsUnitAlive(c.u) then
if not c.isStunned then
call ValiantCharge.start(c)
endif
endif
set t = null
endfunction
function ValiantChargeCast takes Combatant c returns nothing
local real x
local real y
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
call SetUnitTimeScale(c.u, 1.0)
call SetUnitAnimationByIndex(c.u, 6)
call TimerStart(c.attackTimer, 3600, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, 0.5, false, function ValiantChargeDamage)
call c.immobilize(0, 3600, null)
endif
endif
endfunction
//! endtextmacro
endlibrary
library ArcherSkills uses BUSChannel
//! textmacro SkillLib2
globals
integer array TranquilizerHitCount
integer array QuickShotCount
unit array LucidBeamRay
timer array LucidBeamTimer
effect array LucidBeamRaySfx
AngledRect array LucidBeamHitBox
real array LucidBeamDelay
real array LucidBeamMasteryDelay
real array LucidBeamDamage
real array LucidBeamMaxDistance
real array LucidBeamRectDistance
real array LucidBeamManacost
effect array LucidBeamLight
integer array LucidBeamLevel
real array ViciousHailX
real array ViciousHailY
private group TempGroup = CreateGroup()
endglobals
struct Afterimage extends array
static boolean array Registered
static real array Chance
static real array Damage
static method unregister takes Combatant c returns nothing
set Registered[c] = false
endmethod
static method register takes Combatant c, integer pid returns nothing
set Registered[c] = true
set Chance[c] = AfterimageChance(pid)
set Damage[c] = AfterimageDamage(pid)
endmethod
endstruct
private struct SnareTrap
Combatant c
unit net
group captured
integer level
boolean capture
boolean sprung // true means it's not a trap anymore
real targetX
real targetY
real lifespan // Lifespan of both net and trap
real delay // Delay for the trap to sprung
real aoe
real duration
real accuracy
real slow
static unit DummyCaster
static timer CheckerTimer = CreateTimer()
static group TargetGroup = CreateGroup() // Group containing units affected by the spells buff
static group AffectedGroup = CreateGroup() // Group containing any units iterated by the spell
static group RecycleGroup = CreateGroup() // For recycling purpose
static group TempGroup = CreateGroup()
static group TempGroup2
static method check takes nothing returns nothing
local unit fog
loop
set fog = FirstOfGroup(TargetGroup)
exitwhen (fog == null)
call GroupRemoveUnit(TargetGroup, fog)
// Remove buff if a unit is still in target group (has the spell buff)
// but not iterated by the spell at all. Means the unit is nowhere around
// any net
if (not IsUnitAlive(fog) or not IsUnitInGroup(fog, AffectedGroup)) then
call Combatant[fog].removeBuff(21)
else
// Return the unit to the new target group if still snared
call GroupAddUnit(RecycleGroup, fog)
endif
endloop
// Recycle group
set TempGroup2 = TargetGroup
set TargetGroup = RecycleGroup
set RecycleGroup = TempGroup2
call GroupClear(AffectedGroup)
// Reset and pause the checker timer if there's no affected unit's left
if (FirstOfGroup(TargetGroup) == null) then
call PauseTimer(CheckerTimer)
endif
endmethod
static method onPeriodic takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local Combatant c2
local unit fog
local real a
local real x
local real y
if (.lifespan > 0.03125) then
if (.sprung) then
if (.delay == 0) then
set .lifespan = .lifespan - 0.03125
call GroupEnumUnitsInRange(TempGroup, .targetX, .targetY, .aoe, null)
loop
set fog = FirstOfGroup(TempGroup)
exitwhen (fog == null)
call GroupRemoveUnit(TempGroup, fog)
// If target is classified
if (IsUnitAlive(fog) and IsUnitEnemy(fog, .c.owner) and GetUnitAbilityLevel(fog, 'Amov') > 0) then
if (not IsUnitInGroup(fog, TargetGroup)) then
set c2 = Combatant[fog]
call StatusBonus.cleanse(c2, 24)
call StatusBonus.create(fog, 6, -GetUnitMoveSpeed(c2.u)*.slow, 0, 21)
if .level >= 15 then
if not c2.melee then
call c2.disarm(21, 5, null)
call c2.silence(21, 5, null)
endif
elseif .level >= 5 then
call StatusBonus.create(fog, 5, -.accuracy, 0, 21)
endif
call c2.applyBuff(21, 0, null)
if (.capture) then
call GroupAddUnit(.captured, fog)
endif
// Make sure the target has the buffs
if (c2.hasBuff(21)) then
if (FirstOfGroup(TargetGroup) == null) then
// Start the timer to check that affected units are still snared (within AoE)
call TimerStart(CheckerTimer, 0.03125, true, function thistype.check)
endif
call GroupAddUnit(TargetGroup, fog)
endif
endif
call GroupAddUnit(AffectedGroup, fog)
endif
endloop
set .capture = false
if (FirstOfGroup(.captured) != null) then
loop
set fog = FirstOfGroup(.captured)
exitwhen (fog == null)
call GroupRemoveUnit(.captured, fog)
// Prevent unit to be removed when outside the rope area
call GroupAddUnit(AffectedGroup, fog)
call GroupAddUnit(RecycleGroup, fog)
set x = GetUnitX(fog)
set y = GetUnitY(fog)
// Prevent captured unit from leaving
if ((.targetX-x)*(.targetX-x)+(.targetY-y)*(.targetY-y) > .aoe*.aoe) then
call IssueImmediateOrderById(fog, ORDER_stop)
set a = Atan2(y-.targetY, x-.targetX)
call SetUnitX(fog, .targetX+.aoe*Cos(a))
call SetUnitY(fog, .targetY+.aoe*Sin(a))
endif
endloop
// Recycle group
set TempGroup2 = .captured
set .captured = RecycleGroup
set RecycleGroup = TempGroup2
endif
else
// Springing trap
set .delay = .delay - 0.03125
if (.delay <= 0) then
call RemoveUnit(.net)
call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl", .targetX, .targetY))
set .net = CreateUnit(.c.owner, 'h023', .targetX, .targetY, 0)
call SetUnitAnimation(.net, "birth")
call QueueUnitAnimation(.net, "stand")
set .lifespan = .duration
set .delay = 0
endif
endif
else
set .lifespan = .lifespan - 0.03125
// Check if there is any target unit passing by the trap
call GroupEnumUnitsInRange(TempGroup, .targetX, .targetY, .aoe, null)
loop
set fog = FirstOfGroup(TempGroup)
exitwhen (fog == null)
call GroupRemoveUnit(TempGroup, fog)
if (IsUnitAlive(fog) and IsUnitEnemy(fog, c.owner) and GetUnitAbilityLevel(fog, 'Amov') > 0) then
set .sprung = true
exitwhen true
endif
endloop
if (fog != null) then
call GroupClear(TempGroup)
set fog = null
endif
endif
else
// Dispose the spell instance
call DestroyGroup(.captured)
call KillUnit(.net)
call ReleaseTimer(t)
call deallocate()
set .captured = null
set .net = null
endif
set t = null
endmethod
static method onRemove takes Missile missile returns boolean
local thistype this = missile.data
// Hoping the missile library handles world bounds correctly yeah I'm lazy so what?
set .targetX = missile.x
set .targetY = missile.y
// Check whether the missile should be a trap or a net
if (.sprung) then
set .net = CreateUnit(.c.owner, 'h023', .targetX, .targetY, 0)
call SetUnitAnimation(.net, "birth")
call QueueUnitAnimation(.net, "stand")
else
set .net = CreateUnit(.c.owner, 'h024', .targetX, .targetY, 0)
static if APPLY_EXP_TIMER then
call UnitApplyTimedLife(.net, 'BTLF', .lifespan)
endif
endif
call TimerStart(NewTimerEx(this), 0.03125, true, function thistype.onPeriodic)
return true
endmethod
implement MissileStruct
static method cast takes Combatant c, real x, real y returns nothing
local Missile missile
local thistype this
local unit fog
local real angle
local real x2
local real y2
set this = allocate()
set .c = c
set .targetX = x
set .targetY = y
set .captured = CreateGroup()
set .capture = true
set .sprung = false
set .duration = SnareTrapNetDuration(c.pid)
set .slow = SnareTrapMovespeedReduction(c.pid)
set .accuracy = SnareTrapAccuracyReduction(c.pid)
// Initialize the missile
set x2 = GetUnitX(c.u)
set y2 = GetUnitY(c.u)
set angle = Atan2(.targetY-y2, .targetX-x2)
set missile = Missile.createXYZ(x2+16*Cos(angle), y2+16*Sin(angle), 64+GetUnitFlyHeight(c.u), .targetX, .targetY, 0)
set missile.arc = 0.15
set missile.data = this
set .level = PlayerSkillData[.c.pid][28].level
set .aoe = 200
// Check if there's target units around the target area
call GroupEnumUnitsInRange(TempGroup, .targetX, .targetY, .aoe, null)
loop
set fog = FirstOfGroup(TempGroup)
exitwhen (fog == null)
call GroupRemoveUnit(TempGroup, fog)
if (IsUnitAlive(fog) and IsUnitEnemy(fog, c.owner) and GetUnitAbilityLevel(fog, 'Amov') > 0) then
set .sprung = true
exitwhen true
endif
endloop
if (fog != null) then
call GroupClear(TempGroup)
set fog = null
endif
// If a target is detected, throw a net, else, a trap
if (.sprung) then
set missile.speed = 15
set missile.model = "Abilities\\Spells\\Orc\\Ensnare\\EnsnareMissile.mdl"
set missile.scale = 1.5
set .lifespan = .duration
set .delay = 0
else
set missile.speed = 30
set missile.model = "war3mapImported\\Swashbuckler_SnareTrap_Projectile.MDX"
set missile.scale = 1
set .lifespan = SnareTrapTrapDuration(c.pid)
set .delay = 1
endif
call launch(missile)
endmethod
endstruct
struct ViciousHailMissile
ViciousHail parent
unit dummy
real hVel
real zVel
real hAcc
real zAcc
real x
real y
real z
real cosA
real sinA
static constant real PITCH = 80*bj_DEGTORAD
static constant real TIME = 3
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
set .x = .x + .hVel * .cosA
set .y = .y + .hVel * .sinA
set .z = .z - .zVel
set .hVel = .hVel + .hAcc
set .zVel = .zVel + .zAcc
if .z > 0 then
call SetUnitX(.dummy, .x)
call SetUnitY(.dummy, .y)
call SetUnitFlyHeight(.dummy, .z, 0)
else
call .parent.damage()
call ViciousHailSfx[GetRandomInt(0, 2)].play(.x, .y, PanelCore_GetUnitZ(.dummy), 50)
call DestroyEffectTimed(AddSpecialEffect("war3mapImported\\ViciousHailTarget.mdx", .x, .y), 1)
call RemoveUnit(.dummy)
call ReleaseTimer(t)
call deallocate()
set .dummy = null
endif
set t = null
endmethod
static method create takes ViciousHail parent, player p, real x, real y, real z, real a returns thistype
local thistype this = allocate()
local real pitch = PanelCore_HP - PITCH
local real d = z / Cos(pitch)
local real hd = d * Sin(pitch)
set .parent = parent
set .cosA = Cos(a)
set .sinA = Sin(a)
set .x = x - hd * .cosA
set .y = y - hd * .sinA
set .z = z
set .hVel = 0
set .zVel = 0
set .hAcc = hd / (0.5 * (TIME * TIME)) * 0.03125
set .zAcc = z / (0.5 * (TIME * TIME)) * 0.03125
set .dummy = CreateUnit(p, 'e01P', x, y, a * bj_RADTODEG)
static if not LIBRARY_AutoFly then
if UnitAddAbility(.dummy, 'Amrf') and UnitRemoveAbility(.dummy, 'Amrf') then
endif
endif
call SetUnitX(.dummy, .x)
call SetUnitY(.dummy, .y)
call SetUnitFlyHeight(.dummy, .z, 0)
call TimerStart(NewTimerEx(this), 0.03125, true, function thistype.onTick)
return this
endmethod
endstruct
struct ViciousHail
Combatant c
real duration
real targX
real targY
real targA
real delay
timer time
integer count
integer level
effect lightSfx
real aoe
real dps
real slow
real armor
static constant integer MIN_SPAWN = 1
static constant integer MAX_SPAWN = 2
static constant real INTERVAL = 0.07
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local integer ct = GetRandomInt(MIN_SPAWN, MAX_SPAWN)
local real d
local real a
if .delay > 0 then
set .delay = .delay - INTERVAL
endif
if .duration > 0 then
set .duration = .duration - INTERVAL
loop
exitwhen ct <= 0
set d = GetRandomReal(0, .aoe)
set a = GetRandomReal(-bj_PI, bj_PI)
set .count = .count + 1
call ViciousHailMissile.create(this, c.owner, .targX + d * Cos(a), .targY + d * Sin(a), 800, .targA)
set ct = ct - 1
endloop
endif
set t = null
endmethod
method damage takes nothing returns nothing
local unit fog
local Combatant c2
local real amount
local integer i
set .count = .count - 1
if .count <= 0 then
call DestroyEffect(.lightSfx)
call ReleaseTimer(.time)
call deallocate()
set .lightSfx = null
set .time = null
endif
if .delay <= 0 then
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] and IsUnitInRangeXY(MainUnit[i], targX, targY, 500) then
call CameraShaker_StartH(i, 5, 1.0)
call CameraShaker_StartV(i, 5, 1.0)
endif
set i = i + 1
endloop
set .delay = 0.5
call GroupEnumUnitsInRange(Group, targX, targY, .aoe, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, c.owner) and IsUnitAlive(fog) then
set c2 = Combatant[fog]
if not c2.isInvulnerable then
set amount = CalculateConstantDamage(c, c2, .dps, true)*0.5
call Damage(c.u, fog, amount, false, false, false)
call StatusBonus.cleanse(c2, 24)
if .level >= 15 then
call StatusBonus.create(fog, 1, -.armor, 0, 24)
elseif .level >= 5 then
call StatusBonus.create(fog, 6, -GetUnitMoveSpeed(fog)*.slow, 0, 24)
endif
call c2.applyBuff(24, 3.0, null)
endif
endif
endloop
endif
endmethod
static method create takes unit u, real x, real y returns thistype
local thistype this = allocate()
local PlayerSkill skill
set .c = Combatant[u]
set skill = PlayerSkillData[c.pid][29]
set .count = 0
set .delay = 0
set .duration = 3
set .targX = x
set .targY = y
set .targA = Atan2(y-GetUnitY(u), x-GetUnitX(u))
set .time = NewTimerEx(this)
set .level = skill.level
set .aoe = FericiousHailRadius(c.pid)
set .dps = FericiousHailDamage(c.pid)
set .slow = FericiousHailSlow(c.pid)
set .armor = FericiousHailPhysicArmor(c.pid)
set .lightSfx = AddSpecialEffect("war3mapImported\\LightGreen60.mdx", x, y)
call TimerStart(.time, INTERVAL, true, function thistype.onTick)
return this
endmethod
endstruct
struct QuickShotMissile
effect light
real percent
Missile missile
Combatant c
static method onRemove takes Missile missile returns boolean
local thistype this = missile.data
call DestroyEffect(.light)
set .light = null
return true
endmethod
static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = missile.data
local real damage
call missile.hitWidget(hit)
if IsUnitEnemy(hit, missile.owner) and IsUnitAlive(hit) and not Combatant[hit].isInvulnerable then
set damage = CalculateConstantDamage(c, Combatant[hit], missile.damage, true)*.percent
call Damage(missile.source, hit, damage, false, true, true)
return true
endif
return false
endmethod
implement MissileStruct
static method create takes unit whichUnit returns thistype
local thistype this = allocate()
local player p = GetOwningPlayer(whichUnit)
local real a = GetUnitFacing(whichUnit)*bj_DEGTORAD
local real x
local real y
local real z = GetUnitFlyHeight(whichUnit)
local unit m
set c = Combatant[whichUnit]
set x = GetUnitX(whichUnit)
set y = GetUnitY(whichUnit)
set m = CreateUnit(p, 'e000', x, y, a * bj_RADTODEG)
static if not LIBRARY_AutoFly then
if UnitAddAbility(m, 'Amrf') and UnitRemoveAbility(m, 'Amrf') then
endif
endif
call SetUnitFlyHeight(m, z+60, 0)
set x = x + (c.attackRange+50) * Cos(a)
set y = y + (c.attackRange+50) * Sin(a)
set .percent = QuickShotDamagePercent(c.pid)
set .missile = Missile.createEx(m, x, y, z+60)
set .missile.source = whichUnit
set .missile.owner = p
set .missile.speed = 50
set .missile.model = "war3mapImported\\BlueArrow.mdx"
set .missile.damage = c.randomPhysicDamage
set .missile.collision = 70
set .missile.scale = 0.5
set .missile.data = this
set .light = AddSpecialEffectTarget("war3mapImported\\LightLtBlue30.mdx", m, "origin")
call launch(.missile)
set m = null
return this
endmethod
endstruct
struct LunarStrikeMissile
real illusion
effect trail
effect trail2
effect light
Missile missile
Combatant c
static method onRemove takes Missile missile returns boolean
local thistype this = missile.data
call DestroyEffect(.trail)
call DestroyEffect(.trail2)
call DestroyEffect(.light)
set .light = null
set .trail = null
set .trail2 = null
return true
endmethod
static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = missile.data
local real damage
local Combatant c2
local Combatant ill
local CompanionAI cai
local HumanoidAI hai
call missile.hitWidget(hit)
if IsUnitEnemy(hit, missile.owner) and IsUnitAlive(hit) and not Combatant[hit].isInvulnerable then
set c2 = Combatant[hit]
if .illusion > 0. and not c2.isIllusion and GetUnitAbilityLevel(hit, 'Amov') > 0 and GetRandomReal(0.000, 1.000) <= .illusion then
set ill = Illusion.copy(c2, c.owner, 0.5, 2.0-EmbodimentDamageTakenBonus(c.pid))
if c2.owner == CREEP_PLAYER then
set cai = CompanionAI.create(c, ill)
set cai.id = 45
set cai.sfx = "war3mapImported\\BlinkCaster.mdx"
else
set hai = HumanoidAI.create(c, ill)
set hai.id = 45
set hai.sfx = "war3mapImported\\BlinkCaster.mdx"
endif
call UnitApplyTimedLife(ill.u, 'BTLF', 15.0+EmbodimentLifespanBonus(c.pid))
call GroupAddUnit(PlayerUnits, ill.u)
call SetUnitVertexColor(ill.u, 0, 75, 255, 255)
endif
set damage = CalculateConstantDamage(c, c2, missile.damage, true)
call Damage(missile.source, hit, damage, false, true, true)
endif
return false
endmethod
implement MissileStruct
static method create takes unit whichUnit returns thistype
local thistype this = allocate()
local player p = GetOwningPlayer(whichUnit)
local real a = GetUnitFacing(whichUnit)*bj_DEGTORAD
local real x
local real y
local real z = GetUnitFlyHeight(whichUnit)
local unit m
set c = Combatant[whichUnit]
set x = GetUnitX(whichUnit)
set y = GetUnitY(whichUnit)
set m = CreateUnit(p, 'e000', x, y, a * bj_RADTODEG)
set .trail = AddSpecialEffectTarget("war3mapImported\\Lunar Strike Trail.mdx", m, "origin")
set .trail2 = AddSpecialEffectTarget("war3mapImported\\Lunar Strike Trail.mdx", m, "origin")
set .light = AddSpecialEffectTarget("war3mapImported\\LightLtBlue60.mdx", m, "origin")
static if not LIBRARY_AutoFly then
if UnitAddAbility(m, 'Amrf') and UnitRemoveAbility(m, 'Amrf') then
endif
endif
call SetUnitFlyHeight(m, z+60, 0)
set x = x + (c.attackRange+200) * Cos(a)
set y = y + (c.attackRange+200) * Sin(a)
set .illusion = LunarStrikeIllusionChance(c.pid)
set .missile = Missile.createEx(m, x, y, z+60)
set .missile.source = whichUnit
set .missile.owner = p
set .missile.speed = 50
set .missile.model = "war3mapImported\\RuneSpear.mdx"
set .missile.damage = LunarStrikeDamage(c.pid)
set .missile.collision = 100
set .missile.data = this
call launch(.missile)
set m = null
return this
endmethod
endstruct
struct PrimalStrikeMissile
effect trail
effect trail2
effect light
real lastEffect
real kb
real dmg
Missile missile
Combatant c
static method createShockwave takes Missile missile returns nothing
local unit u = CreateUnit(missile.owner, 'e000', missile.x, missile.y, missile.angle*bj_RADTODEG)
static if not LIBRARY_AutoFly then
if UnitAddAbility(u, 'Amrf') and UnitRemoveAbility(u, 'Amrf') then
endif
endif
call PanelCore_SetUnitZ(u, missile.z)
call SetUnitScale(u, 0.5, 0.5, 0.5)
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\dash sfx.mdx", u, "origin"))
call UnitApplyTimedLife(u, 'BTLF', 5)
set u = null
endmethod
static method onRemove takes Missile missile returns boolean
local thistype this = missile.data
call DestroyEffect(.trail)
call DestroyEffect(.trail2)
call DestroyEffect(.light)
call createShockwave(missile)
set .light = null
set .trail = null
set .trail2 = null
return true
endmethod
static method onPeriod takes Missile missile returns boolean
local thistype this = missile.data
if missile.distance > .lastEffect then
set .lastEffect = .lastEffect + 128
call createShockwave(missile)
endif
return false
endmethod
static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = missile.data
local real damage
local Combatant c2 = Combatant[hit]
call missile.hitWidget(hit)
if IsUnitEnemy(hit, missile.owner) and IsUnitAlive(hit) and not c2.isInvulnerable then
call CameraShaker_StartH(c2.pid, 10, 0.2)
call CameraShaker_StartV(c2.pid, 10, 0.2)
set damage = CalculateConstantDamage(c, c2, missile.damage, true)*.dmg
call Damage(missile.source, hit, damage, false, true, true)
if .kb > 0 and c2.hp > 0 then
call Knockback.create(hit, missile.angle, .kb, GENERAL_KNOCKBACK_SPEED, true)
endif
return true
endif
return false
endmethod
implement MissileStruct
static method create takes unit whichUnit returns thistype
local thistype this = allocate()
local player p = GetOwningPlayer(whichUnit)
local real a = GetUnitFacing(whichUnit)*bj_DEGTORAD
local real x
local real y
local real z = GetUnitFlyHeight(whichUnit)
local real dist
local unit m
local PlayerSkill skill
set c = Combatant[whichUnit]
set skill = PlayerSkillData[c.pid][37]
set x = GetUnitX(whichUnit)
set y = GetUnitY(whichUnit)
set m = CreateUnit(p, 'e000', x, y, a * bj_RADTODEG)
set .trail = AddSpecialEffectTarget("war3mapImported\\Primal Strike Trail.mdx", m, "origin")
set .trail2 = AddSpecialEffectTarget("war3mapImported\\Primal Strike Trail.mdx", m, "origin")
set .light = AddSpecialEffectTarget("war3mapImported\\LightWhite60.mdx", m, "origin")
static if not LIBRARY_AutoFly then
if UnitAddAbility(m, 'Amrf') and UnitRemoveAbility(m, 'Amrf') then
endif
endif
call SetUnitFlyHeight(m, z+60, 0)
set dist = c.attackRange + PrimalStrikeDistanceBonus(c.pid)
set x = x + dist * Cos(a)
set y = y + dist * Sin(a)
set .dmg = PrimalStrikeDamageAmount(c.pid)
set .missile = Missile.createEx(m, x, y, z+60)
set .missile.source = whichUnit
set .missile.owner = p
set .missile.speed = 70
set .missile.model = "war3mapImported\\FrostArrowAzulFlakeless.mdx"
set .missile.damage = c.randomPhysicDamage
set .missile.collision = 70
set .missile.data = this
set .lastEffect = 0
if skill.level >= 5 then
set .kb = PrimalStrikeKnockback(c.pid)
endif
call launch(.missile)
set m = null
return this
endmethod
endstruct
struct TripleShardMissile
effect array light[4]
Missile missile
Combatant c
group hitGroup
static method onRemove takes Missile missile returns boolean
local thistype this = missile.data
local integer i = 0
call DestroyGroup(.hitGroup)
loop
exitwhen i > 3
call DestroyEffect(.light[i])
set .light[i] = null
set i = i + 1
endloop
set .hitGroup = null
return true
endmethod
static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = missile.data
local real damage
call missile.hitWidget(hit)
if IsUnitEnemy(hit, missile.owner) and IsUnitAlive(hit) and not IsUnitInGroup(hit, .hitGroup) and not Combatant[hit].isInvulnerable then
call GroupAddUnit(.hitGroup, hit)
set damage = CalculateConstantDamage(c, Combatant[hit], missile.damage, true)
call Damage(missile.source, hit, damage, false, true, true)
endif
return false
endmethod
implement MissileStruct
static method create takes unit whichUnit returns thistype
local thistype this = allocate()
local player p = GetOwningPlayer(whichUnit)
local real a2
local real a
local real x
local real y
local real z = GetUnitFlyHeight(whichUnit)
local real dist
local unit m
local integer i = 0
local integer ct
set c = Combatant[whichUnit]
set ct = TripleShardCount(c.pid)
set a2 = GetUnitFacing(whichUnit) - 15.*I2R(ct-1)/2.
set dist = c.attackRange+TripleShardDistance(c.pid)
loop
exitwhen i >= ct
set a = (a2 + 15. * i)*bj_DEGTORAD
set x = GetUnitX(whichUnit)
set y = GetUnitY(whichUnit)
set m = CreateUnit(p, 'e000', x, y, a * bj_RADTODEG)
static if not LIBRARY_AutoFly then
if UnitAddAbility(m, 'Amrf') and UnitRemoveAbility(m, 'Amrf') then
endif
endif
set .light[i] = AddSpecialEffectTarget("war3mapImported\\LightLtBlue30.mdx", m, "origin")
call SetUnitFlyHeight(m, z+60, 0)
set x = x + dist * Cos(a)
set y = y + dist * Sin(a)
set .missile = Missile.createEx(m, x, y, z+60)
set .missile.source = whichUnit
set .missile.owner = p
set .missile.speed = c.missileSpeed
set .missile.model = "war3mapImported\\SpiritArrow_ByEpsilon.mdx"
set .missile.damage = TripleShardDamage(c.pid)
set .missile.collision = c.missileCollision
set .missile.data = this
call launch(.missile)
set i = i + 1
endloop
set .hitGroup = CreateGroup()
set m = null
return this
endmethod
endstruct
struct BouncingGlaiveMissile
Missile missile
Combatant c
integer jumpCount
real px
real py
static real MAX_RANGE = 700
static method onRemove takes Missile missile returns boolean
return true
endmethod
static method onPeriod takes Missile missile returns boolean
local thistype this = missile.data
local unit u
set u = CreateUnit(c.owner, 'e01L', px, py, GetRandomReal(0, 360))
static if not LIBRARY_AutoFly then
if UnitAddAbility(u, 'Amrf') and UnitRemoveAbility(u, 'Amrf') then
endif
endif
call SetUnitTimeScale(u, 0)
call SetUnitFlyHeight(u, GetUnitFlyHeight(missile.dummy), 0)
call FadingDecay.create(u, 128., 25)
set px = missile.x
set py = missile.y
set u = null
return missile.distance >= MAX_RANGE
endmethod
static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = missile.data
local real damage
local real dx
local real dy
local real dd
local real ddx
local unit u
local boolean hitObj
if IsUnitEnemy(hit, missile.owner) and IsUnitAlive(hit) then
call missile.hitWidget(hit)
set hitObj = GetUnitAbilityLevel(hit, 'Amov') <= 0
if not Combatant[hit].isInvulnerable then
set BouncingGlaiveHit.pitch = GetRandomReal(0.75, 1.25)
call BouncingGlaiveHit.play(missile.x, missile.y, PanelCore_GetUnitZ(missile.dummy), 180)
set damage = CalculateConstantDamage(c, Combatant[hit], missile.damage, true)
call Damage(missile.source, hit, damage, false, true, true)
endif
set jumpCount = jumpCount - 1
if jumpCount < 0 then
return true
else
set ddx = MAX_RANGE
set missile.target = null
call GroupEnumUnitsInRange(Group, missile.x, missile.y, MAX_RANGE, null)
loop
set u = FirstOfGroup(Group)
exitwhen u == null
call GroupRemoveUnit(Group, u)
if IsUnitEnemy(u, missile.owner) and IsUnitVisible(u, missile.owner) and IsUnitAlive(u) and (hitObj or GetUnitAbilityLevel(u, 'Amov') > 0) and not missile.hasHitWidget(u) then
set dx = GetUnitX(u)-missile.x
set dy = GetUnitY(u)-missile.y
set dd = SquareRoot(dx*dx+dy*dy)
if dd < ddx then
set ddx = dd
set missile.target = u
endif
endif
endloop
if (missile.target != null) then
set BouncingGlaiveLaunch.pitch = GetRandomReal(1, 1.25)
call BouncingGlaiveLaunch.play(missile.x, missile.y, PanelCore_GetUnitZ(missile.dummy), 180)
set missile.distance = 0
set missile.angle = Atan2(GetUnitY(missile.target)-missile.y, GetUnitX(missile.target)-missile.x)
call missile.bounce()
else
return true
endif
endif
endif
return false
endmethod
implement MissileStruct
static method create takes unit whichUnit returns thistype
local thistype this = allocate()
local player p = GetOwningPlayer(whichUnit)
local real a = GetUnitFacing(whichUnit)*bj_DEGTORAD
local real x = GetUnitX(whichUnit)
local real y = GetUnitY(whichUnit)
local real z = GetUnitFlyHeight(whichUnit)
local real da
local real dax
local unit u
set BouncingGlaiveLaunch.pitch = GetRandomReal(1, 1.25)
call BouncingGlaiveLaunch.play(x, y, PanelCore_GetUnitZ(whichUnit), 180)
set c = Combatant[whichUnit]
set jumpCount = BouncingGlaiveBounceCount(c.pid)
set px = x
set py = y
set .missile = Missile.create(x, y, z+60, a, MAX_RANGE, z+60)
set .missile.source = whichUnit
set dax = 135*bj_DEGTORAD
call GroupEnumUnitsInRange(Group, x, y, MAX_RANGE, null)
loop
set u = FirstOfGroup(Group)
exitwhen u == null
call GroupRemoveUnit(Group, u)
if IsUnitEnemy(u, p) and IsUnitVisible(u, p) and IsUnitAlive(u) then
set da = Atan2(GetUnitY(u)-y, GetUnitX(u)-x)
set da = RAbsBJ(PanelCore_AngularDifference(da, a))
if da < dax then
set dax = da
set .missile.target = u
endif
endif
endloop
set .missile.turn = 5*bj_DEGTORAD
set .missile.owner = p
set .missile.speed = 30
set .missile.model = "war3mapImported\\ArcaneGlaive_2.mdx"
set .missile.damage = BouncingGlaiveDamage(c.pid)
set .missile.collision = 40
set .missile.scale = 0.5
set .missile.data = this
call launch(.missile)
return this
endmethod
endstruct
struct TranquilizerMissile
Missile missile
Combatant c
static method onRemove takes Missile missile returns boolean
return true
endmethod
static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = missile.data
local real damage
local Combatant c2
if IsUnitEnemy(hit, missile.owner) and IsUnitAlive(hit) then
set c2 = Combatant[hit]
if not c2.isInvulnerable then
set TranquilizerHitCount[c2] = TranquilizerReqHitCount(c.pid)
call c2.applyStun(15, TranquilizerDuration(c.pid), AddSpecialEffectTarget("Abilities\\Spells\\Undead\\Sleep\\SleepTarget.mdl", hit, "overhead"))
endif
return true
endif
return false
endmethod
implement MissileStruct
static method create takes unit whichUnit returns thistype
local thistype this = allocate()
local player p = GetOwningPlayer(whichUnit)
local real a = GetUnitFacing(whichUnit)*bj_DEGTORAD
local real x = GetUnitX(whichUnit)
local real y = GetUnitY(whichUnit)
local real z = GetUnitFlyHeight(whichUnit)
set c = Combatant[whichUnit]
set .missile = Missile.create(x, y, z+60, a, c.attackRange, z+60)
set .missile.source = whichUnit
set .missile.owner = p
set .missile.speed = 30
set .missile.model = "war3mapImported\\BonefireArrow1.mdx"
set .missile.damage = 0//c.randomPhysicDamage*DarknessClawPercentage(c.pid)
set .missile.collision = 60
set .missile.scale = 1
set .missile.data = this
call launch(.missile)
return this
endmethod
endstruct
struct ForceWall extends array
implement LinkedList
Combatant c
real x
real y
real aoe
real duration
real dps
real dmgDelay
real reflectChance
group inside
group missiles
effect sfx
effect ground
effect light
timer t
static constant real WALL_WIDTH = 128.
static method IsReflectMissile takes unit whichUnit, unit source returns unit
local thistype node = base.next
local real dx
local real dy
loop
exitwhen node.head or node == 0
if not IsUnitInGroup(whichUnit, node.missiles) and IsUnitEnemy(source, node.c.owner) then
set dx = node.x-GetUnitX(whichUnit)
set dy = node.y-GetUnitY(whichUnit)
if dx*dx+dy*dy <= node.aoe*node.aoe then
call GroupAddUnit(node.missiles, whichUnit)
if GetRandomReal(0.000, 1.000) <= node.reflectChance then
return node.c.u
endif
endif
endif
set node = node.next
endloop
return null
endmethod
method destroy takes nothing returns nothing
call DestroyEffect(.sfx)
call DestroyEffect(.light)
//call DestroyEffect(.ground)
call DestroyGroup(.inside)
call DestroyGroup(.missiles)
call ReleaseTimer(.t)
call removeNode()
call deallocate()
set .sfx = null
set .light = null
//set .ground = null
set .inside = null
set .missiles = null
set .t = null
endmethod
static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local unit fog
local real insideDmgArea
local real insideSafeArea
local real damage
local real a
local real dx
local real dy
if .dmgDelay > 0 then
set .dmgDelay = .dmgDelay - 0.03125
endif
set .duration = .duration - 0.03125
if .duration > 0 then
set insideDmgArea = .aoe-WALL_WIDTH
call GroupEnumUnitsInRange(Group, .x, .y, .aoe, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, .c.owner) and IsUnitAlive(fog) then
set a = Atan2(GetUnitY(fog)-.y, GetUnitX(fog)-.x)
if IsUnitInGroup(fog, .inside) then
set dx = .x-GetUnitX(fog)
set dy = .y-GetUnitY(fog)
if dx*dx+dy*dy >= insideDmgArea*insideDmgArea then
if GetUnitAbilityLevel(fog, 'Amov') > 0 then
// Prevent go outside
call IssueImmediateOrderById(fog, ORDER_stop)
call SetUnitX(fog, .x + insideDmgArea * Cos(a))
call SetUnitY(fog, .y + insideDmgArea * Sin(a))
endif
if .dmgDelay <= 0 and .dps > 0 then
// Deal damage
set damage = CalculateConstantDamage(c, Combatant[fog], .dps, true)*0.5
call Damage(c.u, fog, damage, false, false, false)
endif
endif
else
if GetUnitAbilityLevel(fog, 'Amov') > 0 then
// Prevent go inside
call IssueImmediateOrderById(fog, ORDER_stop)
call SetUnitX(fog, .x + .aoe * Cos(a))
call SetUnitY(fog, .y + .aoe * Sin(a))
endif
if .dmgDelay <= 0 and .dps > 0 then
// Deal damage
set damage = CalculateConstantDamage(c, Combatant[fog], .dps, true)*0.5
call Damage(c.u, fog, damage, false, false, false)
endif
endif
endif
endloop
if .dmgDelay <= 0 then
set .dmgDelay = 0.5
endif
else
call destroy()
endif
set t = null
endmethod
static method create takes Combatant c returns thistype
local thistype this = allocate()
local PlayerSkill skill = PlayerSkillData[c.pid][44]
local unit fog
set .c = c
set .x = GetUnitX(c.u)
set .y = GetUnitY(c.u)
set .reflectChance = ForceWallReflectChance(c.pid)
set .duration = ForceWallDuration(c.pid)
set .aoe = ForceWallRadius(c.pid)
if skill.level < 15 then
set .dps = 0.
else
set .dps = ForceWallDamage(c.pid)
endif
set .missiles = CreateGroup()
set .inside = CreateGroup()
if skill.level < 10 then
set .sfx = AddSpecialEffect("war3mapImported\\ForceWallSmall.mdx", .x, .y)
//set .ground = AddSpecialEffect("war3mapImported\\ForceWallGroundSmall.mdx", .x, .y)
set .light = AddSpecialEffect("war3mapImported\\LightLtBlue60.mdx", .x, .y)
else
set .sfx = AddSpecialEffect("war3mapImported\\ForceWallMed.mdx", .x, .y)
//set .ground = AddSpecialEffect("war3mapImported\\ForceWallGroundMed.mdx", .x, .y)
set .light = AddSpecialEffect("war3mapImported\\LightLtBlue300.mdx", .x, .y)
endif
call GroupEnumUnitsInRange(Group, .x, .y, .aoe-WALL_WIDTH, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, .c.owner) and IsUnitAlive(fog) then
call GroupAddUnit(.inside, fog)
endif
endloop
set .t = NewTimerEx(this)
call TimerStart(.t, 0.03125, true, function thistype.onTick)
call base.insertNode(this)
return this
endmethod
endstruct
private function LucidBeamPeriodic takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
local Combatant c2
local real a
local real x
local real y
local real z
local real kb
local real damage
local unit fog
local boolean b
if c.isChanneling and c.sp >= LucidBeamManacost[c] and IsUnitAlive(c.u) then
set a = GetUnitFacing(c.u) * bj_DEGTORAD
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
call LucidBeamHitBox[c].move(x + LucidBeamRectDistance[c] * Cos(a), y + LucidBeamRectDistance[c] * Sin(a))
set LucidBeamHitBox[c].angle = a * bj_RADTODEG
set x = x + 16 * Cos(PlayerCamera[c.pid].Rotation+PanelCore_HP) + 32 * Cos(a)
set y = y + 16 * Sin(PlayerCamera[c.pid].Rotation+PanelCore_HP) + 32 * Sin(a)
call SetUnitX(LucidBeamRay[c], x)
call SetUnitY(LucidBeamRay[c], y)
call SetUnitFacing(LucidBeamRay[c], a*bj_RADTODEG)
call CameraShaker_StartH(c.pid, 2, 0.1)
call CameraShaker_StartV(c.pid, 2, 0.1)
set LucidBeamMasteryDelay[c] = LucidBeamMasteryDelay[c] - 0.03
if LucidBeamMasteryDelay[c] <= 0 then
set LucidBeamMasteryDelay[c] = 3
call PlayerSkill(PlayerSkillData[c.pid][43]).addMastery()
endif
set LucidBeamDelay[c] = LucidBeamDelay[c] + 0.03
if LucidBeamDelay[c] > 0.25 then
set z = PanelCore_GetUnitZ(c.u)
call LucidBeam.play(x, y, z, 100)
set c.sp = c.sp - LucidBeamManacost[c]
set LucidBeamDelay[c] = 0
call LucidBeamHitBox[c].enum(TempGroup, null)
set b = false
loop
set fog = FirstOfGroup(TempGroup)
exitwhen fog == null
call GroupRemoveUnit(TempGroup, fog)
if IsUnitEnemy(fog, c.owner) and IsUnitAlive(fog) then
set c2 = Combatant[fog]
if not c2.isInvulnerable then
set b = true
if LucidBeamLevel[c] >= 5 then
set kb = 8.0 - c2.knockbackResist
if kb > 0 then
call Knockback.create(fog, a, kb, kb*4*0.03125, false)
endif
endif
if LucidBeamLevel[c] >= 15 then
call c2.silence(22, 1.0, null)
endif
set damage = CalculateConstantDamage(c, c2, LucidBeamDamage[c], true)*0.25
call Damage(c.u, fog, damage, false, false, false)
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\MoonBeamTarget.mdx", fog, "chest"))
endif
endif
endloop
call GroupClear(TempGroup)
if b then
call LucidBeamHit.play(x, y, z, 100)
endif
endif
//call DestroyEffect(AddSpecialEffect("war3mapImported\\MoonBeamImpactSmaller.mdx", x + LucidBeamMaxDistance[c] * Cos(a), y + LucidBeamMaxDistance[c] * Sin(a)))
else
set c.isChanneling = false
set c.channeledSkill = 0
call ReleaseTimer(t)
call DestroyEffect(LucidBeamLight[c])
call DestroyEffect(LucidBeamRaySfx[c])
call RemoveUnit(LucidBeamRay[c])
call LucidBeamHitBox[c].destroy()
set LucidBeamTimer[c] = null
set LucidBeamRaySfx[c] = null
set LucidBeamLight[c] = null
set LucidBeamRay[c] = null
endif
set t = null
endfunction
function LucidBeamCast takes Combatant c returns nothing
local real dp
local real a
local real x
local real y
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if c.isChanneling then
call SetUnitAnimation(c.u, "stand")
set c.isChanneling = false
set c.channeledSkill = 0
elseif not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
if LucidBeamRay[c] != null then
call ReleaseTimer(LucidBeamTimer[c])
call DestroyEffect(LucidBeamLight[c])
call DestroyEffect(LucidBeamRaySfx[c])
call RemoveUnit(LucidBeamRay[c])
set LucidBeamTimer[c] = null
set LucidBeamRaySfx[c] = null
set LucidBeamLight[c] = null
set LucidBeamRay[c] = null
endif
set a = GetUnitFacing(c.u) * bj_DEGTORAD
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
set LucidBeamLevel[c] = PlayerSkill(PlayerSkillData[c.pid][43]).level
set LucidBeamManacost[c] = SkillData(43).manacost[LucidBeamLevel[c]]*0.25
set LucidBeamDamage[c] = LucidBeamDamageAmount(c.pid)
set LucidBeamMaxDistance[c] = LucidBeamDistance(c.pid)*0.6
set LucidBeamRectDistance[c] = (LucidBeamMaxDistance[c]/2.+50.)
set LucidBeamMasteryDelay[c] = 3
set LucidBeamDelay[c] = 0
call SetUnitAnimationByIndex(c.u, 6)
set LucidBeamHitBox[c] = AngledRect.create(x + LucidBeamRectDistance[c] * Cos(a), y + LucidBeamRectDistance[c] * Sin(a), 100, LucidBeamMaxDistance[c]+100., a*bj_RADTODEG)
set x = x + 16 * Cos(PlayerCamera[c.pid].Rotation+PanelCore_HP) + 32 * Cos(a)
set y = y + 16 * Sin(PlayerCamera[c.pid].Rotation+PanelCore_HP) + 32 * Sin(a)
call LucidBeam.play(x, y, PanelCore_GetUnitZ(c.u), 100)
set LucidBeamRay[c] = CreateUnit(PASSIVE, 'e000', x, y, a*bj_RADTODEG)
call SetUnitScale(LucidBeamRay[c], 0.6, 0.6, 0.6)
set LucidBeamRaySfx[c] = AddSpecialEffectTarget(LucidBeamVFX(c.pid), LucidBeamRay[c], "origin")
set LucidBeamLight[c] = AddSpecialEffectTarget("war3mapImported\\LightLtBlue60.mdx", c.u, "origin")
set LucidBeamDelay[c] = 0
set LucidBeamTimer[c] = NewTimerEx(c)
call TimerStart(LucidBeamTimer[c], 0.03, true, function LucidBeamPeriodic)
set c.isChanneling = true
set c.channeledSkill = 43
endif
endif
endfunction
private function LunarStrikeDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
if IsUnitAlive(c.u) then
call LunarStrikeLaunchSfx.play(GetUnitX(c.u), GetUnitY(c.u), PanelCore_GetUnitZ(c.u), 200)
call CameraShaker_StartH(c.pid, 20, 0.5)
call CameraShaker_StartV(c.pid, 20, 0.5)
call LunarStrikeMissile.create(c.u)
call SetUnitTimeScale(c.u, 1.0)
call TimerStart(c.launchTimer, 0, false, null)
endif
set t = null
endfunction
function LunarStrikeCast takes Combatant c returns nothing
local real dp
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
call CameraShaker_StartH(c.pid, 3, 3600.)
call CameraShaker_StartV(c.pid, 3, 3600.)
call LunarStrikeCastSfx.play(GetUnitX(c.u), GetUnitY(c.u), PanelCore_GetUnitZ(c.u), 200)
set dp = c.dmgPoint*(c.attackRate/c.attackRateDef)*1.5
call SetUnitTimeScale(c.u, c.attackRateDef/c.attackRate/1.5)
call SetUnitAnimation(c.u, "slam")
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, c.attackRate, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, dp, false, function LunarStrikeDamage)
call c.immobilize(0, dp, null)
call BUS_StartChannel(BUS_GetChannelByName("LunarStrike"), c.u, null, 0., 0., dp/4, 0, false)
endif
endif
endfunction
private function PrimalStrikeDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
if IsUnitAlive(c.u) then
call PrimalStrikeLaunchSfx.play(GetUnitX(c.u), GetUnitY(c.u), PanelCore_GetUnitZ(c.u), 200)
call CameraShaker_StartH(c.pid, 30, 1.0)
call CameraShaker_StartV(c.pid, 30, 1.0)
call PrimalStrikeMissile.create(c.u)
call SetUnitTimeScale(c.u, 1.0)
call TimerStart(c.launchTimer, 0, false, null)
endif
set t = null
endfunction
function PrimalStrikeCast takes Combatant c returns nothing
local real dp
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
call CameraShaker_StartH(c.pid, 3, 3600.)
call CameraShaker_StartV(c.pid, 3, 3600.)
call PrimalStrikeCastSfx.play(GetUnitX(c.u), GetUnitY(c.u), PanelCore_GetUnitZ(c.u), 200)
set dp = c.dmgPoint*(c.attackRate/c.attackRateDef)*1.5
call SetUnitTimeScale(c.u, c.attackRateDef/c.attackRate/1.5)
call SetUnitAnimation(c.u, "attack")
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, c.attackRate, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, dp, false, function PrimalStrikeDamage)
call c.immobilize(0, dp, null)
call BUS_StartChannel(BUS_GetChannelByName("PrimalStrike"), c.u, null, 0., 0., dp/4, 0, false)
endif
endif
endfunction
private function TripleShardDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
if IsUnitAlive(c.u) then
call CameraShaker_StartH(c.pid, 5, 0.1)
call CameraShaker_StartV(c.pid, 5, 0.1)
call TripleShardMissile.create(c.u)
call SetUnitTimeScale(c.u, 1.0)
call TimerStart(c.launchTimer, 0, false, null)
call TimerStart(c.attackTimer, (c.dmgPoint*(c.attackRate/c.attackRateDef))*0.25, false, null)
endif
set t = null
endfunction
function TripleShardCast takes Combatant c returns nothing
local real dp
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
set dp = c.dmgPoint*(c.attackRate/c.attackRateDef)
call SetUnitTimeScale(c.u, c.attackRateDef/c.attackRate)
call SetUnitAnimation(c.u, "slam")
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, c.attackRate, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, dp, false, function TripleShardDamage)
call c.immobilize(0, dp, null)
endif
endif
endfunction
private function QuickShotDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
local real dp
if IsUnitAlive(c.u) then
call CameraShaker_StartH(c.pid, 10, 0.1)
call CameraShaker_StartV(c.pid, 10, 0.1)
call QuickShotMissile.create(c.u)
set QuickShotCount[c] = QuickShotCount[c] - 1
if not c.isDisarmed and not c.isStunned and not c.isSilenced and QuickShotCount[c] > 0 then
set dp = c.dmgPoint*(c.attackRate/c.attackRateDef)/2
call SetUnitTimeScale(c.u, c.attackRateDef/c.attackRate*2)
call SetUnitAnimation(c.u, "slam")
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, c.attackRate/2, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, dp, false, function QuickShotDamage)
call c.immobilize(0, dp, null)
else
set dp = c.dmgPoint*(c.attackRate/c.attackRateDef)
call TimerStart(c.attackTimer, dp*0.25, false, null)
endif
endif
set t = null
endfunction
function QuickShotCast takes Combatant c returns nothing
local real dp
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
set QuickShotCount[c] = QuickShotAttackCount(c.pid)
set dp = c.dmgPoint*(c.attackRate/c.attackRateDef)/2
call SetUnitTimeScale(c.u, c.attackRateDef/c.attackRate*2)
call SetUnitAnimation(c.u, "slam")
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, c.attackRate/2, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, dp, false, function QuickShotDamage)
call c.immobilize(0, dp, null)
endif
endif
endfunction
private function ForceWallDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
if IsUnitAlive(c.u) then
call ForceWall.create(c)
call TimerStart(c.attackTimer, 0.25, false, function Combatant.resetTimer)
call c.immobilize(0, 0.25, null)
endif
set t = null
endfunction
function ForceWallCast takes Combatant c returns nothing
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
call SetUnitTimeScale(c.u, 1)
call SetUnitAnimation(c.u, "spell")
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, 999, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, 0.5, false, function ForceWallDamage)
call c.immobilize(0, 0.75, null)
endif
endif
endfunction
private function BouncingGlaiveDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
if IsUnitAlive(c.u) then
call BouncingGlaiveMissile.create(c.u)
call SetUnitTimeScale(c.u, 1.0)
call TimerStart(c.launchTimer, 0, false, null)
endif
set t = null
endfunction
function BouncingGlaiveCast takes Combatant c returns nothing
local real dp
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
call SetUnitTimeScale(c.u, 1.0)
call SetUnitAnimationByIndex(c.u, 12)
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, c.attackRate, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, 0.3, false, function BouncingGlaiveDamage)
call c.immobilize(0, 0.7, null)
endif
endif
endfunction
private function TranquilizerDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
if IsUnitAlive(c.u) then
call TranquilizerMissile.create(c.u)
call SetUnitTimeScale(c.u, 1.0)
call TimerStart(c.launchTimer, 0, false, null)
endif
set t = null
endfunction
function TranquilizerCast takes Combatant c returns nothing
local real dp
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
set dp = c.dmgPoint*(c.attackRate/c.attackRateDef)
call SetUnitTimeScale(c.u, c.attackRateDef/c.attackRate)
call SetUnitAnimation(c.u, "attack")
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, c.attackRate, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, dp, false, function TranquilizerDamage)
call c.immobilize(0, dp, null)
endif
endif
endfunction
function FastReloadCast takes Combatant c returns nothing
local real x
local real y
local real dur
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isStunned and not c.isAttacking and not c.isSilenced then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\PeterifyVer.2.mdx", c.u, "chest"))
call c.disarm(0, 1, null)
call c.immobilize(0, 1, null)
call SetUnitAnimationByIndex(c.u, 11)
call QueueUnitAnimation(c.u, "stand")
set dur = FastReloadDuration(c.pid)
call StatusBonus.cleanse(c, 16)
call StatusBonus.create(c.u, 2, FastReloadSpeedBonus(c.pid), dur, 16)
call c.applyBuff(16, dur, AddSpecialEffectTarget("war3mapImported\\CircleOutBuff.mdx", c.u, "origin"))
endif
endif
endfunction
function AcuteSightCast takes Combatant c returns nothing
local real x
local real y
local real dur
local PlayerSkill skill
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isStunned and not c.isAttacking and not c.isSilenced then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\Concecration.mdx", c.u, "origin"))
call c.disarm(0, 1, null)
call c.immobilize(0, 1, null)
call SetUnitAnimationByIndex(c.u, 11)
call QueueUnitAnimation(c.u, "stand")
set skill = PlayerSkillData[c.pid][36]
set dur = 30.
call StatusBonus.cleanse(c, 17)
call StatusBonus.create(c.u, 5, AcuteSightAccuracy(c.pid), dur, 17)
if skill.level >= 15 then
call StatusBonus.create(c.u, 7, (c.physicDmgMax+c.physicDmgMin)/2. * AcuteSightDamageBonus(c.pid), dur, 17)
endif
if skill.level >= 10 then
call StatusBonus.create(c.u, 14, AcuteSightInterruption(c.pid), dur, 17)
endif
if skill.level >= 5 then
call StatusBonus.create(c.u, 13, AcuteSightCriticalChance(c.pid), dur, 17)
endif
call c.applyBuff(17, dur, AddSpecialEffectTarget("war3mapImported\\Dalaran BrillianceSmall.mdx", c.u, "overhead"))
endif
endif
endfunction
private function ViciousHailDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
if IsUnitAlive(c.u) then
call ViciousHail.create(c.u, ViciousHailX[c], ViciousHailY[c])
call SetUnitTimeScale(c.u, 1.0)
call TimerStart(c.launchTimer, 0, false, null)
endif
set t = null
endfunction
function ViciousHailCast takes Combatant c, real x, real y returns nothing
local real dp
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
set ViciousHailX[c] = x
set ViciousHailY[c] = y
set dp = c.dmgPoint*(c.attackRate/c.attackRateDef)
call SetUnitTimeScale(c.u, c.attackRateDef/c.attackRate)
call SetUnitAnimationByIndex(c.u, 11)
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(c.attackTimer, c.attackRate, false, function Combatant.resetTimer)
call TimerStart(c.launchTimer, dp, false, function ViciousHailDamage)
call c.immobilize(0, dp, null)
endif
endif
endfunction
function SummonWolfCast takes Combatant c returns nothing
local real x
local real y
local Combatant c2
local CompanionAI ai
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
//call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\PeterifyVer.2.mdx", c.u, "chest"))
call c.disarm(0, 1, null)
call c.immobilize(0, 1, null)
call SetUnitAnimationByIndex(c.u, 11)
call QueueUnitAnimation(c.u, "stand")
set c2 = Combatant.create(CreateUnit(c.owner, SummonWolfModel(c.pid), x, y, GetRandomReal(0, 360)))
//call UnitApplyTimedLife(c2.u, 'BTLF', 300)
call GroupAddUnit(PlayerUnits, c2.u)
call CompanionAI.removeWithId(c, 35)
set ai = CompanionAI.create(c, c2)
set ai.id = 35
set ai.sfx = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspirittarget.mdl"
call UnitAddAbility(c2.u, 'Aloc')
call UnitRemoveAbility(c2.u, 'Aloc')
call ShowUnit(c2.u, false)
call ShowUnit(c2.u, true)
call UnitAddAbility(c2.u, 'Amrf')
call UnitRemoveAbility(c2.u, 'Amrf')
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Orc\\FeralSpirit\\feralspirittarget.mdl", x, y))
set c2.level = Level[c.pid]
set c2.dropQuality = 0
set c2.noRemove = false
set c2.hitsToKill = false
set c2.destructible = false
set c2.ignoreDamage = false
set c2.melee = true
set c2.missileHoming = false
set c2.missilePiercing = false
set c2.missile = ""
set c2.missileCollision = 50.0
set c2.missileScale = 0.0
set c2.missileSpeed = 0.0
set c2.missileArch = 0
set c2.missileTurn = 0
set c2.missileXY = 0
set c2.missileZ = 0
set c2.dmgAoE = 0
set c2.attackRadius = 5.0*bj_DEGTORAD
set c2.attackRange = 160.0
set c2.dmgPoint = 0.3
set c2.attackRateDef = 1.75
set c2.attackRate = c2.attackRateDef
set c2.physicDmgMin = SummonWolfMinDamage(c.pid)
set c2.physicDmgMax = SummonWolfMaxDamage(c.pid)
set c2.physicDefense = SummonWolfPhysicDef(c.pid)
set c2.magicDmgMin = 0
set c2.magicDmgMax = 0
set c2.magicDefense = SummonWolfMagicDef(c.pid)
set c2.criticalRate = SummonWolfCriticalChance(c.pid)
set c2.criticalPower = 0.5
set c2.blockRate = 0.00
set c2.evasionRate = 0
set c2.knockback = 0.0
set c2.knockbackResist = 0.0
set c2.interrupt = 0.0
set c2.interruptResist = 0.0
set c2.stun = 0.0
set c2.stunResist = 0.0
set c2.hp = SummonWolfHealth(c.pid)
set c2.hpMax = c2.hp
set c2.hpRegen = 0.0
set c2.sp = 0
set c2.spMax = 0
set c2.spRegen = 0
set c2.xpMultiplier = 0.0
set c2.wType = WEAPON_TYPE_METAL_MEDIUM_CHOP
endif
endif
endfunction
function SnaringTrapCast takes Combatant c, real x, real y returns nothing
local real dp
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
call SetUnitAnimationByIndex(c.u, 12)
call QueueUnitAnimation(c.u, "stand")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
set dp = c.dmgPoint*(c.attackRate/c.attackRateDef)
call SnareTrap.cast(c, x, y)
call TimerStart(c.attackTimer, c.attackRate, false, function Combatant.resetTimer)
call c.immobilize(0, dp, null)
endif
endif
endfunction
function IllusoryIncarnationCast takes Combatant c returns nothing
local real x
local real y
local real dealt
local real taken
local real dur
local integer ct
local integer i
local PlayerSkill skill
local PlayerSkill afterimage
local HumanoidAI ai
local Combatant c2
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isStunned and not c.isAttacking and not c.isSilenced then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
//call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\Concecration.mdx", c.u, "origin"))
call c.disarm(0, 1, null)
call c.immobilize(0, 1, null)
call SetUnitAnimation(c.u, "spell")
call QueueUnitAnimation(c.u, "stand")
set skill = PlayerSkillData[c.pid][42]
set afterimage = PlayerSkillData[c.pid][46]
set ct = IllusoryIncarnationCount(c.pid)
set dealt = IllusoryIncarnationDamageDealt(c.pid)
set taken = IllusoryIncarnationDamageTaken(c.pid)-EmbodimentDamageTakenBonus(c.pid)
set dur = IllusoryIncarnationDuration(c.pid)+EmbodimentLifespanBonus(c.pid)
call HumanoidAI.removeWithId(c, 42)
set i = 0
loop
exitwhen i >= ct
set c2 = Illusion.copy(c, c.owner, dealt, taken)
set c2.level = Level[c.pid]
set ai = HumanoidAI.create(c, c2)
set ai.id = 42
set ai.sfx = "war3mapImported\\BlinkCaster.mdx"
if afterimage.level > 0 then
call Afterimage.register(c2, c.pid)
endif
call UnitApplyTimedLife(c2.u, 'BTLF', dur)
call GroupAddUnit(PlayerUnits, c2.u)
if skill.level < 5 then
call SetUnitVertexColor(c2.u, 215, 215, 215, 100)
elseif skill.level < 10 then
call SetUnitVertexColor(c2.u, 0, 75, 255, 100)
elseif skill.level < 15 then
call SetUnitVertexColor(c2.u, 72, 0, 255, 100)
else
call SetUnitVertexColor(c2.u, 255, 72, 0, 100)
endif
call DestroyEffect(AddSpecialEffect("war3mapImported\\BlinkCaster.mdx", GetUnitX(c2.u), GetUnitY(c2.u)))
set i = i + 1
endloop
endif
endif
endfunction
function ShadowMeldCast takes Combatant c returns nothing
local PlayerSkill skill
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isStunned and not c.isAttacking and not c.isSilenced then
call ShadowMeldSfx.play(GetUnitX(c.u), GetUnitY(c.u), PanelCore_GetUnitZ(c.u), 200)
call DestroyEffectTimed(AddSpecialEffectTarget("war3mapImported\\Timerift Missle.mdx", c.u, "chest"), 1.0)
call c.disarm(0, 1, null)
call c.immobilize(0, 1, null)
call SetUnitAnimationByIndex(c.u, 11)
call QueueUnitAnimation(c.u, "stand")
set skill = PlayerSkillData[c.pid][26]
call Invisibility.apply(c, 26, 30., null)
if skill.level >= 5 then
call StatusBonus.create(c.u, 6, GetUnitMoveSpeed(c.u)*ShadowMeldSpeedBonus(c.pid), 30., 26)
endif
endif
endif
endfunction
//! endtextmacro
endlibrary
scope Persecute
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Persecute v1.0
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//
// I. Description
// Throws a paintball at the target. Marking it as a wanted
// target. Marked unit will leave traces as it travels.
// Ally units who's targeting it will have their attack
// speed and move speed increased. The mark lasts for 15
// seconds.
//
// Level 1 - 15% attack speed bonus. 10% move speed bonus.
// Level 2 - 25% attack speed bonus. 15% move speed bonus.
// Level 3 - 35% attack speed bonus. 20% move speed bonus.
//
// II. Requirements
// • Missile by BPower | hiveworkshop.com/threads/missile.265370/
// • UnitIndexer by TriggerHappy | hiveworkshop.com/threads/system-unitdex-unit-indexer.248209/
// • TimerUtils by Vexorian | wc3c.net/showthread.php?t=101322
//
// III. How to import
// • Import dummy.mdx from import manager to your map. Other files are optional
// • Import the following object data to your map:
// (Unit)
// • Dummy Caster
// • Missile Dummy
// (Ability)
// • Persecute (Buff)
// • Persecute (Mark)
// • Persecute (Main)
// (Buff)
// • Persecute (Buff)
// • Persecute (Mark)
// • Make sure "Persecute (Buff)" ability has "Persecute (Buff)" as buff
// • Make sure "Persecute (Mark)" ability has "Persecute (Mark)" as buff
// • Import and configure required libraries properly
// • Import Persecute trigger and configure it properly
//
// IV. Credits
// • HappyCockroach : spell concept
// • TriggerHappy : UnitIndexer library
// • Vexorian : TimerUtils library
//
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Configurations
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// A. Static configurations
globals
// 1. Persecute main ability raw code
private constant integer MAIN_SPELL_ID = 'A00B'
//
// 2. Persecute (Mark) ability raw code
private constant integer MARK_SPELL_ID = 'A00C'
//
// 3. Persecute (Buff) ability raw code
private constant integer BONUS_SPELL_ID = 'A00D'
//
// 4. Persecute (Buff) buff raw code
private constant integer MARK_BUFF_ID = 'B003'
//
// 5. Persecute (Mark) buff raw code
private constant integer BONUS_BUFF_ID = 'B004'
//
// 6. Dummy Caster unit raw code
private constant integer DUMMY_CASTER_ID = 'e000'
//
// 7. Persecute (Mark) ability order id
private constant integer MARK_ORDER_ID = 852570 // "wandofshadowsight"
//
// 8. Persecute (Buff) ability order id
private constant integer BONUS_ORDER_ID = 852101 // "bloodlust"
//
// 9. Launched missile model file path
private constant string MISSILE_MODEL_PATH = "war3mapImported\\Swashbuckler_Persecute_Projectile.MDX"
//
// 10. Missile move speed
private constant real MISSILE_SPEED = 25.0
//
// 11. Missile trajectory arc
private constant real MISSILE_ARC = 0.15
//
// 12. Missile launching vertical (height) offset
private constant real MISSILE_LAUNCH_VOFFSET = 125.0
//
// 13. Missile launching horizontal (xy) offset
private constant real MISSILE_LAUNCH_HOFFSET = 65.0
//
// Interval at which the detection trigger will reset
// (Just don't modify if you don't know what it means) Congrats! If you are reading this, it means you are certified nerd
private constant real TRIGGER_RESET_INTERVAL = 30.0
//
// Better not to modify this
private constant real INTERVAL = 0.1
endglobals
//
// B. Dynamic configurations
//
// 14. Mark duration on normal units
private constant function MarkDurationNormal takes integer level returns real
return 20.0
endfunction
//
// 15. Mark duration on hero units
private constant function MarkDurationHero takes integer level returns real
return 10.0
endfunction
//
// 16. Classification of unit that can receive bonus stats when
// chasing a target with Persecute (Buff - Target) buff
// • chaser = unit that's targeting the marked unit
// • caster = owner of the caster (who gives the mark)
// • target = marked unit
// Current targets: enemy of target, ally of caster, non-mechanical, non-structure
private constant function AllowedChaser takes unit chaser, player caster, player target returns boolean
return IsUnitEnemy(chaser, target) and IsUnitAlly(chaser, caster) and not IsUnitType(chaser, UNIT_TYPE_MECHANICAL) and not IsUnitType(chaser, UNIT_TYPE_STRUCTURE)
endfunction
//
//
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
native UnitAlive takes unit id returns boolean
globals
private constant integer ATTACK_ORDER_ID = 851983 // "attack"
private constant integer SMART_ORDER_ID = 851971 // "smart"
private constant player PASSIVE = Player(PLAYER_NEUTRAL_PASSIVE)
private unit DummyCaster
endglobals
private struct PersecuteMark
unit target
real duration
static thistype array Index
static method onPeriodic takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
// If need the buff to be removed
if (.duration <= INTERVAL or not UnitAlive(.target) or GetUnitAbilityLevel(.target, MARK_BUFF_ID) == 0) then
set Index[GetUnitUserData(.target)] = 0
call UnitRemoveAbility(.target, MARK_BUFF_ID)
call ReleaseTimer(t)
call deallocate()
set .target = null
else
set .duration = .duration - INTERVAL
endif
set t = null
endmethod
static method apply takes Missile missile returns nothing
local thistype this
local integer data = GetUnitUserData(missile.target)
// If already registered
if (Index[data] != 0) then
set this = Index[data]
if (IsUnitType(missile.target, UNIT_TYPE_HERO)) then
set .duration = MarkDurationHero(missile.data)
else
set .duration = MarkDurationNormal(missile.data)
endif
else
set this = allocate()
set Index[data] = this
set .target = missile.target
// If target is a hero
if (IsUnitType(missile.target, UNIT_TYPE_HERO)) then
set .duration = MarkDurationHero(missile.data)
else
set .duration = MarkDurationNormal(missile.data)
endif
// If not have the buff yet
if (GetUnitAbilityLevel(missile.target, MARK_BUFF_ID) == 0) then
call SetUnitOwner(DummyCaster, missile.owner, false)
call IssueTargetOrderById(DummyCaster, MARK_ORDER_ID, missile.target)
call SetUnitOwner(DummyCaster, PASSIVE, false)
endif
call TimerStart(NewTimerEx(this), INTERVAL, true, function thistype.onPeriodic)
endif
endmethod
endstruct
private struct Persecute extends array
static group TempGroup
static group BonusGroup = CreateGroup() // Group containing units with bonus buff
static group DetectGroup = CreateGroup() // Group containing units registered in detection trigger
static group RecycleGroup = CreateGroup() // For recycling purpose
static timer ResetTimer = CreateTimer()
static timer CheckTimer = CreateTimer()
static trigger DetectTrigger = CreateTrigger()
static trigger LearnTrigger = CreateTrigger()
static integer array AbilityLevel
static player array CasterOwner
static unit array TargetUnit
static method removeBonus takes unit u returns nothing
if (IsUnitInGroup(u, BonusGroup)) then
call GroupRemoveUnit(BonusGroup, u)
call UnitRemoveAbility(u, BONUS_BUFF_ID)
// If there is no unit with the bonus buff anymore
if (FirstOfGroup(BonusGroup) == null) then
call PauseTimer(CheckTimer)
endif
endif
endmethod
static method check takes nothing returns nothing
local integer data
local unit fog
loop
set fog = FirstOfGroup(DetectGroup)
exitwhen (fog == null)
call GroupRemoveUnit(DetectGroup, fog)
call GroupAddUnit(RecycleGroup, fog)
if (IsUnitInGroup(fog, BonusGroup)) then
set data = GetUnitUserData(fog)
// Check if unit's target is still alive and still marked
if (not UnitAlive(TargetUnit[data]) or not IsUnitVisible(TargetUnit[data], GetOwningPlayer(fog)) or GetUnitAbilityLevel(TargetUnit[data], MARK_BUFF_ID) == 0) then
call removeBonus(fog)
endif
// Add compatibility with spell stealing abilities (no permanent buff)
elseif (GetUnitAbilityLevel(fog, BONUS_BUFF_ID) > 0) then
call UnitRemoveAbility(fog, BONUS_BUFF_ID)
endif
endloop
set TempGroup = DetectGroup
set DetectGroup = RecycleGroup
set RecycleGroup = TempGroup
endmethod
static method addBonus takes unit u, unit t returns nothing
if (not IsUnitInGroup(u, BonusGroup) and AllowedChaser(u, CasterOwner[GetUnitUserData(t)], GetOwningPlayer(t))) then
// If the unit is the first one to have bonus buff
if (FirstOfGroup(BonusGroup) == null) then
call TimerStart(CheckTimer, INTERVAL, true, function thistype.check)
endif
call GroupAddUnit(BonusGroup, u)
// Apply move and attack speed bonus based on ability level
call SetUnitAbilityLevel( DummyCaster, BONUS_SPELL_ID, AbilityLevel[GetUnitUserData(t)])
call IssueTargetOrderById(DummyCaster, BONUS_ORDER_ID, u)
endif
endmethod
static method onDetect takes nothing returns boolean
local unit t = GetEventTargetUnit()
local unit u = GetTriggerUnit()
set TargetUnit[GetUnitUserData(u)] = t
// If the target is marked
if (GetUnitAbilityLevel(t, MARK_BUFF_ID) > 0) then
call addBonus(u, t)
else
call removeBonus(u)
endif
set t = null
set u = null
return false
endmethod
static method onOrder takes nothing returns boolean
local integer order
local unit t = GetOrderTargetUnit()
local unit u = GetTriggerUnit()
if (t != null) then
set order = GetIssuedOrderId()
// Make sure the order is "attack"
if (order == ATTACK_ORDER_ID or (order == SMART_ORDER_ID and IsUnitEnemy(u, GetOwningPlayer(t)))) then
// Save the unit's current target
set TargetUnit[GetUnitUserData(u)] = t
// If the target is marked
if (GetUnitAbilityLevel(t, MARK_BUFF_ID) > 0) then
call addBonus(u, t)
else
call removeBonus(u)
endif
else
call removeBonus(u)
endif
else
call removeBonus(u)
endif
set t = null
set u = null
return false
endmethod
static method onRemove takes Missile missile returns boolean
local integer data
local unit fog
if (UnitAlive(missile.target)) then
set data = GetUnitUserData(missile.target)
set AbilityLevel[data] = GetUnitAbilityLevel(missile.source, MAIN_SPELL_ID)
set CasterOwner[data] = missile.owner
// Every unit can only have one mark
if (GetUnitAbilityLevel(missile.target, MARK_BUFF_ID) > 0) then
call UnitRemoveAbility(missile.target, MARK_BUFF_ID)
loop
set fog = FirstOfGroup(BonusGroup)
exitwhen (fog == null)
call GroupRemoveUnit(BonusGroup, fog)
if (TargetUnit[GetUnitUserData(fog)] == missile.target) then
call removeBonus(fog)
else
call GroupAddUnit(RecycleGroup, fog)
endif
endloop
set TempGroup = BonusGroup
set BonusGroup = RecycleGroup
set RecycleGroup = TempGroup
endif
// Re-apply to reset mark duration
call PersecuteMark.apply(missile)
call IssueTargetOrderById(DummyCaster, MARK_ORDER_ID, missile.target)
loop
set fog = FirstOfGroup(DetectGroup)
exitwhen (fog == null)
call GroupRemoveUnit(DetectGroup, fog)
call GroupAddUnit(RecycleGroup, fog)
// If unit's target is the marked unit
if (TargetUnit[GetUnitUserData(fog)] == missile.target) then
call addBonus(fog, missile.target)
endif
endloop
set TempGroup = DetectGroup
set DetectGroup = RecycleGroup
set RecycleGroup = TempGroup
endif
return true
endmethod
implement MissileStruct
static method onCast takes nothing returns boolean
local Missile missile
local unit caster
local unit target
local real xt
local real yt
local real x
local real y
local real a
if (GetSpellAbilityId() == MAIN_SPELL_ID) then
set caster = GetTriggerUnit()
set target = GetSpellTargetUnit()
set x = GetUnitX(caster)
set y = GetUnitY(caster)
set xt = GetUnitX(target)
set yt = GetUnitY(target)
set a = Atan2(yt-y, xt-x)
// Launch the paintball
set missile = Missile.createXYZ(x+MISSILE_LAUNCH_HOFFSET*Cos(a), y+MISSILE_LAUNCH_HOFFSET*Sin(a), MISSILE_LAUNCH_VOFFSET+GetUnitFlyHeight(caster), xt, yt, MISSILE_LAUNCH_VOFFSET+GetUnitFlyHeight(target))
set missile.owner = GetTriggerPlayer()
set missile.source = caster
set missile.target = target
set missile.arc = MISSILE_ARC
set missile.speed = MISSILE_SPEED
set missile.model = MISSILE_MODEL_PATH
set missile.data = GetUnitAbilityLevel(caster, MAIN_SPELL_ID)
call launch(missile)
set target = null
set caster = null
endif
return false
endmethod
static method resetTrigger takes nothing returns nothing
local unit fog
// Reset detection trigger
call DestroyTrigger(DetectTrigger)
set DetectTrigger = CreateTrigger()
call TriggerAddCondition(DetectTrigger, Condition(function thistype.onDetect))
loop
set fog = FirstOfGroup(DetectGroup)
exitwhen (fog == null)
call GroupRemoveUnit(DetectGroup, fog)
call GroupAddUnit(RecycleGroup, fog)
call TriggerRegisterUnitEvent(DetectTrigger, fog, EVENT_UNIT_ACQUIRED_TARGET)
endloop
// Recycle group
set TempGroup = DetectGroup
set DetectGroup = RecycleGroup
set RecycleGroup = TempGroup
endmethod
static method onDeindex takes nothing returns boolean
local unit u = GetIndexedUnit()
set TargetUnit[GetIndexedUnitId()] = null
call GroupRemoveUnit(DetectGroup, u)
if (IsUnitInGroup(u, BonusGroup)) then
call GroupRemoveUnit(BonusGroup, u)
// If there is no unit with the bonus buff anymore
if (FirstOfGroup(BonusGroup) == null) then
call PauseTimer(CheckTimer)
endif
endif
set u = null
return false
endmethod
static method initializeSpell takes nothing returns nothing
local unit fog
local group g = CreateGroup()
local trigger t1 = CreateTrigger()
local trigger t2 = CreateTrigger()
local integer i = 0
local player p
// Prepare triggers
loop
exitwhen (i == bj_MAX_PLAYER_SLOTS)
set p = Player(i)
call TriggerRegisterPlayerUnitEvent(t1, p, EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerRegisterPlayerUnitEvent(t2, p, EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
call TriggerRegisterPlayerUnitEvent(t2, p, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
call TriggerRegisterPlayerUnitEvent(t2, p, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
set i = i + 1
endloop
call EnableTrigger(DetectTrigger)
call DestroyTrigger(LearnTrigger)
call TriggerAddCondition(t1, Condition(function thistype.onCast))
call TriggerAddCondition(t2, Condition(function thistype.onOrder))
call TriggerAddCondition(DetectTrigger, Condition(function thistype.onDetect))
call RegisterUnitIndexEvent(Condition(function thistype.onDeindex), UnitIndexer.DEINDEX)
// Periodically reset detection trigger to prevent event leaks
call TimerStart(ResetTimer, TRIGGER_RESET_INTERVAL, true, function thistype.resetTrigger)
// Create dummy caster to apply buffs
set DummyCaster = CreateUnit(PASSIVE, DUMMY_CASTER_ID, 0, 0, 0)
call UnitAddAbility(DummyCaster, BONUS_SPELL_ID)
call UnitAddAbility(DummyCaster, MARK_SPELL_ID)
call GroupEnumUnitsInRect(g, GetWorldBounds(), null)
loop
set fog = FirstOfGroup(g)
exitwhen (fog == null)
call GroupRemoveUnit(g, fog)
if (IsUnitIndexed(fog)) then
call TriggerRegisterUnitEvent(DetectTrigger, fog, EVENT_UNIT_ACQUIRED_TARGET)
call GroupAddUnit(DetectGroup, fog)
endif
endloop
call DestroyGroup(g)
set LearnTrigger = null
set g = null
endmethod
static method onLearn takes nothing returns boolean
if (GetLearnedSkill() == MAIN_SPELL_ID) then
// The first time the spell appears in game, initialize the spell trigger
call initializeSpell()
endif
return false
endmethod
static method onIndex takes nothing returns boolean
local unit u
if (IsTriggerEnabled(DetectTrigger)) then
set u = GetIndexedUnit()
// Add indexed unit to the detection trigger
call TriggerRegisterUnitEvent(DetectTrigger, u, EVENT_UNIT_ACQUIRED_TARGET)
call GroupAddUnit(DetectGroup, u)
set u = null
elseif (GetUnitAbilityLevel(GetIndexedUnit(), MAIN_SPELL_ID) > 0) then
// The first time the spell appears in game, initialize the spell trigger
call initializeSpell()
endif
return false
endmethod
static method onInit takes nothing returns nothing
call DisableTrigger(DetectTrigger)
call TriggerRegisterAnyUnitEventBJ(LearnTrigger, EVENT_PLAYER_HERO_SKILL)
call TriggerAddCondition(LearnTrigger, Condition(function thistype.onLearn))
call RegisterUnitIndexEvent(Condition(function thistype.onIndex), UnitIndexer.INDEX)
endmethod
endstruct
endscope
library Cinemax uses TimerUtils
//! textmacro CreatePaperObject takes TYPE, CODE, INDEX, EXTENSION
//! external ObjectMerger w3b YTlb $TYPE$$CODE$ bnam "(Cover) $INDEX$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\cover$INDEX$$EXTENSION$" btxi 33 bfvi 1 bsel 0 bgsc 0 bshd "" barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
/*
//! runtextmacro CreatePaperObject ("CC", "00", "0", ".blp")
//! runtextmacro CreatePaperObject ("CC", "01", "1", ".blp")
//! runtextmacro CreatePaperObject ("CC", "02", "2", ".blp")
//! runtextmacro CreatePaperObject ("CC", "03", "3", ".blp")
//! runtextmacro CreatePaperObject ("CC", "04", "4", ".blp")
//! runtextmacro CreatePaperObject ("CC", "05", "5", ".blp")
//! runtextmacro CreatePaperObject ("CC", "06", "6", ".blp")
//! runtextmacro CreatePaperObject ("CC", "07", "7", ".blp")
//! runtextmacro CreatePaperObject ("CC", "08", "8", ".blp")
//! runtextmacro CreatePaperObject ("CC", "09", "9", ".blp")
//! runtextmacro CreatePaperObject ("CC", "0A", "10", ".blp")
//! runtextmacro CreatePaperObject ("CC", "0B", "11", ".blp")
//! runtextmacro CreatePaperObject ("CC", "0C", "12", ".blp")
//! runtextmacro CreatePaperObject ("CC", "0D", "13", ".blp")
//! runtextmacro CreatePaperObject ("CC", "0E", "14", ".blp")
//! runtextmacro CreatePaperObject ("CC", "0F", "15", ".blp")
*/
struct Cinemax
Panel PaperPlatform
PanelPlatform PaperHighlight
PanelPlatform PaperCover
BJObjectId CoverIndex
integer TransitionIndex
real TransitionSpeed
static integer array PlayerSceneIndex
static method transition takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
if (TransitionIndex < 13) then
set CoverIndex = CoverIndex.plus_1()
set TransitionIndex = TransitionIndex + 1
if (TransitionIndex == 13) then
// Next scene here
set PaperCover.texture = 'BSAL'
call TimerStart(t, 1, false, function thistype.transition)
else
set PaperCover.texture = CoverIndex
call TimerStart(t, TransitionSpeed, false, function thistype.transition)
endif
call PaperCover.refresh()
else
set CoverIndex = 'CC00'
set TransitionIndex = 0
set PaperCover.texture = CoverIndex
call PaperCover.refresh()
call TimerStart(t, TransitionSpeed, false, function thistype.transition)
endif
set t = null
endmethod
method play takes nothing returns nothing
local integer pid = 0
// If player is not playing other cinemax
if (PlayerSceneIndex[pid] == 0) then
call ClearTextMessages()
call ShowInterface(false, 2.0)
call EnableUserControl(false)
call EnableUserUI(false)
call PaperPlatform.show(true)
call PaperPlatform.refresh()
call PaperCover.show(true)
set CoverIndex = 'CC00'
set TransitionIndex = 0
set TransitionSpeed = 0.05
set PaperCover.texture = CoverIndex
call PaperCover.refresh()
call TimerStart(NewTimerEx(this), 3, false, function thistype.transition)
endif
endmethod
method addScene takes CinemaxScene scene returns nothing
endmethod
static method create takes nothing returns thistype
local thistype this = allocate()
local PanelTextEx temp
set PaperPlatform = Panel.create(Locale, 'e01M', 'CP00', 0, 0, -PanelCamera_LEVEL_GAP*10)
call PaperPlatform.show(false)
set PaperCover = PanelPlatform.create(PaperPlatform, 'e01M', 'BSAL', 0, 0, 20)
call PaperCover.show(false)
return this
endmethod
static method start takes nothing returns nothing
local thistype this = create()
call this.play()
endmethod
static method onInit takes nothing returns nothing
//call TimerStart(NewTimer(), 10, false, function thistype.start)
endmethod
endstruct
struct CinemaxScene
string narration
method setNarration takes string transcript returns nothing
endmethod
method addObject takes CinemaxObject obj returns nothing
endmethod
static method create takes nothing returns thistype
local thistype this = allocate()
return this
endmethod
endstruct
struct CinemaxObject
integer plat
integer text
real startX
real startY
real targX
real targY
real startAlpha
real targAlpha
real alphaRate
real vertShake
real horzShake
static method create takes integer platform, integer texture returns thistype
local thistype this = allocate()
return this
endmethod
endstruct
endlibrary
library AttPoints
globals
boolean IsDataLoading = false
integer array AttributePoint
integer array Strength
integer array Dexterity
integer array Wisdom
integer array Fortitude
endglobals
function AddAttributePoint takes integer id, integer amount returns nothing
local integer i
set AttributePoint[id] = AttributePoint[id] + amount
if AttributePoint[id] < 0 then
set AttributePoint[id] = 0
elseif AttributePoint[id] > 999 then
set AttributePoint[id] = 999
endif
call CharacterWindow_AttrValText[id][4].setText(I2S(AttributePoint[id]), FONTSTYLE_FrizQTShaded)
call CharacterWindow_AttrValText[id][4].move(-18-CharacterWindow_AttrValText[id][4].width/2, CharacterWindow_AttrValText[id][4].yOffset, 2)
call CharacterWindow_AttrValText[id][4].refresh()
set i = 0
loop
exitwhen i == 4
call CharacterWindow_AttrIncButton[id][i].show(AttributePoint[id] != 0)
call CharacterWindow_AttrIncButton[id][i].refresh()
set i = i + 1
endloop
if AttributePoint[id] > 0 then
call CharacterWindow_AttNotifBG[id].show(true)
call CharacterWindow_AttNotifText[id].show(true)
call CharacterWindow_AttNotifText[id].setText(I2S(AttributePoint[id]), FONTSTYLE_FrizQTShaded)
call CharacterWindow_AttNotifText[id].move(CharacterWindow_AttNotifBG[id].xOffset-CharacterWindow_AttNotifText[id].width/2., CharacterWindow_AttNotifBG[id].yOffset, CharacterWindow_AttNotifText[id].level)
call CharacterWindow_AttNotifBG[id].refresh()
call CharacterWindow_AttNotifText[id].refresh()
else
call CharacterWindow_AttNotifBG[id].show(false)
call CharacterWindow_AttNotifText[id].show(false)
endif
if AttributePoint[id] > 0 or SkillPoint[id] > 0 then
if UnitRemoveAbility(Controller[id], 'A006') and UnitAddAbility(Controller[id], 'A00C') then
endif
elseif AttributePoint[id] < 1 and SkillPoint[id] < 1 then
if UnitRemoveAbility(Controller[id], 'A00C') and UnitAddAbility(Controller[id], 'A006') then
endif
endif
endfunction
function AddAttPoints takes integer pid, integer index, integer amount returns boolean
local Combatant c = Combatant[MainUnit[pid]]
local ItemObject obj
local integer i
local integer j
local boolean b
local boolean result = true
if index == 0 then
if amount < 0 and -amount > Strength[pid] then // set minimum zero
set amount = -Strength[pid]
elseif Strength[pid] + amount > 999 then
set result = false
set amount = 999 - Strength[pid]
endif
if amount != 0 then
set Strength[pid] = Strength[pid] + amount
call CharacterWindow_AttrValText[pid][0].setText(I2S(Strength[pid]), FONTSTYLE_FrizQTShaded)
call CharacterWindow_AttrValText[pid][0].move((-80+51.0*0)-CharacterWindow_AttrValText[pid][0].width/2, CharacterWindow_AttrValText[pid][0].yOffset, 2)
call CharacterWindow_AttrValText[pid][0].refresh()
set c.physicDmgMin = c.physicDmgMin + 0.35*amount
set c.physicDmgMax = c.physicDmgMax + 0.35*amount
set c.criticalPower = c.criticalPower + 0.001*amount
endif
elseif index == 1 then
if amount < 0 and -amount > Dexterity[pid] then
set amount = -Dexterity[pid]
elseif Dexterity[pid] + amount > 999 then
set result = false
set amount = 999 - Dexterity[pid]
endif
if amount != 0 then
set Dexterity[pid] = Dexterity[pid] + amount
call CharacterWindow_AttrValText[pid][1].setText(I2S(Dexterity[pid]), FONTSTYLE_FrizQTShaded)
call CharacterWindow_AttrValText[pid][1].move((-80+51.0*1)-CharacterWindow_AttrValText[pid][1].width/2, CharacterWindow_AttrValText[pid][1].yOffset, 2)
call CharacterWindow_AttrValText[pid][1].refresh()
set c.criticalRate = c.criticalRate + 0.0015*amount
set c.evasionRate = c.evasionRate + 0.0015*amount
//set c.blockRate = c.blockRate + 0.0015*amount
endif
elseif index == 2 then
if amount < 0 and -amount > Wisdom[pid] then
set amount = -Wisdom[pid]
elseif Wisdom[pid] + amount > 999 then
set result = false
set amount = 999 - Wisdom[pid]
endif
if amount != 0 then
set Wisdom[pid] = Wisdom[pid] + amount
call CharacterWindow_AttrValText[pid][2].setText(I2S(Wisdom[pid]), FONTSTYLE_FrizQTShaded)
call CharacterWindow_AttrValText[pid][2].move((-80+51.0*2)-CharacterWindow_AttrValText[pid][2].width/2, CharacterWindow_AttrValText[pid][2].yOffset, 2)
call CharacterWindow_AttrValText[pid][2].refresh()
set c.magicDmgMin = c.magicDmgMin + 0.3*amount
set c.magicDmgMax = c.magicDmgMax + 0.3*amount
set c.spMax = c.spMax + 3.0*amount
call Regeneration.add(MainUnit[pid], false, 0.025*amount)
endif
elseif index == 3 then
if amount < 0 and -amount > Fortitude[pid] then
set amount = -Fortitude[pid]
elseif Fortitude[pid] + amount > 999 then
set result = false
set amount = 999 - Fortitude[pid]
endif
if amount != 0 then
set Fortitude[pid] = Fortitude[pid] + amount
call CharacterWindow_AttrValText[pid][3].setText(I2S(Fortitude[pid]), FONTSTYLE_FrizQTShaded)
call CharacterWindow_AttrValText[pid][3].move((-80+51.0*3)-CharacterWindow_AttrValText[pid][3].width/2, CharacterWindow_AttrValText[pid][3].yOffset, 2)
call CharacterWindow_AttrValText[pid][3].refresh()
set c.physicDefense = c.physicDefense + 0.33*amount
set c.hpMax = c.hpMax + 10.0*amount
call Regeneration.add(MainUnit[pid], true, 0.0425*amount)
endif
endif
if amount != 0 then
if Tooltips1[pid].control.visible then
if Tooltips1[pid].itmObject != 0 then
call Tooltips1[pid].setItem(Tooltips1[pid].itmObject)
elseif Tooltips1[pid].skill != 0 then
call Tooltips1[pid].setSkill(Tooltips1[pid].skill)
endif
endif
if amount < 0 then
if c.hp > c.hpMax then
set c.hp = c.hpMax
endif
if c.sp > c.spMax then
set c.sp = c.spMax
endif
if not IsDataLoading then
set i = 1
loop
exitwhen i > 10
set b = true
//set SlotObject[pid][i] = content.object
if CharacterWindow_SlotObject[pid][i] != 0 then
if b and CharacterWindow_SlotObject[pid][i].id.reqStrength != 0 then
if Strength[pid] < CharacterWindow_SlotObject[pid][i].id.reqStrength then
set b = false
endif
endif
if b and CharacterWindow_SlotObject[pid][i].id.reqDexterity != 0 then
if Dexterity[pid] < CharacterWindow_SlotObject[pid][i].id.reqDexterity then
set b = false
endif
endif
if b and CharacterWindow_SlotObject[pid][i].id.reqWisdom != 0 then
if Wisdom[pid] < CharacterWindow_SlotObject[pid][i].id.reqWisdom then
set b = false
endif
endif
if b and CharacterWindow_SlotObject[pid][i].id.reqFortitude != 0 then
if Fortitude[pid] < CharacterWindow_SlotObject[pid][i].id.reqFortitude then
set b = false
endif
endif
if not b then
//call CharacterWindow_Detach(pid, i)
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 10., RarityColor[CharacterWindow_SlotObject[pid][i].id.rarity] + CharacterWindow_SlotObject[pid][i].id.name + "|r has been detached due to insufficient requirement(s).")
if not Bag[pid].addItem(CharacterWindow_SlotObject[pid][i]) then
call CharacterWindow_SlotObject[pid][i].move(GetUnitX(MainUnit[pid]), GetUnitY(MainUnit[pid]))
call CharacterWindow_SlotObject[pid][i].show(true)
endif
set obj = CharacterWindow_SlotObject[pid][i]
set CharacterWindow_SlotObject[pid][i] = 0
set CharacterWindow_Slot[pid][i].texture = 'BSAL'
call CharacterWindow_Slot[pid][i].show(false)
call CharacterWindow_SlotRarity[pid][i].show(false)
//call CharacterWindow_OpenContext(pid, false)
if CharacterWindow_ContextVisible[pid] and CharacterWindow_SelectIndex[pid] == i then
set CharacterWindow_ContextVisible[pid] = false
call CharacterWindow_ContextMenu[i].move(CharacterWindow_CONTEXT_X_CLOSE, CharacterWindow_ContextMenu[i].yOffset, CharacterWindow_ContextMenu[i].level)
set CharacterWindow_SelectIndex[pid] = 0
call CharacterWindow_Selection[pid].show(false)
call PauseTimer(CharacterWindow_UpdateTimer[i])
set j = 0
loop
exitwhen j == 4
call CharacterWindow_ContextButton[pid][j].show(false)
set j = j + 1
endloop
call CharacterWindow_ContextMenu[pid].refresh()
endif
call Inventory.RemoveBonus(Combatant[MainUnit[pid]], obj)
//
endif
endif
set i = i + 1
endloop
endif
endif
endif
return result
endfunction
endlibrary
library CombatSystem uses Mouse, TimerUtils, ExpSystem, Missile, BUSChannel, CameraShaker, MouseUtils, CreepSfx, DamageText, CreepDeathHandler
globals
boolean CanReflect = true
boolean StealHP = true
boolean StealSP = true
boolean IsCriticalDamage = false
private timer array DPSTimer
private real array DamageTotal
private integer array DamageCount
private group Group = CreateGroup()
private group Group2 = CreateGroup()
endglobals
function CalculateTextTagWidth takes string s returns real
local real result = 0.0
local integer i = 0
local integer t = StringLength(s)
return 0.
loop
exitwhen i == t
//set result = result + LoadReal(PanelTextEx.FontData, FONTSTYLE_FrizQTShaded+1, Char2Ascii(SubString(s, i, i+1)))
set i = i + 1
endloop
return result*0.5
endfunction
public function CalculateConstantDamage takes Combatant s, Combatant t, real amount, boolean isPhysic returns real
local integer level1
local integer level2
local integer diff
local real result = 0
local real amt
set IsCriticalDamage = false
if isPhysic then
set amt = (amount*PHYSIC_DAMAGE_MULTIPLIER-t.physicDefense*PHYSIC_ARMOR_MULTIPLIER)
if amt > 0 then
set result = result + amt
endif
else
set amt = (amount*MAGIC_DAMAGE_MULTIPLIER-t.magicDefense*MAGIC_ARMOR_MULTIPLIER)
if amt > 0 then
set result = result + amt
endif
endif
if s.criticalRate > 0 then
if IsUnitInGroup(s.u, MainGroup) then
set level1 = Level[s.pid]
else
set level1 = s.level
endif
if IsUnitInGroup(t.u, MainGroup) then
set level2 = Level[t.pid]
else
set level2 = t.level
endif
set diff = level1-level2
if diff > 10 then
set diff = 10
elseif diff < -10 then
set diff = -10
endif
if GetRandomReal(0.000, 1.000) <= s.criticalRate*(1.-(10.-I2R(diff))/20.) then
set result = result * (1. + s.criticalPower)
set IsCriticalDamage = true
//call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\CriticalHit.mdx", t.u, "chest"))
call CriticalHit[GetRandomInt(0, 2)].play(GetUnitX(s.u), GetUnitY(s.u), PanelCore_GetUnitZ(s.u), 150)
if IsUnitInGroup(s.u, MainGroup) then
call CameraShaker_StartH(s.pid, 10, 0.2)
endif
endif
endif
return result
endfunction
public function CalculateDamage takes Combatant s, Combatant t returns real
local integer level1
local integer level2
local integer diff
local real result = 0
local real amt
set IsCriticalDamage = false
set amt = (GetRandomReal(s.physicDmgMin, s.physicDmgMax)*PHYSIC_DAMAGE_MULTIPLIER-t.physicDefense*PHYSIC_ARMOR_MULTIPLIER)
if amt > 0 then
set result = result + amt
endif
set amt = (GetRandomReal(s.magicDmgMin, s.magicDmgMax)*MAGIC_DAMAGE_MULTIPLIER-t.magicDefense*MAGIC_ARMOR_MULTIPLIER)
if amt > 0 then
set result = result + amt
endif
if s.criticalRate > 0 then
if IsUnitInGroup(s.u, MainGroup) then
set level1 = Level[s.pid]
else
set level1 = s.level
endif
if IsUnitInGroup(t.u, MainGroup) then
set level2 = Level[t.pid]
else
set level2 = t.level
endif
set diff = level1-level2
if diff > 10 then
set diff = 10
elseif diff < -10 then
set diff = -10
endif
if GetRandomReal(0.000, 1.000) <= s.criticalRate*(1.-(10.-I2R(diff))/20.) then
set result = result * (1. + s.criticalPower)
set IsCriticalDamage = true
//call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\CriticalHit.mdx", t.u, "chest"))
call CriticalHit[GetRandomInt(0, 2)].play(GetUnitX(s.u), GetUnitY(s.u), PanelCore_GetUnitZ(s.u), 150)
if IsUnitInGroup(s.u, MainGroup) then
call CameraShaker_StartH(s.pid, 10, 0.2)
endif
endif
endif
return result
endfunction
private function displayDialog takes nothing returns nothing
local timer t = GetExpiredTimer()
call Revive_ShowDialog(Player(GetTimerData(t)))
call ReleaseTimer(t)
set t = null
endfunction
private function DPS takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
call DamageText_Show(I2S(R2I(DamageTotal[id]/5.)), id, gg_unit_h002_0010, 255, 0, 240, TEXTTAG_DPS_SIZE)
set DamageTotal[id] = 0
set DamageCount[id] = 0
set DPSTimer[id] = null
call ReleaseTimer(t)
set t = null
endfunction
private function ResetTimeScale takes nothing returns nothing
local Combatant c = GetTimerData(GetExpiredTimer())
call SetUnitTimeScale(c.u, 1)
call ReleaseTimer(GetExpiredTimer())
endfunction
private function revivePet takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
call c.revive()
call SetUnitPosition(c.u, GetUnitX(MainUnit[c.pid]), GetUnitY(MainUnit[c.pid]))
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\Awaken\\Awaken.mdl", GetUnitX(c.u), GetUnitY(c.u)))
call ReleaseTimer(t)
set c.reviveTimer = null
set t = null
endfunction
public function Damage takes unit s, unit u, real amount, boolean play, boolean knock, boolean applyEffects returns nothing
local CreepAI ai
local CompanionAI cai
local HumanoidAI hai
local Combatant c = Combatant[u]
local Combatant cs = Combatant[s]
local integer level1
local integer level2
local integer level
local integer tier
local integer diff
local integer id
local integer i
local real a
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local unit fog
local real xp
local real xp2
local real dp
local real amt
local group gr = null
local group gr2
local boolean alertTarget
if IsUnitAlive(u) then
if c.isInvulnerable then
return
endif
// Alert summoned units
if FirstOfGroup(c.subordinate) != null then
set gr = c.subordinate
set alertTarget = true
elseif FirstOfGroup(cs.subordinate) != null then
set gr = cs.subordinate
set alertTarget = false
endif
if gr != null then
set gr2 = CreateGroup()
loop
set fog = FirstOfGroup(gr)
exitwhen fog == null
call GroupRemoveUnit(gr, fog)
call GroupAddUnit(gr2, fog)
if CompanionAI[fog] > 0 then
set cai = CompanionAI[fog]
if cai.target <= 0 or cai.combatModeDur <= 0 then
if cai.combatModeDur < 3.0 then
set cai.combatModeDur = 3.0
endif
if alertTarget then
set cai.target = cs
else
set cai.target = c
endif
endif
elseif HumanoidAI[fog] > 0 then
set hai = HumanoidAI[fog]
if hai.target <= 0 or hai.combatModeDur <= 0 then
if hai.combatModeDur < 3.0 then
set hai.combatModeDur = 3.0
endif
if alertTarget then
set hai.target = cs
else
set hai.target = c
endif
endif
endif
endloop
if alertTarget then
set c.subordinate = gr2
else
set cs.subordinate = gr2
endif
call DestroyGroup(gr)
set gr = null
set gr2 = null
endif
if applyEffects then
if c.blockRate > 0 and c.uid == 'h004' then
if IsUnitInGroup(s, MainGroup) then
set level1 = Level[cs.pid]
else
set level1 = cs.level
endif
if IsUnitInGroup(u, MainGroup) then
set level2 = Level[c.pid]
else
set level2 = c.level
endif
set diff = level1-level2
if diff > 10 then
set diff = 10
elseif diff < -10 then
set diff = -10
endif
if GetRandomReal(0.000, 1.000) <= c.blockRate*((10.-I2R(diff))/20.) then
call DamageText_Show("BLOCK", cs.pid, u, 175, 175, 175, TEXTTAG_NORMAL_SIZE)
call UnitDamageTarget(s, u, 100, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_ACID, WEAPON_TYPE_WOOD_LIGHT_BASH)
return
endif
endif
if (c.evasionRate + Blindness.TotalAmount[cs]) > cs.accuracy then
if GetRandomReal(0.000, 1.000) <= c.evasionRate - cs.accuracy + Blindness.TotalAmount[cs] then
call DamageText_Show("MISS", cs.pid, u, 157, 224, 27, TEXTTAG_NORMAL_SIZE)
return
endif
endif
endif
// if being tranquilized/asleep
if c.hasBuff(15) then
set TranquilizerHitCount[c] = TranquilizerHitCount[c] - 1
if TranquilizerHitCount[c] <= 0 then
call c.removeBuff(15) // Awake
endif
endif
// If has damage amplification
if AmplifyDamage.IsRegistered[c] then
set amount = amount * AmplifyDamage.Taken[c]
endif
if AmplifyDamage.IsRegistered[cs] then
set amount = amount * AmplifyDamage.Dealt[cs]
endif
if CanReflect and c.dmgReflect > 0 then
set CanReflect = false
if c.dmgReflect > amount then
set amount = 0
call Damage(u, s, amount, false, false, false)
else
set amount = amount - c.dmgReflect
call Damage(u, s, c.dmgReflect, false, false, false)
endif
endif
if c.dmgProtection > 0 and amount > 0 then
if c.dmgProtection > amount then
set c.dmgProtection = c.dmgProtection - amount
call DamageBlock.damage(c, amount)
set amount = 0
else
call DamageBlock.damage(c, c.dmgProtection)
set amount = amount - c.dmgProtection
set c.dmgProtection = 0
endif
endif
if c.owner == CREEP_PLAYER then
if c.destructible and IsUnitAlive(c.u) then
call SetUnitAnimation(c.u, "stand")
call SetUnitAnimation(c.u, "hit")
call QueueUnitAnimation(c.u, "stand")
endif
if c.hitsToKill then
set c.hp = c.hp - 1.0
elseif (c.u == gg_unit_h002_0010 and cs.pid <= 3) then
set DamageTotal[cs.pid] = DamageTotal[cs.pid] + (amount*(1.-(I2R(PlayerCount-1)/3.*PLAYER_COUNT_DAMAGE_PENALTY)))
set DamageCount[cs.pid] = DamageCount[cs.pid] + 1
if (DPSTimer[cs.pid] == null) then
set DPSTimer[cs.pid] = NewTimerEx(cs.pid)
call TimerStart(DPSTimer[cs.pid], 5, false, function DPS)
endif
elseif not c.ignoreDamage then
set c.hp = c.hp - amount*(1.-(I2R(PlayerCount-1)/3.*PLAYER_COUNT_DAMAGE_PENALTY))
endif
call MiniHealthBar_Show(cs.owner, c, c.hp/c.hpMax)
set ai = CreepAI[c.u]
call ai.damage(cs, amount)
else
set c.hp = c.hp - amount
if not IsUnitInGroup(u, MainGroup) then
call MiniHealthBar_Show(c.owner, c, c.hp/c.hpMax)
endif
endif
if c.hp > 0 then
if applyEffects then
if not c.destructible and GetUnitAbilityLevel(u, 'Amov') > 0 then
if StealHP and cs.hpSteal > 0 then
set c.hp = c.hp - cs.hpSteal
if c.hp < 1 then
set c.hp = 1
endif
set cs.hp = cs.hp + cs.hpSteal
if cs.hp > cs.hpMax then
set cs.hp = cs.hpMax
endif
call DamageText_Show(I2S(R2I(cs.hpSteal)), 0, cs.u, HEAL_R, HEAL_G, HEAL_B, TEXTTAG_NORMAL_SIZE)
endif
if StealSP and cs.spSteal > 0 then
set c.sp = c.sp - cs.spSteal
if c.sp < 0 then
set c.sp = 0
endif
set cs.sp = cs.sp + cs.spSteal
if cs.sp > cs.spMax then
set cs.sp = cs.spMax
endif
call DamageText_Show(I2S(R2I(cs.spSteal)), 0, cs.u, MANA_R, MANA_G, MANA_B, TEXTTAG_NORMAL_SIZE)
endif
endif
set StealHP = true
set StealSP = true
if cs.interrupt-c.interruptResist > 0 then
if GetRandomReal(0.000, 1.000) <= cs.interrupt-c.interruptResist then
call IssueImmediateOrder(u, "stop")
call SetUnitAnimation(u, "ready")
call QueueUnitAnimation(u, "stand")
call c.interruption()
endif
endif
if cs.stun-c.stunResist > 0 then
if GetRandomReal(0.000, 1.000) <= cs.stun-c.stunResist then
call IssueImmediateOrder(u, "stop")
call SetUnitAnimation(u, "stand")
call c.applyStun(1, MINISTUN_DURATION, AddSpecialEffectTarget("Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl", u, "overhead"))
endif
endif
if knock and cs.knockback-c.knockbackResist > 0 then
call Knockback.create(u, Atan2(y-GetUnitY(s), x-GetUnitX(s)), cs.knockback-c.knockbackResist, 10.0, false)
endif
if cs.melee and c.hasBuff(2) then // has "counter attack" buff
if GetRandomReal(0, 1) <= CounterAttackTriggerChance(c.pid) then
call DamageText_Show("COUNTER", cs.pid, u, 255, 108, 0, TEXTTAG_NORMAL_SIZE)
if IsUnitAlive(c.u) then
call IssueImmediateOrder(c.u, "stop")
if not c.isDisarmed and not c.isStunned and not c.isAttacking and GetUnitCurrentOrder(c.u) != 851986 then
set dp = c.dmgPoint*(c.attackRate/c.attackRateDef)*0.25
set DoubleCrashMissile.create(c.u).factor = false
call SetUnitTimeScale(c.u, c.attackRateDef/c.attackRate*4)
set DoubleCrashAnimDex[c] = 4
call SetUnitAnimationByIndex(c.u, DoubleCrashAnimDex[c])
call QueueUnitAnimation(c.u, "ready")
call QueueUnitAnimation(c.u, "stand")
call TimerStart(NewTimerEx(c), dp, false, function ResetTimeScale)
call c.immobilize(0, dp, null)
endif
endif
return
endif
endif
if cs.hasBuff(9) and not c.hasBuff(10) then // has "corrupted blade" buff
call StatusBonus.create(c.u, 1, -CorruptedBladePhysicArmorReduction(cs.pid), 10, 10)
call c.applyBuff(10, 10, AddSpecialEffectTarget("war3mapImported\\ArmorCorruption.mdx", c.u, "overhead"))
endif
if cs.hasBuff(13) and not c.hasBuff(14) then // has "poison attack"
call StatusBonus.create(c.u, 6, -GetUnitMoveSpeed(c.u)*0.2, 5.0, 14)
call PeriodicDamage.create(cs.u, c.u, amount*0.15, 1.0, 5.0, 14)
call c.applyBuff(14, 5, AddSpecialEffectTarget("Abilities\\Weapons\\PoisonSting\\PoisonStingTarget.mdl", c.u, "chest"))
endif
if cs.hasBuff(19) and not c.hasBuff(30) then // has Poison Coating
if GetRandomReal(0.000, 1.000) < PoisonCoatingChance(c.pid) then
call PeriodicDamage.create(cs.u, c.u, PoisonCoatingDamage(c.pid), 1.0, 5.0, 30)
call c.applyBuff(30, 5.0, AddSpecialEffectTarget("Abilities\\Weapons\\PoisonSting\\PoisonStingTarget.mdl", c.u, "chest"))
endif
endif
if IsUnitInGroup(cs.u, MainGroup) or (cs.owner == CREEP_PLAYER and cs.dropQuality > 1) then
// Apply fire element
if cs.fireElement > 0.0 and GetRandomReal(0.0, 100.0) < cs.fireElement+c.earthElement*WEAK_ELEMENT_FACTOR-c.waterElement and not c.hasBuff(27) then
call PeriodicDamage.create(cs.u, c.u, amount*0.15, 1.0, 5.0, 27)
call c.applyBuff(27, 5, AddSpecialEffectTarget("war3mapImported\\Burning Core.mdx", c.u, "chest"))
endif
// Apply water element
if cs.waterElement > 0.0 and GetRandomReal(0.0, 100.0) < cs.waterElement+c.fireElement*WEAK_ELEMENT_FACTOR-c.windElement and not c.hasBuff(28) then
call StatusBonus.create(c.u, 6, -GetUnitMoveSpeed(c.u)*0.4, 5.0, 28)
call c.applyBuff(28, 5.0, AddSpecialEffectTarget("war3mapImported\\ColdBuff.mdx", c.u, "chest"))
endif
// Apply earth element
if cs.earthElement > 0.0 and GetRandomReal(0.0, 100.0) < cs.earthElement+c.windElement*WEAK_ELEMENT_FACTOR-c.fireElement and not c.hasBuff(29) then
if IsUnitInGroup(cs.u, MainGroup) then
set level = Level[cs.pid]
set tier = 3
else
set level = cs.level
if cs.owner == CREEP_PLAYER then
set tier = cs.dropQuality
else
set tier = 3
endif
endif
call StatusBonus.create(c.u, 1, -CorrosionPhysicArmorReduction(tier, level), 10.0, 29)
call StatusBonus.create(c.u, 4, -CorrosionMagicArmorReduction(tier, level), 10.0, 29)
call c.applyBuff(29, 10.0, AddSpecialEffectTarget("Abilities\\Spells\\Other\\AcidBomb\\BottleImpact.mdl", c.u, "chest"))
endif
// Apply wind element
if cs.windElement > 0.0 and GetRandomReal(0.0, 100.0) < cs.windElement+c.waterElement*WEAK_ELEMENT_FACTOR-c.earthElement then
set i = 0
loop
exitwhen i >= 6
call ShockMissile.create(cs, GetUnitX(c.u), GetUnitY(c.u), 60.*i+GetRandomReal(-15., 15.), amount, c.u, "war3mapImported\\LightningShockMissile.mdx")
set i = i + 1
endloop
endif
endif
endif
endif
if play and cs.wType != WEAPON_TYPE_WHOKNOWS then
call UnitDamageTarget(s, u, 1, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_ACID, cs.wType)
endif
if CanReflect then
if IsCriticalDamage then
call DamageText_Show(I2S(R2I(amount)), 0, u, CRIT_DAMAGE_R, CRIT_DAMAGE_G, CRIT_DAMAGE_B, TEXTTAG_CRITICAL_SIZE)
else
call DamageText_Show(I2S(R2I(amount)), 0, u, NORMAL_DAMAGE_R, NORMAL_DAMAGE_G, NORMAL_DAMAGE_B, TEXTTAG_NORMAL_SIZE)
endif
else
call DamageText_Show(I2S(R2I(amount)), 0, u, REFLECT_R, REFLECT_G, REFLECT_B, TEXTTAG_NORMAL_SIZE)
endif
if c.hp <= 0 then
call c.purgeBuff()
if c.attackRateDef > 0 and cs.hasBuff(12) then
set SoulboundMissile.Target[cs] = c.u
call SoulboundMissile.create(cs)
endif
if c.owner == CREEP_PLAYER then
if cs.pid <= 3 then
set xp = (10*(1.+0.02*(c.level-1)))*c.xpMultiplier
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] and IsUnitAlive(MainUnit[i]) and IsUnitInRangeXY(MainUnit[i], x, y, EXP_SHARE_RANGE) then
if c.level < Level[i] then
if Level[i]-c.level <= 10 then
set xp2 = xp * (1.-I2R(Level[i]-c.level)/15.)
if xp2 < 0 then
set xp2 = 0.
endif
else
set xp2 = 0.
endif
else
set xp2 = xp
endif
call AddEXP(i, xp2)
endif
set i = i + 1
endloop
endif
elseif Departing and InDungeon then
set Departing = false
set ReadyCount = 0
call DialogDisplay(Locale, StairDownDialog, false)
call DisplayTimedTextToPlayer(Locale, 0, 0, 5., "Departure canceled. " + GetPlayerName(c.owner) + " got killed.")
endif
if IsUnitInGroup(u, MainGroup) then
if IsUnitAlive(PetFighter[c.pid].u) then
call PetFighter[c.pid].kill()
elseif PetFighter[c.pid].reviveTimer != null then
call ReleaseTimer(PetFighter[c.pid].reviveTimer)
set PetFighter[c.pid].reviveTimer = null
endif
call TimerStart(NewTimerEx(c.pid), 3.0, false, function displayDialog)
endif
if c.noRemove then
call c.kill()
if c.owner == CREEP_PLAYER then
call GroupAddUnit(Combatant.RemoveLater, u)
endif
if IsUnitInGroup(u, PlayerUnits) and not IsUnitInGroup(u, MainGroup) then
set c.reviveTimer = NewTimerEx(c)
call TimerStart(c.reviveTimer, 30, false, function revivePet)
endif
else
call KillUnit(u)
endif
if c.destToRemove != null then
call RemoveDestructable(c.destToRemove)
endif
if c.owner == CREEP_PLAYER then
call OnCreepDead(c.u)
call c.destroy()
endif
set c.hp = 0
set c.sp = 0
endif
set CanReflect = true
endif
endfunction
//! runtextmacro GenericSkillLib()
//! runtextmacro SkillLib()
//! runtextmacro SkillLib2()
struct ResetDummy
unit dummy
static real MapEdgeX
static real MapEdgeY
private static method onExpire takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
call SetUnitX(.dummy, MapEdgeX)
call SetUnitY(.dummy, MapEdgeY)
call SetUnitScale(.dummy, 1, 1, 1)
call destroy()
set .dummy = null
call ReleaseTimer(t)
set t = null
endmethod
static method reset takes unit whichUnit returns nothing
local thistype this = create()
set .dummy = whichUnit
call TimerStart(NewTimerEx(this), 5.0, false, function thistype.onExpire)
endmethod
static method onInit takes nothing returns nothing
set MapEdgeX = GetRectMaxX(bj_mapInitialPlayableArea)
set MapEdgeY = GetRectMaxY(bj_mapInitialPlayableArea)
endmethod
endstruct
struct UnitMissile
Missile missile
Combatant c
boolean decay
boolean piercing
boolean homing
boolean targetExclusive
boolean finalDamage
real dist
real factor
real dmgBonus
private static group Group = CreateGroup()
static method onRemove takes Missile missile returns boolean
local thistype this = missile.data
local real damage
local unit u
if c.dmgAoE > 0 then
call GroupEnumUnitsInRange(Group, missile.x, missile.y, c.dmgAoE, null)
loop
set u = FirstOfGroup(Group)
exitwhen u == null
call GroupRemoveUnit(Group, u)
if (u == missile.target or not .targetExclusive) and IsUnitEnemy(u, c.owner) and IsUnitAlive(u) and not missile.hasHitWidget(u) then
call missile.hitWidget(u)
if .finalDamage then
set damage = missile.damage*.factor+.dmgBonus
else
set damage = CalculateDamage(c, Combatant[u])*.factor+.dmgBonus
call Damage(missile.source, u, damage, true, true, true)
endif
endif
endloop
endif
call ResetDummy.reset(missile.dummy)
return .decay
endmethod
static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = missile.data
local real damage
local Combatant targ
if (hit == missile.target or not .targetExclusive) and IsUnitEnemy(hit, missile.owner) and IsUnitAlive(hit) then
call missile.hitWidget(hit)
set targ = Combatant[hit]
if ReflectMissile.TotalAmount[targ] > 0 and GetRandomReal(0.000, 1.000) <= ReflectMissile.TotalAmount[targ] then
set damage = CalculateDamage(c, targ)*.factor+.dmgBonus
call reflect(hit, missile, damage*ReflectMissile.getDamageFactor(targ))
set .decay = false
return true
else
if .finalDamage then
set damage = missile.damage*.factor+.dmgBonus
else
set damage = CalculateDamage(c, targ)*.factor+.dmgBonus
// Has compact bolt buff
if c.hasBuff(18) then
set damage = damage + CalculateConstantDamage(c, targ, CompactBoltDamage(c.pid) * I2R(R2I(missile.distance/UNITS_PER_METER)), true)
endif
endif
call Damage(missile.source, hit, damage, true, true, true)
//call DestroyEffect(AddSpecialEffect(missile.model, missile.x, missile.y))
return not .piercing
endif
endif
return false
endmethod
static method onPeriod takes Missile missile returns boolean
local thistype this = missile.data
local real a
local real damage
local unit reflector
if .homing then
set a = Atan2(GetUnitY(missile.target)-missile.y, GetUnitX(missile.target)-missile.x)
set a = RAbsBJ(PanelCore_AngularDifference(a, missile.angle))
if a > PanelCore_HP then
set missile.turn = missile.turn/2.
set .homing = false
endif
endif
set reflector = ForceWall.IsReflectMissile(missile.dummy, missile.source)
if reflector != null then
set damage = CalculateDamage(c, Combatant[reflector])
call reflect(reflector, missile, damage*0.5)
set .decay = false
return true
endif
return missile.distance >= .dist
endmethod
implement MissileStruct
static method create takes unit whichUnit returns thistype
local thistype this = allocate()
local player p = GetOwningPlayer(whichUnit)
local real a = GetUnitFacing(whichUnit)*bj_DEGTORAD
local real x
local real y
local real z = GetUnitFlyHeight(whichUnit)
local real da
local real dax
local unit u
set c = Combatant[whichUnit]
set x = GetUnitX(whichUnit) + c.missileXY * Cos(a)
set y = GetUnitY(whichUnit) + c.missileXY * Sin(a)
if c.missileArch > 0 then
set .missile = Missile.create(x, y, z+c.missileZ, a, c.attackRange, 0)
else
set .missile = Missile.create(x, y, z+c.missileZ, a, c.attackRange, z+c.missileZ)
endif
set .decay = true
set .targetExclusive = false
set .finalDamage = false
set .factor = 1.
set .dmgBonus = 0.
set .missile.source = whichUnit
set .missile.owner = p
if StringLength(c.missile2) > 0 and c.missile2 != null then
set .missile.attachment = c.missile2
endif
set .missile.model = c.missile
set .missile.speed = c.missileSpeed
set .missile.scale = c.missileScale
set .missile.turn = c.missileTurn
set .missile.arc = c.missileArch
set .missile.collision = c.missileCollision
set .missile.data = this
set .homing = c.missileHoming
set .piercing = c.missilePiercing
set .dist = c.attackRange
if c.missileHoming then
if CreepAI[whichUnit] > 0 then
set .missile.target = CreepAI[whichUnit].target
else
set dax = 90*bj_DEGTORAD
call GroupEnumUnitsInRange(Group, x, y, c.attackRange, null)
loop
set u = FirstOfGroup(Group)
exitwhen u == null
call GroupRemoveUnit(Group, u)
if IsUnitEnemy(u, p) and IsUnitVisible(u, p) and IsUnitAlive(u) then
set da = Atan2(GetUnitY(u)-y, GetUnitX(u)-x)
set da = RAbsBJ(PanelCore_AngularDifference(da, a))
if da < dax then
set da = dax
set .missile.target = u
endif
endif
endloop
endif
endif
call launch(.missile)
return this
endmethod
static method reflect takes unit whichUnit, Missile m, real damage returns thistype
local thistype this = allocate()
local player p = GetOwningPlayer(whichUnit)
local real a = Atan2(GetUnitY(m.source) - m.y, GetUnitX(m.source) - m.x)
local real x
local real y
local real z = GetUnitFlyHeight(whichUnit)
local real da
local real dax
local unit u
local Combatant c2 = Combatant[m.source]
set c = Combatant[whichUnit]
set x = m.x
set y = m.y
if c.missileArch > 0 then
set .missile = Missile.create(x, y, m.z, a, c2.attackRange, 0)
else
set .missile = Missile.create(x, y, m.z, a, c2.attackRange, z+c2.missileZ)
endif
set .decay = true
set .targetExclusive = true
set .finalDamage = true
set .factor = 1.
set .dmgBonus = 0.
set .missile.source = whichUnit
set .missile.target = m.source
set .missile.owner = p
if StringLength(c2.missile2) > 0 and c2.missile2 != null then
set .missile.attachment = c2.missile2
endif
set .missile.model = m.model
set .missile.speed = m.speed
set .missile.scale = m.scale
set .missile.damage = damage
set .missile.turn = m.turn
set .missile.arc = m.arc
set .missile.collision = m.collision
set .missile.data = this
set .homing = thistype(m.data).homing
set .piercing = thistype(m.data).piercing
set .dist = thistype(m.data).dist
call launch(.missile)
return this
endmethod
endstruct
private struct CombatantBuff extends array
Combatant c
Buff bff
effect sfx
timer t
implement LinkedList
endstruct
struct Combatant
readonly unit u
readonly integer data
readonly integer pid
readonly integer uid
readonly player owner
// Creep stats
integer dropQuality
destructable destToRemove
integer channeledSkill
integer level
boolean hitsToKill
boolean noRemove
boolean destructible
boolean ignoreDamage
boolean isChanneling
boolean melee
boolean missileHoming
boolean missilePiercing
boolean isIllusion
string missile
string missile2
real missileCollision
real missileSpeed
real missileArch
real missileTurn
real missileScale
real missileXY
real missileZ
real dmgPoint
real dmgAoE
real attackRadius
real attackRange
real attackRate
real attackRateDef
real physicDmgMin
real physicDmgMax
real physicDefense
real magicDmgMin
real magicDmgMax
real magicDefense
real physicReflect
real magicReflect
real dmgReflect
real blockRate
real criticalRate
real criticalPower
real evasionRate
real accuracy
real knockback
real knockbackResist
real interrupt
real interruptResist
real stun
real stunResist
real hp
real hpMax
real hpSteal
real sp
real spMax
real spSteal
real xpMultiplier
real dmgProtection
weapontype wType
real fireElement
real fireElementResist
real waterElement
real waterElementResist
real earthElement
real earthElementResist
real windElement
real windElementResist
real holyElement
real darkElement
real reflectRate
real reflectPower
effect upgradeSfx
effect upgradeSfx2
effect attachment
string attachSize
string attachPoint
timer silenceTimer
timer disarmTimer
timer immobileTimer
timer stunTimer
timer attackTimer
timer launchTimer
timer invulTimer
timer reviveTimer
group subordinate
string array onAttackSfxPath[4]
string array onAlertSfxPath[4]
//boolean array buffAvailable[BUFF_VARIATION_COUNT]
integer onAttackSfxCt
integer onAlertSfxCt
integer sfxId
integer skillCastIndex
real skillCastX
real skillCastY
real skillCastDistance
timer skillCastTimer
CombatantBuff buffs
Buff activeDisarm
Buff activeSilence
Buff activeImmobilize
Buff activeInvul
Buff activeStun
private static integer array UnitDex
static group RemoveLater = CreateGroup()
static method resetTimer takes nothing returns nothing
call TimerStart(GetExpiredTimer(), 0, false, null)
endmethod
method operator randomPhysicDamage takes nothing returns real
return GetRandomReal(physicDmgMin, physicDmgMax)
endmethod
method operator randomMagicDamage takes nothing returns real
return GetRandomReal(magicDmgMin, magicDmgMax)
endmethod
method operator isSilenced takes nothing returns boolean
return TimerGetRemaining(silenceTimer) > 0.01
endmethod
method operator isDisarmed takes nothing returns boolean
return TimerGetRemaining(disarmTimer) > 0.01
endmethod
method operator isImmobilized takes nothing returns boolean
return TimerGetRemaining(immobileTimer) > 0.01
endmethod
method operator isStunned takes nothing returns boolean
return TimerGetRemaining(stunTimer) > 0.01
endmethod
method operator isInvulnerable takes nothing returns boolean
return TimerGetRemaining(invulTimer) > 0.01
endmethod
method operator isAttacking takes nothing returns boolean
return TimerGetRemaining(launchTimer) > 0.0
endmethod
method operator isAttackReady takes nothing returns boolean
return TimerGetRemaining(attackTimer) <= 0.01
endmethod
method kill takes nothing returns nothing
if not IsUnitPaused(u) then
call UnitAddAbility(u, 'Aloc')
call SetUnitAnimation(u, "death")
call SetUnitPathing(u, false)
call PauseUnit(u, true)
endif
endmethod
method revive takes nothing returns nothing
if IsUnitPaused(u) then
call SetUnitAnimation(.u, "stand")
call UnitRemoveAbility(.u, 'Aloc')
call PauseUnit(.u, false)
call ShowUnit(.u, false)
call ShowUnit(.u, true)
call SetUnitPathing(u, true)
set .hp = .hpMax
set .sp = .spMax
endif
endmethod
method mobilize takes Buff b returns nothing
if activeImmobilize == b then
call TimerStart(immobileTimer, 0, false, null)
endif
endmethod
method unsilence takes Buff b returns nothing
if activeSilence == b then
call TimerStart(silenceTimer, 0, false, null)
endif
endmethod
method arm takes Buff b returns nothing
if activeDisarm == b then
call TimerStart(disarmTimer, 0, false, null)
endif
endmethod
method vulnerable takes Buff b returns nothing
if activeInvul == b then
call TimerStart(invulTimer, 0, false, null)
endif
endmethod
method removeStun takes Buff b returns nothing
if activeStun == b then
call TimerStart(stunTimer, 0, false, null)
endif
endmethod
method interruption takes nothing returns nothing
if not IsUnitAlive(.u) then
return
endif
if isChanneling then
call cast(channeledSkill, 0, 0, "")
endif
call TimerStart(launchTimer, 0, false, function thistype.resetTimer)
call IssueImmediateOrder(u, "stop")
call SetUnitAnimation(u, "stand")
endmethod
method silence takes Buff b, real duration, effect sfx returns nothing
if not IsUnitAlive(.u) then
return
endif
if GetUnitAbilityLevel(u, 'Amov') > 0 and not isInvulnerable then
if duration > TimerGetRemaining(silenceTimer) then
set activeSilence = b
call TimerStart(silenceTimer, duration, false, function thistype.resetTimer)
endif
if b > 0 then
call applyBuff(b, duration, sfx)
else
call DestroyEffectTimed(sfx, duration)
endif
else
call DestroyEffect(sfx)
endif
endmethod
method disarm takes Buff b, real duration, effect sfx returns nothing
if not IsUnitAlive(.u) then
return
endif
if GetUnitAbilityLevel(u, 'Amov') > 0 and not isInvulnerable then
call interruption()
if duration > TimerGetRemaining(disarmTimer) then
set activeDisarm = b
call TimerStart(disarmTimer, duration, false, function thistype.resetTimer)
endif
if b > 0 then
call applyBuff(b, duration, sfx)
else
call DestroyEffectTimed(sfx, duration)
endif
else
call DestroyEffect(sfx)
endif
endmethod
method immobilize takes Buff b, real duration, effect sfx returns nothing
if not IsUnitAlive(.u) then
return
endif
if GetUnitAbilityLevel(u, 'Amov') > 0 and not isInvulnerable then
call IssueImmediateOrder(u, "stop")
if duration > TimerGetRemaining(immobileTimer) then
set activeImmobilize = b
call TimerStart(immobileTimer, duration, false, function thistype.resetTimer)
endif
if b > 0 then
call applyBuff(b, duration, sfx)
elseif sfx != null then
call DestroyEffectTimed(sfx, duration)
endif
else
call DestroyEffect(sfx)
endif
endmethod
method invulnerable takes Buff b, real duration, effect sfx returns nothing
if not IsUnitAlive(.u) then
return
endif
if GetUnitAbilityLevel(u, 'Amov') > 0 and not isInvulnerable then
if duration > TimerGetRemaining(invulTimer) then
set activeInvul = b
call TimerStart(invulTimer, duration, false, function thistype.resetTimer)
endif
if b > 0 then
call applyBuff(b, duration, sfx)
elseif sfx != null then
call DestroyEffectTimed(sfx, duration)
endif
else
call DestroyEffect(sfx)
endif
endmethod
method applyStun takes Buff b, real duration, effect sfx returns nothing
if not IsUnitAlive(.u) then
return
endif
if GetUnitAbilityLevel(u, 'Amov') > 0 and not isInvulnerable and stunResist <= 10 then
call interruption()
if duration > TimerGetRemaining(stunTimer) then
set activeStun = b
call TimerStart(stunTimer, duration, false, function thistype.resetTimer)
endif
if b > 0 then
call applyBuff(b, duration, sfx)
elseif sfx != null then
call DestroyEffectTimed(sfx, duration)
endif
else
call DestroyEffect(sfx)
endif
endmethod
method removeBuffEffect takes Buff b returns nothing
if b == 1 then
call removeStun(b)
//elseif b == 2 then
elseif b == 3 then
call StatusBonus.cleanse(this, b)
elseif b == 4 then
call DamageBlock.cleanse(this, b)
//elseif b == 5 then
//elseif b == 6 then
elseif b == 7 then
call StatusBonus.cleanse(this, b)
elseif b == 8 then
call StatusBonus.cleanse(this, b)
call ReflectMissile.cleanse(this, b)
//elseif b == 9 then
elseif b == 10 then
call StatusBonus.cleanse(this, b)
elseif b == 11 then
call StatusBonus.cleanse(this, b)
//elseif b == 12 then
//elseif b == 13 then
elseif b == 14 then
call StatusBonus.cleanse(this, b)
call PeriodicDamage.cleanse(this, b)
elseif b == 15 then
call removeStun(b)
set TranquilizerHitCount[this] = 0
elseif b == 16 then
call StatusBonus.cleanse(this, b)
elseif b == 17 then
call StatusBonus.cleanse(this, b)
//elseif b == 18 then
//elseif b == 19 then
//elseif b == 20 then
elseif b == 21 then
call StatusBonus.cleanse(this, b)
call arm(b)
call unsilence(b)
elseif b == 22 then
call unsilence(b)
elseif b == 23 then
call Blindness.cleanse(this, b)
elseif b == 24 then
call StatusBonus.cleanse(this, b)
elseif b == 25 then
call AmplifyDamage.remove(this)
elseif b == 26 then
call StatusBonus.cleanse(this, b)
elseif b == 27 then
call PeriodicDamage.cleanse(this, b)
elseif b == 28 then
call StatusBonus.cleanse(this, b)
elseif b == 29 then
call StatusBonus.cleanse(this, b)
elseif b == 30 then
call PeriodicDamage.cleanse(this, b)
endif
endmethod
method getBuff takes Buff b returns CombatantBuff
local CombatantBuff node = .buffs.next
loop
exitwhen node.head or node == 0
if node.bff == b then
return node
endif
set node = node.next
endloop
return 0
endmethod
method hasBuff takes Buff b returns boolean
if IsUnitInGroup(.u, MainGroup) then
return BuffBars[pid].has(b)
else
return getBuff(b) != 0 //buffAvailable[b]
endif
endmethod
method applyBuff takes Buff b, real duration, effect sfx returns nothing
local CombatantBuff bff
if not IsUnitAlive(.u) then
return
endif
if hp > 0 then
if IsUnitInGroup(.u, MainGroup) then
call BuffBars[pid].addBuff(b, duration, false, true, sfx)
else
set bff = getBuff(b)
if bff == 0 then
set bff = CombatantBuff.allocate()
set bff.c = this
set bff.bff = b
//set buffAvailable[b] = true
call .buffs.insertNode(bff)
endif
if bff.sfx != null then
call DestroyEffect(bff.sfx)
endif
set bff.sfx = sfx
if (duration > 0) then
if bff.t == null then
set bff.t = NewTimerEx(bff)
endif
call TimerStart(bff.t, duration, false, function thistype.buffExpired)
elseif bff.t != null then
call ReleaseTimer(bff.t)
set bff.t = null
endif
endif
else
call DestroyEffect(sfx)
endif
endmethod
private method removeBuffNode takes CombatantBuff bff returns nothing
call removeBuffEffect(bff.bff)
if bff.sfx != null then
call DestroyEffect(bff.sfx)
set bff.sfx = null
endif
if bff.t != null then
call ReleaseTimer(bff.t)
set bff.t = null
endif
call bff.removeNode()
call bff.deallocate()
//set buffAvailable[bff.bff] = false
set bff.bff = 0
endmethod
method removeBuff takes Buff b returns nothing
if hasBuff(b) then
if IsUnitInGroup(.u, MainGroup) then
call BuffBars[.pid].removeBuff(b)
else
call removeBuffNode(getBuff(b))
endif
endif
endmethod
method purgeBuff takes nothing returns nothing
local CombatantBuff node
if IsUnitInGroup(.u, MainGroup) then
call BuffBars[.pid].removeAll()
else
set node = .buffs.next
loop
exitwhen node.head or node == 0
call removeBuffNode(node)
set node = node.next
endloop
endif
endmethod
private static method buffExpired takes nothing returns nothing
local timer t = GetExpiredTimer()
local CombatantBuff bf = GetTimerData(t)
local thistype this = bf.c
call removeBuffNode(bf)
set t = null
endmethod
static method recast takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local real x2 = GetUnitX(.u)
local real y2 = GetUnitY(.u)
if (x2-skillCastX)*(x2-skillCastX)+(y2-skillCastY)*(y2-skillCastY) <= skillCastDistance then
call IssueImmediateOrder(.u, "stop")
call cast(skillCastIndex, skillCastX, skillCastY, "")
call ReleaseTimer(skillCastTimer)
set skillCastTimer = null
endif
set t = null
endmethod
method cast takes integer spell, real x, real y, string anim returns nothing
local real a
local group gr
local unit fog
local real x2
local real y2
local boolean reveal
if not IsUnitAlive(.u) then
return
endif
if isChanneling then
if spell == channeledSkill then
if spell == 43 then
call LucidBeamCast(this)
endif
endif
else
set reveal = false
if spell != 43 then
call PlayerSkill(PlayerSkillData[pid][spell]).addMastery()
endif
if spell == 9 then
set reveal = true
call SetUnitFacing(.u, Atan2(y-GetUnitY(.u), x-GetUnitX(.u))*bj_RADTODEG)
call DoubleCrashCast(this)
elseif spell == 1 then
set reveal = true
call DeathBlowCast(this)
elseif spell == 3 then
set reveal = true
call TauntCast(this)
elseif spell == 10 then
set reveal = true
call CounterAttackCast(this)
elseif spell == 12 then
set reveal = true
call HolyShieldCast(this)
elseif spell == 2 then
set reveal = true
call RapidAttackCast(this)
elseif spell == 5 then
set reveal = true
call ForceBarrierCast(this)
elseif spell == 4 then
set reveal = true
call SolidifyCast(this)
elseif spell == 19 then
set reveal = true
call DreadfulHowlCast(this)
elseif spell == 20 then
set reveal = true
call SpectraVortexCast(this)
elseif spell == 17 then
set reveal = true
call SetUnitFacing(.u, Atan2(y-GetUnitY(.u), x-GetUnitX(.u))*bj_RADTODEG)
call DarknessClawCast(this)
elseif spell == 13 then
set reveal = true
set a = Atan2(y-GetUnitY(.u), x-GetUnitX(.u))
call SetUnitFacing(.u, a*bj_RADTODEG)
call AeroJabCast(this, a)
elseif spell == 43 then
set reveal = true
call SetUnitFacing(.u, Atan2(y-GetUnitY(.u), x-GetUnitX(.u))*bj_RADTODEG)
call LucidBeamCast(this)
elseif spell == 45 then
set reveal = true
call SetUnitFacing(.u, Atan2(y-GetUnitY(.u), x-GetUnitX(.u))*bj_RADTODEG)
call LunarStrikeCast(this)
elseif spell == 41 then
set reveal = true
call SetUnitFacing(.u, Atan2(y-GetUnitY(.u), x-GetUnitX(.u))*bj_RADTODEG)
call TripleShardCast(this)
elseif spell == 33 then
set reveal = true
call SetUnitFacing(.u, Atan2(y-GetUnitY(.u), x-GetUnitX(.u))*bj_RADTODEG)
call QuickShotCast(this)
elseif spell == 44 then
set reveal = true
call ForceWallCast(this)
elseif spell == 25 then
set reveal = true
call SetUnitFacing(.u, Atan2(y-GetUnitY(.u), x-GetUnitX(.u))*bj_RADTODEG)
call BouncingGlaiveCast(this)
elseif spell == 27 then
set reveal = true
call SetUnitFacing(.u, Atan2(y-GetUnitY(.u), x-GetUnitX(.u))*bj_RADTODEG)
call TranquilizerCast(this)
elseif spell == 34 then
set reveal = true
call FastReloadCast(this)
elseif spell == 36 then
set reveal = true
call AcuteSightCast(this)
elseif spell == 37 then
set reveal = true
call SetUnitFacing(.u, Atan2(y-GetUnitY(.u), x-GetUnitX(.u))*bj_RADTODEG)
call PrimalStrikeCast(this)
elseif spell == 28 then
set x2 = GetUnitX(.u)
set y2 = GetUnitY(.u)
set skillCastDistance = 400
if SquareRoot((x2-x)*(x2-x)+(y2-y)*(y2-y)) > skillCastDistance then
call IssuePointOrder(.u, "move", x, y)
if skillCastTimer != null then
call ReleaseTimer(skillCastTimer)
endif
set skillCastTimer = NewTimerEx(this)
set skillCastX = x
set skillCastY = y
set skillCastIndex = spell
set skillCastDistance = skillCastDistance * skillCastDistance
call TimerStart(skillCastTimer, 0.1, true, function thistype.recast)
else
set reveal = true
call SetUnitFacing(.u, Atan2(y-GetUnitY(.u), x-GetUnitX(.u))*bj_RADTODEG)
call SnaringTrapCast(this, x, y)
endif
elseif spell == 21 then
set reveal = true
call NightmareFallCast(this)
elseif spell == 18 then
set reveal = true
call VampiricGroanCast(this)
elseif spell == 26 then
call ShadowMeldCast(this)
elseif spell == 29 then
set x2 = GetUnitX(.u)
set y2 = GetUnitY(.u)
set skillCastDistance = 700
if SquareRoot((x2-x)*(x2-x)+(y2-y)*(y2-y)) > skillCastDistance then
call IssuePointOrder(.u, "move", x, y)
if skillCastTimer != null then
call ReleaseTimer(skillCastTimer)
endif
set skillCastTimer = NewTimerEx(this)
set skillCastX = x
set skillCastY = y
set skillCastIndex = spell
set skillCastDistance = skillCastDistance * skillCastDistance
call TimerStart(skillCastTimer, 0.1, true, function thistype.recast)
else
set reveal = true
call SetUnitFacing(.u, Atan2(y-y2, x-x2)*bj_RADTODEG)
call ViciousHailCast(this, x, y)
endif
elseif spell == 35 then
set reveal = true
call SummonWolfCast(this)
elseif spell == 42 then
set reveal = true
call IllusoryIncarnationCast(this)
elseif spell == 11 then
set reveal = true
call SetUnitFacing(.u, Atan2(y-GetUnitY(.u), x-GetUnitX(.u))*bj_RADTODEG)
call ValiantChargeCast(this)
elseif spell == ORDER_ATTACK_SKILL then
set gr = CreateGroup()
loop
set fog = FirstOfGroup(.subordinate)
exitwhen fog == null
call GroupRemoveUnit(.subordinate, fog)
call GroupAddUnit(gr, fog)
if CompanionAI[fog] > 0 then
set CompanionAI[fog].combatModeDur = 3600.0
elseif HumanoidAI[fog] > 0 then
set HumanoidAI[fog].combatModeDur = 3600.0
endif
endloop
call DestroyGroup(.subordinate)
set .subordinate = gr
set gr = null
elseif spell == ORDER_STOP_SKILL then
set gr = CreateGroup()
loop
set fog = FirstOfGroup(.subordinate)
exitwhen fog == null
call GroupRemoveUnit(.subordinate, fog)
call GroupAddUnit(gr, fog)
if CompanionAI[fog] > 0 then
set CompanionAI[fog].combatModeDur = 0.0
set CompanionAI[fog].wanderDelay = 0.0
elseif HumanoidAI[fog] > 0 then
set HumanoidAI[fog].combatModeDur = 0.0
set HumanoidAI[fog].wanderDelay = 0.0
endif
endloop
call DestroyGroup(.subordinate)
set .subordinate = gr
set gr = null
elseif spell == ORDER_MOVE_SKILL then
set gr = CreateGroup()
loop
set fog = FirstOfGroup(.subordinate)
exitwhen fog == null
call GroupRemoveUnit(.subordinate, fog)
call GroupAddUnit(gr, fog)
if CompanionAI[fog] > 0 then
set CompanionAI[fog].target = 0
set CompanionAI[fog].combatModeDur = 3600.0
set CompanionAI[fog].wanderDelay = 3600.0
elseif HumanoidAI[fog] > 0 then
set HumanoidAI[fog].target = 0
set HumanoidAI[fog].combatModeDur = 3600.0
set HumanoidAI[fog].wanderDelay = 3600.0
endif
call Combatant[fog].move(x, y)
endloop
call DestroyGroup(.subordinate)
set .subordinate = gr
set gr = null
endif
if reveal and Invisibility.isInvisible(this) then
call Invisibility.reveal(this)
endif
endif
endmethod
private static method AfterImage takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
set UnitMissile.create(u).factor = Afterimage.Damage[this]
call ReleaseTimer(t)
set t = null
endmethod
private static method onLaunch takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local real f
local real x
local real y
local real dp
local unit fog
local real damage
local real dmgBonus
if IsUnitAlive(u) then
set dmgBonus = 0.
if Invisibility.isInvisible(this) then
if Invisibility.invisBuff(this) == 26 then // Shadow Meld
set dmgBonus = ShadowMeldDamage(pid)
endif
call Invisibility.reveal(this)
endif
if melee then
set f = GetUnitFacing(u)*bj_DEGTORAD
set x = GetUnitX(u)
set y = GetUnitY(u)
call GroupEnumUnitsInRange(Group, x, y, attackRange, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitEnemy(fog, owner) and IsUnitAlive(fog) then
if RAbsBJ(PanelCore_AngularDifference(f, Atan2(GetUnitY(fog)-y, GetUnitX(fog)-x))) < attackRadius then
set damage = CalculateDamage(this, Combatant[fog])+dmgBonus
call Damage(u, fog, damage, true, true, true)
endif
endif
endloop
if IsUnitInGroup(.u, MainGroup) then
call SwingSounds[GetRandomInt(0, 2)].play(x, y, PanelCore_GetUnitZ(u), 100)
endif
else
set UnitMissile.create(u).dmgBonus = dmgBonus
if Afterimage.Registered[this] then
if GetRandomReal(0.000, 1.000) <= Afterimage.Chance[this] then
set dp = dmgPoint*(attackRate/attackRateDef)
call TimerStart(NewTimerEx(this), dp*0.25, false, function thistype.AfterImage)
endif
endif
endif
call SetUnitTimeScale(u, 1.0)
endif
call TimerStart(t, 0, false, null)
set t = null
endmethod
method attack takes nothing returns nothing
local real dp
local real x
local real y
if IsUnitAlive(u) then
call IssueImmediateOrder(u, "stop")
if isAttackReady and not isDisarmed and not isStunned then
if isChanneling then
/*static if USE_MEMORY_HACK then
if IsLAN then
set x = MouseX[pid]
set y = MouseY[pid]
else
set x = GetMouseX()
set y = GetMouseY()
endif
else
set x = GetPlayerMouseX(.owner)
set y = GetPlayerMouseY(.owner)
endif
call SetUnitFacing(.u, Atan2(y-GetUnitY(.u), x-GetUnitX(.u))*bj_RADTODEG)*/
else
call CreepSfx_attack(this)
set dp = dmgPoint*(attackRate/attackRateDef)
call SetUnitTimeScale(u, attackRateDef/attackRate)
call SetUnitAnimation(u, "attack")
call QueueUnitAnimation(u, "ready")
call QueueUnitAnimation(u, "stand")
call TimerStart(attackTimer, attackRate, false, function thistype.resetTimer)
call TimerStart(launchTimer, dp, false, function thistype.onLaunch)
call immobilize(0, dp, null)
endif
endif
endif
endmethod
method move takes real x, real y returns nothing
if IsUnitAlive(u) and not isStunned and not isImmobilized then
if not isChanneling then
//call SetUnitFacing(u, Atan2(y-GetUnitY(u), x-GetUnitX(u))*bj_RADTODEG)
//else
call IssuePointOrder(u, "move", x, y)
endif
endif
endmethod
method follow takes unit target returns nothing
if IsUnitAlive(u) and not isChanneling and not isImmobilized and not isStunned and IsUnitVisible(target, .owner) then
call IssueTargetOrder(u, "move", target)
endif
endmethod
static method operator [] takes unit u returns thistype
return UnitDex[GetUnitUserData(u)]
endmethod
method operator hpRegen= takes real r returns nothing
call Regeneration.apply(u, true, r)
endmethod
method operator hpRegen takes nothing returns real
return Regeneration.get(u, true)
endmethod
method operator spRegen= takes real r returns nothing
call Regeneration.apply(u, false, r)
endmethod
method operator spRegen takes nothing returns real
return Regeneration.get(u, false)
endmethod
method destroy takes nothing returns nothing
if UnitDex[GetUnitUserData(.u)] != 0 then
set UnitDex[GetUnitUserData(.u)] = 0
call Afterimage.unregister(this)
call .purgeBuff()
if not IsUnitInGroup(.u, MainGroup) then
call .buffs.flushNode()
endif
if .owner == CREEP_PLAYER then
call GroupRemoveUnit(CreepUnits, .u)
endif
//if .noRemove then
//call RemoveUnit(.u)
//endif
call GroupRemoveUnit(AllUnits, .u)
call DestroyGroup(.subordinate)
call DestroyEffect(.upgradeSfx)
call ReleaseTimer(.silenceTimer)
call ReleaseTimer(.disarmTimer)
call ReleaseTimer(.immobileTimer)
call ReleaseTimer(.stunTimer)
call ReleaseTimer(.attackTimer)
call ReleaseTimer(.launchTimer)
call ReleaseTimer(.invulTimer)
call deallocate()
set .silenceTimer = null
set .upgradeSfx = null
set .disarmTimer = null
set .immobileTimer = null
set .stunTimer = null
set .attackTimer = null
set .launchTimer = null
set .invulTimer = null
set .subordinate = null
set .destToRemove = null
set .u = null
endif
endmethod
static method create takes unit u returns thistype
local thistype this = allocate()
local integer id = GetUnitUserData(u)
//call BJDebugMsg("Create " + I2S(this))
set .u = u
set .data = id
set .isIllusion = false
set .dmgProtection = 0
set .owner = GetOwningPlayer(u)
set .uid = GetUnitTypeId(u)
set .pid = GetPlayerId(.owner)
set .subordinate = CreateGroup()
if not IsUnitInGroup(.u, MainGroup) then
set .buffs = CombatantBuff.createNode()
endif
set .silenceTimer = NewTimerEx(this)
set .disarmTimer = NewTimerEx(this)
set .immobileTimer = NewTimerEx(this)
set .stunTimer = NewTimerEx(this)
set .attackTimer = NewTimerEx(this)
set .launchTimer = NewTimerEx(this)
set .invulTimer = NewTimerEx(this)
set UnitDex[id] = this
call TimerStart(.silenceTimer, 0, false, null)
call TimerStart(.disarmTimer, 0, false, null)
call TimerStart(.immobileTimer, 0, false, null)
call TimerStart(.stunTimer, 0, false, null)
call TimerStart(.attackTimer, 0, false, null)
call TimerStart(.launchTimer, 0, false, null)
call TimerStart(.invulTimer, 0, false, null)
if .owner == CREEP_PLAYER then
call GroupAddUnit(CreepUnits, .u)
endif
call GroupAddUnit(AllUnits, .u)
return this
endmethod
endstruct
endlibrary
library ExpSystem uses Skill, AttPoints, XPBar,PlayerInit
globals
integer array Level
real array EXPCurrent
real array EXPTarget
real array HPGrowth
real array MPGrowth
integer array Fame
endglobals
function AddEXP takes integer id, real amount returns nothing
local boolean b
local real factor
if Level[id] < MAXIMUM_LEVEL then
set EXPCurrent[id] = EXPCurrent[id] + amount*(1.+ActiveScroll.expRate)
if EXPCurrent[id] < 0 then
set EXPCurrent[id] = 0
endif
set b = false
loop
if EXPCurrent[id] >= EXPTarget[id] then
set b = true
if Level[id] < MAXIMUM_LEVEL then
set EXPCurrent[id] = EXPCurrent[id] - EXPTarget[id]
set EXPTarget[id] = (EXPTarget[id]*EXP_GROWTH+EXP_GROWTH_CONST)
set factor = CalculateStatusBaseFactor(I2R(Level[id]), 100.)
set Fighter[id].hpMax = Fighter[id].hpMax + HPGrowth[id]*factor
set Fighter[id].spMax = Fighter[id].spMax + MPGrowth[id]*factor
set Level[id] = Level[id] + 1
if ModuloInteger(Level[id], SKILL_PTS_GIVE_LEVEL_SPACE) == 0 then
call AddSkillPoint(id, SKILL_PTS_GIVEN)
endif
call AddAttributePoint(id, ATTRIBUTE_PTS_GIVEN)
else
set EXPCurrent[id] = 0
endif
else
exitwhen true
endif
endloop
call XPBar_Update(id)
if b then
// Adjust pet level
call PetFighter[id].purgeBuff()
call ResetPetStats(PetFighter[id].uid, id)
call AdjustCreepStrength(PetFighter[id], Level[id])
call EvaluateSkillList(id)
call CharacterWindow_UpdateLevel(id, Level[id])
if Tooltips1[id].control.visible then
if Tooltips1[id].skill != 0 then
call Tooltips1[id].setSkill(Tooltips1[id].skill)
elseif Tooltips1[id].itmObject != 0 then
call Tooltips1[id].setItem(Tooltips1[id].itmObject)
endif
endif
set Fighter[id].hp = Fighter[id].hpMax
set Fighter[id].sp = Fighter[id].spMax
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Levelup\\LevelupCaster.mdl", MainUnit[id], "origin"))
//set SavingPlayerID = id
//call ExecuteFunc("CreateNewSaveThreadEx")
endif
else
set EXPCurrent[id] = 0
endif
endfunction
endlibrary
library Footstep initializer init uses RapidSound
globals
public RSound array FootstepSound
public timer Timer
endglobals
private function check takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 3
if IsPlaying[i] and GetUnitCurrentOrder(MainUnit[i]) == 851986 then
call FootstepSound[GetRandomInt(2, 9)].play(GetUnitX(MainUnit[i]), GetUnitY(MainUnit[i]), PanelCore_GetUnitZ(MainUnit[i]), 25)
endif
set i = i + 1
endloop
endfunction
private function init takes nothing returns nothing
local integer i = 2
loop
exitwhen i > 9
set FootstepSound[i] = RSound.create("war3mapImported\\step " + I2S(i) + ".wav", true, true, 12700, 12700)
set i = i + 1
endloop
set Timer = CreateTimer()
call TimerStart(Timer, 0.3, true, function check)
endfunction
endlibrary
library Revive initializer init uses SRS
globals
dialog array ReviveDialog
button array ReviveDialogOpt1
endglobals
private function onClick takes nothing returns boolean
local player p = GetTriggerPlayer()
local button but = GetClickedButton()
local integer pid = GetPlayerId(p)
local real g = I2R(GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD))
local location loc
call PetFighter[pid].revive()
call Fighter[pid].revive()
set Fighter[pid].hp = Fighter[pid].hpMax
set Fighter[pid].sp = Fighter[pid].spMax
if but == ReviveDialogOpt1[pid] then
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, R2I(g)-R2I(g*0.1))
else
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, R2I(g)-R2I(g*0.025))
set IgnoreEntrance = true
set loc = GetLastCreatedStairs(true)
call SetUnitPosition(MainUnit[pid], GetLocationX(loc), GetLocationY(loc))
call RemoveLocation(loc)
set loc = null
endif
call SetUnitPosition(Pet[pid], GetUnitX(MainUnit[pid]), GetUnitY(MainUnit[pid]))
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\Awaken\\Awaken.mdl", GetUnitX(MainUnit[pid]), GetUnitY(MainUnit[pid])))
if PlayerSkillData[pid][8].level > 0 then
call Fighter[pid].applyBuff(5, 0, null)
endif
if PlayerSkillData[pid][6].level > 0 then
call Fighter[pid].applyBuff(6, 0, null)
endif
if PlayerSkillData[pid][22].level > 0 then
call Fighter[pid].applyBuff(9, 0, AddSpecialEffectTarget("war3mapImported\\Sweep_Astral_" + I2S(PlayerSkillData[pid][22].level) + "_med.mdx", MainUnit[pid], "weapon"))
endif
if PlayerSkillData[pid][24].level > 0 then
call Fighter[pid].applyBuff(12, 0, null)
endif
if PlayerSkillData[pid][40].level > 0 then
call Fighter[pid].applyBuff(18, 0, null)
endif
if PlayerSkillData[pid][32].level > 0 then
call Fighter[pid].applyBuff(19, 0, null)
endif
if PlayerSkillData[pid][30].level > 0 then
call Fighter[pid].applyBuff(20, 0, null)
endif
//set SavingPlayerID = pid
//call ExecuteFunc("CreateNewSaveThreadEx")
return false
endfunction
public function ShowDialog takes player p returns nothing
local integer id = GetPlayerId(p)
local real g = I2R(GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD))
call DialogClear(ReviveDialog[id])
call DialogSetMessage(ReviveDialog[id], "|cffcc0000You are dead. Respawn locations:|r")
call DialogAddButton(ReviveDialog[id], "|cffffffffEntrance gate (Cost: |cffffcc00" + I2S(R2I(g*0.025)) + " g|cffffffff)|R", 0)
set ReviveDialogOpt1[id] = DialogAddButton(ReviveDialog[id], "|cffffffffCurrent location (Cost: |cffffcc00" + I2S(R2I(g*0.1)) + " g|cffffffff)|R", 0)
call DialogDisplay(p, ReviveDialog[id], true)
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
exitwhen i > 3
set ReviveDialog[i] = DialogCreate()
call TriggerRegisterDialogEvent(t, ReviveDialog[i])
set i = i + 1
endloop
call TriggerAddCondition(t, Condition(function onClick))
endfunction
endlibrary
library Keyboard initializer init uses PanelCore, ShortcutBar, Mouse, MouseUtils
globals
boolean array IsKeyVerified
real Smooth = 0//0.03//0.4
unit array MainUnit
real array CameraDistance
real array LastRot
boolean array CameraOn
boolean array ItemOn
CustomText array PlayerNameTag
private timer array Tim
player Locale
integer PNumb
private rect TempRect
private integer TempInt
real CamAng = bj_CAMERA_DEFAULT_AOA
real CamRot = 163.97
boolean IgnoreCooldown = false
private destructable array OccludedDest
private integer array OccludedDestTarget
public real array Smoothing
private real array OccludedDestX
private real array OccludedDestY
private integer OccludedDestCt = 0
private player ItemFinderPlayer = null
private unit ItemFinder = null
private unit ClosestItem = null
private real ClosestItemDist = 600
private group TempGroup = CreateGroup()
integer array LastNumbKey
timer array HoldNumbTimer
endglobals
private function checkDest takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= OccludedDestCt
if not IsUnitInRangeXY(MainUnit[OccludedDestTarget[i]], OccludedDestX[i], OccludedDestY[i], OCCLUSION_DEST_DISTANCE+128) then
call SetDestructableOccluderHeight(OccludedDest[i], 5.0)
call SetDestructableAnimation(OccludedDest[i], "birth alternate")
call QueueDestructableAnimation(OccludedDest[i], "stand")
set OccludedDest[i] = OccludedDest[OccludedDestCt]
set OccludedDestTarget[i] = OccludedDestTarget[OccludedDestCt]
set OccludedDestX[i] = OccludedDestX[OccludedDestCt]
set OccludedDestY[i] = OccludedDestY[OccludedDestCt]
set OccludedDest[OccludedDestCt] = null
set OccludedDestCt = OccludedDestCt - 1
set i = i - 1
endif
set i = i + 1
endloop
endfunction
private function hideDest takes nothing returns nothing
local destructable d = GetEnumDestructable()
local integer id
if GetDestructableOccluderHeight(d) > 0.0 and IsUnitInRangeXY(MainUnit[TempInt], GetDestructableX(d), GetDestructableY(d), OCCLUSION_DEST_DISTANCE) then
set id = GetDestructableTypeId(d)
if id == 'B04M' or id == 'B04N' then
call SetDestructableOccluderHeight(d, 0.0)
call SetDestructableAnimation(d, "death alternate")
set OccludedDest[OccludedDestCt] = d
set OccludedDestTarget[OccludedDestCt] = TempInt
set OccludedDestX[OccludedDestCt] = GetDestructableX(d)
set OccludedDestY[OccludedDestCt] = GetDestructableY(d)
set OccludedDestCt = OccludedDestCt + 1
endif
endif
set d = null
endfunction
private function def takes nothing returns nothing
local real x
local real y
local real uz
local real z2
local real rot
local real d
local real cd
local real mhx
local real mh
local real z
local real cz
local real a
local timer t = GetExpiredTimer()
local integer i = GetTimerData(t)
local unit npc
if CameraOn[i] and IsPlaying[i] then
set x = GetUnitX(MainUnit[i])
set y = GetUnitY(MainUnit[i])
if InDungeon then
set TempInt = i
call SetRect(TempRect, x-OCCLUSION_DEST_DISTANCE, y-OCCLUSION_DEST_DISTANCE, x+OCCLUSION_DEST_DISTANCE, y+OCCLUSION_DEST_DISTANCE)
call EnumDestructablesInRect(TempRect, null, function hideDest)
endif
if SelectedMerchant[i] != null then
set npc = SelectedMerchant[i]
else
set npc = ShopMerchants_CurrentMerchant[i]
endif
if npc != null then
set rot = GetUnitFacing(npc) + 180.0
call PlayerCamera[i].setField(CAMERA_FIELD_ANGLE_OF_ATTACK, 350.0, 0.25)
call PlayerCamera[i].setField(CAMERA_FIELD_TARGET_DISTANCE, 400.0, 0.25)
call PlayerCamera[i].setField(CAMERA_FIELD_ROTATION, rot, 0.0)
if rot != LastRot[i] then
call RefreshItemNames()
call RefreshPortalText()
call RefreshNPCText()
endif
set LastRot[i] = rot
else
call PlayerCamera[i].setField(CAMERA_FIELD_ANGLE_OF_ATTACK, CamAng, Smooth)
call PlayerCamera[i].setField(CAMERA_FIELD_TARGET_DISTANCE, CameraDistance[i], Smooth)
if InDoor[i] then
call PlayerCamera[i].setField(CAMERA_FIELD_ROTATION, 90, Smooth)
if 90 != LastRot[i] then
call RefreshItemNames()
call RefreshPortalText()
call RefreshNPCText()
endif
set LastRot[i] = 90
else
call PlayerCamera[i].setField(CAMERA_FIELD_ROTATION, CamRot, Smooth)
if CamRot != LastRot[i] then
call RefreshItemNames()
call RefreshPortalText()
call RefreshNPCText()
endif
set LastRot[i] = CamRot
endif
endif
//set cz = PlayerCamera[i].ZOffset+uz+CameraShaker_VMagnitude[i]-GetCameraTargetPositionZ()
if npc != null then
call PlayerCamera[i].setField(CAMERA_FIELD_ZOFFSET, DungeonZ+GetUnitFlyHeight(SelectedMerchant[i])+64, 0)
else
call PlayerCamera[i].setField(CAMERA_FIELD_ZOFFSET, DungeonZ+GetUnitFlyHeight(MainUnit[i])+CameraShaker_VMagnitude[i]*CameraShaker_Intensity[i]*DEFAULT_SHAKE_INTENSITY+128, 0)
endif
if MainUnit[i] != null then
if npc != null then
set x = GetUnitX(npc)
set y = GetUnitY(npc)
endif
if CameraShaker_HMagnitude[i] > 0 then
set a = PlayerCamera[i].Rotation-PanelCore_HP
set x = x + (CameraShaker_HMagnitude[i]*CameraShaker_Intensity[i]*DEFAULT_SHAKE_INTENSITY) * Cos(a)
set y = y + (CameraShaker_HMagnitude[i]*CameraShaker_Intensity[i]*DEFAULT_SHAKE_INTENSITY) * Sin(a)
endif
call PlayerCamera[i].move(x, y, Smoothing[i])
call PlayerNameTag[i].move(x, y, 200)
endif
endif
if IsPlaying[i] then
if InDungeon then
call SetCameraField(CAMERA_FIELD_FARZ, 6000.0, 0)
else
call SetCameraField(CAMERA_FIELD_FARZ, 10000.0, 0)
endif
call PlayerCamera[i].refresh()
endif
set t = null
endfunction
private function findClosestItem takes nothing returns boolean
local unit i = GetFilterUnit()
local real x = GetUnitX(i)
local real y = GetUnitY(i)
local real dx
local real dy
if GetUnitTypeId(i) == 'e02F' and IsUnitVisible(i, ItemFinderPlayer) and IsUnitInRangeXY(ItemFinder, x, y, ClosestItemDist) then
set ClosestItem = i
set dx = GetUnitX(ItemFinder)-x
set dy = GetUnitY(ItemFinder)-y
set ClosestItemDist = SquareRoot(dx*dx+dy*dy)
endif
set i = null
return false
endfunction
private function onOrder takes nothing returns boolean
local integer order
local unit fog
local integer id
local player p
if GetUnitTypeId(GetTriggerUnit()) == 'h001' then
set order = GetIssuedOrderId()
if order == ORDER_defend or order == ORDER_undefend then
set p = GetTriggerPlayer()
set id = GetPlayerId(p)
if order == ORDER_defend then
set ItemOn[id] = false
elseif order == ORDER_undefend then
set ItemOn[id] = true
endif
loop
set fog = FirstOfGroup(ItemObject.AllItem)
exitwhen fog == null
call GroupRemoveUnit(ItemObject.AllItem, fog)
call GroupAddUnit(TempGroup, fog)
if Locale == p then
set ItemObject[fog].selectable = ItemOn[id]
endif
endloop
call DestroyGroup(ItemObject.AllItem)
set ItemObject.AllItem = TempGroup
set TempGroup = CreateGroup()
endif
endif
return false
endfunction
private function onCast takes nothing returns boolean
local unit u = GetTriggerUnit()
local player p
local unit fog
local integer spell
local integer id
local integer i
local integer data
local integer best1
local real value
local real need
local real best1data
local Combatant c
local ItemObject obj
if GetUnitAbilityLevel(u, 'A007') > 0 then
set spell = GetSpellAbilityId()
set p = GetTriggerPlayer()
set id = GetPlayerId(p)
if spell == 'A007' then
call Bag[id].show(not Bag[id].visible)
call Bag[id].panel.refresh()
elseif spell == 'A006' or spell == 'A00C' then
call CharacterWindow_Show(id, not CharacterWindow_Visible[id])
if CharacterWindow_Visible[id] then
call ShopUI[id].show(false)
endif
elseif spell == 'A00D' then
if InDungeon then
if MiniMap_MaximizeButton.texture == "war3mapImported\\MinimapMinimize.blp" then
set MiniMap_MaximizeButton.texture = "war3mapImported\\MinimapMaximize.blp"
set MiniMap_TilePanel.visible = false
set MiniMap_Frame.visible = false
else
call MiniMap_HideAll()
set MiniMap_MaximizeButton.texture = "war3mapImported\\MinimapMinimize.blp"
set MiniMap_TilePanel.visible = true
set MiniMap_Frame.visible = true
call MiniMap_UpdateMinimap()
endif
endif
elseif spell == 'A009' then
if CharacterWindow_Visible[id] then
if CharacterWindow_TabIndex[id] < 2 then
call CharacterWindow_OpenTab(id, CharacterWindow_TabIndex[id]+1)
else
call CharacterWindow_OpenTab(id, 0)
endif
endif
elseif spell == 'A00P' then
if IsUnitAlive(MainUnit[id]) then
set c = Fighter[id]
set need = c.hpMax-c.hp
if need <= 1 then
call DisplayTimedTextToPlayer(p, 0, 0, 1., "|cffffcc00Already at full health!|r")
return false
endif
set best1 = -1
set best1data = 999999999
set i = 0
loop
exitwhen i == 20
if Inventory_SlotIndex[Bag[id]][i].object.id.category == Items.CONSUMABLE then
set value = Inventory_SlotIndex[Bag[id]][i].object.hp
if value > 0 then
set value = RAbsBJ(value-need)
if value < best1data then
set best1 = i
set best1data = value
endif
endif
endif
set i = i + 1
endloop
if best1 != -1 then
call Bag[id].useItemAtSlot(best1)
else
call DisplayTimedTextToPlayer(p, 0, 0, 1., "|cffff0000Out of health potion!|r")
endif
endif
elseif spell == 'A00Q' then
if IsUnitAlive(MainUnit[id]) then
set c = Fighter[id]
set need = c.spMax-c.sp
if need <= 1 then
call DisplayTimedTextToPlayer(p, 0, 0, 1., "|cffffcc00Already at full mana!|r")
return false
endif
set best1 = -1
set best1data = 999999999
set i = 0
loop
exitwhen i == 20
if Inventory_SlotIndex[Bag[id]][i].object.id.category == Items.CONSUMABLE then
set value = Inventory_SlotIndex[Bag[id]][i].object.sp
if value > 0 then
set value = RAbsBJ(value-need)
if value < best1data then
set best1 = i
set best1data = value
endif
endif
endif
set i = i + 1
endloop
if best1 != -1 then
call Bag[id].useItemAtSlot(best1)
else
call DisplayTimedTextToPlayer(p, 0, 0, 1., "|cffff0000Out of mana potion!|r")
endif
endif
elseif spell == 'A013' then
call IssueImmediateOrder(Fighter[id].u, "stop")
elseif spell == 'A014' then
call Fighter[id].attack()
elseif spell == 'A003' then
set ClosestItemDist = 800
set ClosestItem = null
set ItemFinder = Fighter[id].u
set ItemFinderPlayer = Fighter[id].owner
call GroupEnumUnitsInRange(TempGroup, GetUnitX(ItemFinder), GetUnitY(ItemFinder), 600, Filter(function findClosestItem))
call GroupClear(TempGroup)
if ClosestItem != null then
call IssueTargetOrder(Controller[id], "smart", ClosestItem)
endif
endif
endif
set u = null
return false
endfunction
private function pressKey takes player p, integer numb returns nothing
local integer id = GetPlayerId(p)
local integer data
local integer data2
local integer data3
local integer i
local real cd
local real x
local real y
local string s
local PlayerSkill skill
local SkillData sData
set data = GetUnitUserData(MainUnit[id])
if UnitAlive(MainUnit[id]) and not IsUnitPaused(MainUnit[id]) then
if numb == 0 then
set numb = 10
endif
set numb = numb - 1
if not IsShortcutSlotInCooldown(id, numb) then
set data3 = GetUnitUserData(ShortcutBar_Button[id][numb].dummy)
if ShortcutBar_ButtonType[data3] == 1 then
if not Fighter[id].isSilenced and not Fighter[id].isStunned and not Fighter[id].isDisarmed and not Fighter[id].isAttacking then
set sData = ShortcutBar_ButtonSkill[data3]
set skill = PlayerSkillData[id][sData]
if Fighter[id].hp <= sData.lifecost[skill.level] then
//call DisplayTimedTextToPlayer(p, 0, 0, 1., "Not enough HP.")
elseif Fighter[id].sp < sData.manacost[skill.level] then
//call DisplayTimedTextToPlayer(p, 0, 0, 1., "Not enough MP.")
else
set x = 0
set y = 0
static if USE_MEMORY_HACK then
if IsLAN then
set x = MouseX[id]
set y = MouseY[id]
else
set x = GetMouseX()
set y = GetMouseY()
endif
else
set x = GetPlayerMouseX(p)
set y = GetPlayerMouseY(p)
endif
if not Fighter[id].isChanneling then
if ShortcutBar_SkillSelection[id].visible then
call ShortcutBar_SkillSelection[id].clear()
set ShortcutBar_SelectIndex[id] = -1
call ShortcutBar_SkillSelection[id].show(false)
endif
if IgnoreCooldown then
set cd = 0
else
set cd = sData.cooldown[skill.level]
set Fighter[id].hp = Fighter[id].hp - sData.lifecost[skill.level]
set Fighter[id].sp = Fighter[id].sp - sData.manacost[skill.level]
endif
if cd > 0 then
set i = 0
loop
exitwhen i > 9
set data2 = GetUnitUserData(ShortcutBar_Button[id][i].dummy)
if ShortcutBar_ButtonType[data2] == 1 and ShortcutBar_ButtonSkill[data2] == sData then
call ShortcutBar_PutToCooldown(id, i, cd, cd)
endif
set i = i + 1
endloop
call SkillCooldown.start(sData, cd)
endif
endif
call Combatant[MainUnit[id]].cast(sData, x, y, "")
endif
endif
elseif ShortcutBar_ButtonType[data3] == 2 then
call Bag[id].useItemAtSlot(ShortcutBar_ButtonTarget[data3])
set ShortcutBar_SelectIndex[id] = -1
call ShortcutBar_SkillSelection[id].show(false)
endif
endif
endif
endfunction
private function repeatNumbKey takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
local player p = Player(id)
if Fighter[id].isChanneling then
call SetUnitFacing(MainUnit[id], Atan2(GetPlayerMouseY(p)-GetUnitY(MainUnit[id]), GetPlayerMouseX(p)-GetUnitX(MainUnit[id]))*bj_RADTODEG)
else
call pressKey(p, LastNumbKey[id])
endif
set t = null
endfunction
private function onPress takes nothing returns boolean
local oskeytype pressed
local player p = GetTriggerPlayer()
local boolean down = BlzGetTriggerPlayerIsKeyDown()
local integer id = GetPlayerId(p)
local integer numb
if down then
if HoldNumbTimer[id] == null then
set HoldNumbTimer[id] = NewTimerEx(id)
endif
call TimerStart(HoldNumbTimer[id], 0.1, true, function repeatNumbKey)
else
call PauseTimer(HoldNumbTimer[id])
if not Fighter[id].isChanneling then
return false
endif
endif
set pressed = BlzGetTriggerPlayerKey()
if pressed == OSKEY_0 then
set numb = 0
elseif pressed == OSKEY_1 then
set numb = 1
elseif pressed == OSKEY_2 then
set numb = 2
elseif pressed == OSKEY_3 then
set numb = 3
elseif pressed == OSKEY_4 then
set numb = 4
elseif pressed == OSKEY_5 then
set numb = 5
elseif pressed == OSKEY_6 then
set numb = 6
elseif pressed == OSKEY_7 then
set numb = 7
elseif pressed == OSKEY_8 then
set numb = 8
elseif pressed == OSKEY_9 then
set numb = 9
endif
set LastNumbKey[id] = numb
call pressKey(p, numb)
return false
endfunction
public function SetCamSmoothness takes integer id, integer level returns integer
if level < 0 then
set level = 0
elseif level > 4 then
set level = 4
endif
call TimerStart(Tim[id], 0.05-0.01*level, true, function def)
return level
endfunction
private function checkArrow takes nothing returns nothing
local integer i = 0
local player p
loop
exitwhen i > 3
if IsPlaying[i] and CameraOn[i] then
set p = Player(i)
if IsArrowKeyPressed(p, ARROW_KEY_UP) then
if PlayerCamera[i].TargetDistance > 800 then
set CameraDistance[i] = PlayerCamera[i].TargetDistance - 30
if CameraDistance[i] < 800 then
set CameraDistance[i] = 800
endif
endif
elseif IsArrowKeyPressed(p, ARROW_KEY_DOWN) then
if PlayerCamera[i].TargetDistance < 1600 then
set CameraDistance[i] = PlayerCamera[i].TargetDistance + 30
if CameraDistance[i] > 1600 then
set CameraDistance[i] = 1600
endif
endif
endif
endif
set i = i + 1
endloop
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
local player p
set TempRect = Rect(0, 0, 0, 0)
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function onCast))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerAddCondition(t, Condition(function onOrder))
set Locale = GetLocalPlayer()
set PNumb = GetPlayerId(Locale)
set t = CreateTrigger()
call TriggerAddCondition(t, Condition(function onPress))
loop
exitwhen i > 3
set p = Player(i)
set Tim[i] = NewTimerEx(i)
set CameraDistance[i] = 1200
set IsKeyVerified[i] = true
call TimerStart(Tim[i], PanelCamera_INTERVAL, true, function def)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_0, 0, true)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_0, 0, false)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_1, 0, true)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_1, 0, false)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_2, 0, true)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_2, 0, false)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_3, 0, true)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_3, 0, false)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_4, 0, true)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_4, 0, false)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_5, 0, true)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_5, 0, false)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_6, 0, true)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_6, 0, false)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_7, 0, true)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_7, 0, false)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_8, 0, true)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_8, 0, false)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_9, 0, true)
call BlzTriggerRegisterPlayerKeyEvent(t, p, OSKEY_9, 0, false)
set i = i + 1
endloop
call FogEnable(false)
call FogMaskEnable(false)
call EnableDragSelect(true, false)
call EnablePreSelect(false, false)
call EnableSelect(true, false)
//call SelectUnit(MainUnit[PNumb], true)
call SetCameraPosition(GetUnitX(MainUnit[PNumb]), GetUnitY(MainUnit[PNumb]))
//call RegisterAnyNumberKeyEvent(Condition(function onPress))
call TimerStart(CreateTimer(), 0.03, true, function checkArrow)
call TimerStart(CreateTimer(), 0.5, true, function checkDest)
endfunction
endlibrary
library LeftClick initializer init uses Track, Mouse, PanelCore, MouseUtils, UpgradeMenu
globals
private trackable Detector
private real X
private real X2
private real Y
private real Z
private real RestartDelay
private integer RestartId
real array MouseX
real array MouseY
timer array RestartTimer
timer array RightClickTimer
timer array LeftClickTimer
constant real EST_PING = 0.25
constant integer STREAM_ACC = 4
private integer array StreamCount
private integer OrderIndex = 1
endglobals
private function CreateDest takes nothing returns nothing
call CreateDestructableZ('B00J', X, Y, Z, 0, 1 , 0)
endfunction
private function InitDest2 takes nothing returns nothing
loop
exitwhen X > X2
call ForForce(bj_FORCE_PLAYER[0], function CreateDest)
set X = X + 1024
endloop
endfunction
function InitDest takes rect r, real z returns nothing
local real x = GetRectMinX(r)
local real y = GetRectMinY(r)
local real y2 = GetRectMaxY(r)
set X2 = GetRectMaxX(r)
set Z = z
loop
exitwhen y > y2
set X = x
set Y = y
call ForForce(bj_FORCE_PLAYER[0], function InitDest2)
set y = y + 1024
endloop
endfunction
private function CreateTrack2 takes nothing returns nothing
call CreateTrack("war3mapImported\\Track1024.mdx", X, Y, Z+10, 0)
endfunction
private function InitTrack2 takes nothing returns nothing
loop
exitwhen X > X2
call ForForce(bj_FORCE_PLAYER[0], function CreateTrack2)
set X = X + 1024
endloop
endfunction
function InitTrack takes rect r, real z returns nothing
local real x = GetRectMinX(r)
local real y = GetRectMinY(r)
local real y2 = GetRectMaxY(r)
set X2 = GetRectMaxX(r)
set Z = z
loop
exitwhen y > y2
set X = x
set Y = y
call ForForce(bj_FORCE_PLAYER[0], function InitTrack2)
set y = y + 1024
endloop
endfunction
private function leftClick takes player p, integer id returns nothing
local real x
local real y
if IsUnitAlive(MainUnit[id]) then
if IsKeyVerified[id] then
if IsUnitSelected(Controller[id], p) then
if ShopMerchants_CurrentMerchant[id] != null then
set ShopMerchants_CurrentMerchant[id] = null
if ShopUI[id].visible then
call ShopUI[id].show(false)
endif
if UpgradeMenu_Main[id].visible then
call UpgradeMenu_CloseWindow(id)
endif
else
if Fighter[id].isAttackReady then
static if USE_MEMORY_HACK then
if IsLAN then
set x = MouseX[id]
set y = MouseY[id]
else
set x = GetMouseX()
set y = GetMouseY()
endif
else
set x = GetPlayerMouseX(p)
set y = GetPlayerMouseY(p)
endif
if x != 0 and y != 0 or USE_MEMORY_HACK then
call SetUnitFacing(MainUnit[id], Atan2(y-GetUnitY(MainUnit[id]), x-GetUnitX(MainUnit[id]))*bj_RADTODEG)
endif
else
call IssueImmediateOrder(MainUnit[id], "stop")
endif
if x != 0 and y != 0 or USE_MEMORY_HACK then
call Fighter[id].attack()
endif
endif
else
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[id], true)
endif
endif
endif
endif
endfunction
private function repeatLeftClick takes nothing returns nothing
static if not USE_MEMORY_HACK then
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
local player p = Player(id)
call leftClick(p, id)
set t = null
endif
endfunction
private function onClick takes nothing returns boolean
local player p = GetTriggerTrackablePlayer()
local integer id = GetPlayerId(p)
call leftClick(p, id)
static if not USE_MEMORY_HACK then
if UserMouse[p].isMouseButtonClicked(MOUSE_BUTTON_TYPE_LEFT) and ShopMerchants_CurrentMerchant[id] == null then
if LeftClickTimer[id] == null then
set LeftClickTimer[id] = NewTimerEx(id)
endif
call TimerStart(LeftClickTimer[id], 0.1, true, function repeatLeftClick)
endif
endif
return false
endfunction
private function rightClick takes player p, integer id returns nothing
local real x
local real y
if UnitAlive(MainUnit[id]) then
if IsKeyVerified[id] then
static if USE_MEMORY_HACK then
if IsLAN then
set x = MouseX[id]
set y = MouseY[id]
else
set x = GetMouseX()
set y = GetMouseY()
endif
else
set x = GetPlayerMouseX(p)
set y = GetPlayerMouseY(p)
endif
if x != 0 and y != 0 or USE_MEMORY_HACK then
if IsUnitSelected(Controller[id], p) then
if ShopMerchants_CurrentMerchant[id] != null then
set ShopMerchants_CurrentMerchant[id] = null
if ShopUI[id].visible then
call ShopUI[id].show(false)
endif
if UpgradeMenu_Main[id].visible then
call UpgradeMenu_CloseWindow(id)
endif
else
call Fighter[id].move(x, y)
endif
else
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[id], true)
endif
endif
endif
endif
endif
endfunction
private function repeatRightClick takes nothing returns nothing
static if not USE_MEMORY_HACK then
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
local player p = Player(id)
call rightClick(p, id)
set t = null
endif
endfunction
public function onOrder takes nothing returns boolean
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(u)
local integer id = GetPlayerId(p)
if GetIssuedOrderId() != 851973 then
call rightClick(p, id)
static if not USE_MEMORY_HACK then
if UserMouse[p].isMouseButtonClicked(MOUSE_BUTTON_TYPE_RIGHT) and ShopMerchants_CurrentMerchant[id] == null then
if RightClickTimer[id] == null then
set RightClickTimer[id] = NewTimerEx(id)
endif
call TimerStart(RightClickTimer[id], 0.25, true, function repeatRightClick)
endif
endif
endif
set u = null
return false
endfunction
private function onMouseUp takes nothing returns boolean
static if not USE_MEMORY_HACK then
local integer id = GetPlayerId(GetTriggerPlayer())
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
call ReleaseTimer(RightClickTimer[id])
set RightClickTimer[id] = null
elseif BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_LEFT then
if CharacterWindowRotate_IsRotating[id] then
//set CharacterWindowRotate_IsRotating[id] = false
endif
call ReleaseTimer(LeftClickTimer[id])
set LeftClickTimer[id] = null
endif
endif
return false
endfunction
private function onMouseDown takes nothing returns boolean
static if not USE_MEMORY_HACK then
local player p = GetTriggerPlayer()
local integer id = GetPlayerId(p)
if UnitAlive(MainUnit[id]) then
if IsKeyVerified[id] then
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT and GetPlayerMouseX(p) != 0 and GetPlayerMouseY(p) != 0 then
if not IsUnitSelected(Controller[id], p) then
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[id], true)
endif
endif
else
endif
endif
endif
endif
return false
endfunction
private function RestartStreamEx takes nothing returns nothing
local timer t = GetExpiredTimer()
set RestartDelay = TimerGetTimeout(t)
set RestartId = GetTimerData(t)
call ExecuteFunc("RestartStream")
call ReleaseTimer(t)
set t = null
endfunction
private function StreamReceived takes nothing returns boolean
local SyncData d = GetSyncedData()
local integer id = d.readInt(0)
local real delay = d.readReal(2)
local string s
set MouseX[id] = d.readReal(0)
set MouseY[id] = d.readReal(1)
call d.destroy()
if IsPlaying[id] then
call TimerStart(NewTimerEx(id), RAbsBJ(delay), false, function RestartStreamEx)
endif
return false
endfunction
function RestartStream takes nothing returns nothing
local SyncData d = SyncData.create(Player(RestartId))
static if USE_MEMORY_HACK then
call d.addReal(GetMouseX())
call d.addReal(GetMouseY())
endif
call d.addReal(RestartDelay)
call d.addInt(RestartId)
set d.onComplete = Filter(function StreamReceived)
call d.start()
endfunction
private function StartStreamEx takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
local SyncData data
set data = SyncData.create(Player(id))
static if USE_MEMORY_HACK then
call data.addReal(GetMouseX())
call data.addReal(GetMouseY())
endif
call data.addReal(EST_PING/STREAM_ACC*(4-StreamCount[id]))
call data.addInt(id)
set data.onComplete = Filter(function StreamReceived)
call data.start()
set StreamCount[id] = StreamCount[id] - 1
if (StreamCount[id] > 0) then
call TimerStart(t, EST_PING/STREAM_ACC, false, function StartStreamEx)
else
call ReleaseTimer(t)
endif
set t = null
endfunction
public function StartStream takes integer id returns nothing
static if USE_MEMORY_HACK then
set StreamCount[id] = STREAM_ACC
call TimerStart(NewTimerEx(id), EST_PING/STREAM_ACC, false, function StartStreamEx)
endif
endfunction
private function init takes nothing returns nothing
call ShowDestructable(gg_dest_B038_1303, false)
call InitDest(gg_rct_InitArea, 0)
call InitDest(gg_rct_InteriorArea, 0)
call CreateTrack("war3mapImported\\TrackHUGE.mdx", 0, 0, 2050, 0)
call CreateTrack("war3mapImported\\TrackHUGE.mdx", 0, 0, 20, 0)
call ShowDestructable(gg_dest_B038_1303, true)
call RegisterAnyClickEvent(function onClick)
static if not USE_MEMORY_HACK then
call OnMouseEvent(function onMouseDown, EVENT_MOUSE_DOWN)
call OnMouseEvent(function onMouseUp, EVENT_MOUSE_UP)
endif
endfunction
endlibrary
scope Calibration
globals
private integer AttemptIndex = 0
private player TempPlayer = null
private group array SelectionGroup
endglobals
private function reselect takes nothing returns nothing
if Locale == TempPlayer then
call SelectUnit(GetEnumUnit(), true)
endif
endfunction
private function calibrate takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
local player p = Player(id)
call CalibrateNumberKeys(id)
if Locale == p then
call ClearTextMessages()
endif
if IsKeyVerified[id] then
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Calibration is done.")
else
call DisplayTimedTextToPlayer(p, 0, 0, 0, "Calibration is done.")
call DisplayTimedTextToPlayer(p, 0, 0, 0, "|cff00ff00Now press ANY number key (0-9) to verify the calibration.|r")
call DisplayTimedTextToPlayer(p, 0, 0, 0, "If nothing happens, try the calibration again by entering \"|cffffcc00-c|r\".")
call DisplayTimedTextToPlayer(p, 0, 0, 0, "Open Read Me (|cffffcc00F9|r) for more info about the calibration.")
endif
set TempPlayer = p
call ForGroup(SelectionGroup[id], function reselect)
call DestroyGroup(SelectionGroup[id])
set SelectionGroup[id] = null
call ReleaseTimer(t)
set t = null
endfunction
private function Trig_calibrate_Actions takes nothing returns nothing
local player p = GetTriggerPlayer()
local integer id = GetPlayerId(p)
if MainUnit[id] != null then
if SelectionGroup[id] == null then
set SelectionGroup[id] = CreateGroup()
if IsLAN then
call SyncSelections()
endif
call GroupEnumUnitsSelected(SelectionGroup[id], p, Filter(function FilterOutUI))
if Locale == p then
call ClearTextMessages()
endif
if (PatchVersion < PATCH_LEVEL_129) then
call DisplayTimedTextToPlayer(p, 0, 0, 0, "Calibrating number keys. Press and hold |cffffcc00CTRL|r key until it's completed.")
else
call DisplayTimedTextToPlayer(p, 0, 0, 0, "Calibrating number keys. Press and hold |cffffcc00SHIFT|r key until it's completed.")
endif
call TimerStart(NewTimerEx(id), 2.0, false, function calibrate)
endif
endif
endfunction
function InitTrig_Calibration takes nothing returns nothing
set gg_trg_Calibration = CreateTrigger()
call TriggerRegisterPlayerChatEvent(gg_trg_Calibration, Player(0), "-c", true)
call TriggerRegisterPlayerChatEvent(gg_trg_Calibration, Player(1), "-c", true)
call TriggerRegisterPlayerChatEvent(gg_trg_Calibration, Player(2), "-c", true)
call TriggerRegisterPlayerChatEvent(gg_trg_Calibration, Player(3), "-c", true)
call TriggerAddAction( gg_trg_Calibration, function Trig_calibrate_Actions )
endfunction
endscope
library DungeonStamp uses Ascii, DestructableHider
globals
//=========================================
//configurables
private constant integer TERRAIN_DEFAULT_TILE = 'Ddrt' //defines the default ground tile for the dungeon
private constant integer TERRAIN_DEFAULT_VARIANCE = 17 //defines the variation used for the default tile (use -1 for random)
private constant integer STAMP_SIZE = 5 //defines the edge size of each stamp; must be an odd number
private constant integer STAMP_SIZE_SQUARED = 25 //please calculate STAMP_SIZE*STAMP_SIZE and enter the value here
//limit:
// -> n * STAMP_SIZE_SQUARED < 8192
// -> for n = number of registered stamps
// -> print registry methods only supported for stamp size of 5
// -> for other sizes use rect registry method instead
private constant integer MAX_DESTRUCTABLES_PER_STAMP = 100 //defines the maximum number of destructables per stamp
//limit:
// -> n * MAX_DESTRUCTABLES_PER_STAMP < 8192
// -> for n = number of registered stamps
// -> print registry methods only supported for MAX_DESTRUCTABLES_PER_STAMP = 25
// -> for other values use rect registry method instead
constant string DUNGEON_PRINT_DIRECTORY = ".\\save\\" //This is the directory where all generated text files from the print commands will be saved.
//=========================================
//=========================================
constant integer STAMP_SIZE_REAL = STAMP_SIZE*128
constant integer ORIENTATION_0 = 0
constant integer ORIENTATION_90 = 200
constant integer ORIENTATION_180 = 400
constant integer ORIENTATION_270 = 600
private constant hashtable HASH = InitHashtable()
constant integer STAIR_UP_OFFSET = 20
constant integer STAIR_DOWN_OFFSET = 35
constant integer STAMP_OFFSET = 50
/*
These are the stamp shapes for the dungeon type
*/
constant integer SHAPE_BLACK = 0
constant integer SHAPE_HALL = 1 // Default Orientation:
constant integer SHAPE_WALL_L = 2 // I = 0° (left wall)
constant integer SHAPE_WALL_L_B = 3 // I_ = 0° (left wall and bottom wall)
constant integer SHAPE_WALL_L_B_R = 4 // I_I = 0° (left wall, bottom wall and right wall (dead end))
constant integer SHAPE_WALL_BL = 5 // . = 0° (wall in bottom left corner)
constant integer SHAPE_WALL_BL_TL = 6 // : = 0° (wall in bottom left and top left corner)
constant integer SHAPE_WALL_BL_TR = 7 // . ' = 0° (wall in bottom left and top right corner)
constant integer SHAPE_WALL_BL_TL_BR = 8 // : . = 0° (wall in bottom left, top left and bottom right corner)
constant integer SHAPE_WALL_BL_TL_BR_TP = 9 // : : = 0° (wall in all corners, plus-shaped corridor)
constant integer SHAPE_WALL_L_BR = 10 // I . = 0° (left wall and bottom right corner)
constant integer SHAPE_WALL_L_TR = 11 // I ' = 0° (left wall and top right corner)
constant integer SHAPE_WALL_L_R = 12 // I I = 0° (left wall and right wall)
constant integer SHAPE_WALL_L_B_TR = 13 // I_' = 0° (left wall, bottom wall, top-right corner)
constant integer SHAPE_WALL_L_BR_TR = 14 // I : = 0° (left wall, bottom-right corner and top-right corner)
constant integer SHAPE_STAIRS_UP_WALL = SHAPE_WALL_L + STAIR_UP_OFFSET
// I> = 0° (Stairs in western wall, poiting east)
constant integer SHAPE_STAIRS_UP_HALL = SHAPE_HALL + STAIR_UP_OFFSET
// > = 0° (Stairs inside room, pointing east)
constant integer SHAPE_STAIRS_UP_END = SHAPE_WALL_L_B_R + STAIR_UP_OFFSET
// I^I = 0° (Stairs at dead end, pointing north)
constant integer SHAPE_STAIRS_DOWN_WALL = SHAPE_WALL_L + STAIR_DOWN_OFFSET
// I> = 0° (Stairs in western wall, poiting east)
constant integer SHAPE_STAIRS_DOWN_HALL = SHAPE_HALL + STAIR_DOWN_OFFSET
// > = 0° (Stairs inside room, pointing east)
constant integer SHAPE_STAIRS_DOWN_END = SHAPE_WALL_L_B_R + STAIR_DOWN_OFFSET
endglobals
struct stamp
private integer shape
private integer number
private integer tile
private real rare
integer data
real value
integer array destraw[MAX_DESTRUCTABLES_PER_STAMP]
real array destx[MAX_DESTRUCTABLES_PER_STAMP]
real array desty[MAX_DESTRUCTABLES_PER_STAMP]
real array destrot[MAX_DESTRUCTABLES_PER_STAMP]
integer array terrain[STAMP_SIZE_SQUARED]
integer array variation[STAMP_SIZE_SQUARED]
private static thistype temp
private static integer tempindex = 0
private static real tempx = 0
private static real tempy = 0
private static integer intI = 0
private static integer intJ = 0
static method create takes integer shp, integer tileset, real rarity, integer customdata, real customvalue returns thistype
local thistype this = thistype.allocate()
set this.shape = shp
set this.tile = tileset
set this.rare = rarity
set this.data = customdata
set this.value = customvalue
set this.number = LoadInteger(HASH, this.shape, 0) + 1
call SaveInteger(HASH, this.shape, 0, this.number)
call SaveInteger(HASH, this.shape, this.number, this)
return this
endmethod
static method setDestructableData takes integer raw, real scale, real z, boolean dead returns nothing
call SaveReal(HASH, raw, 0, scale)
call SaveReal(HASH, raw, 1, z)
call SaveBoolean(HASH, raw, 2, dead)
endmethod
static method getDestructableScale takes integer raw returns real
if HaveSavedReal(HASH, raw, 0) then
return LoadReal(HASH, raw, 0)
endif
return 1.
endmethod
static method getDestructableZ takes integer raw returns real
if HaveSavedReal(HASH, raw, 1) then
return LoadReal(HASH, raw, 1)
endif
return 0.
endmethod
static method getDestructableAlive takes integer raw returns boolean
if HaveSavedBoolean(HASH, raw, 2) then
return LoadBoolean(HASH, raw, 2)
endif
return true
endmethod
method canHaveStairs takes nothing returns boolean
local integer shp = ModuloInteger(this.shape, STAMP_OFFSET)
return (shp == SHAPE_WALL_L or shp == SHAPE_WALL_L_B_R or shp == SHAPE_HALL)
endmethod
static method removeSub takes nothing returns nothing
call RemoveDestructable(GetEnumDestructable())
call DestructableHider_unregister(GetEnumDestructable())
endmethod
static method remove takes rect area, integer gridX, integer gridY returns nothing
local integer i = 0
local integer j
local real x = GetRectMinX(area)+gridX*STAMP_SIZE_REAL
local real y = GetRectMinY(area)+gridY*STAMP_SIZE_REAL
local rect r = Rect(x-16, y-16, x+16+STAMP_SIZE_REAL, y+16+STAMP_SIZE_REAL)
loop
exitwhen i >= STAMP_SIZE
set j = 0
loop
exitwhen j >= STAMP_SIZE
set x = GetRectMinX(area)+gridX*STAMP_SIZE_REAL+i*128
set y = GetRectMinY(area)+gridY*STAMP_SIZE_REAL+j*128
if x <= GetRectMaxX(area) and y <= GetRectMaxY(area) then
call SetTerrainType(x, y, TERRAIN_DEFAULT_TILE, TERRAIN_DEFAULT_VARIANCE, 1, 1)
endif
set j = j + 1
endloop
set i = i + 1
endloop
if GetRectMaxX(r) <= GetRectMaxX(area) and GetRectMaxY(r) <= GetRectMaxY(area) then
call EnumDestructablesInRect(r, null, function thistype.removeSub)
else
call SetRect(r, GetRectMinX(r), GetRectMinY(r), GetRectMaxX(area), GetRectMaxY(area))
call EnumDestructablesInRect(r, null, function thistype.removeSub)
endif
call RemoveRect(r)
set r = null
endmethod
method place takes rect area, integer gridX, integer gridY, integer orientation returns nothing
local integer i = 0
local integer j
local location loc = Location(0,0)
local real x
local real y
local integer u
local integer v
call thistype.remove(area, gridX, gridY) //remove existing stamps
//paint ground tiles
if intJ != intI then
set intJ = intI
endif
set intI = intI + 1
if GetRectMinX(area)+gridX*STAMP_SIZE_REAL <= GetRectMaxX(area) and GetRectMinY(area)+gridY*STAMP_SIZE_REAL <= GetRectMaxY(area) then
loop
exitwhen i >= STAMP_SIZE
set j = 0
loop
exitwhen j >= STAMP_SIZE
set x = GetRectMinX(area)+gridX*STAMP_SIZE_REAL+i*128
set y = GetRectMinY(area)+gridY*STAMP_SIZE_REAL+j*128
if orientation == ORIENTATION_0 then
set u = i
set v = j
elseif orientation == ORIENTATION_90 then
set u = j
set v = STAMP_SIZE-1-i
elseif orientation == ORIENTATION_180 then
set u = STAMP_SIZE-1-i
set v = STAMP_SIZE-1-j
else
set u = STAMP_SIZE-1-j
set v = i
endif
call SetTerrainType(x, y, this.terrain[u*STAMP_SIZE+v], this.variation[u*STAMP_SIZE+v], 1, 1)
if i == (STAMP_SIZE-1) then
if this.terrain[u*STAMP_SIZE+v] != TERRAIN_DEFAULT_TILE and GetTerrainType(x+128, y) == TERRAIN_DEFAULT_TILE then
call SetTerrainType(x+128, y, this.terrain[u*STAMP_SIZE+v], this.variation[u*STAMP_SIZE+v], 1, 1)
endif
endif
if j == (STAMP_SIZE-1) then
if this.terrain[u*STAMP_SIZE+v] != TERRAIN_DEFAULT_TILE and GetTerrainType(x, y+128) == TERRAIN_DEFAULT_TILE then
call SetTerrainType(x, y+128, this.terrain[u*STAMP_SIZE+v], this.variation[u*STAMP_SIZE+v], 1, 1)
endif
endif
if u == (STAMP_SIZE-1) and j == (STAMP_SIZE-1) then
if this.terrain[u*STAMP_SIZE+v] != TERRAIN_DEFAULT_TILE and GetTerrainType(x+128, y+128) == TERRAIN_DEFAULT_TILE then
call SetTerrainType(x+128, y+128, this.terrain[u*STAMP_SIZE+v], this.variation[u*STAMP_SIZE+v], 1, 1)
endif
endif
set j = j + 1
endloop
set i = i + 1
endloop
if orientation == ORIENTATION_0 then
if this.shape == SHAPE_BLACK then
set MiniMap_TileTexture[gridX][gridY] = "ReplaceableTextures\\CommandButtons\\BTNalpha.blp"
elseif this.shape == SHAPE_HALL then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\L.blp"
elseif this.shape == SHAPE_WALL_L_B then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\BL.blp"
elseif this.shape == SHAPE_WALL_L_B_R then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\LBR.blp"
elseif this.shape == SHAPE_WALL_BL then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TL then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TL_BR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TL_BR_TP then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L_BR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\L.blp"
elseif this.shape == SHAPE_WALL_L_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\L.blp"
elseif this.shape == SHAPE_WALL_L_R then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\LR.blp"
elseif this.shape == SHAPE_WALL_L_B_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\BL.blp"
elseif this.shape == SHAPE_WALL_L_BR_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\L.blp"
elseif this.shape == SHAPE_WALL_L+STAIR_UP_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\L.blp"
elseif this.shape == SHAPE_HALL+STAIR_UP_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L_B_R+STAIR_UP_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\LBR.blp"
elseif this.shape == SHAPE_WALL_L+STAIR_DOWN_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\L.blp"
elseif this.shape == SHAPE_HALL+STAIR_DOWN_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L_B_R+STAIR_DOWN_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\LBR.blp"
endif
elseif orientation == ORIENTATION_90 then
if this.shape == SHAPE_BLACK then
set MiniMap_TileTexture[gridX][gridY] = "ReplaceableTextures\\CommandButtons\\BTNalpha.blp"
elseif this.shape == SHAPE_HALL then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\B.blp"
elseif this.shape == SHAPE_WALL_L_B then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\BR.blp"
elseif this.shape == SHAPE_WALL_L_B_R then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\TRB.blp"
elseif this.shape == SHAPE_WALL_BL then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TL then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TL_BR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TL_BR_TP then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L_BR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\B.blp"
elseif this.shape == SHAPE_WALL_L_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\B.blp"
elseif this.shape == SHAPE_WALL_L_R then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\TB.blp"
elseif this.shape == SHAPE_WALL_L_B_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\BR.blp"
elseif this.shape == SHAPE_WALL_L_BR_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\B.blp"
elseif this.shape == SHAPE_WALL_L+STAIR_UP_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\B.blp"
elseif this.shape == SHAPE_HALL+STAIR_UP_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L_B_R+STAIR_UP_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\TLB.blp"
elseif this.shape == SHAPE_WALL_L+STAIR_DOWN_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\B.blp"
elseif this.shape == SHAPE_HALL+STAIR_DOWN_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L_B_R+STAIR_DOWN_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\TLB.blp"
endif
elseif orientation == ORIENTATION_180 then
if this.shape == SHAPE_BLACK then
set MiniMap_TileTexture[gridX][gridY] = "ReplaceableTextures\\CommandButtons\\BTNalpha.blp"
elseif this.shape == SHAPE_HALL then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\R.blp"
elseif this.shape == SHAPE_WALL_L_B then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\TR.blp"
elseif this.shape == SHAPE_WALL_L_B_R then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\LTR.blp"
elseif this.shape == SHAPE_WALL_BL then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TL then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TL_BR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TL_BR_TP then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L_BR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\R.blp"
elseif this.shape == SHAPE_WALL_L_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\R.blp"
elseif this.shape == SHAPE_WALL_L_R then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\LR.blp"
elseif this.shape == SHAPE_WALL_L_B_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\TR.blp"
elseif this.shape == SHAPE_WALL_L_BR_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\R.blp"
elseif this.shape == SHAPE_WALL_L+STAIR_UP_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\R.blp"
elseif this.shape == SHAPE_HALL+STAIR_UP_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L_B_R+STAIR_UP_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\MLTR.blp"
elseif this.shape == SHAPE_WALL_L+STAIR_DOWN_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\R.blp"
elseif this.shape == SHAPE_HALL+STAIR_DOWN_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L_B_R+STAIR_DOWN_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\MLTR.blp"
endif
else
if this.shape == SHAPE_BLACK then
set MiniMap_TileTexture[gridX][gridY] = "ReplaceableTextures\\CommandButtons\\BTNalpha.blp"
elseif this.shape == SHAPE_HALL then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\T.blp"
elseif this.shape == SHAPE_WALL_L_B then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\TL.blp"
elseif this.shape == SHAPE_WALL_L_B_R then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\TLB.blp"
elseif this.shape == SHAPE_WALL_BL then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TL then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TL_BR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_BL_TL_BR_TP then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L_BR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\T.blp"
elseif this.shape == SHAPE_WALL_L_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\T.blp"
elseif this.shape == SHAPE_WALL_L_R then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\TB.blp"
elseif this.shape == SHAPE_WALL_L_B_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\TL.blp"
elseif this.shape == SHAPE_WALL_L_BR_TR then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\T.blp"
elseif this.shape == SHAPE_WALL_L+STAIR_UP_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\T.blp"
elseif this.shape == SHAPE_HALL+STAIR_UP_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L_B_R+STAIR_UP_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\TRB.blp"
elseif this.shape == SHAPE_WALL_L+STAIR_DOWN_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\T.blp"
elseif this.shape == SHAPE_HALL+STAIR_DOWN_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\M.blp"
elseif this.shape == SHAPE_WALL_L_B_R+STAIR_DOWN_OFFSET then
set MiniMap_TileTexture[gridX][gridY] = "MiniMap\\TRB.blp"
endif
endif
//place destructables
set i = 0
loop
exitwhen i >= MAX_DESTRUCTABLES_PER_STAMP
if this.destraw[i] != 0 then
if orientation == ORIENTATION_0 then
call MoveLocation(loc, GetRectMinX(area)+gridX*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2+this.destx[i], GetRectMinY(area)+gridY*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2+this.desty[i])
if stamp.getDestructableAlive(this.destraw[i]) then
call SetDestructableLife(CreateDestructableZ(this.destraw[i], GetLocationX(loc), GetLocationY(loc), GetLocationZ(loc)+stamp.getDestructableZ(this.destraw[i]), this.destrot[i], stamp.getDestructableScale(this.destraw[i]), 0), this.destrot[i]+360)
else
call SetDestructableLife(CreateDeadDestructableZ(this.destraw[i], GetLocationX(loc), GetLocationY(loc), GetLocationZ(loc)+stamp.getDestructableZ(this.destraw[i]), this.destrot[i], stamp.getDestructableScale(this.destraw[i]), 0), this.destrot[i]+360)
endif
elseif orientation == ORIENTATION_90 then
call MoveLocation(loc, GetRectMinX(area)+gridX*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2-this.desty[i], GetRectMinY(area)+gridY*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2+this.destx[i])
if stamp.getDestructableAlive(this.destraw[i]) then
call SetDestructableLife(CreateDestructableZ(this.destraw[i], GetLocationX(loc), GetLocationY(loc), GetLocationZ(loc)+stamp.getDestructableZ(this.destraw[i]), this.destrot[i]+90, stamp.getDestructableScale(this.destraw[i]), 0), this.destrot[i]+450)
else
call SetDestructableLife(CreateDeadDestructableZ(this.destraw[i], GetLocationX(loc), GetLocationY(loc), GetLocationZ(loc)+stamp.getDestructableZ(this.destraw[i]), this.destrot[i]+90, stamp.getDestructableScale(this.destraw[i]), 0), this.destrot[i]+450)
endif
elseif orientation == ORIENTATION_180 then
call MoveLocation(loc, GetRectMinX(area)+gridX*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2-this.destx[i], GetRectMinY(area)+gridY*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2-this.desty[i])
if stamp.getDestructableAlive(this.destraw[i]) then
call SetDestructableLife(CreateDestructableZ(this.destraw[i], GetLocationX(loc), GetLocationY(loc), GetLocationZ(loc)+stamp.getDestructableZ(this.destraw[i]), this.destrot[i]+180, stamp.getDestructableScale(this.destraw[i]), 0), this.destrot[i]+540)
else
call SetDestructableLife(CreateDeadDestructableZ(this.destraw[i], GetLocationX(loc), GetLocationY(loc), GetLocationZ(loc)+stamp.getDestructableZ(this.destraw[i]), this.destrot[i]+180, stamp.getDestructableScale(this.destraw[i]), 0), this.destrot[i]+540)
endif
else
call MoveLocation(loc, GetRectMinX(area)+gridX*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2+this.desty[i], GetRectMinY(area)+gridY*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2-this.destx[i])
if stamp.getDestructableAlive(this.destraw[i]) then
call SetDestructableLife(CreateDestructableZ(this.destraw[i], GetLocationX(loc), GetLocationY(loc), GetLocationZ(loc)+stamp.getDestructableZ(this.destraw[i]), this.destrot[i]+270, stamp.getDestructableScale(this.destraw[i]), 0), this.destrot[i]+630)
else
call SetDestructableLife(CreateDeadDestructableZ(this.destraw[i], GetLocationX(loc), GetLocationY(loc), GetLocationZ(loc)+stamp.getDestructableZ(this.destraw[i]), this.destrot[i]+270, stamp.getDestructableScale(this.destraw[i]), 0), this.destrot[i]+630)
endif
endif
endif
set i = i + 1
endloop
endif
call RemoveLocation(loc)
set intJ = intJ + 1
set loc = null
endmethod
private static method getDest takes nothing returns boolean
local destructable d = GetFilterDestructable()
if thistype.tempindex < MAX_DESTRUCTABLES_PER_STAMP then
set thistype.temp.destraw[thistype.tempindex] = GetDestructableTypeId(d)
set thistype.temp.destx[thistype.tempindex] = GetDestructableX(d)-thistype.tempx
set thistype.temp.desty[thistype.tempindex] = GetDestructableY(d)-thistype.tempy
if GetDestructableLife(d) == GetDestructableMaxLife(d) then
set thistype.temp.destrot[thistype.tempindex] = 0
else
set thistype.temp.destrot[thistype.tempindex] = ModuloReal(GetDestructableLife(d)/GetDestructableMaxLife(d)*1000, 360)
endif
set thistype.tempindex = thistype.tempindex + 1
else
call BJDebugMsg("ERROR: Stamp contains too many destructables! Increase MAX_DESTRUCTABLES_PER_STAMP or reduce number of destructables!")
endif
set d = null
return false
endmethod
static method register takes rect which, integer shp, integer tileset, real rarity, integer customdata, real customvalue returns thistype
local thistype this = thistype.create(shp, tileset, rarity, customdata, customvalue)
local integer i = 0
local integer j
set thistype.temp = this
set thistype.tempindex = 0
set thistype.tempx = GetRectMinX(which)+STAMP_SIZE_REAL/2
set thistype.tempy = GetRectMinY(which)+STAMP_SIZE_REAL/2
call EnumDestructablesInRect(which, Condition(function thistype.getDest), null)
loop
exitwhen i >= STAMP_SIZE
set j = 0
loop
exitwhen j >= STAMP_SIZE
set this.terrain[i*STAMP_SIZE+j] = GetTerrainType(GetRectMinX(which)+i*128, GetRectMinY(which)+j*128)
set this.variation[i*STAMP_SIZE+j] = GetTerrainVariance(GetRectMinX(which)+i*128, GetRectMinY(which)+j*128)
set j = j + 1
endloop
set i = i + 1
endloop
return this
endmethod
static method placeByLogic takes rect area, integer x, integer y, boolean isCave, boolean isStairs, boolean isUp, integer fromTileset, boolean sw, boolean w, boolean nw, boolean s, boolean c, boolean n, boolean se, boolean e, boolean ne returns thistype
local integer wc = 0
local integer cc = 0
local thistype this
local thistype array valid
local integer validcount = 0
local integer i = 0
local integer shp = -1
local integer max = 0
local integer orient = 0
local integer stairs = 0
if isStairs then
if isUp then
set stairs = STAIR_UP_OFFSET
else
set stairs = STAIR_DOWN_OFFSET
endif
endif
if sw and not (s or w) then
set cc = cc + 1
endif
if nw and not (n or w) then
set cc = cc + 1
endif
if se and not (s or e) then
set cc = cc + 1
endif
if ne and not (n or e) then
set cc = cc + 1
endif
if w then
set wc = wc + 1
endif
if s then
set wc = wc + 1
endif
if n then
set wc = wc + 1
endif
if e then
set wc = wc + 1
endif
if c then
set shp = SHAPE_BLACK + ORIENTATION_0
else
if wc == 0 then
if cc == 0 then
set shp = SHAPE_HALL + GetRandomInt(0,3)*ORIENTATION_90 + stairs
elseif cc == 1 then
if sw then
set shp = SHAPE_WALL_BL + ORIENTATION_0
elseif se then
set shp = SHAPE_WALL_BL + ORIENTATION_90
elseif ne then
set shp = SHAPE_WALL_BL + ORIENTATION_180
elseif nw then
set shp = SHAPE_WALL_BL + ORIENTATION_270
endif
elseif cc == 2 then
if sw and nw then
set shp = SHAPE_WALL_BL_TL + ORIENTATION_0
elseif sw and se then
set shp = SHAPE_WALL_BL_TL + ORIENTATION_90
elseif se and ne then
set shp = SHAPE_WALL_BL_TL + ORIENTATION_180
elseif ne and nw then
set shp = SHAPE_WALL_BL_TL + ORIENTATION_270
elseif sw and ne then
set shp = SHAPE_WALL_BL_TR + (GetRandomInt(0,1)*2)*ORIENTATION_90
elseif se and nw then
set shp = SHAPE_WALL_BL_TR + (GetRandomInt(0,1)*2+1)*ORIENTATION_90
endif
elseif cc == 3 then
if not ne then
set shp = SHAPE_WALL_BL_TL_BR + ORIENTATION_0
elseif not nw then
set shp = SHAPE_WALL_BL_TL_BR + ORIENTATION_90
elseif not sw then
set shp = SHAPE_WALL_BL_TL_BR + ORIENTATION_180
elseif not se then
set shp = SHAPE_WALL_BL_TL_BR + ORIENTATION_270
endif
elseif cc == 4 then
set shp = SHAPE_WALL_BL_TL_BR_TP + GetRandomInt(0,3)*ORIENTATION_90
endif
elseif wc == 1 then
if cc == 0 then
if w then
set shp = SHAPE_WALL_L + ORIENTATION_0 + stairs
elseif s then
set shp = SHAPE_WALL_L + ORIENTATION_90 + stairs
elseif e then
set shp = SHAPE_WALL_L + ORIENTATION_180 + stairs
elseif n then
set shp = SHAPE_WALL_L + ORIENTATION_270 + stairs
endif
elseif cc == 1 then
if w then
if se then
set shp = SHAPE_WALL_L_BR + ORIENTATION_0
elseif ne then
set shp = SHAPE_WALL_L_TR + ORIENTATION_0
endif
elseif s then
if ne then
set shp = SHAPE_WALL_L_BR + ORIENTATION_90
elseif nw then
set shp = SHAPE_WALL_L_TR + ORIENTATION_90
endif
elseif e then
if nw then
set shp = SHAPE_WALL_L_BR + ORIENTATION_180
elseif sw then
set shp = SHAPE_WALL_L_TR + ORIENTATION_180
endif
elseif n then
if sw then
set shp = SHAPE_WALL_L_BR + ORIENTATION_270
elseif se then
set shp = SHAPE_WALL_L_TR + ORIENTATION_270
endif
endif
elseif cc == 2 then
if w then
set shp = SHAPE_WALL_L_BR_TR + ORIENTATION_0
elseif s then
set shp = SHAPE_WALL_L_BR_TR + ORIENTATION_90
elseif e then
set shp = SHAPE_WALL_L_BR_TR + ORIENTATION_180
elseif n then
set shp = SHAPE_WALL_L_BR_TR + ORIENTATION_270
endif
endif
elseif wc == 2 then
if cc == 0 then
if w and s then
set shp = SHAPE_WALL_L_B + ORIENTATION_0
elseif s and e then
set shp = SHAPE_WALL_L_B + ORIENTATION_90
elseif e and n then
set shp = SHAPE_WALL_L_B + ORIENTATION_180
elseif n and w then
set shp = SHAPE_WALL_L_B + ORIENTATION_270
elseif w and e then
set shp = SHAPE_WALL_L_R + (GetRandomInt(0,1)*2)*ORIENTATION_90
elseif n and s then
set shp = SHAPE_WALL_L_R + (GetRandomInt(0,1)*2+1)*ORIENTATION_90
endif
elseif cc == 1 then
if w and s then
set shp = SHAPE_WALL_L_B_TR + ORIENTATION_0
elseif s and e then
set shp = SHAPE_WALL_L_B_TR + ORIENTATION_90
elseif e and n then
set shp = SHAPE_WALL_L_B_TR + ORIENTATION_180
elseif n and w then
set shp = SHAPE_WALL_L_B_TR + ORIENTATION_270
endif
endif
elseif wc == 3 then
if not n then
set shp = SHAPE_WALL_L_B_R + ORIENTATION_0 + stairs
elseif not w then
set shp = SHAPE_WALL_L_B_R + ORIENTATION_90 + stairs
elseif not s then
set shp = SHAPE_WALL_L_B_R + ORIENTATION_180 + stairs
elseif not e then
set shp = SHAPE_WALL_L_B_R + ORIENTATION_270 + stairs
endif
elseif wc == 4 then
set shp = SHAPE_BLACK + ORIENTATION_0
endif
endif
if shp == -1 then
call BJDebugMsg("ERROR: no shape found by wall logic!")
return 0
else
set max = shp
set shp = ModuloInteger(shp,ORIENTATION_90)
set orient = max-shp
endif
set max = LoadInteger(HASH, shp, 0)
set i = 1
loop
exitwhen i > max
set this = LoadInteger(HASH, shp, i)
if this.tile == fromTileset then
if validcount <= 0 then
set valid[validcount] = this
set validcount = validcount+1
elseif GetRandomReal(0,1) <= this.rare then
set valid[validcount] = this
set validcount = validcount+1
endif
endif
set i = i + 1
endloop
if validcount <= 0 then
if HaveSavedInteger(HASH, shp, 1) then
set valid[0] = LoadInteger(HASH, shp, 1)
set validcount = 1
else
call BJDebugMsg("ERROR: No registered stamp found. Please register stamps for this tileset before calling the build algorithm!")
return 0
endif
endif
set this = valid[GetRandomInt(0,validcount-1)]
/*if ActiveScroll.id.dungeonType == 0 then
if this == st[55] then
set this = st[0]
endif
elseif ActiveScroll.id.dungeonType == 1 then
if this == st[0] or this == st[49] or this == st[50] or this == st[51] or this == st[53] or this == st[54] then
set this = st[55]
endif
endif*/
call this.place(area,x,y,orient)
return this
endmethod
method print takes nothing returns nothing
local integer i = 0
local string terraindump = ""
local string variationdump = ""
local string destrawdump = ""
local string xdump = ""
local string ydump = ""
local string facedump = ""
if MAX_DESTRUCTABLES_PER_STAMP == 25 and STAMP_SIZE_SQUARED == 25 then
loop
exitwhen i >= 25
if i > 0 then
set terraindump = terraindump + ",'" + A2S(this.terrain[i]) + "'"
set variationdump = variationdump + "," + I2S(this.variation[i])
if this.destraw[i] != 0 then
set destrawdump = destrawdump + ",'" + A2S(this.destraw[i]) + "'"
else
set destrawdump = destrawdump + ",0"
endif
set xdump = xdump + "," + I2S(R2I(this.destx[i]))
set ydump = ydump + "," + I2S(R2I(this.desty[i]))
set facedump = facedump + "," + I2S(R2I(this.destrot[i]))
else
set terraindump = "'" + A2S(this.terrain[i]) + "'"
set variationdump = I2S(this.variation[i])
if this.destraw[i] != 0 then
set destrawdump = "'" + A2S(this.destraw[i]) + "'"
else
set destrawdump = "0"
endif
set xdump = I2S(R2I(this.destx[i]))
set ydump = I2S(R2I(this.desty[i]))
set facedump = I2S(R2I(this.destrot[i]))
endif
set i = i + 1
endloop
call PreloadGenClear()
call PreloadGenStart()
call Preload("\")\n\n call data.registerTerrain("+terraindump+") \n\n//")
call Preload("\")\n\n call data.registerVariation("+variationdump+") \n\n//")
call Preload("\")\n\n call data.registerDestructable("+destrawdump+") \n\n//")
call Preload("\")\n\n call data.registerDestX("+xdump+") \n\n//")
call Preload("\")\n\n call data.registerDestY("+ydump+") \n\n//")
call Preload("\")\n\n call data.registerDestFace("+facedump+") \n\n//")
call Preload("\")\n\n \n\n//")
call PreloadGenEnd(DUNGEON_PRINT_DIRECTORY+"stamp(shape"+I2S(this.shape)+").txt")
else
call BJDebugMsg("ERROR: Text-based stamp registry only supported for default values of stamp size (5x5) and destructables per stamp (25)!")
endif
endmethod
//==========================================================================
//The following methods are wrappers designed for use with the .print method
//==========================================================================
method registerTerrain takes integer t00, integer t01, integer t02, integer t03, integer t04, integer t10, integer t11, integer t12, integer t13, integer t14, integer t20, integer t21, integer t22, integer t23, integer t24, integer t30, integer t31, integer t32, integer t33, integer t34, integer t40, integer t41, integer t42, integer t43, integer t44 returns nothing
if STAMP_SIZE_SQUARED == 25 then
set this.terrain[0] = t00
set this.terrain[1] = t01
set this.terrain[2] = t02
set this.terrain[3] = t03
set this.terrain[4] = t04
set this.terrain[5] = t10
set this.terrain[6] = t11
set this.terrain[7] = t12
set this.terrain[8] = t13
set this.terrain[9] = t14
set this.terrain[10] = t20
set this.terrain[11] = t21
set this.terrain[12] = t22
set this.terrain[13] = t23
set this.terrain[14] = t24
set this.terrain[15] = t30
set this.terrain[16] = t31
set this.terrain[17] = t32
set this.terrain[18] = t33
set this.terrain[19] = t34
set this.terrain[20] = t40
set this.terrain[21] = t41
set this.terrain[22] = t42
set this.terrain[23] = t43
set this.terrain[24] = t44
endif
endmethod
method registerVariation takes integer t00, integer t01, integer t02, integer t03, integer t04, integer t10, integer t11, integer t12, integer t13, integer t14, integer t20, integer t21, integer t22, integer t23, integer t24, integer t30, integer t31, integer t32, integer t33, integer t34, integer t40, integer t41, integer t42, integer t43, integer t44 returns nothing
if STAMP_SIZE_SQUARED == 25 then
set this.variation[0] = t00
set this.variation[1] = t01
set this.variation[2] = t02
set this.variation[3] = t03
set this.variation[4] = t04
set this.variation[5] = t10
set this.variation[6] = t11
set this.variation[7] = t12
set this.variation[8] = t13
set this.variation[9] = t14
set this.variation[10] = t20
set this.variation[11] = t21
set this.variation[12] = t22
set this.variation[13] = t23
set this.variation[14] = t24
set this.variation[15] = t30
set this.variation[16] = t31
set this.variation[17] = t32
set this.variation[18] = t33
set this.variation[19] = t34
set this.variation[20] = t40
set this.variation[21] = t41
set this.variation[22] = t42
set this.variation[23] = t43
set this.variation[24] = t44
endif
endmethod
method registerDestructable takes integer t00, integer t01, integer t02, integer t03, integer t04, integer t10, integer t11, integer t12, integer t13, integer t14, integer t20, integer t21, integer t22, integer t23, integer t24, integer t30, integer t31, integer t32, integer t33, integer t34, integer t40, integer t41, integer t42, integer t43, integer t44 returns nothing
if MAX_DESTRUCTABLES_PER_STAMP == 25 then
set this.destraw[0] = t00
set this.destraw[1] = t01
set this.destraw[2] = t02
set this.destraw[3] = t03
set this.destraw[4] = t04
set this.destraw[5] = t10
set this.destraw[6] = t11
set this.destraw[7] = t12
set this.destraw[8] = t13
set this.destraw[9] = t14
set this.destraw[10] = t20
set this.destraw[11] = t21
set this.destraw[12] = t22
set this.destraw[13] = t23
set this.destraw[14] = t24
set this.destraw[15] = t30
set this.destraw[16] = t31
set this.destraw[17] = t32
set this.destraw[18] = t33
set this.destraw[19] = t34
set this.destraw[20] = t40
set this.destraw[21] = t41
set this.destraw[22] = t42
set this.destraw[23] = t43
set this.destraw[24] = t44
endif
endmethod
method registerDestX takes real t00, real t01, real t02, real t03, real t04, real t10, real t11, real t12, real t13, real t14, real t20, real t21, real t22, real t23, real t24, real t30, real t31, real t32, real t33, real t34, real t40, real t41, real t42, real t43, real t44 returns nothing
if MAX_DESTRUCTABLES_PER_STAMP == 25 then
set this.destx[0] = t00
set this.destx[1] = t01
set this.destx[2] = t02
set this.destx[3] = t03
set this.destx[4] = t04
set this.destx[5] = t10
set this.destx[6] = t11
set this.destx[7] = t12
set this.destx[8] = t13
set this.destx[9] = t14
set this.destx[10] = t20
set this.destx[11] = t21
set this.destx[12] = t22
set this.destx[13] = t23
set this.destx[14] = t24
set this.destx[15] = t30
set this.destx[16] = t31
set this.destx[17] = t32
set this.destx[18] = t33
set this.destx[19] = t34
set this.destx[20] = t40
set this.destx[21] = t41
set this.destx[22] = t42
set this.destx[23] = t43
set this.destx[24] = t44
endif
endmethod
method registerDestY takes real t00, real t01, real t02, real t03, real t04, real t10, real t11, real t12, real t13, real t14, real t20, real t21, real t22, real t23, real t24, real t30, real t31, real t32, real t33, real t34, real t40, real t41, real t42, real t43, real t44 returns nothing
if MAX_DESTRUCTABLES_PER_STAMP == 25 then
set this.desty[0] = t00
set this.desty[1] = t01
set this.desty[2] = t02
set this.desty[3] = t03
set this.desty[4] = t04
set this.desty[5] = t10
set this.desty[6] = t11
set this.desty[7] = t12
set this.desty[8] = t13
set this.desty[9] = t14
set this.desty[10] = t20
set this.desty[11] = t21
set this.desty[12] = t22
set this.desty[13] = t23
set this.desty[14] = t24
set this.desty[15] = t30
set this.desty[16] = t31
set this.desty[17] = t32
set this.desty[18] = t33
set this.desty[19] = t34
set this.desty[20] = t40
set this.desty[21] = t41
set this.desty[22] = t42
set this.desty[23] = t43
set this.desty[24] = t44
endif
endmethod
method registerDestFace takes real t00, real t01, real t02, real t03, real t04, real t10, real t11, real t12, real t13, real t14, real t20, real t21, real t22, real t23, real t24, real t30, real t31, real t32, real t33, real t34, real t40, real t41, real t42, real t43, real t44 returns nothing
if MAX_DESTRUCTABLES_PER_STAMP == 25 then
set this.destrot[0] = t00
set this.destrot[1] = t01
set this.destrot[2] = t02
set this.destrot[3] = t03
set this.destrot[4] = t04
set this.destrot[5] = t10
set this.destrot[6] = t11
set this.destrot[7] = t12
set this.destrot[8] = t13
set this.destrot[9] = t14
set this.destrot[10] = t20
set this.destrot[11] = t21
set this.destrot[12] = t22
set this.destrot[13] = t23
set this.destrot[14] = t24
set this.destrot[15] = t30
set this.destrot[16] = t31
set this.destrot[17] = t32
set this.destrot[18] = t33
set this.destrot[19] = t34
set this.destrot[20] = t40
set this.destrot[21] = t41
set this.destrot[22] = t42
set this.destrot[23] = t43
set this.destrot[24] = t44
endif
endmethod
endstruct
endlibrary
library DungeonGenerator
globals
constant integer DUNGEON_SIZE_X = 30 //grid dimensions of the dungeon integer field
constant integer DUNGEON_SIZE_Y = 30
//Ingame coordinates: DUNGEON_SIZE_X * TILE_SIZE * 128
private constant real DUNGEON_VERIFICATION_THRESHOLD = 0.1 //fraction of a generated dungeon map that must be verified as reachable before the verification algorithm stops
private constant integer MAX_VERIFY_ATTEMPTS = 10 //maximum number of verification attempts to reach the specified threshold
//-> when failing, the generated map is considered unusable and should be discarded by the user
//====================
//end of configurables
constant integer DUNGEON_EMPTY = 0
constant integer DUNGEON_ROOM = 1
constant integer DUNGEON_CAVE = 2
constant integer DUNGEON_CORRIDOR = 3
endglobals
struct Room
thistype llPrev
thistype llNext
integer minx
integer maxx
integer miny
integer maxy
integer centerx
integer centery
method getNext takes nothing returns thistype
return this.llNext
endmethod
static method create takes integer x1, integer y1, integer x2, integer y2 returns thistype
local thistype this = thistype.allocate()
set this.llNext = 0
set this.llPrev = 0
set this.minx = x1
set this.maxx = x2
set this.miny = y1
set this.maxy = y2
set this.centerx = (x1+x2)/2
set this.centery = (y1+y2)/2
return this
endmethod
method onDestroy takes nothing returns nothing
set this.llPrev = 0
set this.llNext = 0
endmethod
endstruct
struct RoomList
private Room llHead
static method create takes nothing returns thistype
local thistype this = thistype.allocate()
set this.llHead = 0
return this
endmethod
private method llAdd takes Room b returns nothing
set b.llNext = this.llHead
if this.llHead != 0 then
set this.llHead.llPrev = b
endif
set this.llHead = b
set b.llPrev = 0
endmethod
private method llRemove takes Room b returns nothing
if b.llPrev != 0 then
set b.llPrev.llNext = b.llNext
else
set this.llHead = b.llNext
endif
if b.llNext != 0 then
set b.llNext.llPrev = b.llPrev
endif
endmethod
method getFirst takes nothing returns Room
return this.llHead
endmethod
method add takes Room b returns nothing
call this.llAdd(b)
endmethod
method remove takes Room b returns nothing
call this.llRemove(b)
endmethod
method iterator takes nothing returns RoomListIterator
return RoomListIterator.create(this)
endmethod
method onDestroy takes nothing returns nothing
local RoomListIterator iter = this.iterator()
local Room nxt
loop
exitwhen iter.hasNoNext()
set nxt = iter.next()
call this.llRemove(nxt)
call nxt.destroy()
endloop
call iter.destroy()
endmethod
endstruct
struct RoomListIterator
private RoomList roomList
private Room nextRoom
static method create takes RoomList roomList returns thistype
local thistype this = thistype.allocate()
set this.roomList = roomList
set this.nextRoom = roomList.getFirst()
return this
endmethod
method hasNext takes nothing returns boolean
return this.nextRoom != 0
endmethod
method hasNoNext takes nothing returns boolean
return this.hasNext() == false
endmethod
method next takes nothing returns Room
local Room tmp = this.nextRoom
set this.nextRoom = this.nextRoom.getNext()
return tmp
endmethod
endstruct
globals
private constant integer MAX_VERIFY_PER_ITERATION = 64
private integer array map[DUNGEON_SIZE_X][DUNGEON_SIZE_Y]
private boolean array verifymap[DUNGEON_SIZE_X][DUNGEON_SIZE_Y]
private stamp array stamps[DUNGEON_SIZE_X][DUNGEON_SIZE_Y]
private integer stacksize = 0
private integer array stackx
private integer array stacky
private boolean usable = false
private integer verified
private integer veriAttempts = 0
private trigger veriTrig = null
private trigger printTrig = null
private integer printCount = 0
private trigger clearTrig = null
private integer clearCount = 0
private trigger veriClearTrig = null
private integer veriClearCount = 0
private trigger clearUnverifiedTrig = null
private integer clearUnverifiedCount = 0
private rect buildArea = null
private timer buildTimer = null
private trigger buildTrig = null
private integer buildx = 0
private integer buildy = 0
private integer buildTileset
private integer buildStairsConsidered
private integer buildStairsUpPickX
private integer buildStairsUpPickY
private integer buildStairsDownPickX
private integer buildStairsDownPickY
private trigger removeTrig = null
private rect enumArea = null
private trigger enumTrig = null
private trigger enumCallTrig = null
private integer enumx = 0
private integer enumy = 0
private real lastUpX = 0
private real lastUpY = 0
private real lastDownX = 0
private real lastDownY = 0
private stamp curstamp = 0
endglobals
//For use with .enumerateMap()
function GetEnumStamp takes nothing returns stamp
return curstamp
endfunction
function GetEnumStampData takes nothing returns integer
return curstamp.data
endfunction
function GetEnumStampValue takes nothing returns real
return curstamp.value
endfunction
function GetEnumStampCenterX takes nothing returns real
return GetRectMinX(enumArea)+enumx*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2
endfunction
function GetEnumStampCenterY takes nothing returns real
return GetRectMinY(enumArea)+enumy*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2
endfunction
function GetLastCreatedStairs takes boolean up returns location
if up then
return Location(lastUpX, lastUpY)
else
return Location(lastDownX, lastDownY)
endif
endfunction
struct Dungeon extends array
static method isVerified takes integer x, integer y returns boolean
return verifymap[x][y]
endmethod
static method getTile takes integer x, integer y returns integer
return map[x][y]
endmethod
static method isWall takes integer x, integer y returns boolean
if x >= 0 and x < DUNGEON_SIZE_X and y >= 0 and y < DUNGEON_SIZE_Y then
return map[x][y] == DUNGEON_EMPTY
endif
return true
endmethod
static method getAdjacentWalls takes integer x, integer y, integer radius returns integer
local integer count = 0
local integer i = -radius
local integer j
loop
exitwhen i > radius
set j = -radius
loop
exitwhen j > radius
if not (i == x and j == y) then
if map[x+i][y+j] <= DUNGEON_EMPTY then
set count = count + 1
endif
endif
set j = j + 1
endloop
set i = i + 1
endloop
return count
endmethod
private static method enumSub takes nothing returns nothing
local integer j = 0
local integer i = enumx
loop
exitwhen j >= DUNGEON_SIZE_Y
set curstamp = stamps[enumx][j]
set enumy = j
call TriggerExecute(enumCallTrig)
set j = j + 1
endloop
set enumx = enumx+1
if enumx < DUNGEON_SIZE_X then
call TriggerExecute(enumTrig)
endif
endmethod
static method enumerateMap takes rect area, code actionFunc returns nothing
if enumTrig == null then
set enumTrig = CreateTrigger()
call TriggerAddAction(enumTrig, function thistype.enumSub)
endif
if enumCallTrig != null then
call TriggerClearActions(enumCallTrig)
call DestroyTrigger(enumCallTrig)
endif
set enumCallTrig = CreateTrigger()
call TriggerAddAction(enumCallTrig, actionFunc)
set enumArea = area
set enumx = 0
set enumy = 0
call TriggerExecute(enumTrig)
endmethod
private static method removeSub takes nothing returns nothing
local integer j = 0
local integer i = buildx
loop
exitwhen j >= DUNGEON_SIZE_Y
call stamp.remove(buildArea,i,j)
set stamps[i][j] = 0
set j = j + 1
endloop
set buildx = buildx+1
if buildx < DUNGEON_SIZE_X then
call TriggerExecute(removeTrig)
endif
endmethod
static method removeAll takes rect area returns nothing
if removeTrig == null then
set removeTrig = CreateTrigger()
call TriggerAddAction(removeTrig, function thistype.removeSub)
endif
set buildArea = area
set buildx = 0
call TriggerExecute(removeTrig)
endmethod
private static method buildSub takes nothing returns nothing
local integer x = buildx
local integer y = buildy
local boolean cave = false
local stamp s = 0
local integer rnd
if map[x][y] == DUNGEON_CAVE then
set cave = true
endif
if map[x][y] >= DUNGEON_ROOM then
set s = stamp.placeByLogic(buildArea, x, y, cave, false, false, buildTileset, thistype.isWall(x-1,y-1), thistype.isWall(x-1,y), thistype.isWall(x-1,y+1), thistype.isWall(x,y-1), thistype.isWall(x,y), thistype.isWall(x,y+1), thistype.isWall(x+1,y-1), thistype.isWall(x+1,y), thistype.isWall(x+1,y+1))
set stamps[x][y] = s
if s == 0 then
elseif s.canHaveStairs() then
//reservoir sampling
set buildStairsConsidered = buildStairsConsidered+1
set rnd = GetRandomInt(1,buildStairsConsidered)
if rnd == 1 then
set buildStairsUpPickX = x
set buildStairsUpPickY = y
elseif rnd == 2 then
set buildStairsDownPickX = x
set buildStairsDownPickY = y
endif
endif
elseif map[x][y] == DUNGEON_EMPTY then
set s = stamp.placeByLogic(buildArea, x, y, cave, false, false, buildTileset, thistype.isWall(x-1,y-1), thistype.isWall(x-1,y), thistype.isWall(x-1,y+1), thistype.isWall(x,y-1), thistype.isWall(x,y), thistype.isWall(x,y+1), thistype.isWall(x+1,y-1), thistype.isWall(x+1,y), thistype.isWall(x+1,y+1))
set stamps[x][y] = s
endif
set buildy = buildy+1
if buildy >= DUNGEON_SIZE_Y then
set buildy = 0
set buildx = buildx+1
endif
if buildx < DUNGEON_SIZE_X and buildy < DUNGEON_SIZE_Y then
call TimerStart(buildTimer, 0, false, function thistype.buildSub)
else
//place stairs
set x = buildStairsUpPickX
set y = buildStairsUpPickY
if map[x][y] == DUNGEON_CAVE then
set cave = true
endif
set s = stamp.placeByLogic(buildArea, x, y, cave, true, true, buildTileset, thistype.isWall(x-1,y-1), thistype.isWall(x-1,y), thistype.isWall(x-1,y+1), thistype.isWall(x,y-1), thistype.isWall(x,y), thistype.isWall(x,y+1), thistype.isWall(x+1,y-1), thistype.isWall(x+1,y), thistype.isWall(x+1,y+1))
set lastUpX = GetRectMinX(buildArea)+x*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2
set lastUpY = GetRectMinY(buildArea)+y*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2
set x = buildStairsDownPickX
set y = buildStairsDownPickY
if map[x][y] == DUNGEON_CAVE then
set cave = true
endif
set s = stamp.placeByLogic(buildArea, x, y, cave, true, false, buildTileset, thistype.isWall(x-1,y-1), thistype.isWall(x-1,y), thistype.isWall(x-1,y+1), thistype.isWall(x,y-1), thistype.isWall(x,y), thistype.isWall(x,y+1), thistype.isWall(x+1,y-1), thistype.isWall(x+1,y), thistype.isWall(x+1,y+1))
set lastDownX = GetRectMinX(buildArea)+x*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2
set lastDownY = GetRectMinY(buildArea)+y*STAMP_SIZE_REAL+STAMP_SIZE_REAL/2
call TriggerExecute(buildTrig)
endif
endmethod
static method build takes rect area, integer tileset, code actionFunc returns nothing
if buildTimer == null then
set buildTimer = CreateTimer()
endif
if buildTrig != null then
call TriggerClearActions(buildTrig)
call DestroyTrigger(buildTrig)
endif
set buildTrig = CreateTrigger()
call TriggerAddAction(buildTrig, actionFunc)
set buildArea = area
set buildTileset = tileset
set buildStairsConsidered = 0
set buildStairsUpPickX = 0
set buildStairsUpPickY = 0
set buildStairsDownPickX = 0
set buildStairsDownPickY = 0
set buildx = 0
set buildy = 0
call TimerStart(buildTimer, 0, false, function thistype.buildSub)
endmethod
private static method clearUnverifiedSub takes nothing returns nothing
local integer j = 0
local integer i = clearUnverifiedCount
loop
exitwhen j >= DUNGEON_SIZE_Y
if not verifymap[i][j] then
set map[i][j] = DUNGEON_EMPTY
endif
set j = j + 1
endloop
set clearUnverifiedCount = clearUnverifiedCount+1
if clearUnverifiedCount < DUNGEON_SIZE_X then
call TriggerExecute(clearUnverifiedTrig)
endif
endmethod
static method clearUnverified takes nothing returns nothing
if clearUnverifiedTrig == null then
set clearUnverifiedTrig = CreateTrigger()
call TriggerAddAction(clearUnverifiedTrig, function thistype.clearUnverifiedSub)
endif
set clearUnverifiedCount = 0
call TriggerExecute(clearUnverifiedTrig)
endmethod
static method isMapUsable takes nothing returns boolean
return usable
endmethod
private static method verifyMapClear takes nothing returns nothing
local integer j = 0
local integer i = veriClearCount
loop
exitwhen j >= DUNGEON_SIZE_Y
set verifymap[i][j] = false
set j = j + 1
endloop
set veriClearCount = veriClearCount+1
if veriClearCount < DUNGEON_SIZE_X then
call TriggerExecute(veriClearTrig)
endif
endmethod
static method verifyMap takes nothing returns nothing
local integer i = 0
local integer j
local integer count = 0
if veriTrig == null then
set veriTrig = CreateTrigger()
call TriggerAddAction(veriTrig, function thistype.verifyMap)
set veriClearTrig = CreateTrigger()
call TriggerAddAction(veriClearTrig, function thistype.verifyMapClear)
endif
if stacksize <= 0 then
set stacksize = 1
set verified = 0
loop
set stackx[0] = GetRandomInt(1,DUNGEON_SIZE_X-2)
set stacky[0] = GetRandomInt(1,DUNGEON_SIZE_Y-2)
exitwhen map[stackx[0]][stacky[0]] >= DUNGEON_ROOM
endloop
set veriClearCount = 0
call TriggerExecute(veriClearTrig)
else
loop
exitwhen stacksize <= 0
exitwhen count > MAX_VERIFY_PER_ITERATION
set stacksize = stacksize-1
set i = stackx[stacksize]
set j = stacky[stacksize]
if map[i][j] >= DUNGEON_ROOM and not verifymap[i][j] then
set verifymap[i][j] = true
set verified = verified + 1
if not verifymap[i][j+1] then
set stackx[stacksize] = i
set stacky[stacksize] = j+1
set stacksize = stacksize+1
endif
if not verifymap[i][j-1] then
set stackx[stacksize] = i
set stacky[stacksize] = j-1
set stacksize = stacksize+1
endif
if not verifymap[i+1][j] then
set stackx[stacksize] = i+1
set stacky[stacksize] = j
set stacksize = stacksize+1
endif
if not verifymap[i-1][j] then
set stackx[stacksize] = i-1
set stacky[stacksize] = j
set stacksize = stacksize+1
endif
endif
set count = count + 1
endloop
endif
if stacksize <= 0 then
if I2R(verified)/I2R(DUNGEON_SIZE_X*DUNGEON_SIZE_Y) > DUNGEON_VERIFICATION_THRESHOLD then
set veriAttempts = 0
set usable = true
return
elseif veriAttempts > MAX_VERIFY_ATTEMPTS then
set veriAttempts = 0
set usable = false
return
else
set veriAttempts = veriAttempts+1
endif
endif
call TriggerExecute(veriTrig)
endmethod
private static method clearSub takes nothing returns nothing
local integer j = 0
local integer i = clearCount
loop
exitwhen j >= DUNGEON_SIZE_Y
set map[i][j] = DUNGEON_EMPTY
set j = j + 1
endloop
set clearCount = clearCount+1
if clearCount < DUNGEON_SIZE_X then
call TriggerExecute(clearTrig)
endif
endmethod
static method clearMap takes nothing returns nothing
if clearTrig == null then
set clearTrig = CreateTrigger()
call TriggerAddAction(clearTrig, function thistype.clearSub)
endif
set clearCount = 0
call TriggerExecute(clearTrig)
endmethod
private static method printSub takes nothing returns nothing
local string s = ""
local integer j = printCount
local integer i = 0
if j >= 0 then
loop
exitwhen i >= DUNGEON_SIZE_X
if map[i][j] == DUNGEON_EMPTY then
set s = s + " "
elseif verifymap[i][j] then
if map[i][j] == DUNGEON_ROOM then
set s = s + "#"
elseif map[i][j] == DUNGEON_CAVE then
set s = s + "+"
elseif map[i][j] == DUNGEON_CORRIDOR then
set s = s + "."
endif
else
set s = s + "X"
endif
set i = i + 1
endloop
call Preload("\")\n\n "+s+" \n\n//")
set printCount = printCount-1
call TriggerExecute(printTrig)
endif
endmethod
static method printMap takes nothing returns nothing
if printTrig == null then
set printTrig = CreateTrigger()
call TriggerAddAction(printTrig, function thistype.printSub)
endif
set printCount = DUNGEON_SIZE_Y-1
call PreloadGenClear()
call PreloadGenStart()
call TriggerExecute(printTrig)
call PreloadGenEnd(DUNGEON_PRINT_DIRECTORY+"layout.txt")
endmethod
endstruct
struct DungeonCavern
integer state //determines the generator phase
boolean doWrite //switches between evolving and writing phase
integer percentAreWalls //determines the original distribution of walls to rooms
integer minx //determines the extends of the current map
integer maxx
integer miny
integer maxy
integer curx
integer highcut
integer lowcut
integer iterations
integer disableLowcutAfter
boolean horizontalCut
boolean finished
trigger trig
static thistype temp = 0
static integer array tempmap[DUNGEON_SIZE_X][DUNGEON_SIZE_Y]
method onDestroy takes nothing returns nothing
call TriggerClearActions(this.trig)
call DestroyTrigger(this.trig)
set this.trig = null
endmethod
method evolve takes integer hc, integer lc returns boolean
local integer i = this.curx
local integer j = this.miny+1
local integer numWalls1
local integer numWalls2
loop
exitwhen j >= this.maxy-1
set numWalls1 = Dungeon.getAdjacentWalls(i,j, 1)
if i >= this.minx+2 and i < this.maxx-2 and j >= this.miny+2 and j < this.maxy-2 then
set numWalls2 = Dungeon.getAdjacentWalls(i,j,2)
else
set numWalls2 = numWalls1+5
endif
if numWalls1 >= hc or numWalls2 <= lc then
set thistype.tempmap[i][j] = DUNGEON_EMPTY
else
set thistype.tempmap[i][j] = DUNGEON_CAVE
endif
set j = j + 1
endloop
set this.curx = i+1
if this.curx >= this.maxx-1 then
return true
endif
return false
endmethod
method write takes nothing returns nothing
local integer i = this.minx
local integer j
loop
exitwhen i >= this.maxx
set j = this.miny
loop
exitwhen j >= this.maxy
set map[i][j] = thistype.tempmap[i][j]
set thistype.tempmap[i][j] = DUNGEON_EMPTY
set j = j + 1
endloop
set i = i + 1
endloop
set curx = this.minx+1
endmethod
method randomize takes nothing returns nothing
local integer i = this.minx+1
local integer j
local integer centery = (this.miny+this.maxy)/2
loop
exitwhen i >= this.maxx-1
set j = this.miny+1
loop
exitwhen j >= this.maxy-1
if map[i][j] == DUNGEON_EMPTY then
if (j == centery and this.horizontalCut) or GetRandomInt(1,100) > this.percentAreWalls then
set map[i][j] = DUNGEON_CAVE
endif
endif
set j = j + 1
endloop
set i = i + 1
endloop
endmethod
private static method generateSub takes nothing returns nothing
local thistype this = thistype.temp
if this.state == 0 then
call this.randomize()
set this.state = 1
elseif this.state >= 1 and this.state <= this.disableLowcutAfter then
if this.doWrite then
call this.write()
set this.state = this.state+1
set this.doWrite = false
else
if this.evolve(this.highcut,this.lowcut) then
set this.doWrite = true
endif
endif
elseif this.state <= this.iterations then
if this.doWrite then
call this.write()
set this.state = this.state+1
set this.doWrite = false
else
if this.evolve(this.highcut,-1) then
set this.doWrite = true
endif
endif
elseif this.state == this.iterations+1 then
set this.finished = true
endif
if not this.finished then
call TriggerExecute(this.trig)
endif
endmethod
method generate takes nothing returns nothing
set thistype.temp = this
call TriggerExecute(this.trig)
endmethod
static method create takes integer x1, integer y1, integer x2, integer y2, integer wallPercent, boolean horizontalBlank, integer cuthigh, integer cutlow, integer phases, integer stopLowcutAfter returns thistype
local thistype this = thistype.allocate()
set this.state = 0
set this.doWrite = false
set this.percentAreWalls = wallPercent
set this.minx = x1
set this.maxx = x2
set this.miny = y1
set this.maxy = y2
set this.curx = x1+1
set this.highcut = cuthigh
set this.lowcut = cutlow
set this.iterations = phases
set this.disableLowcutAfter = stopLowcutAfter
set this.horizontalCut = horizontalBlank
set this.finished = false
set this.trig = CreateTrigger()
call TriggerAddAction(this.trig, function thistype.generateSub)
return this
endmethod
endstruct
struct DungeonUniform
RoomList connected //list of already connected rooms
RoomList unconnected //list of remaining unconnected rooms
boolean allowIrregular //determines if non-rectangular rooms are allowed
real roomPercentage //we stop createing rooms after this percentage of level area has been dug out
integer minSize //minimum room dimension
integer maxWidth //maximum room width
integer maxHeight //maximum room height
real extraChance //chance to create an extra corridor per room
real extraDead //chance to create a deadend corridor per room
integer maxRoomAttempts //maximum number of attempts to create a valid room
integer maxRooms //maximum number of created rooms
integer rooms //counts the number of created rooms
integer dug //counts the number of cells dug
integer state //determines the generator phase
integer minx //determines the extends of the map
integer maxx
integer miny
integer maxy
boolean finished
trigger trig
static thistype temp = 0
method onDestroy takes nothing returns nothing
call this.connected.destroy()
call this.unconnected.destroy()
call TriggerClearActions(this.trig)
call DestroyTrigger(this.trig)
set this.trig = null
endmethod
method digLine takes boolean horizontal, integer x, integer y, integer last returns nothing
local integer i = x
local integer j = y
local integer l = last
if last < x and horizontal then
set l = x
set i = last
elseif last < y and not horizontal then
set l = y
set j = last
endif
loop
if map[i][j] == DUNGEON_EMPTY then
set map[i][j] = DUNGEON_CORRIDOR
set this.dug = this.dug+1
endif
if horizontal then
set i = i + 1
exitwhen i > l
else
set j = j + 1
exitwhen j > l
endif
endloop
endmethod
method digRoom takes integer x1, integer y1, integer x2, integer y2 returns nothing
local integer i = x1
local integer j
loop
exitwhen i > x2
set j = y1
loop
exitwhen j > y2
if map[i][j] != DUNGEON_ROOM then
set map[i][j] = DUNGEON_ROOM
set this.dug = this.dug+1
endif
set j = j + 1
endloop
set i = i + 1
endloop
set this.rooms = this.rooms+1
call this.unconnected.add(Room.create(x1,y1,x2,y2))
endmethod
method generateRoom takes nothing returns boolean
local integer count = 0
local integer x1
local integer y1
local integer x2
local integer y2
loop
exitwhen count > this.maxRoomAttempts
set x1 = GetRandomInt(this.minx+1,this.maxx-2)
set y1 = GetRandomInt(this.miny+1,this.maxy-2)
set x2 = x1+GetRandomInt(this.minSize, this.maxWidth)-1
set y2 = y1+GetRandomInt(this.minSize, this.maxHeight)-1
if not this.allowIrregular then
//snap regular rooms to odd-numbered grid positions
if ModuloInteger(x1,2) == 0 then
set x1=x1-1
endif
if ModuloInteger(y1,2) == 0 then
set y1=y1-1
endif
if ModuloInteger(x2,2) == 0 then
set x2=x2-1
endif
if ModuloInteger(y2,2) == 0 then
set y2=y2-1
endif
endif
if x1 > this.minx and y1 > this.miny and x2 < (this.maxx-1) and y2 < (this.maxy-1) then
if this.allowIrregular or (map[x1][y1] != DUNGEON_ROOM and map[x2][y1] != DUNGEON_ROOM and map[x1][y2] != DUNGEON_ROOM and map[x2][y2] != DUNGEON_ROOM) then
call this.digRoom(x1,y1,x2,y2)
if GetRandomReal(0,1) <= this.extraDead then
set x1 = GetRandomInt(x1,x2)
set y1 = GetRandomInt(y1,y2)
if GetRandomInt(0,1) == 1 then
set x2 = x1+GetRandomInt(-(this.maxWidth), this.maxWidth)
if x2 > this.minx+1 and x2 < this.maxx-2 then
call this.digLine(true,x1,y1,x2)
endif
else
set y2 = y1+GetRandomInt(-(this.maxHeight), this.maxHeight)
if y2 > this.miny+1 and y2 < this.maxy-2 then
call this.digLine(false,x1,y1,y2)
endif
endif
endif
endif
return true
endif
set count = count + 1
endloop
return false
endmethod
method connectRooms takes Room start, Room other returns nothing
local integer count = 0
local integer diffX = other.centerx - start.centerx
local integer diffY = other.centery - start.centery
local integer minCommonX = -1
local integer maxCommonX = -1
local integer minCommonY = -1
local integer maxCommonY = -1
local Room s
local Room o
local integer temp1
local integer temp2
//determine common coordinates
if start.minx <= other.minx then
set s = start
set o = other
else
set s = other
set o = start
endif
if o.minx <= s.maxx then
set minCommonX = o.minx
if s.maxx <= o.maxx then
set maxCommonX = s.maxx
else
set maxCommonX = o.maxx
endif
endif
if start.miny <= other.miny then
set s = start
set o = other
else
set s = other
set o = start
endif
if o.miny <= s.maxy then
set minCommonY = o.miny
if s.maxy <= o.maxy then
set maxCommonY = s.maxy
else
set maxCommonY = o.maxy
endif
endif
if minCommonX >= 0 and maxCommonX >= 0 and minCommonY >= 0 and maxCommonY >= 0 then
//rooms overlap each other; no connection needed
elseif minCommonX >= 0 and maxCommonX >= 0 and minCommonX != maxCommonX then
//dig straight along y-axis
call this.digLine(false, GetRandomInt(minCommonX, maxCommonX), start.centery, other.centery)
elseif minCommonY >= 0 and maxCommonY >= 0 and minCommonY != maxCommonY then
//dig straight along x-axis
call this.digLine(true, start.centerx, GetRandomInt(minCommonY, maxCommonY), other.centerx)
else
//L or S-shaped connections
if IAbsBJ(diffX) > IAbsBJ(diffY) then
if diffX > 0 then
set s = start
set o = other
else
set s = other
set o = start
endif
if s.maxx <= o.minx-4 and GetRandomInt(1,2) <= 1 then //S-shaped connection
set temp1 = GetRandomInt(s.miny, s.maxy)
set temp2 = GetRandomInt(o.miny, o.maxy)
call this.digLine(true, s.centerx, temp1, (s.maxx+o.minx)/2)
call this.digLine(false, (s.maxx+o.minx)/2, temp1, temp2)
call this.digLine(true, (s.maxx+o.minx)/2, temp2, o.centerx)
else //L-shaped connection
set temp1 = GetRandomInt(s.miny, s.maxy)
set temp2 = GetRandomInt(o.minx, o.maxx)
call this.digLine(true, s.centerx, temp1, temp2)
call this.digLine(false, temp2, temp1, o.centery)
endif
else
if diffY > 0 then
set s = start
set o = other
else
set s = other
set o = start
endif
if s.maxy <= o.miny-4 and GetRandomInt(1,2) <= 1 then //S-shaped connection
set temp1 = GetRandomInt(s.minx, s.maxx)
set temp2 = GetRandomInt(o.minx, o.maxx)
call this.digLine(false, temp1, s.centery, (s.maxy+o.miny)/2)
call this.digLine(true, temp1, (s.maxy+o.miny)/2, temp2)
call this.digLine(false, temp2, (s.maxy+o.miny)/2, o.centery)
else //L-shaped connection
set temp1 = GetRandomInt(s.minx, s.maxx)
set temp2 = GetRandomInt(o.miny, o.maxy)
call this.digLine(false, temp1, s.centery, temp2)
call this.digLine(true, temp1, temp2, o.centerx)
endif
endif
endif
endmethod
method generateCorridor takes nothing returns boolean
local real closedist = DUNGEON_SIZE_X+DUNGEON_SIZE_Y
local real distance
local RoomListIterator iter
local Room current = 0
local Room closest = 0
local Room extra = 0
local Room start = 0
if this.unconnected.getFirst() != 0 and this.connected.getFirst() == 0 then
set start = this.unconnected.getFirst()
call this.unconnected.remove(start)
call this.connected.add(start)
endif
if this.connected.getFirst() != 0 and this.unconnected.getFirst() != 0 then
set start = this.connected.getFirst()
set iter = this.unconnected.iterator()
loop
exitwhen iter.hasNoNext()
set current = iter.next()
set distance = SquareRoot((current.centerx-start.centerx)*(current.centerx-start.centerx) + (current.centery-start.centery)*(current.centery-start.centery))
if distance < closedist then
set closedist = distance
set extra = closest
set closest = current
endif
endloop
call iter.destroy()
if closest != 0 then
call this.connectRooms(start, closest)
call this.unconnected.remove(closest)
call this.connected.add(closest)
if extra != 0 and GetRandomReal(0,1) <= this.extraChance then
call this.connectRooms(start, extra)
endif
return true
endif
endif
return false
endmethod
private static method generateSub takes nothing returns nothing
local thistype this = thistype.temp
if this.state == 0 then
if I2R(this.dug)/I2R((this.maxx-this.minx)*(this.maxy-this.miny)) > this.roomPercentage or this.rooms >= this.maxRooms or not this.generateRoom() then
set this.state = 1
endif
elseif this.state == 1 then
if not this.generateCorridor() then
set this.state = 2
endif
elseif this.state == 2 then
set this.finished = true
endif
if not this.finished then
call TriggerExecute(this.trig)
endif
endmethod
method generate takes nothing returns nothing
set thistype.temp = this
call TriggerExecute(this.trig)
endmethod
method connectClosestRoom takes integer x, integer y returns boolean
local RoomListIterator iter = this.connected.iterator()
local Room current = 0
local Room closest = 0
local real distance
local real closedist = DUNGEON_SIZE_X*DUNGEON_SIZE_Y
loop
exitwhen iter.hasNoNext()
set current = iter.next()
set distance = SquareRoot((current.centerx-x)*(current.centerx-x) + (current.centery-y)*(current.centery-y))
if distance < closedist then
set closedist = distance
set closest = current
endif
endloop
call iter.destroy()
if closest != 0 then
set current = Room.create(x,y,x,y)
call this.connectRooms(closest, current)
call current.destroy()
return true
endif
return false
endmethod
static method create takes integer x1, integer y1, integer x2, integer y2, integer roomAttempts, integer roomsMax, real percent, boolean nonRectangular, integer min, integer width, integer height, real extraCorridorChance, real extraDeadendChance returns thistype
local thistype this = thistype.allocate()
set this.connected = RoomList.create()
set this.unconnected = RoomList.create()
set this.minx = x1
set this.maxx = x2
set this.miny = y1
set this.maxy = y2
set this.dug = 0
set this.state = 0
set this.rooms = 0
set this.allowIrregular = nonRectangular
set this.maxRoomAttempts = roomAttempts
set this.maxRooms = roomsMax
set this.roomPercentage = percent
set this.minSize = min
set this.maxWidth = width
set this.maxHeight = height
set this.extraChance = extraCorridorChance
set this.extraDead = extraDeadendChance
set this.finished = false
set this.trig = CreateTrigger()
call TriggerAddAction(this.trig, function thistype.generateSub)
return this
endmethod
endstruct
endlibrary
function Trig_RegisterStamps_Actions takes nothing returns nothing
// Crypt
call stamp.setDestructableData('B006', 1.20, 2000, true) //Rescale Corner Piece pillar
call stamp.setDestructableData('B009', 1.50, 2000+30, true) //Rescale Circle of Power
call stamp.setDestructableData('B007', 1.0, 2000, true)
call stamp.setDestructableData('B005', 1.0, 2000, true)
call stamp.setDestructableData('B04F', 1.0, 2050, true)
call stamp.setDestructableData('B04G', 5.0, 2000+75, true)
call stamp.setDestructableData('B04H', 5.0, 2000+75, true)
call stamp.setDestructableData('B008', 1.0, 2000+75, true)
call stamp.setDestructableData('OTsp', 1.0, 2000+75, true)
call stamp.setDestructableData('B04D', 1.0, 75, true)
call stamp.setDestructableData('B04E', 1.0, 75, true)
call stamp.setDestructableData('B04I', 5.0, 75, true)
call stamp.setDestructableData('B04J', 5.0, 75, true)
call stamp.setDestructableData('B01P', 1.00, 2000-15, true)
call stamp.setDestructableData('B01Y', 1.00, 2000-15, true)
call stamp.setDestructableData('B01Q', 1.00, 2000-275, true)
call stamp.setDestructableData('B01R', 1.00, 2000-275, true)
call stamp.setDestructableData('B01S', 1.00, 2000-275, true)
call stamp.setDestructableData('B01T', 1.00, 2000-275, true)
call stamp.setDestructableData('B01U', 1.00, 2000-275, true)
call stamp.setDestructableData('B01V', 1.00, 2000-275, true)
call stamp.setDestructableData('B01W', 1.00, 2000-275, true)
call stamp.setDestructableData('B01X', 1.00, 2000-275, true)
call stamp.setDestructableData('B01Z', 1.00, 2000-15, true)
call stamp.setDestructableData('B020', 2.00, 2000, true)
call stamp.setDestructableData('B021', 2.00, 2000+275, true)
call stamp.setDestructableData('B022', 2.00, 2000+550, true)
call stamp.setDestructableData('B023', 2.00, 2000-275, true)
call stamp.setDestructableData('B024', 2.00, 2000-550, true)
call stamp.setDestructableData('B025', 2.00, 2000-825, true)
call stamp.setDestructableData('B029', 2.00, 2000-1100, true)
call stamp.setDestructableData('B026', 1.00, 2000, true)
call stamp.setDestructableData('B027', 1.00, 2000+880, true)
//call stamp.setDestructableData('B028', 2.00, 880, true)
call stamp.setDestructableData('B02B', 2.00, 2000+0, true)
call stamp.setDestructableData('B02D', 2.00, 2000+0, true)
call stamp.setDestructableData('B02E', 2.00, 2000+0, true)
call stamp.setDestructableData('B02F', 2.00, 2000+0, true)
call stamp.setDestructableData('B02H', 4.00, 2000+0, true)
call stamp.setDestructableData('B02I', 3.00, 2000-1000, true)
call stamp.setDestructableData('B02M', 3.00, 2000-1000, true)
call stamp.setDestructableData('B02N', 3.00, 2000-1000, true)
call stamp.setDestructableData('B02J', 1.00, 2000-800, true)
call stamp.setDestructableData('B02K', 1.00, 2000-200, true)
call stamp.setDestructableData('B02L', 1.00, 2000-500, true)
call stamp.setDestructableData('B02O', 4.60, 2000+675, true)
call stamp.setDestructableData('B036', 1.00, 2000, true)
call stamp.setDestructableData('B037', 1.00, 2000, true)
call stamp.setDestructableData('B04K', 1.50, 2000, true)
call stamp.setDestructableData('B069', 1.00, 2000+300, true)
call stamp.setDestructableData('B06A', 20.00, 2000-1500, true)
call stamp.setDestructableData('B06B', 1.00, 2000-1000, true)
call stamp.setDestructableData('B06Q', 2.00, 0, true)
// Forest
call stamp.setDestructableData('B04M', 1.00, 0, true)
call stamp.setDestructableData('B04N', 0.75, 0, true)
call stamp.setDestructableData('B04S', 2.00, 0, true)
call stamp.setDestructableData('B04X', 3.00, 0, true)
call stamp.setDestructableData('B04Y', 1.00, 175, true)
call stamp.setDestructableData('B050', 2.00, 0, true)
call stamp.setDestructableData('B051', 0.75, 0, true)
call stamp.setDestructableData('B052', 1.00, 100, true)
call stamp.setDestructableData('B054', 1.00, 50, true)
call stamp.setDestructableData('B055', 1.00, 0, true)
// Chamber
call stamp.setDestructableData('B00D', 1.00, -25, true)
call stamp.setDestructableData('B00H', 1.00, -25, true)
call stamp.setDestructableData('B00I', 1.00, -25, true)
call stamp.setDestructableData('B045', 1.00, -25, true)
call stamp.setDestructableData('B046', 1.00, -25, true)
call stamp.setDestructableData('B047', 1.00, -25, true)
call stamp.setDestructableData('B07K', 1.00, -25, true)
call stamp.setDestructableData('B07L', 1.00, -25, true)
call stamp.setDestructableData('B090', 1.00, -25, true)
call stamp.setDestructableData('B091', 0.25, 0, true)
call stamp.setDestructableData('B092', 0.25, 0, true)
call stamp.setDestructableData('B093', 0.25, 0, true)
//register at least one stamp for each shape
// custom data (here: max creep level)
// The rect that stamp weighting | custom value (here: spawn rate)
// holds the stamp The shape of the stamp Tileset of the stamp (if more than 1 of same shape) | |
// v v v v v v
// Crypt
set st[0] = stamp.register(gg_rct_Stamp01, SHAPE_BLACK, 0, 1, 0, 0)
/*set st[1] = stamp.register(gg_rct_Stamp01_2, SHAPE_BLACK, 0, 0.25, 0, 0)
set st[2] = stamp.register(gg_rct_Stamp01_3, SHAPE_BLACK, 0, 0.25, 0, 0)
set st[3] = stamp.register(gg_rct_Stamp01_4, SHAPE_BLACK, 0, 0.05, 0, 0)
set st[4] = stamp.register(gg_rct_Stamp01_5, SHAPE_BLACK, 0, 0.05, 0, 0)
set st[5] = stamp.register(gg_rct_Stamp01_6, SHAPE_BLACK, 0, 0.05, 0, 0)*/
set st[6] = stamp.register(gg_rct_Stamp02, SHAPE_HALL, 0, 1, 5, 0.15)
set st[7] = stamp.register(gg_rct_Stamp03, SHAPE_WALL_L, 0, 1, 4, 0.05)
set st[8] = stamp.register(gg_rct_Stamp03_2, SHAPE_WALL_L, 0, 0.75, 4, 0.05)
set st[9] = stamp.register(gg_rct_Stamp04, SHAPE_WALL_L_B, 0, 1, 0, 0)
set st[10] = stamp.register(gg_rct_Stamp05, SHAPE_WALL_L_B_R, 0, 1, 10, 0.70)
set st[11] = stamp.register(gg_rct_Stamp06, SHAPE_WALL_BL, 0, 1, 4, 0.1)
set st[12] = stamp.register(gg_rct_Stamp07, SHAPE_WALL_BL_TL, 0, 1, 5, 0.05)
set st[13] = stamp.register(gg_rct_Stamp08, SHAPE_WALL_BL_TR, 0, 1, 5, 0.1)
set st[14] = stamp.register(gg_rct_Stamp09, SHAPE_WALL_BL_TL_BR, 0, 1, 5, 0.05)
set st[15] = stamp.register(gg_rct_Stamp10, SHAPE_WALL_BL_TL_BR_TP, 0, 1, 6, 0.2)
set st[16]= stamp.register(gg_rct_Stamp11, SHAPE_WALL_L_BR, 0, 1, 5, 0.1)
set st[17]= stamp.register(gg_rct_Stamp12, SHAPE_WALL_L_TR, 0, 1, 3, 0.1)
set st[18]= stamp.register(gg_rct_Stamp13, SHAPE_WALL_L_R, 0, 1, 5, 0.15)
set st[19]= stamp.register(gg_rct_Stamp14, SHAPE_WALL_L_B_TR, 0, 1, 5, 0.25)
set st[20]= stamp.register(gg_rct_Stamp15, SHAPE_WALL_L_BR_TR, 0, 1, 9, 0.25)
set st[21]= stamp.register(gg_rct_Stamp16, SHAPE_STAIRS_UP_WALL, 0, 1, 0, 0)
set st[22]= stamp.register(gg_rct_Stamp17, SHAPE_STAIRS_UP_HALL, 0, 1, 0, 0)
set st[23]= stamp.register(gg_rct_Stamp18, SHAPE_STAIRS_UP_END, 0, 1, 0, 0)
set st[24]= stamp.register(gg_rct_Stamp19, SHAPE_STAIRS_DOWN_WALL, 0, 1, 10, 1)
set st[25]= stamp.register(gg_rct_Stamp20, SHAPE_STAIRS_DOWN_HALL, 0, 1, 10, 1)
set st[26]= stamp.register(gg_rct_Stamp21, SHAPE_STAIRS_DOWN_END, 0, 1, 10, 1)
set st[27]=stamp.register(gg_rct_StampExtra, SHAPE_HALL, 0, 0.5, 7, 0.1)
// Forest
set st[28] = stamp.register(gg_rct_Stamp01_7, SHAPE_BLACK, 1, 1, 0, 0)
set st[29] = stamp.register(gg_rct_Stamp02_Kopieren, SHAPE_HALL, 1, 1, 5, 0.15)
set st[30] = stamp.register(gg_rct_Stamp03_Kopieren, SHAPE_WALL_L, 1, 1, 4, 0.05)
set st[31] = stamp.register(gg_rct_Stamp04_Kopieren, SHAPE_WALL_L_B, 1, 1, 0, 0)
set st[32] = stamp.register(gg_rct_Stamp05_Kopieren, SHAPE_WALL_L_B_R, 1, 1, 10, 0.70)
set st[33] = stamp.register(gg_rct_Stamp06_Kopieren, SHAPE_WALL_BL, 1, 1, 4, 0.1)
set st[34] = stamp.register(gg_rct_Stamp07_Kopieren, SHAPE_WALL_BL_TL, 1, 1, 5, 0.05)
set st[35] = stamp.register(gg_rct_Stamp08_Kopieren, SHAPE_WALL_BL_TR, 1, 1, 5, 0.1)
set st[36] = stamp.register(gg_rct_Stamp09_Kopieren, SHAPE_WALL_BL_TL_BR, 1, 1, 5, 0.05)
set st[37] = stamp.register(gg_rct_Stamp10_Kopieren, SHAPE_WALL_BL_TL_BR_TP, 1, 1, 6, 0.2)
set st[38] = stamp.register(gg_rct_Stamp11_Kopieren, SHAPE_WALL_L_BR, 1, 1, 5, 0.1)
set st[39] = stamp.register(gg_rct_Stamp12_Kopieren, SHAPE_WALL_L_TR, 1, 1, 3, 0.1)
set st[40] = stamp.register(gg_rct_Stamp13_Kopieren, SHAPE_WALL_L_R, 1, 1, 5, 0.15)
set st[41] = stamp.register(gg_rct_Stamp14_Kopieren, SHAPE_WALL_L_B_TR, 1, 1, 5, 0.25)
set st[42] = stamp.register(gg_rct_Stamp15_Kopieren, SHAPE_WALL_L_BR_TR, 1, 1, 9, 0.25)
set st[43] = stamp.register(gg_rct_Stamp16_Kopieren, SHAPE_WALL_L+STAIR_UP_OFFSET, 1, 1, 0, 0)
set st[44] = stamp.register(gg_rct_Stamp17_Kopieren, SHAPE_HALL+STAIR_UP_OFFSET, 1, 1, 0, 0)
set st[45] = stamp.register(gg_rct_Stamp18_Kopieren, SHAPE_WALL_L_B_R+STAIR_UP_OFFSET, 1, 1, 0, 0)
set st[46] = stamp.register(gg_rct_Stamp19_Kopieren, SHAPE_WALL_L+STAIR_DOWN_OFFSET, 1, 1, 10, 1)
set st[47] = stamp.register(gg_rct_Stamp20_Kopieren, SHAPE_HALL+STAIR_DOWN_OFFSET, 1, 1, 10, 1)
set st[48] = stamp.register(gg_rct_Stamp21_Kopieren, SHAPE_WALL_L_B_R+STAIR_DOWN_OFFSET, 1, 1, 10, 1)
set st[49] = stamp.register(gg_rct_Stamp01_Kopieren, SHAPE_HALL, 1, 1, 6, 0.10)
set st[50] = stamp.register(gg_rct_StampExtra_Kopieren, SHAPE_HALL, 1, 0.7, 7, 0.10)
set st[51] = stamp.register(gg_rct_StampExtra_Kopieren_2, SHAPE_WALL_L, 1, 1, 0, 0)
set st[52] = stamp.register(gg_rct_StampExtra_Kopieren_3, SHAPE_WALL_L, 1, 1, 0, 0)
set st[53] = stamp.register(gg_rct_StampExtra_Kopieren_4, SHAPE_WALL_L, 1, 1, 0, 0)
set st[54] = stamp.register(gg_rct_StampExtra_Kopieren_5, SHAPE_WALL_L_B, 1, 1, 0, 0)
set st[55] = stamp.register(gg_rct_StampExtra_Kopieren_6, SHAPE_WALL_L_B, 1, 1, 0, 0)
// Chamber
set st[56] = stamp.register(gg_rct_Stamp01_7_Copy, SHAPE_BLACK, 2, 1, 0, 0)
set st[57] = stamp.register(gg_rct_Stamp02_Kopieren_Copy, SHAPE_HALL, 2, 1, 5, 0.15)
set st[58] = stamp.register(gg_rct_Stamp03_Kopieren_Copy, SHAPE_WALL_L, 2, 1, 4, 0.05)
set st[59] = stamp.register(gg_rct_Stamp04_Kopieren_Copy, SHAPE_WALL_L_B, 2, 1, 0, 0)
set st[60] = stamp.register(gg_rct_Stamp05_Kopieren_Copy, SHAPE_WALL_L_B_R, 2, 1, 10, 0.70)
set st[61] = stamp.register(gg_rct_Stamp06_Kopieren_Copy, SHAPE_WALL_BL, 2, 1, 4, 0.1)
set st[62] = stamp.register(gg_rct_Stamp07_Kopieren_Copy, SHAPE_WALL_BL_TL, 2, 1, 5, 0.05)
set st[63] = stamp.register(gg_rct_Stamp08_Kopieren_Copy, SHAPE_WALL_BL_TR, 2, 1, 5, 0.1)
set st[64] = stamp.register(gg_rct_Stamp09_Kopieren_Copy, SHAPE_WALL_BL_TL_BR, 2, 1, 5, 0.05)
set st[65] = stamp.register(gg_rct_Stamp10_Kopieren_Copy, SHAPE_WALL_BL_TL_BR_TP, 2, 1, 6, 0.2)
set st[66] = stamp.register(gg_rct_Stamp11_Kopieren_Copy, SHAPE_WALL_L_BR, 2, 1, 5, 0.1)
set st[67] = stamp.register(gg_rct_Stamp12_Kopieren_Copy, SHAPE_WALL_L_TR, 2, 1, 3, 0.1)
set st[68] = stamp.register(gg_rct_Stamp13_Kopieren_Copy, SHAPE_WALL_L_R, 2, 1, 5, 0.15)
set st[69] = stamp.register(gg_rct_Stamp14_Kopieren_Copy, SHAPE_WALL_L_B_TR, 2, 1, 5, 0.25)
set st[70] = stamp.register(gg_rct_Stamp15_Kopieren_Copy, SHAPE_WALL_L_BR_TR, 2, 1, 9, 0.25)
set st[71] = stamp.register(gg_rct_Stamp16_Kopieren_Copy, SHAPE_WALL_L+STAIR_UP_OFFSET, 2, 1, 0, 0)
set st[72] = stamp.register(gg_rct_Stamp17_Kopieren_Copy, SHAPE_HALL+STAIR_UP_OFFSET, 2, 1, 0, 0)
set st[73] = stamp.register(gg_rct_Stamp18_Kopieren_Copy, SHAPE_WALL_L_B_R+STAIR_UP_OFFSET, 2, 1, 0, 0)
set st[74] = stamp.register(gg_rct_Stamp19_Kopieren_Copy, SHAPE_WALL_L+STAIR_DOWN_OFFSET, 2, 1, 10, 1)
set st[75] = stamp.register(gg_rct_Stamp20_Kopieren_Copy, SHAPE_HALL+STAIR_DOWN_OFFSET, 2, 1, 10, 1)
set st[76] = stamp.register(gg_rct_Stamp21_Kopieren_Copy, SHAPE_WALL_L_B_R+STAIR_DOWN_OFFSET, 2, 1, 10, 1)
set st[77] = stamp.register(gg_rct_Stamp01_Kopieren_Copy, SHAPE_HALL, 2, 1, 6, 0.10)
set st[78] = stamp.register(gg_rct_StampExtra_Kopieren_Copy, SHAPE_HALL, 2, 0.7, 7, 0.10)
set st[79] = stamp.register(gg_rct_StampExtra_Kopieren_2_Copy, SHAPE_WALL_L, 2, 1, 0, 0)
set st[80] = stamp.register(gg_rct_StampExtra_Kopieren_3_Copy, SHAPE_WALL_L, 2, 1, 0, 0)
set st[81] = stamp.register(gg_rct_StampExtra_Kopieren_4_Copy, SHAPE_WALL_L, 2, 1, 0, 0)
//set st[54] = stamp.register(gg_rct_StampExtra_Kopieren_5_Copy, SHAPE_WALL_L_B, 2, 1, 0, 0)
//set st[55] = stamp.register(gg_rct_StampExtra_Kopieren_6_Copy, SHAPE_WALL_L_B, 2, 1, 0, 0)
endfunction
//===========================================================================
function InitTrig_RegisterStamps takes nothing returns nothing
set gg_trg_RegisterStamps = CreateTrigger( )
call TriggerAddAction( gg_trg_RegisterStamps, function Trig_RegisterStamps_Actions )
endfunction
library Gate initializer init uses TimerUtils
globals
real GateX
real GateY
boolean GateOpen = false
boolean GateAnimating = false
ItemObject ActiveScroll = 0
integer Activator = -1
private timer Timer
private integer Pid
private integer Slot
quest StatsModifierQuest = null
endglobals
public function DisposeScroll takes nothing returns nothing
set GateOpen = false
call SetDestructableAnimationSpeed(gg_dest_B04E_1304, 999)
call SetDestructableAnimation(gg_dest_B04E_1304, "death")
call ActiveScroll.destroy()
set ActiveScroll = 0
set Activator = -1
endfunction
private function SetOpen takes nothing returns nothing
local string s = ""
local integer i = 0
//call SetDestructableAnimation(gg_dest_B038_1303, "stand")
set s = s + "|cffffcc00Monster Stats Modifier|r:\n"
if ActiveScroll.physicDmgPctg != 0 then
if ActiveScroll.physicDmgPctg > 0 then
set s = s + "- Physical damage +" + I2S(R2I(ActiveScroll.physicDmgPctg*100)) + "%\n"
else
set s = s + "- |cffaa0000Physical damage " + I2S(R2I(ActiveScroll.physicDmgPctg*100)) + "%|R\n"
endif
endif
if ActiveScroll.physicDefPctg != 0 then
if ActiveScroll.physicDefPctg > 0 then
set s = s + "- Physical defense +" + I2S(R2I(ActiveScroll.physicDefPctg*100)) + "%\n"
else
set s = s + "- |cffaa0000Physical defense " + I2S(R2I(ActiveScroll.physicDefPctg*100)) + "%|R\n"
endif
endif
if ActiveScroll.magicDmgPctg != 0 then
if ActiveScroll.magicDmgPctg > 0 then
set s = s + "- Magic damage +" + I2S(R2I(ActiveScroll.magicDmgPctg*100)) + "%\n"
else
set s = s + "- |cffaa0000Magic damage " + I2S(R2I(ActiveScroll.magicDmgPctg*100)) + "%|R\n"
endif
endif
if ActiveScroll.magicDefPctg != 0 then
if ActiveScroll.magicDefPctg > 0 then
set s = s + "- Magic defense +" + I2S(R2I(ActiveScroll.magicDefPctg*100)) + "%\n"
else
set s = s + "- |cffaa0000Magic defense " + I2S(R2I(ActiveScroll.magicDefPctg*100)) + "%|R\n"
endif
endif
if ActiveScroll.aspdPctg != 0 then
if ActiveScroll.aspdPctg > 0 then
set s = s + "- Attack speed +" + I2S(R2I(ActiveScroll.aspdPctg*100)) + "%\n"
else
set s = s + "- |cffaa0000Attack speed " + I2S(R2I(ActiveScroll.aspdPctg*100)) + "%|R\n"
endif
endif
if ActiveScroll.mspdPctg != 0 then
if ActiveScroll.mspdPctg > 0 then
set s = s + "- Move speed +" + I2S(R2I(ActiveScroll.mspdPctg*100)) + "%\n"
else
set s = s + "- |cffaa0000Move speed " + I2S(R2I(ActiveScroll.mspdPctg*100)) + "%|R\n"
endif
endif
if ActiveScroll.hpPctg != 0 then
if ActiveScroll.hpPctg > 0 then
set s = s + "- Health point +" + I2S(R2I(ActiveScroll.hpPctg*100)) + "%\n"
else
set s = s + "- |cffaa0000Health point " + I2S(R2I(ActiveScroll.hpPctg*100)) + "%|R\n"
endif
endif
set s = s + "|cffffcc00Player Stats Modifier|r:\n"
if ActiveScroll.expRate != 0 then
if ActiveScroll.expRate > 0 then
set s = s + "- EXP rate +" + I2S(R2I(ActiveScroll.expRate*100)) + "%\n"
else
set s = s + "- |cffaa0000EXP rate " + I2S(R2I(ActiveScroll.expRate*100)) + "%|R\n"
endif
endif
if ActiveScroll.goldRate != 0 then
if ActiveScroll.goldRate > 0 then
set s = s + "- Gold rate +" + I2S(R2I(ActiveScroll.goldRate*100)) + "%\n"
else
set s = s + "- |cffaa0000Gold rate " + I2S(R2I(ActiveScroll.goldRate*100)) + "%|R\n"
endif
endif
if StatsModifierQuest != null then
call DestroyQuest(StatsModifierQuest)
endif
set StatsModifierQuest = CreateQuestBJ(bj_QUESTTYPE_REQ_DISCOVERED, "Status Modifier", s, "ReplaceableTextures\\CommandButtons\\BTNWaygate.blp" )
call ClearTextMessages()
call QuestStartSound.play(0, 0, 0, 135)
call DisplayTimedTextToPlayer(Locale, 0, 0, 30., "|cffffcc00The gate is ready!|r\n|cffffcc00Destination|r: " + ActiveScroll.id.name + "\n" + s)
set GateOpen = true
set GateAnimating = false
loop
exitwhen i > 3
if IsPlaying[i] and RectContainsUnit(gg_rct_GateArea, MainUnit[i]) then
call DialogClear(StartDialog[i])
call DialogSetMessage(StartDialog[i], "Are you ready?")
set StartDialogButton[i] = DialogAddButton(StartDialog[i], "Yes", 0)
call DialogAddButton(StartDialog[i], "No", 0)
call DialogDisplay(Player(i), StartDialog[i], true)
endif
set i = i + 1
endloop
endfunction
private function ReOpen takes nothing returns nothing
call GateBirthSound.play(0, 0, 0, 135)
call SetDestructableAnimation(gg_dest_B04E_1304, "birth")
call QueueDestructableAnimation(gg_dest_B04E_1304, "stand")
//call SetDestructableAnimation(gg_dest_B038_1303, "work")
call TimerStart(Timer, 7, false, function SetOpen)
endfunction
public function UseScroll takes integer pid, integer slot returns nothing
local real dx
local real dy
local integer i
set dx = GateX-GetUnitX(MainUnit[pid])
set dy = GateY-GetUnitY(MainUnit[pid])
if dx*dx+dy*dy <= 490000 then
if not GateAnimating then
set GateAnimating = true
call SetDestructableAnimationSpeed(gg_dest_B04E_1304, 1)
if GateOpen then
set i = 0
loop
exitwhen i > 3
set IsReady[i] = false
set i = i + 1
endloop
set ReadyCount = 0
set GateOpen = false
call Bag[Activator].addItem(ActiveScroll)
call SetDestructableAnimation(gg_dest_B04E_1304, "death")
call SetDestructableAnimation(gg_dest_B038_1303, "stand")
call TimerStart(Timer, 3, false, function ReOpen)
call GateDeathSound.play(0, 0, 0, 135)
call DisplayTimedTextToPlayer(Locale, 0, 0, 10., "Active scroll is replaced. All player status is set back to not ready.")
call DisplayTimedTextToPlayer(Bag[Activator].play, 0, 0, 10., "Added scroll item back: " + ActiveScroll.id.name + ".")
else
call GateBirthSound.play(0, 0, 0, 135)
call DisplayTimedTextToPlayer(Locale, 0, 0, 10., GetPlayerName(Bag[pid].play) + " has activated the gate.")
call SetDestructableAnimation(gg_dest_B04E_1304, "birth")
call QueueDestructableAnimation(gg_dest_B04E_1304, "stand")
//call SetDestructableAnimation(gg_dest_B038_1303, "work")
call TimerStart(Timer, 7, false, function SetOpen)
endif
set ActiveScroll = Inventory_SlotIndex[Bag[pid]][slot].object
set Activator = pid
call Bag[pid].dropItemFromSlot(slot, true)
call Bag[pid].closeContextMenu()
call ActiveScroll.move(WorldBounds.maxX, WorldBounds.maxY)
else
call DisplayTimedTextToPlayer(Bag[pid].play, 0, 0, 1., "Failed. The gate is busy.")
endif
else
call DisplayTimedTextToPlayer(Bag[pid].play, 0, 0, 1., "Failed. Must be close to the gate.")
endif
endfunction
private function init takes nothing returns nothing
set Timer = NewTimer()
set GateX = GetDestructableX(gg_dest_B038_1303)
set GateY = GetDestructableY(gg_dest_B038_1303)
call SetDestructableAnimationSpeed(gg_dest_B04E_1304, 999)
call SetDestructableAnimation(gg_dest_B04E_1304, "death")
endfunction
endlibrary
library DungeonGeneration initializer init uses DungeonGenerator, LeftClick, ChainGenerator
globals
boolean InDungeon = false
boolean ReturningHome = false
integer DungeonIndex = 0
integer DungeonExtraLevelCount = 0
integer TILESET_DEFAULT = 0
private integer PRINT_UNTIL = 21
stamp array st
real array CreepNestX
real array CreepNestY
boolean RedPortalRevealed = false
boolean IgnoreEntrance = false
real RedPortalX
real RedPortalY
real BluePortalX
real BluePortalY
real DungeonZ = 0
integer DungeonLevel
boolean Departing = false
private integer ReadyCount = 0
private trigger StairDownTrigger2 = null
dialog StairDownDialog
private button StairDownYes = null
private button StairUpYes = null
public trigger StairDownTrigger = null
public trigger StairUpTrigger = null
private group Group = CreateGroup()
private group ReadyGroup = CreateGroup()
private constant real EXP_BASE = 1.005
endglobals
private function checkReadyGroup takes nothing returns nothing
local unit fog
local location loc2
local group g
local player p
local integer i
local boolean b
if InDungeon then
if Departing then
set loc2 = GetLastCreatedStairs(ReturningHome)
set g = CreateGroup()
loop
set fog = FirstOfGroup(ReadyGroup)
exitwhen fog == null
call GroupRemoveUnit(ReadyGroup, fog)
if IsUnitInRangeLoc(fog, loc2, 600.) then
call GroupAddUnit(g, fog)
else
set p = GetOwningPlayer(fog)
set Departing = false
set ReadyCount = 0
call GroupClear(ReadyGroup)
call DialogDisplay(Locale, StairDownDialog, false)
call DisplayTimedTextToPlayer(Locale, 0, 0, 5., "Departure canceled. " + GetPlayerName(p) + " moves too far from the gate.")
endif
endloop
call RemoveLocation(loc2)
call DestroyGroup(ReadyGroup)
set ReadyGroup = g
set loc2 = null
set g = null
elseif not RedPortalRevealed then
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] and IsUnitInRangeXY(MainUnit[i], RedPortalX, RedPortalY, 800.0) then
set RedPortalRevealed = true
call DisplayTimedTextToPlayer(Locale, 0, 0, 5., GetPlayerName(Player(i)) + " has discovered the red portal!")
exitwhen true
endif
set i = i + 1
endloop
endif
endif
endfunction
private function onEnter takes nothing returns boolean
local unit u = GetIndexedUnit()
local integer data
if GetOwningPlayer(u) == CREEP_PLAYER then
set data = GetUnitUserData(u)
set CreepNestX[data] = GetUnitX(u)
set CreepNestY[data] = GetUnitY(u)
endif
set u = null
return false
endfunction
function CreateCreep takes real x, real y, integer level returns nothing
local Combatant c
local IPool pool
local integer index
local integer i = 0
local integer ix
local unit u
if ActiveScroll.id.dungeonType == 0 then
set pool = DungeonMonsters
elseif ActiveScroll.id.dungeonType == 1 then
set pool = ForestMonsters
endif
set index = pool.getItem()
set ix = GetRandomInt(MonsterCountMin[index], MonsterCountMax[index])
loop
exitwhen i == ix
set u = CreateUnit(CREEP_PLAYER, MonsterPack[index].getItem(), x+GetRandomReal(-200,200), y+GetRandomReal(-200,200), GetRandomReal(0,360))
call IndexCreep(u)
call UnitAddAbility(u, 'Aloc')
call UnitRemoveAbility(u, 'Aloc')
call ShowUnit(u, false)
call ShowUnit(u, true)
call UnitAddAbility(u, 'Amrf')
call UnitRemoveAbility(u, 'Amrf')
call AdjustCreepStrength(Combatant[u], level)
set MiniHealthBar_nameDisplayed.boolean[GetUnitTypeId(u)] = false
set i = i + 1
endloop
endfunction
private function SpawnCreatures takes nothing returns nothing
//Get the coordinates of the currently enumerated stamp
local real x = GetEnumStampCenterX()
local real y = GetEnumStampCenterY()
//Get the custom registered real and integer values for the enumerated stamp
local integer data = GetEnumStampData()
local real value = GetEnumStampValue()
local unit u
//Here we will use the registered value as creep spawn chance and the registered integer as the max creep level
if GetRandomReal(0,1) <= value then
call CreateCreep(x, y, DungeonLevel)
endif
if GetRandomReal(0,1) <= value then
call CreateCreep(x, y, DungeonLevel)
endif
if GetRandomReal(0,1) <= value then
call CreateCreep(x, y, DungeonLevel)
endif
endfunction
/*
A custom callback function that will be fired as soon as the dungeon has finished building.
*/
function RemoveItems takes nothing returns nothing
if (IsItemVisible(GetEnumItem())) then
//call ItemObject[GetEnumItem()].destroy()
endif
endfunction
private function enableControl takes nothing returns nothing
call EnableUserControl(true)
call EnableUserUI(true)
call ReleaseTimer(GetExpiredTimer())
endfunction
private function fadeIn takes nothing returns nothing
call ShowInterface(true, 2.0)
call SetCineFilterStartColor(0, 0, 0, 255)
call SetCineFilterEndColor(0, 0, 0, 0)
call SetCineFilterDuration(2.0)
call DisplayCineFilter(true)
call TimerStart(GetExpiredTimer(), 2, false, function enableControl)
endfunction
public function recreate takes nothing returns nothing
call ClearTextMessages()
call DisplayTimedTextToPlayer(Locale, 0.9, 0.3, 0, "Working on a nice dungeon...")
call ExecuteFunc("aaa___Recreate")
call ReleaseTimer(GetExpiredTimer())
endfunction
public function generateScrolls takes nothing returns nothing
local integer i = 0
local ItemObject obj
call BaseScroll.clearItem()
set obj = ItemObject.create(ITEM_INDEX_SCROLLS+1, 1, 1, WorldBounds.maxX, WorldBounds.maxY)
call obj.setScrollStats(GetRandomInt(1, 7))
call BaseScroll.addItem(obj)
set i = 0
loop
exitwhen i >= 19
set obj = ItemObject.create(ITEM_INDEX_SCROLLS+GetRandomInt(1, DUNGEON_VARIATION), 1, 1, WorldBounds.maxX, WorldBounds.maxY)
call obj.setScrollStats(GetRandomInt(0, SCROLL_VARIATION))
call BaseScroll.addItem(obj)
set i = i + 1
endloop
endfunction
public function returnBase takes nothing returns nothing
local Combatant c
local integer i = 0
local ItemObject obj
set DungeonZ = 0
set InDungeon = false
set Departing = false
loop
exitwhen i > 3
if IsPlaying[i] then
set c = Combatant[MainUnit[i]]
set c.hp = c.hpMax
set c.sp = c.spMax
call SetUnitPosition(MainUnit[i], START_X, START_Y)
call RelocateSubordinates(MainUnit[i])
endif
set i = i + 1
endloop
call MiniMap_Show(false)
if StatsModifierQuest != null then
call DestroyQuest(StatsModifierQuest)
endif
call ForForce(bj_FORCE_PLAYER[0], function MiniMap_ClearTexture)
call ForForce(bj_FORCE_PLAYER[0], function Gate_DisposeScroll)
call ForForce(bj_FORCE_PLAYER[0], function generateScrolls)
set CamRot = 163.97
call SetCameraField(CAMERA_FIELD_ROTATION, CamRot, 0)
call SetTerrainFogEx(0,0,100000,0,0,0,0)
call SetDayNightModels("war3mapImported\\DNCSelection.mdx", "war3mapImported\\DNCSelection.mdx")
//call SetTerrainFogEx(0,0,7500,0.5,45./255.,45./255.,45./255.)
call SetSkyModel("war3mapImported\\LordaeronHillsSky2.mdx")
call ShowInterface(true, 2.0)
call SetCineFilterStartColor(0, 0, 0, 255)
call SetCineFilterEndColor(0, 0, 0, 0)
call SetCineFilterDuration(2.0)
call DisplayCineFilter(true)
call TimerStart(GetExpiredTimer(), 2, false, function enableControl)
endfunction
private function onClick takes nothing returns boolean
local group g
local unit u
local integer id
local location loc
if GetClickedButton() == StairDownYes then
set id = GetPlayerId(GetTriggerPlayer())
set loc = GetLastCreatedStairs(false)
if IsUnitInRangeLoc(MainUnit[id], loc, 600.0) then
set ReadyCount = ReadyCount + 1
call GroupAddUnit(ReadyGroup, MainUnit[id])
call DisplayTimedTextToPlayer(Locale, 0, 0, 5., GetPlayerName(GetTriggerPlayer()) + " is ready.")
if ReadyCount >= PlayerCount then
set Departing = false
set ReadyCount = 0
call GroupClear(ReadyGroup)
call ShowInterface(false, 2.0)
call EnableUserControl(false)
call EnableUserUI(false)
call SetCineFilterStartColor(0, 0, 0, 0)
call SetCineFilterEndColor(0, 0, 0, 255)
call SetCineFilterDuration(2.0)
call DisplayCineFilter(true)
call ClearTextMessages()
if DungeonIndex < DungeonExtraLevelCount then
call TimerStart(NewTimer(), 3, false, function recreate)
else
call TimerStart(NewTimer(), 3, false, function returnBase)
endif
set g = CreateGroup()
call GroupEnumUnitsOfPlayer(g, CREEP_PLAYER, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g, u)
if u != gg_unit_h002_0010 then
call PauseUnit(u, true)
endif
endloop
call DestroyGroup(g)
set g = null
set DungeonIndex = DungeonIndex + 1
endif
else
set Departing = false
set ReadyCount = 0
call GroupClear(ReadyGroup)
call DialogDisplay(Locale, StairDownDialog, false)
call DisplayTimedTextToPlayer(Locale, 0, 0, 5., "Departure failed. " + GetPlayerName(GetTriggerPlayer()) + " is out of range from the portal.")
endif
call RemoveLocation(loc)
set loc = null
elseif GetClickedButton() == StairUpYes then
set id = GetPlayerId(GetTriggerPlayer())
set loc = GetLastCreatedStairs(true)
if IsUnitInRangeLoc(MainUnit[id], loc, 600.0) then
set ReadyCount = ReadyCount + 1
call GroupAddUnit(ReadyGroup, MainUnit[id])
call DisplayTimedTextToPlayer(Locale, 0, 0, 5., GetPlayerName(GetTriggerPlayer()) + " is ready.")
if ReadyCount == PlayerCount then
set Departing = false
set ReadyCount = 0
call GroupClear(ReadyGroup)
call ShowInterface(false, 2.0)
call EnableUserControl(false)
call EnableUserUI(false)
call SetCineFilterStartColor(0, 0, 0, 0)
call SetCineFilterEndColor(0, 0, 0, 255)
call SetCineFilterDuration(2.0)
call DisplayCineFilter(true)
call ClearTextMessages()
call StopMusic(true)
call TimerStart(NewTimer(), 3, false, function returnBase)
set g = CreateGroup()
call GroupEnumUnitsOfPlayer(g, CREEP_PLAYER, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g, u)
if u != gg_unit_h002_0010 then
call PauseUnit(u, true)
endif
endloop
call DestroyGroup(g)
set g = null
endif
else
set Departing = false
set ReadyCount = 0
call GroupClear(ReadyGroup)
call DialogDisplay(Locale, StairDownDialog, false)
call DisplayTimedTextToPlayer(Locale, 0, 0, 5., "Departure failed. " + GetPlayerName(GetTriggerPlayer()) + " is out of range from the portal.")
endif
call RemoveLocation(loc)
set loc = null
else
set Departing = false
set ReadyCount = 0
call GroupClear(ReadyGroup)
call DialogDisplay(Locale, StairDownDialog, false)
call DisplayTimedTextToPlayer(Locale, 0, 0, 5., "Departure canceled. " + GetPlayerName(GetTriggerPlayer()) + " declined to depart.")
endif
return false
endfunction
private function stairDown takes nothing returns boolean
local unit u = GetTriggerUnit()
local unit fog
local integer count
local boolean b
local location loc
if IsUnitInGroup(u, MainGroup) and not Departing then
set ReturningHome = false
set loc = GetLastCreatedStairs(false)
set b = true
loop
set fog = FirstOfGroup(MainGroup)
exitwhen fog == null
call GroupRemoveUnit(MainGroup, fog)
call GroupAddUnit(Group, fog)
if fog != u and IsPlaying[GetPlayerId(GetOwningPlayer(fog))] and not IsUnitInRangeLoc(fog, loc, 600.0) then
set b = false
endif
endloop
call RemoveLocation(loc)
set loc = null
if b then
set Departing = true
call DialogClear(StairDownDialog)
if DungeonIndex < DungeonExtraLevelCount then
call DialogSetMessage(StairDownDialog, "Move to next dungeon?")
else
call DialogSetMessage(StairDownDialog, "Return to base?")
endif
set StairDownYes = DialogAddButton(StairDownDialog, "Yes", 0)
call DialogAddButton(StairDownDialog, "No", 0)
call DialogDisplay(Locale, StairDownDialog, true)
else
call DisplayTimedTextToPlayer(Locale, 0, 0, 5., "Unable to depart. All players must gather near the gate.")
endif
call DestroyGroup(MainGroup)
set MainGroup = Group
set Group = CreateGroup()
endif
set u = null
return false
endfunction
private function stairUp takes nothing returns boolean
local unit u = GetTriggerUnit()
local unit fog
local integer count
local boolean b
local location loc
if IsUnitInGroup(u, MainGroup) and not Departing and not IgnoreEntrance then
set ReturningHome = true
set loc = GetLastCreatedStairs(true)
set b = true
loop
set fog = FirstOfGroup(MainGroup)
exitwhen fog == null
call GroupRemoveUnit(MainGroup, fog)
call GroupAddUnit(Group, fog)
if fog != u and IsPlaying[GetPlayerId(GetOwningPlayer(fog))] and not IsUnitInRangeLoc(fog, loc, 600.0) then
set b = false
endif
endloop
call RemoveLocation(loc)
set loc = null
if b then
set Departing = true
call DialogClear(StairDownDialog)
call DialogSetMessage(StairDownDialog, "Return to base?")
set StairUpYes = DialogAddButton(StairDownDialog, "Yes", 0)
call DialogAddButton(StairDownDialog, "No", 0)
call DialogDisplay(Locale, StairDownDialog, true)
else
call DisplayTimedTextToPlayer(Locale, 0, 0, 5., "Unable to depart. All players must gather near the gate.")
endif
call DestroyGroup(MainGroup)
set MainGroup = Group
set Group = CreateGroup()
endif
set IgnoreEntrance = false
set u = null
return false
endfunction
private function decorateDungeon takes nothing returns boolean
local destructable d = GetFilterDestructable()
local integer id = GetDestructableTypeId(d)
local integer rand
local integer i
local integer j
local unit u
local real a
local real sz
local real x
local real y
local real z
local real ofs
if id != 'B00J' and id != 'B035' then
call DestructableHider_register(d)
endif
if id == 'B055' then // Forest particle 1
call DestructableHider_register(CreateDestructableZ('B08H', GetDestructableX(d), GetDestructableY(d), 50, 0, 1, 0))
elseif id == 'B057' then // Forest particle 2
if GetRandomInt(0, 100) < 7 then
call DestructableHider_register(CreateDestructableZ('B056', GetDestructableX(d), GetDestructableY(d), 0, GetRandomReal(0, 359.99), 1, 0))
call DestructableHider_register(CreateDestructableZ('B08H', GetDestructableX(d), GetDestructableY(d), 50, 0, 1, 0))
endif
call DestructableHider_unregister(d)
call RemoveDestructable(d)
elseif id == 'B058' then // Forest Gates
set u = CreateUnit(CREEP_PLAYER, 'h005', GetDestructableX(d), GetDestructableY(d), GetDestructableLife(d))
call IndexCreep(u)
set a = GetUnitFacing(u)
if a == 90 or a == 270 then
set Combatant[u].destToRemove = CreateDestructableZ('B05F', GetDestructableX(d), GetDestructableY(d), 90, 0, 1, 0)
else
set Combatant[u].destToRemove = CreateDestructableZ('B059', GetDestructableX(d), GetDestructableY(d), 0, 0, 1, 0)
endif
call DestructableHider_register(Combatant[u].destToRemove)
call UnitAddAbility(u, 'Aloc')
call UnitRemoveAbility(u, 'Aloc')
call ShowUnit(u, false)
call ShowUnit(u, true)
call UnitAddAbility(u, 'Amrf')
call UnitRemoveAbility(u, 'Amrf')
call AdjustCreepStrength(Combatant[u], 1)
call DestructableHider_unregister(d)
call RemoveDestructable(d)
elseif id == 'B06C' then // Crypt void area decorations
if GetRandomInt(0, 100) < 25 then
set rand = GetRandomInt(0, 2)
if rand == 0 then // Big pillar
set sz = GetRandomReal(0.75, 1.25)
set a = GetRandomReal(0, 359.99) * bj_DEGTORAD
set x = GetDestructableX(d)
set y = GetDestructableY(d)
set z = 2725
set ofs = (128*sz)
set i = R2I(11./sz)
loop
exitwhen i < 0
call DestructableHider_register(CreateDestructableZ('B020', x + ofs * Cos(a), y + ofs * Sin(a), z, a * bj_RADTODEG, 2 * sz, 0))
call DestructableHider_register(CreateDestructableZ('B020', x + ofs * Cos(a+PanelCore_HP), y + ofs * Sin(a+PanelCore_HP), z, a * bj_RADTODEG + 90, 2 * sz, 0))
call DestructableHider_register(CreateDestructableZ('B020', x + ofs * Cos(a-PanelCore_HP), y + ofs * Sin(a-PanelCore_HP), z, a * bj_RADTODEG - 90, 2 * sz, 0))
call DestructableHider_register(CreateDestructableZ('B020', x + ofs * Cos(a+bj_PI), y + ofs * Sin(a+bj_PI), z, a * bj_RADTODEG + 180, 2 * sz, 0))
set z = z - 275*sz
set i = i - 1
endloop
elseif rand == 1 then // Crystal pillar
set rand = GetRandomInt(0, 2)
set a = GetRandomReal(0.75, 1.25)
set x = GetDestructableX(d) + GetRandomReal(-200, 200)
set y = GetDestructableY(d) + GetRandomReal(-200, 200)
set z = GetRandomReal(-200, 800)
// Crystals
if rand == 0 then
call DestructableHider_register(CreateDestructableZ('B02I', x, y, 1000 + z, GetRandomReal(0, 359.99), 3 * a, 0))
call DestructableHider_register(CreateDestructableZ('B08O', x, y, 1250 + z, 0, 1, 0))
elseif rand == 1 then
call DestructableHider_register(CreateDestructableZ('B02M', x, y, 1000 + z, GetRandomReal(0, 359.99), 3 * a, 0))
call DestructableHider_register(CreateDestructableZ('B08M', x, y, 1250 + z, 0, 1, 0))
elseif rand == 2 then
call DestructableHider_register(CreateDestructableZ('B02N', x, y, 1000 + z, GetRandomReal(0, 359.99), 3 * a, 0))
call DestructableHider_register(CreateDestructableZ('B08N', x, y, 1250 + z, 0, 1, 0))
endif
// Support
call DestructableHider_register(CreateDestructableZ('B02J', x, y, 1200 + z, GetRandomReal(0, 359.99), a, 0))
elseif rand == 2 then // Hanging block
//call CreateDestructableZ('B056', GetDestructableX(d), GetDestructableY(d), 0, GetRandomReal(0, 359.99), 1, 0)
endif
endif
call DestructableHider_unregister(d)
call RemoveDestructable(d)
elseif id == 'B06F' then // Crypt props
if GetRandomInt(0, 100) < 15 then
set rand = GetRandomInt(0, 5)
if rand == 0 then // Rock 4
call DestructableHider_register(CreateDestructableZ('B06E', GetDestructableX(d), GetDestructableY(d), 2000, GetRandomReal(0, 359.99), GetRandomReal(0.25, 0.5), 0))
elseif rand == 1 then // Rock 5
call DestructableHider_register(CreateDestructableZ('B06G', GetDestructableX(d), GetDestructableY(d), 2000, GetRandomReal(0, 359.99), GetRandomReal(0.5, 0.75), 0))
elseif rand == 2 then // Bone1
call DestructableHider_register(CreateDestructableZ('B06H', GetDestructableX(d), GetDestructableY(d), 2000, GetRandomReal(0, 359.99), GetRandomReal(0.75, 1.0), 0))
elseif rand == 3 then // Fog quarter
call DestructableHider_register(CreateDestructableZ('B069', GetDestructableX(d), GetDestructableY(d), 2000 + GetRandomReal(0, 200), GetRandomReal(0, 359.99), GetRandomReal(0.75, 1.25), 0))
elseif rand == 4 then // Fallen pillar
set x = GetDestructableX(d)
set y = GetDestructableY(d)
set a = GetRandomReal(0, 359.99)
call DestructableHider_register(CreateDestructableZ('B06D', x, y, 2032, a, GetRandomReal(3.75, 4.00), 0))
// Double pillar
if GetRandomInt(0, 100) < 50 then
set a = a * bj_DEGTORAD
set ofs = GetRandomReal(0, 384) // Intersection point offset
set x = x + ofs * Cos(a)
set y = y + ofs * Sin(a)
// Create pathing at intersecion point
call DestructableHider_register(CreateDestructableZ('YTpb', x-32, y-32, 2000,0, 1, 0))
call DestructableHider_register(CreateDestructableZ('YTpb', x+32, y-32, 2000,0, 1, 0))
call DestructableHider_register(CreateDestructableZ('YTpb', x-32, y+32, 2000,0, 1, 0))
call DestructableHider_register(CreateDestructableZ('YTpb', x+32, y+32, 2000,0, 1, 0))
set a = a - PanelCore_HP + GetRandomReal(-PanelCore_HP, PanelCore_HP) / 2
set ofs = GetRandomReal(192, 288) // Intersection point offset 2
set x = x - ofs * Cos(a)
set y = y - ofs * Sin(a)
call DestructableHider_register(CreateDestructableZ('B06P', x, y, 2032, a * bj_RADTODEG, GetRandomReal(3.75, 4.00), 0))
endif
elseif rand == 5 then // Bats
call DestructableHider_register(CreateDestructableZ('B06R', GetDestructableX(d), GetDestructableY(d), 2000, GetRandomReal(0, 359.99), 1, 0))
endif
endif
call DestructableHider_unregister(d)
call RemoveDestructable(d)
elseif id == 'B06B' then // Crypt void fog
call DestructableHider_register(CreateDestructableZ('B06B', GetDestructableX(d), GetDestructableY(d), 1000 + GetRandomReal(-100, 100), GetRandomReal(0, 359.99), 1, 0))
call DestructableHider_unregister(d)
call RemoveDestructable(d)
elseif id == 'B06J' then // Crypt wall deco 1
set a = GetDestructableLife(d) * bj_DEGTORAD
set x = GetDestructableX(d) + 192 * Cos(a)
set y = GetDestructableY(d) + 192 * Sin(a)
call DestructableHider_register(CreateDestructableZ('B06I', x, y, 1800, a * bj_RADTODEG - 90, 2, 0))
// Glow
call DestructableHider_register(CreateDestructableZ('B06S', x + 32 * Cos(a), y + 32 * Sin(a), 1864, 0, 2, 0))
call DestructableHider_register(CreateDestructableZ('B06S', x + 32 * Cos(a), y + 32 * Sin(a), 1864, 0, 2, 0))
// Fire
call DestructableHider_register(CreateDestructableZ('B06T', x + 32 * Cos(a), y + 32 * Sin(a), 1896, 0, 0.5, 0))
// Light
call DestructableHider_register(CreateDestructableZ('B08K', x + 32 * Cos(a), y + 32 * Sin(a), 1916, 0, 1, 0))
if GetRandomInt(0, 100) < 60 then
set x = GetDestructableX(d) + 256 * Cos(a)
set y = GetDestructableY(d) + 256 * Sin(a)
call GenerateUnevenChain(x, y, 616, x + 500 * Cos(a), y + 500 * Sin(a), 816, 0, 500, 1.5, -1, 200, GetRandomInt(0, 1) * 2)
endif
call DestructableHider_unregister(d)
call RemoveDestructable(d)
elseif id == 'B007' then // Crypt brazier
set x = GetDestructableX(d)
set y = GetDestructableY(d)
call DestructableHider_register(CreateDestructableZ('B08L', x, y, 2050, 0, 1, 0))
elseif id == 'B04Z' then // Forest brazier
set x = GetDestructableX(d)
set y = GetDestructableY(d)
call DestructableHider_register(CreateDestructableZ('B08L', x, y, 50, 0, 1, 0))
elseif id == 'B06K' then // Crypt Corner chain
if GetRandomInt(0, 100) < 75 then
set x = GetDestructableX(d)
set y = GetDestructableY(d)
set i = GetRandomInt(0, 2)
loop
exitwhen i < 0
set a = (GetDestructableLife(d) + GetRandomReal(-45, 45)) * bj_DEGTORAD
call GenerateUnevenChain(x, y, 2000, x + 500 * Cos(a), y + 500 * Sin(a), 2200, 0, 500, 1.5, 0, GetRandomReal(175, 225), 0)
set i = i - 1
endloop
endif
call DestructableHider_unregister(d)
call RemoveDestructable(d)
elseif id == 'B06L' then // Crypt Hanging Chain Pillar
set a = GetDestructableLife(d) * bj_DEGTORAD
set x = GetDestructableX(d)
set y = GetDestructableY(d)
set i = GetRandomInt(0, 2)
loop
exitwhen i < 0
call GenerateEvenChain(x, y, 2364, x + 352 * Cos(a), y + 352 * Sin(a), 2364, 2000, GetRandomReal(50, 1000), 1, 0.5, 1)
set i = i - 1
endloop
call DestructableHider_unregister(d)
call RemoveDestructable(d)
elseif id == 'B06N' then // Crypt Grass
if GetRandomInt(0, 100) < 35 then
call DestructableHider_register(CreateDestructableZ('B06O', GetDestructableX(d), GetDestructableY(d), 2005, GetRandomReal(0, 359.99), GetRandomReal(1.5, 2), GetRandomInt(0, 1) * 2))
endif
call DestructableHider_unregister(d)
call RemoveDestructable(d)
elseif id == 'B06M' then // Crypt Pillar Chain
if GetRandomInt(0, 100) < 60 then
set a = (GetDestructableLife(d) + GetRandomReal(-25, 25)) * bj_DEGTORAD
set x = GetDestructableX(d)
set y = GetDestructableY(d)
set i = GetRandomInt(0, 2)
call GenerateUnevenChain(x, y, 2000, x + 50 * Cos(a), y + 50 * Sin(a), 2400, 2000, 50, 1, -1, 250, 1)
if GetRandomInt(0, 1) == 1 then
call GenerateUnevenChain(x, y, 2000, x + 50 * Cos(a - PanelCore_HP), y + 50 * Sin(a - PanelCore_HP), 2400, 2000, 50, 1, -1, 250, 1)
endif
if (i > 0) then
set a = (GetDestructableLife(d) + GetRandomReal(-25, 25)) * bj_DEGTORAD
call GenerateUnevenChain(x, y, 1800, x + 5 * Cos(a), y + 5 * Sin(a), 2050, 2000, 50, 1, -1, 90,1)
if GetRandomInt(0, 1) == 1 then
call GenerateUnevenChain(x, y, 1800, x + 5 * Cos(a - PanelCore_HP), y + 5 * Sin(a - PanelCore_HP), 2050, 2000, 50, 1, -1, 90, 1)
endif
endif
if (i > 1) then
set a = (GetDestructableLife(d) + GetRandomReal(-25, 25)) * bj_DEGTORAD
call GenerateUnevenChain(x, y, 2000, x + 5 * Cos(a), y + 5 * Sin(a), 2250, 2000, 50, 1, -1, 120, 1)
if GetRandomInt(0, 1) == 1 then
call GenerateUnevenChain(x, y, 2000, x + 5 * Cos(a - PanelCore_HP), y + 5 * Sin(a - PanelCore_HP), 2250, 2000, 50, 1, -1, 120, 1)
endif
endif
endif
call DestructableHider_unregister(d)
call RemoveDestructable(d)
elseif id == 'B06U' then // Crypt pillar gargoyle
if GetRandomInt(0, 100) < 75 then
set x = GetDestructableX(d)
set y = GetDestructableY(d)
if GetRandomInt(0, 100) < 15 then
set u = CreateUnit(CREEP_PLAYER, 'h00T', x, y, GetDestructableLife(d))
call UnitAddAbility(u, 'Aloc')
call UnitRemoveAbility(u, 'Aloc')
call ShowUnit(u, false)
call ShowUnit(u, true)
call UnitAddAbility(u, 'Amrf')
call UnitRemoveAbility(u, 'Amrf')
call SetUnitPathing(u, false)
call SetUnitX(u, x)
call SetUnitY(u, y)
call PanelCore_SetUnitZ(u, 2400)
call UnitRemoveAbility(u, 'Amov')
call GargoyleStatue.create(u)
else
call DestructableHider_register(CreateDestructableZ('B06V', x, y, 2400, GetDestructableLife(d), 1, 0))
endif
endif
call DestructableHider_unregister(d)
call RemoveDestructable(d)
elseif id == 'B008' then // Red portal
set x = GetDestructableX(d)
set y = GetDestructableY(d)
call DestructableHider_register(CreateDestructableZ('B08I', x, y, 2100, 0, 1, 0))
elseif id == 'OTsp' then // Blue portal
set x = GetDestructableX(d)
set y = GetDestructableY(d)
call DestructableHider_register(CreateDestructableZ('B08J', x, y, 2100, 0, 1, 0))
elseif id == 'B04D' then // Red portal
set x = GetDestructableX(d)
set y = GetDestructableY(d)
call DestructableHider_register(CreateDestructableZ('B08I', x, y, 100, 0, 1, 0))
elseif id == 'B04E' then // Blue portal
set x = GetDestructableX(d)
set y = GetDestructableY(d)
call DestructableHider_register(CreateDestructableZ('B08J', x, y, 100, 0, 1, 0))
endif
set d = null
return false
endfunction
private function enumGates takes nothing returns boolean
local destructable d = GetFilterDestructable()
local integer id = GetDestructableTypeId(d)
if id == 'B036' then
if ActiveScroll.id.dungeonType == 0 then
call CreateDestructableZ('B037', GetDestructableX(d), GetDestructableY(d), 2000, GetDestructableLife(d), 1, 0)
else
call CreateDestructableZ('B037', GetDestructableX(d), GetDestructableY(d), 0, GetDestructableLife(d), 1, 0)
endif
endif
set d = null
return false
endfunction
private function findPortal takes nothing returns boolean
local destructable d = GetFilterDestructable()
local integer id = GetDestructableTypeId(d)
local real x
local real y
if id == 'B008' or id == 'B04D' then
if StairDownTrigger != null then
call DestroyTrigger(StairDownTrigger)
endif
set StairDownTrigger = CreateTrigger()
set x = GetDestructableX(d)
set y = GetDestructableY(d)
call TriggerRegisterEnterRectSimple(StairDownTrigger, Rect(x-200, y-200, x+200, y+200))
call TriggerAddCondition(StairDownTrigger, Condition(function stairDown))
elseif id == 'B04E' or id == 'OTsp' then
if StairUpTrigger != null then
call DestroyTrigger(StairUpTrigger)
endif
set StairUpTrigger = CreateTrigger()
set x = GetDestructableX(d)
set y = GetDestructableY(d)
call TriggerRegisterEnterRectSimple(StairUpTrigger, Rect(x-200, y-200, x+200, y+200))
call TriggerAddCondition(StairUpTrigger, Condition(function stairUp))
endif
set d = null
return false
endfunction
public function OnFinish takes nothing returns nothing
local Combatant c
local location loc = GetLastCreatedStairs(true) //Get the location of the last created staircase
local location loc2 = GetLastCreatedStairs(false)
local group g = CreateGroup()
local ItemObject itm
local unit u
local unit fog
local integer i = 0
local real x = GetLocationX(loc2)
local real y = GetLocationY(loc2)
local real x2 = GetLocationX(loc)
local real y2 = GetLocationY(loc)
local real xt
local real yt
local real dx = x2-x
local real dy = y2-y
local rect r
//if dx*dx+dy*dy < 2000*2000 then
if dx*dx+dy*dy > 6000*6000 then
set GeneratingDungeon = false
set SoulHarvest.WantDestroy = true
call SludgeMonsterSplit_Reset()
set RedPortalRevealed = false
set RedPortalX = x
set RedPortalY = y
set BluePortalX = x2
set BluePortalY = y2
call ClearTextMessages()
call DisplayTimedTextToPlayer(Locale, 0.9, 0.3, 1.5, "|cff00ff00Working on a nice dungeon...|r")
call MiniMap_UpdateTexture()
call MiniMap_HidePartitions()
call MiniMap_Show(true)
set DungeonLevel = 1000
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] then
call SetUnitPosition(MainUnit[i], x2+GetRandomReal(-100,100), y2+GetRandomReal(-100,100))
call RelocateSubordinates(MainUnit[i])
if Level[i] < DungeonLevel then
set DungeonLevel = Level[i]
endif
set c = Combatant[MainUnit[i]]
set c.hp = c.hpMax
set c.sp = c.spMax
set Departing = false
call ShopUI[i].show(false)
call Tooltips1[i].show(false)
call Tooltips2[i].show(false)
call Bag[i].show(false)
call CharacterWindow_Show(i, false)
set Tooltips1[i].itmObject = -1
set Tooltips2[i].itmObject = -1
call ShortcutBar_SkillSelection[i].clear()
set ShortcutBar_SelectIndex[i] = -1
call ShortcutBar_SkillSelection[i].show(false)
endif
set i = i + 1
endloop
call PanCameraToTimed(x2, y2, 0)
set r = RectFromCenterSizeBJ(loc, 600, 600)
call EnumDestructablesInRect(r, Condition(function enumGates), null)
call EnumDestructablesInRect(r, Condition(function findPortal), null)
call RemoveRect(r)
set r = RectFromCenterSizeBJ(loc2, 600, 600)
call EnumDestructablesInRect(r, Condition(function enumGates), null)
call EnumDestructablesInRect(r, Condition(function findPortal), null)
call RemoveRect(r)
call SetSkyModel("war3mapImported\\LordaeronHillsSky.mdx")
if ActiveScroll.id.dungeonType == 0 then
//call SetTerrainFogEx(0,1000000,3500,0.5,0./255.,0./255.,0./255.)
call SetTerrainFogEx(0,0,3500,0.5,25./255.,25./255.,25./255.)
call SetDayNightModels("war3mapImported\\DNCCrypt.mdx", "war3mapImported\\DNCCrypt.mdx")
//call SetDayNightModels("Environment\\DNC\\DNCLordaeron\\DNCLordaeronTerrain\\DNCLordaeronTerrain.mdx", "Environment\\DNC\\DNCLordaeron\\DNCLordaeronUnit\\DNCLordaeronUnit.mdx")
elseif ActiveScroll.id.dungeonType == 1 then
call SetTerrainFogEx(0,0,5000,0.5,50./255.,75./255.,50./255.)
call SetDayNightModels("war3mapImported\\DNCSelection.mdx", "war3mapImported\\DNCSelection.mdx")
elseif ActiveScroll.id.dungeonType == 2 then
call SetTerrainFogEx(0,0,10000,0.5,255./255.,42./255.,0./255.)
call SetDayNightModels("war3mapImported\\DNCSelection.mdx", "war3mapImported\\DNCSelection.mdx")
endif
//call EnumItemsInRect(gg_rct_Dungeon_Area, null, function RemoveItems)
// Remove all creeps
call GroupEnumUnitsOfPlayer(g, CREEP_PLAYER, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g,u)
if (u != gg_unit_h002_0010 and (GetUnitAbilityLevel(u, 'Aloc') == 0 or IsUnitInGroup(u, Combatant.RemoveLater))) then
call Combatant[u].destroy()
call RemoveUnit(u)
endif
endloop
// Remove all items
call GroupEnumUnitsOfPlayer(g, PASSIVE, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g,u)
if (GetUnitTypeId(u) == 'e02F' and (RectContainsUnit(gg_rct_InteriorArea, u) or RectContainsUnit(gg_rct_InitArea, u) or RectContainsUnit(gg_rct_Dungeon_Area, u))) then
set itm = ItemObject[u]
if itm.visible then
call itm.destroy()
endif
endif
endloop
if ActiveScroll.id.dungeonType == 0 then
set DungeonZ = 2000
call CreateDestructableZ('B035', GetRectCenterX(gg_rct_Dungeon_Area), GetRectCenterY(gg_rct_Dungeon_Area), 2000, 0, 1, 0)
elseif ActiveScroll.id.dungeonType == 2 then
set DungeonZ = 0
if ActiveScroll.id.dungeonType == 2 then
set x = GetRectMinX(gg_rct_Dungeon_Area)
set xt = GetRectMaxX(gg_rct_Dungeon_Area)
set yt = GetRectMaxY(gg_rct_Dungeon_Area)
loop
exitwhen x > xt
set y = GetRectMinY(gg_rct_Dungeon_Area)
loop
exitwhen y > yt
//call CreateUnit(PASSIVE, 'e02U', x, y, 0)
call CreateDestructableZ('B03G', x, y, 0, 0, 1, 0)
set y = y + 1280
endloop
set x = x + 1280
endloop
endif
else
set DungeonZ = 0
endif
call Dungeon.enumerateMap(gg_rct_Dungeon_Area, function SpawnCreatures)
call EnumDestructablesInRect(gg_rct_Dungeon_Area, Condition(function decorateDungeon), null)
call GroupEnumUnitsInRect(Group, gg_rct_Dungeon_Area, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitInGroup(fog, PlayerUnits) then
call PanelCore_SetUnitZ(u, PanelCore_GetUnitZ(u))
endif
endloop
// Clear start area
call GroupEnumUnitsInRange(Group, x2, y2, CREEP_VISION_RANGE+500., null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if fog != gg_unit_h002_0010 and GetOwningPlayer(fog) == CREEP_PLAYER and not Combatant[fog].destructible then
call Combatant[fog].destroy()
call RemoveUnit(fog)
endif
endloop
if ActiveScroll.id.dungeonType == 0 then
call InitDest(gg_rct_Dungeon_Area, 2020)
else
call InitDest(gg_rct_Dungeon_Area, 20)
endif
call TimerStart(NewTimer(), 3, false, function fadeIn)
else
call TimerStart(NewTimer(), 2, false, function recreate)
endif
call RemoveLocation(loc)
call RemoveLocation(loc2)
call DestroyGroup(g)
set loc = null
set loc2 = null
set g = null
set u = null
endfunction
function aaa___Recreate takes nothing returns nothing
local DungeonUniform dung
local DungeonCavern dung2
call MiniMap_ClearTexture()
if ActiveScroll.id.dungeonType == 0 then
set dung = DungeonUniform.create(0,0,25+ActiveScroll.dungeonSize,25+ActiveScroll.dungeonSize, 10, 35, 0.3, false, 3, 6, 6, 0.2, 0.2) //read the readme for what all these parameters mean
call Dungeon.removeAll(gg_rct_Dungeon_Area)
call Dungeon.clearMap()
call dung.generate()
call Dungeon.verifyMap()
if Dungeon.isMapUsable() then
call Dungeon.clearUnverified()
call Dungeon.build(gg_rct_Dungeon_Area, ActiveScroll.id.dungeonType, function OnFinish)
endif
elseif ActiveScroll.id.dungeonType == 1 then
set dung2 = DungeonCavern.create(0,0,25+ActiveScroll.dungeonSize,25+ActiveScroll.dungeonSize, 40, true, 5, 2, 5, 5)
call Dungeon.removeAll(gg_rct_Dungeon_Area)
call Dungeon.clearMap()
call dung2.generate()
call Dungeon.verifyMap()
if Dungeon.isMapUsable() then
call Dungeon.clearUnverified()
call Dungeon.build(gg_rct_Dungeon_Area, ActiveScroll.id.dungeonType, function OnFinish)
endif
elseif ActiveScroll.id.dungeonType == 2 then
set dung2 = DungeonCavern.create(0,0,25+ActiveScroll.dungeonSize,25+ActiveScroll.dungeonSize, 40, true, 5, 2, 5, 5)
call Dungeon.removeAll(gg_rct_Dungeon_Area)
call Dungeon.clearMap()
call dung2.generate()
call Dungeon.verifyMap()
if Dungeon.isMapUsable() then
call Dungeon.clearUnverified()
call Dungeon.build(gg_rct_Dungeon_Area, ActiveScroll.id.dungeonType, function OnFinish)
endif
endif
endfunction
private function init takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function onEnter), UnitIndexer.INDEX)
set StairDownDialog = DialogCreate()
set StairDownTrigger2 = CreateTrigger()
call TriggerRegisterDialogEvent(StairDownTrigger2, StairDownDialog)
call TriggerAddCondition(StairDownTrigger2, Condition(function onClick))
call TimerStart(CreateTimer(), 0.1, true, function checkReadyGroup)
endfunction
endlibrary
/*
Creates a natural looking cavern.
*/
function Cave takes nothing returns nothing
local DungeonCavern dung2 = DungeonCavern.create(0,0,30,30, 40, true, 5, 2, 5, 5)
call Dungeon.removeAll(gg_rct_Dungeon_Area)
call Dungeon.clearMap()
call dung2.generate()
call Dungeon.verifyMap()
if Dungeon.isMapUsable() then
call Dungeon.clearUnverified()
call Dungeon.build(gg_rct_Dungeon_Area, TILESET_DEFAULT, function OnFinish)
endif
endfunction
/*
Creates two dungeons layered on top of each other.
*/
function Both takes nothing returns nothing
local DungeonUniform dung1 = DungeonUniform.create(0,0,64,64, 10, 20, 0.20, true, 3, 6, 6, 0.1, 0.2)
local DungeonCavern dung2 = DungeonCavern.create(0,0,64,64, 40, true, 5, 2, 4, 4)
call Dungeon.removeAll(gg_rct_Dungeon_Area)
call Dungeon.clearMap()
call dung2.generate()
call dung1.generate()
call Dungeon.verifyMap()
if Dungeon.isMapUsable() then
call Dungeon.clearUnverified()
call Dungeon.build(gg_rct_Dungeon_Area, TILESET_DEFAULT, function OnFinish)
endif
endfunction
/*
Creates two dungeons side by side; each taking up half of the area. They will also be randomly connected.
*/
function SideBySide takes nothing returns nothing
local integer x
local integer y
local DungeonUniform dung1 = DungeonUniform.create(32,0,64,64, 10, 15, 0.25, false, 3, 6, 6, 0.1, 0.2)
local DungeonCavern dung2 = DungeonCavern.create(0,0,32,64, 40, true, 5, 2, 6, 4)
local boolean connected = false
local integer connectAttempts = 0
call Dungeon.removeAll(gg_rct_Dungeon_Area)
call Dungeon.clearMap()
call dung2.generate()
call dung1.generate()
loop
if not connected then
if connectAttempts > 20 then
exitwhen true
endif
set x = GetRandomInt(1,62)
set y = GetRandomInt(1,62)
if Dungeon.getTile(x,y) >= DUNGEON_CAVE then
set connected = dung1.connectClosestRoom(x,y)
endif
set connectAttempts = connectAttempts+1
else
exitwhen true
endif
endloop
call Dungeon.verifyMap()
if Dungeon.isMapUsable() then
call Dungeon.clearUnverified()
call Dungeon.build(gg_rct_Dungeon_Area, TILESET_DEFAULT, function OnFinish)
endif
endfunction
//===========================================================================
function InitTrig_OtherDungeons takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterPlayerChatEvent(t, Player(0), "-both", true)
call TriggerAddAction(t, function Both)
set t = CreateTrigger()
call TriggerRegisterPlayerChatEvent(t, Player(0), "-side", true)
call TriggerAddAction(t, function SideBySide)
set t = CreateTrigger()
call TriggerRegisterPlayerChatEvent(t, Player(0), "-cave", true)
call TriggerAddAction(t, function Cave)
set t = CreateTrigger()
endfunction
scope EscButton
private function onPress takes nothing returns boolean
local player p = GetTriggerPlayer()
local integer pid = GetPlayerId(p)
if not IsUnitSelected(Controller[pid], p) then
if (Locale == p) then
call ClearSelection()
call SelectUnit(Controller[pid], true)
endif
elseif Tooltips1[pid].control.visible then
call Tooltips1[pid].show(false)
set Tooltips1[pid].itmObject = -1
call Tooltips2[pid].show(false)
set Tooltips2[pid].itmObject = -1
elseif UpgradeMenu_Main[pid].visible then
call UpgradeMenu_CloseWindow(pid)
elseif ShopUI[pid].visible then
call ShopUI[pid].show(false)
elseif Bag[pid].visible then
call Bag[pid].show(false)
elseif CharacterWindow_Visible[pid] then
call CharacterWindow_Show(pid, false)
elseif ShortcutBar_SkillSelection[pid].visible then
call ShortcutBar_SkillSelection[pid].clear()
set ShortcutBar_SelectIndex[pid] = -1
call ShortcutBar_SkillSelection[pid].show(false)
endif
return false
endfunction
function InitTrig_EscButton takes nothing returns nothing
set gg_trg_EscButton = CreateTrigger()
call TriggerRegisterPlayerEventEndCinematic(gg_trg_EscButton, Player(0))
call TriggerRegisterPlayerEventEndCinematic(gg_trg_EscButton, Player(1))
call TriggerRegisterPlayerEventEndCinematic(gg_trg_EscButton, Player(2))
call TriggerRegisterPlayerEventEndCinematic(gg_trg_EscButton, Player(3))
call TriggerAddCondition(gg_trg_EscButton, Condition(function onPress))
endfunction
endscope
scope AntiYellowCursor initializer init
globals
private unit LastSelection = null
private UIFrame Comp
private timer T
endglobals
private function resetCursor takes nothing returns nothing
call EnableUserControl(false)
call EnableUserControl(true)
//set Comp.visible = false
endfunction
private function checkSelection takes nothing returns nothing
local unit u
if CharacterManager_GameModeCode == 22 then
set u = BlzGetMouseFocusUnit()
if u == null then
if LastSelection != null then
//set Comp.visible = true
call TimerStart(T, 0.3, false, function resetCursor)
set LastSelection = null
endif
elseif LastSelection != u then
set LastSelection = u
endif
set u = null
endif
endfunction
private function init takes nothing returns nothing
/*set Comp = UIFrame.create(false, UIFrame.TYPE_TEXTURE, UIFrame.Null, 0, 0, 0)
set Comp.anchorPoint = FRAMEPOINT_CENTER
set Comp.opacity = 128
set Comp.visible = false
call Comp.setSize(10000, 10000)*/
set T = CreateTimer()
call TimerStart(CreateTimer(), 0.03, true, function checkSelection)
endfunction
endscope
library CooldownAnimation uses PanelPlatform, TimerUtils, BJObjectId
struct CooldownAnimation
PanelPlatform plat
BJObjectId index
integer count
timer time
static real ASEC = 1.00000000000/120.00000000000
static thistype array Index
static method Stop takes PanelPlatform plat returns nothing
local thistype this = Index[plat]
if this != 0 then
call deallocate()
call ReleaseTimer(.time)
set Index[.plat] = 0
set .time = null
endif
endmethod
static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
set .count = .count - 1
if .count < 0 or .plat.dummy == null then
call .plat.show(false)
call deallocate()
call ReleaseTimer(t)
set Index[.plat] = 0
set .time = null
else
set .index = .index.plus_1()
set .plat.texture = .index
call .plat.refresh()
endif
set t = null
endmethod
static method create takes PanelPlatform plat, real duration, real default returns thistype
local thistype this
local real rate = duration/default
local integer exit
if Index[plat] == 0 then
set this = allocate()
set Index[plat] = this
set .plat = plat
set .time = NewTimerEx(this)
else
set this = Index[plat]
endif
set .count = R2I(120*rate)
set .index = 'CD00'
set exit = 120 - .count
loop
exitwhen exit == 0
set .index = .index.plus_1()
set exit = exit - 1
endloop
set .plat.texture = .index
call .plat.show(true)
call .plat.refresh()
call TimerStart(.time, ASEC*default, true, function thistype.onTick)
return this
endmethod
endstruct
endlibrary
//! textmacro CreateCooldownObject takes TYPE, CODE, INDEX, FILEPATH, EXTENSION
//! external ObjectMerger w3b YTlb $TYPE$$CODE$ bnam "(Cooldown) $TYPE$ Bar $INDEX$" bfxr -1 bfil ".mdl" boch 0 btxf "$FILEPATH$\$INDEX$$EXTENSION$" btxi 33 bfvi 1 bsel 0 bgsc 0 bshd "" barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
//! runtextmacro CreateCooldownObject ("CD", "00", "0", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "01", "1", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "02", "2", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "03", "3", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "04", "4", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "05", "5", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "06", "6", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "07", "7", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "08", "8", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "09", "9", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0A", "10", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0B", "11", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0C", "12", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0D", "13", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0E", "14", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0F", "15", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0G", "16", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0H", "17", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0I", "18", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0J", "19", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0K", "20", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0L", "21", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0M", "22", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0N", "23", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0O", "24", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0P", "25", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0Q", "26", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0R", "27", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0S", "28", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0T", "29", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0U", "30", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0V", "31", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0W", "32", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0X", "33", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0Y", "34", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "0Z", "35", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "10", "36", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "11", "37", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "12", "38", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "13", "39", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "14", "40", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "15", "41", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "16", "42", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "17", "43", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "18", "44", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "19", "45", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1A", "46", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1B", "47", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1C", "48", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1D", "49", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1E", "50", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1F", "51", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1G", "52", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1H", "53", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1I", "54", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1J", "55", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1K", "56", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1L", "57", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1M", "58", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1N", "59", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1O", "60", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1P", "61", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1Q", "62", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1R", "63", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1S", "64", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1T", "65", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1U", "66", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1V", "67", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1W", "68", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1X", "69", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1Y", "70", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "1Z", "71", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "20", "72", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "21", "73", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "22", "74", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "23", "75", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "24", "76", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "25", "77", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "26", "78", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "27", "79", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "28", "80", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "29", "81", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2A", "82", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2B", "83", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2C", "84", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2D", "85", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2E", "86", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2F", "87", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2G", "88", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2H", "89", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2I", "90", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2J", "91", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2K", "92", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2L", "93", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2M", "94", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2N", "95", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2O", "96", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2P", "97", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2Q", "98", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2R", "99", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2S", "100", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2T", "101", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2U", "102", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2V", "103", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2W", "104", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2X", "105", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2Y", "106", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "2Z", "107", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "30", "108", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "31", "109", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "32", "110", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "33", "111", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "34", "112", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "35", "113", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "36", "114", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "37", "115", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "38", "116", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "39", "117", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "3A", "118", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "3B", "119", "cooldown", ".blp")
//! runtextmacro CreateCooldownObject ("CD", "3C", "120", "cooldown", ".blp")
library MiniMap initializer init uses TimerUtils, UIUtils
globals
constant boolean LEGEND_BOUND_RADIAL = false
constant real LEGEND_REFRESH_RATE = 0.01
constant real GENERAL_SIZE = 0.85
constant real BOUND_RADIUS = 128.0*GENERAL_SIZE//70.0
constant real DEFAULT_ZOOM_LEVEL = 0.35
constant real MINIMAP_X = 1225.0
constant real MINIMAP_Y = 636.0
constant real MINIMAP_WIDTH = 258.0*GENERAL_SIZE
constant real MINIMAP_HEIGHT = 258.0*GENERAL_SIZE
constant real MINIMAP_MIN_X = MINIMAP_X-MINIMAP_WIDTH/2
constant real MINIMAP_MAX_X = MINIMAP_X+MINIMAP_WIDTH/2
constant real MINIMAP_MIN_Y = MINIMAP_Y-MINIMAP_HEIGHT/2
constant real MINIMAP_MAX_Y = MINIMAP_Y+MINIMAP_HEIGHT/2
constant integer TILE_DIMENSION = 30
constant real TILE_SCALE = 0.2
constant real TILE_WIDTH = 209.0*TILE_SCALE
constant real TILE_HEIGHT = 200.0*TILE_SCALE
constant real TILE_WIDTH_T = TILE_WIDTH*TILE_DIMENSION
constant real TILE_HEIGHT_T = TILE_HEIGHT*TILE_DIMENSION
public real ZoomLevel = DEFAULT_ZOOM_LEVEL
public UIFrame Frame
public UIFrame TilePanel
public UIFrame ButtonPanel
public UIFrame MaximizeButton
public UIFrame Background
public UIFrame BluePortal
public UIFrame RedPortal
public UIFrame array Allies
public UIFrame array Tile[200][200]
public string array TileTexture[TILE_DIMENSION][TILE_DIMENSION]
private integer TempInt
private integer TempInt2
real DungeonWidth
real DungeonHeight
real DungeonMaxX
real DungeonMinX
real DungeonMaxY
real DungeonMinY
real DungeonCenterX
real DungeonCenterY
private integer width
private integer height
private integer xGrid
private integer yGrid
private integer xGrid2
private integer yGrid2
private integer exitW
private integer exitH
private integer color
endglobals
private function GetUnitDungeonX takes unit u returns real
return GetUnitX(u)-DungeonCenterX
endfunction
private function GetUnitDungeonY takes unit u returns real
return GetUnitY(u)-DungeonCenterY
endfunction
struct Legend extends array
boolean static
boolean persistent
UIFrame plat
unit u
real x
real y
implement LinkedList
method destroy takes nothing returns nothing
call .plat.destroy()
call removeNode()
call deallocate()
set .u = null
endmethod
endstruct
struct MinimapLegend extends array
static Legend legends
static Legend current
static timer t
static method onTick takes nothing returns nothing
local real x
local real y
local real x2
local real y2
local real dx
local real dy
local real a
local real r
local real bound
if not InDungeon then
return
endif
if current.head or current == 0 then
call PauseTimer(t)
endif
if current > 0 and current != legends then
//if .current.static or UnitAlive(.current.u) then
set x = GetUnitDungeonX(MainUnit[PNumb])
set y = GetUnitDungeonY(MainUnit[PNumb])
if .current.static then
set x2 = .current.x-DungeonCenterX
set y2 = .current.y-DungeonCenterY
else
set x2 = GetUnitX(.current.u)-DungeonCenterX
set y2 = GetUnitY(.current.u)-DungeonCenterY
endif
set dx = (x-x2)*(TILE_WIDTH/640.)*ZoomLevel
set dy = (y-y2)*(TILE_HEIGHT/640.)*ZoomLevel
static if LEGEND_BOUND_RADIAL then
set r = SquareRoot(dx*dx+dy*dy)
if r > BOUND_RADIUS then
if current.persistent then
set r = BOUND_RADIUS
set a = Atan2(y2-y, x2-x)
set current.plat.visible = Frame.visible
call current.plat.move(r*Cos(a), r*Sin(a))
else
set current.plat.visible = false
endif
else
set a = Atan2(y2-y, x2-x)
set current.plat.visible = Frame.visible
call current.plat.move(r*Cos(a), r*Sin(a))
endif
else
if current.persistent then
if dx > BOUND_RADIUS then
set dx = BOUND_RADIUS
elseif dx < -BOUND_RADIUS then
set dx = -BOUND_RADIUS
endif
if dy > BOUND_RADIUS then
set dy = BOUND_RADIUS
elseif dy < -BOUND_RADIUS then
set dy = -BOUND_RADIUS
endif
set current.plat.visible = true
call current.plat.move(-dx, -dy)
else
if dx > BOUND_RADIUS or dx < -BOUND_RADIUS or dy > BOUND_RADIUS or dy < -BOUND_RADIUS then
set current.plat.visible = false
else
set current.plat.visible = true
call current.plat.move(-dx, -dy)
endif
endif
endif
//else
// call .current.destroy()
//endif
endif
set current = current.next
endmethod
static method addStatic takes real x, real y, string texture, real scale, boolean persistent returns Legend
local Legend l = Legend.allocate()
set l.persistent = persistent
set l.static = true
set l.x = x
set l.y = y
set l.plat = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, Frame, 0.0, 0.0, 4)
set l.plat.texture = texture
set l.plat.localScale = scale
set l.plat.visible = false
set l.plat.scalePosition = false
call l.plat.setPivotPoint(0.5, 0.5)
call legends.insertNode(l)
return l
endmethod
static method add takes unit u, string texture, real scale, boolean persistent returns Legend
local Legend l = Legend.allocate()
set l.persistent = persistent
set l.static = false
set l.u = u
set l.plat = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, Frame, 0.0, 0.0, 4)
set l.plat.texture = texture
set l.plat.localScale = scale
set l.plat.visible = false
set l.plat.scalePosition = false
call l.plat.setPivotPoint(0.5, 0.5)
call legends.insertNode(l)
return l
endmethod
static method refresh takes nothing returns nothing
set current = legends.next
call TimerStart(t, LEGEND_REFRESH_RATE, true, function thistype.onTick)
endmethod
static method create takes nothing returns thistype
set legends = Legend.createNode()
set t = NewTimer()
return 0
endmethod
endstruct
public function Zoom takes real z returns nothing
if z > 1.5 then
set z = 1.5
elseif z < 0.5 then
set z = 0.5
endif
set ZoomLevel = z
set TilePanel.localScale = z
endfunction
private function EvalVisibilitySub takes nothing returns nothing
local UIFrame tile
local real xb = TILE_WIDTH/2*ZoomLevel
local real yb = TILE_HEIGHT/2*ZoomLevel
local real x2
local real y2
local real dx
local real dy
set tile = Tile[TempInt][TempInt2]
if IsUnitAlive(MainUnit[PNumb]) and tile.texture != "ReplaceableTextures\\CommandButtons\\BTNalpha.blp" then
set x2 = (TilePanel.localPosX + tile.localPosX*ZoomLevel)
set y2 = (TilePanel.localPosY + tile.localPosY*ZoomLevel)
set tile.visible = (x2-xb > MINIMAP_MIN_X and x2+xb < MINIMAP_MAX_X and y2-yb > MINIMAP_MIN_Y and y2+yb < MINIMAP_MAX_Y)
set dx = I2R(TempInt-xGrid)
set dy = I2R(TempInt2-yGrid)
set dx = dx*dx+dy*dy
set color = 0
if dx < 4. then
set color = 255
else
set color = R2I(255.*(1.-dx/16.))
if color < 0 then
set color = 0
elseif color > 255 then
set color = 255
endif
endif
/*if color == 0 and tile.red == 0 then
call tile.show(false)
elseif tile.red < color then
call tile.setColor(color, color, color, 255)
endif*/
if color == 0 and tile.opacity <= 0 then
set tile.visible = false
elseif tile.opacity < color then
set tile.opacity = color
endif
elseif tile.visible then
set tile.visible = false
endif
endfunction
private function EvalVisibility takes nothing returns nothing
local integer i
local integer j
local integer k
local real x
local real y
local real x2
local real y2
local real dx
local real dy
local real a
local real r
local real bound
if InDungeon then
set width = R2I(MINIMAP_WIDTH/(TILE_WIDTH*ZoomLevel)/2.)
set height = R2I(MINIMAP_HEIGHT/(TILE_HEIGHT*ZoomLevel)/2.)
set xGrid = R2I((GetUnitX(MainUnit[PNumb])-DungeonMinX)/640.)
set yGrid = R2I((GetUnitY(MainUnit[PNumb])-DungeonMinY)/640.)
//if xGrid != LastPlayerGridX[PNumb] or yGrid != LastPlayerGridY[PNumb] then
//set LastPlayerGridX[PNumb] = xGrid
//set LastPlayerGridY[PNumb] = yGrid
set exitW = xGrid+width+1
set exitH = yGrid+height+1
if exitW > TILE_DIMENSION-1 then
set exitW = TILE_DIMENSION-1
elseif exitW < 0 then
set exitW = 0
endif
if exitH > TILE_DIMENSION-1 then
set exitH = TILE_DIMENSION-1
elseif exitH < 0 then
set exitH = 0
endif
set j = xGrid-width-1
if j > TILE_DIMENSION-1 then
set j = TILE_DIMENSION-1
elseif j < 0 then
set j = 0
endif
loop
exitwhen j > exitW
set k = yGrid-height-1
if k > TILE_DIMENSION-1 then
set k = TILE_DIMENSION-1
elseif k < 0 then
set k = 0
endif
loop
exitwhen k > exitH
set TempInt = j
set TempInt2 = k
call ForForce(bj_FORCE_PLAYER[0], function EvalVisibilitySub)
set k = k + 1
endloop
set j = j + 1
endloop
//endif
set bound = 70.
set x = GetUnitDungeonX(MainUnit[PNumb])
set y = GetUnitDungeonY(MainUnit[PNumb])
set x2 = BluePortalX-DungeonCenterX
set y2 = BluePortalY-DungeonCenterY
set dx = (x-x2)*(TILE_WIDTH/640.)*ZoomLevel
set dy = (y-y2)*(TILE_HEIGHT/640.)*ZoomLevel
static if LEGEND_BOUND_RADIAL then
set r = SquareRoot(dx*dx+dy*dy)
if r > BOUND_RADIUS then
set r = BOUND_RADIUS
endif
set a = Atan2(y2-y, x2-x)
call BluePortal.move(r*Cos(a), r*Sin(a))
else
if dx > BOUND_RADIUS then
set dx = BOUND_RADIUS
elseif dx < -BOUND_RADIUS then
set dx = -BOUND_RADIUS
endif
if dy > BOUND_RADIUS then
set dy = BOUND_RADIUS
elseif dy < -BOUND_RADIUS then
set dy = -BOUND_RADIUS
endif
call BluePortal.move(-dx, -dy)
endif
if RedPortalRevealed then
set x2 = RedPortalX-DungeonCenterX
set y2 = RedPortalY-DungeonCenterY
set dx = (x-x2)*(TILE_WIDTH/640.)*ZoomLevel
set dy = (y-y2)*(TILE_HEIGHT/640.)*ZoomLevel
static if LEGEND_BOUND_RADIAL then
set r = SquareRoot(dx*dx+dy*dy)
if r > BOUND_RADIUS then
set r = BOUND_RADIUS
endif
set a = Atan2(y2-y, x2-x)
call RedPortal.move(r*Cos(a), r*Sin(a))
else
if dx > BOUND_RADIUS then
set dx = BOUND_RADIUS
elseif dx < -BOUND_RADIUS then
set dx = -BOUND_RADIUS
endif
if dy > BOUND_RADIUS then
set dy = BOUND_RADIUS
elseif dy < -BOUND_RADIUS then
set dy = -BOUND_RADIUS
endif
call RedPortal.move(-dx, -dy)
endif
set RedPortal.visible = true
else
set RedPortal.visible = false
endif
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] and i != PNumb then
set x2 = GetUnitDungeonX(MainUnit[i])
set y2 = GetUnitDungeonY(MainUnit[i])
set dx = (x-x2)*(TILE_WIDTH/640.)*ZoomLevel
set dy = (y-y2)*(TILE_HEIGHT/640.)*ZoomLevel
static if LEGEND_BOUND_RADIAL then
set r = SquareRoot(dx*dx+dy*dy)
if r > BOUND_RADIUS then
set r = BOUND_RADIUS
endif
set a = Atan2(y2-y, x2-x)
call Allies[i].move(r*Cos(a), r*Sin(a))
else
if dx > BOUND_RADIUS then
set dx = BOUND_RADIUS
elseif dx < -BOUND_RADIUS then
set dx = -BOUND_RADIUS
endif
if dy > BOUND_RADIUS then
set dy = BOUND_RADIUS
elseif dy < -BOUND_RADIUS then
set dy = -BOUND_RADIUS
endif
call Allies[i].move(-dx, -dy)
endif
else
set Allies[i].visible = false
endif
set i = i + 1
endloop
call MinimapLegend.refresh()
endif
endfunction
public function UpdateMinimap takes nothing returns nothing
local real x
local real y
if Frame.visible then
set x = MINIMAP_X-(TILE_WIDTH_T*(GetUnitDungeonX(MainUnit[PNumb])/(DungeonWidth/2)/2))*ZoomLevel
set y = MINIMAP_Y-(TILE_HEIGHT_T*(GetUnitDungeonY(MainUnit[PNumb])/(DungeonHeight/2)/2))*ZoomLevel
call ForForce(bj_FORCE_PLAYER[0], function EvalVisibility)
call TilePanel.move(x, y)
endif
endfunction
public function UpdateTexture takes nothing returns nothing
local integer i
local integer j
set i = 0
loop
exitwhen i == TILE_DIMENSION
set j = 0
loop
exitwhen j == TILE_DIMENSION
set Tile[i][j].texture = TileTexture[i][j]
set j = j + 1
endloop
set i = i + 1
endloop
endfunction
public function HideAll takes nothing returns nothing
local integer i
local integer j
set i = 0
loop
exitwhen i == TILE_DIMENSION
set j = 0
loop
exitwhen j == TILE_DIMENSION
set Tile[i][j].visible = false
set j = j + 1
endloop
set i = i + 1
endloop
endfunction
public function Show takes boolean b returns nothing
set Frame.visible = b
set TilePanel.visible = b
set ButtonPanel.visible = b
endfunction
public function ClearTexture takes nothing returns nothing
local integer i
local integer j
set i = 0
loop
exitwhen i == TILE_DIMENSION
set j = 0
loop
exitwhen j == TILE_DIMENSION
set TileTexture[i][j] = "ReplaceableTextures\\CommandButtons\\BTNalpha.blp"
set j = j + 1
endloop
set i = i + 1
endloop
endfunction
public function HidePartitions takes nothing returns nothing
local integer i = 0
local integer j
loop
exitwhen i == TILE_DIMENSION
set j = 0
loop
exitwhen j == TILE_DIMENSION
set Tile[i][j].opacity = 0
set Tile[i][j].visible = false
set j = j + 1
endloop
set i = i + 1
endloop
endfunction
private function onSelect takes nothing returns boolean
if Locale == GetTriggerPlayer() then
if MaximizeButton.texture == "war3mapImported\\MinimapMaximize.blp" then
set MaximizeButton.texture = "war3mapImported\\MinimapMinimize.blp"
set TilePanel.visible = false
set Frame.visible = false
else
call HideAll()
set MaximizeButton.texture = "war3mapImported\\MinimapMaximize.blp"
set TilePanel.visible = true
set Frame.visible = true
call UpdateMinimap()
endif
endif
return false
endfunction
private function CreateTile takes nothing returns nothing
set Tile[TempInt][TempInt2] = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, TilePanel, ((-TILE_WIDTH_T+TILE_WIDTH)/2)+TILE_WIDTH*TempInt, ((-TILE_HEIGHT_T+TILE_HEIGHT)/2)+TILE_HEIGHT*TempInt2, 0)
set Tile[TempInt][TempInt2].localScale = TILE_SCALE
set Tile[TempInt][TempInt2].visible = false
set Tile[TempInt][TempInt2].name = "Tile " + I2S(TempInt) + " - " + I2S(TempInt2)
set Tile[TempInt][TempInt2].inheritOpacity = false
set Tile[TempInt][TempInt2].alwaysRefresh = false
call Tile[TempInt][TempInt2].setPivotPoint(0.5, 0.5)
call Tile[TempInt][TempInt2].setSize(215, 206)
endfunction
public function Create takes nothing returns nothing
local integer i
local integer j
local UIFrame comp
set Frame = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, UIFrame.Null, MINIMAP_X, MINIMAP_Y, 0)
set Frame.localScale = GENERAL_SIZE
set Frame.name = "main frame"
//set Frame.texture = "war3mapImported\\MinimapBG.tga"
call Frame.setSize(0, 0)
call Frame.setPivotPoint(0.5, 0.5)
set TilePanel = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, UIFrame.Null, MINIMAP_X, MINIMAP_Y, 1)
set TilePanel.localScale = DEFAULT_ZOOM_LEVEL
set TilePanel.name = "tile panel"
call TilePanel.setSize(0, 0)
call TilePanel.setPivotPoint(0.5, 0.5)
set ButtonPanel = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, UIFrame.Null, MINIMAP_X, MINIMAP_Y, 0)
set ButtonPanel.localScale = GENERAL_SIZE
set ButtonPanel.name = "button panel"
call ButtonPanel.setSize(0, 0)
call ButtonPanel.setPivotPoint(0.5, 0.5)
set Background = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, Frame, 0, 0, 0)
set Background.texture = "Textures\\black32.blp"
set Background.name = "background panel"
set Background.opacity = 32
call Background.setSize(258, 258)
call Background.setPivotPoint(0.5, 0.5)
// White dot
set comp = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, Frame, 0, 0, 3)
call comp.setSize(5, 5)
call comp.setPivotPoint(0.5, 0.5)
set BluePortal = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, Frame, 0, 0, 2)
set BluePortal.texture = "war3mapImported\\PortalBlue.tga"
set BluePortal.localScale = 0.5
set BluePortal.scalePosition = false
call BluePortal.setSize(50, 50)
call BluePortal.setPivotPoint(0.5, 0.5)
set RedPortal = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, Frame, 0, 0, 3)
set RedPortal.texture = "war3mapImported\\PortalRed.tga"
set RedPortal.localScale = 0.5
set RedPortal.scalePosition = false
call RedPortal.setSize(50, 50)
call RedPortal.setPivotPoint(0.5, 0.5)
set MaximizeButton = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, ButtonPanel, 115, 113, 4)
set MaximizeButton.texture = "war3mapImported\\MinimapMinimize.blp"
set MaximizeButton.localScale = 0.4
call MaximizeButton.setSize(55, 55)
call MaximizeButton.setPivotPoint(0.5, 0.5)
set i = 0
loop
exitwhen i == TILE_DIMENSION
set TempInt = i
set j = 0
loop
exitwhen j == TILE_DIMENSION
set TempInt2 = j
call ForForce(bj_FORCE_PLAYER[0], function CreateTile)
set j = j + 1
endloop
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] then
set Allies[i] = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, Frame, 0, 0, 3)
set Allies[i].texture = "Replaceabletextures\\Teamcolor\\Teamcolor0" + I2S(i) + ".blp"
set Allies[i].visible = PNumb != i
set Allies[i].scalePosition = false
call Allies[i].setSize(5, 5)
call Allies[i].setPivotPoint(0.5, 0.5)
endif
set i = i + 1
endloop
set TilePanel.visible = false
set Frame.visible = false
set ButtonPanel.visible = false
call MinimapLegend.create()
call TimerStart(CreateTimer(), 0.5, true, function UpdateMinimap)
endfunction
private function init takes nothing returns nothing
set DungeonMaxX = GetRectMaxX(gg_rct_Dungeon_Area)
set DungeonMinX = GetRectMinX(gg_rct_Dungeon_Area)
set DungeonMaxY = GetRectMaxY(gg_rct_Dungeon_Area)
set DungeonMinY = GetRectMinY(gg_rct_Dungeon_Area)
set DungeonCenterX = GetRectCenterX(gg_rct_Dungeon_Area)
set DungeonCenterY = GetRectCenterY(gg_rct_Dungeon_Area)
set DungeonWidth = DungeonMaxX - DungeonMinX
set DungeonHeight = DungeonMaxY - DungeonMinY
call Create()
endfunction
endlibrary
library MiniMap initializer init uses TimerUtils, UIUtils
//! runtextmacro CREATE_MULTI_ARRAY("PanelPlatform", "Tile", "3")
globals
constant boolean LEGEND_BOUND_RADIAL = false
constant real LEGEND_REFRESH_RATE = 0.01
constant real GENERAL_SIZE = 0.7
constant real BOUND_RADIUS = 128.0*GENERAL_SIZE//70.0
constant real DEFAULT_ZOOM_LEVEL = 0.35
constant real MINIMAP_X = 525.0
constant real MINIMAP_Y = 245.0
constant real MINIMAP_WIDTH = 258.0*GENERAL_SIZE
constant real MINIMAP_HEIGHT = 258.0*GENERAL_SIZE
constant real MINIMAP_MIN_X = MINIMAP_X-MINIMAP_WIDTH/2
constant real MINIMAP_MAX_X = MINIMAP_X+MINIMAP_WIDTH/2
constant real MINIMAP_MIN_Y = MINIMAP_Y-MINIMAP_HEIGHT/2
constant real MINIMAP_MAX_Y = MINIMAP_Y+MINIMAP_HEIGHT/2
constant integer TILE_DIMENSION = 30
constant real TILE_SCALE = 0.2
constant real TILE_WIDTH = 209.0*TILE_SCALE
constant real TILE_HEIGHT = 200.0*TILE_SCALE
constant real TILE_WIDTH_T = TILE_WIDTH*TILE_DIMENSION
constant real TILE_HEIGHT_T = TILE_HEIGHT*TILE_DIMENSION
//public PanelPlatform array Tile[4][100][100]
public integer array LastPlayerGridX
public integer array LastPlayerGridY
public real array ZoomLevel
public Panel array Frame
public Panel array TilePanel
public Panel array ButtonPanel
public PanelPlatform array MaximizeButton
public PanelPlatform array Background
public PanelPlatform array BluePortal
public PanelPlatform array RedPortal
public PanelPlatform array Allies[4][4]
//! runtextmacro PASTE_MULTI_ARRAY_VARIABLE("public", "Tile")
public integer array TileTexture[TILE_DIMENSION][TILE_DIMENSION]
private integer TempInt
private integer TempInt2
private integer TempInt3
real DungeonWidth
real DungeonHeight
real DungeonMaxX
real DungeonMinX
real DungeonMaxY
real DungeonMinY
real DungeonCenterX
real DungeonCenterY
private integer width
private integer height
private integer xGrid
private integer yGrid
private integer xGrid2
private integer yGrid2
private integer exitW
private integer exitH
private integer color
endglobals
struct Legend extends array
boolean static
boolean persistent
PanelPlatform plat
unit u
real x
real y
implement LinkedList
method destroy takes nothing returns nothing
call .plat.destroy()
call removeNode()
call deallocate()
set .u = null
endmethod
endstruct
private function GetUnitDungeonX takes unit u returns real
return GetUnitX(u)-DungeonCenterX
endfunction
private function GetUnitDungeonY takes unit u returns real
return GetUnitY(u)-DungeonCenterY
endfunction
struct MinimapLegend
private static thistype array Index
integer pid
Legend legends
Legend current
timer t
static method operator [] takes integer pid returns thistype
return Index[pid]
endmethod
static method onTick takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local real x
local real y
local real x2
local real y2
local real dx
local real dy
local real a
local real r
local real bound
if not InDungeon then
return
endif
if .current.head or .current == 0 then
call PauseTimer(.t)
endif
if .current > 0 and .current != .legends then
//if .current.static or UnitAlive(.current.u) then
set x = GetUnitDungeonX(MainUnit[.pid])
set y = GetUnitDungeonY(MainUnit[.pid])
if .current.static then
set x2 = .current.x-DungeonCenterX
set y2 = .current.y-DungeonCenterY
else
set x2 = GetUnitX(.current.u)-DungeonCenterX
set y2 = GetUnitY(.current.u)-DungeonCenterY
endif
set dx = (x-x2)*(TILE_WIDTH/640.)*ZoomLevel[.pid]
set dy = (y-y2)*(TILE_HEIGHT/640.)*ZoomLevel[.pid]
static if LEGEND_BOUND_RADIAL then
set r = SquareRoot(dx*dx+dy*dy)
if r > BOUND_RADIUS then
if .current.persistent then
set r = BOUND_RADIUS
set a = Atan2(y2-y, x2-x)
call .current.plat.show(true)
call .current.plat.move(r*Cos(a), r*Sin(a), .current.plat.level)
call .current.plat.refresh()
else
call .current.plat.show(false)
endif
else
set a = Atan2(y2-y, x2-x)
call .current.plat.show(true)
call .current.plat.move(r*Cos(a), r*Sin(a), .current.plat.level)
call .current.plat.refresh()
endif
else
if .current.persistent then
if dx > BOUND_RADIUS then
set dx = BOUND_RADIUS
elseif dx < -BOUND_RADIUS then
set dx = -BOUND_RADIUS
endif
if dy > BOUND_RADIUS then
set dy = BOUND_RADIUS
elseif dy < -BOUND_RADIUS then
set dy = -BOUND_RADIUS
endif
call .current.plat.show(true)
call .current.plat.move(-dx, -dy, .current.plat.level)
call .current.plat.refresh()
else
if dx > BOUND_RADIUS or dx < -BOUND_RADIUS or dy > BOUND_RADIUS or dy < -BOUND_RADIUS then
call .current.plat.show(false)
else
call .current.plat.show(true)
call .current.plat.move(-dx, -dy, .current.plat.level)
call .current.plat.refresh()
endif
endif
endif
//else
// call .current.destroy()
//endif
endif
set .current = .current.next
endmethod
method addStatic takes real x, real y, integer id, integer texture, real scale, boolean persistent returns Legend
local Legend l = Legend.allocate()
set l.persistent = persistent
set l.static = true
set l.x = x
set l.y = y
set l.plat = PanelPlatform.create(Frame[.pid], id, texture, 0.0, 0.0, 4)
set l.plat.scale = scale
set l.plat.transformAxis = false
call l.plat.show(false)
call .legends.insertNode(l)
return l
endmethod
method add takes unit u, integer id, integer texture, real scale, boolean persistent returns Legend
local Legend l = Legend.allocate()
set l.persistent = persistent
set l.static = false
set l.u = u
set l.plat = PanelPlatform.create(Frame[.pid], id, texture, 0.0, 0.0, 4)
set l.plat.scale = scale
set l.plat.transformAxis = false
call l.plat.show(false)
call .legends.insertNode(l)
return l
endmethod
method refresh takes nothing returns nothing
set .current = .legends.next
call TimerStart(.t, LEGEND_REFRESH_RATE, true, function thistype.onTick)
endmethod
static method create takes integer pid returns thistype
local thistype this = allocate()
set Index[pid] = this
set .pid = pid
set .legends = Legend.createNode()
set .t = NewTimerEx(this)
return this
endmethod
endstruct
public function Zoom takes integer i, real z returns nothing
if IsPlaying[i] then
if z > 1.5 then
set z = 1.5
elseif z < 0.5 then
set z = 0.5
endif
set ZoomLevel[i] = z
set TilePanel[i].scale = z
endif
endfunction
private function EvalVisibilitySub takes nothing returns nothing
local PanelPlatform tile
local real xb = TILE_WIDTH/2*ZoomLevel[TempInt]
local real yb = TILE_HEIGHT/2*ZoomLevel[TempInt]
local real x2
local real y2
local real dx
local real dy
local boolean visible
set tile = Tile[TempInt][TempInt2][TempInt3].value
if IsUnitAlive(MainUnit[TempInt]) and tile.texture != 'BSAL' then
set x2 = (TilePanel[TempInt].xOffset + tile.xOffset*ZoomLevel[TempInt])
set y2 = (TilePanel[TempInt].yOffset + tile.yOffset*ZoomLevel[TempInt])
set visible = tile.visible
call tile.show(x2-xb > MINIMAP_MIN_X and x2+xb < MINIMAP_MAX_X and y2-yb > MINIMAP_MIN_Y and y2+yb < MINIMAP_MAX_Y)
set dx = I2R(TempInt2-xGrid)
set dy = I2R(TempInt3-yGrid)
set dx = dx*dx+dy*dy
set color = 0
if dx < 4. then
set color = 255
else
set color = R2I(255.*(1.-dx/16.))
if color < 0 then
set color = 0
elseif color > 255 then
set color = 255
endif
endif
/*if color == 0 and tile.red == 0 then
call tile.show(false)
elseif tile.red < color then
call tile.setColor(color, color, color, 255)
endif*/
if color == 0 and tile.alpha == 0 then
call tile.show(false)
elseif tile.alpha < color then
call tile.setColor(255, 255, 255, color)
endif
if not visible and tile.visible then
call tile.refresh()
endif
elseif tile.visible then
call tile.show(false)
endif
endfunction
private function EvalVisibility takes nothing returns nothing
local integer i
local integer j
local integer k
local real x
local real y
local real x2
local real y2
local real dx
local real dy
local real a
local real r
local real bound
if InDungeon then
set width = R2I(MINIMAP_WIDTH/(TILE_WIDTH*ZoomLevel[TempInt])/2.)
set height = R2I(MINIMAP_HEIGHT/(TILE_HEIGHT*ZoomLevel[TempInt])/2.)
set xGrid = R2I((GetUnitX(MainUnit[TempInt])-DungeonMinX)/640.)
set yGrid = R2I((GetUnitY(MainUnit[TempInt])-DungeonMinY)/640.)
//if xGrid != LastPlayerGridX[TempInt] or yGrid != LastPlayerGridY[TempInt] then
//set LastPlayerGridX[TempInt] = xGrid
//set LastPlayerGridY[TempInt] = yGrid
set exitW = xGrid+width+1
set exitH = yGrid+height+1
if exitW > TILE_DIMENSION-1 then
set exitW = TILE_DIMENSION-1
elseif exitW < 0 then
set exitW = 0
endif
if exitH > TILE_DIMENSION-1 then
set exitH = TILE_DIMENSION-1
elseif exitH < 0 then
set exitH = 0
endif
set j = xGrid-width-1
if j > TILE_DIMENSION-1 then
set j = TILE_DIMENSION-1
elseif j < 0 then
set j = 0
endif
loop
exitwhen j > exitW
set k = yGrid-height-1
if k > TILE_DIMENSION-1 then
set k = TILE_DIMENSION-1
elseif k < 0 then
set k = 0
endif
loop
exitwhen k > exitH
set TempInt2 = j
set TempInt3 = k
call ForForce(bj_FORCE_PLAYER[0], function EvalVisibilitySub)
set k = k + 1
endloop
set j = j + 1
endloop
//endif
set bound = 70.
set x = GetUnitDungeonX(MainUnit[TempInt])
set y = GetUnitDungeonY(MainUnit[TempInt])
set x2 = BluePortalX-DungeonCenterX
set y2 = BluePortalY-DungeonCenterY
set dx = (x-x2)*(TILE_WIDTH/640.)*ZoomLevel[TempInt]
set dy = (y-y2)*(TILE_HEIGHT/640.)*ZoomLevel[TempInt]
static if LEGEND_BOUND_RADIAL then
set r = SquareRoot(dx*dx+dy*dy)
if r > BOUND_RADIUS then
set r = BOUND_RADIUS
endif
set a = Atan2(y2-y, x2-x)
call BluePortal[TempInt].move(r*Cos(a), r*Sin(a), BluePortal[TempInt].level)
else
if dx > BOUND_RADIUS then
set dx = BOUND_RADIUS
elseif dx < -BOUND_RADIUS then
set dx = -BOUND_RADIUS
endif
if dy > BOUND_RADIUS then
set dy = BOUND_RADIUS
elseif dy < -BOUND_RADIUS then
set dy = -BOUND_RADIUS
endif
call BluePortal[TempInt].move(-dx, -dy, BluePortal[TempInt].level)
endif
call BluePortal[TempInt].refresh()
if RedPortalRevealed then
set x2 = RedPortalX-DungeonCenterX
set y2 = RedPortalY-DungeonCenterY
set dx = (x-x2)*(TILE_WIDTH/640.)*ZoomLevel[TempInt]
set dy = (y-y2)*(TILE_HEIGHT/640.)*ZoomLevel[TempInt]
static if LEGEND_BOUND_RADIAL then
set r = SquareRoot(dx*dx+dy*dy)
if r > BOUND_RADIUS then
set r = BOUND_RADIUS
endif
set a = Atan2(y2-y, x2-x)
call RedPortal[TempInt].move(r*Cos(a), r*Sin(a), RedPortal[TempInt].level)
else
if dx > BOUND_RADIUS then
set dx = BOUND_RADIUS
elseif dx < -BOUND_RADIUS then
set dx = -BOUND_RADIUS
endif
if dy > BOUND_RADIUS then
set dy = BOUND_RADIUS
elseif dy < -BOUND_RADIUS then
set dy = -BOUND_RADIUS
endif
call RedPortal[TempInt].move(-dx, -dy, RedPortal[TempInt].level)
endif
call RedPortal[TempInt].show(true)
call RedPortal[TempInt].refresh()
else
call RedPortal[TempInt].show(false)
endif
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] and i != TempInt then
set x2 = GetUnitDungeonX(MainUnit[i])
set y2 = GetUnitDungeonY(MainUnit[i])
set dx = (x-x2)*(TILE_WIDTH/640.)*ZoomLevel[TempInt]
set dy = (y-y2)*(TILE_HEIGHT/640.)*ZoomLevel[TempInt]
static if LEGEND_BOUND_RADIAL then
set r = SquareRoot(dx*dx+dy*dy)
if r > BOUND_RADIUS then
set r = BOUND_RADIUS
endif
set a = Atan2(y2-y, x2-x)
call Allies[TempInt][i].move(r*Cos(a), r*Sin(a), Allies[TempInt][i].level)
else
if dx > BOUND_RADIUS then
set dx = BOUND_RADIUS
elseif dx < -BOUND_RADIUS then
set dx = -BOUND_RADIUS
endif
if dy > BOUND_RADIUS then
set dy = BOUND_RADIUS
elseif dy < -BOUND_RADIUS then
set dy = -BOUND_RADIUS
endif
call Allies[TempInt][i].move(-dx, -dy, Allies[TempInt][i].level)
endif
call Allies[TempInt][i].refresh()
else
call Allies[TempInt][i].show(false)
endif
set i = i + 1
endloop
call MinimapLegend[TempInt].refresh()
endif
endfunction
public function UpdateMinimap takes integer i returns nothing
local real x
local real y
if Frame[i].visible then
set x = MINIMAP_X-(TILE_WIDTH_T*(GetUnitDungeonX(MainUnit[i])/(DungeonWidth/2)/2))*ZoomLevel[i]
set y = MINIMAP_Y-(TILE_HEIGHT_T*(GetUnitDungeonY(MainUnit[i])/(DungeonHeight/2)/2))*ZoomLevel[i]
call TilePanel[i].move(x, y, 0.)
set TempInt = i
call ForForce(bj_FORCE_PLAYER[0], function EvalVisibility)
endif
endfunction
private function update takes nothing returns nothing
local player p
local timer t = GetExpiredTimer()
local integer i = GetTimerData(t)
if IsPlaying[i] then
call UpdateMinimap(i)
else
call TilePanel[i].show(false)
call Frame[i].show(false)
call ReleaseTimer(t)
endif
set t = null
endfunction
private function UpdateTextureSub2 takes nothing returns nothing
local integer k = 0
loop
exitwhen k == TILE_DIMENSION
if TileTexture[TempInt2][k] == 0 then
set Tile[TempInt][TempInt2][k].value.texture = 'BSAL'
else
set Tile[TempInt][TempInt2][k].value.texture = TileTexture[TempInt2][k]
endif
set k = k + 1
endloop
endfunction
private function UpdateTextureSub takes nothing returns nothing
local integer id
local integer j
set id = TempInt
set j = 0
loop
exitwhen j == TILE_DIMENSION
set TempInt2 = j
call ForForce(bj_FORCE_PLAYER[0], function UpdateTextureSub2)
set j = j + 1
endloop
endfunction
public function UpdateTexture takes integer id returns nothing
set TempInt = id
call ForForce(bj_FORCE_PLAYER[0], function UpdateTextureSub)
endfunction
private function HideAllSub2 takes nothing returns nothing
local integer k
set k = 0
loop
exitwhen k == TILE_DIMENSION
call Tile[TempInt][TempInt2][k].value.show(false)
set k = k + 1
endloop
endfunction
private function HideAllSub takes nothing returns nothing
local integer j
set j = 0
loop
exitwhen j == TILE_DIMENSION
set TempInt2 = j
call ForForce(bj_FORCE_PLAYER[0], function HideAllSub2)
set j = j + 1
endloop
endfunction
public function HideAll takes integer id returns nothing
set TempInt = id
call ForForce(bj_FORCE_PLAYER[0], function HideAllSub)
endfunction
public function Show takes integer id, boolean b returns nothing
call TilePanel[id].show(b)
call Frame[id].show(b)
call ButtonPanel[id].show(b)
call TilePanel[id].refresh()
call Frame[id].refresh()
call ButtonPanel[id].refresh()
endfunction
private function ClearTextureSub takes nothing returns nothing
local integer j
local integer k
set j = 0
loop
exitwhen j == TILE_DIMENSION
set k = 0
loop
exitwhen k == TILE_DIMENSION
set TileTexture[j][k] = 0
set k = k + 1
endloop
set j = j + 1
endloop
endfunction
public function ClearTexture takes nothing returns nothing
call ForForce(bj_FORCE_PLAYER[0], function ClearTextureSub)
endfunction
private function HidePartitionsSub3 takes nothing returns nothing
local integer k
set k = 0
loop
exitwhen k == TILE_DIMENSION
//call Tile[TempInt][TempInt2][k].value.setColor(0, 0, 0, 255)
call Tile[TempInt][TempInt2][k].value.setColor(255, 255, 255, 0)
call Tile[TempInt][TempInt2][k].value.show(false)
set k = k + 1
endloop
endfunction
private function HidePartitionsSub2 takes nothing returns nothing
local integer j
set j = 0
loop
exitwhen j == TILE_DIMENSION
set TempInt2 = j
call ForForce(bj_FORCE_PLAYER[0], function HidePartitionsSub3)
set j = j + 1
endloop
endfunction
private function HidePartitionsSub takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 3
set TempInt = i
call ForForce(bj_FORCE_PLAYER[0], function HidePartitionsSub2)
set i = i + 1
endloop
endfunction
public function HidePartitions takes nothing returns nothing
call ForForce(bj_FORCE_PLAYER[0], function HidePartitionsSub)
endfunction
private function CreateTile takes nothing returns nothing
set Tile[TempInt][TempInt2][TempInt3] = PanelPlatform.create(TilePanel[TempInt], 'e012', 0, ((-TILE_WIDTH_T+TILE_WIDTH)/2)+TILE_WIDTH*TempInt2, ((-TILE_HEIGHT_T+TILE_HEIGHT)/2)+TILE_HEIGHT*TempInt3, -1)
set Tile[TempInt][TempInt2][TempInt3].value.scale = TILE_SCALE
call Tile[TempInt][TempInt2][TempInt3].value.show(false)
endfunction
private function CreateSub takes nothing returns nothing
local integer id
local integer i = 0
local integer j
local integer k
set id = TempInt
set ZoomLevel[id] = DEFAULT_ZOOM_LEVEL
set TilePanel[id] = Panel.create(Player(id), 0, 0, MINIMAP_X, MINIMAP_Y, 0.0)
set TilePanel[id].scale = DEFAULT_ZOOM_LEVEL
set Frame[id] = Panel.create(Player(id), 'e011', 'BSAL', MINIMAP_X, MINIMAP_Y, 0.0)
//set Frame[id] = Panel.create(Player(id), 'e011', 'B03M', MINIMAP_X, MINIMAP_Y, 0.0)
set Frame[id].scale = GENERAL_SIZE
set ButtonPanel[id] = Panel.create(Player(id), 'e011', 'BSAL', MINIMAP_X, MINIMAP_Y, 0.0)
set ButtonPanel[id].scale = GENERAL_SIZE
//set Background[id] = PanelPlatform.create(Frame[id], 'e011', 'BSAL', MINIMAP_X, MINIMAP_Y, 0)
set Background[id] = PanelPlatform.create(Frame[id], 'e011', 'B016', 0.0, 0.0, -3)
call Background[id].setColor(0, 0, 0, 32)
set PanelPlatform.create(Frame[id], 'e007', 0, 0.0, 0.0, 3).scale = 0.1 // white dot
set BluePortal[id] = PanelPlatform.create(Frame[id], 'e007', 'B03O', 0.0, 0.0, 1)
set BluePortal[id].scale = 0.5
set BluePortal[id].transformAxis = false
set RedPortal[id] = PanelPlatform.create(Frame[id], 'e007', 'B03N', 0.0, 0.0, 2)
set RedPortal[id].scale = 0.5
set RedPortal[id].transformAxis = false
set MaximizeButton[id] = PanelPlatform.create(ButtonPanel[id], 'e01A', 'B05C', 113, 111, 3)
set MaximizeButton[id].scale = 0.5
set j = 0
loop
exitwhen j == TILE_DIMENSION
set k = 0
loop
exitwhen k == TILE_DIMENSION
set TempInt2 = j
set TempInt3 = k
call ForForce(bj_FORCE_PLAYER[0], function CreateTile)
set k = k + 1
endloop
set j = j + 1
endloop
loop
exitwhen i > 3
if IsPlaying[i] and i != id then
set Allies[id][i] = PanelPlatform.create(Frame[id], 'e007', 0, 0.0, 0.0, 3)
set Allies[id][i].scale = 0.1
set Allies[id][i].transformAxis = false
call Allies[id][i].setColor(PLAYER_COLOR_R[i], PLAYER_COLOR_G[i], PLAYER_COLOR_B[i], 255)
endif
set i = i + 1
endloop
call TilePanel[id].show(false)
call Frame[id].show(false)
call ButtonPanel[id].show(false)
call MinimapLegend.create(id)
call TimerStart(NewTimerEx(id), 1., true, function update)
endfunction
public function Create takes integer id returns nothing
set TempInt = id
call ForForce(bj_FORCE_PLAYER[0], function CreateSub)
endfunction
private function onSelect takes nothing returns boolean
local unit u = GetTriggerUnit()
local player play = GetTriggerPlayer()
local integer pid = GetPlayerId(play)
if u == MaximizeButton[pid].dummy then
if MaximizeButton[pid].texture == 'B05C' then
set MaximizeButton[pid].texture = 'B05B'
call TilePanel[pid].show(false)
call Frame[pid].show(false)
else
call HideAll(pid)
set MaximizeButton[pid].texture = 'B05C'
call TilePanel[pid].show(true)
call Frame[pid].show(true)
call TilePanel[pid].refresh()
call Frame[pid].refresh()
call UpdateMinimap(pid)
endif
call MaximizeButton[pid].refresh()
if Locale == play then
call SelectUnit(u, false)
call SelectUnit(Controller[pid], true)
endif
endif
set u = null
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
//! runtextmacro INIT_MULTI_ARRAY_VARIABLE("Tile")
set DungeonMaxX = GetRectMaxX(gg_rct_Dungeon_Area)
set DungeonMinX = GetRectMinX(gg_rct_Dungeon_Area)
set DungeonMaxY = GetRectMaxY(gg_rct_Dungeon_Area)
set DungeonMinY = GetRectMinY(gg_rct_Dungeon_Area)
set DungeonCenterX = GetRectCenterX(gg_rct_Dungeon_Area)
set DungeonCenterY = GetRectCenterY(gg_rct_Dungeon_Area)
set DungeonWidth = DungeonMaxX - DungeonMinX
set DungeonHeight = DungeonMaxY - DungeonMinY
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SELECTED)
call TriggerAddCondition(t, Condition(function onSelect))
endfunction
endlibrary
library Tooltips uses CalculationLib
globals
string array DungeonSizeNames
string array CategoryNames
string array QualityNames
string array RarityNames
string array SkillClassNames
string array RarityColor
integer array RarityColorR
integer array RarityColorG
integer array RarityColorB
constant real FONT_SIZE = 0.017
Tooltips array Tooltips1
Tooltips array Tooltips2
endglobals
private struct TooltipsContents extends array
PanelPlatform content
implement Queue
endstruct
private struct TooltipsSockets extends array
PanelPlatform slot
PanelTextTag value
implement Queue
endstruct
struct Tooltips
ItemObject itmObject
PlayerSkill skill
readonly Panel control
readonly PanelPlatform header // 50 px
readonly PanelPlatform footer // 8 px
readonly TooltipsContents contents // 28 px
readonly PanelPlatform icon
readonly PanelTextTag title
readonly PanelTextTag subtitle
readonly PanelPlatform goldIcon
readonly PanelTextEx goldValue
readonly PanelTextEx quality
readonly PanelTextTag bonus
readonly PanelTextTag setTitle
readonly PanelTextTag setContent
readonly PanelTextTag socketTitle
readonly TooltipsSockets sockets
readonly PanelTextTag enchantment
readonly PanelTextTag requirement
readonly PanelTextTag comment
private player play
readonly integer owner
readonly integer height
readonly integer bonusCount
readonly integer socketCount
readonly integer enchantCount
boolean playSound
static string array Params
method show takes boolean b returns nothing
if IsKeyVerified[owner] or not b then
/*if b and .playSound then
if Locale == play then
call TooltipsDisplaySound.play(0, 0, 0, 100)
else
call TooltipsDisplaySound.play(0, 0, 0, 0)
endif
endif*/
call control.show(b)
call control.refresh()
endif
endmethod
method reset takes nothing returns nothing
local TooltipsContents node = contents.first
set height = 0
loop
exitwhen node == 0
call node.content.destroy()
set node = node.next
endloop
call contents.clear()
endmethod
method incHeight takes nothing returns nothing
local TooltipsContents node = contents.enqueue()
set node.content = PanelPlatform.create(control, 'e00P', 'B01B', 0, 0, 0)
set height = height + 1
endmethod
method refresh takes nothing returns nothing
local real y
local real y2
local TooltipsContents node
local TooltipsSockets socket
local TooltipsSockets prev
set y = (50.+8.+28.*height)/2. // top of tooltips
call header.move(0, y-25, 0)
call header.refresh()
call title.move(-132, header.yOffset-5.5)
call title.refresh()
call subtitle.move(-127, header.yOffset-17)
call subtitle.refresh()
call goldValue.move(129-goldValue.width, header.yOffset-10, 1)
call goldValue.refresh()
call goldIcon.move(129-goldValue.width-10, header.yOffset-12, 1)
call goldIcon.refresh()
call quality.move(129-quality.width, header.yOffset+7, 1)
call quality.refresh()
set y = y - 50. // top of content area
// Refresh content backgrounds and footer
set node = contents.first
set y2 = y
loop
exitwhen node == 0
call node.content.move(0, y2-14., 0)
call node.content.refresh()
set y2 = y2 - 28.
set node = node.next
endloop
call footer.move(0, y2-4., 0)
call footer.refresh()
call icon.move(110, y-8.-22.5, 1)
call icon.refresh()
set y = y-15. // top indenting 10px
if bonusCount > 0 then
call bonus.move(-127, y-(13.*bonusCount)+3.)
call bonus.refresh()
set y = y-(13.*bonusCount)-11. // bottom of bonus info
endif
if ItemSet.ItemIndex[itmObject.id] != 0 then
call setTitle.move(-127, y-10.0)
call setTitle.refresh()
call setContent.move(-122, y-13.-13.*(ItemSet.ItemIndex[itmObject.id].tCount-1)+3.)
call setContent.refresh()
set y = y-13.-13.*(ItemSet.ItemIndex[itmObject.id].tCount-1)-11. // bottom of set info
endif
if itmObject.socketCountMax > 0 then
call socketTitle.move(-127, y-10.)
call socketTitle.refresh()
set socket = sockets.first
set prev = 0
loop
exitwhen socket == 0
if prev == 0 then
call socket.slot.move(-117, y-13.-18.+10., 1)
else
call socket.slot.move(-117, prev.slot.yOffset-18., 1)
endif
call socket.value.move(-105, socket.slot.yOffset-8.)
call socket.value.refresh()
call socket.slot.refresh()
set prev = socket
set socket = socket.next
endloop
set y = y-13.-18.*itmObject.socketCountMax-11. // bottom of socket info
endif
if itmObject.id.reqCount > 0 or itmObject.id.commentLn > 0 then
if itmObject.id.commentLn > 0 then
if itmObject.id.reqCount > 0 then
call requirement.move(-127, y-13.-13.-13.*(itmObject.id.reqCount+itmObject.id.commentLn))
else
call requirement.move(-127, y-13.*itmObject.id.commentLn)
endif
else
call requirement.move(-127, y-13.-13.*itmObject.id.reqCount)
endif
call requirement.refresh()
endif
endmethod
private method getParams takes PlayerSkill skill returns nothing
local SkillData data = skill.id
if data == 1 then
set Params[0] = I2S(R2I(DeathBlowDamageAmount(.owner)))
set Params[1] = I2S(R2I(DeathBlowStunDuration(.owner)))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(DeathBlowDamageAmount(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 2 then
set Params[0] = R2SW(RapidAttackSpeedBonus(.owner), 1, 2)
set Params[1] = I2S(R2I(RapidAttackSpeedDuration(.owner)))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + R2SW(RapidAttackSpeedBonus(.owner), 1, 2) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 3 then
set Params[0] = I2S(R2I(TauntThreatAmount(.owner)))
if skill.level < 5 then
set Params[1] = ""
else
set Params[1] = " Conveys 5 seconds fear adding " + I2S(R2I(TauntMissChance(.owner)*100.+0.5)) + "% miss chance to taunted units."
endif
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(TauntThreatAmount(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 4 then
set Params[0] = I2S(R2I(SolidifyPhysicArmor(.owner)))
set Params[1] = I2S(R2I(SolidifyBlockBonus(.owner)*100.+0.5))
if skill.level < 5 then
set Params[2] = ""
else
set Params[2] = " Reflects missiles at " + I2S(R2I(SolidifyReflectChance(.owner)*100.+0.5)) + "% chance dealing " + I2S(R2I(SolidifyReflectDamage(.owner)*100.+0.5)) + "% damage."
endif
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(SolidifyPhysicArmor(.owner))) + "|cffcccccc)"
set Params[1] = Params[1] + " (|cff00ff00" + I2S(R2I(SolidifyBlockBonus(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 5 then
set Params[0] = I2S(R2I(ForceBarrierAmount(.owner)))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(ForceBarrierAmount(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 6 then
set Params[0] = I2S(R2I(MenacingPressenceThreatAmount(.owner)))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(MenacingPressenceThreatAmount(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 7 then
set Params[0] = I2S(FortificationBonusAmount(.owner))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(FortificationBonusAmount(.owner)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 8 then
set Params[0] = I2S(R2I(ExcellentRecoveryRegeneration(.owner)))
set Params[1] = I2S(R2I(ExcellentRecoveryAmplification(.owner)*100.+0.5))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(ExcellentRecoveryRegeneration(.owner))) + "|cffcccccc)"
set Params[1] = Params[1] + " (|cff00ff00" + I2S(R2I(ExcellentRecoveryAmplification(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 9 then
set Params[0] = I2S(R2I(DoubleCrashDamagePercent(.owner)*100.+0.5))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(DoubleCrashDamagePercent(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 10 then
set Params[0] = I2S(R2I(CounterAttackTriggerChance(.owner)*100.+0.5))
set Params[1] = I2S(R2I(CounterAttackDamage(.owner)*100.+0.5))
set Params[2] = I2S(R2I(CounterAttackDuration(.owner)))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(CounterAttackTriggerChance(.owner)*100.+0.5)) + "|cffcccccc)"
set Params[2] = Params[2] + " (|cff00ff00" + I2S(R2I(CounterAttackDuration(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 11 then
set Params[0] = I2S(R2I(ValiantChargeDamage(.owner)))
set Params[1] = R2SW(ValiantChargeKnockback(.owner)/UNITS_PER_METER, 1, 1)
if skill.level < 5 then
set Params[2] = ""
elseif skill.level < 15 then
set Params[2] = " and stuns for 1 second"
else
set Params[2] = " and stuns for 2 second"
endif
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(ValiantChargeDamage(.owner))) + "|cffcccccc)"
set Params[1] = Params[1] + " (|cff00ff00" + R2SW(ValiantChargeKnockback(.owner)/UNITS_PER_METER, 1, 1) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 12 then
set Params[0] = I2S(R2I(HolyShieldPhysicArmor(.owner)))
if skill.level < 5 then
set Params[1] = ""
elseif skill.level < 10 then
set Params[1] = " and magic defense by " + I2S(R2I(HolyShieldMagicArmor(.owner)))
elseif skill.level < 15 then
set Params[1] = ", magic defense by " + I2S(R2I(HolyShieldMagicArmor(.owner))) + ", and elemental resistance by " + I2S(R2I(HolyShieldResistance(.owner)))
else
set Params[1] = ", magic defense by " + I2S(R2I(HolyShieldMagicArmor(.owner))) + ", elemental resistance by " + I2S(R2I(HolyShieldResistance(.owner))) + ", and attack power by " + I2S(R2I(HolyShieldDamageBonus(.owner)*100.+0.5)) + "%"
endif
set Params[2] = I2S(R2I(HolyShieldDuration(.owner)))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(HolyShieldPhysicArmor(.owner))) + "|cffcccccc)"
set Params[2] = Params[2] + " (|cff00ff00" + I2S(R2I(HolyShieldDuration(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 13 then
set Params[0] = I2S(R2I(AeroJabDamageAmount(.owner)*100.+0.5))
set Params[1] = R2SW(AeroJabDistance(.owner)/UNITS_PER_METER, 2, 1)
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(AeroJabDamageAmount(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 14 then
set Params[0] = I2S(R2I(ProtectionVigorPercentage(.owner)*100.+0.5))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(ProtectionVigorPercentage(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 15 then
set Params[0] = I2S(UnholyStrengthBonusAmount(.owner))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(UnholyStrengthBonusAmount(.owner)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 16 then
set Params[0] = I2S(DivineResistanceBonus(.owner))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(DivineResistanceBonus(.owner)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 17 then
set Params[0] = I2S(R2I(DarknessClawPercentage(.owner)*100.+0.5))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(DarknessClawPercentage(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 18 then
set Params[0] = I2S(R2I(VampiricGroanHealthSteal(.owner)))
if skill.level < 5 then
set Params[1] = ""
else
set Params[1] = " and mana by " + I2S(R2I(VampiricGroanManaSteal(.owner))) + " points per second"
endif
set Params[2] = I2S(VampiricGroanMaxTarget(.owner))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(VampiricGroanHealthSteal(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 19 then
set Params[0] = I2S(R2I(DreadfulHowlAccuracyReduction(.owner)*100.+0.5))
set Params[1] = I2S(R2I(DreadfulHowlPhysicArmorReduction(.owner)))
set Params[2] = I2S(R2I(DreadfulHowlMagicArmorReduction(.owner)))
set Params[3] = I2S(R2I(DreadfulHowlDuration(.owner)))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(DreadfulHowlAccuracyReduction(.owner)*100.+0.5)) + "|cffcccccc)"
set Params[1] = Params[1] + " (|cff00ff00" + I2S(R2I(DreadfulHowlPhysicArmorReduction(.owner))) + "|cffcccccc)"
set Params[2] = Params[2] + " (|cff00ff00" + I2S(R2I(DreadfulHowlMagicArmorReduction(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 20 then
set Params[0] = I2S(R2I(SpectraVortexPercentage(.owner)*100.+0.5))
set Params[1] = I2S(R2I(SpectraVortexDuration(.owner)))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(SpectraVortexPercentage(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 21 then
set Params[0] = I2S(NightmareFallPillarCount(.owner))
set Params[1] = I2S(R2I(NightmareFallDamage(.owner)))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[1] = Params[1] + " (|cff00ff00" + I2S(R2I(NightmareFallDamage(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 22 then
set Params[0] = I2S(R2I(CorruptedBladePhysicArmorReduction(.owner)))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(CorruptedBladePhysicArmorReduction(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 23 then
set Params[0] = I2S(R2I(DarkArtsWisdomAmount(.owner)))
set Params[1] = I2S(R2I(DarkArtsPercentage(.owner)*100.+0.5))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(DarkArtsWisdomAmount(.owner))) + "|cffcccccc)"
set Params[1] = Params[1] + " (|cff00ff00" + I2S(R2I(DarkArtsPercentage(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 24 then
set Params[0] = I2S(R2I(SoulboundPercentage(.owner)*100.+0.5))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(SoulboundPercentage(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 25 then
set Params[0] = I2S(BouncingGlaiveBounceCount(.owner))
set Params[1] = I2S(R2I(BouncingGlaiveDamage(.owner)))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[1] = Params[1] + " (|cff00ff00" + I2S(R2I(BouncingGlaiveDamage(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 26 then
if skill.level < 5 then
set Params[0] = ""
else
set Params[0] = " while increasing movespeed by " + I2S(R2I(ShadowMeldSpeedBonus(.owner)*100.+0.5)) + "%"
endif
set Params[1] = I2S(R2I(ShadowMeldDamage(.owner)))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[1] = Params[1] + " (|cff00ff00" + I2S(R2I(ShadowMeldDamage(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 27 then
set Params[0] = R2SW(TranquilizerDuration(.owner), 2, 1)
if skill.level < 5 then
set Params[1] = ""
elseif skill.level < 10 then
set Params[1] = "twice "
elseif skill.level < 15 then
set Params[1] = "thrice "
else
set Params[1] = "4 times "
endif
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(TranquilizerDuration(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 28 then
set Params[0] = I2S(R2I(SnareTrapMovespeedReduction(.owner)*100.+0.5))
if skill.level < 5 then
set Params[1] = ""
elseif skill.level < 15 then
set Params[1] = " and reduces accuracy by " + I2S(R2I(SnareTrapAccuracyReduction(.owner)*100.+0.5))
else
set Params[1] = ", reduces accuracy by " + I2S(R2I(SnareTrapAccuracyReduction(.owner)*100.+0.5)) + ", and disables ranged units"
endif
set Params[2] = R2SW(SnareTrapNetDuration(.owner), 1, 1)
set Params[3] = I2S(R2I(SnareTrapTrapDuration(.owner)))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(SnareTrapMovespeedReduction(.owner)*100.+0.5)) + "|cffcccccc)"
set Params[2] = Params[2] + " (|cff00ff00" + I2S(R2I(SnareTrapNetDuration(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 29 then
set Params[0] = I2S(R2I(FericiousHailDamage(.owner)))
if skill.level < 5 then
set Params[1] = ""
elseif skill.level < 15 then
set Params[1] = " and slows movement by " + I2S(R2I(FericiousHailSlow(.owner)*100.+0.5)) + "%"
else
set Params[1] = ", slows movement by " + I2S(R2I(FericiousHailSlow(.owner)*100.+0.5)) + "%, and reduces physic armor by " + I2S(R2I(FericiousHailPhysicArmor(.owner)))
endif
set Params[2] = I2S(R2I(FericiousHailRadius(.owner)/UNITS_PER_METER))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(FericiousHailDamage(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 30 then
set Params[0] = R2SW(SilentStepAggroRange(.owner)/UNITS_PER_METER, 1, 1)
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + R2SW(SilentStepAggroRange(.owner)/UNITS_PER_METER, 3, 1) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 31 then
set Params[0] = I2S(AlacrityBonusAmount(.owner))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(AlacrityBonusAmount(.owner)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 32 then
set Params[0] = I2S(R2I(PoisonCoatingChance(.owner)*100.+0.5))
set Params[1] = I2S(R2I(PoisonCoatingDamage(.owner)))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(PoisonCoatingChance(.owner))) + "|cffcccccc)"
set Params[1] = Params[1] + " (|cff00ff00" + I2S(R2I(PoisonCoatingDamage(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 33 then
if skill.level < 15 then
set Params[0] = "twice"
else
set Params[0] = "thrice"
endif
set Params[1] = I2S(R2I(QuickShotDamagePercent(.owner)*100.+0.5))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[1] = Params[1] + " (|cff00ff00" + I2S(R2I(QuickShotDamagePercent(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 34 then
set Params[0] = R2SW(FastReloadSpeedBonus(.owner), 1, 2)
set Params[1] = I2S(R2I(FastReloadDuration(.owner)))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + R2SW(FastReloadSpeedBonus(.owner), 1, 2) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 35 then
set Params[0] = I2S(R2I(SummonWolfMinDamage(.owner)))
set Params[1] = I2S(R2I(SummonWolfMaxDamage(.owner)))
set Params[2] = I2S(R2I(SummonWolfHealth(.owner)))
if skill.level < 5 then
set Params[3] = ""
else
set Params[3] = " Has " + I2S(R2I(SummonWolfCriticalChance(.owner)*100.+0.5)) + "% chance to deal 150% damage on attacks."
endif
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[2] = Params[2] + " (|cff00ff00" + I2S(R2I(SummonWolfHealth(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 36 then
set Params[0] = I2S(R2I(AcuteSightAccuracy(.owner)*100.+0.5))
if skill.level < 5 then
set Params[1] = ""
elseif skill.level < 10 then
set Params[1] = " and critical chance by " + I2S(R2I(AcuteSightCriticalChance(.owner)*100.+0.5)) + "%"
elseif skill.level < 15 then
set Params[1] = ", critical chance by " + I2S(R2I(AcuteSightCriticalChance(.owner)*100.+0.5)) + "%, and interruption chance by " + I2S(R2I(AcuteSightInterruption(.owner)*100.+0.5)) + "%"
else
set Params[1] = ", critical chance by " + I2S(R2I(AcuteSightCriticalChance(.owner)*100.+0.5)) + "%, interruption chance by " + I2S(R2I(AcuteSightInterruption(.owner)*100.+0.5)) + "%, and physic damage by " + I2S(R2I(AcuteSightDamageBonus(.owner)*100.+0.5)) + "%"
endif
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(AcuteSightAccuracy(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 37 then
set Params[0] = I2S(R2I(PrimalStrikeDamageAmount(.owner)*100.+0.5))
if skill.level < 5 then
set Params[1] = ""
else
set Params[1] = " and knocking it " + R2SW(PrimalStrikeKnockback(.owner)/UNITS_PER_METER, 1, 1) + " meter away"
endif
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(PrimalStrikeDamageAmount(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 38 then
set Params[0] = I2S(R2I(ExtendedRangeBonus(.owner)/UNITS_PER_METER))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(ExtendedRangeBonus(.owner)/UNITS_PER_METER)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 39 then
set Params[0] = I2S(R2I(CatlikeReflexEvasion(.owner)*100.+0.5))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(CatlikeReflexEvasion(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 40 then
set Params[0] = R2SW(CompactBoltDamage(.owner), 1, 2)
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(CompactBoltDamage(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 41 then
set Params[0] = I2S(TripleShardCount(.owner))
set Params[1] = I2S(R2I(TripleShardDamage(.owner)))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[1] = Params[1] + " (|cff00ff00" + I2S(R2I(TripleShardDamage(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 42 then
set Params[0] = I2S(IllusoryIncarnationCount(.owner))
set Params[1] = "s"
set Params[2] = "Each"
set Params[3] = I2S(R2I(IllusoryIncarnationDamageDealt(.owner)*100.+0.5))
set Params[4] = I2S(R2I(IllusoryIncarnationDamageTaken(.owner)*100.+0.5))
set Params[5] = I2S(R2I(IllusoryIncarnationDuration(.owner)))
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[3] = Params[3] + " (|cff00ff00" + I2S(R2I(IllusoryIncarnationDamageDealt(.owner)*100.+0.5)) + "|cffcccccc)"
set Params[4] = Params[4] + " (|cff00ff00" + I2S(R2I(IllusoryIncarnationDamageTaken(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 43 then
set Params[0] = I2S(R2I(LucidBeamDamageAmount(.owner)))
if skill.level < 15 then
set Params[1] = ""
else
set Params[1] = " and silences affected units"
endif
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(LucidBeamDamageAmount(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 44 then
if skill.level < 5 then
set Params[0] = ""
elseif skill.level < 15 then
set Params[0] = "Has " + I2S(R2I(ForceWallReflectChance(.owner)*100.+0.5)) + "% chance to reflect enemies' missile at 50% damage."
else
set Params[0] = "Has " + I2S(R2I(ForceWallReflectChance(.owner)*100.+0.5)) + "% chance to reflect enemies' missile at 50% damage. Deals " + I2S(R2I(ForceWallDamage(.owner))) + " damage per second to enemies touching the barrier."
endif
set Params[1] = I2S(R2I(ForceWallRadius(.owner)/UNITS_PER_METER))
set Params[2] = R2SW(ForceWallDuration(.owner), 1, 2)
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[2] = Params[2] + " (|cff00ff00" + R2SW(ForceWallDuration(.owner), 1, 2) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 45 then
set Params[0] = I2S(R2I(LunarStrikeDamage(.owner)))
if skill.level < 5 then
set Params[1] = ""
else
set Params[1] = " Has " + I2S(R2I(LunarStrikeIllusionChance(.owner)*100.+0.5)) + "% chance to create an illusion of struck enemies. The illusion has 50% damage and takes 200% damage. Lasts for 15 seconds."
endif
if skill.level > 0 and skill.level < MAXIMUM_ACTIVE_SKILL_LEVEL then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(LunarStrikeDamage(.owner))) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 46 then
set Params[0] = I2S(R2I(AfterimageChance(.owner)*100.+0.5))
set Params[1] = I2S(R2I(AfterimageDamage(.owner)*100.+0.5))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + I2S(R2I(AfterimageChance(.owner)*100.+0.5)) + "|cffcccccc)"
set Params[1] = Params[1] + " (|cff00ff00" + I2S(R2I(AfterimageDamage(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 47 then
set Params[0] = R2SW(ElunesGraceRegeneration(.owner), 1, 1)
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + R2SW(ElunesGraceRegeneration(.owner), 1, 1) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
elseif data == 48 then
set Params[0] = R2SW(EmbodimentLifespanBonus(.owner), 2, 1)
set Params[1] = I2S(R2I(EmbodimentDamageTakenBonus(.owner)*100.+0.5))
if skill.learnable and skill.level > 0 then
set CalculationLib_LevelOffset = 1
set Params[0] = Params[0] + " (|cff00ff00" + R2SW(EmbodimentLifespanBonus(.owner), 2, 1) + "|cffcccccc)"
set Params[1] = Params[1] + " (|cff00ff00" + I2S(R2I(EmbodimentDamageTakenBonus(.owner)*100.+0.5)) + "|cffcccccc)"
set CalculationLib_LevelOffset = 0
endif
endif
endmethod
method setSkill takes PlayerSkill skill returns nothing
local real y
local string s = "|cff0085bcType\nClass\nTarget\nReq. Level\nMastery"
local TooltipsSockets socket
local TooltipsContents node
local SkillData data
local integer i
local integer j
local integer k
local integer len
local integer param
local integer lines = 0
local integer lines2 = 0
local real width
local string rome
local string desc
local string sub
local string sub2
local string col1
local string col2
call reset()
call incHeight()
set .skill = skill
set data = skill.id
set itmObject = 0
set icon.texture = data.icon
call title.setText("|cffcccccc" + data.name + "|r", 0.020)
call title.refresh()
if data.lifecost[skill.level] > 0 then
set s = s + "\nHP Cost"
elseif data.manacost[skill.level] > 0 then
set s = s + "\nMP Cost"
endif
set desc = ""
set i = 0
set param = -1
set len = StringLength(data.description)
call getParams(skill)
loop
exitwhen i == len
set sub = SubString(data.description, i, i + 1)
if sub == "@" then
set param = param + 1
set desc = desc + Params[param]
else
set desc = desc + sub
endif
set i = i + 1
endloop
set i = 0
set len = StringLength(desc)
set width = 0
set lines = 1
loop
exitwhen i == len
set sub = SubString(desc, i, i + 1)
if sub == "|" then
set i = i + 8
else
set width = width + quality.getCharWidth(sub)*0.335
if width > 230 then
set lines = lines + 1
set width = 0
set j = i - 1
loop
exitwhen j < 0
set sub2 = SubString(desc, j, j + 1)
if sub2 == " " then
set desc = SubString(desc, 0, j) + "\n" + SubString(desc, j + 1, len)
set i = i + 1
set len = len + 1
exitwhen true
endif
set j = j - 1
endloop
endif
endif
set i = i + 1
endloop
set s = s + "\nCooldown\n\n[Description]|cffcccccc\n" + desc + "|r"
call bonus.setText(s, FONT_SIZE)
if data.active and data.category != 4 then
call setTitle.show(true)
set s = "|cff0085bc[Upgrades]|r\n"
set lines2 = 5
set rome = ""
set i = 0
loop
exitwhen i > 2
if skill.level >= 5 + 5 * i then
set col1 = "|cffd3ae00"
set col2 = "|cffcccccc"
else
set col1 = "|cff907700"
set col2 = "|cff747474"
endif
set lines2 = lines2 + 1
set rome = rome + "I"
set desc = data.mutation[i]
set j = 0
set len = StringLength(desc)
set width = 0
loop
exitwhen j == len
set sub = SubString(desc, j, j + 1)
if sub == "|" then
set j = j + 8
else
set width = width + quality.getCharWidth(sub)*0.335
if width > 230 then
set lines2 = lines2 + 1
set width = 0
set k = j - 1
loop
exitwhen k < 0
set sub2 = SubString(desc, k, k + 1)
if sub2 == " " then
set desc = SubString(desc, 0, k) + "\n " + SubString(desc, k + 1, len)
set j = j + 1
set len = len + 1
exitwhen true
endif
set k = k - 1
endloop
endif
endif
set j = j + 1
endloop
set s = s + col1 + "Tier - " + rome + " [Level " + I2S(5 + 5 * i) + "] :|r\n " + col2 + desc + "|r"
if i < 2 then
set s = s + "\n"
endif
set i = i + 1
endloop
call setTitle.setText(s, FONT_SIZE)
else
call setTitle.show(false)
endif
set s = "|cffcccccc: " + SkillClassNames[data.category]
set s = s + "\n: " + CharacterWindow_SubTabNames[owner][data.subclass]
set s = s + "\n: " + data.target
if data.active then
if Level[owner] >= data.levelReq then
set s = s + "\n: " + I2S(data.levelReq)
else
set s = s + "\n: |cffaa0000" + I2S(data.levelReq) + "|cffcccccc"
endif
else
if Level[owner] >= PassiveSkillLevelReq[data.tier-6][skill.level+1] then
set s = s + "\n: " + I2S(PassiveSkillLevelReq[data.tier-6][skill.level+1])
else
set s = s + "\n: |cffaa0000" + I2S(PassiveSkillLevelReq[data.tier-6][skill.level+1]) + "|cffcccccc"
endif
endif
set s = s + "\n: " + R2SW(skill.mastery, 3, 3) + " %"
if data.lifecost[skill.level] > 0 then
set s = s + "\n: " + I2S(R2I(data.lifecost[skill.level]))
elseif data.manacost[skill.level] > 0 then
set s = s + "\n: " + I2S(R2I(data.manacost[skill.level]))
endif
set s = s + "\n: " + I2S(R2I(data.cooldown[skill.level])) + " s"
call subtitle.setText(s, FONT_SIZE)
call subtitle.refresh()
call quality.show(true)
call quality.setText("Level " + I2S(skill.level), FONTSTYLE_FrizQTShaded)
call quality.refresh()
call goldIcon.show(false)
call goldValue.show(false)
call socketTitle.show(false)
call enchantment.show(false)
call setContent.show(false)
call requirement.show(false)
call comment.show(false)
set socket = sockets.first
loop
exitwhen socket == 0
call socket.slot.show(false)
call socket.value.show(false)
set socket = socket.next
endloop
call incHeight()
call incHeight()
call incHeight()
call incHeight()
set i = lines
loop
exitwhen i <= 1
call incHeight()
set i = i - 2
endloop
set i = lines2
loop
exitwhen i <= 1
call incHeight()
set i = i - 2
endloop
set y = (58.+28.*height)/2.
call header.move(0, y-25, 0)
call header.refresh()
call icon.move(110, header.yOffset-55., 1)
call icon.refresh()
call title.move(-132, header.yOffset-10.5)
call title.refresh()
call quality.move(129-quality.width, header.yOffset+7, 1)
call quality.refresh()
call bonus.move(-127, header.yOffset-50.-(13*(8+lines)))
call bonus.show(true)
call bonus.refresh()
call setTitle.move(-127, bonus.yOffset-(13*lines2))
call setTitle.refresh()
call subtitle.move(-60, header.yOffset-54.-13*6)
call subtitle.refresh()
set y = y - 50.
set node = contents.first
loop
exitwhen node == 0
call node.content.move(0, y-14., 0)
call node.content.refresh()
set y = y - 28.
set node = node.next
endloop
call footer.move(0, y-4, 0)
call footer.refresh()
endmethod
method setItem takes ItemObject obj returns nothing
local string bonusStr = ""
local string bonusStr2 = ""
local string s
local integer i
local integer bc
local boolean b
local boolean b2
local integer need = 0
local real cHeight
local TooltipsSockets socket
local ItemSocket iSocket
if obj <= 0 or obj.id <= 0 then
call show(false)
return
endif
call reset()
//call incHeight()
set itmObject = obj
set .skill = 0
set icon.texture = obj.id.texture
call subtitle.show(true)
call goldIcon.show(true)
call goldValue.show(true)
call quality.show(true)
if obj.id.category < Items.CONSUMABLE then
if obj.upgradeLevel > 0 then
call title.setText(RarityColor[obj.rarity] + obj.id.name + " +" + I2S(obj.upgradeLevel) + "|r", 0.020)
else
call title.setText(RarityColor[obj.rarity] + obj.id.name + "|r", 0.020)
endif
else
call title.setText("|cffcccccc" + obj.id.name + "|r", 0.020)
endif
set bonusCount = 0
if obj.id.category < Items.CONSUMABLE and obj.id.category != 5 and obj.id.category != 10 then
call subtitle.setText(RarityColor[obj.rarity] + RarityNames[obj.rarity] + " armor piece (" + CategoryNames[obj.id.category] + ")|r", FONT_SIZE)
elseif obj.id.category == 5 or obj.id.category == 10 then
call subtitle.setText(RarityColor[obj.rarity] + RarityNames[obj.rarity] + " weapon (" + obj.id.class + ")|r", FONT_SIZE)
elseif obj.id.category == Items.CONSUMABLE then
call subtitle.setText("|cffccccccConsumeable item|r", FONT_SIZE)
elseif obj.id.category == Items.MISC then
if obj.id.class == "Misc" then
call subtitle.setText("|cffccccccMiscellanous item|r", FONT_SIZE)
else
call subtitle.setText("|cffccccccMaterial item|r", FONT_SIZE)
endif
elseif obj.id.category == Items.GEM then
call subtitle.setText("|cffccccccSocketable item|r", FONT_SIZE)
elseif obj.id.category == Items.SCROLL then
call subtitle.setText("|cffccccccDungeon scroll|r", FONT_SIZE)
endif
if obj.charge > 0 then
call goldValue.setText(I2S(obj.gold*obj.charge), FONTSTYLE_FrizQTShaded)
else
call goldValue.setText(I2S(obj.gold), FONTSTYLE_FrizQTShaded)
endif
if obj.id.maxCharge < 1 and obj.id.category >= Items.CONSUMABLE then
call quality.show(false)
else
call quality.show(true)
if obj.id.category < Items.CONSUMABLE then
call quality.setText("Quality: " + QualityNames[obj.quality], FONTSTYLE_FrizQTShaded)
else
call quality.setText("Amount: " + I2S(obj.charge), FONTSTYLE_FrizQTShaded)
endif
endif
set cHeight = 10. /*space*/
if obj.id.category == Items.MISC then
call bonus.show(false)
else
// populate bonus
set b = false
set b2 = true
set bc = 0
if obj.physicDmgMin != 0 then
set bonusStr2 = bonusStr2 + "|cffdf9d00Physical damage:|cffcccccc " + I2S(R2I(obj.physicDmgMin)) + " - " + I2S(R2I(obj.physicDmgMax)) + "|r\n"
set bc = bc + 1
set b = true
endif
if obj.magicDmgMin != 0 then
set bonusStr2 = bonusStr2 + "|cffdf9d00Magic damage:|cffcccccc " + I2S(R2I(obj.magicDmgMin)) + " - " + I2S(R2I(obj.magicDmgMax)) + "|r\n"
set bc = bc + 1
set b = true
endif
if obj.id != 21 then
set bonusStr = bonusStr + "|cff0085bc"
endif
if obj.strength != 0 then
if obj.strength > 0 then
set bonusStr = bonusStr + "Strength +" + I2S(obj.strength) + "\n"
else
set bonusStr = bonusStr + "Strength " + I2S(obj.strength) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.dexterity != 0 then
if obj.dexterity > 0 then
set bonusStr = bonusStr + "Dexterity +" + I2S(obj.dexterity) + "\n"
else
set bonusStr = bonusStr + "Dexterity " + I2S(obj.dexterity) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.wisdom != 0 then
if obj.wisdom > 0 then
set bonusStr = bonusStr + "Wisdom +" + I2S(obj.wisdom) + "\n"
else
set bonusStr = bonusStr + "Wisdom " + I2S(obj.wisdom) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.fortitude != 0 then
if obj.fortitude > 0 then
set bonusStr = bonusStr + "Fortitude +" + I2S(obj.fortitude) + "\n"
else
set bonusStr = bonusStr + "Fortitude " + I2S(obj.fortitude) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.attackRange != 0 then
if obj.attackRange > 0 then
set bonusStr = bonusStr + "Attack range +" + R2SW(obj.attackRange/UNITS_PER_METER, 1, 1) + " m\n"
else
set bonusStr = bonusStr + "Attack range " + R2SW(obj.attackRange/UNITS_PER_METER, 1, 1) + " m\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.aspd != 0 then
if obj.aspd > 0 then
if R2I(obj.aspd) == obj.aspd then
set bonusStr = bonusStr + "Attack speed +" + I2S(R2I(obj.aspd)) + "\n"
else
set bonusStr = bonusStr + "Attack speed +" + R2SW(obj.aspd, 3, 2) + "\n"
endif
else
if R2I(obj.aspd) == obj.aspd then
set bonusStr = bonusStr + "Attack speed " + I2S(R2I(obj.aspd)) + "\n"
else
set bonusStr = bonusStr + "Attack speed " + R2SW(obj.aspd, 3, 2) + "\n"
endif
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.mspd != 0 then
if obj.mspd > 0 then
set bonusStr = bonusStr + "Move speed +" + I2S(R2I(obj.mspd)) + "\n"
else
set bonusStr = bonusStr + "Move speed " + I2S(R2I(obj.mspd)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.physicDmg != 0 then
if obj.physicDmg > 0 then
set bonusStr = bonusStr + "Physical damage +" + I2S(R2I(obj.physicDmg)) + "\n"
else
set bonusStr = bonusStr + "Physical damage " + I2S(R2I(obj.physicDmg)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.physicDefense != 0 then
if obj.physicDefense > 0 then
if R2I(obj.physicDefense) == obj.physicDefense then
set bonusStr = bonusStr + "Physical defense +" + I2S(R2I(obj.physicDefense)) + "\n"
else
set bonusStr = bonusStr + "Physical defense +" + R2SW(obj.physicDefense, 3, 2) + "\n"
endif
else
if R2I(obj.physicDefense) == obj.physicDefense then
set bonusStr = bonusStr + "Physical defense " + I2S(R2I(obj.physicDefense)) + "\n"
else
set bonusStr = bonusStr + "Physical defense " + R2SW(obj.physicDefense, 3, 2) + "\n"
endif
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.magicDmg != 0 then
if obj.magicDmg > 0 then
set bonusStr = bonusStr + "Magic damage +" + I2S(R2I(obj.magicDmg)) + "\n"
else
set bonusStr = bonusStr + "Magic damage " + I2S(R2I(obj.magicDmg)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.magicDefense != 0 then
if obj.magicDefense > 0 then
if R2I(obj.magicDefense) == obj.magicDefense then
set bonusStr = bonusStr + "Magic defense +" + I2S(R2I(obj.magicDefense)) + "\n"
else
set bonusStr = bonusStr + "Magic defense +" + R2SW(obj.magicDefense, 3, 2) + "\n"
endif
else
if R2I(obj.magicDefense) == obj.magicDefense then
set bonusStr = bonusStr + "Magic defense " + I2S(R2I(obj.magicDefense)) + "\n"
else
set bonusStr = bonusStr + "Magic defense " + R2SW(obj.magicDefense, 3, 2) + "\n"
endif
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.dmgReflect != 0 then
if obj.dmgReflect > 0 then
set bonusStr = bonusStr + "Reflected damage +" + I2S(R2I(obj.dmgReflect)) + "\n"
else
set bonusStr = bonusStr + "Reflected damage " + I2S(R2I(obj.dmgReflect)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.blockRate != 0 then
if obj.blockRate > 0 then
set bonusStr = bonusStr + "Block chance +" + I2S(R2I(obj.blockRate*100.)) + "%\n"
else
set bonusStr = bonusStr + "Block chance " + I2S(R2I(obj.blockRate*100.)) + "%\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.criticalRate != 0 then
if obj.criticalRate > 0 then
set bonusStr = bonusStr + "Critical chance +" + I2S(R2I(obj.criticalRate*100.)) + "%\n"
else
set bonusStr = bonusStr + "Critical chance " + I2S(R2I(obj.criticalRate*100.)) + "%\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.criticalPower != 0 then
if obj.criticalPower > 0 then
set bonusStr = bonusStr + "Critical power +" + I2S(R2I(obj.criticalPower*100.)) + "%\n"
else
set bonusStr = bonusStr + "Critical power " + I2S(R2I(obj.criticalPower*100.)) + "%\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.evasionRate != 0 then
if obj.evasionRate > 0 then
set bonusStr = bonusStr + "Evasion chance +" + I2S(R2I(obj.evasionRate*100.)) + "%\n"
else
set bonusStr = bonusStr + "Evasion chance " + I2S(R2I(obj.evasionRate*100.)) + "%\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.accuracy != 0 then
if obj.accuracy > 0 then
set bonusStr = bonusStr + "Accuracy +" + I2S(R2I(obj.accuracy*100.)) + "\n"
else
set bonusStr = bonusStr + "Accuracy " + I2S(R2I(obj.accuracy*100.)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.knockback != 0 then
if obj.knockback > 0 then
set bonusStr = bonusStr + "Knockback power +" + I2S(R2I(obj.knockback)) + "\n"
else
set bonusStr = bonusStr + "Knockback power " + I2S(R2I(obj.knockback)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.knockbackResist != 0 then
if obj.knockbackResist > 0 then
set bonusStr = bonusStr + "Knockback resistance +" + I2S(R2I(obj.knockbackResist)) + "\n"
else
set bonusStr = bonusStr + "Knockback resistance " + I2S(R2I(obj.knockbackResist)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.interrupt != 0 then
if obj.interrupt > 0 then
set bonusStr = bonusStr + "Interrupt chance +" + I2S(R2I(obj.interrupt*100.)) + "%\n"
else
set bonusStr = bonusStr + "Interrupt chance " + I2S(R2I(obj.interrupt*100.)) + "%\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.interruptResist != 0 then
if obj.interruptResist > 0 then
set bonusStr = bonusStr + "Interrupt resistance +" + I2S(R2I(obj.interruptResist*100.)) + "%\n"
else
set bonusStr = bonusStr + "Interrupt resistance " + I2S(R2I(obj.interruptResist*100.)) + "%\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.stun != 0 then
if obj.stun > 0 then
set bonusStr = bonusStr + "Stun chance +" + I2S(R2I(obj.stun*100.)) + "%\n"
else
set bonusStr = bonusStr + "Stun chance " + I2S(R2I(obj.stun*100.)) + "%\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.stunResist != 0 then
if obj.stunResist > 0 then
set bonusStr = bonusStr + "Stun resistance +" + I2S(R2I(obj.stunResist*100.)) + "%\n"
else
set bonusStr = bonusStr + "Stun resistance " + I2S(R2I(obj.stunResist*100.)) + "%\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.hp != 0 then
if obj.hp > 0 then
set bonusStr = bonusStr + "Health +" + I2S(R2I(obj.hp)) + "\n"
else
set bonusStr = bonusStr + "Health " + I2S(R2I(obj.hp)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.sp != 0 then
if obj.sp > 0 then
set bonusStr = bonusStr + "Mana +" + I2S(R2I(obj.sp)) + "\n"
else
set bonusStr = bonusStr + "Mana " + I2S(R2I(obj.sp)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.hpSteal != 0 then
if obj.hpSteal > 0 then
set bonusStr = bonusStr + "Health stolen +" + I2S(R2I(obj.hpSteal)) + "\n"
else
set bonusStr = bonusStr + "Health stolen " + I2S(R2I(obj.hpSteal)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.spSteal != 0 then
if obj.spSteal > 0 then
set bonusStr = bonusStr + "Mana stolen +" + I2S(R2I(obj.spSteal)) + "\n"
else
set bonusStr = bonusStr + "Mana stolen " + I2S(R2I(obj.spSteal)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.hpMax != 0 then
if obj.hpMax > 0 then
set bonusStr = bonusStr + "Maximum health +" + I2S(R2I(obj.hpMax)) + "\n"
else
set bonusStr = bonusStr + "Maximum health " + I2S(R2I(obj.hpMax)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.spMax != 0 then
if obj.spMax > 0 then
set bonusStr = bonusStr + "Maximum mana +" + I2S(R2I(obj.spMax)) + "\n"
else
set bonusStr = bonusStr + "Maximum mana " + I2S(R2I(obj.spMax)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.hpRegen != 0 then
if obj.hpRegen > 0 then
if R2I(obj.hpRegen) == obj.hpRegen then
set bonusStr = bonusStr + "Health regeneration +" + I2S(R2I(obj.hpRegen)) + "\n"
else
set bonusStr = bonusStr + "Health regeneration +" + R2SW(obj.hpRegen, 3, 2) + "\n"
endif
else
if R2I(obj.hpRegen) == obj.hpRegen then
set bonusStr = bonusStr + "Health regeneration " + I2S(R2I(obj.hpRegen)) + "\n"
else
set bonusStr = bonusStr + "Health regeneration " + R2SW(obj.hpRegen, 3, 2) + "\n"
endif
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.spRegen != 0 then
if obj.spRegen > 0 then
if R2I(obj.spRegen) == obj.spRegen then
set bonusStr = bonusStr + "Mana regeneration +" + I2S(R2I(obj.spRegen)) + "\n"
else
set bonusStr = bonusStr + "Mana regeneration +" + R2SW(obj.spRegen, 3, 2) + "\n"
endif
else
if R2I(obj.spRegen) == obj.spRegen then
set bonusStr = bonusStr + "Mana regeneration " + I2S(R2I(obj.spRegen)) + "\n"
else
set bonusStr = bonusStr + "Mana regeneration " + R2SW(obj.spRegen, 3, 2) + "\n"
endif
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.fireElement != 0 then
if obj.fireElement > 0 then
set bonusStr = bonusStr + "Fire element +" + I2S(R2I(obj.fireElement)) + "\n"
else
set bonusStr = bonusStr + "Fire element " + I2S(R2I(obj.fireElement)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.waterElement != 0 then
if obj.waterElement > 0 then
set bonusStr = bonusStr + "Water element +" + I2S(R2I(obj.waterElement)) + "\n"
else
set bonusStr = bonusStr + "Water element " + I2S(R2I(obj.waterElement)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.earthElement != 0 then
if obj.earthElement > 0 then
set bonusStr = bonusStr + "Earth element +" + I2S(R2I(obj.earthElement)) + "\n"
else
set bonusStr = bonusStr + "Earth element " + I2S(R2I(obj.waterElement)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.windElement != 0 then
if obj.windElement > 0 then
set bonusStr = bonusStr + "Wind element +" + I2S(R2I(obj.windElement)) + "\n"
else
set bonusStr = bonusStr + "Wind element " + I2S(R2I(obj.windElement)) + "\n"
endif
set bonusCount = bonusCount + 1
set b2 = false
endif
if obj.id.category == 14 then
set bonusStr = bonusStr + "|cffdf9d00Dungeon Size:|r " + DungeonSizeNames[obj.dungeonSize] + "\n\n"
set bonusStr = bonusStr + "|cff0085bcMonster Stats Modifier:|r\n"
set bonusCount = bonusCount + 3
endif
if obj.physicDmgPctg != 0 then
if obj.physicDmgPctg > 0 then
set bonusStr = bonusStr + " Physical damage +" + I2S(R2I(obj.physicDmgPctg*100)) + "%\n"
else
set bonusStr = bonusStr + " Physical damage " + I2S(R2I(obj.physicDmgPctg*100)) + "%\n"
endif
set bonusCount = bonusCount + 1
endif
if obj.physicDefPctg != 0 then
if obj.physicDefPctg > 0 then
set bonusStr = bonusStr + " Physical defense +" + I2S(R2I(obj.physicDefPctg*100)) + "%\n"
else
set bonusStr = bonusStr + " Physical defense " + I2S(R2I(obj.physicDefPctg*100)) + "%\n"
endif
set bonusCount = bonusCount + 1
endif
if obj.magicDmgPctg != 0 then
if obj.magicDmgPctg > 0 then
set bonusStr = bonusStr + " Magic damage +" + I2S(R2I(obj.magicDmgPctg*100)) + "%\n"
else
set bonusStr = bonusStr + " Magic damage " + I2S(R2I(obj.magicDmgPctg*100)) + "%\n"
endif
set bonusCount = bonusCount + 1
endif
if obj.magicDefPctg != 0 then
if obj.magicDefPctg > 0 then
set bonusStr = bonusStr + " Magic defense +" + I2S(R2I(obj.magicDefPctg*100)) + "%\n"
else
set bonusStr = bonusStr + " Magic defense " + I2S(R2I(obj.magicDefPctg*100)) + "%\n"
endif
set bonusCount = bonusCount + 1
endif
if obj.aspdPctg != 0 then
if obj.aspdPctg > 0 then
set bonusStr = bonusStr + " Attack speed +" + I2S(R2I(obj.aspdPctg*100)) + "%\n"
else
set bonusStr = bonusStr + " Attack speed " + I2S(R2I(obj.aspdPctg*100)) + "%\n"
endif
set bonusCount = bonusCount + 1
endif
if obj.mspdPctg != 0 then
if obj.mspdPctg > 0 then
set bonusStr = bonusStr + " Move speed +" + I2S(R2I(obj.mspdPctg*100)) + "%\n"
else
set bonusStr = bonusStr + " Move speed " + I2S(R2I(obj.mspdPctg*100)) + "%\n"
endif
set bonusCount = bonusCount + 1
endif
if obj.hpPctg != 0 then
if obj.hpPctg > 0 then
set bonusStr = bonusStr + " Health point +" + I2S(R2I(obj.hpPctg*100)) + "%\n"
else
set bonusStr = bonusStr + " Health point " + I2S(R2I(obj.hpPctg*100)) + "%\n"
endif
set bonusCount = bonusCount + 1
endif
if obj.id.category == 14 then
set bonusStr = bonusStr + "\n|cff0085bcPlayer Stats Modifier:|r\n"
set bonusCount = bonusCount + 2
endif
if obj.expRate != 0 then
if obj.expRate > 0 then
set bonusStr = bonusStr + " EXP rate +" + I2S(R2I(obj.expRate*100)) + "%\n"
else
set bonusStr = bonusStr + " EXP rate " + I2S(R2I(obj.expRate*100)) + "%\n"
endif
set bonusCount = bonusCount + 1
endif
if obj.goldRate != 0 then
if obj.goldRate > 0 then
set bonusStr = bonusStr + " Gold rate +" + I2S(R2I(obj.goldRate*100)) + "%\n"
else
set bonusStr = bonusStr + " Gold rate " + I2S(R2I(obj.goldRate*100)) + "%\n"
endif
set bonusCount = bonusCount + 1
endif
if obj.dropRate != 0 then
if obj.dropRate > 0 then
set bonusStr = bonusStr + " Drop rate +" + I2S(R2I(obj.dropRate*100)) + "%\n"
else
set bonusStr = bonusStr + " Drop rate " + I2S(R2I(obj.dropRate*100)) + "%\n"
endif
set bonusCount = bonusCount + 1
endif
if b then
if b2 then
set bonusCount = bc
set bonusStr = bonusStr2
else
set bonusCount = bonusCount + bc + 1
set bonusStr = bonusStr2 + "\n" + bonusStr
endif
endif
set cHeight = cHeight + 13.*bonusCount /*content*/
call bonus.setText(SubString(bonusStr, 0, StringLength(bonusStr)-1), FONT_SIZE)
call bonus.show(true)
call bonus.refresh()
endif
// Set info
if ItemSet.ItemIndex[obj.id] != 0 then
call setTitle.show(true)
call setContent.show(true)
call setTitle.setText("|cffda00eaCollection: " + ItemSet.ItemIndex[obj.id].name + "|r", FONT_SIZE)
set cHeight = cHeight + 11. /*space*/ + 13. /*title*/ + 13.*(ItemSet.ItemIndex[obj.id].tCount-1)/*set info*/
set bonusStr = "|cffda00ea"
set b = true
set i = 1
loop
exitwhen i == ItemSet.ItemIndex[obj.id].count
if b and i > ItemSet.ActiveIndex[0].integer[ItemSet.ItemIndex[obj.id]] - 1 then
set bonusStr = bonusStr + "|cff43004f"
set b = true
endif
set bonusStr = bonusStr + I2S(i +1) + " pieces: " + ItemSet.ItemIndex[obj.id].bonus[i].comment
set bonusStr = bonusStr + "\n"
set i = i + 1
endloop
call setContent.setText(SubString(bonusStr, 0, StringLength(bonusStr)-1) + "|r", FONT_SIZE)
call setContent.refresh()
call setTitle.refresh()
else
call setTitle.show(false)
call setContent.show(false)
endif
// Socket info
if obj.socketCountMax > 0 then
call socketTitle.show(true)
set cHeight = cHeight + 11. /*space*/ + 13. /*title*/ + 18.*obj.socketCountMax /*socket info*/
set i = 0
set socket = sockets.first
set iSocket = obj.socketData.first
loop
exitwhen socket == 0
set i = i + 1
if i <= obj.socketCountMax then
if iSocket.gem == 0 then
call socket.value.setText("|cff6c6c6b- Empty slot -|r", FONT_SIZE)
set socket.slot.texture = 'B016'
else
call socket.value.setText("|cffffd800" + iSocket.comment + "|r", FONT_SIZE)
set socket.slot.texture = iSocket.gem.id.texture
endif
call socket.slot.show(true)
call socket.value.show(true)
call socket.slot.refresh()
call socket.value.refresh()
else
call socket.slot.show(false)
call socket.value.show(false)
endif
set iSocket = iSocket.next
set socket = socket.next
endloop
else
call socketTitle.show(false)
set socket = sockets.first
loop
exitwhen socket == 0
call socket.slot.show(false)
call socket.value.show(false)
set socket = socket.next
endloop
endif
// Requirement info
if obj.id.reqCount > 0 then
call requirement.show(true)
set s = "|cffd5a603Requirements:|r"
if obj.id.job != 0 then
if GetUnitTypeId(MainUnit[owner]) != obj.id.job then
set s = s + "|cffaa0000"
else
set s = s + "|cffcccccc"
endif
set s = s + "\n Class: " + GetObjectName(obj.id.job)
endif
if obj.reqLevel != 0 then
if obj.id.category == Items.GEM then
set s = s + "\n |cffccccccItem level: " + I2S(obj.reqLevel)
elseif obj.id.category == Items.MISC and obj.id.class != "Misc" then
set s = s + "\n |cffccccccItem level: " + I2S(obj.reqLevel)
else
if Level[owner] < obj.reqLevel then
set s = s + "|cffaa0000"
else
set s = s + "|cffcccccc"
endif
set s = s + "\n Level: " + I2S(obj.reqLevel)
endif
endif
if obj.id.reqStrength != 0 then
if Strength[owner] < obj.id.reqStrength then
set s = s + "|cffaa0000"
else
set s = s + "|cffcccccc"
endif
set s = s + "\n Strength: " + I2S(obj.id.reqStrength)
endif
if obj.id.reqDexterity != 0 then
if Dexterity[owner] < obj.id.reqDexterity then
set s = s + "|cffaa0000"
else
set s = s + "|cffcccccc"
endif
set s = s + "\n Dexterity: " + I2S(obj.id.reqDexterity)
endif
if obj.id.reqWisdom != 0 then
if Wisdom[owner] < obj.id.reqWisdom then
set s = s + "|cffaa0000"
else
set s = s + "|cffcccccc"
endif
set s = s + "\n Wisdom: " + I2S(obj.id.reqWisdom)
endif
if obj.id.reqFortitude != 0 then
if Fortitude[owner] < obj.id.reqFortitude then
set s = s + "|cffaa0000"
else
set s = s + "|cffcccccc"
endif
set s = s + "\n Fortitude: " + I2S(obj.id.reqFortitude)
endif
call requirement.setText(s, FONT_SIZE)
set cHeight = cHeight + 13. /*space*/ + 13. /*title*/ + 13.*(obj.id.reqCount+1) /*req info*/
else
call requirement.setText("", FONT_SIZE)
call requirement.show(false)
endif
// item comment
if obj.id.commentLn > 0 then
call requirement.show(true)
set s = requirement.text
if obj.id.reqCount > 0 then
call requirement.setText(requirement.text + "\n\n|cff70eb72" + obj.id.comment + "|r", FONT_SIZE)
set cHeight = cHeight + 13. /*space*/ + 13.*(obj.id.commentLn+1) /*comment*/
else
call requirement.setText(requirement.text + "|cff70eb72" + obj.id.comment + "|r", FONT_SIZE)
set cHeight = cHeight + 13.*obj.id.commentLn /*comment*/
endif
endif
set cHeight = cHeight + 10. /*space*/
// Calculate tooptips content height
set need = R2I(cHeight/28.)
if need < 2 then
set need = 2
endif
set i = 0
loop
exitwhen i == need
call incHeight()
set i = i + 1
endloop
call refresh()
endmethod
static method create takes integer p returns thistype
local thistype this = allocate()
local TooltipsSockets node
local integer i = 4
local player play = Player(p)
set owner = p
set .play = play
set control = Panel.create(play, 0, 0, 0, 0, -10*PanelCamera_LEVEL_GAP)
set header = PanelPlatform.create(control, 'e00R', 'B01A', 0, 0, 0)
set footer = PanelPlatform.create(control, 'e00Q', 'B01C', 0, 0, 0)
set icon = PanelPlatform.create(control, 'e00S', 'B016', 0, 0, 1)
set icon.scale = 0.8
set contents = TooltipsContents.create()
set title = PanelTextTag.create(control, "Name", 0.020, 0, 0)
set subtitle = PanelTextTag.create(control, "SubName", FONT_SIZE, 0, 0)
set goldIcon = PanelPlatform.create(control, 'e007', 'B01D', 0, 0, 0)
set goldIcon.scale = 0.3
set goldValue = PanelTextEx.create(control, "", FONTSTYLE_FrizQTShaded, 0, 0, 1)
set goldValue.scale = 0.275
set quality = PanelTextEx.create(control, "", FONTSTYLE_FrizQTShaded, 0, 0, 1)
set quality.scale = 0.275
set bonus = PanelTextTag.create(control, "Bonus", FONT_SIZE, 0, 0)
set setTitle = PanelTextTag.create(control, "Collection bonus", FONT_SIZE, 0, 0)
set setContent = PanelTextTag.create(control, "-", FONT_SIZE, 0, 0)
set socketTitle = PanelTextTag.create(control, "|cffd5a603Sockets:|r", FONT_SIZE, 0, 0)
set sockets = TooltipsSockets.create()
loop
exitwhen i == 0
set node = sockets.enqueue()
set node.slot = PanelPlatform.create(control, 'e00L', 'B016', 0, 0, 1)
set node.slot.scale = 0.3
set node.value = PanelTextTag.create(control, "empty", FONT_SIZE, 0, 0)
set i = i - 1
endloop
set requirement = PanelTextTag.create(control, "Requires:", FONT_SIZE, 0, 0)
set height = 0
call show(false)
return this
endmethod
static method onInit takes nothing returns nothing
endmethod
endstruct
endlibrary
library ItemObjectTooltips initializer init
private function onDeselect takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer uid = GetUnitTypeId(u)
local integer pid
if uid == 'e02F' then
set pid = GetPlayerId(GetTriggerPlayer())
call Tooltips1[pid].show(false)
call Tooltips2[pid].show(false)
endif
set u = null
return false
endfunction
private function onSelect takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer uid = GetUnitTypeId(u)
local integer pid
local ItemObject obj
if uid == 'e02F' then
set pid = GetPlayerId(GetTriggerPlayer())
set obj = ItemObject[u]
if obj > 0 then
call Tooltips1[pid].show(true)
call Tooltips1[pid].setItem(obj)
if obj.id.category < Items.CONSUMABLE and CharacterWindow_SlotObject[pid][obj.id.category] != 0 then
call Tooltips2[pid].show(true)
call Tooltips1[pid].control.move(150, 0, Tooltips1[pid].control.zDepth)
call Tooltips2[pid].control.move(-150, 0, Tooltips2[pid].control.zDepth)
call Tooltips1[pid].control.refresh()
call Tooltips2[pid].control.refresh()
call Tooltips2[pid].setItem(CharacterWindow_SlotObject[pid][obj.id.category])
else
call Tooltips1[pid].control.move(0, 0, Tooltips1[pid].control.zDepth)
call Tooltips1[pid].control.refresh()
call Tooltips2[pid].show(false)
set Tooltips2[pid].itmObject = -1
endif
endif
endif
set u = null
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterPlayerSelectionEventBJ(t, Player(0), true)
call TriggerRegisterPlayerSelectionEventBJ(t, Player(1), true)
call TriggerRegisterPlayerSelectionEventBJ(t, Player(2), true)
call TriggerRegisterPlayerSelectionEventBJ(t, Player(3), true)
call TriggerAddCondition(t, Condition(function onSelect))
set t = CreateTrigger()
call TriggerRegisterPlayerSelectionEventBJ(t, Player(0), false)
call TriggerRegisterPlayerSelectionEventBJ(t, Player(1), false)
call TriggerRegisterPlayerSelectionEventBJ(t, Player(2), false)
call TriggerRegisterPlayerSelectionEventBJ(t, Player(3), false)
call TriggerAddCondition(t, Condition(function onDeselect))
endfunction
endlibrary
library Inventory uses UnitIndexer, CharacterManager, UpgradeMenu
///! runtextmacro DECLARE_ARRAY_2D("", "InventoryContent", "SlotIndex", "8", "21")
///! runtextmacro DECLARE_ARRAY_2D("", "PanelPlatform", "ContextButton", "8", "7")
///! runtextmacro DECLARE_ARRAY_2D("", "PanelPlatform", "SlotMoveHighlight", "8", "20")
globals
public Inventory array UnitBag
public Inventory array SlotBag
public Inventory array PorterBag
public Inventory array ExitBag
public Inventory array SortBag
public Inventory array ContextButtonBag
public Inventory array ContextButtonIndex
public Inventory array InventoryIndex
public InventoryContent array ButtonSlot
public InventoryContent array SlotIndex[4][21]
public PanelPlatform array ContextButton[4][7]
public PanelPlatform array SlotMoveHighlight[4][20]
public timer array PickItemTimer
public unit array PickItemTarget
public integer array PickItemOrder
unit LastSelection = null
endglobals
private function CreateNewSaveThread takes nothing returns nothing
call CharacterManager_SaveData(GetEnumPlayer())
endfunction
struct InventoryContent extends array
implement LinkedList
Inventory parent
PanelPlatform plat
PanelPlatform rarity
PanelPlatform cool
PanelTextEx text
integer index
ItemObject object
endstruct
struct Inventory
Panel panel
InventoryContent contents
PanelPlatform highlight
PanelPlatform context
PanelPlatform sort
PanelPlatform exit
PanelTextEx gold
unit main
player play
integer pid
integer page
integer index
timer time
timer dClick
boolean open // context opened
boolean moving // if item moving mode
boolean socketing // if item socketing mode
boolean visible // inventory opened
static boolean skipDetect = false
static constant real CONTEXT_X_CLOSE = -104.0
static constant real CONTEXT_X_OPEN = -201.0
static constant real ANIM_SPEED = 10
method getEmptySlot takes nothing returns integer
local integer i = 0
loop
exitwhen i == 20 or SlotIndex[this][i].object == 0
set i = i + 1
endloop
return i
endmethod
method getStackableSlot takes ItemObject object returns integer
local integer i = 0
loop
exitwhen i == 20/* or SlotIndex[this][i].object == 0*/ or (SlotIndex[this][i].object.id == object.id and SlotIndex[this][i].object.charge < object.id.maxCharge)
set i = i + 1
endloop
if i == 20 then
return getEmptySlot()
endif
return i
endmethod
method selectSlot takes integer dex, integer data returns nothing
local integer i = 0
set open = true
set index = dex
call context.show(true)
call highlight.show(true)
call context.move(ButtonSlot[data].plat.xOffset-85, ButtonSlot[data].plat.yOffset-83, context.level)
call highlight.move(ButtonSlot[data].plat.xOffset, ButtonSlot[data].plat.yOffset, 4)
call highlight.refresh()
call context.refresh()
set i = 0
loop
exitwhen i == 5
call ContextButton[this][i].show(true)
call ContextButton[this][i].move(context.xOffset, context.yOffset+85-28*i, context.level+1)
call ContextButton[this][i].refresh()
set i = i + 1
endloop
endmethod
method closeContextMenu takes nothing returns nothing
local integer i = 0
set open = false
set index = -1
call context.show(false)
call highlight.show(false)
set i = 0
loop
exitwhen i == 5
call ContextButton[this][i].show(false)
set i = i + 1
endloop
endmethod
method verifyRequirements takes integer index, boolean print returns boolean
local boolean b = true
if UpgradeMenu_Main[pid].visible then
return true
endif
if SlotIndex[this][index].object.id.reqCount > 0 then
if b and SlotIndex[this][index].object.id.job != 0 then
if GetUnitTypeId(MainUnit[pid]) != SlotIndex[this][index].object.id.job then
if print then
call DisplayTimedTextToPlayer(play, 0, 0, 1., "Requires class of " + GetObjectName(SlotIndex[this][index].object.id.job) + ".")
endif
set b = false
endif
endif
if b and SlotIndex[this][index].object.reqLevel != 0 then
if SlotIndex[this][index].object.id.category != Items.GEM and SlotIndex[this][index].object.id.category != Items.MISC and Level[pid] < SlotIndex[this][index].object.reqLevel then
if print then
call DisplayTimedTextToPlayer(play, 0, 0, 1., "Requires higher level (" + I2S(SlotIndex[this][index].object.reqLevel) + ").")
endif
set b = false
endif
endif
if b and SlotIndex[this][index].object.id.reqStrength != 0 then
if Strength[pid] < SlotIndex[this][index].object.id.reqStrength then
if print then
call DisplayTimedTextToPlayer(play, 0, 0, 1., "Requires higher strength (" + I2S(SlotIndex[this][index].object.id.reqStrength) + ").")
endif
set b = false
endif
endif
if b and SlotIndex[this][index].object.id.reqDexterity != 0 then
if Dexterity[pid] < SlotIndex[this][index].object.id.reqDexterity then
if print then
call DisplayTimedTextToPlayer(play, 0, 0, 1., "Requires higher dexterity (" + I2S(SlotIndex[this][index].object.id.reqDexterity) + ").")
endif
set b = false
endif
endif
if b and SlotIndex[this][index].object.id.reqWisdom != 0 then
if Wisdom[pid] < SlotIndex[this][index].object.id.reqWisdom then
if print then
call DisplayTimedTextToPlayer(play, 0, 0, 1., "Requires higher wisdom (" + I2S(SlotIndex[this][index].object.id.reqWisdom) + ").")
endif
set b = false
endif
endif
if b and SlotIndex[this][index].object.id.reqFortitude != 0 then
if Fortitude[pid] < SlotIndex[this][index].object.id.reqFortitude then
call DisplayTimedTextToPlayer(play, 0, 0, 1., "Requires higher fortitude (" + I2S(SlotIndex[this][index].object.id.reqFortitude) + ").")
set b = false
endif
endif
endif
return b
endmethod
public static method ApplyBonus takes Combatant c, ItemObject itm returns nothing
local ItemSet iDex
local integer bonusDex
local real heal
local integer vol
local integer tier
if itm.goldGiven > 0 then
if Locale == c.owner then
set vol = 150
else
set vol = 0
endif
call ItemBuySound.play(0, 0, 0, vol)
call SetPlayerState(c.owner, PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(c.owner, PLAYER_STATE_RESOURCE_GOLD)+itm.goldGiven)
endif
if itm.id.category == Items.RIGHT_HAND or itm.id.category == Items.LEFT_HAND and StringLength(itm.id.upgradeSfx) > 0 then
if itm.upgradeLevel < 3 then
set tier = 0
elseif itm.upgradeLevel < 6 then
set tier = 1
elseif itm.upgradeLevel < 9 then
set tier = 2
elseif itm.upgradeLevel < 11 then
set tier = 3
elseif itm.upgradeLevel < 12 then
set tier = 4
else
set tier = 5
endif
if itm.id.category == Items.LEFT_HAND then
if c.upgradeSfx != null then
call DestroyEffect(c.upgradeSfx)
endif
set c.upgradeSfx = AddSpecialEffectTarget("war3mapImported\\Upgrade_FX_" + itm.id.upgradeSfx + "_" + I2S(tier) + ".mdx", c.u, "weapon")
else
if c.upgradeSfx2 != null then
call DestroyEffect(c.upgradeSfx2)
endif
set c.upgradeSfx2 = AddSpecialEffectTarget("war3mapImported\\Upgrade_FX_" + itm.id.upgradeSfx + "_" + I2S(tier) + ".mdx", c.u, "hand,right")
endif
endif
call AddAttPoints(c.pid, 0, itm.strength)
call AddAttPoints(c.pid, 1, itm.dexterity)
call AddAttPoints(c.pid, 2, itm.wisdom)
call AddAttPoints(c.pid, 3, itm.fortitude)
call Regeneration.add(c.u, true, itm.hpRegen)
call Regeneration.add(c.u, false, itm.spRegen)
set c.physicDmgMin = c.physicDmgMin + itm.physicDmg
set c.physicDmgMax = c.physicDmgMax + itm.physicDmg
set c.physicDmgMin = c.physicDmgMin + itm.physicDmgMin
set c.physicDmgMax = c.physicDmgMax + itm.physicDmgMax
set c.physicDefense = c.physicDefense + itm.physicDefense
set c.magicDmgMin = c.magicDmgMin + itm.magicDmg
set c.magicDmgMax = c.magicDmgMax + itm.magicDmg
set c.magicDmgMin = c.magicDmgMin + itm.magicDmgMin
set c.magicDmgMax = c.magicDmgMax + itm.magicDmgMax
set c.magicDefense = c.magicDefense + itm.magicDefense
set c.attackRange = c.attackRange + itm.attackRange
set c.blockRate = c.blockRate + itm.blockRate
set c.criticalRate = c.criticalRate + itm.criticalRate
set c.criticalPower = c.criticalPower + itm.criticalPower
set c.evasionRate = c.evasionRate + itm.evasionRate
set c.knockback = c.knockback + itm.knockback
set c.knockbackResist = c.knockbackResist + itm.knockbackResist
set c.interrupt = c.interrupt + itm.interrupt
set c.interruptResist = c.interruptResist + itm.interruptResist
set c.stun = c.stun + itm.stun
set c.stunResist = c.stunResist + itm.stunResist
if BuffBars[c.pid].has(5) then
set heal = itm.hp * (1.+ExcellentRecoveryAmplification(c.pid))
else
set heal = itm.hp
endif
set c.hp = c.hp + heal
if heal > 0 then
call DamageText_Show(I2S(R2I(heal)), 0, c.u, HEAL_R, HEAL_G, HEAL_B, TEXTTAG_NORMAL_SIZE)
elseif heal < 0 then
call DamageText_Show(I2S(R2I(-heal)), 0, c.u, NORMAL_DAMAGE_R, NORMAL_DAMAGE_G, NORMAL_DAMAGE_B, TEXTTAG_NORMAL_SIZE)
endif
set c.sp = c.sp + itm.sp
if itm.sp > 0 then
call DamageText_Show(I2S(R2I(itm.sp)), 0, c.u, MANA_R, MANA_G, MANA_B, TEXTTAG_NORMAL_SIZE)
endif
set c.hpMax = c.hpMax + itm.hpMax
set c.spMax = c.spMax + itm.spMax
set c.attackRate = c.attackRate - itm.aspd
set c.fireElement = c.fireElement + itm.fireElement
set c.fireElementResist = c.fireElementResist + itm.fireElementResist
set c.waterElement = c.waterElement + itm.waterElement
set c.waterElementResist = c.waterElementResist + itm.waterElementResist
set c.earthElement = c.earthElement + itm.earthElement
set c.earthElementResist = c.earthElementResist + itm.earthElementResist
set c.windElement = c.windElement + itm.windElement
set c.windElementResist = c.windElementResist + itm.windElementResist
set c.holyElement = c.holyElement + itm.holyElement
set c.darkElement = c.darkElement + itm.darkElement
call SetUnitMoveSpeed(c.u, GetUnitMoveSpeed(c.u) + itm.mspd)
if ItemSet.ItemIndex[itm.id] != 0 then
set iDex = ItemSet.ItemIndex[itm.id]
set bonusDex = ItemSet.ActiveIndex[c.pid].integer[iDex]
if bonusDex < iDex.count then
call AddAttPoints(c.pid, 0, iDex.bonus[bonusDex].strength)
call AddAttPoints(c.pid, 1, iDex.bonus[bonusDex].dexterity)
call AddAttPoints(c.pid, 2, iDex.bonus[bonusDex].wisdom)
call AddAttPoints(c.pid, 3, iDex.bonus[bonusDex].fortitude)
call Regeneration.add(c.u, true, iDex.bonus[bonusDex].hpRegen)
call Regeneration.add(c.u, false, iDex.bonus[bonusDex].spRegen)
set c.physicDmgMin = c.physicDmgMin + iDex.bonus[bonusDex].physicDmg
set c.physicDmgMax = c.physicDmgMax + iDex.bonus[bonusDex].physicDmg
set c.physicDefense = c.physicDefense + iDex.bonus[bonusDex].physicDefense
set c.magicDmgMin = c.magicDmgMin + iDex.bonus[bonusDex].magicDmg
set c.magicDmgMax = c.magicDmgMax + iDex.bonus[bonusDex].magicDmg
set c.magicDefense = c.magicDefense + iDex.bonus[bonusDex].magicDefense
set c.attackRange = c.attackRange + iDex.bonus[bonusDex].attackRange
set c.blockRate = c.blockRate + iDex.bonus[bonusDex].blockRate
set c.criticalRate = c.criticalRate + iDex.bonus[bonusDex].criticalRate
set c.criticalPower = c.criticalPower + iDex.bonus[bonusDex].criticalPower
set c.evasionRate = c.evasionRate + iDex.bonus[bonusDex].evasionRate
set c.knockback = c.knockback + iDex.bonus[bonusDex].knockback
set c.knockbackResist = c.knockbackResist + iDex.bonus[bonusDex].knockbackResist
set c.interrupt = c.interrupt + iDex.bonus[bonusDex].interrupt
set c.interruptResist = c.interruptResist + iDex.bonus[bonusDex].interruptResist
set c.stun = c.stun + iDex.bonus[bonusDex].stun
set c.stunResist = c.stunResist + iDex.bonus[bonusDex].stunResist
set c.hp = c.hp + iDex.bonus[bonusDex].hp
set c.sp = c.sp + iDex.bonus[bonusDex].sp
set c.hpMax = c.hpMax + iDex.bonus[bonusDex].hpMax
set c.spMax = c.spMax + iDex.bonus[bonusDex].spMax
set c.attackRate = c.attackRate - iDex.bonus[bonusDex].aspd
set c.fireElement = c.fireElement + iDex.bonus[bonusDex].fireElement
set c.fireElementResist = c.fireElementResist + iDex.bonus[bonusDex].fireElementResist
set c.waterElement = c.waterElement + iDex.bonus[bonusDex].waterElement
set c.waterElementResist = c.waterElementResist + iDex.bonus[bonusDex].waterElementResist
set c.earthElement = c.earthElement + iDex.bonus[bonusDex].earthElement
set c.earthElementResist = c.earthElementResist + iDex.bonus[bonusDex].earthElementResist
set c.windElement = c.windElement + iDex.bonus[bonusDex].windElement
set c.windElementResist = c.windElementResist + iDex.bonus[bonusDex].windElementResist
set c.holyElement = c.holyElement + iDex.bonus[bonusDex].holyElement
set c.darkElement = c.darkElement + iDex.bonus[bonusDex].darkElement
call SetUnitMoveSpeed(c.u, GetUnitMoveSpeed(c.u) + iDex.bonus[bonusDex].mspd)
set ItemSet.ActiveIndex[c.pid].integer[iDex] = bonusDex+1
if ItemSet.ItemIndex[Tooltips1[c.pid].itmObject.id] == ItemSet.ItemIndex[itm.id] then
call Tooltips1[c.pid].setItem(Tooltips1[c.pid].itmObject)
endif
endif
endif
if c.hp > c.hpMax then
set c.hp = c.hpMax
endif
if c.sp > c.spMax then
set c.sp = c.spMax
endif
if Tooltips1[c.pid].control.visible then
if Tooltips1[c.pid].skill != 0 then
call Tooltips1[c.pid].setSkill(Tooltips1[c.pid].skill)
elseif Tooltips1[c.pid].itmObject != 0 then
call Tooltips1[c.pid].setItem(Tooltips1[c.pid].itmObject)
endif
endif
endmethod
public static method RemoveBonus takes Combatant c, ItemObject itm returns nothing
local ItemSet iDex
local ItemObject obj
local integer bonusDex
if itm.id.category == Items.RIGHT_HAND or itm.id.category == Items.LEFT_HAND and StringLength(itm.id.upgradeSfx) > 0 then
if itm.id.category == Items.LEFT_HAND then
if c.upgradeSfx != null then
call DestroyEffect(c.upgradeSfx)
set c.upgradeSfx = null
endif
else
if c.upgradeSfx2 != null then
call DestroyEffect(c.upgradeSfx2)
set c.upgradeSfx2 = null
endif
endif
endif
call AddAttPoints(c.pid, 0, -itm.strength)
call AddAttPoints(c.pid, 1, -itm.dexterity)
call AddAttPoints(c.pid, 2, -itm.wisdom)
call AddAttPoints(c.pid, 3, -itm.fortitude)
call Regeneration.add(c.u, true, -itm.hpRegen)
call Regeneration.add(c.u, false, -itm.spRegen)
set c.physicDmgMin = c.physicDmgMin - itm.physicDmg
set c.physicDmgMax = c.physicDmgMax - itm.physicDmg
set c.physicDmgMin = c.physicDmgMin - itm.physicDmgMin
set c.physicDmgMax = c.physicDmgMax - itm.physicDmgMax
set c.physicDefense = c.physicDefense - itm.physicDefense
set c.magicDmgMin = c.magicDmgMin - itm.magicDmg
set c.magicDmgMax = c.magicDmgMax - itm.magicDmg
set c.magicDmgMin = c.magicDmgMin - itm.magicDmgMin
set c.magicDmgMax = c.magicDmgMax - itm.magicDmgMax
set c.magicDefense = c.magicDefense - itm.magicDefense
set c.attackRange = c.attackRange - itm.attackRange
set c.blockRate = c.blockRate - itm.blockRate
set c.criticalRate = c.criticalRate - itm.criticalRate
set c.criticalPower = c.criticalPower - itm.criticalPower
set c.evasionRate = c.evasionRate - itm.evasionRate
set c.knockback = c.knockback - itm.knockback
set c.knockbackResist = c.knockbackResist - itm.knockbackResist
set c.interrupt = c.interrupt - itm.interrupt
set c.interruptResist = c.interruptResist - itm.interruptResist
set c.stun = c.stun - itm.stun
set c.stunResist = c.stunResist - itm.stunResist
set c.hp = c.hp - itm.hp
set c.sp = c.sp - itm.sp
set c.hpMax = c.hpMax - itm.hpMax
set c.spMax = c.spMax - itm.spMax
set c.attackRate = c.attackRate + itm.aspd
set c.fireElement = c.fireElement - itm.fireElement
set c.fireElementResist = c.fireElementResist - itm.fireElementResist
set c.waterElement = c.waterElement - itm.waterElement
set c.waterElementResist = c.waterElementResist - itm.waterElementResist
set c.earthElement = c.earthElement - itm.earthElement
set c.earthElementResist = c.earthElementResist - itm.earthElementResist
set c.windElement = c.windElement - itm.windElement
set c.windElementResist = c.windElementResist - itm.windElementResist
set c.holyElement = c.holyElement - itm.holyElement
set c.darkElement = c.darkElement - itm.darkElement
call SetUnitMoveSpeed(c.u, GetUnitMoveSpeed(c.u) - itm.mspd)
if ItemSet.ItemIndex[itm.id] != 0 then
set iDex = ItemSet.ItemIndex[itm.id]
set bonusDex = ItemSet.ActiveIndex[c.pid].integer[iDex]
if bonusDex > 0 then
//set obj = CharacterWindow_SlotObject[c.pid][itm.id.category]
//if iDex != ItemSet.ItemIndex[obj.id] then
set bonusDex = bonusDex-1
set ItemSet.ActiveIndex[c.pid].integer[iDex] = bonusDex
call AddAttPoints(c.pid, 0, -iDex.bonus[bonusDex].strength)
call AddAttPoints(c.pid, 1, -iDex.bonus[bonusDex].dexterity)
call AddAttPoints(c.pid, 2, -iDex.bonus[bonusDex].wisdom)
call AddAttPoints(c.pid, 3, -iDex.bonus[bonusDex].fortitude)
call Regeneration.add(c.u, true, -iDex.bonus[bonusDex].hpRegen)
call Regeneration.add(c.u, false, -iDex.bonus[bonusDex].spRegen)
set c.physicDmgMin = c.physicDmgMin - iDex.bonus[bonusDex].physicDmg
set c.physicDmgMax = c.physicDmgMax - iDex.bonus[bonusDex].physicDmg
set c.physicDefense = c.physicDefense - iDex.bonus[bonusDex].physicDefense
set c.magicDmgMin = c.magicDmgMin - iDex.bonus[bonusDex].magicDmg
set c.magicDmgMax = c.magicDmgMax - iDex.bonus[bonusDex].magicDmg
set c.magicDefense = c.magicDefense - iDex.bonus[bonusDex].magicDefense
set c.attackRange = c.attackRange - iDex.bonus[bonusDex].attackRange
set c.blockRate = c.blockRate - iDex.bonus[bonusDex].blockRate
set c.criticalRate = c.criticalRate - iDex.bonus[bonusDex].criticalRate
set c.criticalPower = c.criticalPower - iDex.bonus[bonusDex].criticalPower
set c.evasionRate = c.evasionRate - iDex.bonus[bonusDex].evasionRate
set c.knockback = c.knockback - iDex.bonus[bonusDex].knockback
set c.knockbackResist = c.knockbackResist - iDex.bonus[bonusDex].knockbackResist
set c.interrupt = c.interrupt - iDex.bonus[bonusDex].interrupt
set c.interruptResist = c.interruptResist - iDex.bonus[bonusDex].interruptResist
set c.stun = c.stun - iDex.bonus[bonusDex].stun
set c.stunResist = c.stunResist - iDex.bonus[bonusDex].stunResist
set c.hp = c.hp - iDex.bonus[bonusDex].hp
set c.sp = c.sp - iDex.bonus[bonusDex].sp
set c.hpMax = c.hpMax - iDex.bonus[bonusDex].hpMax
set c.spMax = c.spMax - iDex.bonus[bonusDex].spMax
set c.attackRate = c.attackRate + iDex.bonus[bonusDex].aspd
set c.fireElement = c.fireElement - iDex.bonus[bonusDex].fireElement
set c.fireElementResist = c.fireElementResist - iDex.bonus[bonusDex].fireElementResist
set c.waterElement = c.waterElement - iDex.bonus[bonusDex].waterElement
set c.waterElementResist = c.waterElementResist - iDex.bonus[bonusDex].waterElementResist
set c.earthElement = c.earthElement - iDex.bonus[bonusDex].earthElement
set c.earthElementResist = c.earthElementResist - iDex.bonus[bonusDex].earthElementResist
set c.windElement = c.windElement - iDex.bonus[bonusDex].windElement
set c.windElementResist = c.windElementResist - iDex.bonus[bonusDex].windElementResist
set c.holyElement = c.holyElement - iDex.bonus[bonusDex].holyElement
set c.darkElement = c.darkElement - iDex.bonus[bonusDex].darkElement
call SetUnitMoveSpeed(c.u, GetUnitMoveSpeed(c.u) - iDex.bonus[bonusDex].mspd)
if ItemSet.ItemIndex[Tooltips1[c.pid].itmObject.id] == ItemSet.ItemIndex[itm.id] then
call Tooltips1[c.pid].setItem(Tooltips1[c.pid].itmObject)
endif
//endif
endif
endif
if c.hp > c.hpMax then
set c.hp = c.hpMax
endif
if c.sp > c.spMax then
set c.sp = c.spMax
endif
if Tooltips1[c.pid].control.visible then
if Tooltips1[c.pid].skill != 0 then
call Tooltips1[c.pid].setSkill(Tooltips1[c.pid].skill)
elseif Tooltips1[c.pid].itmObject != 0 then
call Tooltips1[c.pid].setItem(Tooltips1[c.pid].itmObject)
endif
endif
endmethod
method dropItemFromSlot takes integer slot, boolean restoreObject returns boolean
local InventoryContent node = SlotIndex[this][slot]
local integer data
local integer i
if node.object != 0 then
if Tooltips1[pid].control.visible and Tooltips1[pid].itmObject == node.object then
call Tooltips1[pid].show(false)
set Tooltips1[pid].itmObject = -1
call Tooltips2[pid].show(false)
set Tooltips2[pid].itmObject = -1
endif
if ShortcutBar_SkillSelection[pid].visible then
call ShortcutBar_SkillSelection[pid].clear()
set ShortcutBar_SelectIndex[pid] = -1
call ShortcutBar_SkillSelection[pid].show(false)
endif
set i = 0
loop
exitwhen i == 10
set data = GetUnitUserData(ShortcutBar_Button[pid][i].dummy)
if ShortcutBar_ButtonType[data] == 2 and ShortcutBar_ButtonTarget[data] == slot then
call ShortcutBar_ChargeText[pid][i].show(false)
set ShortcutBar_Button[pid][i].texture = 'BSAL'
set ShortcutBar_ButtonType[data] = 0
call ShortcutBar_Button[pid][i].refresh()
call ShortcutBar_PutToCooldown(pid, i, 0.0001, 0.0001)
endif
set i = i + 1
endloop
if restoreObject then
call node.object.move(GetUnitX(main), GetUnitY(main))
call node.object.show(true)
else
call node.object.destroy()
endif
set node.object = 0
set node.plat.texture = 'BSAL'
call node.rarity.show(false)
call node.plat.show(false)
call node.text.show(false)
return true
endif
return false
endmethod
method useItemAtSlot takes integer index returns boolean
local integer i
local integer j
local integer data
local real dur
local ItemObject obj
if UnitAlive(MainUnit[pid]) then
if SlotIndex[this][index].object.id.category < Items.CONSUMABLE then
//call DisplayTimedTextToPlayer(play, 0, 0, 3., "Item equipped: " + SlotIndex[this][index].object.id.name + " (" + QualityNames[SlotIndex[this][index].object.quality] + ")")
if UpgradeMenu_Main[pid].visible then
if UpgradeMenu_EffectAnimation[pid] == 0 and UpgradeMenu_SetItem(pid, 0, SlotIndex[this][index].object) then
set obj = SlotIndex[this][index].object
call dropItemFromSlot(index, true)
call obj.show(false)
call closeContextMenu()
endif
else
call CharacterWindow_Attach(pid, index)
call closeContextMenu()
endif
elseif SlotIndex[this][index].object.id.category == Items.GEM then
if UpgradeMenu_Main[pid].visible then
call DisplayTimedTextToPlayer(play, 0, 0, 5., "Unable to use this item when upgrading.")
else
call enableItemSocket(not socketing)
endif
elseif SlotIndex[this][index].object.id.category == Items.SCROLL then
if UpgradeMenu_Main[pid].visible then
call DisplayTimedTextToPlayer(play, 0, 0, 5., "Unable to use this item when upgrading.")
else
call Gate_UseScroll(pid, index)
endif
elseif SlotIndex[this][index].object.id.category == Items.MISC and SlotIndex[this][index].object.id.class != "Misc" then
if UpgradeMenu_Main[pid].visible then
set obj = ItemObject.create(SlotIndex[this][index].object.id, 1, 0, WorldBounds.maxX, WorldBounds.maxY)
if UpgradeMenu_EffectAnimation[pid] == 0 and UpgradeMenu_SetItem(pid, SlotIndex[this][index].object.id.strength, obj) then
if SlotIndex[this][index].object.charge > 1 then
set SlotIndex[this][index].object.charge = SlotIndex[this][index].object.charge - 1
call SlotIndex[this][index].text.setText(I2S(SlotIndex[this][index].object.charge), FONTSTYLE_FrizQTShaded)
if SlotIndex[this][index].object.charge > 9 then
call SlotIndex[this][index].text.move(SlotIndex[this][index].plat.xOffset+10, SlotIndex[this][index].text.yOffset, SlotIndex[this][index].text.level)
else
call SlotIndex[this][index].text.move(SlotIndex[this][index].plat.xOffset+15, SlotIndex[this][index].text.yOffset, SlotIndex[this][index].text.level)
endif
call SlotIndex[this][index].text.refresh()
else
call dropItemFromSlot(index, false)
endif
call closeContextMenu()
endif
else
call DisplayTimedTextToPlayer(play, 0, 0, 5., "Use this item with the uprade menu open to insert.")
endif
elseif SlotIndex[this][index].object.id.category == Items.CONSUMABLE then
if not SlotIndex[this][index].object.id.onCooldown() then
set dur = SlotIndex[this][index].object.cooldown
set i = 0
loop
exitwhen i == 20
if i != index and SlotIndex[this][i].object.id.cooldownGroup == SlotIndex[this][index].object.id.cooldownGroup then
call CooldownAnimation.create(SlotIndex[this][i].cool, dur, dur)
call SlotIndex[this][i].object.id.startCooldown(dur)
endif
set i = i + 1
endloop
set i = 0
loop
exitwhen i == 10
set data = GetUnitUserData(ShortcutBar_Button[pid][i].dummy)
if ShortcutBar_ButtonType[data] == 2 then
if SlotIndex[this][ShortcutBar_ButtonTarget[data]].object.id.cooldownGroup == SlotIndex[this][index].object.id.cooldownGroup then
call ShortcutBar_PutToCooldown(pid, i, dur, dur)
endif
endif
set i = i + 1
endloop
call SlotIndex[this][index].object.id.startCooldown(dur)
if SlotIndex[this][index].object.charge > 0 then
call ApplyBonus(Fighter[pid], SlotIndex[this][index].object)
endif
if SlotIndex[this][index].object.charge > 1 then
call CooldownAnimation.create(SlotIndex[this][index].cool, dur, dur)
set SlotIndex[this][index].object.charge = SlotIndex[this][index].object.charge - 1
call SlotIndex[this][index].text.setText(I2S(SlotIndex[this][index].object.charge), FONTSTYLE_FrizQTShaded)
if SlotIndex[this][index].object.charge > 9 then
call SlotIndex[this][index].text.move(SlotIndex[this][index].plat.xOffset+10, SlotIndex[this][index].text.yOffset, SlotIndex[this][index].text.level)
else
call SlotIndex[this][index].text.move(SlotIndex[this][index].plat.xOffset+15, SlotIndex[this][index].text.yOffset, SlotIndex[this][index].text.level)
endif
call SlotIndex[this][index].text.refresh()
set i = 0
loop
exitwhen i == 10
set data = GetUnitUserData(ShortcutBar_Button[pid][i].dummy)
if ShortcutBar_ButtonType[data] == 2 and ShortcutBar_ButtonTarget[data] == index then
call ShortcutBar_ChargeText[pid][i].setText(I2S(SlotIndex[this][index].object.charge), FONTSTYLE_FrizQTShaded)
call ShortcutBar_ChargeText[pid][i].refresh()
endif
set i = i + 1
endloop
if Tooltips1[pid].control.visible and Tooltips1[pid].itmObject == SlotIndex[this][index].object then
call Tooltips1[pid].setItem(SlotIndex[this][index].object)
endif
else
set j = 0
loop
exitwhen j == 20
if j != index and SlotIndex[this][j].object.id == SlotIndex[this][index].object.id then
exitwhen true
endif
set j = j + 1
endloop
if j < 20 then
set i = 0
loop
exitwhen i == 10
set data = GetUnitUserData(ShortcutBar_Button[pid][i].dummy)
if ShortcutBar_ButtonType[data] == 2 and ShortcutBar_ButtonTarget[data] == index then
set ShortcutBar_ButtonTarget[data] = j
call ShortcutBar_ChargeText[pid][i].setText(I2S(SlotIndex[this][j].object.charge), FONTSTYLE_FrizQTShaded)
call ShortcutBar_ChargeText[pid][i].refresh()
endif
set i = i + 1
endloop
endif
call dropItemFromSlot(index, false)
call closeContextMenu()
return false
endif
else
call DisplayTimedTextToPlayer(play, 0, 0, 1., "Still on cooldown.")
endif
endif
endif
return true
endmethod
method moveItemToSlot takes integer from, integer to returns boolean
local InventoryContent node1
local InventoryContent node2
local ItemObject object
local integer charge
local integer skin
local integer data
local integer i
local real cooldown
local PanelPlatform cool
if from > -1 and to > -1 and from < 20 and to < 20 and from != to then
if ShortcutBar_SkillSelection[pid].visible then
call ShortcutBar_SkillSelection[pid].clear()
set ShortcutBar_SelectIndex[pid] = -1
call ShortcutBar_SkillSelection[pid].show(false)
endif
set node1 = SlotIndex[this][from]
set node2 = SlotIndex[this][to]
set object = node1.object
if node1.object.id.category == Items.CONSUMABLE and node2.object.id.category == Items.CONSUMABLE and /*
*/ node2.object.charge < node2.object.id.maxCharge and node1.object.id == node2.object.id then
set charge = node2.object.id.maxCharge-node2.object.charge
if charge > node1.object.charge then
set node2.object.charge = node2.object.charge + node1.object.charge
call dropItemFromSlot(from, false)
else
set node2.object.charge = node2.object.id.maxCharge
set node1.object.charge = node1.object.charge - charge
if node1.object.charge > 9 then
call node1.text.move(node1.plat.xOffset+10, node1.text.yOffset, node1.text.level)
else
call node1.text.move(node1.plat.xOffset+15, node1.text.yOffset, node1.text.level)
endif
call node1.text.setText(I2S(node1.object.charge), FONTSTYLE_FrizQTShaded)
call node1.text.refresh()
endif
if node2.object.charge > 9 then
call node2.text.move(node2.plat.xOffset+10, node2.text.yOffset, node2.text.level)
else
call node2.text.move(node2.plat.xOffset+15, node2.text.yOffset, node2.text.level)
endif
call node2.text.setText(I2S(node2.object.charge), FONTSTYLE_FrizQTShaded)
call node2.text.refresh()
set i = 0
loop
exitwhen i == 10
set data = GetUnitUserData(ShortcutBar_Button[pid][i].dummy)
if ShortcutBar_ButtonType[data] == 2 then
if ShortcutBar_ButtonTarget[data] == from then
call ShortcutBar_ChargeText[pid][i].setText(I2S(node1.object.charge), FONTSTYLE_FrizQTShaded)
call ShortcutBar_ChargeText[pid][i].refresh()
elseif ShortcutBar_ButtonTarget[data] == to then
call ShortcutBar_ChargeText[pid][i].setText(I2S(node2.object.charge), FONTSTYLE_FrizQTShaded)
call ShortcutBar_ChargeText[pid][i].refresh()
endif
endif
set i = i + 1
endloop
else
set i = 0
loop
exitwhen i == 10
set data = GetUnitUserData(ShortcutBar_Button[pid][i].dummy)
if ShortcutBar_ButtonType[data] == 2 then
if ShortcutBar_ButtonTarget[data] == from then
set ShortcutBar_ButtonTarget[data] = to
elseif ShortcutBar_ButtonTarget[data] == to then
set ShortcutBar_ButtonTarget[data] = from
endif
endif
set i = i + 1
endloop
set cool = node1.cool
set skin = node1.plat.texture
set node1.object = node2.object
set node1.cool = node2.cool
set node1.plat.texture = node2.plat.texture
call SetUnitVertexColor(node1.rarity.dummy, RarityColorR[node2.object.rarity], RarityColorG[node2.object.rarity], RarityColorB[node2.object.rarity], RARITY_BORDER_ALPHA)
if node1.object.id.maxCharge > 0 then
if node1.object.charge > 9 then
call node1.text.move(node1.plat.xOffset+10, node1.text.yOffset, node1.text.level)
else
call node1.text.move(node1.plat.xOffset+15, node1.text.yOffset, node1.text.level)
endif
call node1.text.setText(I2S(node1.object.charge), FONTSTYLE_FrizQTShaded)
call node1.text.show(true)
call node1.text.refresh()
else
call node1.text.show(false)
endif
call node1.plat.show(node1.object != 0)
call node1.rarity.show(node1.object != 0)
set node2.object = object
set node2.cool = cool
call SetUnitVertexColor(node2.rarity.dummy, RarityColorR[object.rarity], RarityColorG[object.rarity], RarityColorB[object.rarity], RARITY_BORDER_ALPHA)
if object == 0 then
set node2.plat.texture = 'BSAL'
else
set node2.plat.texture = skin
endif
if node2.object.id.maxCharge > 0 then
if node2.object.charge > 9 then
call node2.text.move(node2.plat.xOffset+10, node2.text.yOffset, node2.text.level)
else
call node2.text.move(node2.plat.xOffset+15, node2.text.yOffset, node2.text.level)
endif
call node2.text.setText(I2S(node2.object.charge), FONTSTYLE_FrizQTShaded)
call node2.text.show(true)
call node2.text.refresh()
else
call node2.text.show(false)
endif
call node2.plat.show(node2.object != 0)
call node2.rarity.show(node2.object != 0)
call node1.cool.move(node1.plat.xOffset, node1.plat.yOffset, node1.cool.level)
call node2.cool.move(node2.plat.xOffset, node2.plat.yOffset, node2.cool.level)
call node1.plat.refresh()
call node2.plat.refresh()
call node1.rarity.refresh()
call node2.rarity.refresh()
call node1.cool.refresh()
call node2.cool.refresh()
if Locale == play then
call InventorySwapSound.play(0, 0, 0, 100)
else
call InventorySwapSound.play(0, 0, 0, 0)
endif
endif
call selectSlot(to, GetUnitUserData(node2.plat.dummy))
return true
else
call closeContextMenu()
endif
return false
endmethod
method sortContent takes boolean repeat returns nothing
local integer i = 0
local integer j
local integer lowestIndex
local integer lowestCategory
local integer lowestLevel
local integer lowestId
local ItemObject obj
loop
exitwhen i >= 20
set lowestIndex = 50
set obj = SlotIndex[this][i].object
if obj > 0 then
set lowestCategory = obj.id.category
set lowestLevel = obj.reqLevel
set lowestId = obj.idToInt
else
set lowestCategory = 50
set lowestLevel = MAXIMUM_LEVEL + 1
set lowestId = 9999
endif
set j = i + 1
loop
exitwhen j >= 20
set obj = SlotIndex[this][j].object
if obj > 0 then
if obj.id.category < lowestCategory then
set lowestCategory = obj.id.category
set lowestIndex = j
elseif obj.id.category == lowestCategory then
if obj.idToInt < lowestId then
set lowestId = obj.idToInt
set lowestIndex = j
elseif obj.idToInt == lowestId then
if obj.reqLevel < lowestLevel then
set lowestLevel = obj.reqLevel
set lowestIndex = j
endif
endif
endif
endif
set j = j + 1
endloop
if lowestIndex < 50 and i != lowestIndex then
call moveItemToSlot(lowestIndex, i)
endif
set i = i + 1
endloop
call enableItemMove(false)
call enableItemSocket(false)
call closeContextMenu()
if repeat then
call sortContent(false)
endif
endmethod
method addItemToSlot takes ItemObject object, integer slot returns boolean
local InventoryContent node
local integer id
local integer i
local integer data
if object <= 0 then
return false
endif
if ShortcutBar_SkillSelection[pid].visible then
call ShortcutBar_SkillSelection[pid].clear()
set ShortcutBar_SelectIndex[pid] = -1
call ShortcutBar_SkillSelection[pid].show(false)
endif
set node = SlotIndex[this][slot]
loop
exitwhen node.index == 20
if node.object == 0 then
set node.object = ItemObject.duplicate(object, GetUnitX(main), GetUnitY(main))
set node.object.charge = 0
set node.plat.texture = object.id.texture
call node.object.show(false)
call node.plat.show(true)
call node.plat.refresh()
call SetUnitVertexColor(node.rarity.dummy, RarityColorR[node.object.rarity], RarityColorG[node.object.rarity], RarityColorB[node.object.rarity], RARITY_BORDER_ALPHA)
call node.rarity.show(true)
call node.rarity.refresh()
if node.object.id.onCooldown() then
call CooldownAnimation.create(node.cool, node.object.id.getCooldown(), node.object.cooldown)
call node.cool.refresh()
endif
if socketing then
call enableItemSocket(false)
endif
endif
if node.object.charge + object.charge < node.object.id.maxCharge then
set node.object.charge = node.object.charge + object.charge
set object.charge = 0
else
if node.object.id.maxCharge > 0 then
set object.charge = object.charge-(node.object.id.maxCharge-node.object.charge)
else
set object.charge = object.charge-1
endif
set node.object.charge = node.object.id.maxCharge
endif
if node.object.id.maxCharge > 0 then
if node.object.charge > 9 then
call node.text.move(node.plat.xOffset+10, node.text.yOffset, node.text.level)
else
call node.text.move(node.plat.xOffset+15, node.text.yOffset, node.text.level)
endif
call node.text.setText(I2S(node.object.charge), FONTSTYLE_FrizQTShaded)
call node.text.show(true)
call node.text.refresh()
set i = 0
loop
exitwhen i == 10
set data = GetUnitUserData(ShortcutBar_Button[pid][i].dummy)
if ShortcutBar_ButtonType[data] == 2 then
if ShortcutBar_ButtonTarget[data] == node.index then
call ShortcutBar_ChargeText[pid][i].setText(I2S(node.object.charge), FONTSTYLE_FrizQTShaded)
call ShortcutBar_ChargeText[pid][i].refresh()
endif
endif
set i = i + 1
endloop
if Tooltips1[pid].control.visible and Tooltips1[pid].itmObject == node.object then
call Tooltips1[pid].setItem(node.object)
endif
else
call node.text.show(false)
endif
if not IsDataLoading and not UpgradeMenu_Main[pid].visible and node.object.id.category < 11 then
set id = GetPlayerId(play)
if CharacterWindow_SlotObject[id][node.object.id.category] == 0 then
//call CharacterWindow_Attach(id, node.index)
//call useItemAtSlot(node.index)
if verifyRequirements(node.index, false) then
call useItemAtSlot(node.index)
endif
endif
endif
exitwhen object.charge <= 0
set node = SlotIndex[this][getStackableSlot(object)]
endloop
if node.index == 20 then
call DisplayTimedTextToPlayer(play, 0, 0, 1., "Inventory is full.")
call object.move(GetUnitX(object.object), GetUnitY(object.object))
return false
else
call object.destroy()
return true
endif
endmethod
method addItem takes ItemObject object returns boolean
if object.id.category == Items.CONSUMABLE or (object.id.category == Items.MISC and object.id.maxCharge > 0) then
return addItemToSlot(object, getStackableSlot(object))
else
return addItemToSlot(object, getEmptySlot())
endif
endmethod
method addItemEx takes unit u returns boolean
return addItem(ItemObject[u])
endmethod
method addItemCreate takes Items id, integer amount, integer quality returns boolean
return addItem(ItemObject.create(id, amount, quality, GetUnitX(main), GetUnitY(main)))
endmethod
method enableItemMove takes boolean b returns nothing
local integer i
if b then
call context.show(false)
set i = 0
loop
exitwhen i == 5
call ContextButton[this][i].show(false)
set i = i + 1
endloop
call enableItemSocket(false)
set moving = true
set socketing = false
set i = 0
loop
exitwhen i == 20
if i != index then
call SlotIndex[this][i].plat.show(true)
call SlotMoveHighlight[this][i].show(true)
call SlotMoveHighlight[this][i].setColor(0, 255, 0, 255)
call SlotIndex[this][i].plat.refresh()
call SlotMoveHighlight[this][i].refresh()
endif
set i = i + 1
endloop
elseif moving then
set moving = false
set i = 0
loop
exitwhen i == 20
call SlotIndex[this][i].plat.show(SlotIndex[this][i].object != 0)
call SlotMoveHighlight[this][i].show(false)
set i = i + 1
endloop
call highlight.move(SlotIndex[this][index].plat.xOffset, SlotIndex[this][index].plat.yOffset, 4)
call highlight.refresh()
endif
endmethod
method enableItemSocket takes boolean b returns nothing
local integer i
local boolean available
if b then
call context.show(false)
set i = 0
loop
exitwhen i == 5
call ContextButton[this][i].show(false)
set i = i + 1
endloop
call enableItemMove(false)
set socketing = true
set moving = false
set available = false
set i = 0
loop
exitwhen i == 20
if i != index and SlotIndex[this][i].object.id.category < Items.CONSUMABLE and SlotIndex[this][i].object.socketCountMax > 0 and SlotIndex[this][i].object.socketCount < SlotIndex[this][i].object.socketCountMax then
if SlotIndex[this][i].object.reqLevel >= SlotIndex[this][index].object.reqLevel then
set available = true
call SlotIndex[this][i].plat.show(true)
call SlotMoveHighlight[this][i].show(true)
call SlotMoveHighlight[this][i].setColor(255, 255, 0, 255)
call SlotIndex[this][i].plat.refresh()
call SlotMoveHighlight[this][i].refresh()
endif
endif
set i = i + 1
endloop
if not available then
call enableItemSocket(false)
call DisplayTimedTextToPlayer(play, 0, 0, 5., "No item is available for socketing!")
endif
elseif socketing then
set socketing = false
set i = 0
loop
exitwhen i == 20
call SlotIndex[this][i].plat.show(SlotIndex[this][i].object != 0)
call SlotMoveHighlight[this][i].show(false)
set i = i + 1
endloop
call highlight.move(SlotIndex[this][index].plat.xOffset, SlotIndex[this][index].plat.yOffset, 4)
call highlight.refresh()
endif
endmethod
method show takes boolean b returns nothing
if IsKeyVerified[pid] or not b then
if b != visible then
set visible = b
if b then
if Locale == play then
call TooltipsDisplaySound.play(0, 0, 0, 100)
else
call TooltipsDisplaySound.play(0, 0, 0, 0)
endif
else
call enableItemMove(false)
call enableItemSocket(false)
call closeContextMenu()
endif
call panel.show(b)
endif
endif
endmethod
static method create takes unit whichUnit returns thistype
local thistype this = allocate()
local integer index = -1
local integer i
local integer j
local integer data
local InventoryContent node
local BJObjectId id = 'eIP0'
set play = GetOwningPlayer(whichUnit)
set panel = Panel.create(play, 'e00F', 'B00V', 448.0, -100, 0)
//set panel = Panel.create('h00B', 'B005', 560.0, -135, 0)
set panel.scale = 0.9
set highlight = PanelPlatform.create(panel, 'e008', 0, 0, 0, 4)
call highlight.show(false)
set contents = InventoryContent.createNode()
set main = whichUnit
set pid = GetPlayerId(play)
set InventoryIndex[pid] = this
set index = -1
set time = NewTimerEx(this)
set dClick = NewTimerEx(this)
set open = false
set visible = true
set moving = false
set context = PanelPlatform.create(panel, 'e00B', 'B00R', CONTEXT_X_CLOSE, -24.0, 6)
call context.show(false)
set sort = PanelPlatform.create(panel, 'e02J', 'B01F', 116, 96, 1)
set sort.scale = 0.405
set exit = PanelPlatform.create(panel, 'e001', 0, 127.5, 130.0, 1)
set exit.scale = 0.7
call exit.setColor(255, 255, 255, 0)
set UnitBag[GetUnitUserData(main)] = this
set ExitBag[GetUnitUserData(exit.dummy)] = this
set SortBag[GetUnitUserData(sort.dummy)] = this
set gold = PanelTextEx.create(panel, "0", FONTSTYLE_FrizQTShaded, -120, 96, 1)
set gold.scale = 0.3
set i = 0
loop
exitwhen i > 3
set j = 0
loop
exitwhen j > 4
set index = index + 1
set id = id.plus_1()
set node = InventoryContent.allocate()
set node.parent = this
set node.plat = PanelPlatform.create(panel, id, 'BSAL', -115.0+54.5*j, 52.0-53.5*i, 1)
set node.plat.scale = 0.8
set node.rarity = PanelPlatform.create(panel, 'e00Y', 0, node.plat.xOffset, node.plat.yOffset, 2)
set node.rarity.scale = 0.8
set node.text = PanelTextEx.create(panel, "", FONTSTYLE_FrizQTShaded, node.plat.xOffset+15, node.plat.yOffset-17, 5)
set node.text.scale = 0.3
call node.rarity.show(false)
call node.plat.show(false)
call node.text.show(false)
set SlotMoveHighlight[this][index] = PanelPlatform.create(panel, 'e008', 0, node.plat.xOffset, node.plat.yOffset, 4)
call SlotMoveHighlight[this][index].setColor(0, 255, 0, 255)
call SlotMoveHighlight[this][index].show(false)
set node.index = index
set node.object = 0
set node.cool = PanelPlatform.create(panel, 'e007', 'BSAL', node.plat.xOffset, node.plat.yOffset, 3)
set node.cool.scale = 0.85
call node.cool.setColor(0, 0, 0, 155)
call node.cool.show(false)
call contents.insertNode(node)
set data = GetUnitUserData(node.plat.dummy)
set SlotBag[data] = this
set ButtonSlot[data] = node
set SlotIndex[this][index] = node
set j = j + 1
endloop
set i = i + 1
endloop
set SlotIndex[this][20].index = 20 // end of list
set id = 'eCB0'
set i = 0
loop
exitwhen i == 5
set id = id.plus_1()
set ContextButton[this][i] = PanelPlatform.create(panel, id, 'B099', -200.0, 59.0-28.0*i, 0)
call ContextButton[this][i].setColor(255, 255, 255, 64)
call ContextButton[this][i].show(false)
set ContextButtonBag[GetUnitUserData(ContextButton[this][i].dummy)] = this
set ContextButtonIndex[GetUnitUserData(ContextButton[this][i].dummy)] = i+1
set i = i + 1
endloop
return this
endmethod
private static method onSelect takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer data = GetUnitUserData(u)
local integer data2
local integer charge
local integer i
local real cool
local boolean b
local thistype this
local InventoryContent slot
local ItemObject object
if ExitBag[data] != 0 then
set this = ExitBag[data]
call show(false)
if Locale == play then
call SelectUnit(u, false)
call SelectUnit(Controller[pid], true)
endif
elseif SortBag[data] != 0 then
set this = SortBag[data]
call sortContent(true)
if Locale == play then
call SelectUnit(u, false)
call SelectUnit(Controller[pid], true)
endif
elseif SlotBag[data] != 0 then
set this = SlotBag[data]
if ButtonSlot[data].object != -1 then
if moving then
if moveItemToSlot(index, ButtonSlot[data].index) then
set index = ButtonSlot[data].index
endif
call enableItemMove(false)
elseif socketing then
set object = SlotIndex[this][index].object
if ButtonSlot[data].object.socket(object) then
call DisplayTimedTextToPlayer(play, 0, 0, 5., "The gem has been inserted.")
call dropItemFromSlot(index, true)
call object.show(false)
if Tooltips1[pid].control.visible and Tooltips1[pid].itmObject == ButtonSlot[data].object then
call Tooltips1[pid].setItem(ButtonSlot[data].object)
endif
if Locale == play then
call ItemSocketSound.play(0, 0, 0, 135)
else
call ItemSocketSound.play(0, 0, 0, 0)
endif
call ForForce(bj_FORCE_PLAYER[pid], function CreateNewSaveThread)
endif
set index = ButtonSlot[data].index
call enableItemSocket(false)
call selectSlot(index, data)
else
if index != ButtonSlot[data].index then
if visible then
set index = ButtonSlot[data].index
call selectSlot(index, data)
call TimerStart(dClick, DOUBLE_CLICK_WAIT_TIME, false, null)
endif
else
if TimerGetRemaining(dClick) > 0.01 then
if ShopUI[pid].visible and ShopMerchants_CurrentMerchant[pid] != null then
if not SlotIndex[this][index].object.id.onCooldown() then
if Locale == play then
call InventorySellSound.play(0, 0, 0, 100)
else
call InventorySellSound.play(0, 0, 0, 0)
endif
set charge = SlotIndex[this][index].object.charge
if charge == 0 then
set charge = 1
endif
call SetPlayerState(play, PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(play, PLAYER_STATE_RESOURCE_GOLD)+SlotIndex[this][index].object.gold*charge)
call ShopUI[pid].addItem(ShopUI[pid].clist.sellItem(SlotIndex[this][index].object))
call dropItemFromSlot(index, false)
call enableItemMove(false)
call closeContextMenu()
//set SavingPlayerID = pid
//call ExecuteFunc("CreateNewSaveThreadEx")
else
call DisplayTimedTextToPlayer(play, 0, 0, 1., "Still on cooldown.")
endif
elseif verifyRequirements(index, true) then
call TimerStart(dClick, DOUBLE_CLICK_WAIT_TIME, false, null)
call useItemAtSlot(index)
endif
else
call closeContextMenu()
endif
endif
endif
endif
if Locale == play then
call SelectUnit(u, false)
call SelectUnit(Controller[pid], true)
endif
elseif ContextButtonBag[data] != 0 then
set this = ContextButtonBag[data]
if UnitAlive(MainUnit[pid]) then
if ContextButtonIndex[data] == 1 then // Use
if verifyRequirements(index, true) then
call enableItemMove(false)
call useItemAtSlot(index)
endif
elseif ContextButtonIndex[data] == 2 then // move
call enableItemMove(not moving)
elseif ContextButtonIndex[data] == 3 then // drop
if not SlotIndex[this][index].object.id.onCooldown() then
call dropItemFromSlot(index, true)
call enableItemMove(false)
call enableItemSocket(false)
call closeContextMenu()
if Locale == play then
call InventoryDropSound.play(0, 0, 0, 100)
else
call InventoryDropSound.play(0, 0, 0, 0)
endif
//set SavingPlayerID = pid
//call ExecuteFunc("CreateNewSaveThreadEx")
else
call DisplayTimedTextToPlayer(play, 0, 0, 1., "Still on cooldown.")
endif
elseif ContextButtonIndex[data] == 4 then // sell
if ShopUI[pid].visible and ShopMerchants_CurrentMerchant[pid] != null then
if not SlotIndex[this][index].object.id.onCooldown() then
if Locale == play then
call InventorySellSound.play(0, 0, 0, 100)
else
call InventorySellSound.play(0, 0, 0, 0)
endif
set charge = SlotIndex[this][index].object.charge
if charge == 0 then
set charge = 1
endif
call SetPlayerState(play, PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(play, PLAYER_STATE_RESOURCE_GOLD)+SlotIndex[this][index].object.gold*charge)
//call SetPlayerState(play, PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState(play, PLAYER_STATE_RESOURCE_LUMBER)+SlotIndex[this][index].object.lumber*charge)
call ShopUI[pid].addItem(ShopUI[pid].clist.sellItem(SlotIndex[this][index].object))
call dropItemFromSlot(index, false)
call enableItemMove(false)
call enableItemSocket(false)
call closeContextMenu()
//set SavingPlayerID = pid
//call ExecuteFunc("CreateNewSaveThreadEx")
else
call DisplayTimedTextToPlayer(play, 0, 0, 1., "Still on cooldown.")
endif
else
call DisplayTimedTextToPlayer(play, 0, 0, 1., "Must select a merchant first.")
endif
elseif ContextButtonIndex[data] == 5 then
call enableItemMove(false)
call closeContextMenu()
endif
else
call DisplayTimedTextToPlayer(play, 0, 0, 1., "You are dead.")
endif
if Locale == play then
call SelectUnit(u, false)
call SelectUnit(Controller[pid], true)
endif
endif
set u = null
return false
endmethod
private static method onDeindex takes nothing returns boolean
local unit u = GetIndexedUnit()
local integer data = GetUnitUserData(u)
if SlotBag[data] != 0 then
set SlotBag[data] = 0
set ButtonSlot[data] = 0
endif
set u = null
return false
endmethod
private static method checkPickItem takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
local integer vol
local ItemObject obj
if GetUnitCurrentOrder(MainUnit[id]) == PickItemOrder[id] then
if IsUnitInRange(MainUnit[id], PickItemTarget[id], ITEM_PICKUP_RANGE) then
set obj = ItemObject[PickItemTarget[id]]
if obj.id.autoUse then
call ApplyBonus(Fighter[id], obj)
call obj.destroy()
else
if InventoryIndex[id].addItemEx(PickItemTarget[id]) then
if Locale == Player(id) then
set vol = 150
else
set vol = 0
endif
call PickUpItemSfx.play(0, 0, 0, vol)
endif
endif
call ReleaseTimer(PickItemTimer[id])
set PickItemTimer[id] = null
call IssueImmediateOrder(MainUnit[id], "stop")
endif
else
call ReleaseTimer(PickItemTimer[id])
set PickItemTimer[id] = null
endif
set t = null
endmethod
method orderPickItem takes unit u returns nothing
if not Fighter[pid].isStunned and not Fighter[pid].isAttacking and not Fighter[pid].isImmobilized and not Fighter[pid].isChanneling then
if GetUnitTypeId(u) == 'e02F' then
if PickItemTimer[pid] == null then
set PickItemTimer[pid] = NewTimerEx(pid)
call TimerStart(PickItemTimer[pid], 0.1, true, function thistype.checkPickItem)
endif
set PickItemOrder[pid] = GetIssuedOrderId()
set PickItemTarget[pid] = u
set skipDetect = true
call IssueTargetOrderById(MainUnit[pid], PickItemOrder[pid], u)
set skipDetect = false
endif
endif
endmethod
private static method onOrder takes nothing returns boolean
local unit u = GetOrderTargetUnit()
local integer data = GetUnitUserData(u)
local integer id
local thistype this
if skipDetect then
return false
endif
if u != null and GetIssuedOrderId() == ORDER_smart then
if (SlotBag[data] != 0 or ContextButtonBag[data] != 0 or ExitBag[data] != 0) then
set this = SlotBag[data]
set u = GetTriggerUnit()
call IssueImmediateOrderById(u, ORDER_stop)
call IssueImmediateOrderById(u, ORDER_stunned)
if SlotBag[data] != 0 then
if ButtonSlot[data].object != Tooltips1[pid].itmObject or not Tooltips1[pid].control.visible then
call Tooltips1[pid].show(true)
//call Tooltips1.control.move(540.0-ButtonSlot[data].plat.xOffset, 0, 0)
call Tooltips1[pid].setItem(ButtonSlot[data].object)
if ButtonSlot[data].object.id.category < Items.CONSUMABLE and CharacterWindow_SlotObject[pid][ButtonSlot[data].object.id.category] != 0 then
call Tooltips2[pid].show(true)
call Tooltips1[pid].control.move(150, 0, Tooltips1[pid].control.zDepth)
call Tooltips2[pid].control.move(-150, 0, Tooltips2[pid].control.zDepth)
call Tooltips1[pid].control.refresh()
call Tooltips2[pid].control.refresh()
call Tooltips2[pid].setItem(CharacterWindow_SlotObject[pid][ButtonSlot[data].object.id.category])
else
call Tooltips1[pid].control.move(0, 0, Tooltips1[pid].control.zDepth)
call Tooltips1[pid].control.refresh()
call Tooltips2[pid].show(false)
set Tooltips2[pid].itmObject = -1
endif
else
call Tooltips1[pid].show(false)
call Tooltips2[pid].show(false)
set Tooltips1[pid].itmObject = -1
set Tooltips2[pid].itmObject = -1
endif
endif
else
set id = GetPlayerId(GetTriggerPlayer())
if GetTriggerUnit() == Controller[id] then
if GetUnitTypeId(u) == 'e02F' then
call InventoryIndex[id].orderPickItem(u)
elseif PickItemTimer[id] != null then
call ReleaseTimer(PickItemTimer[id])
set PickItemTimer[id] = null
endif
endif
endif
endif
set u = null
return false
endmethod
private static method checkSelection takes nothing returns nothing
local unit u
local integer data
local thistype this
if CharacterManager_GameModeCode == 22 then
set u = BlzGetMouseFocusUnit()
if u == null then
if LastSelection != null then
set data = GetUnitUserData(u)
set this = SlotBag[data]
if Tooltips1[PNumb].itmObject != -1 then
call Tooltips1[PNumb].show(false)
call Tooltips2[PNumb].show(false)
set Tooltips1[PNumb].itmObject = -1
set Tooltips2[PNumb].itmObject = -1
set LastSelection = u
endif
endif
else
if LastSelection != u then
set data = GetUnitUserData(u)
if SlotBag[data] != 0 then
set this = SlotBag[data]
call Tooltips1[PNumb].show(true)
call Tooltips1[PNumb].setItem(ButtonSlot[data].object)
if ButtonSlot[data].object.id.category < Items.CONSUMABLE and CharacterWindow_SlotObject[PNumb][ButtonSlot[data].object.id.category] != 0 then
call Tooltips2[PNumb].show(true)
call Tooltips1[PNumb].control.move(150, 0, Tooltips1[PNumb].control.zDepth)
call Tooltips2[PNumb].control.move(-150, 0, Tooltips2[PNumb].control.zDepth)
call Tooltips1[PNumb].control.refresh()
call Tooltips2[PNumb].control.refresh()
call Tooltips2[PNumb].setItem(CharacterWindow_SlotObject[PNumb][ButtonSlot[data].object.id.category])
else
call Tooltips1[PNumb].control.move(0, 0, Tooltips1[PNumb].control.zDepth)
call Tooltips1[PNumb].control.refresh()
call Tooltips2[PNumb].show(false)
set Tooltips2[PNumb].itmObject = -1
endif
set LastSelection = u
endif
endif
endif
set u = null
endif
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call RegisterUnitIndexEvent(Condition(function thistype.onDeindex), UnitIndexer.DEINDEX)
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SELECTED)
call TriggerAddCondition(t, Condition(function thistype.onSelect))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(t, Condition(function thistype.onOrder))
call TimerStart(CreateTimer(), 0.1, true, function thistype.checkSelection)
endmethod
endstruct
private function UpdateGold takes player p, playerstate state, integer amount returns nothing
local integer id
if state == PLAYER_STATE_RESOURCE_GOLD then
set id = GetPlayerId(p)
call InventoryIndex[id].gold.setText(I2S(amount), FONTSTYLE_FrizQTShaded)
call InventoryIndex[id].gold.refresh()
endif
endfunction
hook SetPlayerState UpdateGold
endlibrary
library Shop uses UnitIndexer
///! runtextmacro DECLARE_ARRAY_2D("", "ShopContent", "SlotIndex", "8", "21")
///! runtextmacro DECLARE_ARRAY_2D("", "PanelPlatform", "ContextButton", "8", "7")
///! runtextmacro DECLARE_ARRAY_2D("", "PanelPlatform", "SlotMoveHighlight", "8", "20")
globals
public Shop array UnitBag
public Shop array SlotBag
public Shop array PorterBag
public Shop array ExitBag
public Shop array ContextButtonBag
public Shop array ContextButtonIndex
public Shop array ShopIndex
public ShopContent array ButtonSlot
public ShopContent array SlotIndex[4][21]
public PanelPlatform array ContextButton[4][7]
public PanelPlatform array SlotMoveHighlight[4][20]
endglobals
struct ShopItemList extends array
implement LinkedList
thistype soldItems
ItemObject object
integer count
method releaseSoldItems takes nothing returns nothing
local thistype node = soldItems.next
loop
exitwhen node.head or node == 0
if node.object != 0 then
call node.object.destroy()
call node.removeNode()
call node.deallocate()
endif
set node = node.next
endloop
set soldItems.count = 0
endmethod
method purchaseSoldItem takes integer index returns nothing
local thistype node = soldItems.next
local integer i = 0
loop
exitwhen node.head or node == 0
if i == index then
call node.removeNode()
call node.deallocate()
set soldItems.count = soldItems.count - 1
endif
set i = i + 1
set node = node.next
endloop
endmethod
method sellItem takes ItemObject obj returns ItemObject
local thistype node = allocate()
set soldItems.count = soldItems.count + 1
set node.object = ItemObject.duplicate(obj, WorldBounds.maxX, WorldBounds.maxY)
call node.object.show(false)
call soldItems.insertNode(node)
return node.object
endmethod
method removeItem takes ItemObject obj returns nothing
local thistype node = this.next
loop
exitwhen node.head or node == 0
if node.object == obj then
set count = count - 1
call node.object.destroy()
call node.removeNode()
call node.deallocate()
return
endif
set node = node.next
endloop
endmethod
method clearItem takes nothing returns nothing
local thistype node = this.next
set count = 0
loop
exitwhen node.head or node == 0
call node.object.destroy()
call node.removeNode()
call node.deallocate()
set node = node.next
endloop
set soldItems.count = 0
set node = soldItems.next
loop
exitwhen node.head or node == 0
call node.object.destroy()
call node.removeNode()
call node.deallocate()
set node = node.next
endloop
endmethod
method addItem takes ItemObject obj returns nothing
local thistype node = allocate()
set count = count + 1
set node.object = obj
call obj.show(false)
call .insertNode(node)
endmethod
method addItemEx takes Items id, integer amount, integer quality returns nothing
local ItemObject obj
set ItemObject.AdjustGoldPrice = false
set obj = ItemObject.create(id, amount, quality, WorldBounds.maxX, WorldBounds.maxY)
set obj.socketCountMax = 0
set obj.gold = R2I(I2R(obj.gold)*ITEM_PRICE_RATE)
call addItem(obj)
endmethod
static method create takes nothing returns thistype
local thistype this = createNode()
set soldItems = createNode()
set soldItems.count = 0
return this
endmethod
endstruct
struct ShopContent extends array
implement LinkedList
Shop parent
PanelPlatform plat
PanelPlatform rarity
PanelTextEx text
integer index
ItemObject object
endstruct
struct Shop
Panel panel
ShopContent contents
PanelPlatform highlight
PanelPlatform context
PanelPlatform exit
ShopItemList clist
unit main
player play
integer pid
integer page
integer selected
timer time
timer dClick
boolean open // context opened
boolean moving // if item moving mode
boolean visible // Shop opened
static constant real CONTEXT_X_CLOSE = 94.0
static constant real CONTEXT_X_OPEN = 191.0
static constant real ANIM_SPEED = 10.
method getEmptySlot takes nothing returns integer
local integer i = 0
loop
exitwhen i == 20 or SlotIndex[this][i].object == 0
set i = i + 1
endloop
return i
endmethod
method getStackableSlot takes ItemObject object returns integer
local integer i = 0
loop
exitwhen i == 20 or (SlotIndex[this][i].object.id == object.id and SlotIndex[this][i].object.charge < object.id.maxCharge)
set i = i + 1
endloop
if i == 20 then
return getEmptySlot()
endif
return i
endmethod
method selectSlot takes integer dex, integer data returns nothing
local integer i = 0
set open = true
set selected = dex
call context.show(true)
call highlight.show(true)
call context.move(ButtonSlot[data].plat.xOffset+85, ButtonSlot[data].plat.yOffset-83, context.level)
call highlight.move(ButtonSlot[data].plat.xOffset, ButtonSlot[data].plat.yOffset, 4)
call context.refresh()
call highlight.refresh()
set i = 0
loop
exitwhen i == 2
call ContextButton[this][i].show(true)
call ContextButton[this][i].move(context.xOffset, context.yOffset+85-28*i, context.level+1)
call ContextButton[this][i].refresh()
set i = i + 1
endloop
endmethod
method closeContextMenu takes nothing returns nothing
local integer i = 0
set open = false
set selected = -1
call highlight.show(false)
call context.show(false)
set i = 0
loop
exitwhen i == 2
call ContextButton[this][i].show(false)
set i = i + 1
endloop
endmethod
method dropItemFromSlot takes integer slot, boolean restoreObject returns boolean
local ShopContent node = SlotIndex[this][slot]
if node.object != 0 then
if not restoreObject then
call node.object.destroy()
endif
set node.object = 0
set node.plat.texture = 'BSAL'
call node.rarity.show(false)
call node.plat.show(false)
call node.text.show(false)
return true
endif
return false
endmethod
method addItemToSlot takes ItemObject object, integer slot returns boolean
local ShopContent node
local integer id
if object <= 0 then
return false
endif
if slot == 20 then
return false
endif
set node = SlotIndex[this][slot]
set node.object = object
set node.plat.texture = object.id.texture
call node.object.show(false)
call SetUnitVertexColor(node.rarity.dummy, RarityColorR[node.object.rarity], RarityColorG[node.object.rarity], RarityColorB[node.object.rarity], RARITY_BORDER_ALPHA)
call node.rarity.show(true)
call node.plat.show(true)
call node.rarity.refresh()
call node.plat.refresh()
if node.object.id.maxCharge > 0 then
if node.object.charge > 9 then
call node.text.move(node.plat.xOffset+10, node.text.yOffset, node.text.level)
else
call node.text.move(node.plat.xOffset+15, node.text.yOffset, node.text.level)
endif
call node.text.setText(I2S(node.object.charge), FONTSTYLE_FrizQTShaded)
call node.text.show(node.object.charge > 1)
call node.text.refresh()
else
call node.text.show(false)
endif
return true
endmethod
method addItem takes ItemObject object returns boolean
return addItemToSlot(object, getEmptySlot())
endmethod
method addItemEx takes unit u returns boolean
return addItem(ItemObject[u])
endmethod
method addItemCreate takes Items id, integer amount, integer quality returns boolean
return addItem(ItemObject.create(id, amount, quality, GetUnitX(main), GetUnitY(main)))
endmethod
method setItemList takes ShopItemList list returns nothing
local integer i = 0
local ShopItemList node = list.next
local ItemObject obj
//if list != .clist then
set .clist = list
loop
exitwhen i > 19
call dropItemFromSlot(i, true)
set i = i + 1
endloop
loop
exitwhen node.head or node == 0
if node.object != 0 then
call addItem(node.object)
endif
set node = node.next
endloop
set node = list.soldItems.next
loop
exitwhen node.head or node == 0
if node.object != 0 then
call addItem(node.object)
endif
set node = node.next
endloop
//endif
endmethod
method show takes boolean b returns nothing
if IsKeyVerified[pid] or not b then
if b != visible then
set visible = b
if b then
if Locale == play then
call TooltipsDisplaySound.play(0, 0, 0, 100)
else
call TooltipsDisplaySound.play(0, 0, 0, 0)
endif
else
set ShopMerchants_CurrentMerchant[pid] = null
call closeContextMenu()
if Bag[pid].visible then
call Bag[pid].show(false)
endif
endif
call panel.show(b)
endif
endif
endmethod
method purchaseSelected takes nothing returns nothing
local integer cg
local boolean b
local ItemObject obj
if GetPlayerState(play, PLAYER_STATE_RESOURCE_GOLD) >= SlotIndex[this][selected].object.gold then
set obj = ItemObject.duplicate(SlotIndex[this][selected].object, WorldBounds.maxX, WorldBounds.maxY)
set b = false
if selected < clist.count then
set obj.gold = R2I(obj.gold/ITEM_PRICE_RATE)
else
set b = true
endif
set cg = obj.charge
if cg == 0 then
set cg = 1
endif
if Bag[pid].addItem(obj) then
call SetPlayerState(play, PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(play, PLAYER_STATE_RESOURCE_GOLD)-SlotIndex[this][selected].object.gold*cg)
if b then
call clist.purchaseSoldItem(selected - clist.count)
call setItemList(clist)
call closeContextMenu()
else
if obj.id.category == Items.SCROLL then
call clist.removeItem(SlotIndex[this][selected].object)
call setItemList(clist)
call closeContextMenu()
endif
endif
else
call obj.destroy()
endif
if Locale == play then
call ItemBuySound.play(0, 0, 0, 100)
else
call ItemBuySound.play(0, 0, 0, 0)
endif
else
call DisplayTimedTextToPlayer(play, 0, 0, 1., "Not enough gold.")
endif
endmethod
static method create takes unit whichUnit returns thistype
local thistype this = allocate()
local integer index = -1
local integer i
local integer j
local integer data
local ShopContent node
local BJObjectId id = 'eIP0'
set play = GetOwningPlayer(whichUnit)
set panel = Panel.create(play, 'e00F', 'B02P', -455.0, 0, 0)
set panel.scale = 0.9
set highlight = PanelPlatform.create(panel, 'e008', 0, 0, 0, 4)
call highlight.show(false)
set contents = ShopContent.createNode()
set main = whichUnit
set pid = GetPlayerId(play)
set ShopIndex[pid] = this
set selected = -1
set time = NewTimerEx(this)
set dClick = NewTimerEx(this)
set open = false
set moving = false
set visible = true
set context = PanelPlatform.create(panel, 'e00D', 'B02Q', CONTEXT_X_CLOSE, 24.0, 6)
call context.show(false)
set exit = PanelPlatform.create(panel, 'e001', 0, 127.5, 130.0, 1)
set exit.scale = 0.7
call exit.setColor(255, 255, 255, 0)
set UnitBag[GetUnitUserData(main)] = this
set ExitBag[GetUnitUserData(exit.dummy)] = this
set i = 0
loop
exitwhen i > 3
set j = 0
loop
exitwhen j > 4
set index = index + 1
set id = id.plus_1()
set node = ShopContent.allocate()
set node.parent = this
set node.plat = PanelPlatform.create(panel, id, 'BSAL', -115.0+54.5*j, 52.0-53.5*i, 1)
set node.plat.scale = 0.8
set node.rarity = PanelPlatform.create(panel, 'e00Y', 'BSAL', node.plat.xOffset, node.plat.yOffset, 2)
set node.rarity.scale = 0.8
set node.text = PanelTextEx.create(panel, "", FONTSTYLE_FrizQTShaded, node.plat.xOffset+15, node.plat.yOffset-17, 5)
set node.text.scale = 0.3
call node.rarity.show(false)
call node.plat.show(false)
call node.text.show(false)
set SlotMoveHighlight[this][index] = PanelPlatform.create(panel, 'e008', 0, node.plat.xOffset, node.plat.yOffset, 3)
call SlotMoveHighlight[this][index].setColor(0, 255, 0, 255)
call SlotMoveHighlight[this][index].show(false)
set node.index = index
set node.object = 0
call contents.insertNode(node)
set data = GetUnitUserData(node.plat.dummy)
set SlotBag[data] = this
set ButtonSlot[data] = node
set SlotIndex[this][index] = node
set j = j + 1
endloop
set i = i + 1
endloop
set SlotIndex[this][20].index = 20 // end of list
set id = 'eCB0'
set i = 0
loop
exitwhen i == 2
set id = id.plus_1()
set ContextButton[this][i] = PanelPlatform.create(panel, id, 'B099', 188, 39.0-28.0*i, 0)
call ContextButton[this][i].setColor(255, 255, 255, 64)
call ContextButton[this][i].show(false)
set ContextButtonBag[GetUnitUserData(ContextButton[this][i].dummy)] = this
set ContextButtonIndex[GetUnitUserData(ContextButton[this][i].dummy)] = i+1
set i = i + 1
endloop
return this
endmethod
private static method onSelect takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer data = GetUnitUserData(u)
local integer i
local integer cg
local boolean b
local thistype this
local ItemObject obj
if ExitBag[data] != 0 then
set this = ExitBag[data]
call show(false)
if Locale == play then
call SelectUnit(u, false)
call SelectUnit(Controller[pid], true)
endif
elseif SlotBag[data] != 0 then
set this = SlotBag[data]
if ButtonSlot[data].object != -1 then
if selected != ButtonSlot[data].index then
if visible then
set selected = ButtonSlot[data].index
call selectSlot(selected, data)
call TimerStart(dClick, DOUBLE_CLICK_WAIT_TIME, false, null)
endif
else
if TimerGetRemaining(dClick) > 0.01 then
call purchaseSelected()
endif
call closeContextMenu()
endif
endif
if Locale == play then
call SelectUnit(u, false)
call SelectUnit(Controller[pid], true)
endif
elseif ContextButtonBag[data] != 0 then
set this = ContextButtonBag[data]
if ContextButtonIndex[data] == 1 then // Buy
call purchaseSelected()
elseif ContextButtonIndex[data] == 2 then // Close
call closeContextMenu()
endif
if Locale == play then
call SelectUnit(u, false)
call SelectUnit(Controller[pid], true)
endif
endif
set u = null
return false
endmethod
private static method onDeindex takes nothing returns boolean
local unit u = GetIndexedUnit()
local integer data = GetUnitUserData(u)
if SlotBag[data] != 0 then
set SlotBag[data] = 0
set ButtonSlot[data] = 0
endif
set u = null
return false
endmethod
private static method onOrder takes nothing returns boolean
local unit u = GetOrderTargetUnit()
local integer data = GetUnitUserData(u)
local thistype this
if u != null and GetIssuedOrderId() == ORDER_smart and (SlotBag[data] != 0 or ContextButtonBag[data] != 0 or ExitBag[data] != 0) then
set this = SlotBag[data]
set u = GetTriggerUnit()
call IssueImmediateOrderById(u, ORDER_stop)
call IssueImmediateOrderById(u, ORDER_stunned)
if SlotBag[data] != 0 then
if ButtonSlot[data].object != Tooltips1[pid].itmObject or not Tooltips1[pid].control.visible then
call Tooltips1[pid].show(true)
//call Tooltips1.control.move(540.0-ButtonSlot[data].plat.xOffset, 0, 0)
call Tooltips1[pid].setItem(ButtonSlot[data].object)
if ButtonSlot[data].object.id.category < Items.CONSUMABLE and CharacterWindow_SlotObject[pid][ButtonSlot[data].object.id.category] != 0 then
call Tooltips2[pid].show(true)
call Tooltips1[pid].control.move(150, 0, Tooltips1[pid].control.zDepth)
call Tooltips2[pid].control.move(-150, 0, Tooltips2[pid].control.zDepth)
call Tooltips1[pid].control.refresh()
call Tooltips2[pid].control.refresh()
call Tooltips2[pid].setItem(CharacterWindow_SlotObject[pid][ButtonSlot[data].object.id.category])
else
call Tooltips1[pid].control.move(0, 0, Tooltips1[pid].control.zDepth)
call Tooltips1[pid].control.refresh()
call Tooltips2[pid].show(false)
set Tooltips2[pid].itmObject = -1
endif
else
call Tooltips1[pid].show(false)
call Tooltips2[pid].show(false)
set Tooltips1[pid].itmObject = -1
set Tooltips2[pid].itmObject = -1
endif
endif
endif
set u = null
return false
endmethod
private static method checkSelection takes nothing returns nothing
local unit u
local integer data
local thistype this
if CharacterManager_GameModeCode == 22 then
set u = BlzGetMouseFocusUnit()
if u == null then
if LastSelection != null then
set data = GetUnitUserData(u)
set this = SlotBag[data]
if Tooltips1[PNumb].itmObject != -1 then
call Tooltips1[PNumb].show(false)
call Tooltips2[PNumb].show(false)
set Tooltips1[PNumb].itmObject = -1
set Tooltips2[PNumb].itmObject = -1
set LastSelection = u
endif
endif
else
if LastSelection != u then
set data = GetUnitUserData(u)
set this = SlotBag[data]
if SlotBag[data] != 0 then
call Tooltips1[PNumb].show(true)
call Tooltips1[PNumb].setItem(ButtonSlot[data].object)
if ButtonSlot[data].object.id.category < Items.CONSUMABLE and CharacterWindow_SlotObject[PNumb][ButtonSlot[data].object.id.category] != 0 then
call Tooltips2[PNumb].show(true)
call Tooltips1[PNumb].control.move(150, 0, Tooltips1[PNumb].control.zDepth)
call Tooltips2[PNumb].control.move(-150, 0, Tooltips2[PNumb].control.zDepth)
call Tooltips1[PNumb].control.refresh()
call Tooltips2[PNumb].control.refresh()
call Tooltips2[PNumb].setItem(CharacterWindow_SlotObject[PNumb][ButtonSlot[data].object.id.category])
else
call Tooltips1[PNumb].control.move(0, 0, Tooltips1[PNumb].control.zDepth)
call Tooltips1[PNumb].control.refresh()
call Tooltips2[PNumb].show(false)
set Tooltips2[PNumb].itmObject = -1
endif
set LastSelection = u
endif
endif
endif
set u = null
endif
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call RegisterUnitIndexEvent(Condition(function thistype.onDeindex), UnitIndexer.DEINDEX)
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SELECTED)
call TriggerAddCondition(t, Condition(function thistype.onSelect))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(t, Condition(function thistype.onOrder))
call TimerStart(CreateTimer(), 0.1, true, function thistype.checkSelection)
endmethod
endstruct
endlibrary
library ShopItemListLib initializer init
globals
ShopItemList DemoItems
ShopItemList WeaponBlade
ShopItemList WeaponBow
ShopItemList ArmorShield
ShopItemList ArmorHat
ShopItemList ArmorChest
ShopItemList ArmorPads
ShopItemList ArmorPants
ShopItemList ArmorBoots
ShopItemList ArmorGloves
ShopItemList BaseRedPotion
ShopItemList BaseBluePotion
ShopItemList BaseScroll
endglobals
public function FlushSoldItems takes nothing returns nothing
call BaseRedPotion.releaseSoldItems()
call BaseBluePotion.releaseSoldItems()
call ArmorHat.releaseSoldItems()
call ArmorChest.releaseSoldItems()
call ArmorPads.releaseSoldItems()
call ArmorGloves.releaseSoldItems()
call ArmorPants.releaseSoldItems()
call ArmorBoots.releaseSoldItems()
call ArmorShield.releaseSoldItems()
endfunction
private function init2 takes nothing returns nothing
local integer i
local ItemObject obj
set BaseRedPotion = ShopItemList.create()
call BaseRedPotion.addItemEx(1, 1, 1)
call BaseRedPotion.addItemEx(2, 1, 1)
call BaseRedPotion.addItemEx(3, 1, 1)
call BaseRedPotion.addItemEx(4, 1, 1)
call BaseRedPotion.addItemEx(5, 1, 1)
call BaseRedPotion.addItemEx(6, 1, 1)
call BaseRedPotion.addItemEx(7, 1, 1)
call BaseRedPotion.addItemEx(8, 1, 1)
call BaseRedPotion.addItemEx(9, 1, 1)
set BaseBluePotion = ShopItemList.create()
call BaseBluePotion.addItemEx(11, 1, 1)
call BaseBluePotion.addItemEx(12, 1, 1)
call BaseBluePotion.addItemEx(13, 1, 1)
call BaseBluePotion.addItemEx(14, 1, 1)
call BaseBluePotion.addItemEx(15, 1, 1)
call BaseBluePotion.addItemEx(16, 1, 1)
call BaseBluePotion.addItemEx(17, 1, 1)
call BaseBluePotion.addItemEx(18, 1, 1)
call BaseBluePotion.addItemEx(19, 1, 1)
set ArmorHat = ShopItemList.create()
call ArmorHat.addItemEx(ITEM_INDEX_EQUIPMENT+2, 1, 1)
call ArmorHat.addItemEx(ITEM_INDEX_EQUIPMENT+3, 1, 1)
call ArmorHat.addItemEx(ITEM_INDEX_EQUIPMENT+4, 1, 1)
call ArmorHat.addItemEx(ITEM_INDEX_EQUIPMENT+5, 1, 1)
call ArmorHat.addItemEx(ITEM_INDEX_EQUIPMENT+6, 1, 1)
call ArmorHat.addItemEx(ITEM_INDEX_EQUIPMENT+7, 1, 1)
call ArmorHat.addItemEx(ITEM_INDEX_EQUIPMENT+8, 1, 1)
call ArmorHat.addItemEx(ITEM_INDEX_EQUIPMENT+9, 1, 1)
call ArmorHat.addItemEx(ITEM_INDEX_EQUIPMENT+10, 1, 1)
call ArmorHat.addItemEx(ITEM_INDEX_EQUIPMENT+11, 1, 1)
set ArmorChest = ShopItemList.create()
call ArmorChest.addItemEx(ITEM_INDEX_EQUIPMENT+13, 1, 1)
call ArmorChest.addItemEx(ITEM_INDEX_EQUIPMENT+14, 1, 1)
call ArmorChest.addItemEx(ITEM_INDEX_EQUIPMENT+15, 1, 1)
call ArmorChest.addItemEx(ITEM_INDEX_EQUIPMENT+16, 1, 1)
call ArmorChest.addItemEx(ITEM_INDEX_EQUIPMENT+17, 1, 1)
call ArmorChest.addItemEx(ITEM_INDEX_EQUIPMENT+18, 1, 1)
call ArmorChest.addItemEx(ITEM_INDEX_EQUIPMENT+19, 1, 1)
call ArmorChest.addItemEx(ITEM_INDEX_EQUIPMENT+20, 1, 1)
call ArmorChest.addItemEx(ITEM_INDEX_EQUIPMENT+21, 1, 1)
call ArmorChest.addItemEx(ITEM_INDEX_EQUIPMENT+22, 1, 1)
set ArmorPads = ShopItemList.create()
call ArmorPads.addItemEx(ITEM_INDEX_EQUIPMENT+24, 1, 1)
call ArmorPads.addItemEx(ITEM_INDEX_EQUIPMENT+25, 1, 1)
call ArmorPads.addItemEx(ITEM_INDEX_EQUIPMENT+26, 1, 1)
call ArmorPads.addItemEx(ITEM_INDEX_EQUIPMENT+27, 1, 1)
call ArmorPads.addItemEx(ITEM_INDEX_EQUIPMENT+28, 1, 1)
call ArmorPads.addItemEx(ITEM_INDEX_EQUIPMENT+29, 1, 1)
call ArmorPads.addItemEx(ITEM_INDEX_EQUIPMENT+30, 1, 1)
call ArmorPads.addItemEx(ITEM_INDEX_EQUIPMENT+31, 1, 1)
call ArmorPads.addItemEx(ITEM_INDEX_EQUIPMENT+32, 1, 1)
call ArmorPads.addItemEx(ITEM_INDEX_EQUIPMENT+33, 1, 1)
set ArmorGloves = ShopItemList.create()
call ArmorGloves.addItemEx(ITEM_INDEX_EQUIPMENT+35, 1, 1)
call ArmorGloves.addItemEx(ITEM_INDEX_EQUIPMENT+36, 1, 1)
call ArmorGloves.addItemEx(ITEM_INDEX_EQUIPMENT+37, 1, 1)
call ArmorGloves.addItemEx(ITEM_INDEX_EQUIPMENT+38, 1, 1)
call ArmorGloves.addItemEx(ITEM_INDEX_EQUIPMENT+39, 1, 1)
call ArmorGloves.addItemEx(ITEM_INDEX_EQUIPMENT+40, 1, 1)
call ArmorGloves.addItemEx(ITEM_INDEX_EQUIPMENT+41, 1, 1)
call ArmorGloves.addItemEx(ITEM_INDEX_EQUIPMENT+42, 1, 1)
call ArmorGloves.addItemEx(ITEM_INDEX_EQUIPMENT+43, 1, 1)
call ArmorGloves.addItemEx(ITEM_INDEX_EQUIPMENT+44, 1, 1)
set ArmorPants = ShopItemList.create()
call ArmorPants.addItemEx(ITEM_INDEX_EQUIPMENT+46, 1, 1)
call ArmorPants.addItemEx(ITEM_INDEX_EQUIPMENT+47, 1, 1)
call ArmorPants.addItemEx(ITEM_INDEX_EQUIPMENT+48, 1, 1)
call ArmorPants.addItemEx(ITEM_INDEX_EQUIPMENT+49, 1, 1)
call ArmorPants.addItemEx(ITEM_INDEX_EQUIPMENT+50, 1, 1)
call ArmorPants.addItemEx(ITEM_INDEX_EQUIPMENT+51, 1, 1)
call ArmorPants.addItemEx(ITEM_INDEX_EQUIPMENT+52, 1, 1)
call ArmorPants.addItemEx(ITEM_INDEX_EQUIPMENT+53, 1, 1)
call ArmorPants.addItemEx(ITEM_INDEX_EQUIPMENT+54, 1, 1)
call ArmorPants.addItemEx(ITEM_INDEX_EQUIPMENT+55, 1, 1)
set ArmorBoots = ShopItemList.create()
call ArmorBoots.addItemEx(ITEM_INDEX_EQUIPMENT+57, 1, 1)
call ArmorBoots.addItemEx(ITEM_INDEX_EQUIPMENT+58, 1, 1)
call ArmorBoots.addItemEx(ITEM_INDEX_EQUIPMENT+59, 1, 1)
call ArmorBoots.addItemEx(ITEM_INDEX_EQUIPMENT+60, 1, 1)
call ArmorBoots.addItemEx(ITEM_INDEX_EQUIPMENT+61, 1, 1)
call ArmorBoots.addItemEx(ITEM_INDEX_EQUIPMENT+62, 1, 1)
call ArmorBoots.addItemEx(ITEM_INDEX_EQUIPMENT+63, 1, 1)
call ArmorBoots.addItemEx(ITEM_INDEX_EQUIPMENT+64, 1, 1)
call ArmorBoots.addItemEx(ITEM_INDEX_EQUIPMENT+65, 1, 1)
call ArmorBoots.addItemEx(ITEM_INDEX_EQUIPMENT+66, 1, 1)
set ArmorShield = ShopItemList.create()
call ArmorShield.addItemEx(ITEM_INDEX_EQUIPMENT+68, 1, 1)
call ArmorShield.addItemEx(ITEM_INDEX_EQUIPMENT+69, 1, 1)
call ArmorShield.addItemEx(ITEM_INDEX_EQUIPMENT+70, 1, 1)
call ArmorShield.addItemEx(ITEM_INDEX_EQUIPMENT+71, 1, 1)
call ArmorShield.addItemEx(ITEM_INDEX_EQUIPMENT+72, 1, 1)
call ArmorShield.addItemEx(ITEM_INDEX_EQUIPMENT+73, 1, 1)
call ArmorShield.addItemEx(ITEM_INDEX_EQUIPMENT+74, 1, 1)
call ArmorShield.addItemEx(ITEM_INDEX_EQUIPMENT+75, 1, 1)
call ArmorShield.addItemEx(ITEM_INDEX_EQUIPMENT+76, 1, 1)
call ArmorShield.addItemEx(ITEM_INDEX_EQUIPMENT+77, 1, 1)
set WeaponBlade = ShopItemList.create()
call WeaponBlade.addItemEx(ITEM_INDEX_EQUIPMENT+79, 1, 1)
call WeaponBlade.addItemEx(ITEM_INDEX_EQUIPMENT+80, 1, 1)
call WeaponBlade.addItemEx(ITEM_INDEX_EQUIPMENT+81, 1, 1)
call WeaponBlade.addItemEx(ITEM_INDEX_EQUIPMENT+82, 1, 1)
call WeaponBlade.addItemEx(ITEM_INDEX_EQUIPMENT+83, 1, 1)
call WeaponBlade.addItemEx(ITEM_INDEX_EQUIPMENT+84, 1, 1)
call WeaponBlade.addItemEx(ITEM_INDEX_EQUIPMENT+85, 1, 1)
call WeaponBlade.addItemEx(ITEM_INDEX_EQUIPMENT+86, 1, 1)
call WeaponBlade.addItemEx(ITEM_INDEX_EQUIPMENT+87, 1, 1)
call WeaponBlade.addItemEx(ITEM_INDEX_EQUIPMENT+88, 1, 1)
set WeaponBow = ShopItemList.create()
call WeaponBow.addItemEx(ITEM_INDEX_EQUIPMENT+90, 1, 1)
call WeaponBow.addItemEx(ITEM_INDEX_EQUIPMENT+91, 1, 1)
call WeaponBow.addItemEx(ITEM_INDEX_EQUIPMENT+92, 1, 1)
call WeaponBow.addItemEx(ITEM_INDEX_EQUIPMENT+93, 1, 1)
call WeaponBow.addItemEx(ITEM_INDEX_EQUIPMENT+94, 1, 1)
call WeaponBow.addItemEx(ITEM_INDEX_EQUIPMENT+95, 1, 1)
call WeaponBow.addItemEx(ITEM_INDEX_EQUIPMENT+96, 1, 1)
call WeaponBow.addItemEx(ITEM_INDEX_EQUIPMENT+97, 1, 1)
call WeaponBow.addItemEx(ITEM_INDEX_EQUIPMENT+98, 1, 1)
call WeaponBow.addItemEx(ITEM_INDEX_EQUIPMENT+99, 1, 1)
set BaseScroll = ShopItemList.create()
set obj = ItemObject.create(ITEM_INDEX_SCROLLS+1, 1, 1, WorldBounds.maxX, WorldBounds.maxY)
call obj.setScrollStats(GetRandomInt(1, 7))
call BaseScroll.addItem(obj)
set i = 0
loop
exitwhen i >= 19
set obj = ItemObject.create(ITEM_INDEX_SCROLLS+GetRandomInt(1, DUNGEON_VARIATION), 1, 1, WorldBounds.maxX, WorldBounds.maxY)
call obj.setScrollStats(GetRandomInt(0, SCROLL_VARIATION))
call BaseScroll.addItem(obj)
set i = i + 1
endloop
call DestroyTimer(GetExpiredTimer())
endfunction
private function init takes nothing returns nothing
call TimerStart(CreateTimer(), 0, false, function init2)
endfunction
endlibrary
library ShopMerchants initializer init uses CharacterWindow, UpgradeMenu
globals
CustomText array NPCNameTag
integer NPCNameTagCount = 0
unit array SelectedMerchant
public unit array CurrentMerchant
public timer array CheckTimer
group Merchants = CreateGroup()
group NPCs = CreateGroup()
endglobals
public function check takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer i = GetTimerData(t)
local real dx
local real dy
if CurrentMerchant[i] != null then
set dx = GetUnitX(CurrentMerchant[i])-GetUnitX(MainUnit[i])
set dy = GetUnitY(CurrentMerchant[i])-GetUnitY(MainUnit[i])
if dx*dx+dy*dy > MERCHANT_BUY_RANGE then
set CurrentMerchant[i] = null
if ShopUI[i].visible then
call ShopUI[i].show(false)
endif
if UpgradeMenu_Main[i].visible then
call UpgradeMenu_CloseWindow(i)
endif
endif
endif
set t = null
endfunction
private function onSelect takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer uid = GetUnitTypeId(u)
local player p = GetTriggerPlayer()
local integer pid = GetPlayerId(p)
local boolean b
local boolean b2
local string s
local real dx
local real dy
if MainUnit[pid] != null and (IsUnitInGroup(u, Merchants) or IsUnitInGroup(u, NPCs)) then
set dx = GetUnitX(u)-GetUnitX(MainUnit[pid])
set dy = GetUnitY(u)-GetUnitY(MainUnit[pid])
if dx*dx+dy*dy > MERCHANT_BUY_RANGE then
call DisplayTimedTextToPlayer(p, 0, 0, 1., "Too far from the NPC.")
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[pid], true)
endif
else
set SelectedMerchant[pid] = u
call IssueImmediateOrder(MainUnit[pid], "stop")
call SetUnitFacing(MainUnit[pid], Atan2(dy, dx)*bj_RADTODEG)
endif
else
set SelectedMerchant[pid] = null
endif
set u = null
return false
endfunction
private function onSell takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer iid
local integer pid
local boolean b
local player p
local string s
local item itm
set itm = GetSoldItem()
set iid = GetItemTypeId(itm)
set p = GetOwningPlayer(GetBuyingUnit())
set pid = GetPlayerId(p)
set b = false
if iid == 'I00H' then
call ShopUI[pid].setItemList(WeaponBlade)
set b = true
elseif iid == 'I00I' then
call ShopUI[pid].setItemList(ArmorChest)
set b = true
elseif iid == 'I01D' then
call ShopUI[pid].setItemList(ArmorPads)
set b = true
elseif iid == 'I01I' then
call ShopUI[pid].setItemList(ArmorPants)
set b = true
elseif iid == 'I01M' then
call ShopUI[pid].setItemList(ArmorHat)
set b = true
elseif iid == 'I01S' then
call ShopUI[pid].setItemList(ArmorBoots)
set b = true
elseif iid == 'I01W' then
call ShopUI[pid].setItemList(ArmorGloves)
set b = true
elseif iid == 'I025' then
call ShopUI[pid].setItemList(ArmorShield)
set b = true
elseif iid == 'I019' then
call ShopUI[pid].setItemList(DemoItems)
set b = true
elseif iid == 'I001' then
call ShopUI[pid].setItemList(BaseBluePotion)
set b = true
elseif iid == 'I003' then
call ShopUI[pid].setItemList(WeaponBow)
set b = true
elseif iid == 'I000' then
call ShopUI[pid].setItemList(BaseRedPotion)
set b = true
elseif iid == 'I004' then
call ShopUI[pid].setItemList(BaseScroll)
set b = true
elseif iid == 'I002' then
call ShopUI[pid].setItemList(WeaponBlade)
set b = true
elseif iid == 'I00K' then
call ShopUI[pid].show(false)
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[pid], true)
endif
endif
if b then
set ShopMerchants_CurrentMerchant[pid] = u
if ShopUI[pid].visible then
call ShopUI[pid].closeContextMenu()
else
if not Bag[pid].visible then
call Bag[pid].show(true)
call Bag[pid].panel.refresh()
endif
call ShopUI[pid].show(true)
call ShopUI[pid].panel.refresh()
endif
if CharacterWindow_Visible[pid] then
call CharacterWindow_Show(pid, false)
endif
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[pid], true)
endif
elseif iid == 'I005' then
set CurrentMerchant[pid] = u
call UpgradeMenu_Main[pid].show(true)
call UpgradeMenu_Main[pid].refresh()
if not Bag[pid].visible then
call Bag[pid].show(true)
call Bag[pid].panel.refresh()
endif
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[pid], true)
endif
endif
set u = null
return false
endfunction
private function CreateNameTag takes nothing returns boolean
local unit u = GetFilterUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local boolean interior = RectContainsCoords(gg_rct_InteriorArea, x, y)
if RectContainsCoords(gg_rct_InitArea, x, y) or interior then
if interior then
set NPCNameTag[NPCNameTagCount] = CustomText.create(GetUnitName(u), x, y, 180., ITEM_NAMETAG_SIZE, 0.5)
else
set NPCNameTag[NPCNameTagCount] = CustomText.create(GetUnitName(u), x, y, 130., ITEM_NAMETAG_SIZE, 0.5)
endif
call NPCNameTag[NPCNameTagCount].setColor(NPC_TAG_COLOR_R, NPC_TAG_COLOR_G, NPC_TAG_COLOR_B, 255)
set NPCNameTagCount = NPCNameTagCount + 1
endif
set u = null
return false
endfunction
private function init takes nothing returns nothing
local group g = CreateGroup()
local trigger t = CreateTrigger()
local integer i = 0
loop
exitwhen i > 3
set CheckTimer[i] = NewTimerEx(i)
call TimerStart(CheckTimer[i], 0.1, true, function check)
set i = i + 1
endloop
call GroupAddUnit(Merchants, gg_unit_h011_0007)
call GroupAddUnit(Merchants, gg_unit_h013_0008)
call GroupAddUnit(Merchants, gg_unit_h015_0002)
call GroupAddUnit(Merchants, gg_unit_h016_0005)
call GroupAddUnit(Merchants, gg_unit_h012_0017)
call GroupAddUnit(Merchants, gg_unit_h00N_0011)
call GroupAddUnit(Merchants, gg_unit_h02X_0082)
call GroupAddUnit(NPCs, gg_unit_h00Z_0014)
call GroupAddUnit(NPCs, gg_unit_h00O_0012)
call GroupAddUnit(NPCs, gg_unit_h00W_0016)
call GroupAddUnit(NPCs, gg_unit_h00Y_0015)
call GroupAddUnit(NPCs, gg_unit_h00V_0013)
call GroupEnumUnitsOfPlayer(g, PASSIVE, Filter(function CreateNameTag))
call DestroyGroup(g)
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SELECTED)
call TriggerAddCondition(t, Condition(function onSelect))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SELL_ITEM)
call TriggerAddCondition(t, Condition(function onSell))
endfunction
endlibrary
library CharacterWindow initializer init uses TimerUtils, Skill
///! runtextmacro DECLARE_ARRAY_2D("", "PanelPlatform", "CharSlot", "8", "10")
///! runtextmacro DECLARE_ARRAY_2D("public", "integer", "SlotObject", "8", "10")
//! textmacro CreateSkillXPObject takes CODE, NAME, FILEPATH, EXTENSION
//! external ObjectMerger w3b YTlb $CODE$ bnam "(SkillXP) $NAME$" bfxr -1 bfil ".mdl" boch 0 btxf "$FILEPATH$$NAME$$EXTENSION$" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
/*
//! runtextmacro CreateSkillXPObject ("SXP0", "0", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXP1", "1", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXP2", "2", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXP3", "3", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXP4", "4", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXP5", "5", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXP6", "6", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXP7", "7", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXP8", "8", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXP9", "9", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXPA", "10", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXPB", "11", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXPC", "12", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXPD", "13", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXPE", "14", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXPF", "15", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXPG", "16", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXPH", "17", "war3mapImported\skillexp", ".blp")
//! runtextmacro CreateSkillXPObject ("SXPI", "18", "war3mapImported\skillexp", ".blp")
*/
//! textmacro CreateStatsTextObject takes CODE, NAME, FILEPATH, EXTENSION
//! external ObjectMerger w3b YTlb $CODE$ bnam "(StatsText) $NAME$" bfxr -1 bfil ".mdl" boch 0 btxf "$FILEPATH$$NAME$$EXTENSION$" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
/*
//! runtextmacro CreateStatsTextObject ("ST01", "Name", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST02", "Class", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST03", "Level", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST04", "EXP", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST05", "Fame", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST06", "Title", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST07", "Health Point", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST08", "Mana Point", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST09", "DuelsWon", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0A", "MonsterKilled", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0B", "PlayTime", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0C", "Strength", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0D", "Dexterity", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0E", "Wisdom", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0F", "Fortitude", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0G", "PhysicalDamage", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0H", "MagicDamage", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0I", "PhysicalDefense", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0J", "MagicDefense", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0K", "Critical Chance", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0L", "Critical Power", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0M", "Block Chance", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0N", "Evasion", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0O", "Accuracy", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0P", "Knockback", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0Q", "Knockback Resistance", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0R", "Interruption Chance", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0S", "Interruption Resistance", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0T", "Stun Chance", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0U", "Stun Resistance", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0V", "Holy Element", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0W", "Dark Element", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0X", "Fire Element", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0Y", "Fire Resistance", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST0Z", "Water Element", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST10", "Water Resistance", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST11", "Earth Element", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST12", "Earth Resistance", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST13", "Wind Element", "war3mapImported\StatText", ".blp")
//! runtextmacro CreateStatsTextObject ("ST14", "Wind Resistance", "war3mapImported\StatText", ".blp")
*/
globals
private integer TempInt = 0
public trigger SkillWindowTrigger = CreateTrigger()
integer array SkillPoint
Panel array CharWindowGeneral
Panel array CharWindowStatistic
Panel array CharWindowSkill
Panel array CharWindowEquipment
public PanelTextEx array Title
public PanelTextEx array SubTitle
public PanelTextEx array Name
public PanelTextEx array Rank
public PanelTextEx array Overall
public PanelTextEx array ElementFire
public PanelTextEx array ElementEarth
public PanelTextEx array ElementWater
public PanelTextEx array ElementWind
public PanelModel array Model
public timer array UpdateTimer
public timer array DoubleTimer
public integer array SelectIndex
public integer array TabIndex
public integer array SkillTabIndex
public integer array SkillScrollIndex
public integer array StatsScrollIndex
public boolean array Visible
public boolean array ContextVisible
public boolean array TierLearned[4][9]
public PanelPlatform array SkillNotifBG
public PanelPlatform array AttNotifBG
public PanelTextEx array SkillNotifText
public PanelTextEx array AttNotifText
public PanelPlatform array ExitButton
public PanelPlatform array Background
public PanelPlatform array Selection
public PanelPlatform array ContextMenu
public PanelPlatform array ContextButton[4][4]
public PanelPlatform array TabButton[4][3]
public PanelPlatform array Slot[4][10]
public PanelPlatform array SlotRarity[4][10]
public PanelPlatform array SkillArrowLeft
public PanelPlatform array SkillArrowRight
public PanelPlatform array SkillArrowUp
public PanelPlatform array SkillArrowDown
public PanelPlatform array StatsArrowUp
public PanelPlatform array StatsArrowDown
public PanelTextEx array SkillTabName
public PanelPlatform array StatsText[4][36]
public PanelPlatform array AttrIncButton[4][4]
public PanelTextEx array AttrValText[4][5]
private PanelTextTag array StatsValue
private PanelTextTag array StatsValue2
public integer array SlotIndex
public integer array SlotOwner
public integer array SkillButtonOwner
public integer array StatsButtonOwner
public ItemObject array SlotObject[4][10]
public integer array AttButtonOwner
public integer array ContextButtonOwner
public integer array ContextButtonIndex
public integer array TabButtonOwner
public integer array TabButtonIndex
public integer array ExitButtonOwner
public integer array BackgroundOwner
public string array SubTabNames[4][3]
public SkillRow array SkillRows[4][3]
public integer array SkillCount[4][3]
private BJObjectId array SkillIconId
private constant integer SKILL_PROGRESS_BAR_COUNT = 18
private constant integer STATS_ITEMS_PER_PAGE = 9
private SkillRow array IconIndex
public constant real CONTEXT_X_CLOSE = 104.0-58.0
public constant real CONTEXT_X_OPEN = 191.0-58.0
public constant real ANIM_SPEED = 10.
endglobals
function GetOverallPower takes Combatant c returns integer
local real result = 0
local PlayerSkill node
local SkillData sData
if c.pid < 4 then
if c == Fighter[c.pid] then
set result = GetOverallPower(PetFighter[c.pid])
endif
set result = result + I2R(Level[c.pid])/100.*25.
set result = result + I2R(Strength[c.pid])/100.*33.
set result = result + I2R(Dexterity[c.pid])/100.*33.
set result = result + I2R(Wisdom[c.pid])/100.*33.
set result = result + I2R(Fortitude[c.pid])/100.*33.
set node = Skills[c.pid].next
loop
exitwhen node.head or node == 0
if node.level > 0 then
set sData = node.id
if sData.active then
set result = result + 15.*node.level
else
set result = result + 25.*node.level
endif
endif
set node = node.next
endloop
else
set result = result + I2R(c.level)/100.*25.
endif
if c.missileHoming then
set result = result + I2R(Level[c.pid])*3.
endif
if c.missilePiercing then
set result = result + I2R(Level[c.pid])*5.
endif
set result = result + c.missileSpeed/25.*1.
set result = result + c.missileTurn/PanelCore_HP*5.
set result = result + c.dmgAoE/50.*2.
set result = result + c.attackRange/300.*1.
set result = result + (5.-c.attackRate)*8.
set result = result + (c.physicDmgMin+c.physicDmgMax)/2./15.*20.
set result = result + (c.magicDmgMin+c.magicDmgMax)/2./7.5*20.
set result = result + c.physicDefense/5.*10.
set result = result + c.magicDefense/2.5*10.
set result = result + c.dmgReflect/10.*3.
set result = result + c.blockRate/0.1*5.
set result = result + c.criticalRate/0.1*7.
set result = result + c.criticalPower/0.1*4.
set result = result + RMaxBJ(c.evasionRate, 0)/0.1*5.
set result = result + c.accuracy/0.1*2.
set result = result + c.knockback/16.*5.
set result = result + c.interrupt/0.1*4.
set result = result + c.stun/0.1*5.
set result = result + c.hpMax/250.*2.
set result = result + c.spMax/50.*2.
set result = result + c.hpSteal/5.*2.
set result = result + c.spSteal/1.*2.
set result = result + c.fireElement/5.*2.
set result = result + c.waterElement/5.*2.
set result = result + c.earthElement/5.*2.
set result = result + c.windElement/5.*2.
return R2I(result-100.)
endfunction
function RefreshStatsValues takes integer id returns nothing
//StatsScrollIndex
local string s = ""
local integer i = 0
local integer exit
local Combatant c = Fighter[id]
loop
exitwhen i >= 9
if i == 0 then // name
set s = s + ": " + CharacterName[i] + "\n"
elseif i == 1 then // class
set s = s + ": " + GetUnitName(MainUnit[id]) + "\n"
elseif i == 2 then// level
set s = s + ": " + I2S(Level[id]) + "\n"
elseif i == 3 then // exp
set s = s + ": " + I2S(R2I(EXPCurrent[id])) + "/"+ I2S(R2I(EXPTarget[id])) + "\n"
elseif i == 4 then // fame
set s = s + ": 0" + "\n"
elseif i == 5 then // title
set s = s + ": Unknown" + "\n"
elseif i == 6 then // duels won
set s = s + ": 0" + "\n"
elseif i == 7 then // monsters killed
set s = s + ": 0" + "\n"
elseif i == 8 then // play time
set s = s + ": 00:00:00" + "\n"
endif
set i = i + 1
endloop
call StatsValue[id].setText(s, 0.017)
call StatsValue[id].refresh()
set i = StatsScrollIndex[id]
set exit = i + STATS_ITEMS_PER_PAGE
set s = ""
loop
exitwhen i >= exit
if i == 9 then // hp
set s = s + ": " + I2S(R2I(c.hp)) + "/"+ I2S(R2I(c.hpMax)) + " |cff00ff00+" + R2S(Regeneration.get(MainUnit[id], true)) + "/s|r\n"
elseif i == 10 then // mp
set s = s + ": " + I2S(R2I(c.sp)) + "/"+ I2S(R2I(c.spMax)) + " |cff00ff00+" + R2S(Regeneration.get(MainUnit[id], false)) + "/s|r\n"
elseif i == 11 then // strength
set s = s + ": " + I2S(Strength[id]) + "\n"
elseif i == 12 then // dexterity
set s = s + ": " + I2S(Dexterity[id]) + "\n"
elseif i == 13 then // wisdom
set s = s + ": " + I2S(Wisdom[id]) + "\n"
elseif i == 14 then // fortitude
set s = s + ": " + I2S(Fortitude[id]) + "\n"
elseif i == 15 then // physical damage
set s = s + ": " + I2S(R2I(c.physicDmgMin)) + "-"+ I2S(R2I(c.physicDmgMax)) + "\n"
elseif i == 16 then // magic damage
set s = s + ": " + I2S(R2I(c.magicDmgMin)) + "-"+ I2S(R2I(c.magicDmgMax)) + "\n"
elseif i == 17 then // physical defense
set s = s + ": " + I2S(R2I(c.physicDefense)) + "\n"
elseif i == 18 then // magic defense
set s = s + ": " + I2S(R2I(c.magicDefense)) + "\n"
elseif i == 19 then // critical chance
set s = s + ": " + I2S(R2I(c.criticalRate*100.)) + "%" + "\n"
elseif i == 20 then // critical power
set s = s + ": " + I2S(R2I(c.criticalPower*100.)) + "%" + "\n"
elseif i == 21 then // block chance
set s = s + ": " + I2S(R2I(c.blockRate*100.)) + "%" + "\n"
elseif i == 22 then // evasion
set s = s + ": " + I2S(R2I(c.evasionRate*100.)) + "%" + "\n"
elseif i == 23 then // accuracy
set s = s + ": " + I2S(R2I(c.accuracy*100.)) + "\n"
elseif i == 24 then // knockback
set s = s + ": " + I2S(R2I(c.knockback)) + "\n"
elseif i == 25 then // knockback resistance
set s = s + ": " + I2S(R2I(c.knockbackResist)) + "\n"
elseif i == 26 then // interrupt
set s = s + ": " + I2S(R2I(c.interrupt*100.)) + "%" + "\n"
elseif i == 27 then // interrupt resistance
set s = s + ": " + I2S(R2I(c.interruptResist*100.)) + "%\n"
elseif i == 28 then // stun
set s = s + ": " + I2S(R2I(c.stun*100.)) + "%" + "\n"
elseif i == 29 then // stun resistance
set s = s + ": " + I2S(R2I(c.stunResist*100.)) + "%\n"
elseif i == 30 then // holy element
set s = s + ": " + R2SW(c.holyElement, 3, 1) + "\n"
elseif i == 31 then // dark element
set s = s + ": " + R2SW(c.darkElement, 3, 1) + "\n"
elseif i == 32 then // fire element
set s = s + ": " + R2SW(c.fireElement, 3, 1) + "\n"
elseif i == 33 then // fire resistance
set s = s + ": " + R2SW(c.fireElementResist, 3, 1) + "\n"
elseif i == 34 then // water element
set s = s + ": " + R2SW(c.waterElement, 3, 1) + "\n"
elseif i == 35 then // water resistance
set s = s + ": " + R2SW(c.waterElementResist, 3, 1) + "\n"
elseif i == 36 then // earth element
set s = s + ": " + R2SW(c.earthElement, 3, 1) + "\n"
elseif i == 37 then // earth resistance
set s = s + ": " + R2SW(c.earthElementResist, 3, 1) + "\n"
elseif i == 38 then // wind element
set s = s + ": " + R2SW(c.windElement, 3, 1) + "\n"
elseif i == 39 then // wind resistance
set s = s + ": " + R2SW(c.windElementResist, 3, 1) + "\n"
endif
set i = i + 1
endloop
call StatsValue2[id].setText(s, 0.017)
call StatsValue2[id].refresh()
endfunction
public function ScrollSkillMenu takes integer id, integer i returns nothing
local SkillRow node
set i = SkillScrollIndex[id] + i
if i > SkillCount[id][SkillTabIndex[id]]-4 then
set i = SkillCount[id][SkillTabIndex[id]]-4
endif
if i < 0 then
set i = 0
endif
if i != SkillScrollIndex[id] then
set SkillScrollIndex[id] = i
set node = SkillRows[id][SkillTabIndex[id]].first
loop
exitwhen node == 0
if node.index < SkillScrollIndex[id] or node.index > SkillScrollIndex[id]+3 then
call node.background.show(false)
call node.icon.show(false)
call node.textName.show(false)
call node.textLevel.show(false)
call node.textMaster.show(false)
call node.exp.show(false)
else
call node.background.show(true)
call node.icon.show(true)
call node.textName.show(true)
call node.textLevel.show(true)
call node.textMaster.show(true)
call node.exp.show(true)
call node.background.move(node.background.xOffset, 43-67.*node.index+67.*SkillScrollIndex[id], node.background.level)
call node.icon.move(node.icon.xOffset, node.background.yOffset+2, node.icon.level)
call node.plus.move(node.plus.xOffset, node.icon.yOffset, node.plus.level)
call node.textName.move(node.textName.xOffset, node.background.yOffset+12., 2)
call node.textLevel.move(node.textLevel.xOffset, node.textName.yOffset, 2)
call node.textMaster.move(node.textMaster.xOffset, node.background.yOffset-7., 2)
call node.exp.move(node.exp.xOffset, node.background.yOffset-8., node.exp.level)
call node.background.refresh()
call node.icon.refresh()
call node.textName.refresh()
call node.textLevel.refresh()
call node.textMaster.refresh()
call node.exp.refresh()
endif
set node = node.next
endloop
endif
call EvaluateSkillList(id)
endfunction
struct SkillRow extends array
integer pid
integer index
boolean learnable
SkillData id
PlayerSkill skill
PanelPlatform background
PanelPlatform icon
PanelPlatform plus
PanelPlatform exp
PanelTextEx textName
PanelTextEx textLevel
PanelTextEx textMaster
implement Queue
method setLevel takes integer level returns nothing
call textLevel.setText("Lv. " + I2S(level), FONTSTYLE_FrizQTShaded)
call textLevel.show(textLevel.visible)
call textLevel.refresh()
endmethod
method setMastery takes real value returns nothing
local BJObjectId id
local integer i
if skill.level >= MAXIMUM_ACTIVE_SKILL_LEVEL then
set skill.mastery = 100
call textMaster.setText("Max.", FONTSTYLE_FrizQTShaded)
call textMaster.show(textLevel.visible)
call textMaster.refresh()
set exp.texture = 'SXPI'
call exp.refresh()
else
if (value >= 100) then
set value = 0
call Learn(pid, this.id)
if Tooltips1[pid].control.visible and Tooltips1[pid].skill == PlayerSkillData[pid][skill] then
call Tooltips1[pid].setSkill(Tooltips1[pid].skill)
endif
call ScrollSkillMenu(pid, 0)
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 5., "|cff9cf0ff" + this.id.name + " skill level has increased!|r")
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\HolyAwakening.mdx", MainUnit[pid], "origin"))
endif
set id = BJObjectId('SXP0')
set i = R2I(value / 100. * I2R(SKILL_PROGRESS_BAR_COUNT))
loop
exitwhen i == 0
set id = id.plus_1()
set i = i - 1
endloop
set skill.mastery = value
call textMaster.setText(R2SW(value-0.05, 2, 1) + "%", FONTSTYLE_FrizQTShaded)
call textMaster.show(textLevel.visible)
call textMaster.refresh()
set exp.texture = id
call exp.refresh()
endif
endmethod
endstruct
public function ScrollStatsMenu takes integer id, integer i returns nothing
local integer j
local integer index
local player p = Player(id)
local real y
set i = StatsScrollIndex[id] + i
if i > 30-STATS_ITEMS_PER_PAGE then
set i = 30-STATS_ITEMS_PER_PAGE
endif
if i < 9 then
set i = 9
endif
if i != StatsScrollIndex[id] then
set StatsScrollIndex[id] = i
set j = 9
set index = -1
loop
exitwhen j == 30
if j >= StatsScrollIndex[id] and j < StatsScrollIndex[id] + STATS_ITEMS_PER_PAGE then
set index = index + 1
call StatsText[id][j].move(StatsText[id][j].xOffset, -63-12*index, StatsText[id][j].level)
call StatsText[id][j].show(true)
call StatsText[id][j].refresh()
else
call StatsText[id][j].show(false)
endif
set j = j + 1
endloop
call RefreshStatsValues(id)
endif
endfunction
public function OpenSkillTab takes integer id, integer i returns nothing
local SkillRow node
if i != SkillTabIndex[id] then
set SkillScrollIndex[id] = 0
if i > 2 then
set i = 0
elseif i < 0 then
set i = 2
endif
set node = SkillRows[id][SkillTabIndex[id]].first
loop
exitwhen node == 0
call node.background.show(false)
call node.icon.show(false)
call node.plus.show(false)
call node.textName.show(false)
call node.textLevel.show(false)
call node.textMaster.show(false)
call node.exp.show(false)
set node = node.next
endloop
set SkillTabIndex[id] = i
call SkillTabName[id].setText(SubTabNames[id][SkillTabIndex[id]], FONTSTYLE_FrizQTShaded)
call SkillTabName[id].move(-2.-SkillTabName[id].width/2, SkillTabName[id].yOffset, 1)
call SkillTabName[id].refresh()
set node = SkillRows[id][SkillTabIndex[id]].first
loop
exitwhen node == 0
call node.background.show(true)
call node.icon.show(true)
call node.textName.show(true)
call node.textLevel.show(true)
call node.textMaster.show(true)
call node.exp.show(true)
call node.background.refresh()
call node.icon.refresh()
call node.textName.refresh()
call node.textLevel.refresh()
call node.textMaster.refresh()
call node.exp.refresh()
set node = node.next
endloop
set SkillScrollIndex[id] = -1
call ScrollSkillMenu(id, 0)
endif
endfunction
private function onSelect2 takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer data = GetUnitUserData(u)
local player p = GetTriggerPlayer()
local integer i
local integer uid
local integer tier
local SkillData sData
if SkillButtonOwner[data] != 0 then
set i = SkillButtonOwner[data] - 1
set uid = GetUnitTypeId(u)
if uid == 'e002' then // left
call OpenSkillTab(i, SkillTabIndex[i]-1)
elseif uid == 'e003' then // right
call OpenSkillTab(i, SkillTabIndex[i]+1)
elseif uid == 'e004' then // up
call ScrollSkillMenu(i, -1)
elseif uid == 'e005' then // down
call ScrollSkillMenu(i, 1)
else // skill icon
if ShortcutBar_SkillSelection[i].visible then
call ShortcutBar_SkillSelection[i].clear()
set ShortcutBar_SelectIndex[i] = -1
call ShortcutBar_SkillSelection[i].show(false)
endif
if IconIndex[data].learnable then
call AddSkillPoint(i, -1)
call Learn(i, IconIndex[data].id)
set tier = IconIndex[data].id.tier
if tier < 6 then
set TierLearned[i][tier] = true
endif
if Tooltips1[i].control.visible and Tooltips1[i].skill == PlayerSkillData[i][IconIndex[data].id] then
call Tooltips1[i].setSkill(Tooltips1[i].skill)
endif
if Locale == Player(i) then
call SkillLearnSound.play(0, 0, 0, 100)
else
call SkillLearnSound.play(0, 0, 0, 0)
endif
call ScrollSkillMenu(i, 0)
endif
endif
if Locale == p then
call SelectUnit(u, false)
call SelectUnit(Controller[i], true)
endif
elseif StatsButtonOwner[data] != 0 then
set i = StatsButtonOwner[data] - 1
set uid = GetUnitTypeId(u)
if uid == 'e004' then // up
call ScrollStatsMenu(i, -1)
elseif uid == 'e005' then // down
call ScrollStatsMenu(i, 1)
endif
if Locale == p then
call SelectUnit(u, false)
call SelectUnit(Controller[i], true)
endif
endif
set u = null
return false
endfunction
public function OpenContext takes integer i, boolean b returns nothing
local integer j
//if b != ContextVisible[i] then
set ContextVisible[i] = b
call ContextMenu[i].show(b)
if b then
call ContextMenu[i].move(Slot[i][SelectIndex[i]].xOffset+75, Slot[i][SelectIndex[i]].yOffset-79, ContextMenu[i].level)
call ContextMenu[i].refresh()
set j = 0
loop
exitwhen j == 3
call ContextButton[i][j].show(true)
call ContextButton[i][j].move(ContextMenu[i].xOffset, ContextMenu[i].yOffset+75-25*j, ContextMenu[i].level+1)
call ContextButton[i][j].refresh()
set j = j + 1
endloop
else
set SelectIndex[i] = 0
call Selection[i].show(false)
set j = 0
loop
exitwhen j == 3
call ContextButton[i][j].show(false)
set j = j + 1
endloop
endif
//endif
endfunction
public function Show takes integer i, boolean b returns nothing
local player p = Player(i)
//if Visible[i] != b then
if IsKeyVerified[i] or not b then
call CharWindowGeneral[i].show(b)
call CharWindowEquipment[i].show(b and TabIndex[i] == 0)
call CharWindowSkill[i].show(b and TabIndex[i] == 1)
call CharWindowStatistic[i].show(b and TabIndex[i] == 2)
if b and not Visible[i] then
if Locale == p then
call TooltipsDisplaySound.play(0, 0, 0, 100)
else
call TooltipsDisplaySound.play(0, 0, 0, 0)
endif
else
call OpenContext(i, false)
endif
set Visible[i] = b
call CharWindowGeneral[i].refresh()
call CharWindowEquipment[i].refresh()
call CharWindowSkill[i].refresh()
call CharWindowStatistic[i].refresh()
endif
endfunction
public function OpenTab takes integer id, integer i returns nothing
if i != TabIndex[id] then
set TabIndex[id] = i
call Show(id, Visible[id])
call OpenContext(id, false)
endif
endfunction
public function Detach takes integer i, integer slot returns nothing
local Inventory bag = Inventory_InventoryIndex[i]
local ItemObject obj
if bag.addItem(SlotObject[i][slot]) then
set obj = SlotObject[i][slot]
if obj.attachment != null then
call DestroyEffect(obj.attachment)
set obj.attachment = null
set Fighter[i].missile2 = ""
endif
set SlotObject[i][slot] = 0
set Slot[i][slot].texture = 'BSAL'
call Slot[i][slot].show(false)
call SlotRarity[i][slot].show(false)
call OpenContext(i, false)
call Inventory.RemoveBonus(Fighter[i], obj)
else
call SlotObject[i][slot].show(false)
endif
if Tooltips2[i].control.visible then
call Tooltips2[i].show(false)
call Tooltips1[i].control.move(0, 0, 0)
call Tooltips1[i].control.refresh()
endif
endfunction
public function AttachEx takes integer i, ItemObject obj returns nothing
local integer category = obj.id.category
local Combatant c = Fighter[i]
if obj.attachment == null and StringLength(obj.model) > 0 and (obj.id.category == Items.RIGHT_HAND or obj.id.category == Items.LEFT_HAND and obj.id.class != "Shield") then
set c.missile2 = obj.model + c.attachSize + ".mdx"
set obj.attachment = AddSpecialEffectTarget(c.missile2, MainUnit[i], c.attachPoint+obj.modelPt)
endif
call Inventory.ApplyBonus(c, obj)
set SlotObject[i][category] = obj
set Slot[i][category].texture = obj.id.texture
call Slot[i][category].show(true)
call SetUnitVertexColor(SlotRarity[i][category].dummy, RarityColorR[obj.rarity], RarityColorG[obj.rarity], RarityColorB[obj.rarity], RARITY_BORDER_ALPHA)
call SlotRarity[i][category].show(true)
call SlotRarity[i][category].refresh()
call Slot[i][category].refresh()
call OpenContext(i, false)
if Tooltips2[i].control.visible then
call Tooltips2[i].show(false)
call Tooltips1[i].control.move(0, 0, 0)
call Tooltips1[i].control.refresh()
endif
endfunction
public function Attach takes integer i, integer slot returns nothing
local Inventory bag = Inventory_InventoryIndex[i]
local InventoryContent content = Inventory_SlotIndex[bag][slot]
local integer category = content.object.id.category
local integer texture = Slot[i][category].texture
local integer object = SlotObject[i][category]
local Combatant c = Fighter[i]
if StringLength(content.object.model) > 0 then
if content.object.attachment != null then
call DestroyEffect(content.object.attachment)
endif
set c.missile2 = content.object.model + c.attachSize + ".mdx"
set content.object.attachment = AddSpecialEffectTarget(c.missile2, MainUnit[i], c.attachPoint+content.object.modelPt)
elseif content.object.id.category == Items.RIGHT_HAND or content.object.id.category == Items.LEFT_HAND and content.object.id.class != "Shield" then
set c.missile2 = ""
endif
if SlotObject[i][category].attachment != null then
call DestroyEffect(SlotObject[i][category].attachment)
set SlotObject[i][category].attachment = null
endif
set Slot[i][category].texture = content.plat.texture
set content.plat.texture = texture
set SlotObject[i][category] = content.object
if Tooltips2[i].control.visible then
call Tooltips2[i].show(false)
call Tooltips1[i].control.move(0, 0, 0)
call Tooltips1[i].control.refresh()
endif
if object == 0 then
call content.plat.show(false)
call content.rarity.show(false)
set content.object = 0
else
call Inventory.RemoveBonus(c, object)
set content.object = object
call SetUnitVertexColor(content.rarity.dummy, RarityColorR[content.object.rarity], RarityColorG[content.object.rarity], RarityColorB[content.object.rarity], RARITY_BORDER_ALPHA)
call content.plat.refresh()
call content.rarity.refresh()
endif
call Inventory.ApplyBonus(c, SlotObject[i][category])
call OpenContext(i, false)
call Slot[i][category].show(true)
call SetUnitVertexColor(SlotRarity[i][category].dummy, RarityColorR[SlotObject[i][category].id.rarity], RarityColorG[SlotObject[i][category].id.rarity], RarityColorB[SlotObject[i][category].id.rarity], RARITY_BORDER_ALPHA)
call SlotRarity[i][category].show(true)
call SlotRarity[i][category].refresh()
call Slot[i][category].refresh()
if Locale == Player(i) then
call InventorySwapSound.play(0, 0, 0, 100)
else
call InventorySwapSound.play(0, 0, 0, 0)
endif
endfunction
private function CreateSkillRow takes integer pid, SkillData sData returns nothing
local PlayerSkill skill
local SkillRow node
local integer data
if SkillRows[pid][sData.subclass] == 0 then
set SkillRows[pid][sData.subclass] = SkillRow.create()
endif
set skill = RegisterPlayerSkill(pid, sData)
set node = SkillRows[pid][sData.subclass].enqueue()
set node.id = sData
set node.pid = pid
set node.skill = skill
set skill.row = node
set node.background = PanelPlatform.create(CharWindowSkill[pid], 'e00K', 'B016', -2, 43-67.*SkillCount[pid][sData.subclass], 1)
call node.background.setColor(255, 255, 255, 128)
call node.background.show(false)
set SkillIconId[pid] = SkillIconId[pid].plus_1()
if SkillIconId[pid] == 'eSI5' then
set SkillIconId[pid] = 'eSI1'
endif
set node.icon = PanelPlatform.create(CharWindowSkill[pid], SkillIconId[pid], sData.icon, node.background.xOffset-102., node.background.yOffset+2, node.background.level+1)
set node.icon.scale = 0.6
call node.icon.show(false)
set data = GetUnitUserData(node.icon.dummy)
set IconIndex[data] = node
set SkillButtonOwner[data] = pid + 1
set node.plus = PanelPlatform.create(CharWindowSkill[pid], 'e007', 'B018', node.icon.xOffset, node.icon.yOffset, node.icon.level+1)
set node.plus.scale = 0.4
call node.plus.setColor(255, 255, 255, 200)
call node.plus.show(false)
set node.textName = PanelTextEx.create(CharWindowSkill[pid], sData.name, FONTSTYLE_FrizQTShaded, node.background.xOffset-71., node.background.yOffset+15., 2)
set node.textName.scale = 0.3
call node.textName.setColor(255, 204, 0, 255)
call node.textName.show(false)
set node.textLevel = PanelTextEx.create(CharWindowSkill[pid], "Lv. 0", FONTSTYLE_FrizQTShaded, node.background.xOffset + 95, node.background.yOffset+ 5., 2)
set node.textLevel.scale = 0.3
call node.textLevel.show(false)
set node.textMaster = PanelTextEx.create(CharWindowSkill[pid], "0.0%", FONTSTYLE_FrizQTShaded, node.background.xOffset + 95, node.background.yOffset-15., 2)
set node.textMaster.scale = 0.3
call node.textMaster.show(false)
set node.exp = PanelPlatform.create(CharWindowSkill[pid], 'e01J', 'SXP0', node.background.xOffset+6., node.background.yOffset-8., node.background.level + 1)
call node.exp.show(false)
set node.index = SkillCount[pid][sData.subclass]
set SkillCount[pid][sData.subclass] = SkillCount[pid][sData.subclass] + 1
endfunction
private function EnumSkills takes nothing returns nothing
local integer i = 1
local integer id = GetUnitTypeId(MainUnit[TempInt])
local SkillData data
loop
exitwhen i > Skill_SkillCount
set data = SkillData(i)
if (data.class == id) then
call CreateSkillRow(TempInt, data)
endif
set i = i + 1
endloop
endfunction
private function AutoUpdateOverall takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 3
if MainUnit[i] != null then
call Overall[i].setText(I2S(GetOverallPower(Fighter[i])), FONTSTYLE_FrizQTShaded)
call Overall[i].refresh()
call ElementFire[i].setText(I2S(R2I(Fighter[i].fireElement)), FONTSTYLE_FrizQTShaded)
call ElementFire[i].refresh()
call ElementEarth[i].setText(I2S(R2I(Fighter[i].earthElement)), FONTSTYLE_FrizQTShaded)
call ElementEarth[i].refresh()
call ElementWater[i].setText(I2S(R2I(Fighter[i].waterElement)), FONTSTYLE_FrizQTShaded)
call ElementWater[i].refresh()
call ElementWind[i].setText(I2S(R2I(Fighter[i].windElement)), FONTSTYLE_FrizQTShaded)
call ElementWind[i].refresh()
endif
set i = i + 1
endloop
endfunction
private function AutoUpdateStats takes nothing returns nothing
if CharWindowStatistic[PNumb].visible then
call RefreshStatsValues(PNumb)
endif
endfunction
public function UpdateLevel takes integer i, integer level returns nothing
call Title[i].setText("Level " + I2S(level), FONTSTYLE_FrizQTShaded)
call Title[i].setColor(255, 204, 0, 255)
call Title[i].move(-(Title[i].width+SubTitle[i].width)/2-10, Title[i].yOffset, 1) // Make it centered
call SubTitle[i].move(Title[i].xOffset+Title[i].width, SubTitle[i].yOffset, 1) // Make it centered
call Title[i].refresh()
call SubTitle[i].refresh()
endfunction
public function Create takes integer i returns nothing
local integer j
local integer index
local integer data
local string s = ""
local integer level = 0
local real scale = 1.0
local real offset = 0.0
local player p
local BJObjectId id
if IsPlaying[i] then
set p = Player(i)
set Visible[i] = true
set UpdateTimer[i] = NewTimerEx(i)
set DoubleTimer[i] = NewTimerEx(i)
set CharWindowGeneral[i] = Panel.create(p, 'e000', 0, -440, -50, 0.0)
set CharWindowEquipment[i] = Panel.create(p, 'e00A', 'B00Q', -440, -50, 0.0)
set CharWindowSkill[i] = Panel.create(p, 'e00A', 'B00X', -440, -50, 0.0)
set CharWindowStatistic[i] = Panel.create(p, 'e00A', 'B00Y', -440, -50, 0.0)
set id = GetUnitTypeId(MainUnit[i])
set SkillIconId[i] = 'eSI0'
set TempInt = i
call ForForce(bj_FORCE_PLAYER[0], function EnumSkills)
if id == 'h004' then
set s = "war3mapImported\\Footman ava.mdx"
set level = -1500
set offset = -40
set scale = 1.2
set SubTabNames[i][0] = "Guardian"
set SubTabNames[i][1] = "Royalty"
set SubTabNames[i][2] = "Dark Knight"
elseif id == 'h00C' then
set s = "war3mapImported\\ARCHNIGHEL ava.MDX"
set level = -1500
set offset = -40
set scale = 0.7
set SubTabNames[i][0] = "Huntress"
set SubTabNames[i][1] = "Ranger"
set SubTabNames[i][2] = "Moon Strider"
endif
set ExitButton[i] = PanelPlatform.create(CharWindowGeneral[i], 'e001', 0, 127.5, 186.5, 1)
set ExitButton[i].scale = 0.7
call ExitButton[i].setColor(255, 255, 255, 0)
set ExitButtonOwner[GetUnitUserData(ExitButton[i].dummy)] = i+1
set Background[i] = PanelPlatform.create(CharWindowEquipment[i], 'e009', 0, -55, -5, -2500)
call Background[i].setColor(9, 9, 9, 255)
/*static if USE_MEMORY_HACK then
set Background[i] = PanelPlatform.create(CharWindowEquipment[i], 'e009', 'B00W', -55, 19, -2500)
else
set Background[i] = PanelPlatform.create(CharWindowEquipment[i], 'e02V', 'B00W', -55, 19, -2500)
set BackgroundOwner[GetUnitUserData(Background[i].dummy)] = i+1
endif*/
set Background[i].scale = 1.4
set Selection[i] = PanelPlatform.create(CharWindowEquipment[i], 'e008', 0, 0, 0, 3)
set Selection[i].scale = 0.85
call Selection[i].show(false)
set ContextMenu[i] = PanelPlatform.create(CharWindowEquipment[i], 'e00C', 'B00S', CONTEXT_X_CLOSE, 47.0, 4)
set ContextMenu[i].scale = 0.9
call ContextMenu[i].show(false)
set Model[i] = PanelModel.create(CharWindowEquipment[i], s, -30, offset, level)
set Model[i].scale = scale
set Name[i] = PanelTextEx.create(CharWindowEquipment[i], CharacterName[i], FONTSTYLE_FrizQTShaded, 0, 0, 0)
set Title[i] = PanelTextEx.create(CharWindowEquipment[i], "Level 1 ", FONTSTYLE_FrizQTShaded, 0, 0, 0)
set SubTitle[i] = PanelTextEx.create(CharWindowEquipment[i], " " + GetUnitName(MainUnit[i]), FONTSTYLE_FrizQTShaded, 0, 0, 0)
set Rank[i] = PanelTextEx.create(CharWindowEquipment[i], "Unknown", FONTSTYLE_FrizQTShaded, 0, 0, 0)
set Overall[i] = PanelTextEx.create(CharWindowEquipment[i], "0", FONTSTYLE_FrizQTShaded, 0, 0, 0)
set Name[i].scale = 0.3
set Title[i].scale = 0.3
set SubTitle[i].scale = 0.3
set Rank[i].scale = 0.3
set Overall[i].scale = 0.3
call Title[i].setColor(255, 204, 0, 255)
call SubTitle[i].setColor(213, 55, 30, 255)
call Rank[i].setColor(64, 136, 224, 255)
call Name[i].move(-Name[i].width/2-10, 90, 1) // Make it centered
call Title[i].move(-(Title[i].width+SubTitle[i].width)/2-10, -55, 1) // Make it centered
call SubTitle[i].move(Title[i].xOffset+Title[i].width, -55, 1) // Make it centered
call Rank[i].move(-Rank[i].width/2-10, -70, 1) // Make it centered
call Overall[i].move(-25, -95, 1)
call Name[i].refresh()
call Title[i].refresh()
call SubTitle[i].refresh()
call Rank[i].refresh()
call Overall[i].refresh()
set j = 1
set index = 0
set id = 'eCS0'
loop
exitwhen j > 10
set id = id.plus_1()
set index = index + 1
if index < 6 then
set Slot[i][index] = PanelPlatform.create(CharWindowEquipment[i], id, 'BSAL', -107.0, 80.0-46.0*(j-1), 1)
set SlotRarity[i][index] = PanelPlatform.create(CharWindowEquipment[i], 'e00Y', 'BSAL', -108.0, 80.0-46.0*(j-1), 2)
else
set Slot[i][index] = PanelPlatform.create(CharWindowEquipment[i], id, 'BSAL', 99.0, 80.0-46.0*(j-6), 1)
set SlotRarity[i][index] = PanelPlatform.create(CharWindowEquipment[i], 'e00Y', 'BSAL', 98.0, 80.0-46.0*(j-6), 2)
endif
call Slot[i][index].show(false)
call SlotRarity[i][index].show(false)
set Slot[i][index].transformAxis = true
set Slot[i][index].scale = 0.6
set SlotRarity[i][index].scale = 0.6
set SlotObject[i][index] = 0
set data = GetUnitUserData(Slot[i][index].dummy)
set SlotIndex[data] = index
set SlotOwner[data] = i+1
set j = j + 1
endloop
set id = 'eCB7'
set j = 0
loop
exitwhen j == 3
set id = id.plus_1()
set ContextButton[i][j] = PanelPlatform.create(CharWindowEquipment[i], id, 'B099', 188.0, 76.0-28.0*j, 0)
set ContextButton[i][j].scale = 0.9
call ContextButton[i][j].setColor(255, 255, 255, 128)
call ContextButton[i][j].show(false)
set ContextButtonOwner[GetUnitUserData(ContextButton[i][j].dummy)] = i+1
set ContextButtonIndex[GetUnitUserData(ContextButton[i][j].dummy)] = j+1
set j = j + 1
endloop
set id = 'eTB0'
set j = 0
loop
exitwhen j == 3
set id = id.plus_1()
set TabButton[i][j] = PanelPlatform.create(CharWindowGeneral[i], id, 'BSAL', -99.0+94.*j, 130.5, 0)
set TabButtonOwner[GetUnitUserData(TabButton[i][j].dummy)] = i+1
set TabButtonIndex[GetUnitUserData(TabButton[i][j].dummy)] = j+1
set j = j + 1
endloop
set AttNotifBG[i] = PanelPlatform.create(CharWindowGeneral[i], 'e007', 'B03H', -59.0, 140., 2)
set AttNotifBG[i].scale = 0.303
set SkillNotifBG[i] = PanelPlatform.create(CharWindowGeneral[i], 'e007', 'B03H', 35.0, 140., 2)
set SkillNotifBG[i].scale = 0.303
set AttNotifText[i] = PanelTextEx.create(CharWindowGeneral[i], "0", FONTSTYLE_FrizQTShaded, 0, 0, 3)
set AttNotifText[i].scale = 0.2
set SkillNotifText[i] = PanelTextEx.create(CharWindowGeneral[i], "0", FONTSTYLE_FrizQTShaded, 0, 0, 3)
set SkillNotifText[i].scale = 0.2
call AttNotifBG[i].show(false)
call SkillNotifBG[i].show(false)
call AttNotifText[i].show(false)
call SkillNotifText[i].show(false)
set id = 'ST00'
set j = 0
loop
exitwhen j == 9
set id = id.plus_1()
set StatsText[i][j] = PanelPlatform.create(CharWindowStatistic[i], 'e00O', id, -10, 80-12*j, 2)
set j = j + 1
endloop
loop
exitwhen j == 30
set id = id.plus_1()
set StatsText[i][j] = PanelPlatform.create(CharWindowStatistic[i], 'e00O', id, -10, -69-12*j, 2)
set j = j + 1
endloop
set id = 'eCA0'
set j = 0
loop
exitwhen j == 4
set id = id.plus_1()
set AttrIncButton[i][j] = PanelPlatform.create(CharWindowEquipment[i], id, 'B019', -80+51.0*j, -173, 2)
set AttButtonOwner[GetUnitUserData(AttrIncButton[i][j].dummy)] = i+1
set AttrIncButton[i][j].scale = 0.4
call AttrIncButton[i][j].show(false)
set j = j + 1
endloop
set j = 0
loop
exitwhen j == 4
set id = id.plus_1()
set AttrValText[i][j] = PanelTextEx.create(CharWindowEquipment[i], "0", FONTSTYLE_FrizQTShaded, -85+50.0*j, -153, 2)
set AttrValText[i][j].scale = 0.25
set j = j + 1
endloop
set AttrValText[i][4] = PanelTextEx.create(CharWindowEquipment[i], "0", FONTSTYLE_FrizQTShaded, -18, -132, 2)
set AttrValText[i][4].scale = 0.25
call AttrValText[i][0].setText(I2S(Strength[i]), FONTSTYLE_FrizQTShaded)
call AttrValText[i][1].setText(I2S(Dexterity[i]), FONTSTYLE_FrizQTShaded)
call AttrValText[i][2].setText(I2S(Wisdom[i]), FONTSTYLE_FrizQTShaded)
call AttrValText[i][3].setText(I2S(Fortitude[i]), FONTSTYLE_FrizQTShaded)
set j = 0
loop
exitwhen j == 4
set id = id.plus_1()
call AttrValText[i][j].move((-80+51.0*j)-AttrValText[i][j].width/2, AttrValText[i][j].yOffset, 2)
set j = j + 1
endloop
set StatsValue[i] = PanelTextTag.create(CharWindowStatistic[i], "", 0.017, 8, -24)
set StatsValue2[i] = PanelTextTag.create(CharWindowStatistic[i], "", 0.017, 8, -166)
set SkillTabName[i] = PanelTextEx.create(CharWindowSkill[i], "Active", FONTSTYLE_FrizQTShaded, -2, 104., 1)
set SkillTabName[i].scale = 0.3
call SkillTabName[i].move(-2.-SkillTabName[i].width/2, 103., 1)
set SkillArrowLeft[i] = PanelPlatform.create(CharWindowSkill[i], 'e002', 'B010', -130, 103., 3)
set SkillArrowLeft[i].scale = 3.0
set SkillButtonOwner[GetUnitUserData(SkillArrowLeft[i].dummy)] = i + 1
set SkillArrowRight[i] = PanelPlatform.create(CharWindowSkill[i], 'e003', 'B012', 122, 103., 3)
set SkillArrowRight[i].scale = 3.0
set SkillButtonOwner[GetUnitUserData(SkillArrowRight[i].dummy)] = i + 1
set SkillArrowUp[i] = PanelPlatform.create(CharWindowSkill[i], 'e004', 'B013', -2, 80., 3)
set SkillArrowUp[i].scale = 3.0
set SkillButtonOwner[GetUnitUserData(SkillArrowUp[i].dummy)] = i + 1
set SkillArrowDown[i] = PanelPlatform.create(CharWindowSkill[i], 'e005', 'B011', -2, -195., 3)
set SkillArrowDown[i].scale = 3.0
set SkillButtonOwner[GetUnitUserData(SkillArrowDown[i].dummy)] = i + 1
set StatsArrowUp[i] = PanelPlatform.create(CharWindowStatistic[i], 'e004', 'B013', 133, -59., 1)
set StatsArrowUp[i].scale = 3.0
set StatsButtonOwner[GetUnitUserData(StatsArrowUp[i].dummy)] = i + 1
set StatsArrowDown[i] = PanelPlatform.create(CharWindowStatistic[i], 'e005', 'B011', 133, -162., 1)
set StatsArrowDown[i].scale = 3.0
set StatsButtonOwner[GetUnitUserData(StatsArrowDown[i].dummy)] = i + 1
set ElementFire[i] = PanelTextEx.create(CharWindowStatistic[i], "0", FONTSTYLE_FrizQTShaded, -101, -188, 1)
set ElementEarth[i] = PanelTextEx.create(CharWindowStatistic[i], "0", FONTSTYLE_FrizQTShaded, -38, -188, 1)
set ElementWater[i] = PanelTextEx.create(CharWindowStatistic[i], "0", FONTSTYLE_FrizQTShaded, 25, -188, 1)
set ElementWind[i] = PanelTextEx.create(CharWindowStatistic[i], "0", FONTSTYLE_FrizQTShaded, 88, -188, 1)
set ElementFire[i].scale = 0.25
set ElementEarth[i].scale = 0.25
set ElementWater[i].scale = 0.25
set ElementWind[i].scale = 0.25
call ElementFire[i].refresh()
call ElementEarth[i].refresh()
call ElementWater[i].refresh()
call ElementWind[i].refresh()
set TabIndex[i] = -1
set SkillTabIndex[i] = -1
set SkillScrollIndex[i] = -1
set StatsScrollIndex[i] = -1
call ScrollStatsMenu(i, 0)
call OpenTab(i, 0)
call OpenSkillTab(i, 0)
call Show(i, false)
call AddSkillPoint(i, 1)
endif
endfunction
private function onSelect takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer data = GetUnitUserData(u)
local integer i
local integer j
local integer id
if SlotOwner[data] != 0 then
set i = SlotOwner[data]-1
if SlotIndex[data] != SelectIndex[i] then
if Visible[i] then
set SelectIndex[i] = SlotIndex[data]
call Selection[i].move(Slot[i][SelectIndex[i]].xOffset, Slot[i][SelectIndex[i]].yOffset, Selection[i].level)
call Selection[i].show(true)
call Selection[i].refresh()
//if not ContextVisible[i] then
call OpenContext(i, true)
//endif
call TimerStart(DoubleTimer[i], DOUBLE_CLICK_WAIT_TIME, false, null)
endif
else
if TimerGetRemaining(DoubleTimer[i]) > 0.01 then
call Detach(i, SelectIndex[i])
if Locale == Player(i) then
call InventorySwapSound.play(0, 0, 0, 100)
else
call InventorySwapSound.play(0, 0, 0, 0)
endif
endif
call OpenContext(i, false)
endif
if Locale == Player(i) then
call SelectUnit(u, false)
call SelectUnit(Controller[i], true)
endif
elseif ContextButtonIndex[data] != 0 then
set i = ContextButtonOwner[data]-1
if UnitAlive(MainUnit[i]) then
if ContextButtonIndex[data] == 1 then // detach
call Detach(i, SelectIndex[i])
if Locale == Player(i) then
call InventorySwapSound.play(0, 0, 0, 100)
else
call InventorySwapSound.play(0, 0, 0, 0)
endif
elseif ContextButtonIndex[data] == 2 then // drop
set j = Bag[i].getEmptySlot()
call Detach(i, SelectIndex[i])
call Bag[i].dropItemFromSlot(j, true)
if Locale == Player(i) then
call InventoryDropSound.play(0, 0, 0, 100)
else
call InventoryDropSound.play(0, 0, 0, 0)
endif
elseif ContextButtonIndex[data] == 3 then // close
call OpenContext(i, false)
endif
else
call DisplayTimedTextToPlayer(Player(i), 0, 0, 1., "You are dead.")
endif
if Locale == Player(i) then
call SelectUnit(u, false)
call SelectUnit(Controller[i], true)
endif
elseif TabButtonIndex[data] != 0 then
set i = TabButtonOwner[data]-1
call OpenTab(i, TabButtonIndex[data]-1)
if Locale == Player(i) then
call SelectUnit(u, false)
call SelectUnit(Controller[i], true)
endif
elseif ExitButtonOwner[data] != 0 then
set i = ExitButtonOwner[data]-1
call Show(i, false)
if Locale == Player(i) then
call SelectUnit(u, false)
call SelectUnit(Controller[i], true)
endif
elseif BackgroundOwner[data] != 0 then
set i = BackgroundOwner[data]-1
call BJDebugMsg("click " + I2S(i))
set CharacterWindowRotate_IsRotating[i] = not CharacterWindowRotate_IsRotating[i]
if Locale == Player(i) then
call SelectUnit(u, false)
call SelectUnit(Controller[i], true)
endif
elseif AttButtonOwner[data] != 0 then
set i = AttButtonOwner[data]-1
if AttributePoint[i] > 0 then
set id = GetUnitTypeId(u)
if id == 'eCA1' then
if AddAttPoints(i, 0, 1) then
call AddAttributePoint(i, -1)
//set SavingPlayerID = i
//call ExecuteFunc("CreateNewSaveThreadEx")
endif
elseif id == 'eCA2' then
if AddAttPoints(i, 1, 1)then
call AddAttributePoint(i, -1)
//set SavingPlayerID = i
//call ExecuteFunc("CreateNewSaveThreadEx")
endif
elseif id == 'eCA3' then
if AddAttPoints(i, 2, 1) then
call AddAttributePoint(i, -1)
//set SavingPlayerID = i
//call ExecuteFunc("CreateNewSaveThreadEx")
endif
elseif id == 'eCA4' then
if AddAttPoints(i, 3, 1) then
call AddAttributePoint(i, -1)
//set SavingPlayerID = i
//call ExecuteFunc("CreateNewSaveThreadEx")
endif
endif
endif
if Locale == Player(i) then
call SelectUnit(u, false)
call SelectUnit(Controller[i], true)
endif
endif
set u = null
return false
endfunction
private function onOrder takes nothing returns boolean
local unit u = GetOrderTargetUnit()
local integer data = GetUnitUserData(u)
local integer pid
local integer uid
if u != null and GetIssuedOrderId() == ORDER_smart and (SlotOwner[data] != 0 or ContextButtonIndex[data] != 0 or TabButtonIndex[data] != 0 or ExitButtonOwner[data] != 0 or AttButtonOwner[data] != 0 or SkillButtonOwner[data] != 0) then
if SlotOwner[data] != 0 then
set pid = SlotOwner[data]-1
if SlotObject[pid][SlotIndex[data]] != Tooltips1[pid].itmObject or not Tooltips1[pid].control.visible then
call Tooltips1[pid].show(true)
call Tooltips2[pid].show(false)
call Tooltips1[pid].control.move(0, 0, Tooltips1[pid].control.zDepth)
call Tooltips1[pid].control.refresh()
call Tooltips1[pid].setItem(SlotObject[pid][SlotIndex[data]])
else
call Tooltips1[pid].show(false)
set Tooltips1[pid].itmObject = -1
set Tooltips1[pid].skill = -1
call Tooltips2[pid].show(false)
set Tooltips2[pid].itmObject = -1
set Tooltips2[pid].skill = -1
endif
elseif SkillButtonOwner[data] != 0 then
set uid = GetUnitTypeId(u)
if uid != 'e002' and uid != 'e003' and uid != 'e004' and uid != 'e005' then // up
set pid = SkillButtonOwner[data]-1
if IconIndex[data].skill != Tooltips1[pid].skill or not Tooltips1[pid].control.visible then
call Tooltips1[pid].show(true)
call Tooltips2[pid].show(false)
call Tooltips1[pid].control.move(0, 0, Tooltips1[pid].control.zDepth)
call Tooltips1[pid].control.refresh()
call Tooltips1[pid].setSkill(IconIndex[data].skill)
else
call Tooltips1[pid].show(false)
set Tooltips1[pid].itmObject = -1
set Tooltips1[pid].skill = -1
call Tooltips2[pid].show(false)
set Tooltips2[pid].itmObject = -1
set Tooltips2[pid].skill = -1
endif
endif
endif
set u = GetTriggerUnit()
call IssueImmediateOrderById(u, ORDER_stop)
call IssueImmediateOrderById(u, ORDER_stunned)
endif
set u = null
return false
endfunction
private function checkSelection takes nothing returns nothing
local unit u
local integer data
local integer uid
if CharacterManager_GameModeCode == 22 then
set u = BlzGetMouseFocusUnit()
if u == null then
if LastSelection != null then
set data = GetUnitUserData(u)
if Tooltips1[PNumb].itmObject != -1 then
call Tooltips1[PNumb].show(false)
set Tooltips1[PNumb].itmObject = -1
set Tooltips1[PNumb].skill = -1
call Tooltips2[PNumb].show(false)
set Tooltips2[PNumb].itmObject = -1
set Tooltips2[PNumb].skill = -1
set LastSelection = u
endif
endif
else
if LastSelection != u then
set data = GetUnitUserData(u)
if SlotOwner[data] != 0 then
call Tooltips1[PNumb].show(true)
call Tooltips2[PNumb].show(false)
call Tooltips1[PNumb].control.move(0, 0, Tooltips1[PNumb].control.zDepth)
call Tooltips1[PNumb].control.refresh()
call Tooltips1[PNumb].setItem(SlotObject[PNumb][SlotIndex[data]])
set LastSelection = u
elseif SkillButtonOwner[data] != 0 then
set uid = GetUnitTypeId(u)
if uid != 'e002' and uid != 'e003' and uid != 'e004' and uid != 'e005' then
call Tooltips1[PNumb].show(true)
call Tooltips2[PNumb].show(false)
call Tooltips1[PNumb].control.move(0, 0, Tooltips1[PNumb].control.zDepth)
call Tooltips1[PNumb].control.refresh()
call Tooltips1[PNumb].setSkill(IconIndex[data].skill)
set LastSelection = u
endif
endif
endif
endif
set u = null
endif
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SELECTED)
call TriggerAddCondition(t, Condition(function onSelect))
call TriggerRegisterAnyUnitEventBJ(SkillWindowTrigger, EVENT_PLAYER_UNIT_SELECTED)
call TriggerAddCondition(SkillWindowTrigger, Condition(function onSelect2))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(t, Condition(function onOrder))
call TimerStart(NewTimer(), 0.25, true, function AutoUpdateStats)
call TimerStart(NewTimer(), 0.25, true, function AutoUpdateOverall)
call TimerStart(CreateTimer(), 0.1, true, function checkSelection)
endfunction
endlibrary
library CharacterWindowRotate /*initializer init*/ uses ScreenMouse, CharacterWindow
static if not USE_MEMORY_HACK then
globals
private real LastDiffX = 0
public real array Yaw
public boolean array IsRotating
endglobals
private function onMove takes nothing returns nothing
set LastDiffX = SMGetDifX(0)
endfunction
private function onTick takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 3
if IsRotating[i] then
set Yaw[i] = Yaw[i] + SMGetDifX(i)
call BJDebugMsg(R2S(Yaw[i]))
call BlzSetSpecialEffectYaw(CharacterWindow_Model[i].model, Yaw[i])
endif
set i = i + 1
endloop
set LastDiffX = 0
endfunction
private function init takes nothing returns nothing
local trigger t
local trigger t2
local integer i = 0
loop
exitwhen i > 3
set t = CreateTrigger()
set t2 = CreateTrigger()
call ScreenMouseRegisterPlayer(t, t2, Player(i), true, true, true)
set i = i + 1
endloop
call TimerStart(CreateTimer(), 0.03, true, function onTick)
endfunction
endif
endlibrary
library BuffBar uses PanelCore, LinkedListModule, TimerUtils
private keyword BuffBar
globals
BuffBar array BuffBars
TableArray BuffIdIcon
endglobals
struct Buff
string name
string description
integer icon
endstruct
private struct BuffIcon extends array
PanelPlatform icon
PanelPlatform cool
Buff buffId
BuffBar parent
effect toDestroy
timer timeout
implement LinkedList
endstruct
struct BuffBar
Panel background
BuffIcon icons
integer count
method refresh takes nothing returns nothing
local real x
local real y = 0
local BuffIcon node = .icons.next
local integer tc = .count
local integer c
local integer i = 0
local integer r = 0
set c = tc
if c > 8 then
set c = 8
endif
set x = -(31.25*c)/2+15.625
loop
exitwhen node.head or node == 0
set i = i + 1
if i > 8 then
set tc = tc - 8
set c = tc
if c > 8 then
set c = 8
endif
set x = -(31.25*c)/2.+15.625
set y = y + 31.25
set i = 1
endif
call node.icon.move(x, y, 0)
call node.cool.move(x, y, 1)
call node.icon.refresh()
call node.cool.refresh()
set x = x + 31.25
set node = node.next
endloop
endmethod
method removeAll takes nothing returns nothing
local BuffIcon node = .icons.next
loop
exitwhen node.head or node == 0
call removeBuff(node.buffId)
set node = node.next
endloop
endmethod
method removeBuff takes Buff bid returns nothing
local BuffIcon icon = BuffIdIcon[this].integer[bid]
if icon != 0 then
set BuffIdIcon[this].integer[bid] = 0
if icon.toDestroy != null then
call DestroyEffect(icon.toDestroy)
set icon.toDestroy = null
endif
if icon.timeout != null then
call ReleaseTimer(icon.timeout)
set icon.timeout = null
endif
call Fighter[.background.pid].removeBuffEffect(bid)
set .count = .count - 1
call CooldownAnimation.Stop(icon.cool)
call icon.icon.destroy()
call icon.cool.destroy()
call icon.removeNode()
call icon.deallocate()
call refresh()
endif
endmethod
private static method onTimeout takes nothing returns nothing
local timer t = GetExpiredTimer()
local BuffIcon icon = GetTimerData(t)
call icon.parent.removeBuff(icon.buffId)
set t = null
endmethod
method has takes Buff bid returns boolean
return BuffIdIcon[this].integer[bid] != 0
endmethod
method addBuff takes Buff bid, real duration, boolean stack, boolean reset, effect toDestroy returns nothing
local BuffIcon new
local real dur
if (BuffIdIcon[this].integer[bid] == 0) then
set .count = .count + 1
set new = BuffIcon.allocate()
set new.timeout = NewTimerEx(new)
set new.parent = this
set new.buffId = bid
set new.icon = PanelPlatform.create(.background, 'e00S', bid.icon, 0, 0, 0)
set new.icon.scale = 0.5
set new.cool = PanelPlatform.create(.background, 'e007', 'BSAL', 0, 0, 1)
set new.cool.scale = 0.425
call new.cool.setColor(0, 255, 0, 100)
call new.cool.show(false)
set BuffIdIcon[this].integer[bid] = new
call .icons.insertNode(new)
if (duration > 0) then
call CooldownAnimation.create(new.cool, duration, duration)
call TimerStart(new.timeout, duration, false, function thistype.onTimeout)
endif
call refresh()
elseif stack then
set new = BuffIdIcon[this].integer[bid]
set dur = TimerGetRemaining(new.timeout)+duration
if (dur > 0) then
call CooldownAnimation.create(new.cool, dur, dur)
call TimerStart(new.timeout, dur, false, function thistype.onTimeout)
endif
call TimerStart(new.timeout, dur, false, function thistype.onTimeout)
elseif reset then
set new = BuffIdIcon[this].integer[bid]
if (TimerGetRemaining(new.timeout) < duration) then
if (duration > 0) then
call CooldownAnimation.create(new.cool, duration, duration)
call TimerStart(new.timeout, duration, false, function thistype.onTimeout)
endif
endif
endif
if (new.toDestroy != null) then
call DestroyEffect(new.toDestroy)
endif
set new.toDestroy = toDestroy
endmethod
static method create takes player p returns thistype
local thistype this = allocate()
set .icons = BuffIcon.createNode()
set .background = Panel.create(p, 0, 0, 0, -272-90, PanelCamera_LEVEL_GAP*10)
set .count = 0
return this
endmethod
private static method onInit2 takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 3
if IsPlaying[i] then
set BuffBars[i] = BuffBar.create(Player(i))
endif
set i = i + 1
endloop
call ReleaseTimer(GetExpiredTimer())
endmethod
private static method onInit takes nothing returns nothing
set BuffIdIcon = TableArray[10]
call TimerStart(NewTimer(), 0, false, function thistype.onInit2)
endmethod
endstruct
endlibrary
library XPBar initializer init uses PanelPlatform
///! runtextmacro DECLARE_ARRAY_2D("", "PanelPlatform", "XPBar", "8", "5")
globals
public Panel array BarPanel
public PanelPlatform array XPBar[4][5]
public PanelTextEx array Title
public PanelTextEx array SubTitle
private integer XpBarTextureMaxId
private constant integer XP_TEXTURE_ID = 'XP00'
private constant real XP_BAR_WIDTH = 139.0
private constant real XP_BAR_TOTAL_WIDTH = 560.0
private constant real UPDATE_SPEED = 1.0
private constant integer XP_BAR_COUNT = 140
private constant integer XP_BAR_COLUMNS = R2I(XP_BAR_TOTAL_WIDTH/XP_BAR_WIDTH)
private constant real XP_BAR_SEGMENT = 1./XP_BAR_COLUMNS
endglobals
public function Update takes integer i returns nothing
local integer j
local integer index
local integer target
local BJObjectId id
local real xp
if EXPTarget[i] > 0 then
set xp = EXPCurrent[i]/EXPTarget[i]
set j = 0
set target = R2I(XP_BAR_TOTAL_WIDTH*xp/XP_BAR_WIDTH)
loop
exitwhen j >= XP_BAR_COLUMNS
if j < target then
if XPBar[i][j].texture != XpBarTextureMaxId then
set XPBar[i][j].texture = XpBarTextureMaxId
call XPBar[i][j].refresh()
endif
elseif j > target then
if XPBar[i][j].texture != XP_TEXTURE_ID then
set XPBar[i][j].texture = XP_TEXTURE_ID
call XPBar[i][j].refresh()
endif
endif
set j = j + 1
endloop
set id = BJObjectId(XP_TEXTURE_ID)
set index = R2I((xp-XP_BAR_SEGMENT*target)/XP_BAR_SEGMENT*I2R(XP_BAR_COUNT))
set j = 0
loop
exitwhen j >= index
set id = id.plus_1()
set j = j + 1
endloop
if XPBar[i][target].texture != id then
set XPBar[i][target].texture = id
call XPBar[i][target].refresh()
endif
call Title[i].setText("Level " + I2S(Level[i]) + " ", FONTSTYLE_FrizQTShaded)
call Title[i].setColor(255, 204, 0, 255)
call SubTitle[i].setText("[" + R2SW(EXPCurrent[i]/EXPTarget[i]*100., 3, 2) + "%]", FONTSTYLE_FrizQTShaded)
call Title[i].move(-(Title[i].width+SubTitle[i].width)/2, 0, 2) // Make it centered
call SubTitle[i].move(Title[i].xOffset+Title[i].width, 0, 2) // Make it centered
call Title[i].refresh()
call SubTitle[i].refresh()
endif
endfunction
public function Create takes integer i returns nothing
local integer j
local BJObjectId id
set BarPanel[i] = Panel.create(Player(i), 'e00T', 'B00K', 0, -352.-90, 0.0)
set Title[i] = PanelTextEx.create(BarPanel[i], "Level 1 ", FONTSTYLE_FrizQTShaded, 0, 0, 0)
set SubTitle[i] = PanelTextEx.create(BarPanel[i], "[0.00%]", FONTSTYLE_FrizQTShaded, 0, 0, 0)
set Title[i].scale = 0.3
set SubTitle[i].scale = 0.3
call Title[i].setColor(255, 204, 0, 255)
call Title[i].move(-(Title[i].width+SubTitle[i].width)/2, 0, 2) // Make it centered
call SubTitle[i].move(Title[i].xOffset+Title[i].width, 0, 2) // Make it centered
call Title[i].refresh()
//set BarPanel.scale = 0.6 // x: -260
//set BarPanel[i].scale = 0.8 // x: -260
set j = 0
loop
exitwhen j == 4
set XPBar[i][j] = PanelPlatform.create(BarPanel[i], 'e00U', XP_TEXTURE_ID, -210.+XP_BAR_WIDTH*j, 0.0, 1)
call XPBar[i][j].setColor(200, 200, 200, 255)
set j = j + 1
endloop
call BarPanel[i].show(true)
call BarPanel[i].refresh()
endfunction
private function init takes nothing returns nothing
local integer i
local BJObjectId id
set i = 0
set id = BJObjectId(XP_TEXTURE_ID)
loop
exitwhen i == XP_BAR_COUNT
set id = id.plus_1()
set i = i + 1
endloop
set XpBarTextureMaxId = id
endfunction
endlibrary
library ShortcutBar initializer init uses PanelPlatform, CooldownAnimation
globals
public Panel array SkillSelection
public Panel array BarPanel
public PanelPlatform array Button[4][10]
public PanelPlatform array Cooldown[4][10]
public PanelTextEx array ChargeText[4][10]
public timer array CooldownTimer[4][10]
public PanelPlatform array Number
public integer array SelectIndex
public integer array SkillButtonID
public integer array SkillButtonType
public integer array SkillButtonTarget
public player array SkillButtonOwner
public PanelPlatform array SkillButtonPlatform
public integer array ButtonIndex
public SkillData array ButtonSkill
public integer array ButtonTarget
public integer array ButtonType
public player array ButtonOwner
public PanelPlatform array ButtonPlatform
private boolean array IsAllowed
private trigger Trigger = CreateTrigger()
private trigger array Trigger2
private group SkillButtonGroup = CreateGroup()
endglobals
struct SkillCooldown
private static Table CooldownData
static method operator [] takes integer id returns real
return TimerGetRemaining(CooldownData.timer[id])
endmethod
static method start takes integer id, real dur returns nothing
if CooldownData.timer[id] == null then
set CooldownData.timer[id] = NewTimerEx(id)
endif
call TimerStart(CooldownData.timer[id], dur, false, null)
endmethod
private static method onInit takes nothing returns nothing
set CooldownData = Table.create()
endmethod
endstruct
function IsShortcutSlotInCooldown takes integer id, integer slot returns boolean
return TimerGetRemaining(CooldownTimer[id][slot]) > 0.01
endfunction
public function PutToCooldown takes integer id, integer slot, real dur, real default returns nothing
/*
call SetUnitAnimation(Cooldown[id][slot].dummy, "stand")
call SetUnitTimeScale(Cooldown[id][slot].dummy, 1.000000001/dur)
call Cooldown[id][slot].show(true)
call Cooldown[id][slot].refresh()*/
call CooldownAnimation.create(Cooldown[id][slot], dur, default)
call TimerStart(CooldownTimer[id][slot], dur, false, null)
endfunction
private function onSelect2 takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer data = GetUnitUserData(u)
local player p = SkillButtonOwner[data]
local integer id = GetPlayerId(p)
local integer uid = SkillButtonID[data]
local integer data2 = GetUnitUserData(Button[id][SelectIndex[id]].dummy)
local InventoryContent slot
local real cool
set ButtonType[data2] = SkillButtonType[data]
if SkillButtonType[data] == 0 then
call ChargeText[id][SelectIndex[id]].show(false)
set Button[id][SelectIndex[id]].texture = 'BSAL'
set ButtonType[data2] = 0
elseif SkillButtonType[data] == 1 then
call ChargeText[id][SelectIndex[id]].show(false)
set Button[id][SelectIndex[id]].texture = SkillButtonPlatform[data].texture
set ButtonSkill[data2] = SkillButtonID[data]
set cool = SkillCooldown[SkillButtonID[data]]
if cool > 0 then
call PutToCooldown(id, SelectIndex[id], cool, ButtonSkill[data2].cooldown[PlayerSkill(PlayerSkillData[id][ButtonSkill[data2]]).level])
endif
elseif SkillButtonType[data] == 2 then
set slot = Inventory_SlotIndex[Bag[id]][SkillButtonTarget[data]]
set Button[id][SelectIndex[id]].texture = slot.object.id.texture
set ButtonTarget[data2] = SkillButtonTarget[data]
set cool = slot.object.id.getCooldown()
if cool > 0 then
call PutToCooldown(id, SelectIndex[id], cool, slot.object.cooldown)
endif
call ChargeText[id][SelectIndex[id]].show(true)
call ChargeText[id][SelectIndex[id]].setText(I2S(slot.object.charge),FONTSTYLE_FrizQTShaded)
call ChargeText[id][SelectIndex[id]].refresh()
endif
call Button[id][SelectIndex[id]].refresh()
set SelectIndex[id] = -1
call SkillSelection[id].show(false)
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[id], true)
endif
set u = null
return false
endfunction
private function onSelect takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer data = GetUnitUserData(u)
local integer data2
local player p = ButtonOwner[data]
local integer id = GetPlayerId(p)
local integer uid = ButtonIndex[data]
local PanelPlatform plat = ButtonPlatform[data]
local PanelPlatform butt
local PanelPlatform bg
local PlayerSkill node = Skills[id].next
local SkillData sData
local InventoryContent slot
local integer i = 0
local integer j
local integer count = 0
local boolean array selected
local real xs = plat.xOffset - (60 * (CharacterWindow_SkillCount[id][0]))/2
if IsKeyVerified[id] then
loop
exitwhen node.head or node == 0
set sData = node.id
if node.level > 0 and sData.active then
set count = count + 1
endif
set node = node.next
endloop
loop
exitwhen i == 20
set slot = Inventory_SlotIndex[Bag[id]][i]
if slot.object != 0 and slot.object.id.category == Items.CONSUMABLE then
if not selected[slot.object.id] then
set IsAllowed[i] = true
set selected[slot.object.id] = true
set count = count + 1
else
set IsAllowed[i] = false
endif
endif
set i = i + 1
endloop
set xs = plat.xOffset - (50 * (count))/2
if not IsShortcutSlotInCooldown(id, uid) then
call SkillSelection[id].clear()
call GroupClear(SkillButtonGroup)
if SelectIndex[id] != uid then
call SkillSelection[id].show(true)
set bg = PanelPlatform.create(SkillSelection[id], 'e007', 'B03E', xs + 50 * count / 2, 60, 1)
set bg.scale = 1.25
call bg.refresh()
set bg = PanelPlatform.create(SkillSelection[id], 'e007', 'B03B', xs - 3, 76, 3)
set bg.scale = 1.25
call bg.refresh()
call DestroyTrigger(Trigger2[id])
set Trigger2[id] = CreateTrigger()
set i = 0
set node = Skills[id].next
loop
exitwhen node.head or node == 0
set sData = node.id
if node.level > 0 and sData.active then
set butt = PanelPlatform.create(SkillSelection[id], 'e006', 'BSAL', xs + 50 * i, 75, 3)
set butt.scale = 0.8
call TriggerRegisterUnitEvent(Trigger2[id], butt.dummy, EVENT_UNIT_SELECTED)
set butt.texture = sData.icon
call butt.refresh()
set bg = PanelPlatform.create(SkillSelection[id], 'e007', 'B03D', butt.xOffset, 76, 2)
set bg.scale = 1.25
call bg.refresh()
set data2 = GetUnitUserData(butt.dummy)
set SkillButtonID[data2] = node.id
set SkillButtonType[data2] = 1
set SkillButtonOwner[data2] = p
set SkillButtonPlatform[data2] = butt
call GroupAddUnit(SkillButtonGroup, butt.dummy)
set i = i + 1
endif
set node = node.next
endloop
set j = 0
loop
exitwhen j == 20
set slot = Inventory_SlotIndex[Bag[id]][j]
if slot.object != 0 and slot.object.id.category == Items.CONSUMABLE and IsAllowed[j] then
set butt = PanelPlatform.create(SkillSelection[id], 'e006', 'BSAL', xs + 50 * i, 75, 3)
set butt.scale = 0.8
call TriggerRegisterUnitEvent(Trigger2[id], butt.dummy, EVENT_UNIT_SELECTED)
set butt.texture = slot.object.id.texture
call butt.refresh()
set bg = PanelPlatform.create(SkillSelection[id], 'e007', 'B03D', butt.xOffset, 76, 2)
set bg.scale = 1.25
call bg.refresh()
set data2 = GetUnitUserData(butt.dummy)
set SkillButtonType[data2] = 2
set SkillButtonTarget[data2] = j
set SkillButtonOwner[data2] = p
set SkillButtonPlatform[data2] = butt
call GroupAddUnit(SkillButtonGroup, butt.dummy)
set i = i + 1
endif
set j = j + 1
endloop
set butt = PanelPlatform.create(SkillSelection[id], 'e006', 'B00P', xs + 50 * i, 75, 3)
set butt.scale = 0.8
set bg = PanelPlatform.create(SkillSelection[id], 'e007', 'B03D', butt.xOffset, 76, 2)
set bg.scale = 1.25
call bg.refresh()
set bg = PanelPlatform.create(SkillSelection[id], 'e007', 'B03C', xs + 50 * i + 2, 76, 4)
set bg.scale = 1.25
call bg.refresh()
set data2 = GetUnitUserData(butt.dummy)
set SkillButtonType[data2] = 0
set SkillButtonID[data2] = 0
set SkillButtonOwner[data2] = p
call TriggerRegisterUnitEvent(Trigger2[id], butt.dummy, EVENT_UNIT_SELECTED)
call TriggerAddCondition(Trigger2[id], Condition(function onSelect2))
call butt.refresh()
set SelectIndex[id] = uid
else
set SelectIndex[id] = -1
call SkillSelection[id].show(false)
endif
endif
endif
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[id], true)
endif
set u = null
return false
endfunction
public function Create takes integer i returns nothing
local integer j
local integer data
local BJObjectId id
local player p = Player(i)
set SelectIndex[i] = -1
set SkillSelection[i] = Panel.create(p, 0, 0, 0, -310.-90, 0.05)
set BarPanel[i] = Panel.create(p, 0, 0, 0, -317.-90, 0.05)
//set BarPanel[i] = Panel.create('h005', 'B00L', 0, -317.-90, 0.05)
//set BarPanel.scale = 0.6 // x: -260
set SkillSelection[i].scale = 0.8 // x: -260
set BarPanel[i].scale = 0.8 // x: -260
set Number[i] = PanelPlatform.create(BarPanel[i], 'e00I', 'B00N', -45, 45, 6)
//set Number[i].scale = 1.25
call SkillSelection[i].show(false)
set id = 'eSP0'
set j = 0
loop
exitwhen j > 9
set id = id.plus_1()
set CooldownTimer[i][j] = NewTimerEx(j)
set Cooldown[i][j] = PanelPlatform.create(BarPanel[i], 'e007', 'BSAL', -270 + 60 * j, 0, 2)
call Cooldown[i][j].setColor(0, 0, 0, 155)
call Cooldown[i][j].show(false)
set Button[i][j] = PanelPlatform.create(BarPanel[i], id, 'BSAL', -270 + 60 * j, 0, 1)
call TriggerRegisterUnitEvent(Trigger, Button[i][j].dummy, EVENT_UNIT_SELECTED)
set data = GetUnitUserData(Button[i][j].dummy)
set ButtonPlatform[data] = Button[i][j]
set ButtonOwner[data] = p
set ButtonIndex[data] = j
set ChargeText[i][j] = PanelTextEx.create(BarPanel[i], "0", FONTSTYLE_FrizQTShaded, -272+60*j+17, -18, 3)
set ChargeText[i][j].scale = 0.35
call ChargeText[i][j].show(false)
set j = j + 1
endloop
call BarPanel[i].show(true)
call BarPanel[i].refresh()
endfunction
private function onOrder takes nothing returns boolean
local unit u = GetOrderTargetUnit()
local integer data = GetUnitUserData(u)
local integer id
local integer spell
local PlayerSkill skill
if u != null and GetIssuedOrderId() == ORDER_smart then
if IsUnitInGroup(u, SkillButtonGroup) then
set id = GetPlayerId(GetTriggerPlayer())
if SkillButtonType[data] == 1 then
set spell = SkillButtonID[data]
set skill = PlayerSkillData[id][spell]
if skill != Tooltips1[id].skill or not Tooltips1[id].control.visible then
call Tooltips1[id].show(true)
call Tooltips2[id].show(false)
call Tooltips1[id].control.move(0, 0, Tooltips1[id].control.zDepth)
call Tooltips1[id].control.refresh()
call Tooltips1[id].setSkill(skill)
else
call Tooltips1[id].show(false)
set Tooltips1[id].itmObject = -1
endif
elseif SkillButtonType[data] == 2 then
if Inventory_SlotIndex[Bag[id]][SkillButtonTarget[data]].object != Tooltips1[id].itmObject or not Tooltips1[id].control.visible then
call Tooltips1[id].show(true)
call Tooltips2[id].show(false)
call Tooltips1[id].control.move(0, 0, Tooltips1[id].control.zDepth)
call Tooltips1[id].control.refresh()
call Tooltips1[id].setItem(Inventory_SlotIndex[Bag[id]][SkillButtonTarget[data]].object)
else
call Tooltips1[id].show(false)
set Tooltips1[id].itmObject = -1
endif
endif
set u = GetTriggerUnit()
call IssueImmediateOrderById(u, ORDER_stop)
call IssueImmediateOrderById(u, ORDER_stunned)
elseif ButtonOwner[data] != null then
set id = GetPlayerId(GetTriggerPlayer())
if ButtonType[data] == 1 then
set spell = ButtonSkill[data]
set skill = PlayerSkillData[id][spell]
if skill != Tooltips1[id].skill or not Tooltips1[id].control.visible then
call Tooltips1[id].show(true)
call Tooltips2[id].show(false)
call Tooltips1[id].control.move(0, 0, Tooltips1[id].control.zDepth)
call Tooltips1[id].control.refresh()
call Tooltips1[id].setSkill(skill)
else
call Tooltips1[id].show(false)
set Tooltips1[id].itmObject = -1
endif
elseif ButtonType[data] == 2 then
if Inventory_SlotIndex[Bag[id]][ButtonTarget[data]].object != Tooltips1[id].itmObject or not Tooltips1[id].control.visible then
call Tooltips1[id].show(true)
call Tooltips2[id].show(false)
call Tooltips1[id].control.move(0, 0, Tooltips1[id].control.zDepth)
call Tooltips1[id].control.refresh()
call Tooltips1[id].setItem(Inventory_SlotIndex[Bag[id]][ButtonTarget[data]].object)
else
call Tooltips1[id].show(false)
set Tooltips1[id].itmObject = -1
endif
endif
set u = GetTriggerUnit()
call IssueImmediateOrderById(u, ORDER_stop)
call IssueImmediateOrderById(u, ORDER_stunned)
endif
endif
set u = null
return false
endfunction
private function checkSelection takes nothing returns nothing
local unit u
local integer data
local integer uid
local integer spell
local PlayerSkill skill
if CharacterManager_GameModeCode == 22 then
set u = BlzGetMouseFocusUnit()
if u == null then
if LastSelection != null then
set data = GetUnitUserData(u)
if ButtonOwner[data] != null or SkillButtonOwner[data] != null then
if Tooltips1[PNumb].skill != -1 or Tooltips1[PNumb].itmObject != -1 then
call Tooltips1[PNumb].show(false)
set Tooltips1[PNumb].itmObject = -1
set Tooltips1[PNumb].skill = -1
call Tooltips2[PNumb].show(false)
set Tooltips2[PNumb].itmObject = -1
set Tooltips2[PNumb].skill = -1
set LastSelection = u
endif
endif
endif
else
if LastSelection != u then
set data = GetUnitUserData(u)
if ButtonOwner[data] != null then
if ButtonType[data] == 1 then
set spell = ButtonSkill[data]
set skill = PlayerSkillData[PNumb][spell]
call Tooltips1[PNumb].show(true)
call Tooltips2[PNumb].show(false)
call Tooltips1[PNumb].control.move(0, 0, Tooltips1[PNumb].control.zDepth)
call Tooltips1[PNumb].control.refresh()
call Tooltips1[PNumb].setSkill(skill)
set LastSelection = u
elseif ButtonType[data] == 2 then
call Tooltips1[PNumb].show(true)
call Tooltips2[PNumb].show(false)
call Tooltips1[PNumb].control.move(0, 0, Tooltips1[PNumb].control.zDepth)
call Tooltips1[PNumb].control.refresh()
call Tooltips1[PNumb].setItem(Inventory_SlotIndex[Bag[PNumb]][ButtonTarget[data]].object)
set LastSelection = u
endif
elseif SkillButtonOwner[data] != null then
if SkillButtonType[data] == 1 then
set spell = SkillButtonID[data]
set skill = PlayerSkillData[PNumb][spell]
call Tooltips1[PNumb].show(true)
call Tooltips2[PNumb].show(false)
call Tooltips1[PNumb].control.move(0, 0, Tooltips1[PNumb].control.zDepth)
call Tooltips1[PNumb].control.refresh()
call Tooltips1[PNumb].setSkill(skill)
set LastSelection = u
elseif SkillButtonType[data] == 2 then
call Tooltips1[PNumb].show(true)
call Tooltips2[PNumb].show(false)
call Tooltips1[PNumb].control.move(0, 0, Tooltips1[PNumb].control.zDepth)
call Tooltips1[PNumb].control.refresh()
call Tooltips1[PNumb].setItem(Inventory_SlotIndex[Bag[PNumb]][SkillButtonTarget[data]].object)
set LastSelection = u
endif
endif
endif
endif
set u = null
endif
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(t, Condition(function onOrder))
call TriggerAddCondition(Trigger, Condition(function onSelect))
call TimerStart(CreateTimer(), 0.1, true, function checkSelection)
endfunction
endlibrary
library StatusBox requires PanelPlatform, BJObjectId
/*
~ Status Box
Additional user interface packed with health bar, mana bar, xp bar, and shortcut bar.
Provides elegant looking UI and shortcut click events for your RPG map.
Requires
- PanelSystem | hiveworkshop.com/threads/panel-system-v1-31.292342/
- BJObjectId | hiveworkshop.com/threads/bjobjectid.287128/
How to install:
(Do exactly like what's instructed)
1) Download and import all these textures to your map:
- Download link: https://www.hiveworkshop.com/attachments/statusboxfiles-zip.263146/
- Extract the zip file
- Go to import manager
- Right click, select "Import Files..." (with "s")
- Select the StatuxBoxFiles folder
2) Install PanelSystem properly (uses PanelPlatform plugins)
3) Copy the Status Box trigger group into your map.
4) Go to "ObjectGenerator" trigger, enable it.
5) Save then close and re-open your map.
6) Go to "ObjectGenerator" trigger again, disable it.
7) Save your map. Done.
8) What's left to do to make it functional is to keep updating the StatusBox members
(HP(Max)/MP(Max)/XP(Max)) based on the main unit.
API
struct StatusBox
Members:
static real HP
static real MP
static real XP
static real HPMax
static real MPMax
static real XPMax
- Set/get bar values
readonly static player TriggeringPlayer
- Get clicking player on shortcut click event
readonly static integer TriggeringShortcutIndex
- Get clicked icon index
readonly static integer EventType = 0
- Event type (left click or right click)
static constant integer EVENT_TYPE_LEFT_CLICK = 1
static constant integer EVENT_TYPE_RIGHT_CLICK = 2
- Event type constants
Methods:
static method QuickRefresh takes nothing returns nothing
- Instantly refresh all bars (hp, mp, & xp)
static method RegisterShortcutEvent takes code func returns triggercondition
static method UnregisterShortcutEvent takes triggercondition tc returns nothing
- (Un)register shortcut icon click event
*/
////////////////////
// Configurations //
////////////////////
// Notes:
// - State (bar) refers to both HP & MP bar
globals
// 1. StatusBoxUIPlatform (unit) raw code
private constant integer BOX_PLATFORM_ID = 'e00N'
// 2. StateBarPlatform (unit) raw code
private constant integer BAR_PLATFORM_ID = 'e00M'
// 3. XPBarPlatform (unit) raw code
private constant integer XP_PLATFORM_ID = 0//'hSXP'
// 4. ShortcutIconPlatform (unit) raw code
private constant integer SHORTCUT_PLATFORM_ID = 'hSIP'
// 5. StatusBoxUI (destructable) raw code
private constant integer BOX_TEXTURE_ID = 'BSUI'
// 6. BR Bar 0 (destructable) raw code
private constant integer STATE_BAR_TEXTURE_ID = 'BR00'
// 7. XP Bar 0 (destructable) raw code
private constant integer XP_TEXTURE_ID = 'XP00'
// 8. BarShade&Reflection (destructable) raw code
private constant integer STATE_SHADE_TEXTURE_ID = 'BSSD'
// 9. BarTransparent (destructable) raw code
private constant integer ALPHA_TEXTURE_ID = 'BSAL'
// 10. Level of status box contents
private constant integer BOX_CONTENT_LEVEL = 1
// 11. Status box position coordinate
private constant real UI_POS_X = 0.0
private constant real UI_POS_Y = -284.0-90
// 12. Position coordinate of HP bar
private constant real HP_BAR_X = -386.5
private constant real HP_BAR_Y = -1.0
// 13. Position coordinate of MP bar
private constant real MP_BAR_X = 386.5
private constant real MP_BAR_Y = -1.0
// 14. Position coordinate of XP bar (first column)
private constant real XP_BAR_X = -192.5
private constant real XP_BAR_Y = 10.0
// 15. XP bar texture width
private constant real XP_BAR_WIDTH = 128.0 // px
// 16. XP bar texture width total (4 columns)
private constant real XP_BAR_TOTAL_WIDTH = 512.0 // px
// 17. Position coordinate of the first shortcut icon
private constant real SHORTCUT_POS_X = -270.5
private constant real SHORTCUT_POS_Y = -41.0
// 18. Shortcut icon width
private constant real SHORTCUT_WIDTH = 53.0
// 19. Gap between shortcut icons
private constant real SHORTCUT_GAP = 7.0
// 20. Number of available shortcut icons
private constant integer SHORTCUT_COUNT = 10
// 21. Vertex color for HP bar
private constant integer HP_BAR_RED = 160
private constant integer HP_BAR_GREEN = 15
private constant integer HP_BAR_BLUE = 0
// 22. Vertex color for MP bar
private constant integer MP_BAR_RED = 0
private constant integer MP_BAR_GREEN = 55
private constant integer MP_BAR_BLUE = 160
// 23. Z Depth of the status box
private constant real DEPTH = 0.1
// 24. Update rate of bars (hp, mp, & xp)
private constant real UPDATE_SPEED = 0.05
// 25. Size of the status box
private constant real GENERAL_SIZE = 0.8
// 26. Shortcut icon click event checking interval
private constant real CLICK_CHECK_INTERVAL = 0.01
// 27. Bars texture counts
private constant integer HP_BAR_COUNT = 146
private constant integer MP_BAR_COUNT = 146
private constant integer XP_BAR_COUNT = 65
// 28. Bars refresh interval
private constant real INTERVAL = 0.075
endglobals
//////////////////
// System codes //
//////////////////
struct StatusBox
real HP = 0
real MP = 0
real HPMax = 0
real MPMax = 0
real HPCurrent = 0
real MPCurrent = 0
real XPCurrent = 0
timer Timer
integer Pid
readonly Panel UI
readonly PanelPlatform HPBar
readonly PanelPlatform MPBar
readonly PanelPlatform HPBarShade
readonly PanelPlatform MPBarShade
readonly PanelTextEx HPText
readonly PanelTextEx MPText
private static constant integer XP_BAR_COLUMNS = R2I(XP_BAR_TOTAL_WIDTH/XP_BAR_WIDTH)
private static constant real XP_BAR_SEGMENT = 1./XP_BAR_COLUMNS
static constant integer EVENT_TYPE_LEFT_CLICK = 1
static constant integer EVENT_TYPE_RIGHT_CLICK = 2
method QuickRefresh takes nothing returns nothing
set HPCurrent = HP/HPMax
set MPCurrent = MP/MPMax
endmethod
private static method refresh takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local real hp
local real mp
local real xp
local integer i
local integer j
local integer index
local integer target
local integer data
local BJObjectId id
local PlayerSkill skill
local SkillData sData
local boolean b
local string s
set HP = Fighter[Pid].hp
set HPMax = Fighter[Pid].hpMax
if HPMax > 0 then
set hp = HP/HPMax
set b = true
if HPCurrent > hp then
set HPCurrent = HPCurrent - UPDATE_SPEED
if HPCurrent < hp then
set HPCurrent = hp
endif
elseif HPCurrent < hp then
set HPCurrent = HPCurrent + UPDATE_SPEED
if HPCurrent > hp then
set HPCurrent = hp
endif
else
set b = false
endif
set s = I2S(R2I(HP)) + "/" + I2S(R2I(HPMax))
if HPText.text != s then
call HPText.setText(s, FONTSTYLE_FrizQTShaded)
call HPText.move(HP_BAR_X+140-HPText.width/2, HPText.yOffset, BOX_CONTENT_LEVEL)
call HPText.refresh()
endif
if b then
set id = BJObjectId(STATE_BAR_TEXTURE_ID)
set index = R2I(HPCurrent*I2R(HP_BAR_COUNT))
set i = 0
loop
exitwhen i == index
set id = id.plus_1()
set i = i + 1
endloop
set HPBar.texture = id
call HPBar.refresh()
set id = BJObjectId('TB00')
set index = R2I(HPCurrent*60.)
set i = 0
loop
exitwhen i == index
set id = id.plus_1()
set i = i + 1
endloop
set TeamBarHPTexture[Pid] = id
endif
endif
set MP = Fighter[Pid].sp
set MPMax = Fighter[Pid].spMax
if MPMax > 0 then
set mp = MP/MPMax
set b = true
if MPCurrent > mp then
set MPCurrent = MPCurrent - UPDATE_SPEED
if MPCurrent < mp then
set MPCurrent = mp
endif
elseif MPCurrent < mp then
set MPCurrent = MPCurrent + UPDATE_SPEED
if MPCurrent > mp then
set MPCurrent = mp
endif
else
set b = false
endif
set s = I2S(R2I(MP)) + "/" + I2S(R2I(MPMax))
if MPText.text != s then
call MPText.setText(s, FONTSTYLE_FrizQTShaded)
call MPText.move(MP_BAR_X-140-MPText.width/2, MPText.yOffset, BOX_CONTENT_LEVEL)
call MPText.refresh()
endif
if b then
set id = BJObjectId(STATE_BAR_TEXTURE_ID)
set index = R2I(MPCurrent*I2R(MP_BAR_COUNT))
set i = 0
loop
exitwhen i == index
set id = id.plus_1()
set i = i + 1
endloop
set MPBar.texture = id
call MPBar.refresh()
set id = BJObjectId('TB00')
set index = R2I(MPCurrent*60.)
set i = 0
loop
exitwhen i == index
set id = id.plus_1()
set i = i + 1
endloop
set TeamBarMPTexture[Pid] = id
endif
endif
set i = 0
loop
exitwhen i == 10
set data = GetUnitUserData(ShortcutBar_Button[Pid][i].dummy)
if ShortcutBar_ButtonType[data] == 1 then
set sData = ShortcutBar_ButtonSkill[data]
set skill = PlayerSkillData[Pid][sData]
if Fighter[Pid].isSilenced then
call ShortcutBar_Button[Pid][i].setColor(50, 50, 50, 255)
elseif MP < sData.manacost[skill.level] then
call ShortcutBar_Button[Pid][i].setColor(50, 50, 255, 255)
elseif HP < sData.lifecost[skill.level] then
call ShortcutBar_Button[Pid][i].setColor(255, 50, 50, 255)
else
call ShortcutBar_Button[Pid][i].setColor(255, 255, 255, 255)
endif
endif
set i = i + 1
endloop
set t = null
endmethod
static method create takes player p returns thistype
local thistype this = allocate()
set Timer = NewTimerEx(this)
set Pid = GetPlayerId(p)
set UI = Panel.create(p, BOX_PLATFORM_ID, BOX_TEXTURE_ID, UI_POS_X, UI_POS_Y, DEPTH)
set UI.scale = GENERAL_SIZE
set HPText = PanelTextEx.create(UI, "0/0", FONTSTYLE_FrizQTShaded, HP_BAR_X+140, HP_BAR_Y+12, BOX_CONTENT_LEVEL)
set MPText = PanelTextEx.create(UI, "0/0", FONTSTYLE_FrizQTShaded, MP_BAR_X-140, MP_BAR_Y+12, BOX_CONTENT_LEVEL)
set HPText.scale = 0.375
set MPText.scale = 0.375
set HPBar = PanelPlatform.create(UI, BAR_PLATFORM_ID, STATE_BAR_TEXTURE_ID, HP_BAR_X, HP_BAR_Y, BOX_CONTENT_LEVEL)
set MPBar = PanelPlatform.create(UI, BAR_PLATFORM_ID, STATE_BAR_TEXTURE_ID, MP_BAR_X, MP_BAR_Y, BOX_CONTENT_LEVEL)
set HPBarShade = PanelPlatform.create(UI, BAR_PLATFORM_ID, STATE_SHADE_TEXTURE_ID, HP_BAR_X, HP_BAR_Y, BOX_CONTENT_LEVEL+1)
set MPBarShade = PanelPlatform.create(UI, BAR_PLATFORM_ID, STATE_SHADE_TEXTURE_ID, MP_BAR_X, MP_BAR_Y, BOX_CONTENT_LEVEL+1)
call HPBar.setColor(HP_BAR_RED, HP_BAR_GREEN, HP_BAR_BLUE, 255)
call MPBar.setColor(MP_BAR_RED, MP_BAR_GREEN, MP_BAR_BLUE, 255)
call UI.show(true)
call UI.refresh()
call TimerStart(Timer, INTERVAL, true, function thistype.refresh)
return this
endmethod
endstruct
endlibrary
//! textmacro CreateBarObject takes TYPE, CODE, INDEX, FILEPATH, EXTENSION
//! external ObjectMerger w3b YTlb $TYPE$$CODE$ bnam "(Status Box) $TYPE$ Bar $INDEX$" bfxr -1 bfil ".mdl" boch 0 btxf "$FILEPATH$$INDEX$$EXTENSION$" btxi 33 bfvi 1 bsel 0 bgsc 0 bshd "" barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
/*
//! external ObjectMerger w3a Agra ASCT anam "(Status Box) TextureReplacer" aani "" gra1 1 0 gra2 1 0 gra3 1 3 gra4 1 3 gra5 1 0 aran 1 99999 acdn 1 0 arac "other" atar 1 "debris,decoration,structure,tree" atp1 1 "" aub1 1 ""
//! external ObjectMerger w3b YTlb BSAL bnam "(Status Box) Transparent" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\StatusBoxAlpha.blp" btxi 33 bsel 0 bgsc 0 bshd "" barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb BSUI bnam "(Status Box) UI" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\StatusBoxUI.blp" btxi 33 bsel 0 bgsc 0 bshd "" barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb BSSD bnam "(Status Box) BarShade&Reflection" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BarShade&Reflection.blp" btxi 33 bsel 0 bgsc 0 bshd "" barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3u hfoo hSIP unsf "(Status Box) ShortcutIconPlatform" unam "" umdl "war3mapImported\ShortcutIconPlatform.mdl" ubdg 1 uabi "Avul" uble 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" uaen "" udea "" umvt "" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
//! external ObjectMerger w3u hfoo hSBR unsf "(Status Box) StateBarPlatform" unam "" umdl "war3mapImported\StateBarPlatform.mdl" uabi "Aloc" uble 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" uaen "" udea "" umvt "" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
//! external ObjectMerger w3u hfoo hSBU unsf "(Status Box) UIPlatform" unam "" umdl "war3mapImported\StatusBoxUIPlatform.mdl" uabi "Aloc" uble 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" uaen "" udea "" umvt "" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
//! external ObjectMerger w3u hfoo hSXP unsf "(Status Box) XPBarPlatform" unam "" umdl "war3mapImported\XPBarPlatform.mdl" uabi "Aloc" uble 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" uaen "" udea "" umvt "" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
*/
//! runtextmacro CreateBarObject ("BR", "00", "0", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "01", "1", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "02", "2", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "03", "3", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "04", "4", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "05", "5", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "06", "6", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "07", "7", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "08", "8", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "09", "9", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0A", "10", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0B", "11", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0C", "12", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0D", "13", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0E", "14", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0F", "15", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0G", "16", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0H", "17", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0I", "18", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0J", "19", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0K", "20", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0L", "21", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0M", "22", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0N", "23", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0O", "24", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0P", "25", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0Q", "26", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0R", "27", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0S", "28", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0T", "29", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0U", "30", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0V", "31", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0W", "32", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0X", "33", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0Y", "34", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "0Z", "35", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "10", "36", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "11", "37", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "12", "38", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "13", "39", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "14", "40", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "15", "41", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "16", "42", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "17", "43", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "18", "44", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "19", "45", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1A", "46", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1B", "47", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1C", "48", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1D", "49", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1E", "50", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1F", "51", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1G", "52", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1H", "53", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1I", "54", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1J", "55", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1K", "56", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1L", "57", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1M", "58", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1N", "59", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1O", "60", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1P", "61", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1Q", "62", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1R", "63", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1S", "64", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1T", "65", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1U", "66", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1V", "67", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1W", "68", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1X", "69", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1Y", "70", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "1Z", "71", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "20", "72", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "21", "73", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "22", "74", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "23", "75", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "24", "76", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "25", "77", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "26", "78", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "27", "79", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "28", "80", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "29", "81", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2A", "82", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2B", "83", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2C", "84", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2D", "85", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2E", "86", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2F", "87", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2G", "88", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2H", "89", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2I", "90", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2J", "91", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2K", "92", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2L", "93", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2M", "94", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2N", "95", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2O", "96", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2P", "97", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2Q", "98", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2R", "99", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2S", "100", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2T", "101", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2U", "102", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2V", "103", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2W", "104", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2X", "105", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2Y", "106", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "2Z", "107", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "30", "108", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "31", "109", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "32", "110", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "33", "111", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "34", "112", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "35", "113", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "36", "114", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "37", "115", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "38", "116", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "39", "117", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3A", "118", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3B", "119", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3C", "120", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3D", "121", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3E", "122", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3F", "123", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3G", "124", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3H", "125", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3I", "126", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3J", "127", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3K", "128", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3L", "129", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3M", "130", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3N", "131", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3O", "132", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3P", "133", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3Q", "134", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3R", "135", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3S", "136", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3T", "137", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3U", "138", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3V", "139", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3W", "140", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3X", "141", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3Y", "142", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "3Z", "143", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "40", "144", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "41", "145", "war3mapImported\CustomBar", ".blp")
//! runtextmacro CreateBarObject ("BR", "42", "146", "war3mapImported\CustomBar", ".blp")
/*
//! runtextmacro CreateBarObject ("XP", "00", "0", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "01", "1", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "02", "2", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "03", "3", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "04", "4", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "05", "5", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "06", "6", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "07", "7", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "08", "8", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "09", "9", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0A", "10", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0B", "11", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0C", "12", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0D", "13", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0E", "14", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0F", "15", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0G", "16", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0H", "17", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0I", "18", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0J", "19", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0K", "20", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0L", "21", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0M", "22", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0N", "23", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0O", "24", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0P", "25", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0Q", "26", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0R", "27", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0S", "28", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0T", "29", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0U", "30", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0V", "31", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0W", "32", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0X", "33", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0Y", "34", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0Z", "35", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "10", "36", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "11", "37", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "12", "38", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "13", "39", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "14", "40", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "15", "41", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "16", "42", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "17", "43", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "18", "44", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "19", "45", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1A", "46", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1B", "47", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1C", "48", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1D", "49", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1E", "50", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1F", "51", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1G", "52", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1H", "53", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1I", "54", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1J", "55", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1K", "56", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1L", "57", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1M", "58", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1N", "59", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1O", "60", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1P", "61", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1Q", "62", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1R", "63", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1S", "64", "war3mapImported\CustomXPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1T", "65", "war3mapImported\CustomXPBar", ".blp")*/
//! textmacro CreateBarObject takes TYPE, CODE, INDEX, FILEPATH, EXTENSION
//! external ObjectMerger w3b YTlb $TYPE$$CODE$ bnam "(Shortcut Bar) XP Bar $INDEX$" bfxr -1 bfil ".mdl" boch 0 btxf "$FILEPATH$$INDEX$$EXTENSION$" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
//! runtextmacro CreateBarObject ("XP", "00", "0", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "01", "1", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "02", "2", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "03", "3", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "04", "4", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "05", "5", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "06", "6", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "07", "7", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "08", "8", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "09", "9", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0A", "10", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0B", "11", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0C", "12", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0D", "13", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0E", "14", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0F", "15", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0G", "16", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0H", "17", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0I", "18", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0J", "19", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0K", "20", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0L", "21", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0M", "22", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0N", "23", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0O", "24", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0P", "25", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0Q", "26", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0R", "27", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0S", "28", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0T", "29", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0U", "30", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0V", "31", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0W", "32", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0X", "33", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0Y", "34", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "0Z", "35", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "10", "36", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "11", "37", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "12", "38", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "13", "39", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "14", "40", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "15", "41", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "16", "42", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "17", "43", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "18", "44", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "19", "45", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1A", "46", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1B", "47", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1C", "48", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1D", "49", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1E", "50", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1F", "51", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1G", "52", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1H", "53", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1I", "54", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1J", "55", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1K", "56", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1L", "57", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1M", "58", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1N", "59", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1O", "60", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1P", "61", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1Q", "62", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1R", "63", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1S", "64", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1T", "65", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1U", "66", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1V", "67", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1W", "68", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1X", "69", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1Y", "70", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "1Z", "71", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "20", "72", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "21", "73", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "22", "74", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "23", "75", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "24", "76", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "25", "77", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "26", "78", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "27", "79", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "28", "80", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "29", "81", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2A", "82", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2B", "83", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2C", "84", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2D", "85", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2E", "86", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2F", "87", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2G", "88", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2H", "89", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2I", "90", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2J", "91", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2K", "92", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2L", "93", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2M", "94", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2N", "95", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2O", "96", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2P", "97", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2Q", "98", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2R", "99", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2S", "100", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2T", "101", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2U", "102", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2V", "103", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2W", "104", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2X", "105", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2Y", "106", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "2Z", "107", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "30", "108", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "31", "109", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "32", "110", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "33", "111", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "34", "112", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "35", "113", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "36", "114", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "37", "115", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "38", "116", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "39", "117", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3A", "118", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3B", "119", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3C", "120", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3D", "121", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3E", "122", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3F", "123", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3G", "124", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3H", "125", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3I", "126", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3J", "127", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3K", "128", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3L", "129", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3M", "130", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3N", "131", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3O", "132", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3P", "133", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3Q", "134", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3R", "135", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3S", "136", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3T", "137", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3U", "138", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3V", "139", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3W", "140", "war3mapImported\XPBar", ".blp")
//! runtextmacro CreateBarObject ("XP", "3X", "141", "war3mapImported\XPBar", ".blp")
library TeamBar uses PanelPlatform
globals
Panel array TeamBars
integer array TeamBarHPTexture
integer array TeamBarMPTexture
private real array BarX
endglobals
struct TeamBar
PanelPlatform hpBar
PanelPlatform mpBar
PanelPlatform emblem
PanelTextEx index
integer id
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
if IsPlaying[.id] then
if .emblem.texture == 'B05Y' and Fighter[.id] != 0 then
if Fighter[.id].uid == 'h004' then
set .emblem.texture = 'B05W'
elseif Fighter[.id].uid == 'h00C' then
set .emblem.texture = 'B05X'
endif
call .emblem.refresh()
endif
set .hpBar.texture = TeamBarHPTexture[.id]
set .mpBar.texture = TeamBarMPTexture[.id]
call .hpBar.refresh()
call .mpBar.refresh()
else
call ReleaseTimer(t)
call .hpBar.destroy()
call .mpBar.destroy()
call .emblem.destroy()
call .index.destroy()
call deallocate()
endif
set t = null
endmethod
static method create takes Panel target, integer id, real x returns thistype
local thistype this = allocate()
set .id = id
if Fighter[id].uid == 'h004' then
set .emblem = PanelPlatform.create(target, 'e01I', 'B05W', x, -322, 1)
elseif Fighter[id].uid == 'h00C' then
set .emblem = PanelPlatform.create(target, 'e01I', 'B05X', x, -322, 1)
else
set .emblem = PanelPlatform.create(target, 'e01I', 'B05Y', x, -322, 1)
endif
set .hpBar = PanelPlatform.create(target, 'e01H', 'TB00', x+9, -321, 0)
call .hpBar.setColor(203, 10, 10, 255)
set .mpBar = PanelPlatform.create(target, 'e01G', 'TB00', x+9, -321, 0)
call .mpBar.setColor(20, 20, 175, 255)
set .index = PanelTextEx.create(target, "P" + I2S(id+1), FONTSTYLE_FrizQTShaded, x-27, -303, 2)
set .index.scale = 0.3
call .index.move(x-29-.index.width/2, -303, 2)
call .hpBar.refresh()
call .mpBar.refresh()
call .index.refresh()
call TimerStart(NewTimerEx(this), 0.03125, true, function thistype.onTick)
return this
endmethod
endstruct
endlibrary
//! textmacro Createwar3mapImported\TeamBarObject takes TYPE, CODE, INDEX, FILEPATH, EXTENSION
//! external ObjectMerger w3b YTlb $TYPE$$CODE$ bnam "(TeamBar) $TYPE$ Bar $INDEX$" bfxr -1 bfil ".mdl" boch 0 btxf "$FILEPATH$$INDEX$$EXTENSION$" btxi 33 bfvi 1 bsel 0 bgsc 0 bshd "" barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "00", "0", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "01", "1", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "02", "2", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "03", "3", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "04", "4", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "05", "5", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "06", "6", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "07", "7", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "08", "8", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "09", "9", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0A", "10", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0B", "11", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0C", "12", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0D", "13", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0E", "14", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0F", "15", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0G", "16", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0H", "17", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0I", "18", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0J", "19", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0K", "20", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0L", "21", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0M", "22", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0N", "23", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0O", "24", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0P", "25", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0Q", "26", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0R", "27", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0S", "28", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0T", "29", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0U", "30", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0V", "31", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0W", "32", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0X", "33", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0Y", "34", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "0Z", "35", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "10", "36", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "11", "37", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "12", "38", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "13", "39", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "14", "40", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "15", "41", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "16", "42", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "17", "43", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "18", "44", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "19", "45", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1A", "46", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1B", "47", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1C", "48", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1D", "49", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1E", "50", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1F", "51", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1G", "52", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1H", "53", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1I", "54", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1J", "55", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1K", "56", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1L", "57", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1M", "58", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1N", "59", "war3mapImported\TeamBar", ".blp")
//! runtextmacro Createwar3mapImported\TeamBarObject ("TB", "1O", "60", "war3mapImported\TeamBar", ".blp")
library ClassSelection initializer init uses GameConstants, PanelCore, PlayerInit, Fader
globals
private constant integer CLASS_PAGE_COUNT = 1
private constant integer PET_PAGE_COUNT = 2
public integer array EntrySelectionIndex
public integer array ClassSelectionIndex
public integer array PetSelectionIndex
public integer array ClassPage
public integer array PetPage
public unit array PreviewClassUnit
public unit array PreviewPetUnit
public effect array PreviewClass
public effect array PreviewPet
// UI components
public Panel array UI_LoadEntry
public Panel array UI_LoadControl
public Panel array UI_Selection
public Panel array UI_Header
public Panel array UI_Control
public PanelPlatform array UI_Selection_Class_Button[4][4]
public PanelPlatform array UI_Selection_Class_LeftArrow
public PanelPlatform array UI_Selection_Class_RightArrow
public PanelPlatform array UI_Selection_Pet_Button[4][4]
public PanelPlatform array UI_Selection_Pet_LeftArrow
public PanelPlatform array UI_Selection_Pet_RightArrow
public PanelTextTag array UI_Control_NameInput
public PanelPlatform array UI_Control_NameText
public PanelPlatform array UI_Control_Input
public PanelPlatform array UI_Control_Button
public PanelPlatform array UI_Control_Warning
public PanelPlatform array UI_Control_Return
public PanelPlatform array UI_Control_Return2
public PanelPlatform array UI_Control_Load
public PanelPlatform array UI_Control_Delete
private integer array Headers
private integer array ClassIcons
private string array ClassModels
private real array ClassScale
private integer array PetIcons
private string array PetModels
private real array PetScale
private real array PetHeight
private integer array Warnings
private real PreviewX = 0.
private real PreviewY = 0.
private real PreviewA = 0.
private real PetX = 0.
private real PetY = 0.
private real PetA = 0.
private LoadEntry array Entries
private LoadEntry array Entry[4][7]
private dialog Confirmation
private button ConfirmationYes
public trigger array NameInputTrigger
endglobals
struct LoadEntry extends array
PanelPlatform Background
PanelPlatform Icon
PanelTextTag Name
PanelTextTag Level
PanelTextTag Title
integer char
integer pet
boolean exist
implement LinkedList
endstruct
private function GetStringLine takes string source, integer whichLine returns string
local integer length = StringLength(source)
local integer i = 0
local integer currentline = 0
local string currentlinestr=""
loop
exitwhen i > length
if (SubString(source, i, i+2) == "|n") then
set currentline=currentline+1
if (currentline==whichLine) then
return currentlinestr
else
set currentlinestr = ""
set i = i + 1
endif
else
set currentlinestr = currentlinestr + SubString(source, i, i+1)
endif
set i = i + 1
endloop
return currentlinestr
endfunction
private function SetClassPreview takes integer id, integer index returns nothing
local player p = Player(id)
call RemoveUnit(PreviewClassUnit[id])
call DestroyEffect(PreviewClass[id])
set PreviewClassUnit[id] = CreateUnit(p, 'e000', PreviewX, PreviewY, PreviewA)
static if not LIBRARY_AutoFly then
if UnitAddAbility(PreviewClassUnit[id], 'Amrf') and UnitRemoveAbility(PreviewClassUnit[id], 'Amrf') then
endif
endif
if Locale == p then
call SetUnitScale(PreviewClassUnit[id], ClassScale[index], 1, 1)
else
call SetUnitScale(PreviewClassUnit[id], 0, 0, 0)
endif
set PreviewClass[id] = AddSpecialEffectTarget(ClassModels[index], PreviewClassUnit[id], "origin")
endfunction
private function SetPetPreview takes integer id, integer index returns nothing
local player p = Player(id)
call RemoveUnit(PreviewPetUnit[id])
call DestroyEffect(PreviewPet[id])
set PreviewPetUnit[id] = CreateUnit(p, 'e000', PetX, PetY, PetA)
static if not LIBRARY_AutoFly then
if UnitAddAbility(PreviewPetUnit[id], 'Amrf') and UnitRemoveAbility(PreviewPetUnit[id], 'Amrf') then
endif
endif
if Locale == p then
call SetUnitScale(PreviewPetUnit[id], PetScale[index], 1, 1)
else
call SetUnitScale(PreviewPetUnit[id], 0, 0, 0)
endif
call SetUnitFlyHeight(PreviewPetUnit[id], PetHeight[index], 0)
set PreviewPet[id] = AddSpecialEffectTarget(PetModels[index], PreviewPetUnit[id], "origin")
endfunction
public function SelectEntry takes integer id, integer index returns nothing
local player p
if EntrySelectionIndex[id] != index then
set p = Player(id)
set Entry[id][EntrySelectionIndex[id]].Background.texture = 'B08D'
call Entry[id][EntrySelectionIndex[id]].Background.refresh()
set EntrySelectionIndex[id] = index
set Entry[id][index].Background.texture = 'B08C'
call Entry[id][index].Background.refresh()
call SetClassPreview(id, Entry[id][index].char)
call SetPetPreview(id, Entry[id][index].pet)
//if not IsLAN then
//set UI_Header[id].background = Headers[Entry[id][index].char]
//call UI_Header[id].refresh()
//endif
call UI_Control_Load[id].show(Entry[id][index].exist)
call UI_Control_Delete[id].show(Entry[id][index].exist)
call UI_Control_Load[id].refresh()
call UI_Control_Delete[id].refresh()
endif
endfunction
public function RefreshLoadEntries takes integer id returns nothing
local File f
local LoadEntry entry = Entries[id].next
local integer i = 0
local player p = Player(id)
local boolean show
local string read
local integer icon
loop
exitwhen entry.head or entry == 0
set icon = 'UNAV'
set show = false
if Locale == p then
set f = File.open(MAP_NAME, GetPlayerName(p)+"\\"+CharacterManager_GameMode+"\\Slot-"+I2S(i), File.Flag.READ)
set read = f.read()
set show = StringLength(read) > 0
if show then
call entry.Name.setText(GetStringLine(read, 1), 0.018)
call entry.Level.setText(GetStringLine(read, 2), 0.018)
set entry.char = S2I(GetStringLine(read, 3))
set entry.pet = S2I(GetStringLine(read, 4))
set icon = ClassIcons[entry.char]
else
set entry.char = 0
set entry.pet = 0
endif
call f.close()
endif
set entry.exist = show
if IsLAN then
set entry.Icon.texture = 'UNAV'
else
set entry.Icon.texture = icon
endif
set entry.Background.texture = 'B08D'
call entry.Icon.show(show)
call entry.Name.show(show)
call entry.Level.show(show)
call entry.Title.show(show)
call entry.Icon.refresh()
call entry.Background.refresh()
set entry = entry.next
set i = i + 1
endloop
set EntrySelectionIndex[id] = 0
call SelectEntry(id, 1)
endfunction
public function ToMainMenu takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
if Locale == Player(id) then
call SetDayNightModels("war3mapImported\\DNCNight.mdx", "war3mapImported\\DNCNight.mdx")
endif
call UI_Header[id].show(false)
call UI_Control[id].show(false)
call UI_Selection[id].show(false)
call UI_LoadEntry[id].show(false)
call UI_LoadControl[id].show(false)
call MainMenu_MainPanel[id].show(true)
call PlayerCamera[id].applyCameraSetup(gg_cam_Cine7, true, 0)
call PlayerCamera[id].refresh()
call ReleaseTimer(t)
set t = null
endfunction
public function ReturnToMainMenu takes integer id returns nothing
call DisableTrigger(NameInputTrigger[id])
call Fader_FadeInOut(id, 1)
call TimerStart(NewTimerEx(id), 1., false, function ToMainMenu)
endfunction
public function SetClassPage takes integer id, integer page returns nothing
local integer i = 0
if page < 0 then
set page = CLASS_PAGE_COUNT - 1
elseif page == CLASS_PAGE_COUNT then
set page = 0
endif
set ClassPage[id] = page
loop
exitwhen i > 3
set UI_Selection_Class_Button[id][i].texture = ClassIcons[i + 4*ClassPage[id]+1]
call UI_Selection_Class_Button[id][i].show(ClassIcons[i + 4*ClassPage[id]+1] > 0)
call UI_Selection_Class_Button[id][i].refresh()
set i = i + 1
endloop
endfunction
public function SetPetPage takes integer id, integer page returns nothing
local integer i = 0
if page < 0 then
set page = PET_PAGE_COUNT - 1
elseif page == PET_PAGE_COUNT then
set page = 0
endif
set PetPage[id] = page
loop
exitwhen i > 3
set UI_Selection_Pet_Button[id][i].texture = PetIcons[i + 4*PetPage[id]+1]
call UI_Selection_Pet_Button[id][i].show(PetIcons[i + 4*PetPage[id]+1] > 0)
call UI_Selection_Pet_Button[id][i].refresh()
set i = i + 1
endloop
endfunction
private function ShowWarning takes integer id, integer i returns nothing
set UI_Control_Warning[id].texture = Warnings[i]
call UI_Control_Warning[id].refresh()
call Fade.create(UI_Control_Warning[id].dummy, 425, -2.5)
endfunction
public function Create takes integer i returns nothing
local LoadEntry entry
local BJObjectId id
local player p = Player(i)
local integer j
local real y
set ClassSelectionIndex[i] = 1
set PetSelectionIndex[i] = 1
set UI_LoadEntry[i] = Panel.create(p, 'e01R', 'B08B', -500, 0, 0.0)
set UI_LoadControl[i] = Panel.create(p, 'e000', 'BSAL', 0, 0, 0.0)
set UI_Control_Load[i] = PanelPlatform.create(UI_LoadControl[i], 'e029', 'B08F', -77.5, -237, 0)
set UI_Control_Delete[i] = PanelPlatform.create(UI_LoadControl[i], 'e029', 'B08E', 77.5, -237, 0)
set UI_Control_Return2[i] = PanelPlatform.create(UI_LoadControl[i], 'e029', 'B089', 534, 278, 0)
set UI_Selection[i] = Panel.create(p, 'e01R', 'B07M', -500, 0, 0.0)
set UI_Selection_Pet_LeftArrow[i] = PanelPlatform.create(UI_Selection[i], 'e01W', 'B07S', -84, -135, 1)
set UI_Selection_Pet_RightArrow[i] = PanelPlatform.create(UI_Selection[i], 'e01X', 'B07T', 84, -135, 1)
set UI_Selection_Class_LeftArrow[i] = PanelPlatform.create(UI_Selection[i], 'e01Y', 'B07S', -84, 40, 1)
set UI_Selection_Class_RightArrow[i] = PanelPlatform.create(UI_Selection[i], 'e01Z', 'B07T', 84, 40, 1)
call UI_Selection_Class_LeftArrow[i].show(false)
call UI_Selection_Class_RightArrow[i].show(false)
set UI_Selection_Class_Button[i][0] = PanelPlatform.create(UI_Selection[i], 'e020', 'BSAL', -29, 112, 1)
set UI_Selection_Class_Button[i][1] = PanelPlatform.create(UI_Selection[i], 'e021', 'BSAL', 32, 112, 1)
set UI_Selection_Class_Button[i][2] = PanelPlatform.create(UI_Selection[i], 'e022', 'BSAL', -30, 47, 1)
set UI_Selection_Class_Button[i][3] = PanelPlatform.create(UI_Selection[i], 'e023', 'BSAL', 32, 47, 1)
set UI_Selection_Class_Button[i][0].scale = 0.75
set UI_Selection_Class_Button[i][1].scale = 0.75
set UI_Selection_Class_Button[i][2].scale = 0.75
set UI_Selection_Class_Button[i][3].scale = 0.75
set UI_Selection_Pet_Button[i][0] = PanelPlatform.create(UI_Selection[i], 'e024', 'BSAL', -30, 112-213, 1)
set UI_Selection_Pet_Button[i][1] = PanelPlatform.create(UI_Selection[i], 'e025', 'BSAL', 31, 112-213, 1)
set UI_Selection_Pet_Button[i][2] = PanelPlatform.create(UI_Selection[i], 'e026', 'BSAL', -31, 47-213, 1)
set UI_Selection_Pet_Button[i][3] = PanelPlatform.create(UI_Selection[i], 'e027', 'BSAL', 31, 47-213, 1)
set UI_Selection_Pet_Button[i][0].scale = 0.75
set UI_Selection_Pet_Button[i][1].scale = 0.75
set UI_Selection_Pet_Button[i][2].scale = 0.75
set UI_Selection_Pet_Button[i][3].scale = 0.75
set UI_Header[i] = Panel.create(p, 'e01S', 'B07O', 0, 200, 0.0)
set UI_Control[i] = Panel.create(p, 'e000', 'BSAL', 0, 0, 0.0)
set UI_Control_Input[i] = PanelPlatform.create(UI_Control[i], 'e01U', 'B07Q', -40, -230, 0)
set UI_Control_NameText[i] = PanelPlatform.create(UI_Control[i], 'e01T', 'B07P', -40, -200, 0)
set UI_Control_Button[i] = PanelPlatform.create(UI_Control[i], 'e01V', 'B07R', 82, -223, 0)
set UI_Control_Warning[i] = PanelPlatform.create(UI_Control[i], 'e028', 'BSAL', -40, -260, 0)
set UI_Control_NameInput[i] = PanelTextTag.create(UI_Control[i], "", 0.014, -110, -237)
set UI_Control_Return[i] = PanelPlatform.create(UI_Control[i], 'e029', 'B089', 534, 278, 0)
call UI_Header[i].show(false)
call UI_Control[i].show(false)
call UI_Selection[i].show(false)
call UI_LoadEntry[i].show(false)
call UI_LoadControl[i].show(false)
set Entries[i] = LoadEntry.createNode()
set j = 0
set id = 'eML0'
loop
exitwhen j == MAX_SAVE_SLOT
set id = id.plus_1()
set entry = LoadEntry.allocate()
set Entry[i][j+1] = entry
set y = 120-58*j
set entry.Background = PanelPlatform.create(UI_LoadEntry[i], id, 'B08D', 0, y, 1)
set entry.Icon = PanelPlatform.create(UI_LoadEntry[i], 'e007', 'B07U', -89, y, 2)
set entry.Name = PanelTextTag.create(UI_LoadEntry[i], "-", 0.018, -55, y+7)
set entry.Level = PanelTextTag.create(UI_LoadEntry[i], "-", 0.018, -55, y-8)
set entry.Title = PanelTextTag.create(UI_LoadEntry[i], "Unknown", 0.018, -55, y-23)
set entry.Icon.scale = 0.75
call entry.Name.setColor(224, 201, 73, 255)
call entry.Title.setColor(86, 119, 185, 255)
call entry.Icon.show(false)
call entry.Name.show(false)
call entry.Level.show(false)
call entry.Title.show(false)
call Entries[i].insertNode(entry)
set j = j + 1
endloop
set PreviewClassUnit[i] = CreateUnit(p, 'e000', PreviewX, PreviewY, PreviewA)
set PreviewPetUnit[i] = CreateUnit(p, 'e000', PetX, PetY, PetA)
if Locale != p then
call SetUnitScale(PreviewClassUnit[i], 0, 0, 0)
call SetUnitScale(PreviewPetUnit[i], 0, 0, 0)
endif
set PreviewClass[i] = AddSpecialEffectTarget(ClassModels[0], PreviewClassUnit[i], "origin")
set PreviewPet[i] = AddSpecialEffectTarget(PetModels[0], PreviewPetUnit[i], "origin")
call SetClassPage(i, 0)
call SetPetPage(i, 0)
endfunction
public function CreateNewCharacter takes integer id returns nothing
local player p = Player(id)
call SetClassPreview(id, ClassSelectionIndex[id])
call SetPetPreview(id, PetSelectionIndex[id])
set UI_Header[id].background = Headers[ClassSelectionIndex[id]]
call UI_Header[id].refresh()
call UI_Header[id].show(true)
call UI_Control[id].show(true)
call UI_Selection[id].show(true)
call UI_LoadEntry[id].show(false)
call UI_LoadControl[id].show(false)
call UI_Selection[id].refresh()
call UI_Header[id].refresh()
call UI_Control[id].refresh()
call UI_LoadEntry[id].refresh()
call UI_LoadControl[id].refresh()
call EnableTrigger(NameInputTrigger[id])
endfunction
public function LoadCharacter takes integer id returns nothing
call RefreshLoadEntries(id)
call UI_Header[id].show(false)
call UI_Control[id].show(false)
call UI_Selection[id].show(false)
call UI_LoadEntry[id].show(true)
call UI_LoadControl[id].show(true)
call UI_Selection[id].refresh()
call UI_Header[id].refresh()
call UI_Control[id].refresh()
call UI_LoadEntry[id].refresh()
call UI_LoadControl[id].refresh()
endfunction
private function onSelect takes nothing returns boolean
local player p = GetTriggerPlayer()
local integer id = GetPlayerId(p)
local unit u = GetTriggerUnit()
local unit new
local integer i = 0
local integer selection
if u == UI_Selection_Pet_LeftArrow[id].dummy then
call SetPetPage(id, PetPage[id] - 1)
if Locale == p then
call ClearSelection()
endif
elseif u == UI_Selection_Pet_RightArrow[id].dummy then
call SetPetPage(id, PetPage[id] + 1)
if Locale == p then
call ClearSelection()
endif
elseif u == UI_Control_Input[id].dummy then
call ShowWarning(id, 0)
if Locale == p then
call ClearSelection()
endif
elseif u == UI_Control_Return[id].dummy or u == UI_Control_Return2[id].dummy then
call ReturnToMainMenu(id)
if Locale == p then
call ClearSelection()
endif
elseif u == UI_Control_Button[id].dummy then
if StringLength(UI_Control_NameInput[id].text) > 0 then
call DialogClear(Confirmation)
call DialogSetMessage(Confirmation, "|cffffcc00Create a new " + GetObjectName(GetIndexType(ClassSelectionIndex[id])) + "?|r")
set ConfirmationYes = DialogAddButton(Confirmation, "|cffffffffYes|r", 0)
call DialogAddButton(Confirmation, "|cffffffffNo|r", 0)
call DialogDisplay(p, Confirmation, true)
else
call ShowWarning(id, 2)
endif
if Locale == p then
call ClearSelection()
endif
elseif u == UI_Control_Load[id].dummy then
set CharacterManager_SaveSlot[id] = EntrySelectionIndex[id]-1
call DialogClear(CharacterManager_ManagerDialog[id])
call DialogSetMessage(CharacterManager_ManagerDialog[id], "|cffffcc00Load " + Entry[id][EntrySelectionIndex[id]].Name.text + " (" + Entry[id][EntrySelectionIndex[id]].Level.text + ")?|r")
set CharacterManager_ManagerButton[id][MAX_SAVE_SLOT+4] = DialogAddButton(CharacterManager_ManagerDialog[id], "|cffffffffYes|r", 0)
set CharacterManager_ManagerButton[id][MAX_SAVE_SLOT+1] = DialogAddButton(CharacterManager_ManagerDialog[id], "|cffffffffCancel|r", 0)
call DialogDisplay(p, CharacterManager_ManagerDialog[id], true)
if Locale == p then
call ClearSelection()
endif
elseif u == UI_Control_Delete[id].dummy then
set CharacterManager_SaveSlot[id] = EntrySelectionIndex[id]-1
call DialogClear(CharacterManager_ManagerDialog[id])
call DialogSetMessage(CharacterManager_ManagerDialog[id], "|cffff0000Delete " + Entry[id][EntrySelectionIndex[id]].Name.text + " (" + Entry[id][EntrySelectionIndex[id]].Level.text + ")?|r")
set CharacterManager_ManagerButton[id][MAX_SAVE_SLOT+1] = DialogAddButton(CharacterManager_ManagerDialog[id], "|cffffffffNo|r", 0)
set CharacterManager_ManagerButton[id][MAX_SAVE_SLOT+6] = DialogAddButton(CharacterManager_ManagerDialog[id], "|cffffffffYes|r", 0)
call DialogDisplay(p, CharacterManager_ManagerDialog[id], true)
if Locale == p then
call ClearSelection()
endif
else
loop
exitwhen i > 3
if u == UI_Selection_Class_Button[id][i].dummy then
set selection = i + 4*ClassPage[id] + 1
if ClassSelectionIndex[id] != selection then
set ClassSelectionIndex[id] = selection
call SetClassPreview(id, ClassSelectionIndex[id])
set UI_Header[id].background = Headers[ClassSelectionIndex[id]]
call UI_Header[id].refresh()
endif
if Locale == p then
call ClearSelection()
endif
return false
elseif u == UI_Selection_Pet_Button[id][i].dummy then
set selection = i + 4*PetPage[id] + 1
if PetSelectionIndex[id] != selection then
set PetSelectionIndex[id] = selection
call SetPetPreview(id, PetSelectionIndex[id])
endif
if Locale == p then
call ClearSelection()
endif
return false
endif
set i = i + 1
endloop
set i = 1
loop
exitwhen i > MAX_SAVE_SLOT
if u == Entry[id][i].Background.dummy then
call SelectEntry(id, i)
if Locale == p then
call ClearSelection()
endif
endif
set i = i + 1
endloop
endif
return false
endfunction
private function onClick takes nothing returns boolean
local player p
local integer id
local unit new
if GetClickedButton() == ConfirmationYes then
set p = GetTriggerPlayer()
set id = GetPlayerId(p)
call UI_Header[id].show(false)
call UI_Control[id].show(false)
call UI_Selection[id].show(false)
set CharacterName[id] = UI_Control_NameInput[id].text
call DisableTrigger(NameInputTrigger[id])
set CreateNew[id] = true
set new = CreateUnit(p, GetIndexType(ClassSelectionIndex[id]), PreviewX, PreviewY, 0)
set Pet[id] = CreateUnit(p, GetPetType(PetSelectionIndex[id]), PreviewX, PreviewY, 0)
call InitPlayer(new)
set new = null
endif
return false
endfunction
private function inputName takes nothing returns boolean
local player p = GetTriggerPlayer()
local integer id = GetPlayerId(p)
local string s = GetEventPlayerChatString()
if StringLength(s) > 12 then
call ShowWarning(id, 1)
set s = SubString(s, 0, 11)
endif
call UI_Control_NameInput[id].setText(s, 0.014)
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SELECTED)
call TriggerAddCondition(t, Condition(function onSelect))
set Confirmation = DialogCreate()
set t = CreateTrigger()
call TriggerRegisterDialogEvent(t, Confirmation)
call TriggerAddCondition(t, Condition(function onClick))
loop
exitwhen i > 3
set NameInputTrigger[i] = CreateTrigger()
call TriggerRegisterPlayerChatEvent(NameInputTrigger[i], Player(i), "", false)
call TriggerAddCondition(NameInputTrigger[i], Condition(function inputName))
call DisableTrigger(NameInputTrigger[i])
set i = i + 1
endloop
set PreviewX = GetUnitX(gg_unit_h004_0019)
set PreviewY = GetUnitY(gg_unit_h004_0019)
set PreviewA = GetUnitFacing(gg_unit_h004_0019)
call RemoveUnit(gg_unit_h004_0019)
set PetX = GetUnitX(gg_unit_h028_0038)
set PetY = GetUnitY(gg_unit_h028_0038)
set PetA = GetUnitFacing(gg_unit_h028_0038)
call RemoveUnit(gg_unit_h028_0038)
set Headers[0] = 'B07O'
set Headers[1] = 'B07O'
set Headers[2] = 'B07N'
set ClassIcons[0] = 'B07V'
set ClassIcons[1] = 'B07V'
set ClassIcons[2] = 'B07U'
set ClassModels[0] = "war3mapImported\\dummy.mdl"
set ClassModels[1] = "war3mapImported\\Footman3.mdl"
set ClassModels[2] = "war3mapImported\\ARCHNIGHEL preview.MDX"
set ClassScale[0] = 0.0
set ClassScale[1] = 1.1
set ClassScale[2] = 0.6
set PetIcons[0] = 'B07Z'
set PetIcons[1] = 'B07Z'
set PetIcons[2] = 'B080'
set PetIcons[3] = 'B081'
set PetIcons[4] = 'B082'
set PetIcons[5] = 'B083'
set PetIcons[6] = 'B084'
set PetIcons[7] = 'B085'
set PetModels[0] = "war3mapImported\\dummy.mdl"
set PetModels[1] = "units\\critters\\BrownWolf\\BrownWolf.mdl"
set PetModels[2] = "units\\critters\\SpiderCrab\\SpiderCrab.mdl"
set PetModels[3] = "units\\creeps\\SpiritPig\\SpiritPig.mdl"
set PetModels[4] = "war3mapImported\\Cobra.mdl"
set PetModels[5] = "units\\critters\\BlackStagMale\\BlackStagMale.mdl"
set PetModels[6] = "units\\creeps\\WarEagle\\WarEagle.mdl"
set PetModels[7] = "war3mapImported\\Elk_male.mdl"
set PetScale[0] = 0.0
set PetScale[1] = 1.0
set PetScale[2] = 0.8
set PetScale[3] = 0.8
set PetScale[4] = 0.6
set PetScale[5] = 1.0
set PetScale[6] = 0.4
set PetScale[7] = 0.6
set PetHeight[0] = 0.0
set PetHeight[1] = 0.0
set PetHeight[2] = 0.0
set PetHeight[3] = 0.0
set PetHeight[4] = 0.0
set PetHeight[5] = 0.0
set PetHeight[6] = 100.0
set PetHeight[7] = 0.0
set Warnings[0] = 'B07W'
set Warnings[1] = 'B07X'
set Warnings[2] = 'B07Y'
endfunction
endlibrary
library MainMenu initializer init uses GameConstants, PanelCore, PlayerInit, TimerUtils, Fader
globals
public Panel array MainPanel
public PanelPlatform array Logo
public PanelPlatform array CreateNewButton
public PanelPlatform array LoadButton
endglobals
public function ToCreationScene takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
if Locale == Player(id) then
call SetDayNightModels("war3mapImported\\DNCSelection.mdx", "war3mapImported\\DNCSelection.mdx")
endif
call MainPanel[id].show(false)
call ClassSelection_CreateNewCharacter(id)
call PlayerCamera[id].applyCameraSetup(gg_cam_ClassSelection, true, 0)
call PlayerCamera[id].refresh()
call ReleaseTimer(t)
set t = null
endfunction
public function CreateNew takes integer id returns nothing
call Fader_FadeInOut(id, 1)
call TimerStart(NewTimerEx(id), 1., false, function ToCreationScene)
endfunction
public function ToLoadingScene takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
if Locale == Player(id) then
call SetDayNightModels("war3mapImported\\DNCSelection.mdx", "war3mapImported\\DNCSelection.mdx")
endif
call MainPanel[id].show(false)
call ClassSelection_LoadCharacter(id)
call PlayerCamera[id].applyCameraSetup(gg_cam_ClassSelection, true, 0)
call PlayerCamera[id].refresh()
call ReleaseTimer(t)
set t = null
endfunction
public function LoadCharacter takes integer id returns nothing
call Fader_FadeInOut(id, 1)
call TimerStart(NewTimerEx(id), 1., false, function ToLoadingScene)
endfunction
public function Create takes integer id returns nothing
local player p = Player(id)
set MainPanel[id] = Panel.create(p, 'e01M', 'B086', 0, 0, 0.0)
set Logo[id] = PanelPlatform.create(MainPanel[id], 'e02C', 'B08A', 0, 200, 1)
set CreateNewButton[id] = PanelPlatform.create(MainPanel[id], 'e029', 'B087', -82, -313, 1)
set LoadButton[id] = PanelPlatform.create(MainPanel[id], 'e02A', 'B088', 82, -313, 1)
call MainPanel[id].refresh()
endfunction
private function onSelect takes nothing returns boolean
local player p = GetTriggerPlayer()
local integer id = GetPlayerId(p)
local unit u = GetTriggerUnit()
if u == CreateNewButton[id].dummy then
call CreateNew(id)
if Locale == p then
call ClearSelection()
endif
elseif u == LoadButton[id].dummy then
if CharacterManager_SaveEnabled[id] then
call LoadCharacter(id)
if Locale == p then
call ClearSelection()
endif
endif
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SELECTED)
call TriggerAddCondition(t, Condition(function onSelect))
endfunction
endlibrary
library Fader initializer init uses GameConstants, PanelCore, PlayerInit, TimerUtils
globals
private Panel array FaderPanel
private timer array FaderTimer
private real array FaderRate
endglobals
public function FadeDone takes nothing returns nothing
local integer id = GetTimerData(GetExpiredTimer())
if Locale == Player(id) then
call EnableUserControl(true)
endif
endfunction
public function FadeOut takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
call Fade.create(FaderPanel[id].dummy, 255, -FaderRate[id])
call TimerStart(FaderTimer[id], TimerGetTimeout(t), false, function FadeDone)
set t = null
endfunction
public function FadeInOut takes integer id, real duration returns nothing
if Locale == Player(id) then
call EnableUserControl(false)
endif
set FaderRate[id] = 255./(duration/0.03125)
call Fade.create(FaderPanel[id].dummy, 0, FaderRate[id])
call TimerStart(FaderTimer[id], duration, false, function FadeOut)
endfunction
private function init takes nothing returns nothing
local integer i = 0
local player p
loop
exitwhen i > 3
set p = Player(i)
if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p) == MAP_CONTROL_USER then
set FaderTimer[i] = NewTimerEx(i)
set FaderPanel[i] = Panel.create(p, 'e01M', 'B016', 0, 0, -PanelCamera_LEVEL_GAP*5)
set FaderPanel[i].opacity = 0
call FaderPanel[i].refresh()
endif
set i = i + 1
endloop
endfunction
endlibrary
library IntroScene uses TimerUtils, PanelPlatform
globals
public Panel array Scene
private integer Phase = 0
private BJObjectId FlashTextureId
private constant integer FADE_SPEED = 10
endglobals
private function Animate takes nothing returns nothing
local integer i
set i = 0
loop
exitwhen i > 3
set Scene[i].opacity = Scene[i].opacity - FADE_SPEED
set i = i + 1
endloop
if Scene[0].opacity <= 0 then
//call ShowInterface(true, 0.5)
call EnableUserUI(true)
call ReleaseTimer(GetExpiredTimer())
set i = 0
loop
exitwhen i > 3
call Scene[i].show(false)
set i = i + 1
endloop
endif
endfunction
public function Start takes nothing returns nothing
local integer i
set i = 0
loop
exitwhen i > 3
call PlayerCamera[i].applyCameraSetup(gg_cam_Cine7, true, 0)
call PlayerCamera[i].refresh()
set i = i + 1
endloop
set Phase = -1
call TimerStart(NewTimer(), 0.03125, true, function Animate)
endfunction
public function init takes player p returns nothing
local integer i = GetPlayerId(p)
set Scene[i] = Panel.create(p, 'e01M', 'B016', 0, 0, -5*PanelCamera_LEVEL_GAP)
endfunction
endlibrary
//! textmacro CreateBarObject takes TYPE, CODE, INDEX, FILEPATH, EXTENSION
//! external ObjectMerger w3b YTlb $TYPE$$CODE$ bnam "(TeamLogo) $INDEX$" bfxr -1 bfil ".mdl" boch 0 btxf "$FILEPATH$$INDEX$$EXTENSION$" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
//! runtextmacro CreateBarObject ("TL", "00", "0", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "01", "1", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "02", "2", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "03", "3", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "04", "4", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "05", "5", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "06", "6", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "07", "7", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "08", "8", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "09", "9", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0A", "10", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0B", "11", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0C", "12", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0D", "13", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0E", "14", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0F", "15", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0G", "16", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0H", "17", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0I", "18", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0J", "19", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0K", "20", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0L", "21", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0M", "22", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0N", "23", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0O", "24", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0P", "25", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0Q", "26", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0R", "27", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0S", "28", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0T", "29", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0U", "30", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0V", "31", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0W", "32", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0X", "33", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0Y", "34", "war3mapImported\teamflash", ".blp")
//! runtextmacro CreateBarObject ("TL", "0Z", "35", "war3mapImported\teamflash", ".blp")
library UpgradeMenu initializer onInit uses TimerUtils, PanelPlatform, CharacterManager
globals
public Panel array Main
public PanelPlatform array Effect
public PanelPlatform array Button
public PanelPlatform array Close
public PanelPlatform array Selection
public PanelPlatform array Overlay
public PanelPlatform array CostIcon
public PanelTextEx array CostText
public PanelPlatform array ItemSlot[4][6]
public ItemObject array SlotObject[4][6]
public integer array SelectionIndex
public integer array SlotIndex
public integer array SlotOwner
public integer array StartOwner
public integer array CloseOwner
public integer array UpgradeCost
public BJObjectId array EffectTexture
public integer array EffectRepeat
public integer array EffectAnimation
public real array UpgraderRating
public boolean array Notified
public dialog ConfirmDialog
public button array ConfirmDialogButton
public timer array AnimationTimer
endglobals
private function CreateNewSaveThread takes nothing returns nothing
call CharacterManager_SaveData(GetEnumPlayer())
endfunction
public function RefreshCost takes integer pid returns nothing
local real level
local real cost
local real percent
local integer i = 2
if SlotObject[pid][0] > 0 and SlotObject[pid][1] > 0 then
set level = RMaxBJ(I2R(SlotObject[pid][0].reqLevel), 1)
set cost = UPGRADE_LEVEL_COST_BASE*Pow(UPGRADE_LEVEL_COST_BASE_POWER, level)
set percent = Pow(UPGRADE_LEVEL_COST_PERCENT, level)
set cost = cost + UpgradeOrePrice[SlotObject[pid][1].id.wisdom]*percent
loop
exitwhen i > 5
set cost = cost + UpgradeGemstonePrice[SlotObject[pid][i].id.wisdom]*percent
set i = i + 1
endloop
else
set cost = 0.
endif
set UpgradeCost[pid] = R2I(cost)
call CostText[pid].setText(I2S(UpgradeCost[pid]), FONTSTYLE_FrizQTShaded)
if GetPlayerState(Player(pid), PLAYER_STATE_RESOURCE_GOLD) >= UpgradeCost[pid] then
call CostText[pid].setColor(255, 255, 255, 255)
else
call CostText[pid].setColor(255, 0, 0, 255)
endif
call CostText[pid].refresh()
endfunction
public function SetItem takes integer pid, integer index, ItemObject obj returns boolean
local integer vol
call Tooltips1[pid].show(false)
call Tooltips2[pid].show(false)
if obj > 0 then
if SlotObject[pid][index] > 0 then
if Inventory_InventoryIndex[pid].addItem(SlotObject[pid][index]) then
if Locale == Player(pid) then
set vol = 150
else
set vol = 0
endif
call PickUpItemSfx.play(0, 0, 0, vol)
else
return false
endif
endif
set ItemSlot[pid][index].texture = obj.id.texture
call ItemSlot[pid][index].refresh()
set SlotObject[pid][index] = obj
else
if SlotObject[pid][index] > 0 then
if Inventory_InventoryIndex[pid].addItem(SlotObject[pid][index]) then
/*if Locale == Player(pid) then
set vol = 150
else
set vol = 0
endif
call PickUpItemSfx.play(0, 0, 0, vol)*/
else
return false
endif
endif
if index == 0 then
set ItemSlot[pid][index].texture = 'B01J'
elseif index == 1 then
set ItemSlot[pid][index].texture = 'B01L'
elseif index == 2 then
set ItemSlot[pid][index].texture = 'B01K'
elseif index == 3 then
set ItemSlot[pid][index].texture = 'B01M'
elseif index == 4 then
set ItemSlot[pid][index].texture = 'B01N'
elseif index == 5 then
set ItemSlot[pid][index].texture = 'B01O'
endif
call ItemSlot[pid][index].refresh()
set SlotObject[pid][index] = 0
endif
call RefreshCost(pid)
return true
endfunction
public function CloseWindow takes integer pid returns nothing
local integer i
set ShopMerchants_CurrentMerchant[pid] = null
call Main[pid].show(false)
if Bag[pid].visible then
call Bag[pid].show(false)
endif
set i = 0
loop
exitwhen i > 5
if SlotObject[pid][i] > 0 then
call SetItem(pid, i, 0)
endif
set i = i + 1
endloop
set EffectAnimation[pid] = 0
call Overlay[pid].show(false)
call Effect[pid].show(false)
call Button[pid].show(true)
call CostIcon[pid].show(true)
call CostText[pid].show(true)
call CostIcon[pid].refresh()
call CostText[pid].refresh()
call Button[pid].refresh()
call ReleaseTimer(AnimationTimer[pid])
endfunction
private function Animate takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer pid = GetTimerData(t)
local integer slot
local ItemObject obj
local integer i
local integer j
local integer tier
local InventoryContent content
local real chance
local real reduction
local boolean destroyed
if EffectAnimation[pid] == 1 then
set Effect[pid].texture = EffectTexture[pid]
call Effect[pid].refresh()
set EffectTexture[pid] = EffectTexture[pid].plus_1()
if EffectTexture[pid] == 'UE07' then
set EffectRepeat[pid] = EffectRepeat[pid] + 1
if EffectRepeat[pid] >= 5 then
set EffectAnimation[pid] = 2
call Overlay[pid].show(false)
// Upgrade
set tier = SlotObject[pid][0].upgradeLevel
set chance = UpgradeChanceBase[tier]
set i = 0
loop
exitwhen i >= SlotObject[pid][0].reqLevel
set chance = chance*UPGRADE_GEAR_LEVEL_REDUCTION
set i = i + 1
endloop
set i = 2
loop
exitwhen i > 5
if SlotObject[pid][i] > 0 then
set chance = chance*UpgradeChanceBonus[SlotObject[pid][i].id.wisdom]
endif
set i = i + 1
endloop
if IsAdmin[pid] then
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 5., "Chance was: " + R2S(chance*100.) + "%")
endif
set destroyed = false
if GetRandomReal(0.000, 1.000) <= chance or IsAdmin[pid] then
call SlotObject[pid][0].upgrade(SlotObject[pid][1].id)
call UpgradeSuccessSound.play(0, 0, 0, 100)
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 5., "|cff00ff00Upgrade was successful!|r")
else
set reduction = 1.0
set i = 2
loop
exitwhen i > 5
if SlotObject[pid][i] > 0 then
set reduction = reduction*(2.0-UpgradeChanceBonus[SlotObject[pid][i].id.wisdom])
endif
set i = i + 1
endloop
if GetRandomReal(0.000, 1.000) <= UpgradeDestroyChance[tier]*reduction then
set destroyed = true
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 15., "|cffff0000Upgrade failed. The equipment was destroyed.|r")
elseif GetRandomReal(0.000, 1.000) <= UpgradeResetChance[tier]*reduction then
call SlotObject[pid][0].clearUpgrade()
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 15., "|cffff0000Upgrade failed. The equipment's all upgrades were destroyed.|r")
elseif GetRandomReal(0.000, 1.000) <= UpgradeDowngradeChance[tier]*reduction then
call SlotObject[pid][0].downgrade(true)
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 15., "|cffff0000Upgrade failed. The equipment was downgraded.|r")
else
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 5., "|cffff0000Upgrade failed.|r")
endif
call UpgradeFailedSound.play(0, 0, 0, 100)
endif
// Temper quality
if SlotObject[pid][0].quality > 0 and GetRandomReal(0.000, 1.000) <= UPGRADE_QUALITY_REDUCTION_CHANCE*(1.-UpgraderRating[pid]/100.) then
set SlotObject[pid][0].quality = SlotObject[pid][0].quality - 1
endif
// Return item
set slot = Inventory_InventoryIndex[pid].getEmptySlot()
call SetItem(pid, 0, 0)
if destroyed then
call Inventory_InventoryIndex[pid].dropItemFromSlot(slot, false)
endif
call ForForce(bj_FORCE_PLAYER[pid], function CreateNewSaveThread)
if not destroyed then
set obj = Inventory_SlotIndex[Inventory_InventoryIndex[pid]][slot].object
if UpgradeMenu_SetItem(pid, 0, obj) then
call Inventory_InventoryIndex[pid].dropItemFromSlot(slot, true)
call obj.show(false)
endif
endif
set i = 1
loop
exitwhen i > 5
if SlotObject[pid][i] > 0 then
set j = 0
loop
exitwhen j == 20
set content = Inventory_SlotIndex[Inventory_InventoryIndex[pid]][j]
if content.object.id == SlotObject[pid][i].id then
if content.object.charge > 1 then
set content.object.charge = content.object.charge - 1
call content.text.setText(I2S(content.object.charge), FONTSTYLE_FrizQTShaded)
if content.object.charge > 9 then
call content.text.move(content.plat.xOffset+10, content.text.yOffset, content.text.level)
else
call content.text.move(content.plat.xOffset+15, content.text.yOffset, content.text.level)
endif
call content.text.refresh()
else
call Inventory_InventoryIndex[pid].dropItemFromSlot(j, false)
endif
exitwhen true
endif
set j = j + 1
endloop
if j == 20 then
call SlotObject[pid][i].destroy()
set SlotObject[pid][i] = 0
call SetItem(pid, i, 0)
endif
endif
set i = i + 1
endloop
else
set EffectTexture[pid] = 'UE01'
endif
endif
elseif EffectAnimation[pid] == 2 then
set Effect[pid].texture = EffectTexture[pid]
call Effect[pid].refresh()
set EffectTexture[pid] = EffectTexture[pid].plus_1()
if EffectTexture[pid] == 'UE0P' then
set EffectAnimation[pid] = 0
call Effect[pid].show(false)
call Button[pid].show(true)
call CostIcon[pid].show(true)
call CostText[pid].show(true)
call CostIcon[pid].refresh()
call CostText[pid].refresh()
call Button[pid].refresh()
call ReleaseTimer(t)
endif
endif
set t = null
endfunction
public function Start takes integer pid returns nothing
if EffectAnimation[pid] == 0 then
call SetPlayerState(Player(pid), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(pid), PLAYER_STATE_RESOURCE_GOLD)-UpgradeCost[pid])
//call ItemTemperSound.play(0, 0, 0, 100)
set EffectTexture[pid] = 'UE01'
set EffectRepeat[pid] = 0
set EffectAnimation[pid] = 1
set Effect[pid].texture = EffectTexture[pid]
set SelectionIndex[pid] = -1
call Button[pid].show(false)
call CostIcon[pid].show(false)
call CostText[pid].show(false)
call Selection[pid].show(false)
call Tooltips1[pid].show(false)
call Effect[pid].show(true)
call Overlay[pid].show(true)
call Effect[pid].refresh()
call Overlay[pid].refresh()
set AnimationTimer[pid] = NewTimerEx(pid)
call TimerStart(AnimationTimer[pid], 0.1, true, function Animate)
endif
endfunction
public function VerifyUpgrade takes integer pid returns boolean
if SlotObject[pid][0] <= 0 then
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 5., "|cffffcc00Select the weapon/armor to upgrade.|r")
return false
elseif SlotObject[pid][1] <= 0 then
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 5., "|cffffcc00Select an ore to smelt with.|r")
return false
elseif SlotObject[pid][0].reqLevel < SlotObject[pid][1].id.reqLevel then
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 5., "|cffffcc00The item doesn't meet the ore's minimum level requirement.|r")
return false
elseif SlotObject[pid][0].upgradeLevel >= 12 then
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 5., "|cffffcc00The equipment has reached maximum upgrade level.|r")
return false
elseif Inventory_InventoryIndex[pid].getEmptySlot() == 20 then
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 5., "|cffffcc00Inventory is full. An empty slot is required for returning the equipment.|r")
return false
elseif SlotObject[pid][1].id.fortitude == 1 then
if SlotObject[pid][0].physicDmgMin <= 0 and SlotObject[pid][0].physicDmgMax <= 0 then
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 5., "|cffffcc00Metalrio can only be used to enhance gear's physic damage.|r")
return false
endif
elseif SlotObject[pid][1].id.fortitude == 2 then
if SlotObject[pid][0].magicDmgMin <= 0 and SlotObject[pid][0].magicDmgMax <= 0 then
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 5., "|cffffcc00Setalian can only be used to enhance gear's magic damage.|r")
return false
endif
elseif SlotObject[pid][1].id.fortitude == 3 then
if SlotObject[pid][0].magicDefense <= 0 then
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 5., "|cffffcc00Protalus can only be used to enhance gear's magic defense.|r")
return false
endif
elseif SlotObject[pid][1].id.fortitude == 4 then
if SlotObject[pid][0].physicDefense <= 0 then
call DisplayTimedTextToPlayer(Player(pid), 0, 0, 5., "|cffffcc00Ostalium can only be used to enhance gear's physic defense.|r")
return false
endif
endif
return true
endfunction
public function init takes player p returns nothing
local integer i = GetPlayerId(p)
local integer j
local integer data
set UpgraderRating[i] = 25.0
set SelectionIndex[i] = -1
set Main[i] = Panel.create(p, 'e02K', 'B01H', 0, 25, 3*PanelCamera_LEVEL_GAP)
set Main[i].scale = 0.8
set Close[i] = PanelPlatform.create(Main[i], 'e02T', 0, 220, 208, 1)
set Close[i].scale = 0.45
call Close[i].setColor(255, 255, 255, 0)
set CloseOwner[GetUnitUserData(Close[i].dummy)] = i + 1
set CostIcon[i] = PanelPlatform.create(Main[i], 'e007', 'B01D', 85, -218, 1)
set CostIcon[i].scale = 0.4
set CostText[i] = PanelTextEx.create(Main[i], "0", FONTSTYLE_FrizQTShaded, 100, -218, 1)
set CostText[i].scale = 0.45
set Effect[i] = PanelPlatform.create(Main[i], 'e02S', 'UE01', 1, -7, 1)
set Effect[i].scale = 3.0
set Overlay[i] = PanelPlatform.create(Main[i], 'e00H', 0, 1, -7, 4)
set Overlay[i].scale = 0.705
call Overlay[i].setColor(255, 255, 255, 128)
set Button[i] = PanelPlatform.create(Main[i], 'e02L', 'B01I', 0, -210, 1)
set StartOwner[GetUnitUserData(Button[i].dummy)] = i + 1
set ItemSlot[i][0] = PanelPlatform.create(Main[i], 'e02M', 'B01J', 1, -7, 2)
set ItemSlot[i][1] = PanelPlatform.create(Main[i], 'e02N', 'B01L', 1, 124, 2)
set ItemSlot[i][2] = PanelPlatform.create(Main[i], 'e02O', 'B01K', 130, 29, 2)
set ItemSlot[i][3] = PanelPlatform.create(Main[i], 'e02P', 'B01M', 95, -121, 2)
set ItemSlot[i][4] = PanelPlatform.create(Main[i], 'e02Q', 'B01N', -85, -121, 2)
set ItemSlot[i][5] = PanelPlatform.create(Main[i], 'e02R', 'B01O', -129, 29, 2)
set Selection[i] = PanelPlatform.create(Main[i], 'e008', 0, 0, 0, 3)
call Effect[i].show(false)
call Overlay[i].show(false)
call Selection[i].show(false)
set j = 0
loop
exitwhen j > 5
set ItemSlot[i][j].scale = 0.8
set data = GetUnitUserData(ItemSlot[i][j].dummy)
set SlotIndex[data] = j + 1
set SlotOwner[data] = i
set j = j + 1
endloop
call Main[i].show(false)
endfunction
private function onSelect takes nothing returns boolean
local unit u = GetTriggerUnit()
local player p
local integer data = GetUnitUserData(u)
local integer pid
local integer index
if SlotIndex[data] > 0 then
set pid = SlotOwner[data]
set p = Player(pid)
set index = SlotIndex[data]-1
if SelectionIndex[pid] == index then
set SelectionIndex[pid] = -1
call Selection[pid].show(false)
if EffectAnimation[pid] == 0 then
// Return item
call SetItem(pid, index, 0)
endif
elseif SlotObject[pid][index] > 0 then
set SelectionIndex[pid] = index
call Selection[pid].move(ItemSlot[pid][index].xOffset, ItemSlot[pid][index].yOffset, ItemSlot[pid][index].level+1)
call Selection[pid].show(true)
call Selection[pid].refresh()
else
if index == 0 then
call DisplayTimedTextToPlayer(p, 0, 0, 5., "|cffffcc00Use|r the desired gear to insert it to this slot.")
else
call DisplayTimedTextToPlayer(p, 0, 0, 5., "|cffffcc00Use|r the desired material to insert it to this slot.")
endif
endif
if Locale == p then
call SelectUnit(u, false)
call SelectUnit(Controller[pid], true)
endif
elseif StartOwner[data] > 0 then
set pid = StartOwner[data] - 1
set p = Player(pid)
if GetPlayerState(Player(pid), PLAYER_STATE_RESOURCE_GOLD) >= UpgradeCost[pid] then
if VerifyUpgrade(pid) then
if Notified[pid] then
call Start(pid)
else
call DialogClear(ConfirmDialog)
call DialogSetMessage(ConfirmDialog, "|cffffcc00If upgrade failed, the item might|nbe randomly downgraded or|ncompletely destroyed.|n|nThe game will be automatically|nsaved disregard of the result.|n|nProceed to the process?|r")
set ConfirmDialogButton[0] = DialogAddButton(ConfirmDialog, "Yes", 0)
set ConfirmDialogButton[1] = DialogAddButton(ConfirmDialog, "Yes. Don't remind me.", 0)
set ConfirmDialogButton[2] = DialogAddButton(ConfirmDialog, "No", 0)
call DialogDisplay(p, ConfirmDialog, true)
endif
endif
else
call DisplayTimedTextToPlayer(p, 0, 0, 5., "Not enough gold.")
endif
if Locale == p then
call SelectUnit(u, false)
call SelectUnit(Controller[pid], true)
endif
elseif CloseOwner[data] > 0 then
set pid = CloseOwner[data] - 1
set p = Player(pid)
call CloseWindow(pid)
if Locale == p then
call SelectUnit(u, false)
call SelectUnit(Controller[pid], true)
endif
endif
set u = null
return false
endfunction
private function onOrder takes nothing returns boolean
local unit u = GetOrderTargetUnit()
local integer data
local integer pid
local integer index
local player p
if u != null and GetIssuedOrderId() == ORDER_smart then
set data = GetUnitUserData(u)
if SlotIndex[data] != 0 then
set pid = SlotOwner[data]
set p = Player(pid)
set index = SlotIndex[data]-1
if SlotObject[pid][index] > 0 then
if SlotObject[pid][index] != Tooltips1[pid].itmObject or not Tooltips1[pid].control.visible then
call Tooltips1[pid].show(true)
call Tooltips2[pid].show(false)
call Tooltips1[pid].control.move(-350, 0, Tooltips1[pid].control.zDepth)
call Tooltips1[pid].control.refresh()
call Tooltips1[pid].setItem(SlotObject[pid][index])
else
call Tooltips1[pid].show(false)
set Tooltips1[pid].itmObject = -1
set Tooltips1[pid].skill = -1
call Tooltips2[pid].show(false)
set Tooltips2[pid].itmObject = -1
set Tooltips2[pid].skill = -1
endif
endif
set u = GetTriggerUnit()
call IssueImmediateOrderById(u, ORDER_stop)
call IssueImmediateOrderById(u, ORDER_stunned)
endif
set u = null
endif
return false
endfunction
private function onClick takes nothing returns boolean
local button but = GetClickedButton()
local player p = GetTriggerPlayer()
local integer id = GetPlayerId(p)
if but == ConfirmDialogButton[0] then
call Start(id)
elseif but == ConfirmDialogButton[1] then
set Notified[id] = true
call Start(id)
endif
return false
endfunction
private function checkSelection takes nothing returns nothing
local unit u
local integer data
local integer uid
if CharacterManager_GameModeCode == 22 then
set u = BlzGetMouseFocusUnit()
if u == null then
if LastSelection != null then
set data = GetUnitUserData(u)
if Tooltips1[PNumb].itmObject != -1 then
call Tooltips1[PNumb].show(false)
set Tooltips1[PNumb].itmObject = -1
set Tooltips1[PNumb].skill = -1
call Tooltips2[PNumb].show(false)
set Tooltips2[PNumb].itmObject = -1
set Tooltips2[PNumb].skill = -1
set LastSelection = u
endif
endif
else
if LastSelection != u then
set data = GetUnitUserData(u)
if SlotIndex[data] != 0 then
call Tooltips1[PNumb].show(true)
call Tooltips2[PNumb].show(false)
call Tooltips1[PNumb].control.move(-350, 0, Tooltips1[PNumb].control.zDepth)
call Tooltips1[PNumb].control.refresh()
call Tooltips1[PNumb].setItem(SlotObject[PNumb][SlotIndex[data]-1])
set LastSelection = u
endif
endif
endif
set u = null
endif
endfunction
private function onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SELECTED)
call TriggerAddCondition(t, Condition(function onSelect))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(t, Condition(function onOrder))
set ConfirmDialog = DialogCreate()
set t = CreateTrigger()
call TriggerRegisterDialogEvent(t, ConfirmDialog)
call TriggerAddCondition(t, Condition(function onClick))
call TimerStart(CreateTimer(), 0.1, true, function checkSelection)
endfunction
endlibrary
//! textmacro CreateEffectObject takes TIER
//! external ObjectMerger w3b YTlb UE0$TIER$ bnam "(Upgrade Menu) Effect $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\UpgradeEffect$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
//! runtextmacro CreateEffectObject ("1")
//! runtextmacro CreateEffectObject ("2")
//! runtextmacro CreateEffectObject ("3")
//! runtextmacro CreateEffectObject ("4")
//! runtextmacro CreateEffectObject ("5")
//! runtextmacro CreateEffectObject ("6")
//! runtextmacro CreateEffectObject ("7")
//! runtextmacro CreateEffectObject ("8")
//! runtextmacro CreateEffectObject ("9")
//! runtextmacro CreateEffectObject ("A")
//! runtextmacro CreateEffectObject ("B")
//! runtextmacro CreateEffectObject ("C")
//! runtextmacro CreateEffectObject ("D")
//! runtextmacro CreateEffectObject ("E")
//! runtextmacro CreateEffectObject ("F")
//! runtextmacro CreateEffectObject ("G")
//! runtextmacro CreateEffectObject ("H")
//! runtextmacro CreateEffectObject ("I")
//! runtextmacro CreateEffectObject ("J")
//! runtextmacro CreateEffectObject ("K")
//! runtextmacro CreateEffectObject ("L")
//! runtextmacro CreateEffectObject ("M")
//! runtextmacro CreateEffectObject ("N")
//! runtextmacro CreateEffectObject ("O")
scope NPCMenu
globals
private UIFrame PortraitFrame
private UIFrame PortraitActionFrame
private UIFrame PortraitActionBG
endglobals
function Trig_CmdButton_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local player p = GetTriggerPlayer()
local integer pid = GetPlayerId(p)
local integer i
local integer j
local integer count
local real factor = UIUtils.ScaleFactor
local real size = 34.0 * factor
local real gap = 2.0 * factor
local real pivotX = UIUtils.ResolutionWidth / 2
local real pivotY = 192
local real x
local real y
if Locale == p then
if IsUnitInGroup(u, Merchants) or IsUnitInGroup(u, NPCs) then
set x = pivotX +142.0* factor*0.5
set y = (pivotY+137.0) * factor
set i = 0
set j = 0
set count = 0
loop
exitwhen i > 11
if BlzFrameIsVisible(DefaultFrame.CommandButton[i]) then
call BlzFrameClearAllPoints(DefaultFrame.CommandButton[i])
call BlzFrameSetAbsPoint(DefaultFrame.CommandButton[i], FRAMEPOINT_TOPLEFT, UIUtils.GetScreenPosX(x), UIUtils.GetScreenPosY(y))
call BlzFrameSetSize(DefaultFrame.CommandButton[i], size*UIUtils.PXTODPI, size*UIUtils.PXTODPI)
set y = y - size
if j >= 3 then
set j = -1
set x = x +size + gap
set y = (pivotY+137.0) * factor
endif
endif
set i = i + 1
set j = j + 1
endloop
call BlzFrameClearAllPoints(DefaultFrame.Portrait)
call BlzFrameSetAbsPoint(DefaultFrame.Portrait, FRAMEPOINT_BOTTOM, UIUtils.GetScreenPosX(pivotX), UIUtils.GetScreenPosY((pivotY+8.0) * factor))
call BlzFrameSetSize(DefaultFrame.Portrait, 100.0 * factor*UIUtils.PXTODPI, 105.0 * factor*UIUtils.PXTODPI)
call BlzFrameClearAllPoints(DefaultFrame.UnitNameText)
call BlzFrameSetAbsPoint(DefaultFrame.UnitNameText, FRAMEPOINT_TOP, UIUtils.GetScreenPosX(pivotX), UIUtils.GetScreenPosY((pivotY-5.0) * factor))
set PortraitFrame.visible = true
set PortraitActionFrame.visible = true
set PortraitActionBG.visible = true
else
set i = 0
set count = 0
loop
exitwhen i > 11
if BlzFrameIsVisible(DefaultFrame.CommandButton[i]) then
set count = count + 1
endif
set i = i + 1
endloop
set x = UIUtils.GetScreenPosX(UIUtils.ResolutionWidth-gap)
set y = UIUtils.ResolutionHeight*0.5+(size+gap)*(count-1)*0.5-100.0
set i = 0
loop
exitwhen i > 11
if BlzFrameIsVisible(DefaultFrame.CommandButton[i]) then
call BlzFrameClearAllPoints(DefaultFrame.CommandButton[i])
call BlzFrameSetAbsPoint(DefaultFrame.CommandButton[i], FRAMEPOINT_RIGHT, x, UIUtils.GetScreenPosY(y))
call BlzFrameSetSize(DefaultFrame.CommandButton[i], size*UIUtils.PXTODPI, size*UIUtils.PXTODPI)
set y = y - size - gap
endif
set i = i + 1
endloop
call BlzFrameClearAllPoints(DefaultFrame.Portrait)
call BlzFrameSetAbsPoint(DefaultFrame.Portrait, FRAMEPOINT_CENTER, UIUtils.GetScreenPosX(-999.0), UIUtils.GetScreenPosY(-999.0))
call BlzFrameClearAllPoints(DefaultFrame.UnitNameText)
call BlzFrameSetAbsPoint(DefaultFrame.UnitNameText, FRAMEPOINT_BOTTOM, UIUtils.GetScreenPosX(-999.0), UIUtils.GetScreenPosY(-999.0))
set PortraitFrame.visible = false
set PortraitActionFrame.visible = false
set PortraitActionBG.visible = false
endif
endif
set u = null
endfunction
private function initFrame takes nothing returns nothing
local UIFrame comp
local real pivotY = 192
set PortraitFrame = UIFrame.create(false, UIFrame.TYPE_TEXTURE, UIFrame.Null, 0, pivotY, 1)
set PortraitFrame.texture = "war3mapImported\\PortraitFrame.tga"
call PortraitFrame.setSize(138.0, 137.0)
set PortraitFrame.visible = false
call PortraitFrame.setAnchorPoint(0.5, 0.0)
call PortraitFrame.setPivotPoint(0.5, 0.0)
set PortraitActionFrame = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, PortraitFrame, 0, 0, 5)
set PortraitActionFrame.texture = "war3mapImported\\PortraitActionBar.tga"
set PortraitActionFrame.visible = false
call PortraitActionFrame.setSize(114.0, 137.0)
call PortraitActionFrame.setAnchorPoint(1, 0.5)
call PortraitActionFrame.setPivotPoint(0, 0.5)
set PortraitActionBG = UIFrame.create(true, UIFrame.TYPE_SIMPLE_TEXTURE, PortraitFrame, 0, 0, 0)
set PortraitActionBG.texture = "Textures\\black32.blp"
call PortraitActionBG.setSize(114.0, 137.0)
call PortraitActionBG.setAnchorPoint(1, 0.5)
call PortraitActionBG.setPivotPoint(0, 0.5)
set PortraitActionBG.visible = false
/*set comp = UIFrame.create(false, UIFrame.TYPE_TEXTURE, PortraitFrame, 0, 137, 0)
set comp.texture = "war3mapImported\\PortraitFrameTop.tga"
set comp.anchorPoint = FRAMEPOINT_BOTTOM
call comp.setSize(138.0, 42.0)*/
call DestroyTimer(GetExpiredTimer())
endfunction
function InitTrig_NPCMenu takes nothing returns nothing
set gg_trg_NPCMenu = CreateTrigger()
call TriggerRegisterPlayerSelectionEventBJ(gg_trg_NPCMenu, Player(0), true)
call TriggerRegisterPlayerSelectionEventBJ(gg_trg_NPCMenu, Player(1), true)
call TriggerRegisterPlayerSelectionEventBJ(gg_trg_NPCMenu, Player(2), true)
call TriggerRegisterPlayerSelectionEventBJ(gg_trg_NPCMenu, Player(3), true)
call TriggerAddAction(gg_trg_NPCMenu, function Trig_CmdButton_Actions)
call TimerStart(CreateTimer(), 0, false, function initFrame)
endfunction
endscope
//! textmacro CreateIconObject takes TIER
//! external ObjectMerger w3b YTlb EQ0$TIER$ bnam "(Equipment) Boots $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorT$TIER$Boots.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ1$TIER$ bnam "(Equipment) Chest $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorT$TIER$Chest.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ2$TIER$ bnam "(Equipment) Gloves $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorT$TIER$Gloves.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ3$TIER$ bnam "(Equipment) Helmet $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorT$TIER$Helmet.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ4$TIER$ bnam "(Equipment) Pants $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorT$TIER$Pants.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ5$TIER$ bnam "(Equipment) Shield $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorT$TIER$Shield.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ6$TIER$ bnam "(Equipment) Pads $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorT$TIER$Pads.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ7$TIER$ bnam "(Equipment) Blade $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNWeaponT$TIER$Blade.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ8$TIER$ bnam "(Equipment) Bow $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNWeaponT$TIER$Bow.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
//! runtextmacro CreateIconObject ("0")
//! runtextmacro CreateIconObject ("1")
//! runtextmacro CreateIconObject ("2")
//! runtextmacro CreateIconObject ("3")
//! runtextmacro CreateIconObject ("4")
//! runtextmacro CreateIconObject ("5")
//! runtextmacro CreateIconObject ("6")
//! runtextmacro CreateIconObject ("7")
//! runtextmacro CreateIconObject ("8")
//! runtextmacro CreateIconObject ("9")
//! runtextmacro CreateIconObject ("A")
//! textmacro CreateIconObject takes TIER, RAW
//! external ObjectMerger w3b YTlb EQ0$RAW$ bnam "(Equipment) Boots Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorBootsVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ1$RAW$ bnam "(Equipment) Chest Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorChestVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ2$RAW$ bnam "(Equipment) Gloves Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorGlovesVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ3$RAW$ bnam "(Equipment) Helmet Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorHelmetVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ4$RAW$ bnam "(Equipment) Pants Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorPantsVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ5$RAW$ bnam "(Equipment) Shield Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorShieldVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ6$RAW$ bnam "(Equipment) Pads Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorPadsVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ9$RAW$ bnam "(Equipment) Ring Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorRingVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQA$RAW$ bnam "(Equipment) Necklace Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorNecklaceVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ7$RAW$ bnam "(Equipment) Blade Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNWeaponBladeVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQ8$RAW$ bnam "(Equipment) Bow Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNWeaponBowVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
//! textmacro CreateIconObject2 takes TIER, RAW
//! external ObjectMerger w3b YTlb EQB$RAW$ bnam "(Equipment) Boots Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorBootsVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQC$RAW$ bnam "(Equipment) Chest Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorChestVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQD$RAW$ bnam "(Equipment) Gloves Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorGlovesVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQE$RAW$ bnam "(Equipment) Helmet Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorHelmetVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQF$RAW$ bnam "(Equipment) Pants Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorPantsVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQG$RAW$ bnam "(Equipment) Shield Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorShieldVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQH$RAW$ bnam "(Equipment) Pads Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorPadsVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQK$RAW$ bnam "(Equipment) Ring Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorRingVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQL$RAW$ bnam "(Equipment) Necklace Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNArmorNecklaceVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQI$RAW$ bnam "(Equipment) Blade Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNWeaponBladeVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb EQJ$RAW$ bnam "(Equipment) Bow Var $TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNWeaponBowVar$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
//! runtextmacro CreateIconObject ("0", "B")
//! runtextmacro CreateIconObject ("1", "C")
//! runtextmacro CreateIconObject ("2", "D")
//! runtextmacro CreateIconObject ("3", "E")
//! runtextmacro CreateIconObject ("4", "F")
//! runtextmacro CreateIconObject ("5", "G")
//! runtextmacro CreateIconObject ("6", "H")
//! runtextmacro CreateIconObject ("7", "I")
//! runtextmacro CreateIconObject ("8", "J")
//! runtextmacro CreateIconObject ("9", "K")
//! runtextmacro CreateIconObject ("10", "L")
//! runtextmacro CreateIconObject ("11", "M")
//! runtextmacro CreateIconObject ("12", "N")
//! runtextmacro CreateIconObject ("13", "O")
//! runtextmacro CreateIconObject ("14", "P")
//! runtextmacro CreateIconObject ("15", "Q")
//! runtextmacro CreateIconObject ("16", "R")
//! runtextmacro CreateIconObject ("17", "S")
//! runtextmacro CreateIconObject ("18", "T")
//! runtextmacro CreateIconObject ("19", "U")
//! runtextmacro CreateIconObject ("20", "V")
//! runtextmacro CreateIconObject ("21", "W")
//! runtextmacro CreateIconObject ("22", "X")
//! runtextmacro CreateIconObject ("23", "Y")
//! runtextmacro CreateIconObject ("24", "Z")
//! runtextmacro CreateIconObject2("25", "0")
//! runtextmacro CreateIconObject2("26", "1")
//! runtextmacro CreateIconObject2("27", "2")
//! runtextmacro CreateIconObject2("28", "3")
//! runtextmacro CreateIconObject2("29", "4")
//! runtextmacro CreateIconObject2("30", "5")
//! runtextmacro CreateIconObject2("31", "6")
//! runtextmacro CreateIconObject2("32", "7")
//! runtextmacro CreateIconObject2("33", "8")
//! runtextmacro CreateIconObject2("34", "9")
//! runtextmacro CreateIconObject2("35", "A")
//! runtextmacro CreateIconObject2("36", "B")
//! runtextmacro CreateIconObject2("37", "C")
//! runtextmacro CreateIconObject2("38", "D")
//! runtextmacro CreateIconObject2("39", "E")
//! runtextmacro CreateIconObject2("40", "F")
//! textmacro CreateIconObject takes TIER
//! external ObjectMerger w3b YTlb GE0$TIER$ bnam "(Gem) Fire T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNGemFireT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb GE1$TIER$ bnam "(Gem) Water T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNGemWaterT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb GE2$TIER$ bnam "(Gem) Earth T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNGemEarthT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb GE3$TIER$ bnam "(Gem) Wind T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNGemWindT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb GE4$TIER$ bnam "(Gem) Light T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNGemLightT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb GE5$TIER$ bnam "(Gem) Dark T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNGemDarkT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
//! runtextmacro CreateIconObject ("1")
//! runtextmacro CreateIconObject ("2")
//! runtextmacro CreateIconObject ("3")
//! runtextmacro CreateIconObject ("4")
//! runtextmacro CreateIconObject ("5")
//! textmacro CreateIconObject takes TIER
//! external ObjectMerger w3b YTlb OE0$TIER$ bnam "(Ore) Ore Black T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNBlackOreT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb OE1$TIER$ bnam "(Ore) Ore Blue T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNBlueOreT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb OE2$TIER$ bnam "(Ore) Ore Red T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNRedOreT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb OE3$TIER$ bnam "(Ore) Ore Yellow T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNYellowOreT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb OE4$TIER$ bnam "(Ore) Topaz T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNTopazT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb OE5$TIER$ bnam "(Ore) Quartz T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNQuartzT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb OE6$TIER$ bnam "(Ore) Crystal T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNCrystalT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! external ObjectMerger w3b YTlb OE7$TIER$ bnam "(Ore) Jade T$TIER$" bfxr -1 bfil ".mdl" boch 0 btxf "war3mapImported\BTNJadeT$TIER$.blp" btxi 33 bsel 0 bgsc 0 bshd "" bfvi 1 barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
//! runtextmacro CreateIconObject ("1")
//! runtextmacro CreateIconObject ("2")
//! runtextmacro CreateIconObject ("3")
//! runtextmacro CreateIconObject ("4")
library ItemLib initializer init uses Items, ItemSet, ItemLib2
private function init takes nothing returns nothing
local Items itm
/********************************************
POTIONS
********************************************/
if true then
// 1. Small Health Potion
if (true) then
set itm = Items.create()
set itm.name = "Small Health Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeRed.mdl"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 1
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B07E'
set itm.category = Items.CONSUMABLE
set itm.gold = 3
set itm.cooldown = 4
set itm.hp = 150
set itm.sp = 0
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.comment = "Recovers HP when consumed."
set itm.commentLn = 1
endif
// 2. Medium Health Potion
if (true) then
set itm = Items.create()
set itm.name = "Medium Health Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeRed.mdl"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 1
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B07F'
set itm.category = Items.CONSUMABLE
set itm.gold = 3
set itm.cooldown = 4
set itm.hp = 300
set itm.sp = 0
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.comment = "Recovers HP when consumed."
set itm.commentLn = 1
endif
// 3. Large Health Potion
if (true) then
set itm = Items.create()
set itm.name = "Large Health Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeRed.mdl"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 1
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B07G'
set itm.category = Items.CONSUMABLE
set itm.gold = 3
set itm.cooldown = 4
set itm.hp = 600
set itm.sp = 0
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.comment = "Recovers HP when consumed."
set itm.commentLn = 1
endif
// 4. Giant Health Potion
if (true) then
set itm = Items.create()
set itm.name = "Giant Health Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeRed.mdl"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 1
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B07H'
set itm.category = Items.CONSUMABLE
set itm.gold = 3
set itm.cooldown = 5
set itm.hp = 1000
set itm.sp = 0
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.comment = "Recovers HP when consumed."
set itm.commentLn = 1
endif
// 5. Huge Health Potion
if (true) then
set itm = Items.create()
set itm.name = "Huge Health Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeRed.mdl"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 1
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B00T'
set itm.category = Items.CONSUMABLE
set itm.gold = 3
set itm.cooldown = 5
set itm.hp = 1400
set itm.sp = 0
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.comment = "Recovers HP when consumed."
set itm.commentLn = 1
endif
// 6. Grand Health Potion
if (true) then
set itm = Items.create()
set itm.name = "Grand Health Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeRed.mdl"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 1
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B07I'
set itm.category = Items.CONSUMABLE
set itm.gold = 3
set itm.cooldown = 5
set itm.hp = 1800
set itm.sp = 0
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 50
set itm.reqCount = 1
set itm.comment = "Recovers HP when consumed."
set itm.commentLn = 1
endif
// 7. Mega Health Potion
if (true) then
set itm = Items.create()
set itm.name = "Mega Health Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeRed.mdl"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 1
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B08P'
set itm.category = Items.CONSUMABLE
set itm.gold = 3
set itm.cooldown = 6
set itm.hp = 2200
set itm.sp = 0
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.comment = "Recovers HP when consumed."
set itm.commentLn = 1
endif
// 8. Super Health Potion
if (true) then
set itm = Items.create()
set itm.name = "Super Health Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeRed.mdl"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 1
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B08Q'
set itm.category = Items.CONSUMABLE
set itm.gold = 3
set itm.cooldown = 6
set itm.hp = 2600
set itm.sp = 0
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 70
set itm.reqCount = 1
set itm.comment = "Recovers HP when consumed."
set itm.commentLn = 1
endif
// 9. Ultimate Health Potion
if (true) then
set itm = Items.create()
set itm.name = "Ultimate Health Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeRed.mdl"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 1
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B08R'
set itm.category = Items.CONSUMABLE
set itm.gold = 3
set itm.cooldown = 6
set itm.hp = 3000
set itm.sp = 0
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.comment = "Recovers HP when consumed."
set itm.commentLn = 1
endif
// 10. Health Potion T10
if (true) then
set itm = Items.create()
set itm.name = "Health Potion T10"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeRed.mdl"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 1
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B08R'
set itm.category = Items.CONSUMABLE
set itm.gold = 3
set itm.cooldown = 6
set itm.hp = 1
set itm.sp = 0
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 90
set itm.reqCount = 1
set itm.comment = "Recovers HP when consumed."
set itm.commentLn = 1
endif
// 11. Small Mana Potion
if (true) then
set itm = Items.create()
set itm.name = "Small Mana Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeBlue.mdx"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 2
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B08S'
set itm.category = Items.CONSUMABLE
set itm.gold = 4
set itm.cooldown = 8
set itm.hp = 0
set itm.sp = 50
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.comment = "Recovers MP when consumed."
set itm.commentLn = 1
endif
// 12. Medium Mana Potion
if (true) then
set itm = Items.create()
set itm.name = "Medium Mana Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeBlue.mdx"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 2
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B08T'
set itm.category = Items.CONSUMABLE
set itm.gold = 4
set itm.cooldown = 8
set itm.hp = 0
set itm.sp = 100
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.comment = "Recovers MP when consumed."
set itm.commentLn = 1
endif
// 13. Large Mana Potion
if (true) then
set itm = Items.create()
set itm.name = "Large Mana Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeBlue.mdx"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 2
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B08U'
set itm.category = Items.CONSUMABLE
set itm.gold = 4
set itm.cooldown = 8
set itm.hp = 0
set itm.sp = 150
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.comment = "Recovers MP when consumed."
set itm.commentLn = 1
endif
// 14. Giant Mana Potion
if (true) then
set itm = Items.create()
set itm.name = "Giant Mana Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeBlue.mdx"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 2
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B08V'
set itm.category = Items.CONSUMABLE
set itm.gold = 4
set itm.cooldown = 10
set itm.hp = 0
set itm.sp = 200
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.comment = "Recovers MP when consumed."
set itm.commentLn = 1
endif
// 15. Huge Mana Potion
if (true) then
set itm = Items.create()
set itm.name = "Huge Mana Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeBlue.mdx"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 2
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B039'
set itm.category = Items.CONSUMABLE
set itm.gold = 4
set itm.cooldown = 10
set itm.hp = 0
set itm.sp = 250
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.comment = "Recovers MP when consumed."
set itm.commentLn = 1
endif
// 16. Grand Mana Potion
if (true) then
set itm = Items.create()
set itm.name = "Grand Mana Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeBlue.mdx"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 2
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B08W'
set itm.category = Items.CONSUMABLE
set itm.gold = 4
set itm.cooldown = 10
set itm.hp = 0
set itm.sp = 300
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 50
set itm.reqCount = 1
set itm.comment = "Recovers MP when consumed."
set itm.commentLn = 1
endif
// 17. Mega Mana Potion
if (true) then
set itm = Items.create()
set itm.name = "Mega Mana Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeBlue.mdx"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 2
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B08X'
set itm.category = Items.CONSUMABLE
set itm.gold = 4
set itm.cooldown = 12
set itm.hp = 0
set itm.sp = 350
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.comment = "Recovers MP when consumed."
set itm.commentLn = 1
endif
// 18. Super Mana Potion
if (true) then
set itm = Items.create()
set itm.name = "Super Mana Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeBlue.mdx"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 2
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B08Y'
set itm.category = Items.CONSUMABLE
set itm.gold = 4
set itm.cooldown = 12
set itm.hp = 0
set itm.sp = 400
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 70
set itm.reqCount = 1
set itm.comment = "Recovers MP when consumed."
set itm.commentLn = 1
endif
// 19. Ultimate Mana Potion
if (true) then
set itm = Items.create()
set itm.name = "Ultimate Mana Potion"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeBlue.mdx"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 2
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B08Z'
set itm.category = Items.CONSUMABLE
set itm.gold = 4
set itm.cooldown = 12
set itm.hp = 0
set itm.sp = 450
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.comment = "Recovers MP when consumed."
set itm.commentLn = 1
endif
// 20. Mana Potion T10
if (true) then
set itm = Items.create()
set itm.name = "Mana Potion T10"
set itm.avatarPath = "war3mapImported\\Item_Potion_LargeBlue.mdx"
set itm.avatarScale = 0.75
set itm.drop = false
set itm.cooldownGroup = 2
set itm.rarity = 0
set itm.class = "Consumeable"
set itm.maxCharge = 300
set itm.texture = 'B08Z'
set itm.category = Items.CONSUMABLE
set itm.gold = 4
set itm.cooldown = 12
set itm.hp = 0
set itm.sp = 1
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 90
set itm.reqCount = 1
set itm.comment = "Recovers MP when consumed."
set itm.commentLn = 1
endif
// 21. Gold
if (true) then
set itm = Items.create()
set itm.name = "Gold"
set itm.avatarPath = "war3mapImported\\Item_GoldCoins.mdx"
set itm.avatarScale = 0.75
set itm.autoUse = true
set itm.drop = false
set itm.cooldownGroup = 0
set itm.rarity = 6
set itm.class = "Consumeable"
set itm.maxCharge = 1
set itm.texture = 'B09A'
set itm.category = Items.CONSUMABLE
set itm.gold = 0
set itm.cooldown = 0
set itm.hp = 0
set itm.sp = 0
set itm.duration = 0
set itm.job = 0
set itm.reqLevel = 0
set itm.reqCount = 0
set itm.comment = "Cha-ching!"
set itm.commentLn = 1
endif
endif
/********************************************
SCROLLS
********************************************/
if true then
set ITEM_INDEX_SCROLLS = itm
// 1. Tranquil Forest Scroll
if (true) then
set itm = Items.create()
set itm.name = "Tranquil Forest Scroll"
set itm.avatarPath = "war3mapImported\\ScrolRed.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.rarity = 0
set itm.maxCharge = 0
set itm.texture = 'B04C'
set itm.category = Items.SCROLL
set itm.dungeonType = 1
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.comment = "Use this item next to a portal to activate."
set itm.commentLn = 1
endif
// 2. The Forsaken Crypt
if (true) then
set itm = Items.create()
set itm.name = "The Forsaken Crypt"
set itm.avatarPath = "war3mapImported\\ScrolRed.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.rarity = 0
set itm.maxCharge = 0
set itm.texture = 'B03A'
set itm.category = Items.SCROLL
set itm.dungeonType = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.comment = "Use this item next to a portal to activate."
set itm.commentLn = 1
endif
// 3. The Blazing Chamber
if (true) then
set itm = Items.create()
set itm.name = "The Blazing Chamber"
set itm.avatarPath = "war3mapImported\\ScrolRed.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.rarity = 0
set itm.maxCharge = 0
set itm.texture = 'B05A'
set itm.category = Items.SCROLL
set itm.dungeonType = 2
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.comment = "Use this item next to a portal to activate."
set itm.commentLn = 1
endif
endif
/********************************************
GEM
********************************************/
if true then
set ITEM_INDEX_GEM = itm
// 1. Fire Gem T1
if (true) then
set itm = Items.create()
set itm.name = "Small Fire Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Ruby.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE01'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 2
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Fire_1_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 2. Fire Gem T2
if (true) then
set itm = Items.create()
set itm.name = "Medium Fire Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Ruby.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE02'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 5
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Fire_2_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 3. Fire Gem T3
if (true) then
set itm = Items.create()
set itm.name = "Large Fire Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Ruby.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE03'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 8
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Fire_3_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 4. Fire Gem T4
if (true) then
set itm = Items.create()
set itm.name = "Super Fire Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Ruby.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE04'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 11
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Fire_4_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 5. Fire Gem T5
if (true) then
set itm = Items.create()
set itm.name = "Divine Fire Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Ruby.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE05'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 15
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Fire_5_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 6. Water Gem T1
if (true) then
set itm = Items.create()
set itm.name = "Small Water Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Aquamarine.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE11'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 2
set itm.earthElement = 0
set itm.windElement = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_True_Ice_1_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 7. Water Gem T2
if (true) then
set itm = Items.create()
set itm.name = "Medium Water Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Aquamarine.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE12'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 5
set itm.earthElement = 0
set itm.windElement = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_True_Ice_2_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 8. Water Gem T3
if (true) then
set itm = Items.create()
set itm.name = "Large Water Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Aquamarine.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE13'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 8
set itm.earthElement = 0
set itm.windElement = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_True_Ice_3_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 9. Water Gem T4
if (true) then
set itm = Items.create()
set itm.name = "Super Water Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Aquamarine.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE14'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 11
set itm.earthElement = 0
set itm.windElement = 0
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_True_Ice_4_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 10. Water Gem T5
if (true) then
set itm = Items.create()
set itm.name = "Divine Water Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Aquamarine.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE15'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 15
set itm.earthElement = 0
set itm.windElement = 0
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_True_Ice_5_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 11. Earth Gem T1
if (true) then
set itm = Items.create()
set itm.name = "Small Earth Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Jade.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE21'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 2
set itm.windElement = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Acid_1_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 12. Earth Gem T2
if (true) then
set itm = Items.create()
set itm.name = "Medium Earth Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Jade.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE22'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 5
set itm.windElement = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Acid_2_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 13. Earth Gem T3
if (true) then
set itm = Items.create()
set itm.name = "Large Earth Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Jade.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE23'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 8
set itm.windElement = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Acid_3_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 14. Earth Gem T4
if (true) then
set itm = Items.create()
set itm.name = "Super Earth Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Jade.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE24'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 11
set itm.windElement = 0
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Acid_4_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 15. Earth Gem T5
if (true) then
set itm = Items.create()
set itm.name = "Divine Earth Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Jade.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE25'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 15
set itm.windElement = 0
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Acid_5_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 16. Wind Gem T1
if (true) then
set itm = Items.create()
set itm.name = "Small Wind Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Diamond.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE31'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 2
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Lightning_1_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 17. Wind Gem T2
if (true) then
set itm = Items.create()
set itm.name = "Medium Wind Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Diamond.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE32'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 5
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Lightning_2_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 18. Wind Gem T3
if (true) then
set itm = Items.create()
set itm.name = "Large Wind Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Diamond.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE33'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 8
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Lightning_3_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 19. Wind Gem T4
if (true) then
set itm = Items.create()
set itm.name = "Super Wind Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Diamond.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE34'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 11
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Lightning_4_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
// 20. Wind Gem T5
if (true) then
set itm = Items.create()
set itm.name = "Divine Wind Gem"
set itm.avatarPath = "war3mapImported\\Item_Gem_Diamond.mdx"
set itm.avatarScale = 0.5
set itm.drop = false
set itm.rarity = 0
set itm.class = ""
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.maxCharge = 0
set itm.texture = 'GE35'
set itm.category = Items.GEM
set itm.gold = 50
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.criticalRate = 0
set itm.criticalPower = 0
set itm.evasionRate = 0
set itm.knockback = 0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 15
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.model = "war3mapImported\\Sweep_Lightning_5_"
set itm.comment = "Insert this on a socketable item."
set itm.commentLn = 1
endif
endif
/********************************************
MISC
********************************************/
if true then
set ITEM_INDEX_MISC = itm
// 1. Black Ore T1
if (true) then
set itm = Items.create()
set itm.name = "Metalrio [D]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.dropWeight = 4
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 1 // Tier
set itm.fortitude = 1 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE01'
set itm.category = Items.MISC
set itm.gold = 25
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 2. Black Ore T2
if (true) then
set itm = Items.create()
set itm.name = "Metalrio [C]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.dropWeight = 4
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 2 // Tier
set itm.fortitude = 1 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE02'
set itm.category = Items.MISC
set itm.gold = 25
set itm.reqLevel = 5
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 3. Black Ore T3
if (true) then
set itm = Items.create()
set itm.name = "Metalrio [B]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.dropWeight = 4
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 3 // Tier
set itm.fortitude = 1 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE03'
set itm.category = Items.MISC
set itm.gold = 25
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 4. Black Ore T4
if (true) then
set itm = Items.create()
set itm.name = "Metalrio [A]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.dropWeight = 4
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 4 // Tier
set itm.fortitude = 1 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE04'
set itm.category = Items.MISC
set itm.gold = 25
set itm.reqLevel = 15
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 5. Blue Ore T1
if (true) then
set itm = Items.create()
set itm.name = "Setalian [D]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 1 // Tier
set itm.fortitude = 2 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE11'
set itm.category = Items.MISC
set itm.gold = 25
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 6. Blue Ore T2
if (true) then
set itm = Items.create()
set itm.name = "Setalian [C]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.dropWeight = 3
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 2 // Tier
set itm.fortitude = 2 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE12'
set itm.category = Items.MISC
set itm.gold = 25
set itm.reqLevel = 5
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 7. Blue Ore T3
if (true) then
set itm = Items.create()
set itm.name = "Setalian [B]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.dropWeight = 3
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 3 // Tier
set itm.fortitude = 2 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE13'
set itm.category = Items.MISC
set itm.gold = 25
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 8. Blue Ore T4
if (true) then
set itm = Items.create()
set itm.name = "Setalian [A]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.dropWeight = 3
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 4 // Tier
set itm.fortitude = 2 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE14'
set itm.category = Items.MISC
set itm.gold = 25
set itm.reqLevel = 15
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 9. Red Ore T1
if (true) then
set itm = Items.create()
set itm.name = "Protalus [D]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 1 // Tier
set itm.fortitude = 3 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE21'
set itm.category = Items.MISC
set itm.gold = 25
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 10. Red Ore T2
if (true) then
set itm = Items.create()
set itm.name = "Protalus [C]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 2 // Tier
set itm.fortitude = 3 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE22'
set itm.category = Items.MISC
set itm.gold = 25
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.reqLevel = 5
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 11. Red Ore T3
if (true) then
set itm = Items.create()
set itm.name = "Protalus [B]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 3 // Tier
set itm.fortitude = 3 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE23'
set itm.category = Items.MISC
set itm.gold = 25
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 12. Red Ore T4
if (true) then
set itm = Items.create()
set itm.name = "Protalus [A]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 4 // Tier
set itm.fortitude = 3 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE24'
set itm.category = Items.MISC
set itm.gold = 25
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.reqLevel = 15
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 13. Yellow Ore T1
if (true) then
set itm = Items.create()
set itm.name = "Ostalium [D]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 1 // Tier
set itm.fortitude = 4 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE31'
set itm.category = Items.MISC
set itm.gold = 25
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 14. Yellow Ore T2
if (true) then
set itm = Items.create()
set itm.name = "Ostalium [C]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 2 // Tier
set itm.fortitude = 4 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE32'
set itm.category = Items.MISC
set itm.gold = 25
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.reqLevel = 5
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 15. Yellow Ore T3
if (true) then
set itm = Items.create()
set itm.name = "Ostalium [B]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 3 // Tier
set itm.fortitude = 4 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE33'
set itm.category = Items.MISC
set itm.gold = 25
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 16. Yellow Ore T4
if (true) then
set itm = Items.create()
set itm.name = "Ostalium [A]"
set itm.avatarPath = "war3mapImported\\IronOre.mdx"
set itm.avatarScale = 0.7
set itm.drop = false
set itm.rarity = 0
set itm.class = "Ore"
set itm.strength = 1 // Slot index
set itm.wisdom = 4 // Tier
set itm.fortitude = 4 // Ore Type
set itm.maxCharge = 99
set itm.texture = 'OE34'
set itm.category = Items.MISC
set itm.gold = 25
set itm.physicDmg = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDefense = 0
set itm.reqLevel = 15
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment."
set itm.commentLn = 1
endif
// 17. Topaz T1
if (true) then
set itm = Items.create()
set itm.name = "Topaz Scrap"
set itm.avatarPath = "war3mapImported\\GemYellow.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 5 // Slot index
set itm.wisdom = 1 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE41'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nSlightly increases success rate."
set itm.commentLn = 2
endif
// 18. Topaz T2
if (true) then
set itm = Items.create()
set itm.name = "Topaz Fragment"
set itm.avatarPath = "war3mapImported\\GemYellow.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 5 // Slot index
set itm.wisdom = 2 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE42'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nFairly increases success rate."
set itm.commentLn = 2
endif
// 19. Topaz T3
if (true) then
set itm = Items.create()
set itm.name = "Topaz Shard"
set itm.avatarPath = "war3mapImported\\GemYellow.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 5 // Slot index
set itm.wisdom = 3 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE43'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nGreatly increases success rate."
set itm.commentLn = 2
endif
// 20. Topaz T4
if (true) then
set itm = Items.create()
set itm.name = "Topaz Stone"
set itm.avatarPath = "war3mapImported\\GemYellow.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 5 // Slot index
set itm.wisdom = 4 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE44'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nSignificantly increases success rate."
set itm.commentLn = 2
endif
// 21. Quartz T1
if (true) then
set itm = Items.create()
set itm.name = "Quartz Scrap"
set itm.avatarPath = "war3mapImported\\GemBlack.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 3 // Slot index
set itm.wisdom = 1 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE51'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nSlightly increases success rate."
set itm.commentLn = 2
endif
// 22. Quartz T2
if (true) then
set itm = Items.create()
set itm.name = "Quartz Fragment"
set itm.avatarPath = "war3mapImported\\GemBlack.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 3 // Slot index
set itm.wisdom = 2 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE52'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nFairly increases success rate."
set itm.commentLn = 2
endif
// 23. Quartz T3
if (true) then
set itm = Items.create()
set itm.name = "Quartz Shard"
set itm.avatarPath = "war3mapImported\\GemBlack.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 3 // Slot index
set itm.wisdom = 3 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE53'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nGreatly increases success rate."
set itm.commentLn = 2
endif
// 24. Quartz T4
if (true) then
set itm = Items.create()
set itm.name = "Quartz Stone"
set itm.avatarPath = "war3mapImported\\GemBlack.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 3 // Slot index
set itm.wisdom = 4 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE54'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nSignificantly increases success rate."
set itm.commentLn = 2
endif
// 25. Crystal T1
if (true) then
set itm = Items.create()
set itm.name = "Crystal Scrap"
set itm.avatarPath = "war3mapImported\\GemBlue.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 4 // Slot index
set itm.wisdom = 1 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE61'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nSlightly increases success rate."
set itm.commentLn = 2
endif
// 26. Crystal T2
if (true) then
set itm = Items.create()
set itm.name = "Crystal Fragment"
set itm.avatarPath = "war3mapImported\\GemBlue.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 4 // Slot index
set itm.wisdom = 2 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE62'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nFairly increases success rate."
set itm.commentLn = 2
endif
// 27. Crystal T3
if (true) then
set itm = Items.create()
set itm.name = "Crystal Shard"
set itm.avatarPath = "war3mapImported\\GemBlue.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 4 // Slot index
set itm.wisdom = 3 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE63'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nGreatly increases success rate."
set itm.commentLn = 2
endif
// 28. Crystal T4
if (true) then
set itm = Items.create()
set itm.name = "Crystal Stone"
set itm.avatarPath = "war3mapImported\\GemBlue.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 4 // Slot index
set itm.wisdom = 4 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE64'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nSignificantly increases success rate."
set itm.commentLn = 2
endif
// 29. Jade T1
if (true) then
set itm = Items.create()
set itm.name = "Jade Scrap"
set itm.avatarPath = "war3mapImported\\GemGreen.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 2 // Slot index
set itm.wisdom = 1 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE71'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nSlightly increases success rate."
set itm.commentLn = 2
endif
// 30. Jade T2
if (true) then
set itm = Items.create()
set itm.name = "Jade Fragment"
set itm.avatarPath = "war3mapImported\\GemGreen.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 2 // Slot index
set itm.wisdom = 2 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE72'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nFairly increases success rate."
set itm.commentLn = 2
endif
// 31. Jade T3
if (true) then
set itm = Items.create()
set itm.name = "Jade Shard"
set itm.avatarPath = "war3mapImported\\GemGreen.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 2 // Slot index
set itm.wisdom = 3 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE73'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nGreatly increases success rate."
set itm.commentLn = 2
endif
// 32. Jade T4
if (true) then
set itm = Items.create()
set itm.name = "Jade Stone"
set itm.avatarPath = "war3mapImported\\GemGreen.mdx"
set itm.avatarScale = 0.6
set itm.drop = false
set itm.rarity = 0
set itm.class = "Gemstone"
set itm.strength = 2 // Slot index
set itm.wisdom = 4 // Tier
set itm.maxCharge = 99
set itm.texture = 'OE74'
set itm.category = Items.MISC
set itm.gold = 15
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.model = ""
set itm.comment = "Material for upgrading equipment.\nSignificantly increases success rate."
set itm.commentLn = 2
endif
endif
/********************************************
EQUIPMENT
********************************************/
if true then
set ITEM_INDEX_EQUIPMENT = itm
// Helmet
if true then
// 1. Helmet T0
if (true) then
set itm = Items.create()
set itm.name = "Poor's Hat"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Head"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ31'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_HELMET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_HELMET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_HELMET_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 2. Helmet T1
if (true) then
set itm = Items.create()
set itm.name = "Leather Hat"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Head"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ31'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_HELMET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_HELMET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_HELMET_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 3. Helmet T2
if (true) then
set itm = Items.create()
set itm.name = "Fabric Hat"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Head"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ32'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_HELMET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_HELMET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_HELMET_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 4. Helmet T3
if (true) then
set itm = Items.create()
set itm.name = "Linen Hat"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Head"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ33'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_HELMET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_HELMET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_HELMET_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 5. Helmet T4
if (true) then
set itm = Items.create()
set itm.name = "Bone Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Head"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ34'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_HELMET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_HELMET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_HELMET_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 6. Helmet T5
if (true) then
set itm = Items.create()
set itm.name = "Iron Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Head"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ35'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_HELMET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_HELMET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_HELMET_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 50
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 7. Helmet T6
if (true) then
set itm = Items.create()
set itm.name = "Silver Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Head"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ36'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_HELMET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_HELMET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_HELMET_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 8. Helmet T7
if (true) then
set itm = Items.create()
set itm.name = "Steel Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Head"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ37'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_HELMET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_HELMET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_HELMET_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 70
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 9. Helmet T8
if (true) then
set itm = Items.create()
set itm.name = "Golden Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Head"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ38'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_HELMET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_HELMET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_HELMET_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 10. Helmet T9
if (true) then
set itm = Items.create()
set itm.name = "Unholy Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Head"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ39'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_HELMET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_HELMET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_HELMET_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 90
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 11. Helmet T10
if (true) then
set itm = Items.create()
set itm.name = "Celestial Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Head"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ38'//'EQ3A'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_HELMET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_HELMET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_HELMET_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 100
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
endif
// Chest
if true then
// 12. Chest T0
if (true) then
set itm = Items.create()
set itm.name = "Poor's Clothing"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Chest"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ10'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_CHEST_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_CHEST_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 13. Chest T1
if (true) then
set itm = Items.create()
set itm.name = "Leather Clothes"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Chest"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ11'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_CHEST_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_CHEST_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 14. Chest T2
if (true) then
set itm = Items.create()
set itm.name = "Fabric Clothes"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Chest"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ12'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_CHEST_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_CHEST_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 15. Chest T3
if (true) then
set itm = Items.create()
set itm.name = "Linen Clothes"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Chest"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ13'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_CHEST_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_CHEST_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 16. Chest T4
if (true) then
set itm = Items.create()
set itm.name = "Bone Armor"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Chest"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ14'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_CHEST_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_CHEST_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 17. Chest T5
if (true) then
set itm = Items.create()
set itm.name = "Iron Armor"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Chest"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ15'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_CHEST_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_CHEST_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 50
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 18. Chest T6
if (true) then
set itm = Items.create()
set itm.name = "Silver Armor"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Chest"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ16'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_CHEST_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_CHEST_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 19. Chest T7
if (true) then
set itm = Items.create()
set itm.name = "Steel Armor"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Chest"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ17'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_CHEST_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_CHEST_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 70
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 20. Chest T8
if (true) then
set itm = Items.create()
set itm.name = "Golden Armor"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Chest"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ18'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_CHEST_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_CHEST_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 21. Chest T9
if (true) then
set itm = Items.create()
set itm.name = "Unholy Armor"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Chest"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ19'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_CHEST_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_CHEST_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 90
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 22. Chest T10
if (true) then
set itm = Items.create()
set itm.name = "Celestial Armor"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Chest"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ1A'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_CHEST_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_CHEST_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 100
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
endif
// Pads
if true then
// 23. Pads T0
if (true) then
set itm = Items.create()
set itm.name = "Poor's Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 1
set itm.class = "Shoulder"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ61'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_PADS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0.
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_PADS_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 24. Pads T1
if (true) then
set itm = Items.create()
set itm.name = "Leather Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 1
set itm.class = "Shoulder"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ61'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_PADS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0.
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_PADS_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 25. Pads T2
if (true) then
set itm = Items.create()
set itm.name = "Fabric Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 1
set itm.class = "Shoulder"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ62'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_PADS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0.
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_PADS_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 26. Pads T3
if (true) then
set itm = Items.create()
set itm.name = "Leather Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 1
set itm.class = "Shoulder"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ63'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_PADS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0.
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_PADS_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 27. Pads T4
if (true) then
set itm = Items.create()
set itm.name = "Bone Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 1
set itm.class = "Shoulder"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ64'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_PADS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0.
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_PADS_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 28. Pads T5
if (true) then
set itm = Items.create()
set itm.name = "Iron Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 1
set itm.class = "Shoulder"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ65'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_PADS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0.
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_PADS_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 50
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 29. Pads T6
if (true) then
set itm = Items.create()
set itm.name = "Silver Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 1
set itm.class = "Shoulder"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ66'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_PADS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0.
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_PADS_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 30. Pads T7
if (true) then
set itm = Items.create()
set itm.name = "Steel Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 1
set itm.class = "Shoulder"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ67'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_PADS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0.
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_PADS_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 70
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 31. Pads T8
if (true) then
set itm = Items.create()
set itm.name = "Golden Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 1
set itm.class = "Shoulder"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ67'//'EQ68'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_PADS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0.
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_PADS_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 32. Pads T9
if (true) then
set itm = Items.create()
set itm.name = "Unholy Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 1
set itm.class = "Shoulder"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ67'//'EQ69'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_PADS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0.
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_PADS_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 90
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 33. Pads T10
if (true) then
set itm = Items.create()
set itm.name = "Celestial Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 1
set itm.class = "Shoulder"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ67'//'EQ6A'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_PADS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0.
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_PADS_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 100
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
endif
// Gloves
if true then
// 34. Gloves T0
if (true) then
set itm = Items.create()
set itm.name = "Poor's Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Arm"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ23'//'EQ21'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_GLOVES_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_GLOVES_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_GLOVES_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 35. Gloves T1
if (true) then
set itm = Items.create()
set itm.name = "Leather Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Arm"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ23'//'EQ21'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_GLOVES_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_GLOVES_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_GLOVES_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 36. Gloves T2
if (true) then
set itm = Items.create()
set itm.name = "Fabric Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Arm"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ23'//'EQ22'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_GLOVES_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_GLOVES_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_GLOVES_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 37. Gloves T3
if (true) then
set itm = Items.create()
set itm.name = "Linen Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Arm"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ23'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_GLOVES_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_GLOVES_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_GLOVES_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 38. Gloves T4
if (true) then
set itm = Items.create()
set itm.name = "Bone Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Arm"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ23'//'EQ24'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_GLOVES_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_GLOVES_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_GLOVES_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 39. Gloves T5
if (true) then
set itm = Items.create()
set itm.name = "Iron Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Arm"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ26'//'EQ25'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_GLOVES_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_GLOVES_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_GLOVES_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 50
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 40. Gloves T6
if (true) then
set itm = Items.create()
set itm.name = "Silver Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Arm"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ26'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_GLOVES_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_GLOVES_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_GLOVES_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 41. Gloves T7
if (true) then
set itm = Items.create()
set itm.name = "Steel Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Arm"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ27'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_GLOVES_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_GLOVES_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_GLOVES_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 70
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 42. Gloves T8
if (true) then
set itm = Items.create()
set itm.name = "Golden Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Arm"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ28'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_GLOVES_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_GLOVES_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_GLOVES_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 43. Gloves T9
if (true) then
set itm = Items.create()
set itm.name = "Unholy Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Arm"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ26'//'EQ29'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_GLOVES_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_GLOVES_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_GLOVES_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 90
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 44. Gloves T10
if (true) then
set itm = Items.create()
set itm.name = "Celestial Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Arm"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ27'//'EQ2A'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_GLOVES_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_GLOVES_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = GENERIC_ARMOR_GLOVES_MAGIC
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 100
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
endif
// Legs
if true then
// 45. Legs T0
if (true) then
set itm = Items.create()
set itm.name = "Poor's Trousers"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Legs"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ41'//'EQ40'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_LEGS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_LEGS_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 46. Legs T1
if (true) then
set itm = Items.create()
set itm.name = "Leather Pants"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Legs"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ41'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_LEGS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_LEGS_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 47. Legs T2
if (true) then
set itm = Items.create()
set itm.name = "Fabric Pants"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Legs"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ42'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_LEGS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_LEGS_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 48. Legs T3
if (true) then
set itm = Items.create()
set itm.name = "Linen Pants"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Legs"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ43'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_LEGS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_LEGS_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 49. Legs T4
if (true) then
set itm = Items.create()
set itm.name = "Bone Leggings"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Legs"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ43'//'EQ44'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_LEGS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_LEGS_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 50. Legs T5
if (true) then
set itm = Items.create()
set itm.name = "Iron Leggings"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Legs"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ46'//'EQ45'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_LEGS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_LEGS_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 50
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 51. Legs T6
if (true) then
set itm = Items.create()
set itm.name = "Silver Leggings"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Legs"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ46'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_LEGS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_LEGS_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 52. Legs T7
if (true) then
set itm = Items.create()
set itm.name = "Steel Leggings"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Legs"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ47'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_LEGS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_LEGS_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 70
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 53. Legs T8
if (true) then
set itm = Items.create()
set itm.name = "Golden Leggings"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Legs"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ48'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_LEGS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_LEGS_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 54. Legs T9
if (true) then
set itm = Items.create()
set itm.name = "Unholy Leggings"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Legs"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ46'//'EQ49'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_LEGS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_LEGS_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 90
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 55. Legs T10
if (true) then
set itm = Items.create()
set itm.name = "Celestial Leggings"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Legs"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ47'//'EQ4A'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_LEGS_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_LEGS_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 100
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
endif
// Feet
if true then
// 56. Feet T0
if (true) then
set itm = Items.create()
set itm.name = "Poor's Sandals"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Feet"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ01'//'EQ00'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_FEET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_FEET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 57. Feet T1
if (true) then
set itm = Items.create()
set itm.name = "Leather Sandals"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Feet"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ01'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_FEET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_FEET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 58. Feet T2
if (true) then
set itm = Items.create()
set itm.name = "Fabric Sandals"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Feet"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ02'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_FEET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_FEET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 59. Feet T3
if (true) then
set itm = Items.create()
set itm.name = "Linen Sandals"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Feet"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ03'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_FEET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_FEET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 60. Feet T4
if (true) then
set itm = Items.create()
set itm.name = "Bone Greaves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Feet"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ03'//'EQ04'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_FEET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_FEET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 61. Feet T5
if (true) then
set itm = Items.create()
set itm.name = "Iron Greaves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Feet"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ05'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_FEET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_FEET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 50
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 62. Feet T6
if (true) then
set itm = Items.create()
set itm.name = "Silver Greaves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Feet"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ06'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_FEET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_FEET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 63. Feet T7
if (true) then
set itm = Items.create()
set itm.name = "Steel Greaves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Feet"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ07'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_FEET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_FEET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 70
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 64. Feet T8
if (true) then
set itm = Items.create()
set itm.name = "Golden Greaves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Feet"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ07'//'EQ08'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_FEET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_FEET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 65. Feet T9
if (true) then
set itm = Items.create()
set itm.name = "Unholy Greaves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Feet"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ09'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_FEET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_FEET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 90
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 66. Feet T10
if (true) then
set itm = Items.create()
set itm.name = "Celestial Greaves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Feet"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ0A'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_FEET_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_FEET_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 100
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
endif
// Shield
if true then
// 67. Shield T0
if (true) then
set itm = Items.create()
set itm.name = "Poor's Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Shield"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ50'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_SHIELD_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_SHIELD_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.attackRange = 0
set itm.blockRate = GENERIC_ARMOR_SHIELD_BLOCK
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = -1.0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 1
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 68. Shield T1
if (true) then
set itm = Items.create()
set itm.name = "Wooden Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Shield"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ51'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_SHIELD_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_SHIELD_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.attackRange = 0
set itm.blockRate = GENERIC_ARMOR_SHIELD_BLOCK
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = -1.0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 69. Shield T2
if (true) then
set itm = Items.create()
set itm.name = "Oakwood Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Shield"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ52'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_SHIELD_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_SHIELD_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.attackRange = 0
set itm.blockRate = GENERIC_ARMOR_SHIELD_BLOCK
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = -1.0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 70. Shield T3
if (true) then
set itm = Items.create()
set itm.name = "Teakwood Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Shield"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ53'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_SHIELD_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_SHIELD_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.attackRange = 0
set itm.blockRate = GENERIC_ARMOR_SHIELD_BLOCK
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = -1.0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 71. Shield T4
if (true) then
set itm = Items.create()
set itm.name = "Tower Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Shield"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ54'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_SHIELD_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_SHIELD_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.attackRange = 0
set itm.blockRate = GENERIC_ARMOR_SHIELD_BLOCK
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = -1.0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 72. Shield T5
if (true) then
set itm = Items.create()
set itm.name = "Iron Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Shield"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ55'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_SHIELD_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_SHIELD_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.attackRange = 0
set itm.blockRate = GENERIC_ARMOR_SHIELD_BLOCK
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = -1.0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 50
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 73. Shield T6
if (true) then
set itm = Items.create()
set itm.name = "Steel Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Shield"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ56'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_SHIELD_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_SHIELD_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.attackRange = 0
set itm.blockRate = GENERIC_ARMOR_SHIELD_BLOCK
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = -1.0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 60
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 74. Shield T7
if (true) then
set itm = Items.create()
set itm.name = "Runed Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Shield"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ57'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_SHIELD_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_SHIELD_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.attackRange = 0
set itm.blockRate = GENERIC_ARMOR_SHIELD_BLOCK
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = -1.0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 70
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 75. Shield T8
if (true) then
set itm = Items.create()
set itm.name = "Adamantite Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Shield"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ58'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_SHIELD_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_SHIELD_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.attackRange = 0
set itm.blockRate = GENERIC_ARMOR_SHIELD_BLOCK
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = -1.0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 80
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 76. Shield T9
if (true) then
set itm = Items.create()
set itm.name = "Unholy Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Shield"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ59'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_SHIELD_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_SHIELD_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.attackRange = 0
set itm.blockRate = GENERIC_ARMOR_SHIELD_BLOCK
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = -1.0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 90
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 77. Shield T10
if (true) then
set itm = Items.create()
set itm.name = "Celestial Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Shield"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ5A'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = GENERIC_ARMOR_SHIELD_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = GENERIC_ARMOR_SHIELD_PHYSIC
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.attackRange = 0
set itm.blockRate = GENERIC_ARMOR_SHIELD_BLOCK
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = -1.0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 100
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
endif
// Blade
if true then
// 78. Blade T0
if (true) then
set itm = Items.create()
set itm.name = "Training Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "One-handed"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ70'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BLADE_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BLADE_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BLADE_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 1
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 79. Blade T1
if (true) then
set itm = Items.create()
set itm.name = "Copper Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "One-handed"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ71'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BLADE_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BLADE_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BLADE_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 80. Blade T2
if (true) then
set itm = Items.create()
set itm.name = "Iron Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "One-handed"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ72'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BLADE_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BLADE_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BLADE_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 81. Blade T3
if (true) then
set itm = Items.create()
set itm.name = "Steel Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "One-handed"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ73'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BLADE_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BLADE_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BLADE_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 82. Blade T4
if (true) then
set itm = Items.create()
set itm.name = "Sylvanite Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "One-handed"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ74'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BLADE_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BLADE_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BLADE_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 83. Blade T5
if (true) then
set itm = Items.create()
set itm.name = "Arcnite Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "One-handed"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ75'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BLADE_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BLADE_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BLADE_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 50
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 84. Blade T6
if (true) then
set itm = Items.create()
set itm.name = "Mithril Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "One-handed"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ76'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BLADE_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BLADE_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BLADE_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 60
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 85. Blade T7
if (true) then
set itm = Items.create()
set itm.name = "Runed Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "One-handed"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ77'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BLADE_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BLADE_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BLADE_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 70
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 86. Blade T8
if (true) then
set itm = Items.create()
set itm.name = "Adamantite Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "One-handed"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ78'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BLADE_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BLADE_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BLADE_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 80
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 87. Blade T9
if (true) then
set itm = Items.create()
set itm.name = "Unholy Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "One-handed"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ79'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BLADE_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BLADE_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BLADE_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 90
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 88. Blade T10
if (true) then
set itm = Items.create()
set itm.name = "Celestial Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "One-handed"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ7A'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BLADE_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BLADE_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BLADE_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 100
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
endif
// Bow
if true then
// 89. Bow T0
if (true) then
set itm = Items.create()
set itm.name = "Training Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Bow"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ80'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BOW_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BOW_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BOW_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 1
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 90. Bow T1
if (true) then
set itm = Items.create()
set itm.name = "Root Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Bow"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ81'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BOW_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BOW_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BOW_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 91. Bow T2
if (true) then
set itm = Items.create()
set itm.name = "Hardwood Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Bow"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ82'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BOW_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BOW_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BOW_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 92. Bow T3
if (true) then
set itm = Items.create()
set itm.name = "Bamboo Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Bow"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ83'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BOW_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BOW_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BOW_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 93. Bow T4
if (true) then
set itm = Items.create()
set itm.name = "Compound Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Bow"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ84'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BOW_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BOW_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BOW_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 94. Bow T5
if (true) then
set itm = Items.create()
set itm.name = "Cedar Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Bow"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ85'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BOW_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BOW_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BOW_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 50
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 95. Bow T6
if (true) then
set itm = Items.create()
set itm.name = "Maple Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Bow"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ86'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BOW_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BOW_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BOW_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 60
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 96. Bow T7
if (true) then
set itm = Items.create()
set itm.name = "Bone Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Bow"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ87'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BOW_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BOW_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BOW_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 70
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 97. Bow T8
if (true) then
set itm = Items.create()
set itm.name = "Red Elm Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Bow"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ88'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BOW_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BOW_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BOW_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 80
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 98. Bow T9
if (true) then
set itm = Items.create()
set itm.name = "Bubinga Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Bow"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ89'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BOW_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BOW_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BOW_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 90
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 99. Bow T10
if (true) then
set itm = Items.create()
set itm.name = "Celestial Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 1
set itm.class = "Bow"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ8A'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = GENERIC_WEAPON_BOW_GOLD
set itm.physicDmg = 0
set itm.physicDmgMin = GENERIC_WEAPON_BOW_PHYSIC_MIN
set itm.physicDmgMax = GENERIC_WEAPON_BOW_PHYSIC_MAX
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 100
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
endif
endif
call ForForce(bj_FORCE_PLAYER[0], function ItemLib2_init)
//call ForForce(bj_FORCE_PLAYER[0], function Items_AdjustItemStats)
call InitItemSet()
endfunction
globals
integer ITEM_INDEX_POTIONS = 0
integer ITEM_INDEX_SCROLLS = 0
integer ITEM_INDEX_EQUIPMENT = 0
integer ITEM_INDEX_GEM = 0
integer ITEM_INDEX_MISC = 0
endglobals
endlibrary
library ItemLib2
public function init takes nothing returns nothing
local Items itm
/********************************************
EQUIPMENT 2
********************************************/
if true then
// 100. Stone Ring
if (true) then
set itm = Items.create()
set itm.name = "Stone Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Ring"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ9F'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 23
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 2.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 101. Iron Ring
if (true) then
set itm = Items.create()
set itm.name = "Iron Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Ring"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ9F'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 23
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 2.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 102. Flak Ring
if (true) then
set itm = Items.create()
set itm.name = "Iron Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Ring"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ9F'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 23
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 2.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 103. Stainless Ring
if (true) then
set itm = Items.create()
set itm.name = "Stainless Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Ring"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ9F'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 23
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 2.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 104. Mythril Ring
if (true) then
set itm = Items.create()
set itm.name = "Mythril Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Ring"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ9F'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 23
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 2.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 50
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 105. Runed Ring
if (true) then
set itm = Items.create()
set itm.name = "Runed Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Ring"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ9F'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 23
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 2.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 106. Adamant Ring
if (true) then
set itm = Items.create()
set itm.name = "Adamant Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Ring"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ9F'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 23
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 2.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 70
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 107. Ancient Ring
if (true) then
set itm = Items.create()
set itm.name = "Ancient Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Ring"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ9F'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 23
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 2.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 108. Mystical Ring
if (true) then
set itm = Items.create()
set itm.name = "Ancient Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Ring"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ9F'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 23
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 2.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 90
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 109. Sacred Ring
if (true) then
set itm = Items.create()
set itm.name = "Sacred Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 1
set itm.class = "Ring"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQ9F'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 23
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 2.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 100
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 110. Shell Necklace
if (true) then
set itm = Items.create()
set itm.name = "Shell Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Necklace"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQAW'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 30
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 3.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 1
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 111. Clam Necklace
if (true) then
set itm = Items.create()
set itm.name = "Clam Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Necklace"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQAW'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 30
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 3.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 112. Hardshell Necklace
if (true) then
set itm = Items.create()
set itm.name = "Hardshell Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Necklace"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQAW'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 30
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 3.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 113. Bone Necklace
if (true) then
set itm = Items.create()
set itm.name = "Bone Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Necklace"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQAD'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 30
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 3.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 114. Stone Necklace
if (true) then
set itm = Items.create()
set itm.name = "Stone Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Necklace"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQAD'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 30
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 3.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 115. Tomb Necklace
if (true) then
set itm = Items.create()
set itm.name = "Tomb Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Necklace"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQAD'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 30
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 3.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 50
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 116. Iron Necklace
if (true) then
set itm = Items.create()
set itm.name = "Iron Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Necklace"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQAD'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 30
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 3.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 60
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 117. Adamant Necklace
if (true) then
set itm = Items.create()
set itm.name = "Adamant Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Necklace"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQAD'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 30
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 3.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 70
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 118. Obsidian Necklace
if (true) then
set itm = Items.create()
set itm.name = "Obsidian Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Necklace"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQAD'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 30
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 3.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 80
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 119. Amethyst Necklace
if (true) then
set itm = Items.create()
set itm.name = "Amethyst Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Necklace"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQAD'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 30
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 3.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 90
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 120. Celestial Necklace
if (true) then
set itm = Items.create()
set itm.name = "Celestial Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 1
set itm.class = "Necklace"
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.texture = 'EQAO'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 30
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 3.0
set itm.attackRange = 0
set itm.blockRate = 0
set itm.criticalRate = 0.0
set itm.criticalPower = 0.0
set itm.evasionRate = 0.0
set itm.knockback = 0.0
set itm.knockbackResist = 0
set itm.interrupt = 0
set itm.interruptResist = 0
set itm.stun = 0.0
set itm.stunResist = 0
set itm.hpMax = 0
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.
set itm.aspd = 0.
set itm.mspd = 0.
set itm.fireElement = 0
set itm.waterElement = 0
set itm.earthElement = 0
set itm.windElement = 0
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 100
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 121. Claymore
if (true) then
set itm = Items.create()
set itm.name = "Claymore"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 2
set itm.class = "One-handed"
set itm.texture = 'EQ7K'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 40
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 122. Long Bow
if (true) then
set itm = Items.create()
set itm.name = "Long Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 2
set itm.class = "Bow"
set itm.texture = 'EQ84'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 44
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 123. Full Helmet
if (true) then
set itm = Items.create()
set itm.name = "Full Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Head"
set itm.texture = 'EQ3N'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = 25
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 124. Combat Suit
if (true) then
set itm = Items.create()
set itm.name = "Combat Suit"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 2
set itm.class = "Chest"
set itm.texture = 'EQ1J'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = 30
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 125. Spiked Pads
if (true) then
set itm = Items.create()
set itm.name = "Spiked Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 2
set itm.class = "Shoulder"
set itm.texture = 'EQ6M'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = 16
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 126. Wooly Gloves
if (true) then
set itm = Items.create()
set itm.name = "Wooly Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Arm"
set itm.texture = 'EQ2I'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = 18
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 127. Thick Trousers
if (true) then
set itm = Items.create()
set itm.name = "Thick Trousers"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Legs"
set itm.texture = 'EQ4C'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = 25
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 128. Coated Boots
if (true) then
set itm = Items.create()
set itm.name = "Coated Boots"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Feet"
set itm.texture = 'EQ0H'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = 16
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 129. Wooden Buckler
if (true) then
set itm = Items.create()
set itm.name = "Wooden Buckler"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Shield"
set itm.texture = 'EQ5D'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = 37
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 130. Jade Ring
if (true) then
set itm = Items.create()
set itm.name = "Jade Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Ring"
set itm.texture = 'EQ9I'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 28
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 131. Antique Necklace
if (true) then
set itm = Items.create()
set itm.name = "Antique Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 2
set itm.class = "Necklace"
set itm.texture = 'EQAD'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 35
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 132. Necro Blade
if (true) then
set itm = Items.create()
set itm.name = "Necro Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 2
set itm.class = "One-handed"
set itm.texture = 'EQ7L'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 40
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 133. Carved Bow
if (true) then
set itm = Items.create()
set itm.name = "Carved Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 2
set itm.class = "Bow"
set itm.texture = 'EQ86'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 44
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 134. Horned Helmet
if (true) then
set itm = Items.create()
set itm.name = "Horned Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Head"
set itm.texture = 'EQ3E'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = 25
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 135. Compact Armor
if (true) then
set itm = Items.create()
set itm.name = "Compact Armor"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 2
set itm.class = "Chest"
set itm.texture = 'EQ1K'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = 30
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 136. Jade Pads
if (true) then
set itm = Items.create()
set itm.name = "Jade Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 2
set itm.class = "Shoulder"
set itm.texture = 'EQ6P'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = 16
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 137. Apprentice Gloves
if (true) then
set itm = Items.create()
set itm.name = "Apprentice Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Arm"
set itm.texture = 'EQ2D'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = 18
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 138. Combatant Trousers
if (true) then
set itm = Items.create()
set itm.name = "Combatant Trousers"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Legs"
set itm.texture = 'EQ4G'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = 25
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 139. Wanderer Boots
if (true) then
set itm = Items.create()
set itm.name = "Wanderer Boots"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Feet"
set itm.texture = 'EQ0E'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = 16
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 140. Fort Shield
if (true) then
set itm = Items.create()
set itm.name = "Fort Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Shield"
set itm.texture = 'EQ5E'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = 37
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 141. Secret Ring
if (true) then
set itm = Items.create()
set itm.name = "Secret Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Ring"
set itm.texture = 'EQ9H'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 28
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 142. Copper Necklace
if (true) then
set itm = Items.create()
set itm.name = "Copper Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 2
set itm.class = "Necklace"
set itm.texture = 'EQAH'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 35
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 143. Horus Blade
if (true) then
set itm = Items.create()
set itm.name = "Horus Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 2
set itm.class = "One-handed"
set itm.texture = 'EQ7G'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 40
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 144. Talon Bow
if (true) then
set itm = Items.create()
set itm.name = "Talon Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 2
set itm.class = "Bow"
set itm.texture = 'EQ89'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 44
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 145. Khan Helmet
if (true) then
set itm = Items.create()
set itm.name = "Khan Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Head"
set itm.texture = 'EQ3P'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = 25
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 146. Khan Armor
if (true) then
set itm = Items.create()
set itm.name = "Khan Armor"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 2
set itm.class = "Chest"
set itm.texture = 'EQ1E'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = 30
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 147. Violet Pads
if (true) then
set itm = Items.create()
set itm.name = "Violet Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 2
set itm.class = "Shoulder"
set itm.texture = 'EQ6S'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = 16
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 148. Khan Gloves
if (true) then
set itm = Items.create()
set itm.name = "Khan Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Arm"
set itm.texture = 'EQ2H'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = 18
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 149. Hunting Trousers
if (true) then
set itm = Items.create()
set itm.name = "Hunting Trousers"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Legs"
set itm.texture = 'EQ4G'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = 25
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 150. Adventure Boots
if (true) then
set itm = Items.create()
set itm.name = "Adventure Boots"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Feet"
set itm.texture = 'EQ0G'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = 16
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 151. Defender Shield
if (true) then
set itm = Items.create()
set itm.name = "Defender Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Shield"
set itm.texture = 'EQ51'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = 37
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 152. Impure Ring
if (true) then
set itm = Items.create()
set itm.name = "Impure Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Ring"
set itm.texture = 'EQ9H'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 28
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 153. Topaz Necklace
if (true) then
set itm = Items.create()
set itm.name = "Topaz Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 2
set itm.class = "Necklace"
set itm.texture = 'EQAR'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 35
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 154. Slayer Blade
if (true) then
set itm = Items.create()
set itm.name = "Slayer Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 2
set itm.class = "One-handed"
set itm.texture = 'EQ7J'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 40
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 155. Ashwood Bow
if (true) then
set itm = Items.create()
set itm.name = "Ashwood Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 2
set itm.class = "Bow"
set itm.texture = 'EQ88'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 44
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 156. Skull Helmet
if (true) then
set itm = Items.create()
set itm.name = "Skull Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Head"
set itm.texture = 'EQ3D'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = 25
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 157. Bandit Armor
if (true) then
set itm = Items.create()
set itm.name = "Bandit Armor"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 2
set itm.class = "Chest"
set itm.texture = 'EQ1H'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = 30
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 158. Robber Pads
if (true) then
set itm = Items.create()
set itm.name = "Robber Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 2
set itm.class = "Shoulder"
set itm.texture = 'EQ6N'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = 16
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 159. Druid Gloves
if (true) then
set itm = Items.create()
set itm.name = "Druid Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Arm"
set itm.texture = 'EQ2K'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = 18
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 160. Chain Trousers
if (true) then
set itm = Items.create()
set itm.name = "Chain Trousers"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Legs"
set itm.texture = 'EQ4E'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = 25
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 161. Fine Boots
if (true) then
set itm = Items.create()
set itm.name = "Fine Boots"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Feet"
set itm.texture = 'EQ0D'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = 16
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 162. Protector Shield
if (true) then
set itm = Items.create()
set itm.name = "Protector Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Shield"
set itm.texture = 'EQ53'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = 37
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 163. Guilty Ring
if (true) then
set itm = Items.create()
set itm.name = "Guilty Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 2
set itm.class = "Ring"
set itm.texture = 'EQ9H'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 28
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 164. Jade Necklace
if (true) then
set itm = Items.create()
set itm.name = "Jade Necklace"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 2
set itm.class = "Necklace"
set itm.texture = 'EQAV'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 35
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 165. Knight Blade
if (true) then
set itm = Items.create()
set itm.name = "Knight Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 3
set itm.class = "One-handed"
set itm.texture = 'EQ7C'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 45
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 166. Smoking Bow
if (true) then
set itm = Items.create()
set itm.name = "Smoking Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 3
set itm.class = "Bow"
set itm.texture = 'EQ8J'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 50
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 167. Kong Helmet
if (true) then
set itm = Items.create()
set itm.name = "Kong Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Head"
set itm.texture = 'EQ3N'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = 30
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 168. Combat Vest
if (true) then
set itm = Items.create()
set itm.name = "Combat Vest"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 3
set itm.class = "Chest"
set itm.texture = 'EQ1S'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = 35
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 169. Side Pads
if (true) then
set itm = Items.create()
set itm.name = "Side Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 3
set itm.class = "Shoulder"
set itm.texture = 'EQ6T'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = 20
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 170. War Gloves
if (true) then
set itm = Items.create()
set itm.name = "War Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Arm"
set itm.texture = 'EQ2C'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = 23
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 171. Journeyman Trousers
if (true) then
set itm = Items.create()
set itm.name = "Journeyman Trousers"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Legs"
set itm.texture = 'EQ4D'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = 30
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 172. Journeyman Boots
if (true) then
set itm = Items.create()
set itm.name = "Journeyman Boots"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Feet"
set itm.texture = 'EQ0F'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = 21
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 173. Gladius Shield
if (true) then
set itm = Items.create()
set itm.name = "Gladius Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Shield"
set itm.texture = 'EQ5H'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = 42
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 174. Crystal Ring
if (true) then
set itm = Items.create()
set itm.name = "Crystal Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Ring"
set itm.texture = 'EQ9G'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 33
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 175. Aluring Pendant
if (true) then
set itm = Items.create()
set itm.name = "Aluring Pendant"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 3
set itm.class = "Necklace"
set itm.texture = 'EQAF'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 40
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 20
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 176. Flash Blade
if (true) then
set itm = Items.create()
set itm.name = "Flash Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 3
set itm.class = "One-handed"
set itm.texture = 'EQI8'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 45
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 177. Venom Bow
if (true) then
set itm = Items.create()
set itm.name = "Venom Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 3
set itm.class = "Bow"
set itm.texture = 'EQ8I'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 50
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 178. Knight Helmet
if (true) then
set itm = Items.create()
set itm.name = "Knight Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Head"
set itm.texture = 'EQ3J'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = 30
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 179. Mekka Vest
if (true) then
set itm = Items.create()
set itm.name = "Mekka Vest"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 3
set itm.class = "Chest"
set itm.texture = 'EQ1V'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = 35
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 180. Warlord Pads
if (true) then
set itm = Items.create()
set itm.name = "Warlord Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 3
set itm.class = "Shoulder"
set itm.texture = 'EQ6R'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = 20
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 181. Mentor Gloves
if (true) then
set itm = Items.create()
set itm.name = "Mentor Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Arm"
set itm.texture = 'EQ2E'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = 23
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 182. Bounty Trousers
if (true) then
set itm = Items.create()
set itm.name = "Bounty Trousers"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Legs"
set itm.texture = 'EQ4I'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = 30
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 183. Bounty Boots
if (true) then
set itm = Items.create()
set itm.name = "Bounty Boots"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Feet"
set itm.texture = 'EQ0D'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = 21
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 184. Bastion Shield
if (true) then
set itm = Items.create()
set itm.name = "Bastion Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Shield"
set itm.texture = 'EQ5H'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = 42
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 185. Zapper Ring
if (true) then
set itm = Items.create()
set itm.name = "Zapper Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Ring"
set itm.texture = 'EQ9L'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 33
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 186. Frosted Amulet
if (true) then
set itm = Items.create()
set itm.name = "Frosted Amulet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 3
set itm.class = "Necklace"
set itm.texture = 'EQAG'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 40
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 30
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 187. Swift Blade
if (true) then
set itm = Items.create()
set itm.name = "Swift Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 3
set itm.class = "One-handed"
set itm.texture = 'EQI9'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 45
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 188. Undead Bow
if (true) then
set itm = Items.create()
set itm.name = "Undead Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 3
set itm.class = "Bow"
set itm.texture = 'EQ8C'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 50
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 189. Truth Helmet
if (true) then
set itm = Items.create()
set itm.name = "Truth Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Head"
set itm.texture = 'EQ3M'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = 30
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 190. Knight Armor
if (true) then
set itm = Items.create()
set itm.name = "Knight Armor"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 3
set itm.class = "Chest"
set itm.texture = 'EQ1P'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = 35
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 191. Knight Pads
if (true) then
set itm = Items.create()
set itm.name = "Knight Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 3
set itm.class = "Shoulder"
set itm.texture = 'EQ6F'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = 20
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 192. Spiritual Gloves
if (true) then
set itm = Items.create()
set itm.name = "Spiritual Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Arm"
set itm.texture = 'EQ2F'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = 23
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 193. Medieval Trousers
if (true) then
set itm = Items.create()
set itm.name = "Medieval Trousers"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Legs"
set itm.texture = 'EQ4E'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = 30
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 194. Kobold Boots
if (true) then
set itm = Items.create()
set itm.name = "Kobold Boots"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Feet"
set itm.texture = 'EQ0C'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = 21
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 195. Giant Shield
if (true) then
set itm = Items.create()
set itm.name = "Giant Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Shield"
set itm.texture = 'EQ54'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = 42
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 196. Aqua Ring
if (true) then
set itm = Items.create()
set itm.name = "Aqua Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Ring"
set itm.texture = 'EQ9M'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 33
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 197. Pearl Amulet
if (true) then
set itm = Items.create()
set itm.name = "Pearl Amulet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 3
set itm.class = "Necklace"
set itm.texture = 'EQAM'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 40
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 40
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 198. Apprentice Blade
if (true) then
set itm = Items.create()
set itm.name = "Apprentice Blade"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 3
set itm.class = "One-handed"
set itm.texture = 'EQ7D'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 45
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "2"
set itm.comment = ""
set itm.commentLn = 0
endif
// 199. Zeal Bow
if (true) then
set itm = Items.create()
set itm.name = "Zeal Bow"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 3
set itm.class = "Bow"
set itm.texture = 'EQ8M'
set itm.category = Items.LEFT_HAND
set itm.abil = 0
set itm.gold = 50
set itm.job = 'h00C'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "1"
set itm.comment = ""
set itm.commentLn = 0
endif
// 200. Spiky Helmet
if (true) then
set itm = Items.create()
set itm.name = "Spiky Helmet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Head"
set itm.texture = 'EQ33'
set itm.category = Items.HEAD
set itm.abil = 0
set itm.gold = 30
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 201. Tough Armor
if (true) then
set itm = Items.create()
set itm.name = "Tough Armor"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 4
set itm.rarity = 3
set itm.class = "Chest"
set itm.texture = 'EQ1S'
set itm.category = Items.CHEST
set itm.abil = 0
set itm.gold = 35
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 202. Chief Pads
if (true) then
set itm = Items.create()
set itm.name = "Chief Pads"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 1
set itm.rarity = 3
set itm.class = "Shoulder"
set itm.texture = 'EQ63'
set itm.category = Items.SHOULDER
set itm.abil = 0
set itm.gold = 20
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 203. Armored Gloves
if (true) then
set itm = Items.create()
set itm.name = "Armored Gloves"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Arm"
set itm.texture = 'EQ2C'
set itm.category = Items.ARM
set itm.abil = 0
set itm.gold = 23
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 204. Beast Hide Trousers
if (true) then
set itm = Items.create()
set itm.name = "Beast Hide Trousers"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Legs"
set itm.texture = 'EQ4C'
set itm.category = Items.LEGS
set itm.abil = 0
set itm.gold = 30
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 205. Desert Boots
if (true) then
set itm = Items.create()
set itm.name = "Desert Boots"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Feet"
set itm.texture = 'EQ0H'
set itm.category = Items.FEET
set itm.abil = 0
set itm.gold = 21
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 206. Gladiator Shield
if (true) then
set itm = Items.create()
set itm.name = "Gladiator Shield"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Shield"
set itm.texture = 'EQ52'
set itm.category = Items.RIGHT_HAND
set itm.abil = 0
set itm.gold = 42
set itm.job = 'h004'
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 2
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.upgradeSfx = "3"
set itm.comment = ""
set itm.commentLn = 0
endif
// 207. Tracker Ring
if (true) then
set itm = Items.create()
set itm.name = "Tracker Ring"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 2
set itm.rarity = 3
set itm.class = "Ring"
set itm.texture = 'EQ9F'
set itm.category = Items.RING
set itm.abil = 0
set itm.gold = 33
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
// 208. Tomb Amulet
if (true) then
set itm = Items.create()
set itm.name = "Tomb Amulet"
set itm.avatarPath = "war3mapImported\\Bag_1.mdx"
set itm.avatarScale = 1.0
set itm.drop = true
set itm.randomStats = true
set itm.socketCount = 0
set itm.socketCountMax = 3
set itm.rarity = 3
set itm.class = "Necklace"
set itm.texture = 'EQAD'
set itm.category = Items.NECK
set itm.abil = 0
set itm.gold = 40
set itm.job = 0
set itm.reqStrength = 0
set itm.reqDexterity = 0
set itm.reqWisdom = 0
set itm.reqFortitude = 0
set itm.reqLevel = 10
set itm.reqCount = 1
set itm.modelPt = "" // effect attachment point (left or right hand)
set itm.comment = ""
set itm.commentLn = 0
endif
endif
endfunction
endlibrary
library StatsSetLib
function SetStatsSet takes ItemObject itm, integer dex returns nothing
if itm.id.rarity == 2 then
if itm.id.category == Items.HEAD then
set itm.id.gold = 25
set itm.id.physicDefense = 1.0
set itm.id.magicDefense = 0.85
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.stunResist = 0.04
elseif dex == 1 then
set itm.hpMax = 35
elseif dex == 2 then
set itm.spMax = 5
elseif dex == 3 then
set itm.id.fortitude = 3
elseif dex == 4 then
set itm.id.wisdom = 4
elseif dex == 5 then
set itm.id.strength = 2
set itm.id.dexterity = 1
elseif dex == 6 then
set itm.fireElement = 2
elseif dex == 7 then
set itm.waterElement = 2
elseif dex == 8 then
set itm.earthElement = 2
elseif dex == 9 then
set itm.windElement = 2
elseif dex == 10 then
set itm.accuracy = 0.03
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.stunResist = 0.07
elseif dex == 1 then
set itm.hpMax = 50
elseif dex == 2 then
set itm.spMax = 8
elseif dex == 3 then
set itm.id.fortitude = 3
elseif dex == 4 then
set itm.id.wisdom = 4
elseif dex == 5 then
set itm.id.strength = 2
set itm.id.dexterity = 1
elseif dex == 6 then
set itm.fireElement = 3
elseif dex == 7 then
set itm.waterElement = 3
elseif dex == 8 then
set itm.earthElement = 3
elseif dex == 9 then
set itm.windElement = 3
elseif dex == 10 then
set itm.accuracy = 0.06
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.stunResist = 0.09
elseif dex == 1 then
set itm.hpMax = 80
elseif dex == 2 then
set itm.spMax = 12
elseif dex == 3 then
set itm.id.fortitude = 3
elseif dex == 4 then
set itm.id.wisdom = 4
elseif dex == 5 then
set itm.id.strength = 2
set itm.id.dexterity = 1
elseif dex == 6 then
set itm.fireElement = 4
elseif dex == 7 then
set itm.waterElement = 4
elseif dex == 8 then
set itm.earthElement = 4
elseif dex == 9 then
set itm.windElement = 4
elseif dex == 10 then
set itm.accuracy = 0.08
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.stunResist = 0.11
elseif dex == 1 then
set itm.hpMax = 100
elseif dex == 2 then
set itm.spMax = 15
elseif dex == 3 then
set itm.id.fortitude = 3
elseif dex == 4 then
set itm.id.wisdom = 4
elseif dex == 5 then
set itm.id.strength = 2
set itm.id.dexterity = 1
elseif dex == 6 then
set itm.fireElement = 5
elseif dex == 7 then
set itm.waterElement = 5
elseif dex == 8 then
set itm.earthElement = 5
elseif dex == 9 then
set itm.windElement = 5
elseif dex == 10 then
set itm.accuracy = 0.1
endif
endif
elseif itm.id.category == Items.CHEST then
set itm.id.gold = 30
set itm.id.physicDefense = 1.5
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.id.strength = 3
elseif dex == 1 then
set itm.id.dexterity = 2
elseif dex == 2 then
set itm.id.wisdom = 1
elseif dex == 3 then
set itm.id.fortitude = 4
elseif dex == 4 then
set itm.criticalRate = 0.03
elseif dex == 5 then
set itm.fireElement = 3
elseif dex == 6 then
set itm.waterElement = 3
elseif dex == 7 then
set itm.earthElement = 3
elseif dex == 8 then
set itm.windElement = 3
elseif dex == 9 then
set itm.interruptResist = 0.04
elseif dex == 10 then
set itm.criticalPower = 0.05
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.id.strength = 3
elseif dex == 1 then
set itm.id.dexterity = 2
elseif dex == 2 then
set itm.id.wisdom = 1
elseif dex == 3 then
set itm.id.fortitude = 4
elseif dex == 4 then
set itm.criticalRate = 0.05
elseif dex == 5 then
set itm.fireElement = 4
elseif dex == 6 then
set itm.waterElement = 4
elseif dex == 7 then
set itm.earthElement = 4
elseif dex == 8 then
set itm.windElement = 4
elseif dex == 9 then
set itm.interruptResist = 0.06
elseif dex == 10 then
set itm.criticalPower = 0.07
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.id.strength = 3
elseif dex == 1 then
set itm.id.dexterity = 2
elseif dex == 2 then
set itm.id.wisdom = 1
elseif dex == 3 then
set itm.id.fortitude = 4
elseif dex == 4 then
set itm.criticalRate = 0.07
elseif dex == 5 then
set itm.fireElement = 5
elseif dex == 6 then
set itm.waterElement = 5
elseif dex == 7 then
set itm.earthElement = 5
elseif dex == 8 then
set itm.windElement = 5
elseif dex == 9 then
set itm.interruptResist = 0.08
elseif dex == 10 then
set itm.criticalPower = 0.09
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.id.strength = 3
elseif dex == 1 then
set itm.id.dexterity = 2
elseif dex == 2 then
set itm.id.wisdom = 1
elseif dex == 3 then
set itm.id.fortitude = 4
elseif dex == 4 then
set itm.criticalRate = 0.08
elseif dex == 5 then
set itm.fireElement = 6
elseif dex == 6 then
set itm.waterElement = 6
elseif dex == 7 then
set itm.earthElement = 6
elseif dex == 8 then
set itm.windElement = 6
elseif dex == 9 then
set itm.interruptResist = 0.1
elseif dex == 10 then
set itm.criticalPower = 0.1
endif
endif
elseif itm.id.category == Items.SHOULDER then
set itm.id.gold = 16
set itm.id.magicDefense = 1.2
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.id.strength = 2
set itm.id.dexterity = 1
elseif dex == 1 then
set itm.id.wisdom = 3
elseif dex == 2 then
set itm.knockback = 10.0
elseif dex == 3 then
set itm.accuracy = 0.02
elseif dex == 4 then
set itm.spMax = 10
elseif dex == 5 then
set itm.interrupt = 0.03
elseif dex == 6 then
set itm.criticalPower = 0.03
elseif dex == 7 then
set itm.id.dexterity = 1
set itm.id.fortitude = 2
elseif dex == 8 then
set itm.fireElement = 2.0
set itm.waterElement = 2.0
elseif dex == 9 then
set itm.earthElement = 2.0
set itm.windElement = 2.0
elseif dex == 10 then
set itm.fireElement = 1.0
set itm.waterElement = 1.0
set itm.earthElement = 1.0
set itm.windElement = 1.0
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.id.strength = 2
set itm.id.dexterity = 1
elseif dex == 1 then
set itm.id.wisdom = 3
elseif dex == 2 then
set itm.knockback = 15.0
elseif dex == 3 then
set itm.accuracy = 0.04
elseif dex == 4 then
set itm.spMax = 15
elseif dex == 5 then
set itm.interrupt = 0.05
elseif dex == 6 then
set itm.criticalPower = 0.05
elseif dex == 7 then
set itm.id.dexterity = 1
set itm.id.fortitude = 2
elseif dex == 8 then
set itm.fireElement = 4.0
set itm.waterElement = 4.0
elseif dex == 9 then
set itm.earthElement = 4.0
set itm.windElement = 4.0
elseif dex == 10 then
set itm.fireElement = 2.0
set itm.waterElement = 2.0
set itm.earthElement = 2.0
set itm.windElement = 2.0
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.id.strength = 2
set itm.id.dexterity = 1
elseif dex == 1 then
set itm.id.wisdom = 3
elseif dex == 2 then
set itm.knockback = 19.0
elseif dex == 3 then
set itm.accuracy = 0.06
elseif dex == 4 then
set itm.spMax = 20
elseif dex == 5 then
set itm.interrupt = 0.07
elseif dex == 6 then
set itm.criticalPower = 0.07
elseif dex == 7 then
set itm.id.dexterity = 1
set itm.id.fortitude = 2
elseif dex == 8 then
set itm.fireElement = 5.0
set itm.waterElement = 5.0
elseif dex == 9 then
set itm.earthElement = 5.0
set itm.windElement = 5.0
elseif dex == 10 then
set itm.fireElement = 2.5
set itm.waterElement = 2.5
set itm.earthElement = 2.5
set itm.windElement = 2.5
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.id.strength = 2
set itm.id.dexterity = 1
elseif dex == 1 then
set itm.id.wisdom = 3
elseif dex == 2 then
set itm.knockback = 23.0
elseif dex == 3 then
set itm.accuracy = 0.07
elseif dex == 4 then
set itm.spMax = 25
elseif dex == 5 then
set itm.interrupt = 0.08
elseif dex == 6 then
set itm.criticalPower = 0.09
elseif dex == 7 then
set itm.id.dexterity = 1
set itm.id.fortitude = 2
elseif dex == 8 then
set itm.fireElement = 6.0
set itm.waterElement = 6.0
elseif dex == 9 then
set itm.earthElement = 6.0
set itm.windElement = 6.0
elseif dex == 10 then
set itm.fireElement = 3.0
set itm.waterElement = 3.0
set itm.earthElement = 3.0
set itm.windElement = 3.0
endif
endif
elseif itm.id.category == Items.ARM then
set itm.id.gold = 18
set itm.id.physicDefense = 0.9
set itm.id.magicDefense = 0.8
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.aspd = 0.01
elseif dex == 1 then
set itm.interrupt = 0.03
elseif dex == 2 then
set itm.blockRate = 0.02
elseif dex == 3 then
set itm.id.dexterity = 2
elseif dex == 4 then
set itm.id.strength = 1
elseif dex == 5 then
set itm.id.fortitude = 1
elseif dex == 6 then
set itm.interruptResist = 0.05
elseif dex == 7 then
set itm.fireElement = 2.0
elseif dex == 8 then
set itm.waterElement = 2.0
elseif dex == 9 then
set itm.earthElement = 2.0
elseif dex == 10 then
set itm.windElement = 2.0
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.aspd = 0.02
elseif dex == 1 then
set itm.interrupt = 0.05
elseif dex == 2 then
set itm.blockRate = 0.04
elseif dex == 3 then
set itm.id.dexterity = 2
elseif dex == 4 then
set itm.id.strength = 1
elseif dex == 5 then
set itm.id.fortitude = 1
elseif dex == 6 then
set itm.interruptResist = 0.07
elseif dex == 7 then
set itm.fireElement = 3.0
elseif dex == 8 then
set itm.waterElement = 3.0
elseif dex == 9 then
set itm.earthElement = 3.0
elseif dex == 10 then
set itm.windElement = 3.0
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.aspd = 0.03
elseif dex == 1 then
set itm.interrupt = 0.06
elseif dex == 2 then
set itm.blockRate = 0.06
elseif dex == 3 then
set itm.id.dexterity = 2
elseif dex == 4 then
set itm.id.strength = 1
elseif dex == 5 then
set itm.id.fortitude = 1
elseif dex == 6 then
set itm.interruptResist = 0.09
elseif dex == 7 then
set itm.fireElement = 4.0
elseif dex == 8 then
set itm.waterElement = 4.0
elseif dex == 9 then
set itm.earthElement = 4.0
elseif dex == 10 then
set itm.windElement = 4.0
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.aspd = 0.04
elseif dex == 1 then
set itm.interrupt = 0.07
elseif dex == 2 then
set itm.blockRate = 0.07
elseif dex == 3 then
set itm.id.dexterity = 2
elseif dex == 4 then
set itm.id.strength = 1
elseif dex == 5 then
set itm.id.fortitude = 1
elseif dex == 6 then
set itm.interruptResist = 0.1
elseif dex == 7 then
set itm.fireElement = 4.5
elseif dex == 8 then
set itm.waterElement = 4.5
elseif dex == 9 then
set itm.earthElement = 4.5
elseif dex == 10 then
set itm.windElement = 4.5
endif
endif
elseif itm.id.category == Items.LEGS then
set itm.id.gold = 24
set itm.id.physicDefense = 1.2
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.id.strength = 2
elseif dex == 1 then
set itm.id.dexterity = 2
elseif dex == 2 then
set itm.id.wisdom = 2
elseif dex == 3 then
set itm.id.fortitude = 4
elseif dex == 4 then
set itm.id.strength = 2
set itm.id.fortitude = 2
elseif dex == 5 then
set itm.hpMax = 25.0
set itm.spMax = 10.0
elseif dex == 6 then
set itm.hpRegen = 0.1
elseif dex == 7 then
set itm.spRegen = 0.05
elseif dex == 8 then
set itm.knockbackResist = 15.0
elseif dex == 9 then
set itm.interruptResist = 0.03
elseif dex == 10 then
set itm.stunResist = 0.05
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.id.strength = 2
elseif dex == 1 then
set itm.id.dexterity = 2
elseif dex == 2 then
set itm.id.wisdom = 2
elseif dex == 3 then
set itm.id.fortitude = 4
elseif dex == 4 then
set itm.id.strength = 2
set itm.id.fortitude = 2
elseif dex == 5 then
set itm.hpMax = 45.0
set itm.spMax = 15.0
elseif dex == 6 then
set itm.hpRegen = 0.15
elseif dex == 7 then
set itm.spRegen = 0.08
elseif dex == 8 then
set itm.knockbackResist = 20.0
elseif dex == 9 then
set itm.interruptResist = 0.05
elseif dex == 10 then
set itm.stunResist = 0.08
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.id.strength = 2
elseif dex == 1 then
set itm.id.dexterity = 2
elseif dex == 2 then
set itm.id.wisdom = 2
elseif dex == 3 then
set itm.id.fortitude = 4
elseif dex == 4 then
set itm.id.strength = 2
set itm.id.fortitude = 2
elseif dex == 5 then
set itm.hpMax = 55.0
set itm.spMax = 18.0
elseif dex == 6 then
set itm.hpRegen = 0.2
elseif dex == 7 then
set itm.spRegen = 0.1
elseif dex == 8 then
set itm.knockbackResist = 23.0
elseif dex == 9 then
set itm.interruptResist = 0.07
elseif dex == 10 then
set itm.stunResist = 0.09
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.id.strength = 2
elseif dex == 1 then
set itm.id.dexterity = 2
elseif dex == 2 then
set itm.id.wisdom = 2
elseif dex == 3 then
set itm.id.fortitude = 4
elseif dex == 4 then
set itm.id.strength = 2
set itm.id.fortitude = 2
elseif dex == 5 then
set itm.hpMax = 75.0
set itm.spMax = 23.0
elseif dex == 6 then
set itm.hpRegen = 0.25
elseif dex == 7 then
set itm.spRegen = 0.13
elseif dex == 8 then
set itm.knockbackResist = 25.0
elseif dex == 9 then
set itm.interruptResist = 0.09
elseif dex == 10 then
set itm.stunResist = 0.1
endif
endif
elseif itm.id.category == Items.FEET then
set itm.id.gold = 17
set itm.id.physicDefense = 0.6
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.mspd = 10.0
elseif dex == 1 then
set itm.knockbackResist = 5.0
elseif dex == 2 then
set itm.fireElement = 1.0
elseif dex == 3 then
set itm.waterElement = 1.0
elseif dex == 4 then
set itm.earthElement = 1.0
elseif dex == 5 then
set itm.windElement = 1.0
elseif dex == 6 then
set itm.id.strength = 1
elseif dex == 7 then
set itm.id.dexterity = 3
elseif dex == 8 then
set itm.id.wisdom = 1
elseif dex == 9 then
set itm.id.fortitude = 2
elseif dex == 10 then
set itm.evasionRate = 0.03
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.mspd = 15.0
elseif dex == 1 then
set itm.knockbackResist = 10.0
elseif dex == 2 then
set itm.fireElement = 2.0
elseif dex == 3 then
set itm.waterElement = 2.0
elseif dex == 4 then
set itm.earthElement = 2.0
elseif dex == 5 then
set itm.windElement = 2.0
elseif dex == 6 then
set itm.id.strength = 1
elseif dex == 7 then
set itm.id.dexterity = 3
elseif dex == 8 then
set itm.id.wisdom = 1
elseif dex == 9 then
set itm.id.fortitude = 2
elseif dex == 10 then
set itm.evasionRate = 0.05
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.mspd = 15.0
elseif dex == 1 then
set itm.knockbackResist = 13.0
elseif dex == 2 then
set itm.fireElement = 3.0
elseif dex == 3 then
set itm.waterElement = 3.0
elseif dex == 4 then
set itm.earthElement = 3.0
elseif dex == 5 then
set itm.windElement = 3.0
elseif dex == 6 then
set itm.id.strength = 1
elseif dex == 7 then
set itm.id.dexterity = 3
elseif dex == 8 then
set itm.id.wisdom = 1
elseif dex == 9 then
set itm.id.fortitude = 2
elseif dex == 10 then
set itm.evasionRate = 0.06
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.mspd = 15.0
elseif dex == 1 then
set itm.knockbackResist = 15.0
elseif dex == 2 then
set itm.fireElement = 4.0
elseif dex == 3 then
set itm.waterElement = 4.0
elseif dex == 4 then
set itm.earthElement = 4.0
elseif dex == 5 then
set itm.windElement = 4.0
elseif dex == 6 then
set itm.id.strength = 1
elseif dex == 7 then
set itm.id.dexterity = 3
elseif dex == 8 then
set itm.id.wisdom = 1
elseif dex == 9 then
set itm.id.fortitude = 2
elseif dex == 10 then
set itm.evasionRate = 0.07
endif
endif
elseif itm.id.category == Items.RING then
set itm.id.gold = 28
set itm.id.magicDefense = 2.9
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.id.strength = 4
elseif dex == 1 then
set itm.id.dexterity = 4
elseif dex == 2 then
set itm.id.wisdom = 4
elseif dex == 3 then
set itm.id.fortitude = 4
elseif dex == 4 then
set itm.id.strength = 2
set itm.id.dexterity = 2
elseif dex == 5 then
set itm.id.wisdom = 2
set itm.id.dexterity = 2
elseif dex == 6 then
set itm.id.wisdom = 1
set itm.id.dexterity = 1
set itm.id.wisdom = 1
set itm.id.fortitude = 1
elseif dex == 7 then
set itm.fireElement = 3.0
elseif dex == 8 then
set itm.waterElement = 3.0
elseif dex == 9 then
set itm.earthElement = 3.0
elseif dex == 10 then
set itm.windElement = 3.0
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.id.strength = 4
elseif dex == 1 then
set itm.id.dexterity = 4
elseif dex == 2 then
set itm.id.wisdom = 4
elseif dex == 3 then
set itm.id.fortitude = 4
elseif dex == 4 then
set itm.id.strength = 2
set itm.id.dexterity = 2
elseif dex == 5 then
set itm.id.wisdom = 2
set itm.id.dexterity = 2
elseif dex == 6 then
set itm.id.wisdom = 1
set itm.id.dexterity = 1
set itm.id.wisdom = 1
set itm.id.fortitude = 1
elseif dex == 7 then
set itm.fireElement = 4.0
elseif dex == 8 then
set itm.waterElement = 4.0
elseif dex == 9 then
set itm.earthElement = 4.0
elseif dex == 10 then
set itm.windElement = 4.0
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.id.strength = 4
elseif dex == 1 then
set itm.id.dexterity = 4
elseif dex == 2 then
set itm.id.wisdom = 4
elseif dex == 3 then
set itm.id.fortitude = 4
elseif dex == 4 then
set itm.id.strength = 2
set itm.id.dexterity = 2
elseif dex == 5 then
set itm.id.wisdom = 2
set itm.id.dexterity = 2
elseif dex == 6 then
set itm.id.wisdom = 1
set itm.id.dexterity = 1
set itm.id.wisdom = 1
set itm.id.fortitude = 1
elseif dex == 7 then
set itm.fireElement = 4.5
elseif dex == 8 then
set itm.waterElement = 4.5
elseif dex == 9 then
set itm.earthElement = 4.5
elseif dex == 10 then
set itm.windElement = 4.5
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.id.strength = 4
elseif dex == 1 then
set itm.id.dexterity = 4
elseif dex == 2 then
set itm.id.wisdom = 4
elseif dex == 3 then
set itm.id.fortitude = 4
elseif dex == 4 then
set itm.id.strength = 2
set itm.id.dexterity = 2
elseif dex == 5 then
set itm.id.wisdom = 2
set itm.id.dexterity = 2
elseif dex == 6 then
set itm.id.wisdom = 1
set itm.id.dexterity = 1
set itm.id.wisdom = 1
set itm.id.fortitude = 1
elseif dex == 7 then
set itm.fireElement = 5.0
elseif dex == 8 then
set itm.waterElement = 5.0
elseif dex == 9 then
set itm.earthElement = 5.0
elseif dex == 10 then
set itm.windElement = 5.0
endif
endif
elseif itm.id.category == Items.NECK then
set itm.id.gold = 33
set itm.id.magicDefense = 3.5
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.id.strength = 5
elseif dex == 1 then
set itm.id.dexterity = 5
elseif dex == 2 then
set itm.id.wisdom = 5
elseif dex == 3 then
set itm.id.fortitude = 5
elseif dex == 4 then
set itm.id.strength = 3
set itm.id.dexterity = 2
elseif dex == 5 then
set itm.id.wisdom = 3
set itm.id.dexterity = 2
elseif dex == 6 then
set itm.id.wisdom = 1
set itm.id.dexterity = 1
set itm.id.wisdom = 1
set itm.id.fortitude = 2
elseif dex == 7 then
set itm.fireElement = 4.0
elseif dex == 8 then
set itm.waterElement = 4.0
elseif dex == 9 then
set itm.earthElement = 4.0
elseif dex == 10 then
set itm.windElement = 4.0
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.id.strength = 5
elseif dex == 1 then
set itm.id.dexterity = 5
elseif dex == 2 then
set itm.id.wisdom = 5
elseif dex == 3 then
set itm.id.fortitude = 5
elseif dex == 4 then
set itm.id.strength = 3
set itm.id.dexterity = 2
elseif dex == 5 then
set itm.id.wisdom = 3
set itm.id.dexterity = 2
elseif dex == 6 then
set itm.id.wisdom = 1
set itm.id.dexterity = 1
set itm.id.wisdom = 1
set itm.id.fortitude = 2
elseif dex == 7 then
set itm.fireElement = 5.0
elseif dex == 8 then
set itm.waterElement = 5.0
elseif dex == 9 then
set itm.earthElement = 5.0
elseif dex == 10 then
set itm.windElement = 5.0
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.id.strength = 5
elseif dex == 1 then
set itm.id.dexterity = 5
elseif dex == 2 then
set itm.id.wisdom = 5
elseif dex == 3 then
set itm.id.fortitude = 5
elseif dex == 4 then
set itm.id.strength = 3
set itm.id.dexterity = 2
elseif dex == 5 then
set itm.id.wisdom = 3
set itm.id.dexterity = 2
elseif dex == 6 then
set itm.id.wisdom = 1
set itm.id.dexterity = 1
set itm.id.wisdom = 1
set itm.id.fortitude = 2
elseif dex == 7 then
set itm.fireElement = 5.5
elseif dex == 8 then
set itm.waterElement = 5.5
elseif dex == 9 then
set itm.earthElement = 5.5
elseif dex == 10 then
set itm.windElement = 5.5
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.id.strength = 5
elseif dex == 1 then
set itm.id.dexterity = 5
elseif dex == 2 then
set itm.id.wisdom = 5
elseif dex == 3 then
set itm.id.fortitude = 5
elseif dex == 4 then
set itm.id.strength = 3
set itm.id.dexterity = 2
elseif dex == 5 then
set itm.id.wisdom = 3
set itm.id.dexterity = 2
elseif dex == 6 then
set itm.id.wisdom = 1
set itm.id.dexterity = 1
set itm.id.wisdom = 1
set itm.id.fortitude = 2
elseif dex == 7 then
set itm.fireElement = 6.0
elseif dex == 8 then
set itm.waterElement = 6.0
elseif dex == 9 then
set itm.earthElement = 6.0
elseif dex == 10 then
set itm.windElement = 6.0
endif
endif
elseif itm.id.category == Items.RIGHT_HAND then
set itm.id.gold = 36
set itm.id.physicDefense = 1.9
set itm.blockRate = 0.1
set itm.evasionRate = -1.0
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.blockRate = 0.15
elseif dex == 1 then
set itm.knockbackResist = 10.0
elseif dex == 2 then
set itm.stunResist = 0.05
elseif dex == 3 then
set itm.hpMax = 40.0
elseif dex == 4 then
set itm.id.magicDefense = 0.35
elseif dex == 5 then
set itm.fireElement = 3.0
elseif dex == 6 then
set itm.waterElement = 3.0
elseif dex == 7 then
set itm.earthElement = 3.0
elseif dex == 8 then
set itm.windElement = 3.0
elseif dex == 9 then
set itm.id.strength = 3
set itm.id.dexterity = 2
elseif dex == 10 then
set itm.id.wisdom = 1
set itm.id.fortitude = 4
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.blockRate = 0.15
elseif dex == 1 then
set itm.knockbackResist = 15.0
elseif dex == 2 then
set itm.stunResist = 0.08
elseif dex == 3 then
set itm.hpMax = 60.0
elseif dex == 4 then
set itm.id.magicDefense = 0.35
elseif dex == 5 then
set itm.fireElement = 4.0
elseif dex == 6 then
set itm.waterElement = 4.0
elseif dex == 7 then
set itm.earthElement = 4.0
elseif dex == 8 then
set itm.windElement = 4.0
elseif dex == 9 then
set itm.id.strength = 3
set itm.id.dexterity = 2
elseif dex == 10 then
set itm.id.wisdom = 1
set itm.id.fortitude = 4
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.blockRate = 0.15
elseif dex == 1 then
set itm.knockbackResist = 18.0
elseif dex == 2 then
set itm.stunResist = 0.09
elseif dex == 3 then
set itm.hpMax = 90.0
elseif dex == 4 then
set itm.id.magicDefense = 0.35
elseif dex == 5 then
set itm.fireElement = 5.0
elseif dex == 6 then
set itm.waterElement = 5.0
elseif dex == 7 then
set itm.earthElement = 5.0
elseif dex == 8 then
set itm.windElement = 5.0
elseif dex == 9 then
set itm.id.strength = 3
set itm.id.dexterity = 2
elseif dex == 10 then
set itm.id.wisdom = 1
set itm.id.fortitude = 4
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.blockRate = 0.15
elseif dex == 1 then
set itm.knockbackResist = 20.0
elseif dex == 2 then
set itm.stunResist = 0.1
elseif dex == 3 then
set itm.hpMax = 105.0
elseif dex == 4 then
set itm.id.magicDefense = 0.35
elseif dex == 5 then
set itm.fireElement = 6.0
elseif dex == 6 then
set itm.waterElement = 6.0
elseif dex == 7 then
set itm.earthElement = 6.0
elseif dex == 8 then
set itm.windElement = 6.0
elseif dex == 9 then
set itm.id.strength = 3
set itm.id.dexterity = 2
elseif dex == 10 then
set itm.id.wisdom = 1
set itm.id.fortitude = 4
endif
endif
elseif itm.id.category == Items.LEFT_HAND then
if itm.id.class == "One-handed" then
set itm.id.gold = 42
set itm.id.physicDmgMin = 3.0
set itm.id.physicDmgMax = 6.0
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.interrupt = 0.05
elseif dex == 1 then
set itm.id.strength = 5
elseif dex == 2 then
set itm.id.dexterity = 3
elseif dex == 3 then
set itm.id.fortitude = 2
elseif dex == 4 then
set itm.criticalRate = 0.05
elseif dex == 5 then
set itm.criticalPower = 0.05
elseif dex == 6 then
set itm.accuracy = 0.07
elseif dex == 7 then
set itm.aspd = 0.02
elseif dex == 8 then
set itm.knockback = 20.0
elseif dex == 9 then
set itm.interrupt = 0.04
elseif dex == 10 then
set itm.id.physicDmg = 1.5
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.interrupt = 0.08
elseif dex == 1 then
set itm.id.strength = 5
elseif dex == 2 then
set itm.id.dexterity = 3
elseif dex == 3 then
set itm.id.fortitude = 2
elseif dex == 4 then
set itm.criticalRate = 0.07
elseif dex == 5 then
set itm.criticalPower = 0.08
elseif dex == 6 then
set itm.accuracy = 0.1
elseif dex == 7 then
set itm.aspd = 0.03
elseif dex == 8 then
set itm.knockback = 25.0
elseif dex == 9 then
set itm.interrupt = 0.06
elseif dex == 10 then
set itm.id.physicDmg = 1.5
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.interrupt = 0.09
elseif dex == 1 then
set itm.id.strength = 5
elseif dex == 2 then
set itm.id.dexterity = 3
elseif dex == 3 then
set itm.id.fortitude = 2
elseif dex == 4 then
set itm.criticalRate = 0.09
elseif dex == 5 then
set itm.criticalPower = 0.1
elseif dex == 6 then
set itm.accuracy = 0.13
elseif dex == 7 then
set itm.aspd = 0.04
elseif dex == 8 then
set itm.knockback = 28.0
elseif dex == 9 then
set itm.interrupt = 0.08
elseif dex == 10 then
set itm.id.physicDmg = 1.5
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.interrupt = 0.11
elseif dex == 1 then
set itm.id.strength = 5
elseif dex == 2 then
set itm.id.dexterity = 3
elseif dex == 3 then
set itm.id.fortitude = 2
elseif dex == 4 then
set itm.criticalRate = 0.1
elseif dex == 5 then
set itm.criticalPower = 0.12
elseif dex == 6 then
set itm.accuracy = 0.15
elseif dex == 7 then
set itm.aspd = 0.04
elseif dex == 8 then
set itm.knockback = 28.0
elseif dex == 9 then
set itm.interrupt = 0.1
elseif dex == 10 then
set itm.id.physicDmg = 1.5
endif
endif
elseif itm.id.class == "Bow" then
set itm.id.gold = 45
set itm.id.physicDmgMin = 5.0
set itm.id.physicDmgMax = 9.0
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.attackRange = 64.0
elseif dex == 1 then
set itm.id.strength = 3
elseif dex == 2 then
set itm.id.dexterity = 4
elseif dex == 3 then
set itm.id.fortitude = 2
elseif dex == 4 then
set itm.id.physicDmg = 2.0
elseif dex == 5 then
set itm.criticalRate = 0.05
elseif dex == 6 then
set itm.criticalPower = 0.05
elseif dex == 7 then
set itm.knockback = 10.0
elseif dex == 8 then
set itm.interrupt = 0.03
elseif dex == 9 then
set itm.accuracy = 0.05
elseif dex == 10 then
set itm.evasionRate = 0.03
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.attackRange = 64.0
elseif dex == 1 then
set itm.id.strength = 3
elseif dex == 2 then
set itm.id.dexterity = 4
elseif dex == 3 then
set itm.id.fortitude = 2
elseif dex == 4 then
set itm.id.physicDmg = 2.0
elseif dex == 5 then
set itm.criticalRate = 0.07
elseif dex == 6 then
set itm.criticalPower = 0.08
elseif dex == 7 then
set itm.knockback = 15.0
elseif dex == 8 then
set itm.interrupt = 0.05
elseif dex == 9 then
set itm.accuracy = 0.06
elseif dex == 10 then
set itm.evasionRate = 0.05
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.attackRange = 64.0
elseif dex == 1 then
set itm.id.strength = 3
elseif dex == 2 then
set itm.id.dexterity = 4
elseif dex == 3 then
set itm.id.fortitude = 2
elseif dex == 4 then
set itm.id.physicDmg = 2.0
elseif dex == 5 then
set itm.criticalRate = 0.09
elseif dex == 6 then
set itm.criticalPower = 0.1
elseif dex == 7 then
set itm.knockback = 18.0
elseif dex == 8 then
set itm.interrupt = 0.07
elseif dex == 9 then
set itm.accuracy = 0.07
elseif dex == 10 then
set itm.evasionRate = 0.07
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.attackRange = 64.0
elseif dex == 1 then
set itm.id.strength = 3
elseif dex == 2 then
set itm.id.dexterity = 4
elseif dex == 3 then
set itm.id.fortitude = 2
elseif dex == 4 then
set itm.id.physicDmg = 2.0
elseif dex == 5 then
set itm.criticalRate = 0.1
elseif dex == 6 then
set itm.criticalPower = 0.12
elseif dex == 7 then
set itm.knockback = 20.0
elseif dex == 8 then
set itm.interrupt = 0.09
elseif dex == 9 then
set itm.accuracy = 0.08
elseif dex == 10 then
set itm.evasionRate = 0.08
endif
endif
endif
endif
elseif itm.id.rarity == 3 then
if itm.id.category == Items.HEAD then
set itm.id.gold = 26
set itm.id.physicDefense = 1.5
set itm.id.magicDefense = 1.1
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.interruptResist = 0.03
set itm.id.strength = 2
set itm.id.dexterity = 2
elseif dex == 1 then
set itm.id.fortitude = 2
set itm.id.strength = 1
elseif dex == 2 then
set itm.hpMax = 35
set itm.spMax = 6
elseif dex == 3 then
set itm.waterElement = 2
set itm.earthElement = 2
elseif dex == 4 then
set itm.fireElement = 2
set itm.earthElement = 2
elseif dex == 5 then
set itm.fireElement = 2
set itm.windElement = 2
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.interruptResist = 0.05
set itm.id.strength = 3
set itm.id.dexterity = 3
elseif dex == 1 then
set itm.id.fortitude = 3
set itm.id.strength = 2
set itm.id.dexterity = 1
elseif dex == 2 then
set itm.hpMax = 50
set itm.spMax = 10
elseif dex == 3 then
set itm.waterElement = 3
set itm.earthElement = 3
elseif dex == 4 then
set itm.fireElement = 3
set itm.earthElement = 3
elseif dex == 5 then
set itm.fireElement = 3
set itm.windElement = 3
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.interruptResist = 0.08
set itm.id.strength = 3
set itm.id.dexterity = 3
elseif dex == 1 then
set itm.id.fortitude = 3
set itm.id.strength = 2
set itm.id.dexterity = 1
elseif dex == 2 then
set itm.hpMax = 75
set itm.spMax = 15
elseif dex == 3 then
set itm.waterElement = 4
set itm.earthElement = 4
elseif dex == 4 then
set itm.fireElement = 4
set itm.earthElement = 4
elseif dex == 5 then
set itm.fireElement = 4
set itm.windElement = 4
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.interruptResist = 0.1
set itm.id.strength = 3
set itm.id.dexterity = 3
elseif dex == 1 then
set itm.id.fortitude = 3
set itm.id.strength = 2
set itm.id.dexterity = 1
elseif dex == 2 then
set itm.hpMax = 100
set itm.spMax = 20
elseif dex == 3 then
set itm.waterElement = 5
set itm.earthElement = 5
elseif dex == 4 then
set itm.fireElement = 5
set itm.earthElement = 5
elseif dex == 5 then
set itm.fireElement = 5
set itm.windElement = 5
endif
endif
elseif itm.id.category == Items.CHEST then
set itm.id.gold = 37
set itm.id.physicDefense = 2.0
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.criticalRate = 0.02
set itm.criticalPower = 0.04
elseif dex == 1 then
set itm.criticalRate = 0.04
set itm.id.strength = 3
elseif dex == 2 then
set itm.blockRate = 0.04
set itm.id.fortitude = 2
elseif dex == 3 then
set itm.id.physicDmg = 1.0
set itm.criticalPower = 0.04
elseif dex == 4 then
set itm.id.magicDmg = 0.6
set itm.criticalRate = 0.03
elseif dex == 5 then
set itm.hpMax = 110.0
set itm.id.fortitude = 1
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.criticalRate = 0.03
set itm.criticalPower = 0.05
elseif dex == 1 then
set itm.criticalRate = 0.05
set itm.id.strength = 4
elseif dex == 2 then
set itm.blockRate = 0.05
set itm.id.fortitude = 3
elseif dex == 3 then
set itm.id.physicDmg = 1.5
set itm.criticalPower = 0.05
elseif dex == 4 then
set itm.id.magicDmg = 0.75
set itm.criticalRate = 0.03
elseif dex == 5 then
set itm.hpMax = 140.0
set itm.hpRegen = 1.0
set itm.id.fortitude = 2
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.criticalRate = 0.04
set itm.criticalPower = 0.06
elseif dex == 1 then
set itm.criticalRate = 0.06
set itm.id.strength = 4
elseif dex == 2 then
set itm.blockRate = 0.06
set itm.id.fortitude = 3
elseif dex == 3 then
set itm.id.physicDmg = 1.5
set itm.criticalPower = 0.06
elseif dex == 4 then
set itm.id.magicDmg = 0.75
set itm.criticalRate = 0.05
elseif dex == 5 then
set itm.hpMax = 175.0
set itm.hpRegen = 1.5
set itm.id.fortitude = 2
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.criticalRate = 0.05
set itm.criticalPower = 0.07
elseif dex == 1 then
set itm.criticalRate = 0.07
set itm.id.strength = 4
elseif dex == 2 then
set itm.blockRate = 0.07
set itm.id.fortitude = 3
elseif dex == 3 then
set itm.id.physicDmg = 2.0
set itm.criticalPower = 0.07
elseif dex == 4 then
set itm.id.magicDmg = 0.75
set itm.criticalRate = 0.06
elseif dex == 5 then
set itm.hpMax = 200.0
set itm.hpRegen = 2.0
set itm.id.fortitude = 2
endif
endif
elseif itm.id.category == Items.SHOULDER then
set itm.id.gold = 21
set itm.id.magicDefense = 1.7
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.id.strength = 3
set itm.id.dexterity = 2
elseif dex == 1 then
set itm.id.wisdom = 4
set itm.id.fortitude = 1
elseif dex == 2 then
set itm.knockback = 12.0
set itm.interrupt = 0.04
elseif dex == 3 then
set itm.accuracy = 0.03
set itm.id.dexterity = 3
elseif dex == 4 then
set itm.spMax = 12.0
set itm.spRegen = 0.2
elseif dex == 5 then
set itm.criticalPower = 0.03
set itm.blockRate = 0.02
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.id.strength = 4
set itm.id.dexterity = 2
elseif dex == 1 then
set itm.id.wisdom = 5
set itm.id.fortitude = 1
elseif dex == 2 then
set itm.knockback = 15.0
set itm.interrupt = 0.05
elseif dex == 3 then
set itm.accuracy = 0.04
set itm.id.dexterity = 4
elseif dex == 4 then
set itm.spMax = 15.0
set itm.spRegen = 0.25
elseif dex == 5 then
set itm.criticalPower = 0.05
set itm.blockRate = 0.03
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.id.strength = 4
set itm.id.dexterity = 2
elseif dex == 1 then
set itm.id.wisdom = 5
set itm.id.fortitude = 1
elseif dex == 2 then
set itm.knockback = 32.0
set itm.interrupt = 0.06
elseif dex == 3 then
set itm.accuracy = 0.05
set itm.id.dexterity = 4
elseif dex == 4 then
set itm.spMax = 21.0
set itm.spRegen = 0.5
elseif dex == 5 then
set itm.criticalPower = 0.06
set itm.blockRate = 0.05
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.id.strength = 4
set itm.id.dexterity = 2
elseif dex == 1 then
set itm.id.wisdom = 5
set itm.id.fortitude = 1
elseif dex == 2 then
set itm.knockback = 48.0
set itm.interrupt = 0.08
elseif dex == 3 then
set itm.accuracy = 0.07
set itm.id.dexterity = 4
elseif dex == 4 then
set itm.spMax = 26.0
set itm.spRegen = 0.8
elseif dex == 5 then
set itm.criticalPower = 0.07
set itm.blockRate = 0.06
endif
endif
elseif itm.id.category == Items.ARM then
set itm.id.gold = 23
set itm.id.physicDefense = 1.4
set itm.id.magicDefense = 1.3
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.aspd = 0.01
set itm.id.dexterity = 2
elseif dex == 1 then
set itm.interrupt = 0.04
set itm.accuracy = 0.06
elseif dex == 2 then
set itm.blockRate = 0.03
set itm.id.fortitude = 2
elseif dex == 3 then
set itm.stun = 0.03
set itm.hpRegen = 0.8
set itm.spRegen = 0.2
elseif dex == 4 then
set itm.id.physicDmg = 1.0
set itm.id.strength = 2
elseif dex == 5 then
set itm.id.magicDmg = 0.5
set itm.id.wisdom = 2
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.aspd = 0.02
set itm.id.dexterity = 3
elseif dex == 1 then
set itm.interrupt = 0.05
set itm.accuracy = 0.06
elseif dex == 2 then
set itm.blockRate = 0.04
set itm.id.fortitude = 3
elseif dex == 3 then
set itm.stun = 0.04
set itm.hpRegen = 1.0
set itm.spRegen = 0.4
elseif dex == 4 then
set itm.id.physicDmg = 1.2
set itm.id.strength = 3
elseif dex == 5 then
set itm.id.magicDmg = 0.8
set itm.id.wisdom = 3
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.aspd = 0.025
set itm.id.dexterity = 3
elseif dex == 1 then
set itm.interrupt = 0.06
set itm.accuracy = 0.07
elseif dex == 2 then
set itm.blockRate = 0.08
set itm.id.fortitude = 3
elseif dex == 3 then
set itm.stun = 0.08
set itm.hpRegen = 1.25
set itm.spRegen = 0.5
elseif dex == 4 then
set itm.id.physicDmg = 1.2
set itm.id.strength = 3
elseif dex == 5 then
set itm.id.magicDmg = 0.8
set itm.id.wisdom = 3
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.aspd = 0.03
set itm.id.dexterity = 3
elseif dex == 1 then
set itm.interrupt = 0.07
set itm.accuracy = 0.08
elseif dex == 2 then
set itm.blockRate = 0.09
set itm.id.fortitude = 3
elseif dex == 3 then
set itm.stun = 0.1
set itm.hpRegen = 1.25
set itm.spRegen = 0.5
elseif dex == 4 then
set itm.id.physicDmg = 1.2
set itm.id.strength = 3
elseif dex == 5 then
set itm.id.magicDmg = 0.8
set itm.id.wisdom = 3
endif
endif
elseif itm.id.category == Items.LEGS then
set itm.id.gold = 30
set itm.id.physicDefense = 1.75
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.id.strength = 1
set itm.id.fortitude = 3
elseif dex == 1 then
set itm.id.dexterity = 2
set itm.id.wisdom = 2
elseif dex == 2 then
set itm.id.strength = 2
set itm.id.dexterity = 2
elseif dex == 3 then
set itm.hpMax = 70.0
set itm.spMax = 10.0
elseif dex == 4 then
set itm.hpMax = 70.0
set itm.hpRegen = 0.25
elseif dex == 5 then
set itm.id.physicDefense = 1.2
set itm.id.fortitude = 3
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.id.strength = 2
set itm.id.fortitude = 4
elseif dex == 1 then
set itm.id.dexterity = 3
set itm.id.wisdom = 3
elseif dex == 2 then
set itm.id.strength = 3
set itm.id.dexterity = 3
elseif dex == 3 then
set itm.hpMax = 90.0
set itm.spMax = 15.0
elseif dex == 4 then
set itm.hpMax = 90.0
set itm.hpRegen = 0.5
elseif dex == 5 then
set itm.id.physicDefense = 1.9
set itm.id.fortitude = 4
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.id.strength = 2
set itm.id.fortitude = 4
elseif dex == 1 then
set itm.id.dexterity = 3
set itm.id.wisdom = 3
elseif dex == 2 then
set itm.id.strength = 3
set itm.id.dexterity = 3
elseif dex == 3 then
set itm.hpMax = 125.0
set itm.spMax = 20.0
elseif dex == 4 then
set itm.hpMax = 125.0
set itm.hpRegen = 1.0
elseif dex == 5 then
set itm.id.physicDefense = 1.9
set itm.id.fortitude = 4
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.id.strength = 2
set itm.id.fortitude = 4
elseif dex == 1 then
set itm.id.dexterity = 3
set itm.id.wisdom = 3
elseif dex == 2 then
set itm.id.strength = 3
set itm.id.dexterity = 3
elseif dex == 3 then
set itm.hpMax = 160.0
set itm.spMax = 25.0
elseif dex == 4 then
set itm.hpMax = 160.0
set itm.hpRegen = 1.5
elseif dex == 5 then
set itm.id.physicDefense = 1.9
set itm.id.fortitude = 4
endif
endif
elseif itm.id.category == Items.FEET then
set itm.id.gold = 22
set itm.id.physicDefense = 1.1
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.mspd = 12.0
set itm.knockbackResist = 7.0
elseif dex == 1 then
set itm.evasionRate = 0.03
set itm.id.dexterity = 2
elseif dex == 2 then
set itm.spRegen = 0.2
set itm.knockbackResist = 8.0
elseif dex == 3 then
set itm.evasionRate = 0.03
set itm.knockbackResist = 8.0
elseif dex == 4 then
set itm.id.dexterity = 2
set itm.id.strength = 2
elseif dex == 5 then
set itm.id.dexterity = 3
set itm.id.fortitude = 1
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.mspd = 15.0
set itm.knockbackResist = 10.0
elseif dex == 1 then
set itm.evasionRate = 0.05
set itm.id.dexterity = 3
elseif dex == 2 then
set itm.spRegen = 0.3
set itm.knockbackResist = 10.0
elseif dex == 3 then
set itm.evasionRate = 0.05
set itm.knockbackResist = 10.0
elseif dex == 4 then
set itm.id.dexterity = 3
set itm.id.strength = 3
elseif dex == 5 then
set itm.id.dexterity = 4
set itm.id.fortitude = 2
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.mspd = 15.0
set itm.knockbackResist = 15.0
elseif dex == 1 then
set itm.evasionRate = 0.06
set itm.id.dexterity = 3
elseif dex == 2 then
set itm.spRegen = 0.4
set itm.knockbackResist = 15.0
elseif dex == 3 then
set itm.evasionRate = 0.06
set itm.knockbackResist = 15.0
elseif dex == 4 then
set itm.id.dexterity = 3
set itm.id.strength = 3
elseif dex == 5 then
set itm.id.dexterity = 4
set itm.id.fortitude = 2
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.mspd = 15.0
set itm.knockbackResist = 20.0
elseif dex == 1 then
set itm.evasionRate = 0.07
set itm.id.dexterity = 3
elseif dex == 2 then
set itm.spRegen = 0.5
set itm.knockbackResist = 15.0
elseif dex == 3 then
set itm.evasionRate = 0.07
set itm.knockbackResist = 15.0
elseif dex == 4 then
set itm.id.dexterity = 3
set itm.id.strength = 3
elseif dex == 5 then
set itm.id.dexterity = 4
set itm.id.fortitude = 2
endif
endif
elseif itm.id.category == Items.RING then
set itm.id.gold = 33
set itm.id.magicDefense = 3.5
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.fireElement = 4.0
elseif dex == 1 then
set itm.waterElement = 4.0
elseif dex == 2 then
set itm.earthElement = 4.0
elseif dex == 3 then
set itm.windElement = 4.0
elseif dex == 4 then
set itm.hpMax = 100.0
set itm.hpRegen = 0.5
elseif dex == 5 then
set itm.spMax = 20.0
set itm.spRegen = 0.15
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.fireElement = 6.0
elseif dex == 1 then
set itm.waterElement = 6.0
elseif dex == 2 then
set itm.earthElement = 6.0
elseif dex == 3 then
set itm.windElement = 6.0
elseif dex == 4 then
set itm.hpMax = 135.0
set itm.hpRegen = 0.8
elseif dex == 5 then
set itm.spMax = 25.0
set itm.spRegen = 0.3
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.fireElement = 7.0
elseif dex == 1 then
set itm.waterElement = 7.0
elseif dex == 2 then
set itm.earthElement = 7.0
elseif dex == 3 then
set itm.windElement = 7.0
elseif dex == 4 then
set itm.hpMax = 160.0
set itm.hpRegen = 1.2
elseif dex == 5 then
set itm.spMax = 30.0
set itm.spRegen = 0.4
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.fireElement = 8.0
elseif dex == 1 then
set itm.waterElement = 8.0
elseif dex == 2 then
set itm.earthElement = 8.0
elseif dex == 3 then
set itm.windElement = 8.0
elseif dex == 4 then
set itm.hpMax = 200.0
set itm.hpRegen = 1.5
elseif dex == 5 then
set itm.spMax = 35.0
set itm.spRegen = 0.5
endif
endif
elseif itm.id.category == Items.NECK then
set itm.id.gold = 38
set itm.id.magicDefense = 4.0
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.fireElement = 5.0
elseif dex == 1 then
set itm.waterElement = 5.0
elseif dex == 2 then
set itm.earthElement = 5.0
elseif dex == 3 then
set itm.windElement = 5.0
elseif dex == 4 then
set itm.hpMax = 130.0
set itm.hpRegen = 0.6
elseif dex == 5 then
set itm.spMax = 22.0
set itm.spRegen = 0.25
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.fireElement = 7.0
elseif dex == 1 then
set itm.waterElement = 7.0
elseif dex == 2 then
set itm.earthElement = 7.0
elseif dex == 3 then
set itm.windElement = 7.0
elseif dex == 4 then
set itm.hpMax = 150.0
set itm.hpRegen = 1.0
elseif dex == 5 then
set itm.spMax = 28.0
set itm.spRegen = 0.5
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.fireElement = 8.0
elseif dex == 1 then
set itm.waterElement = 8.0
elseif dex == 2 then
set itm.earthElement = 8.0
elseif dex == 3 then
set itm.windElement = 8.0
elseif dex == 4 then
set itm.hpMax = 190.0
set itm.hpRegen = 1.5
elseif dex == 5 then
set itm.spMax = 30.0
set itm.spRegen = 0.7
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.fireElement = 9.0
elseif dex == 1 then
set itm.waterElement = 9.0
elseif dex == 2 then
set itm.earthElement = 9.0
elseif dex == 3 then
set itm.windElement = 9.0
elseif dex == 4 then
set itm.hpMax = 230.0
set itm.hpRegen = 2.0
elseif dex == 5 then
set itm.spMax = 35.0
set itm.spRegen = 0.9
endif
endif
elseif itm.id.category == Items.RIGHT_HAND then
set itm.id.gold = 42
set itm.id.physicDefense = 2.5
set itm.blockRate = 0.1
set itm.evasionRate = -1.0
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.blockRate = 0.15
set itm.id.fortitude = 3
elseif dex == 1 then
set itm.blockRate = 0.15
set itm.id.strength = 3
elseif dex == 2 then
set itm.id.physicDefense = 2.1
set itm.stunResist = 0.06
elseif dex == 3 then
set itm.id.physicDefense = 2.1
set itm.hpMax = 105.0
elseif dex == 4 then
set itm.id.magicDefense = 1.0
elseif dex == 5 then
set itm.blockRate = 0.15
set itm.knockbackResist = 12.0
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.blockRate = 0.15
set itm.id.fortitude = 5
elseif dex == 1 then
set itm.blockRate = 0.15
set itm.id.strength = 5
elseif dex == 2 then
set itm.id.physicDefense = 2.8
set itm.stunResist = 0.09
elseif dex == 3 then
set itm.id.physicDefense = 2.8
set itm.hpMax = 130.0
elseif dex == 4 then
set itm.id.magicDefense = 1.2
elseif dex == 5 then
set itm.blockRate = 0.15
set itm.knockbackResist = 15.0
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.blockRate = 0.15
set itm.id.fortitude = 5
elseif dex == 1 then
set itm.blockRate = 0.15
set itm.id.strength = 5
elseif dex == 2 then
set itm.id.physicDefense = 2.8
set itm.stunResist = 0.1
elseif dex == 3 then
set itm.id.physicDefense = 2.8
set itm.hpMax = 160.0
elseif dex == 4 then
set itm.id.magicDefense = 1.2
elseif dex == 5 then
set itm.blockRate = 0.15
set itm.knockbackResist = 18.0
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.blockRate = 0.15
set itm.id.fortitude = 5
elseif dex == 1 then
set itm.blockRate = 0.15
set itm.id.strength = 5
elseif dex == 2 then
set itm.id.physicDefense = 2.8
set itm.stunResist = 0.11
elseif dex == 3 then
set itm.id.physicDefense = 2.8
set itm.hpMax = 200.0
elseif dex == 4 then
set itm.id.magicDefense = 1.2
elseif dex == 5 then
set itm.blockRate = 0.15
set itm.knockbackResist = 21.0
endif
endif
elseif itm.id.category == Items.LEFT_HAND then
if itm.id.class == "One-handed" then
set itm.id.gold = 49
set itm.id.physicDmgMin = 5.0
set itm.id.physicDmgMax = 10.0
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.interrupt = 0.06
set itm.id.strength = 5
elseif dex == 1 then
set itm.knockback = 7.0
set itm.id.strength = 5
elseif dex == 2 then
set itm.id.strength = 3
set itm.id.dexterity = 2
elseif dex == 3 then
set itm.criticalRate = 0.03
set itm.criticalPower = 0.05
elseif dex == 4 then
set itm.aspd = 0.03
elseif dex == 5 then
set itm.id.physicDmg = 1.2
set itm.criticalPower = 0.03
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.interrupt = 0.08
set itm.id.strength = 5
elseif dex == 1 then
set itm.knockback = 10.0
set itm.id.strength = 5
elseif dex == 2 then
set itm.id.strength = 5
set itm.id.dexterity = 3
elseif dex == 3 then
set itm.criticalRate = 0.05
set itm.criticalPower = 0.06
elseif dex == 4 then
set itm.aspd = 0.04
elseif dex == 5 then
set itm.id.physicDmg = 1.5
set itm.criticalPower = 0.05
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.interrupt = 0.09
set itm.id.strength = 5
elseif dex == 1 then
set itm.knockback = 13.0
set itm.id.strength = 5
elseif dex == 2 then
set itm.id.strength = 5
set itm.id.dexterity = 3
elseif dex == 3 then
set itm.criticalRate = 0.06
set itm.criticalPower = 0.08
elseif dex == 4 then
set itm.aspd = 0.05
elseif dex == 5 then
set itm.id.physicDmg = 1.5
set itm.criticalPower = 0.06
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.interrupt = 0.1
set itm.id.strength = 5
elseif dex == 1 then
set itm.knockback = 15.0
set itm.id.strength = 5
elseif dex == 2 then
set itm.id.strength = 5
set itm.id.dexterity = 3
elseif dex == 3 then
set itm.criticalRate = 0.07
set itm.criticalPower = 0.1
elseif dex == 4 then
set itm.aspd = 0.06
elseif dex == 5 then
set itm.id.physicDmg = 1.5
set itm.criticalPower = 0.08
endif
endif
elseif itm.id.class == "Bow" then
set itm.id.gold = 53
set itm.id.physicDmgMin = 7.0
set itm.id.physicDmgMax = 13.0
if itm.id.reqLevel == 10 then
if dex == 0 then
set itm.attackRange = 64.0
set itm.mspd = 12.0
elseif dex == 1 then
set itm.id.strength = 2
set itm.id.dexterity = 3
elseif dex == 2 then
set itm.criticalRate = 0.05
set itm.criticalPower = 0.06
elseif dex == 3 then
set itm.evasionRate = 0.03
set itm.id.dexterity = 4
elseif dex == 4 then
set itm.id.physicDmg = 1.5
set itm.criticalRate = 0.04
elseif dex == 5 then
set itm.interrupt = 0.04
set itm.aspd = 0.04
endif
elseif itm.id.reqLevel == 20 then
if dex == 0 then
set itm.attackRange = 64.0
set itm.mspd = 15.0
elseif dex == 1 then
set itm.id.strength = 3
set itm.id.dexterity = 4
elseif dex == 2 then
set itm.criticalRate = 0.07
set itm.criticalPower = 0.08
elseif dex == 3 then
set itm.evasionRate = 0.05
set itm.id.dexterity = 5
elseif dex == 4 then
set itm.id.physicDmg = 2.0
set itm.criticalRate = 0.05
elseif dex == 5 then
set itm.interrupt = 0.05
set itm.aspd = 0.05
endif
elseif itm.id.reqLevel == 30 then
if dex == 0 then
set itm.attackRange = 64.0
set itm.mspd = 18.0
elseif dex == 1 then
set itm.id.strength = 3
set itm.id.dexterity = 4
elseif dex == 2 then
set itm.criticalRate = 0.08
set itm.criticalPower = 0.1
elseif dex == 3 then
set itm.evasionRate = 0.07
set itm.id.dexterity = 5
elseif dex == 4 then
set itm.id.physicDmg = 2.0
set itm.criticalRate = 0.07
elseif dex == 5 then
set itm.interrupt = 0.06
set itm.aspd = 0.06
endif
elseif itm.id.reqLevel == 40 then
if dex == 0 then
set itm.attackRange = 64.0
set itm.mspd = 22.0
elseif dex == 1 then
set itm.id.strength = 3
set itm.id.dexterity = 4
elseif dex == 2 then
set itm.criticalRate = 0.09
set itm.criticalPower = 0.12
elseif dex == 3 then
set itm.evasionRate = 0.08
set itm.id.dexterity = 5
elseif dex == 4 then
set itm.id.physicDmg = 2.0
set itm.criticalRate = 0.08
elseif dex == 5 then
set itm.interrupt = 0.08
set itm.aspd = 0.07
endif
endif
endif
endif
endif
endfunction
endlibrary
library ScrollStats
function GetScrollStats takes ItemObject itm returns nothing
if itm.quality == 0 then
set itm.gold = ScrollPriceTier[3]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 1 then
set itm.gold = ScrollPriceTier[0]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.20
set itm.mspdPctg = 0.15
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 2 then
set itm.gold = ScrollPriceTier[0]
set itm.physicDmgPctg = 0.20
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 3 then
set itm.gold = ScrollPriceTier[0]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.20
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 4 then
set itm.gold = ScrollPriceTier[0]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.30
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 5 then
set itm.gold = ScrollPriceTier[0]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.30
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 6 then
set itm.gold = ScrollPriceTier[0]
set itm.physicDmgPctg = 0.10
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.10
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 7 then
set itm.gold = ScrollPriceTier[0]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.15
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.15
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.1
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 8 then
set itm.gold = ScrollPriceTier[1]
set itm.physicDmgPctg = 0.1
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.1
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 9 then
set itm.gold = ScrollPriceTier[1]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.1
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.1
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 10 then
set itm.gold = ScrollPriceTier[1]
set itm.physicDmgPctg = 0.05
set itm.physicDefPctg = 0.05
set itm.magicDmgPctg = 0.05
set itm.magicDefPctg = 0.05
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 11 then
set itm.gold = ScrollPriceTier[1]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.2
set itm.mspdPctg = 0.15
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 12 then
set itm.gold = ScrollPriceTier[2]
set itm.physicDmgPctg = 0.05
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.05
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 13 then
set itm.gold = ScrollPriceTier[2]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.05
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.05
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 14 then
set itm.gold = ScrollPriceTier[2]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.1
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 15 then
set itm.gold = ScrollPriceTier[2]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.15
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 16 then
set itm.gold = ScrollPriceTier[2]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.1
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 17 then
set itm.gold = ScrollPriceTier[2]
set itm.physicDmgPctg = 0.1
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.1
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 18 then
set itm.gold = ScrollPriceTier[2]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.1
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.1
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 19 then
set itm.gold = ScrollPriceTier[2]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.1
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.1
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 20 then
set itm.gold = ScrollPriceTier[2]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.1
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.1
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 21 then
set itm.gold = ScrollPriceTier[4]
set itm.physicDmgPctg = -0.05
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = -0.05
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 22 then
set itm.gold = ScrollPriceTier[4]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = -0.05
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = -0.05
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 23 then
set itm.gold = ScrollPriceTier[4]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.02
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 24 then
set itm.gold = ScrollPriceTier[4]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.02
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 25 then
set itm.gold = ScrollPriceTier[5]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.0
set itm.goldRate = 0.05
set itm.dropRate = 0.0
set itm.dungeonSize = 2
elseif itm.quality == 26 then
set itm.gold = ScrollPriceTier[5]
set itm.physicDmgPctg = 0.0
set itm.physicDefPctg = 0.0
set itm.magicDmgPctg = 0.0
set itm.magicDefPctg = 0.0
set itm.aspdPctg = 0.0
set itm.mspdPctg = 0.0
set itm.hpPctg = 0.0
set itm.expRate = 0.05
set itm.goldRate = 0.0
set itm.dropRate = 0.0
set itm.dungeonSize = 2
endif
endfunction
endlibrary
library ItemSet
function InitItemSet takes nothing returns nothing
local ItemSet iSet
/*set iSet = ItemSet.create("Embershaft")
call iSet.addItem(28)
call iSet.addItem(29)
call iSet.addItem(30)
call iSet.addItem(31)
call iSet.addItem(32)
call iSet.addItem(33)
call iSet.addItem(34)
call iSet.addItem(999)
set iSet.bonus[1].hpMax = 175.
set iSet.bonus[1].comment = "Max health point +175"
set iSet.bonus[2].strength = 5
set iSet.bonus[2].comment = "Strength +35"
set iSet.bonus[3].fortitude = 10
set iSet.bonus[3].comment = "Fortitude +20"
set iSet.bonus[4].physicDmg = 55.
set iSet.bonus[4].comment = "Physical damage +55"
set iSet.bonus[5].hpMax = 350.
set iSet.bonus[5].comment = "Max health point +350"
set iSet.bonus[6].criticalPower = 0.35
set iSet.bonus[6].aspd = 0.25
set iSet.bonus[6].comment = "Critical power +35%\n7 pieces: Attack rate +0.25"
set iSet.bonus[7].blockRate = 0.15
set iSet.bonus[7].comment = "Block chance +15%"
set iSet.tCount = iSet.tCount + 1
set iSet = ItemSet.create("Nobility")
call iSet.addItem(35)
call iSet.addItem(36)
call iSet.addItem(59)
set iSet.bonus[1].hpMax = 45.
set iSet.bonus[1].comment = "Max health point +45"
set iSet.bonus[2].wisdom = 5
set iSet.bonus[2].comment = "Wisdom +3"*/
endfunction
struct ItemSetBonus
string comment
integer strength
integer dexterity
integer wisdom
integer fortitude
real physicDmg
real physicDefense
real magicDmg
real magicDefense
real attackRange
real blockRate
real criticalRate
real criticalPower
real evasionRate
real accuracy
real knockback
real knockbackResist
real interrupt
real interruptResist
real stun
real stunResist
real hp
real hpMax
real sp
real spMax
real hpRegen
real spRegen
real aspd
real mspd
real duration
real fireElement
real fireElementResist
real waterElement
real waterElementResist
real earthElement
real earthElementResist
real windElement
real windElementResist
real holyElement
real darkElement
endstruct
struct ItemSet
Items array items[10]
ItemSetBonus array bonus[10]
integer count
integer tCount
string name
static TableArray ActiveIndex
static thistype array ItemIndex
method has takes Items itm returns boolean
local integer i = 0
loop
exitwhen i == count
if items[i] == itm then
return true
endif
set i = i + 1
endloop
return false
endmethod
method addItem takes Items itm returns nothing
if ItemIndex[itm] == 0 then
set ItemIndex[itm] = this
set items[count] = itm
set bonus[count] = ItemSetBonus.create()
set count = count + 1
set tCount = tCount + 1
endif
endmethod
static method create takes string nm returns thistype
local thistype this = allocate()
local integer i = 0
set name = nm
set count = 0
set tCount = 0
return this
endmethod
private static method onInit takes nothing returns nothing
set ActiveIndex = TableArray[4]
endmethod
endstruct
endlibrary
library Items /*initializer init*/ uses TimerUtils, ItemSet, IPool, ScrollStats, StatsSetLib
globals
private integer TempInt = 1
private IPool array BonusDex
endglobals
private function init takes nothing returns nothing
set BonusDex[Items.HEAD] = IPool.create()
call BonusDex[Items.HEAD].add(ItemObject.BONUS_strength, 1)
call BonusDex[Items.HEAD].add(ItemObject.BONUS_dexterity, 1)
call BonusDex[Items.HEAD].add(ItemObject.BONUS_wisdom, 1)
call BonusDex[Items.HEAD].add(ItemObject.BONUS_fortitude, 1)
call BonusDex[Items.HEAD].add(ItemObject.BONUS_physicDmg, 1)
call BonusDex[Items.HEAD].add(ItemObject.BONUS_physicDefense, 1)
call BonusDex[Items.HEAD].add(ItemObject.BONUS_magicDmg, 1)
call BonusDex[Items.HEAD].add(ItemObject.BONUS_magicDefense, 2)
call BonusDex[Items.HEAD].add(ItemObject.BONUS_accuracy, 2)
call BonusDex[Items.HEAD].add(ItemObject.BONUS_stunResist, 2)
call BonusDex[Items.HEAD].add(ItemObject.BONUS_hpMax, 1)
call BonusDex[Items.HEAD].add(ItemObject.BONUS_hpRegen, 1)
set BonusDex[Items.CHEST] = IPool.create()
call BonusDex[Items.CHEST].add(ItemObject.BONUS_strength, 1)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_dexterity, 1)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_wisdom, 1)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_fortitude, 1)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_physicDmg, 1)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_physicDefense, 2)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_magicDmg, 1)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_magicDefense, 2)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_knockbackResist, 1)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_interruptResist, 1)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_stunResist, 1)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_hpMax, 2)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_spMax, 1)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_hpRegen, 1)
call BonusDex[Items.CHEST].add(ItemObject.BONUS_spRegen, 1)
set BonusDex[Items.LEGS] = IPool.create()
call BonusDex[Items.LEGS].add(ItemObject.BONUS_strength, 1)
call BonusDex[Items.LEGS].add(ItemObject.BONUS_dexterity, 1)
call BonusDex[Items.LEGS].add(ItemObject.BONUS_wisdom, 1)
call BonusDex[Items.LEGS].add(ItemObject.BONUS_fortitude, 1)
call BonusDex[Items.LEGS].add(ItemObject.BONUS_physicDmg, 1)
call BonusDex[Items.LEGS].add(ItemObject.BONUS_physicDefense, 2)
call BonusDex[Items.LEGS].add(ItemObject.BONUS_magicDmg, 1)
call BonusDex[Items.LEGS].add(ItemObject.BONUS_magicDefense, 1)
call BonusDex[Items.LEGS].add(ItemObject.BONUS_evasionRate, 2)
call BonusDex[Items.LEGS].add(ItemObject.BONUS_knockbackResist, 1)
call BonusDex[Items.LEGS].add(ItemObject.BONUS_spMax, 2)
call BonusDex[Items.LEGS].add(ItemObject.BONUS_spRegen, 1)
set BonusDex[Items.FEET] = IPool.create()
call BonusDex[Items.FEET].add(ItemObject.BONUS_strength, 1)
call BonusDex[Items.FEET].add(ItemObject.BONUS_dexterity, 1)
call BonusDex[Items.FEET].add(ItemObject.BONUS_wisdom, 1)
call BonusDex[Items.FEET].add(ItemObject.BONUS_fortitude, 1)
call BonusDex[Items.FEET].add(ItemObject.BONUS_physicDefense, 1)
call BonusDex[Items.FEET].add(ItemObject.BONUS_magicDefense, 1)
call BonusDex[Items.FEET].add(ItemObject.BONUS_evasionRate, 2)
call BonusDex[Items.FEET].add(ItemObject.BONUS_knockbackResist, 2)
call BonusDex[Items.FEET].add(ItemObject.BONUS_spMax, 1)
call BonusDex[Items.FEET].add(ItemObject.BONUS_spRegen, 1)
call BonusDex[Items.FEET].add(ItemObject.BONUS_mspd, 2)
set BonusDex[Items.RIGHT_HAND] = IPool.create()
call BonusDex[Items.RIGHT_HAND].add(ItemObject.BONUS_strength, 1)
call BonusDex[Items.RIGHT_HAND].add(ItemObject.BONUS_dexterity, 1)
call BonusDex[Items.RIGHT_HAND].add(ItemObject.BONUS_wisdom, 1)
call BonusDex[Items.RIGHT_HAND].add(ItemObject.BONUS_fortitude, 2)
call BonusDex[Items.RIGHT_HAND].add(ItemObject.BONUS_physicDefense, 2)
call BonusDex[Items.RIGHT_HAND].add(ItemObject.BONUS_magicDefense, 1)
call BonusDex[Items.RIGHT_HAND].add(ItemObject.BONUS_blockRate, 2)
call BonusDex[Items.RIGHT_HAND].add(ItemObject.BONUS_knockbackResist, 1)
call BonusDex[Items.RIGHT_HAND].add(ItemObject.BONUS_interruptResist, 1)
call BonusDex[Items.RIGHT_HAND].add(ItemObject.BONUS_stunResist, 1)
call BonusDex[Items.RIGHT_HAND].add(ItemObject.BONUS_hpMax, 1)
set BonusDex[Items.NECK] = IPool.create()
call BonusDex[Items.NECK].add(ItemObject.BONUS_strength, 1)
call BonusDex[Items.NECK].add(ItemObject.BONUS_dexterity, 1)
call BonusDex[Items.NECK].add(ItemObject.BONUS_wisdom, 1)
call BonusDex[Items.NECK].add(ItemObject.BONUS_fortitude, 1)
call BonusDex[Items.NECK].add(ItemObject.BONUS_physicDmg, 1)
call BonusDex[Items.NECK].add(ItemObject.BONUS_magicDmg, 1)
call BonusDex[Items.NECK].add(ItemObject.BONUS_magicDmg, 1)
/*
set BonusDexSHOULDER = IPool.create()
set BonusDexARM = IPool.create()
set BonusDexRING = IPool.create()
set BonusDexLEFT_HAND = IPool.create()*/
endfunction
private function Exponent takes real a, real b returns real
return Pow(a, b)
endfunction
public function AdjustItemObjectRarity takes ItemObject itm, integer rarity returns nothing
local integer add
local integer toAdd
if (itm.id.category <= Items.LEFT_HAND and itm.rarity < 7) then
set add = rarity - itm.rarity
if (itm.rarity + add > 7) then
set add = 7 - itm.rarity
endif
loop
exitwhen add <= 0
//set toAdd = GetRandomInt()
//if (itm.id) then
//endif
set add = add - 1
endloop
endif
endfunction
private function AdjustItemGold2 takes ItemObject itm, integer level returns nothing
local real b1 /*Value at value min level 1*/ = 0.
local real b2 /*Value at value min level 100*/ = 0.
local real t1 /*Value at value max level 1*/ = 123.
local real t2 /*Value at value max level 100*/ = 21987.
local real f = CalculateStatusBaseFactor(I2R(itm.gold) - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
set itm.gold = R2I((I2R(itm.gold) + CalculateStatusValue(t, level))*(1. + QualityBonus[itm.quality]))
endfunction
private function AdjustItemGold takes ItemObject itm, integer level returns nothing
local real b1 /*Value at value min level 1*/ = 0.
local real b2 /*Value at value min level 100*/ = 0.
local real t1 /*Value at value max level 1*/ = 123.
local real t2 /*Value at value max level 100*/ = 21987.
local real f = CalculateStatusBaseFactor(I2R(itm.id.gold) - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
set itm.gold = R2I((I2R(itm.id.gold) + CalculateStatusValue(t, level))*(1. + QualityBonus[itm.quality]))
endfunction
private function AdjustItemStrength takes ItemObject itm, integer level returns nothing
local real b1 /*Value at value min level 1*/ = 1.
local real b2 /*Value at value min level 100*/ = 5.
local real t1 /*Value at value max level 1*/ = 15.
local real t2 /*Value at value max level 100*/ = 33.
local real f = CalculateStatusBaseFactor(I2R(itm.id.strength) - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
set itm.strength = R2I((I2R(itm.id.strength) + CalculateStatusValue(t, level))*(1. + QualityBonus[itm.quality]))
endfunction
private function AdjustItemDexterity takes ItemObject itm, integer level returns nothing
local real b1 /*Value at value min level 1*/ = 1.
local real b2 /*Value at value min level 100*/ = 5.
local real t1 /*Value at value max level 1*/ = 15.
local real t2 /*Value at value max level 100*/ = 33.
local real f = CalculateStatusBaseFactor(I2R(itm.id.dexterity) - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
set itm.dexterity = R2I((I2R(itm.id.dexterity) + CalculateStatusValue(t, level))*(1. + QualityBonus[itm.quality]))
endfunction
private function AdjustItemWisdom takes ItemObject itm, integer level returns nothing
local real b1 /*Value at value min level 1*/ = 1.
local real b2 /*Value at value min level 100*/ = 5.
local real t1 /*Value at value max level 1*/ = 15.
local real t2 /*Value at value max level 100*/ = 33.
local real f = CalculateStatusBaseFactor(I2R(itm.id.wisdom) - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
set itm.wisdom = R2I((I2R(itm.id.wisdom) + CalculateStatusValue(t, level))*(1. + QualityBonus[itm.quality]))
endfunction
private function AdjustItemFortitude takes ItemObject itm, integer level returns nothing
local real b1 /*Value at value min level 1*/ = 1.
local real b2 /*Value at value min level 100*/ = 5.
local real t1 /*Value at value max level 1*/ = 15.
local real t2 /*Value at value max level 100*/ = 33.
local real f = CalculateStatusBaseFactor(I2R(itm.id.fortitude) - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
set itm.fortitude = R2I((I2R(itm.id.fortitude) + CalculateStatusValue(t, level))*(1. + QualityBonus[itm.quality]))
endfunction
private function AdjustItemPhysicDamage takes ItemObject itm, integer level returns nothing
local real b1 /*Value at value min level 1*/ = 1.
local real b2 /*Value at value min level 100*/ = 5.
local real t1 /*Value at value max level 1*/ = 10.
local real t2 /*Value at value max level 100*/ = 30.
local real f = CalculateStatusBaseFactor(itm.id.physicDmg - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
set itm.physicDmg = (itm.id.physicDmg + CalculateStatusValue(t, level))*(1. + QualityBonus[itm.quality])
endfunction
private function AdjustItemPhysicDamageRange takes ItemObject itm, integer level returns nothing
local real b1 /*Value at value min level 1*/ = 1.
local real b2 /*Value at value min level 100*/ = 600.
local real t1 /*Value at value max level 1*/ = 40.
local real t2 /*Value at value max level 100*/ = 1500.
local real f = CalculateStatusBaseFactor(itm.id.physicDmgMin - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
local real range = itm.id.physicDmgMax - itm.id.physicDmgMin
set itm.physicDmgMin = (itm.id.physicDmgMin + CalculateStatusValue(t, level))*(1. + QualityBonus[itm.quality])
// Calculate dice
set b1 /*Value at value min level 1*/ = 0
set b2 /*Value at value min level 100*/ = 100
set t1 /*Value at value max level 1*/ = 15
set t2 /*Value at value max level 100*/ = 300
set b = (range - b1) / (t1 - b1) * (t2 - b2) * (level / MAXIMUM_LEVEL)
set itm.physicDmgMax = itm.physicDmgMin + (range + b)
endfunction
private function AdjustItemPhysicDefense takes ItemObject itm, integer level returns nothing
local real b1 /*Value at value min level 1*/ = 1.
local real b2 /*Value at value min level 100*/ = 80.
local real t1 /*Value at value max level 1*/ = 15.
local real t2 /*Value at value max level 100*/ = 800.
local real f = CalculateStatusBaseFactor(itm.id.physicDefense - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
set itm.physicDefense = (itm.id.physicDefense + CalculateStatusValue(t, level))*(1. + QualityBonus[itm.quality])
endfunction
private function AdjustItemMagicDamage takes ItemObject itm, integer level returns nothing
local real b1 /*Value at value min level 1*/ = 1.
local real b2 /*Value at value min level 100*/ = 2.5
local real t1 /*Value at value max level 1*/ = 5.
local real t2 /*Value at value max level 100*/ = 15.
local real f = CalculateStatusBaseFactor(itm.id.magicDmg - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
set itm.magicDmg = (itm.id.magicDmg + CalculateStatusValue(t, level))*(1. + QualityBonus[itm.quality])
endfunction
private function AdjustItemMagicDamageRange takes ItemObject itm, integer level returns nothing
local real b1 /*Value at value min level 1*/ = 1.
local real b2 /*Value at value min level 100*/ = 300.
local real t1 /*Value at value max level 1*/ = 20.
local real t2 /*Value at value max level 100*/ = 750.
local real f = CalculateStatusBaseFactor(itm.id.physicDmgMin - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
local real range = itm.id.magicDmgMax - itm.id.magicDmgMin
set itm.magicDmgMin = (itm.id.magicDmgMin + CalculateStatusValue(t, level))*(1. + QualityBonus[itm.quality])
// Calculate dice
set b1 /*Value at value min level 1*/ = 0
set b2 /*Value at value min level 100*/ = 100
set t1 /*Value at value max level 1*/ = 15
set t2 /*Value at value max level 100*/ = 300
set b = (range - b1) / (t1 - b1) * (t2 - b2) * (level / MAXIMUM_LEVEL)
set itm.magicDmgMax = itm.magicDmgMin + (range + b)
endfunction
private function AdjustItemMagicDefense takes ItemObject itm, integer level returns nothing
local real b1 /*Value at value min level 1*/ = 1.
local real b2 /*Value at value min level 100*/ = 40.
local real t1 /*Value at value max level 1*/ = 7.5
local real t2 /*Value at value max level 100*/ = 400.
local real f = CalculateStatusBaseFactor(itm.id.magicDefense - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
set itm.magicDefense = (itm.id.magicDefense + CalculateStatusValue(t, level))*(1. + QualityBonus[itm.quality])
endfunction
public function AdjustItemObjectLevel takes ItemObject itm, integer level returns nothing
set itm.reqLevel = level
if itm.id.category == Items.SCROLL then
call GetScrollStats(itm)
if itm.gold > 0 then
call AdjustItemGold2(itm, level)
endif
else
if itm.id.noAdjust then
set itm.gold = itm.id.gold
set itm.strength = itm.id.strength
set itm.dexterity = itm.id.dexterity
set itm.wisdom = itm.id.wisdom
set itm.fortitude = itm.id.fortitude
set itm.physicDmg = itm.id.physicDmg
set itm.physicDmgMin = itm.id.physicDmgMin
set itm.physicDmgMax = itm.id.physicDmgMax
set itm.physicDefense = itm.id.physicDefense
set itm.magicDmg = itm.id.magicDmg
set itm.magicDmgMin = itm.id.magicDmgMin
set itm.magicDmgMax = itm.id.magicDmgMax
set itm.magicDefense = itm.id.magicDefense
else
if itm.id.gold > 0 then
call AdjustItemGold(itm, level)
endif
if itm.id.strength > 0 then
call AdjustItemStrength(itm, level)
endif
if itm.id.dexterity > 0 then
call AdjustItemDexterity(itm, level)
endif
if itm.id.wisdom > 0 then
call AdjustItemWisdom(itm, level)
endif
if itm.id.fortitude > 0 then
call AdjustItemFortitude(itm, level)
endif
if itm.id.physicDmg > 0 then
call AdjustItemPhysicDamage(itm, level)
endif
if itm.id.physicDmgMax > 0 then
call AdjustItemPhysicDamageRange(itm, level)
endif
if itm.id.physicDefense > 0 then
call AdjustItemPhysicDefense(itm, level)
endif
if itm.id.magicDmg > 0 then
call AdjustItemMagicDamage(itm, level)
endif
if itm.id.magicDmgMax > 0 then
call AdjustItemMagicDamageRange(itm, level)
endif
if itm.id.magicDefense > 0 then
call AdjustItemMagicDefense(itm, level)
endif
/*
set itm.hpMax = 875.
set itm.spMax = 0
set itm.hpRegen = 0.
set itm.spRegen = 0.*/
endif
endif
endfunction
struct ItemUpgrade extends array
Items ore
real bonus
integer value
implement Stack
endstruct
struct ItemSocket extends array
ItemObject gem
string comment
implement Queue
endstruct
struct ItemEnhancement extends array
integer stats
real value
implement Queue
endstruct
struct ItemObject
integer rarity
integer levelReq
integer goldGiven
integer gold // sell value
integer lumber // sell value
integer strength
integer dexterity
integer wisdom
integer fortitude
real cooldown
real physicDmg
real physicDmgMin
real physicDmgMax
real physicDefense
real magicDmg
real magicDmgMin
real magicDmgMax
real magicDefense
real physicReflect
real magicReflect
real dmgReflect
real attackRange
real blockRate
real criticalRate
real criticalPower
real evasionRate
real accuracy
real knockback
real knockbackResist
real interrupt
real interruptResist
real stun
real stunResist
real hp
real hpMax
real hpSteal
real sp
real spMax
real spSteal
real hpRegen
real spRegen
real aspd
real mspd
real duration
real fireElement
real fireElementResist
real waterElement
real waterElementResist
real earthElement
real earthElementResist
real windElement
real windElementResist
real holyElement
real darkElement
effect avatar
effect attachment
string model
string modelPt
Items id
unit object
integer cg
timer cdTimer
integer quality
integer socketCount
integer socketCountMax
integer statsSet
real physicDmgPctg
real physicDefPctg
real magicDmgPctg
real magicDefPctg
real aspdPctg
real mspdPctg
real hpPctg
real expRate
real goldRate
real dropRate
integer dungeonSize
CustomText nameTag
boolean visible
boolean click
ItemSocket socketData
ItemUpgrade upgradeData
// Upgrade data
integer upgradeLevel
integer blackCount
integer blueCount
integer redCount
integer yellowCount
private real locX
private real locY
static boolean AdjustGoldPrice = true
static boolean NoRandom = false
//
static constant integer BONUS_gold = 0
static constant integer BONUS_lumber = 1
static constant integer BONUS_strength = 2
static constant integer BONUS_dexterity = 3
static constant integer BONUS_wisdom = 4
static constant integer BONUS_fortitude = 5
static constant integer BONUS_cooldown = 6
static constant integer BONUS_physicDmg = 7
static constant integer BONUS_physicDmgMin = 8
static constant integer BONUS_physicDmgMax = 9
static constant integer BONUS_physicDefense = 10
static constant integer BONUS_magicDmg = 11
static constant integer BONUS_magicDmgMin = 12
static constant integer BONUS_magicDmgMax = 13
static constant integer BONUS_magicDefense = 14
static constant integer BONUS_attackRange = 15
static constant integer BONUS_blockRate = 16
static constant integer BONUS_criticalRate = 17
static constant integer BONUS_criticalPower = 18
static constant integer BONUS_evasionRate = 19
static constant integer BONUS_accuracy = 20
static constant integer BONUS_knockback = 21
static constant integer BONUS_knockbackResist = 22
static constant integer BONUS_interrupt = 23
static constant integer BONUS_interruptResist = 24
static constant integer BONUS_stun = 25
static constant integer BONUS_stunResist = 26
static constant integer BONUS_hp = 27
static constant integer BONUS_hpMax = 28
static constant integer BONUS_sp = 29
static constant integer BONUS_spMax = 30
static constant integer BONUS_hpRegen = 31
static constant integer BONUS_spRegen = 32
static constant integer BONUS_aspd = 33
static constant integer BONUS_mspd = 34
static constant integer BONUS_physicDmgPctg = 35
static constant integer BONUS_physicDefPctg = 36
static constant integer BONUS_magicDmgPctg = 37
static constant integer BONUS_magicDefPctg = 38
static constant integer BONUS_aspdPctg = 39
static constant integer BONUS_mspdPctg = 40
static constant integer BONUS_hpPctg = 41
static constant integer BONUS_expRate = 42
static constant integer BONUS_goldRate = 43
static group AllItem = CreateGroup()
static Table ItemIndex
static method operator [] takes unit u returns thistype
return ItemIndex.integer[GetHandleId(u)]
endmethod
method operator idToInt takes nothing returns integer
return id
endmethod
method operator charge takes nothing returns integer
return cg
endmethod
method operator charge= takes integer amount returns nothing
set cg = amount
endmethod
method operator reqLevel takes nothing returns integer
return levelReq
endmethod
method operator reqLevel= takes integer level returns nothing
set levelReq = level
call refreshName()
endmethod
method operator selectable= takes boolean b returns nothing
set click = b
call nameTag.show(b and visible)
if b then
call SetUnitScale(.object, 0.75, 0.75, 0.75)
else
call SetUnitScale(.object, 0., 0., 0.)
endif
endmethod
method destroy takes nothing returns nothing
local integer i
local ItemSocket iSocket
local ItemUpgrade iUpgrade
if this > 0 then
set ItemIndex.integer[GetHandleId(object)] = 0
call ReleaseTimer(cdTimer)
call GroupRemoveUnit(AllItem, object)
static if not USE_MEMORY_HACK then
if avatar != null then
call BlzSetSpecialEffectPosition(avatar, 0, 0, 10000)
endif
endif
if nameTag > 0 then
call nameTag.destroy()
endif
if socketCountMax > 0 then
set iSocket = socketData.first
loop
exitwhen iSocket == 0
if iSocket.gem != 0 then
call iSocket.gem.destroy()
set iSocket.gem = 0
endif
call iSocket.pop()
set iSocket = iSocket.next
endloop
endif
if .upgradeLevel > 0 then
set iUpgrade = upgradeData.first
loop
exitwhen iUpgrade == 0
if iUpgrade.ore != 0 then
call iUpgrade.ore.destroy()
set iUpgrade.ore = 0
endif
call iUpgrade.pop()
set iUpgrade = iUpgrade.next
endloop
endif
if socketData > 0 then
call socketData.destroy()
endif
if upgradeData > 0 then
call upgradeData.destroy()
endif
call DestroyEffect(avatar)
call RemoveUnit(object)
call deallocate()
set avatar = null
set cdTimer = null
set object = null
set i = 0
loop
exitwhen i > 3
if Tooltips1[i].control.visible and Tooltips1[i].itmObject == this then
call Tooltips1[i].show(false)
set Tooltips1[i].itmObject = -1
set Tooltips1[i].skill = -1
call Tooltips2[i].show(false)
set Tooltips2[i].itmObject = -1
set Tooltips2[i].skill = -1
endif
set i = i + 1
endloop
endif
endmethod
method show takes boolean b returns nothing
set visible = b
call ShowUnit(object, b)
call nameTag.show(b and click)
if b then
call SetUnitPosition(object, .locX, .locY)
else
call SetUnitPosition(object, WorldBounds.maxX, WorldBounds.maxY)
endif
static if not USE_MEMORY_HACK then
if b then
set .avatar = AddSpecialEffect(.id.avatarPath, GetUnitX(.object), GetUnitY(.object))
call BlzSetSpecialEffectScale(.avatar, .id.avatarScale)
call BlzPlaySpecialEffect(.avatar, ANIM_TYPE_STAND)
else
call BlzSetSpecialEffectPosition(.avatar, 0, 0, 10000)
call DestroyEffect(.avatar)
endif
endif
endmethod
method move takes real x, real y returns nothing
set .locX = x
set .locY = y
call SetUnitPosition(object, x, y)
call nameTag.move(x, y, 100)
static if not USE_MEMORY_HACK then
call BlzSetSpecialEffectPosition(avatar, x, y, PanelCore_GetTerrainZ(x, y))
endif
endmethod
method refreshName takes nothing returns nothing
static if not USE_MEMORY_HACK then
if id.category < Items.CONSUMABLE then
if id.rarity > 0 then
if .upgradeLevel > 0 then
call BlzSetUnitName(object, RarityColor[id.rarity] + id.name + " +" + I2S(.upgradeLevel) + "|n|cffffcc00" + "(Level " + I2S(IMaxBJ(reqLevel, 1)) + ")|n|nQuality|cffcccccc: " + QualityNames[quality] + "|n|cffffcc00Sockets|cffcccccc: " + I2S(socketCount) + "(" + I2S(socketCountMax) + ")|r")
else
call BlzSetUnitName(object, RarityColor[id.rarity] + id.name + "|n|cffffcc00" + "(Level " + I2S(IMaxBJ(reqLevel, 1)) + ")|n|nQuality|cffcccccc: " + QualityNames[quality] + "|n|cffffcc00Sockets|cffcccccc: " + I2S(socketCount) + "(" + I2S(socketCountMax) + ")|r")
endif
else
if .upgradeLevel > 0 then
call BlzSetUnitName(object, "|cffcccccc" + id.name + " +" + I2S(.upgradeLevel) + "|n|cffffcc00" + "(Level " + I2S(IMaxBJ(reqLevel, 1)) + ")|n|nQuality|cffcccccc: " + QualityNames[quality] + "|n|cffffcc00Sockets|cffcccccc: " + I2S(socketCount) + "(" + I2S(socketCountMax) + ")|r")
else
call BlzSetUnitName(object, "|cffcccccc" + id.name + "|n|cffffcc00" + "(Level " + I2S(IMaxBJ(reqLevel, 1)) + ")|n|nQuality|cffcccccc: " + QualityNames[quality] + "|n|cffffcc00Sockets|cffcccccc: " + I2S(socketCount) + "(" + I2S(socketCountMax) + ")|r")
endif
endif
else
if id == 21 then
call BlzSetUnitName(object, "|cfff0d70aGold +" + I2S(goldGiven) + "|r")
call nameTag.setText("Gold +" + I2S(goldGiven))
call nameTag.setColor(240, 215, 10, 255)
call nameTag.refresh()
else
if id.rarity > 0 then
call BlzSetUnitName(object, RarityColor[id.rarity] + id.name + "|r")
else
call BlzSetUnitName(object, "|cffcccccc" + id.name + "|r")
endif
endif
endif
endif
endmethod
method setScrollStats takes integer dex returns nothing
if id.category == Items.SCROLL then
set .quality = dex
call AdjustItemObjectLevel(this, id.reqLevel)
endif
endmethod
method setStatsSet takes integer dex returns nothing
set .statsSet = dex
call SetStatsSet(this, dex)
endmethod
static method remove takes unit u returns nothing
call ItemObject[u].destroy()
endmethod
method downgrade takes boolean refresh returns nothing
local ItemUpgrade data = upgradeData.first
set .upgradeLevel = .upgradeLevel - 1
set .gold = .gold - data.value
if data.ore.fortitude == 1 then
set .physicDmgMin = .physicDmgMin - data.bonus
set .physicDmgMax = .physicDmgMax - data.bonus
elseif data.ore.fortitude == 2 then
set .magicDmgMin = .magicDmgMin - data.bonus
set .magicDmgMax = .magicDmgMax - data.bonus
elseif data.ore.fortitude == 3 then
set .magicDefense = .magicDefense - data.bonus
elseif data.ore.fortitude == 4 then
set .physicDefense = .physicDefense - data.bonus
endif
call upgradeData.pop()
if refresh then
call refreshName()
endif
endmethod
method clearUpgrade takes nothing returns nothing
loop
exitwhen upgradeData.first == 0
call downgrade(false)
endloop
call refreshName()
endmethod
method upgrade takes Items ore returns ItemUpgrade
local ItemUpgrade data
if ore.class != "Ore" then
return 0
endif
set .upgradeLevel = .upgradeLevel + 1
set data = .upgradeData.push()
set data.ore = ore
if ore.fortitude == 1 then
set data.bonus = ((.physicDmgMin+.physicDmgMax)/2. * UpgradeImprovementBase[ore.wisdom])*UpgradeQualityBonus[.quality]
set .physicDmgMin = .physicDmgMin + data.bonus
set .physicDmgMax = .physicDmgMax + data.bonus
elseif ore.fortitude == 2 then
set data.bonus = ((.magicDmgMin+.magicDmgMin)/2. * UpgradeImprovementBase[ore.wisdom])*UpgradeQualityBonus[.quality]
set .magicDmgMin = .magicDmgMin + data.bonus
set .magicDmgMax = .magicDmgMax + data.bonus
elseif ore.fortitude == 3 then
set data.bonus = (.magicDefense * UpgradeImprovementBase[ore.wisdom])*UpgradeQualityBonus[.quality]
set .magicDefense = .magicDefense + data.bonus
elseif ore.fortitude == 4 then
set data.bonus = (.physicDefense * UpgradeImprovementBase[ore.wisdom])*UpgradeQualityBonus[.quality]
set .physicDefense = .physicDefense + data.bonus
endif
set data.value = R2I(I2R(.gold) * UpgradeValueIncrement[ore.wisdom])
set .gold = .gold + data.value
call refreshName()
return data
endmethod
method socket takes ItemObject gem returns boolean
local ItemSocket iSocket
local string s
if reqLevel < gem.reqLevel or gem.id.category != Items.GEM then
return false
endif
if socketCount < socketCountMax then
set s = ""
if true then // populate bonus
if gem.strength != 0 and gem.id.strength != 0 then
if gem.strength > 0 then
set s = s + "Strength +" + I2S(gem.strength) + ", "
else
set s = s + "Strength " + I2S(gem.strength) + ", "
endif
endif
if gem.dexterity != 0 and gem.id.dexterity != 0 then
if gem.dexterity > 0 then
set s = s + "Dexterity +" + I2S(gem.dexterity) + ", "
else
set s = s + "Dexterity " + I2S(gem.dexterity) + ", "
endif
endif
if gem.wisdom != 0 and gem.id.wisdom != 0 then
if gem.wisdom > 0 then
set s = s + "Wisdom +" + I2S(gem.wisdom) + ", "
else
set s = s + "Wisdom " + I2S(gem.wisdom) + ", "
endif
endif
if gem.fortitude != 0 and gem.id.fortitude != 0 then
if gem.fortitude > 0 then
set s = s + "Fortitude +" + I2S(gem.fortitude) + ", "
else
set s = s + "Fortitude " + I2S(gem.fortitude) + ", "
endif
endif
if gem.aspd != 0 and gem.id.aspd != 0 then
if gem.aspd > 0 then
if R2I(gem.aspd) == gem.aspd then
set s = s + "Attack speed +" + I2S(R2I(gem.aspd)) + ", "
else
set s = s + "Attack speed +" + R2SW(gem.aspd, 3, 2) + ", "
endif
else
if R2I(gem.aspd) == gem.aspd then
set s = s + "Attack speed " + I2S(R2I(gem.aspd)) + ", "
else
set s = s + "Attack speed " + R2SW(gem.aspd, 3, 2) + ", "
endif
endif
endif
if gem.mspd != 0 and gem.id.mspd != 0 then
if gem.mspd > 0 then
set s = s + "Move speed +" + I2S(R2I(gem.mspd)) + ", "
else
set s = s + "Move speed " + I2S(R2I(gem.mspd)) + ", "
endif
endif
if gem.physicDmg != 0 and gem.id.physicDmg != 0 then
if gem.physicDmg > 0 then
set s = s + "Physical damage +" + I2S(R2I(gem.physicDmg)) + ", "
else
set s = s + "Physical damage " + I2S(R2I(gem.physicDmg)) + ", "
endif
endif
if gem.physicDefense != 0 and gem.id.physicDefense != 0 then
if gem.physicDefense > 0 then
if R2I(gem.physicDefense) == gem.physicDefense then
set s = s + "Physical defense +" + I2S(R2I(gem.physicDefense)) + ", "
else
set s = s + "Physical defense +" + R2SW(gem.physicDefense, 3, 2) + ", "
endif
else
if R2I(gem.physicDefense) == gem.physicDefense then
set s = s + "Physical defense " + I2S(R2I(gem.physicDefense)) + ", "
else
set s = s + "Physical defense " + R2SW(gem.physicDefense, 3, 2) + ", "
endif
endif
endif
if gem.magicDmg != 0 and gem.id.magicDmg != 0 then
if gem.magicDmg > 0 then
set s = s + "Magic damage +" + I2S(R2I(gem.magicDmg)) + ", "
else
set s = s + "Magic damage " + I2S(R2I(gem.magicDmg)) + ", "
endif
endif
if gem.magicDefense != 0 and gem.id.magicDefense != 0 then
if gem.magicDefense > 0 then
if R2I(gem.magicDefense) == gem.magicDefense then
set s = s + "Magic defense +" + I2S(R2I(gem.magicDefense)) + ", "
else
set s = s + "Magic defense +" + R2SW(gem.magicDefense, 3, 2) + ", "
endif
else
if R2I(gem.magicDefense) == gem.magicDefense then
set s = s + "Magic defense " + I2S(R2I(gem.magicDefense)) + ", "
else
set s = s + "Magic defense " + R2SW(gem.magicDefense, 3, 2) + ", "
endif
endif
endif
if gem.blockRate != 0 and gem.id.blockRate != 0 then
if gem.blockRate > 0 then
set s = s + "Block chance +" + I2S(R2I(gem.blockRate*100.)) + "%, "
else
set s = s + "Block chance " + I2S(R2I(gem.blockRate*100.)) + "%, "
endif
endif
if gem.criticalRate != 0 and gem.id.criticalRate != 0 then
if gem.criticalRate > 0 then
set s = s + "Critical chance +" + I2S(R2I(gem.criticalRate*100.)) + "%, "
else
set s = s + "Critical chance " + I2S(R2I(gem.criticalRate*100.)) + "%, "
endif
endif
if gem.criticalPower != 0 and gem.id.criticalPower != 0 then
if gem.criticalPower > 0 then
set s = s + "Critical power +" + I2S(R2I(gem.criticalPower*100.)) + "%, "
else
set s = s + "Critical power " + I2S(R2I(gem.criticalPower*100.)) + "%, "
endif
endif
if gem.evasionRate != 0 and gem.id.evasionRate != 0 then
if gem.evasionRate > 0 then
set s = s + "Evasion chance +" + I2S(R2I(gem.evasionRate*100.)) + "%, "
else
set s = s + "Evasion chance " + I2S(R2I(gem.evasionRate*100.)) + "%, "
endif
endif
if gem.accuracy != 0 and gem.id.accuracy != 0 then
if gem.accuracy > 0 then
set s = s + "Accuracy +" + I2S(R2I(gem.accuracy*100.)) + ", "
else
set s = s + "Accuracy " + I2S(R2I(gem.accuracy*100.)) + ", "
endif
endif
if gem.knockback != 0 and gem.id.knockback != 0 then
if gem.knockback > 0 then
set s = s + "Knockback power +" + I2S(R2I(gem.knockback)) + ", "
else
set s = s + "Knockback power " + I2S(R2I(gem.knockback)) + ", "
endif
endif
if gem.knockbackResist != 0 and gem.id.knockbackResist != 0 then
if gem.knockbackResist > 0 then
set s = s + "Knockback resistance +" + I2S(R2I(gem.knockbackResist)) + ", "
else
set s = s + "Knockback resistance " + I2S(R2I(gem.knockbackResist)) + ", "
endif
endif
if gem.interrupt != 0 and gem.id.interrupt != 0 then
if gem.interrupt > 0 then
set s = s + "Interrupt chance +" + I2S(R2I(gem.interrupt*100.)) + "%, "
else
set s = s + "Interrupt chance " + I2S(R2I(gem.interrupt*100.)) + "%, "
endif
endif
if gem.interruptResist != 0 and gem.id.interruptResist != 0 then
if gem.interruptResist > 0 then
set s = s + "Interrupt resistance +" + I2S(R2I(gem.interruptResist*100.)) + "%, "
else
set s = s + "Interrupt resistance " + I2S(R2I(gem.interruptResist*100.)) + "%, "
endif
endif
if gem.stun != 0 and gem.id.stun != 0 then
if gem.stun > 0 then
set s = s + "Stun chance +" + I2S(R2I(gem.stun*100.)) + "%, "
else
set s = s + "Stun chance " + I2S(R2I(gem.stun*100.)) + "%, "
endif
endif
if gem.stunResist != 0 and gem.id.stunResist != 0 then
if gem.stunResist > 0 then
set s = s + "Stun resistance +" + I2S(R2I(gem.stunResist*100.)) + "%, "
else
set s = s + "Stun resistance " + I2S(R2I(gem.stunResist*100.)) + "%, "
endif
endif
if gem.hp != 0 and gem.id.hp != 0 then
if gem.hp > 0 then
set s = s + "Health point +" + I2S(R2I(gem.hp)) + ", "
else
set s = s + "Health point " + I2S(R2I(gem.hp)) + ", "
endif
endif
if gem.hpMax != 0 and gem.id.hpMax != 0 then
if gem.hpMax > 0 then
set s = s + "Max health +" + I2S(R2I(gem.hpMax)) + ", "
else
set s = s + "Max health " + I2S(R2I(gem.hpMax)) + ", "
endif
endif
if gem.hpSteal != 0 and gem.id.hpSteal != 0 then
if gem.hpSteal > 0 then
set s = s + "Health stolen +" + I2S(R2I(gem.hpSteal)) + ", "
else
set s = s + "Health stolen " + I2S(R2I(gem.hpSteal)) + ", "
endif
endif
if gem.hpRegen != 0 and gem.id.hpRegen != 0 then
if gem.hpRegen > 0 then
if R2I(gem.hpRegen) == gem.hpRegen then
set s = s + "Health regeneration +" + I2S(R2I(gem.hpRegen)) + ", "
else
set s = s + "Health regeneration +" + R2SW(gem.hpRegen, 3, 2) + ", "
endif
else
if R2I(gem.hpRegen) == gem.hpRegen then
set s = s + "Health regeneration " + I2S(R2I(gem.hpRegen)) + ", "
else
set s = s + "Health regeneration " + R2SW(gem.hpRegen, 3, 2) + ", "
endif
endif
endif
if gem.sp != 0 and gem.id.sp != 0 then
if gem.sp > 0 then
set s = s + "Mana point +" + I2S(R2I(gem.sp)) + ", "
else
set s = s + "Mana point " + I2S(R2I(gem.sp)) + ", "
endif
endif
if gem.spMax != 0 and gem.id.spMax != 0 then
if gem.spMax > 0 then
set s = s + "Maximum mana +" + I2S(R2I(gem.spMax)) + ", "
else
set s = s + "Maximum mana " + I2S(R2I(gem.spMax)) + ", "
endif
endif
if gem.spRegen != 0 and gem.id.spRegen != 0 then
if gem.spRegen > 0 then
if R2I(gem.spRegen) == gem.spRegen then
set s = s + "Mana regeneration +" + I2S(R2I(gem.spRegen)) + ", "
else
set s = s + "Mana regeneration +" + R2SW(gem.spRegen, 3, 2) + ", "
endif
else
if R2I(gem.spRegen) == gem.spRegen then
set s = s + "Mana regeneration " + I2S(R2I(gem.spRegen)) + ", "
else
set s = s + "Mana regeneration " + R2SW(gem.spRegen, 3, 2) + ", "
endif
endif
endif
if gem.fireElement != 0 and gem.id.fireElement != 0 then
if gem.fireElement > 0 then
set s = s + "Fire element +" + I2S(R2I(gem.fireElement)) + ", "
else
set s = s + "Fire element " + I2S(R2I(gem.fireElement)) + ", "
endif
endif
if gem.fireElementResist != 0 and gem.id.fireElementResist != 0 then
if gem.fireElementResist > 0 then
set s = s + "Fire resistance +" + I2S(R2I(gem.fireElementResist)) + ", "
else
set s = s + "Fire resistance " + I2S(R2I(gem.fireElementResist)) + ", "
endif
endif
if gem.waterElement != 0 and gem.id.waterElement != 0 then
if gem.waterElement > 0 then
set s = s + "Water element +" + I2S(R2I(gem.waterElement)) + ", "
else
set s = s + "Water element " + I2S(R2I(gem.waterElement)) + ", "
endif
endif
if gem.waterElementResist != 0 and gem.id.waterElementResist != 0 then
if gem.waterElementResist > 0 then
set s = s + "Water resistance +" + I2S(R2I(gem.waterElementResist)) + ", "
else
set s = s + "Water resistance " + I2S(R2I(gem.waterElementResist)) + ", "
endif
endif
if gem.earthElement != 0 and gem.id.earthElement != 0 then
if gem.earthElement > 0 then
set s = s + "Earth element +" + I2S(R2I(gem.earthElement)) + ", "
else
set s = s + "Earth element " + I2S(R2I(gem.waterElement)) + ", "
endif
endif
if gem.earthElementResist != 0 and gem.id.earthElementResist != 0 then
if gem.earthElementResist > 0 then
set s = s + "Earth resistance +" + I2S(R2I(gem.earthElementResist)) + ", "
else
set s = s + "Earth resistance " + I2S(R2I(gem.earthElementResist)) + ", "
endif
endif
if gem.windElement != 0 and gem.id.windElement != 0 then
if gem.windElement > 0 then
set s = s + "Wind element +" + I2S(R2I(gem.windElement)) + ", "
else
set s = s + "Wind element " + I2S(R2I(gem.windElement)) + ", "
endif
endif
if gem.windElementResist != 0 and gem.id.windElementResist != 0 then
if gem.windElementResist > 0 then
set s = s + "Wind resistance +" + I2S(R2I(gem.windElementResist)) + ", "
else
set s = s + "Wind resistance " + I2S(R2I(gem.windElementResist)) + ", "
endif
endif
if gem.holyElement != 0 and gem.id.holyElement != 0 then
if gem.holyElement > 0 then
set s = s + "Holy element +" + I2S(R2I(gem.holyElement)) + ", "
else
set s = s + "Holy element " + I2S(R2I(gem.holyElement)) + ", "
endif
endif
if gem.darkElement != 0 and gem.id.darkElement != 0 then
if gem.darkElement > 0 then
set s = s + "Dark element +" + I2S(R2I(gem.darkElement)) + ", "
else
set s = s + "Dark element " + I2S(R2I(gem.darkElement)) + ", "
endif
endif
endif
set socketCount = socketCount + 1
set iSocket = socketData.enqueue()
set iSocket.gem = gem
set iSocket.comment = gem.id.name + ":|cffffe65b " + SubString(s, 0, StringLength(s)-2) + "|r"
if (.id.category == Items.RIGHT_HAND or .id.category == Items.LEFT_HAND and .id.class != "Shield") then
set .model = gem.model
endif
set .gold = .gold + gem.gold
set .lumber = .lumber + gem.lumber
set .strength = .strength + gem.strength
set .dexterity = .dexterity + gem.dexterity
set .wisdom = .wisdom + gem.wisdom
set .fortitude = .fortitude + gem.fortitude
set .cooldown = .cooldown + gem.cooldown
set .physicDmg = .physicDmg + gem.physicDmg
set .physicDmgMin = .physicDmgMin + gem.physicDmgMin
set .physicDmgMax = .physicDmgMax + gem.physicDmgMax
set .physicDefense = .physicDefense + gem.physicDefense
set .magicDmg = .magicDmg + gem.magicDmg
set .magicDmgMin = .magicDmgMin + gem.magicDmgMin
set .magicDmgMax = .magicDmgMax + gem.magicDmgMax
set .magicDefense = .magicDefense + gem.magicDefense
set .physicReflect = .physicReflect + gem.physicReflect
set .magicReflect = .magicReflect + gem.magicReflect
set .dmgReflect = .dmgReflect + gem.dmgReflect
set .attackRange = .attackRange + gem.attackRange
set .blockRate = .blockRate + gem.blockRate
set .criticalRate = .criticalRate + gem.criticalRate
set .criticalPower = .criticalPower + gem.criticalPower
set .evasionRate = .evasionRate + gem.evasionRate
set .accuracy = gem.accuracy
set .knockback = .knockback + gem.knockback
set .knockbackResist = .knockbackResist + gem.knockbackResist
set .interrupt = .interrupt + gem.interrupt
set .interruptResist = .interruptResist + gem.interruptResist
set .stun = .stun + gem.stun
set .stunResist = .stunResist + gem.stunResist
set .hp = .hp + gem.hp
set .hpMax = .hpMax + gem.hpMax
set .sp = .sp + gem.sp
set .spMax = .spMax + gem.spMax
set .hpSteal = .hpSteal + gem.hpSteal
set .spSteal = .spSteal + gem.spSteal
set .aspd = .aspd + gem.aspd
set .mspd = .mspd + gem.mspd
set .duration = .duration + gem.duration
set .fireElement = .fireElement + gem.fireElement
set .fireElementResist = .fireElementResist + gem.fireElementResist
set .waterElement = .waterElement + gem.waterElement
set .waterElementResist = .waterElementResist + gem.waterElementResist
set .earthElement = .earthElement + gem.earthElement
set .earthElementResist = .earthElementResist + gem.earthElementResist
set .windElement = .windElement + gem.windElement
set .windElementResist = .windElementResist + gem.windElementResist
set .holyElement = .holyElement + gem.holyElement
set .darkElement = .darkElement + gem.darkElement
call refreshName()
return true
endif
return false
endmethod
static method duplicate takes thistype i, real x, real y returns thistype
local thistype this = allocate()
local thistype obj
local ItemSocket iSocket
local ItemUpgrade iUpgrade
local ItemUpgrade flip
//call BJDebugMsg("Duplicate item: " + I2S(this))
set .locX = x
set .locY = y
set .object = CreateUnit(PASSIVE, 'e02F', x, y, GetRandomReal(0, 359))
static if USE_MEMORY_HACK then
set .avatar = AddSpecialEffectTarget(i.id.avatarPath, .object, "origin")
else
set .avatar = AddSpecialEffect(i.id.avatarPath, x, y)
call BlzSetSpecialEffectScale(.avatar, i.id.avatarScale)
if i == 21 then
call BlzPlaySpecialEffect(avatar, ANIM_TYPE_BIRTH)
else
call BlzPlaySpecialEffect(avatar, ANIM_TYPE_STAND)
endif
endif
call GroupAddUnit(AllItem, .object)
set .nameTag = CustomText.create(i.id.name, x, y, 100, ITEM_NAMETAG_SIZE, 0.5)
if i.id.rarity > 0 then
call .nameTag.setColor(RarityColorR[i.id.rarity], RarityColorG[i.id.rarity], RarityColorB[i.id.rarity], 255)
else
call .nameTag.setColor(255, 255, 255, 255)
endif
set .id = i.id
set .statsSet = i.statsSet
set .visible = true
set .selectable = ItemOn[PNumb]
set .rarity = i.rarity
set .reqLevel = i.reqLevel
set .charge = i.charge
set .cdTimer = NewTimerEx(this)
set ItemIndex.integer[GetHandleId(.object)] = this
set .socketData = ItemSocket.create()
set .socketCount = 0
set .socketCountMax = i.socketCountMax
if i.socketCount > 0 then
set iSocket = i.socketData.first
loop
exitwhen iSocket == 0
if iSocket.gem != 0 then
set obj = duplicate(iSocket.gem, 0, 0)
if this.socket(obj) then
call obj.show(false)
else
call obj.destroy()
endif
endif
set iSocket = iSocket.next
endloop
endif
set .upgradeLevel = 0
set .upgradeData = ItemUpgrade.create()
if i.upgradeLevel > 0 then
set flip = ItemUpgrade.create()
set iUpgrade = i.upgradeData.first
loop
exitwhen iUpgrade == 0
if iUpgrade.ore != 0 then
set flip.push().ore = iUpgrade.ore
endif
set iUpgrade = iUpgrade.next
endloop
set iUpgrade = flip.first
loop
exitwhen iUpgrade == 0
if iUpgrade.ore != 0 then
//call BJDebugMsg("Dupe (" + I2S(iUpgrade) + "): " + iUpgrade.ore.name)
call this.upgrade(iUpgrade.ore)
endif
set iUpgrade = iUpgrade.next
endloop
call flip.destroy()
endif
set .goldGiven = i.goldGiven
set .model = i.model
set .modelPt = i.modelPt
set .strength = i.strength
set .dexterity = i.dexterity
set .wisdom = i.wisdom
set .fortitude = i.fortitude
set .quality = i.quality
set .gold = i.gold
set .lumber = i.lumber
set .cooldown = i.cooldown
set .physicDmg = i.physicDmg
set .physicDmgMin = i.physicDmgMin
set .physicDmgMax = i.physicDmgMax
set .physicDefense = i.physicDefense
set .magicDmg = i.magicDmg
set .magicDmgMin = i.magicDmgMin
set .magicDmgMax = i.magicDmgMax
set .magicDefense = i.magicDefense
set .physicReflect = i.physicReflect
set .magicReflect = i.magicReflect
set .dmgReflect = i.dmgReflect
set .attackRange = i.attackRange
set .blockRate = i.blockRate
set .criticalRate = i.criticalRate
set .criticalPower = i.criticalPower
set .evasionRate = i.evasionRate
set .accuracy = i.accuracy
set .knockback = i.knockback
set .knockbackResist = i.knockbackResist
set .interrupt = i.interrupt
set .interruptResist = i.interruptResist
set .stun = i.stun
set .stunResist = i.stunResist
set .hp = i.hp
set .hpMax = i.hpMax
set .sp = i.sp
set .spMax = i.spMax
set .hpSteal = i.hpSteal
set .spSteal = i.spSteal
set .hpRegen = i.hpRegen
set .spRegen = i.spRegen
set .aspd = i.aspd
set .mspd = i.mspd
set .duration = i.duration
set .fireElement = i.fireElement
set .fireElementResist = i.fireElementResist
set .waterElement = i.waterElement
set .waterElementResist = i.waterElementResist
set .earthElement = i.earthElement
set .earthElementResist = i.earthElementResist
set .windElement = i.windElement
set .windElementResist = i.windElementResist
set .holyElement = i.holyElement
set .darkElement = i.darkElement
set .physicDmgPctg = i.physicDmgPctg
set .physicDefPctg = i.physicDefPctg
set .magicDmgPctg = i.magicDmgPctg
set .magicDefPctg = i.magicDefPctg
set .aspdPctg = i.aspdPctg
set .mspdPctg = i.mspdPctg
set .hpPctg = i.hpPctg
set .expRate = i.expRate
set .goldRate = i.goldRate
set .dropRate = i.dropRate
set .dungeonSize = i.dungeonSize
call refreshName()
return this
endmethod
static method create takes Items itm, integer amount, integer quality, real x, real y returns thistype
local thistype this = 0
set this = allocate()
//call BJDebugMsg("Create item: " + I2S(this))
set socketData = ItemSocket.create()
set .locX = x
set .locY = y
set object = CreateUnit(PASSIVE, 'e02F', x, y, GetRandomReal(0, 359))
static if USE_MEMORY_HACK then
set avatar = AddSpecialEffectTarget(itm.avatarPath, object, "origin")
else
set avatar = AddSpecialEffect(itm.avatarPath, x, y)
call BlzSetSpecialEffectScale(avatar, itm.avatarScale)
if itm == 21 then
call BlzPlaySpecialEffect(avatar, ANIM_TYPE_BIRTH)
else
call BlzPlaySpecialEffect(avatar, ANIM_TYPE_STAND)
endif
endif
call GroupAddUnit(AllItem, object)
set id = itm
set charge = amount
set cdTimer = NewTimerEx(this)
set ItemIndex.integer[GetHandleId(object)] = this
set .nameTag = CustomText.create(itm.name, x, y, 100, ITEM_NAMETAG_SIZE, 0.5)
if itm.rarity > 0 then
call .nameTag.setColor(RarityColorR[itm.rarity], RarityColorG[itm.rarity], RarityColorB[itm.rarity], 255)
else
call .nameTag.setColor(255, 255, 255, 255)
endif
set .upgradeLevel = 0
set .upgradeData = ItemUpgrade.create()
set .visible = true
set .selectable = ItemOn[PNumb]
set .rarity = itm.rarity
set .reqLevel = itm.reqLevel
set .model = itm.model
set .modelPt = itm.modelPt
set .quality = quality
if itm.socketCount >= itm.socketCountMax then
set .socketCountMax = itm.socketCountMax
else
set .socketCountMax = SocketCountRandomizer[itm.socketCountMax].getItem()
if .socketCountMax < itm.socketCount then
set .socketCountMax = itm.socketCount
endif
endif
set .goldGiven = 0
if not itm.randomStats then
set .strength = itm.strength
set .dexterity = itm.dexterity
set .wisdom = itm.wisdom
set .fortitude = itm.fortitude
set .physicDmg = itm.physicDmg
set .physicDmgMin = itm.physicDmgMin
set .physicDmgMax = itm.physicDmgMax
set .physicDefense = itm.physicDefense
set .magicDmg = itm.magicDmg
set .magicDmgMin = itm.magicDmgMin
set .magicDmgMax = itm.magicDmgMax
set .magicDefense = itm.magicDefense
set .physicReflect = itm.physicReflect
set .magicReflect = itm.magicReflect
set .dmgReflect = itm.dmgReflect
set .lumber = itm.lumber
set .cooldown = itm.cooldown
set .attackRange = itm.attackRange
set .blockRate = itm.blockRate
set .criticalRate = itm.criticalRate
set .criticalPower = itm.criticalPower
set .evasionRate = itm.evasionRate
set .accuracy = itm.accuracy
set .knockback = itm.knockback
set .knockbackResist = itm.knockbackResist
set .interrupt = itm.interrupt
set .interruptResist = itm.interruptResist
set .stun = itm.stun
set .stunResist = itm.stunResist
set .hp = itm.hp
set .hpMax = itm.hpMax
set .sp = itm.sp
set .spMax = itm.spMax
set .hpSteal = itm.hpSteal
set .spSteal = itm.spSteal
set .hpRegen = itm.hpRegen
set .spRegen = itm.spRegen
set .aspd = itm.aspd
set .mspd = itm.mspd
set .duration = itm.duration
set .fireElement = itm.fireElement
set .fireElementResist = itm.fireElementResist
set .waterElement = itm.waterElement
set .waterElementResist = itm.waterElementResist
set .earthElement = itm.earthElement
set .earthElementResist = itm.earthElementResist
set .windElement = itm.windElement
set .windElementResist = itm.windElementResist
set .holyElement = itm.holyElement
set .darkElement = itm.darkElement
set .physicDmgPctg = itm.physicDmgPctg
set .physicDefPctg = itm.physicDefPctg
set .magicDmgPctg = itm.magicDmgPctg
set .magicDefPctg = itm.magicDefPctg
set .aspdPctg = itm.aspdPctg
set .mspdPctg = itm.mspdPctg
set .hpPctg = itm.hpPctg
set .expRate = itm.expRate
set .goldRate = itm.goldRate
set .dropRate = itm.dropRate
set .dungeonSize = itm.dungeonSize
else
set itm.strength = 0
set itm.dexterity = 0
set itm.wisdom = 0
set itm.fortitude = 0
set itm.physicDmg = 0
set itm.physicDmgMin = 0
set itm.physicDmgMax = 0
set itm.physicDefense = 0
set itm.magicDmg = 0
set itm.magicDmgMin = 0
set itm.magicDmgMax = 0
set itm.magicDefense = 0
set .strength = 0
set .dexterity = 0
set .wisdom = 0
set .fortitude = 0
set .physicDmg = 0
set .physicDmgMin = 0
set .physicDmgMax = 0
set .physicDefense = 0
set .magicDmg = 0
set .magicDmgMin = 0
set .magicDmgMax = 0
set .magicDefense = 0
set .physicReflect = 0
set .magicReflect = 0
set .dmgReflect = 0
set .cooldown = 0
set .attackRange = 0
set .blockRate = 0
set .criticalRate = 0
set .criticalPower = 0
set .evasionRate = 0
set .accuracy = 0
set .knockback = 0
set .knockbackResist = 0
set .interrupt = 0
set .interruptResist =0
set .stun = 0
set .stunResist = 0
set .hp = 0
set .hpMax = 0
set .sp = 0
set .spMax = 0
set .hpSteal = 0
set .spSteal = 0
set .hpRegen = 0
set .spRegen = 0
set .aspd = 0
set .mspd = 0
set .duration = 0
set .fireElement = 0
set .fireElementResist = 0
set .waterElement = 0
set .waterElementResist = 0
set .earthElement = 0
set .earthElementResist = 0
set .windElement = 0
set .windElementResist = 0
set .holyElement = 0
set .darkElement = 0
set .physicDmgPctg = 0
set .physicDefPctg = 0
set .magicDmgPctg = 0
set .magicDefPctg = 0
set .aspdPctg = 0
set .mspdPctg = 0
set .hpPctg = 0
set .expRate = 0
set .goldRate = 0
set .dropRate = 0
set .dungeonSize = 0
endif
if itm.randomStats and not NoRandom then
call setStatsSet(GetRandomInt(0, StatsSetCount[.rarity][itm.category]))
endif
set NoRandom = false
if itm.category == Items.MISC then
set .reqLevel = itm.reqLevel
if itm.gold > 0 then
call AdjustItemGold(this, IMaxBJ((itm.wisdom-1)*25, 1))
endif
else
call AdjustItemObjectLevel(this, itm.reqLevel)
endif
call refreshName()
// Apply quality price bonus
if itm.category < Items.CONSUMABLE and AdjustGoldPrice then
set .gold = R2I(I2R(.gold)*SocketCountValueFactor[.socketCountMax]*QualityValueFactor[.quality])
endif
set AdjustGoldPrice = true
return this
endmethod
private static method onInit takes nothing returns nothing
set ItemIndex = Table.create()
endmethod
endstruct
struct Items
boolean cmd
boolean drop
boolean noAdjust
boolean autoUse
boolean randomStats
integer rarity
integer maxCharge
integer texture
integer category
integer abil
integer gold // sell value
integer lumber // sell value
integer socketCount
integer socketCountMax
integer job
integer cooldownGroup
string class
integer strength
integer dexterity
integer wisdom
integer fortitude
real cooldown
real physicDmg
real physicDmgMin
real physicDmgMax
real physicDefense
real magicDmg
real magicDmgMin
real magicDmgMax
real magicDefense
real physicReflect
real magicReflect
real dmgReflect
real attackRange
real blockRate
real criticalRate
real criticalPower
real evasionRate
real accuracy
real knockback
real knockbackResist
real interrupt
real interruptResist
real stun
real stunResist
real hp
real hpMax
real hpSteal
real sp
real spMax
real spSteal
real hpRegen
real spRegen
real aspd
real mspd
real duration
real fireElement
real fireElementResist
real waterElement
real waterElementResist
real earthElement
real earthElementResist
real windElement
real windElementResist
real holyElement
real darkElement
integer reqStrength
integer reqDexterity
integer reqWisdom
integer reqFortitude
integer reqLevel
integer reqCount
real physicDmgPctg
real physicDefPctg
real magicDmgPctg
real magicDefPctg
real aspdPctg
real mspdPctg
real hpPctg
real expRate
real goldRate
real dropRate
integer dungeonSize
integer dungeonType
integer dropWeight
string name
string avatarPath
string upgradeSfx
real avatarScale
string model
string modelPt
string comment
integer commentLn
timer cdTimer
static Table RawTable
static constant integer HEAD = 1
static constant integer CHEST = 2
static constant integer LEGS = 3
static constant integer FEET = 4
static constant integer RIGHT_HAND = 5
static constant integer NECK = 6
static constant integer SHOULDER = 7
static constant integer ARM = 8
static constant integer RING = 9
static constant integer LEFT_HAND = 10
static constant integer CONSUMABLE = 11
static constant integer MISC = 12
static constant integer GEM = 13
static constant integer SCROLL = 14
method getCooldown takes nothing returns real
return TimerGetRemaining(cdTimer)
endmethod
method onCooldown takes nothing returns boolean
return TimerGetRemaining(cdTimer) > 0.001
endmethod
method startCooldown takes real delay returns nothing
if not onCooldown() then
call TimerStart(cdTimer, delay, false, null)
endif
endmethod
static method create takes nothing returns thistype
local thistype this = allocate()
set dropWeight = DEFAULT_DROP_WEIGHT
set cdTimer = NewTimerEx(this)
set cmd = true
return this
endmethod
private static method onInit takes nothing returns nothing
set RawTable = Table.create()
endmethod
endstruct
endlibrary
library GameConstants initializer init uses TimerUtils
globals
// Core
constant string MAP_NAME = "EmberCraft"
constant integer MAX_SAVE_SLOT = 6
constant integer SAVE_DATA_VERSION = 4
constant boolean USE_MEMORY_HACK = false
constant real START_X = -16381.34
constant real START_Y = 13019.70
constant real CREATE_X = -16381.34
constant real CREATE_Y = 13019.70
// Name Tag Color
constant integer PORTAL_TAG_COLOR_R = 155
constant integer PORTAL_TAG_COLOR_G = 255
constant integer PORTAL_TAG_COLOR_B = 66
constant integer NPC_TAG_COLOR_R = 255
constant integer NPC_TAG_COLOR_G = 198
constant integer NPC_TAG_COLOR_B = 0
// Misc
constant real EXP_SHARE_RANGE = 2000.0
constant real SOUL_HARVEST_RANGE = 100.0
constant real SOUL_ACCELERATION = 5.0*0.03125
constant real SOUL_MAX_SPEED = 25.0
constant real ITEM_PICKUP_RANGE = 200.0
constant integer DEFAULT_GEAR_DROP_WEIGHT = 5
constant integer DEFAULT_GEM_DROP_WEIGHT = 5
constant real OCCLUSION_DEST_DISTANCE = 500.0
constant real DEFAULT_SHAKE_INTENSITY = 1.0
constant real SYNC_TIMEOUT = 5.0
constant real ITEM_NAMETAG_SIZE = 0.5
constant integer DEFAULT_DROP_WEIGHT = 10
constant integer DUNGEON_VARIATION = 2
constant integer SCROLL_VARIATION = 26
constant real MERCHANT_BUY_RANGE = 200.0*200.0
constant real DOUBLE_CLICK_WAIT_TIME = 0.5
constant real ITEM_PRICE_RATE = 13.0
constant integer RARITY_BORDER_ALPHA = 150
constant real UNITS_PER_METER = 64.0
constant real SKILL_MASTERY_RATE = 1.0
constant player PASSIVE = Player(PLAYER_NEUTRAL_PASSIVE)
// Upgrade
constant real UPGRADE_LEVEL_COST_BASE_POWER = 1.03
constant real UPGRADE_LEVEL_COST_BASE = 25.0
constant real UPGRADE_LEVEL_COST_PERCENT = 1.01
constant real UPGRADE_GEAR_LEVEL_REDUCTION = 0.985
constant real UPGRADE_QUALITY_REDUCTION_CHANCE = 0.33
constant integer UPGRADE_MAX_LEVEL = 12
// Combat
constant real MINISTUN_DURATION = 1.0
constant real PLAYER_COUNT_DAMAGE_PENALTY = 0.35
constant real PHYSIC_DAMAGE_MULTIPLIER = 2.5
constant real MAGIC_DAMAGE_MULTIPLIER = 3.5
constant real PHYSIC_ARMOR_MULTIPLIER = 1.5
constant real MAGIC_ARMOR_MULTIPLIER = 1.5
constant real GENERAL_KNOCKBACK_SPEED = 15.0
constant real WEAK_ELEMENT_FACTOR = 0.5
constant real STRONG_ELEMENT_FACTOR = 1.0
// Player config
constant real EXP_BASE = 100.0
constant real EXP_GROWTH = 1.035
constant real EXP_GROWTH_CONST = 100.0
constant integer MAXIMUM_LEVEL = 100
constant integer ATTRIBUTE_PTS_GIVEN = 5
constant integer SKILL_PTS_GIVEN = 1
constant integer SKILL_PTS_GIVE_LEVEL_SPACE = 5
constant integer MAXIMUM_ACTIVE_SKILL_LEVEL = 15
constant integer MAXIMUM_PASSIVE_SKILL_LEVEL = 5
// Generic equipment stats
constant real GENERIC_ARMOR_HELMET_PHYSIC = 0.75
constant real GENERIC_ARMOR_HELMET_MAGIC = 0.65
constant integer GENERIC_ARMOR_HELMET_GOLD = 20
constant real GENERIC_ARMOR_CHEST_PHYSIC = 1.0
constant integer GENERIC_ARMOR_CHEST_GOLD = 25
constant real GENERIC_ARMOR_PADS_MAGIC = 0.8
constant integer GENERIC_ARMOR_PADS_GOLD = 13
constant real GENERIC_ARMOR_GLOVES_PHYSIC = 0.6
constant real GENERIC_ARMOR_GLOVES_MAGIC = 0.55
constant integer GENERIC_ARMOR_GLOVES_GOLD = 15
constant real GENERIC_ARMOR_LEGS_PHYSIC = 0.8
constant integer GENERIC_ARMOR_LEGS_GOLD = 20
constant real GENERIC_ARMOR_FEET_PHYSIC = 0.5
constant integer GENERIC_ARMOR_FEET_GOLD = 14
constant real GENERIC_ARMOR_SHIELD_PHYSIC = 1.5
constant real GENERIC_ARMOR_SHIELD_BLOCK = 0.1
constant integer GENERIC_ARMOR_SHIELD_GOLD = 32
constant real GENERIC_WEAPON_BLADE_PHYSIC_MIN = 2
constant real GENERIC_WEAPON_BLADE_PHYSIC_MAX = 4
constant integer GENERIC_WEAPON_BLADE_GOLD = 37
constant real GENERIC_WEAPON_BOW_PHYSIC_MIN = 4
constant real GENERIC_WEAPON_BOW_PHYSIC_MAX = 7
constant integer GENERIC_WEAPON_BOW_GOLD = 40
// Damage text
constant integer NORMAL_DAMAGE_R = 195
constant integer NORMAL_DAMAGE_G = 1
constant integer NORMAL_DAMAGE_B = 1
constant integer CRIT_DAMAGE_R = 0
constant integer CRIT_DAMAGE_G = 78
constant integer CRIT_DAMAGE_B = 183
constant integer HEAL_R = 20
constant integer HEAL_G = 182
constant integer HEAL_B = 3
constant integer MANA_R = 100
constant integer MANA_G = 175
constant integer MANA_B = 255
constant integer REFLECT_R = 255
constant integer REFLECT_G = 0
constant integer REFLECT_B = 162
constant real TEXTTAG_NORMAL_SIZE = 6.0
constant real TEXTTAG_CRITICAL_SIZE = 8.0
constant real TEXTTAG_DPS_SIZE = 8.0
// Creep configs
constant player CREEP_PLAYER = Player(8)
constant real CREEP_VISION_RANGE = 1000.0
constant real CREEP_VISION_ARC = 90.*bj_DEGTORAD
constant real CREEP_SENSE_RADIUS = 200.0
constant real CREEP_MAX_CHASE_DISTANCE = 2000.0*2000.0
constant real CREEP_ALERT_RADIUS = 1000.0
constant real CREEP_SHARED_THREAT_DISTANCE = 300.0
constant real CREEP_SHARED_THREAT_FACTOR = 0.25
// Curve control
constant real CHARACTER_LEVEL_POWER = 1.03
constant real SKILL_LEVEL_POWER = 1.2
constant real STATUS_LEVEL_POWER = 1.02
// Player strength growth
// 1. Health
constant real PHP_level_1_val_1 = 1
constant real PHP_level_1_val_max = 20
constant real PHP_level_max_val_1 = 300
constant real PHP_level_max_val_max = 800
// Creep strength growth
// 2. Physic armor
constant real PA_level_1_val_1 = 0
constant real PA_level_1_val_max = 20
constant real PA_level_max_val_1 = 300
constant real PA_level_max_val_max = 800
// 3. Magic armor
constant real MA_level_1_val_1 = 0
constant real MA_level_1_val_max = 10
constant real MA_level_max_val_1 = 150
constant real MA_level_max_val_max = 400
// 4. Health
constant real HP_level_1_val_1 = 50
constant real HP_level_1_val_max = 400
constant real HP_level_max_val_1 = 5000
constant real HP_level_max_val_max = 50000
// 5. Physic damage
constant real PD_level_1_val_1 = 0
constant real PD_level_1_val_max = 40
constant real PD_level_max_val_1 = 600
constant real PD_level_max_val_max = 1500
// 6. Magic damage
constant real MD_level_1_val_1 = 0
constant real MD_level_1_val_max = 20
constant real MD_level_max_val_1 = 300
constant real MD_level_max_val_max = 750
// 7. Damage dice
constant real DC_level_1_val_1 = 0
constant real DC_level_1_val_max = 15
constant real DC_level_max_val_1 = 100
constant real DC_level_max_val_max = 300
endglobals
globals
IPool array SocketCountRandomizer
real array SocketCountValueFactor
real array QualityValueFactor
real CharacterLevelPower
real StatusValuePower
real DamageDicePower
real array MasteryGrowthTime
real array MasteryGrowthRate
real array SoulHarvestChance
integer array ScrollPriceTier
IPool RarityPool
IPool array DropList[8][101]
IPool array GemDropList
IPool OreDropList
IPool GemstoneDropList
IPool array PotionDropList
integer array TargetLevel
IPool array ItemQualityPool
IPool ItemLevelPool
IPool ItemBonusLevelPool
integer array OreTypeRarity
integer array GemstoneTypeRarity
integer array StatsSetCount[10][11]
real array GoldAmountBonus
real array QualityBonus
real array DropChance
real array PotionDropChance
real array GemDropChance
real array OreDropChance
real array GemstoneDropChance
real array GoldDropChance
real array UpgradeOrePrice
real array UpgradeGemstonePrice
real array UpgradeImprovementBase
real array UpgradeQualityBonus
real array UpgradeChanceBonus
real array UpgradeChanceBase
real array UpgradeDestroyChance
real array UpgradeResetChance
real array UpgradeDowngradeChance
real array UpgradeValueIncrement
IPool SocketCountPool
endglobals
function CalculateSkillLevelFactor takes integer level, integer maxLevel returns real
return (Pow(SKILL_LEVEL_POWER, level) - 1.) / (Pow(SKILL_LEVEL_POWER, maxLevel) - 1.)
endfunction
function CalculateCharLevelValue takes real range, integer level returns real
return range * (Pow(CHARACTER_LEVEL_POWER, level) - 1.) / CharacterLevelPower
endfunction
function CalculateStatusBaseFactor takes real value, real maxValue returns real
return (Pow(STATUS_LEVEL_POWER, value) - 1.) / (Pow(STATUS_LEVEL_POWER, maxValue) - 1.)
endfunction
function CalculateStatusValue takes real range, integer level returns real
return range * (Pow(STATUS_LEVEL_POWER, level) - 1.) / StatusValuePower
endfunction
function GetTypeIndex takes integer id returns integer
if id == 'h004' then
return 1
elseif id == 'h00C' then
return 2
endif
return 0
endfunction
function GetIndexType takes integer index returns integer
if index == 1 then
return 'h004'
elseif index == 2 then
return 'h00C'
endif
return 'h02H'
endfunction
function GetPetIndex takes integer id returns integer
if id == 'h028' then
return 1
elseif id == 'h029' then
return 2
elseif id == 'h02B' then
return 3
elseif id == 'h02D' then
return 4
elseif id == 'h02A' then
return 5
elseif id == 'h02C' then
return 6
elseif id == 'h02E' then
return 7
endif
return 0
endfunction
function GetPetType takes integer index returns integer
if index == 1 then
return 'h028'
elseif index == 2 then
return 'h029'
elseif index == 3 then
return 'h02B'
elseif index == 4 then
return 'h02D'
elseif index == 5 then
return 'h02A'
elseif index == 6 then
return 'h02C'
elseif index == 7 then
return 'h02E'
endif
return 'h02I'
endfunction
function GetItemCategoryIndex takes integer category returns integer
if category < Items.CONSUMABLE then
return ITEM_INDEX_EQUIPMENT
elseif category == Items.SCROLL then
return ITEM_INDEX_SCROLLS
elseif category == Items.GEM then
return ITEM_INDEX_GEM
elseif category == Items.MISC then
return ITEM_INDEX_MISC
elseif category == Items.CONSUMABLE then
return 0
else
return 999
endif
endfunction
function GetGoldenDropMin takes integer level returns real
return 10.0+1.0*level
endfunction
function GetGoldenDropMax takes integer level returns real
return 25.0+3.0*level
endfunction
function GetGoldenDropPartMin takes integer level returns real
return 1.0+1.0*level
endfunction
function GetGoldenDropPartMax takes integer level returns real
return 10.0+2.25*level
endfunction
function GetGoldenDropAmount takes integer level, integer quality returns real
return GetRandomReal(GetGoldenDropMin(level), GetGoldenDropMax(level))*GoldAmountBonus[quality]
endfunction
function GetGoldenDropPart takes integer level returns real
return GetRandomReal(GetGoldenDropPartMin(level), GetGoldenDropPartMax(level))
endfunction
function IsUnitAlive takes unit u returns boolean
return u != null and UnitAlive(u) and not IsUnitPaused(u)
endfunction
private function lateInit takes nothing returns nothing
local Items itm
local integer i
local integer j
local integer level
// Populate equipment
set i = ITEM_INDEX_EQUIPMENT
loop
set itm = Items(i)
exitwhen StringLength(itm.name) <= 0
if (itm.drop and itm.rarity < 7) then
if DropList[itm.rarity][itm.reqLevel] == 0 then
set DropList[itm.rarity][itm.reqLevel] = IPool.create()
endif
if itm.dropWeight <= 0 then
call DropList[itm.rarity][itm.reqLevel].add(itm, DEFAULT_GEAR_DROP_WEIGHT)
else
call DropList[itm.rarity][itm.reqLevel].add(itm, itm.dropWeight)
endif
endif
set i = i + 1
endloop
// Populate potions
set PotionDropList[0] = IPool.create()
set PotionDropList[1] = IPool.create()
set PotionDropList[2] = IPool.create()
set PotionDropList[3] = IPool.create()
set PotionDropList[4] = IPool.create()
set PotionDropList[5] = IPool.create()
set PotionDropList[6] = IPool.create()
set PotionDropList[7] = IPool.create()
set PotionDropList[8] = IPool.create()
set PotionDropList[9] = IPool.create()
set PotionDropList[10] = IPool.create()
call PotionDropList[0].add(1, 4)
call PotionDropList[0].add(11, 2)
call PotionDropList[1].add(2, 4)
call PotionDropList[1].add(12, 2)
call PotionDropList[2].add(3, 4)
call PotionDropList[2].add(13, 2)
call PotionDropList[3].add(4, 4)
call PotionDropList[3].add(14, 2)
call PotionDropList[4].add(5, 4)
call PotionDropList[4].add(15, 2)
call PotionDropList[5].add(6, 4)
call PotionDropList[5].add(16, 2)
call PotionDropList[6].add(7, 4)
call PotionDropList[6].add(17, 2)
call PotionDropList[7].add(8, 4)
call PotionDropList[7].add(18, 2)
call PotionDropList[8].add(9, 4)
call PotionDropList[8].add(19, 2)
// Populate gems
set i = ITEM_INDEX_GEM + 1
loop
exitwhen i > ITEM_INDEX_MISC
set itm = Items(i)
set j = itm.reqLevel/20
if GemDropList[j] == 0 then
set GemDropList[j] = IPool.create()
endif
if itm.dropWeight <= 0 then
call GemDropList[j].add(itm, DEFAULT_GEM_DROP_WEIGHT)
else
call GemDropList[j].add(itm, itm.dropWeight)
endif
set i = i + 1
endloop
// Populate ores & gemstone
set OreDropList = IPool.create()
set GemstoneDropList = IPool.create()
set i = ITEM_INDEX_MISC + 1
loop
exitwhen i > ITEM_INDEX_EQUIPMENT
set itm = Items(i)
if itm.strength == 1 then
call OreDropList.add(itm, IMaxBJ(OreTypeRarity[itm.fortitude] / itm.wisdom, 1))
else
call GemstoneDropList.add(itm, IMaxBJ(GemstoneTypeRarity[itm.strength] / itm.wisdom, 1))
endif
set i = i + 1
endloop
// Target level
set i = 1
loop
exitwhen i > 100
if (DropList[1][i] > 0) then
set TargetLevel[i] = i
set j = i + 1
loop
exitwhen j > 100 or DropList[1][j] > 0
set TargetLevel[j] = i
set j = j + 1
endloop
endif
set i = i + 1
endloop
call ReleaseTimer(GetExpiredTimer())
endfunction
private function init takes nothing returns nothing
local integer i
local integer j
local integer level
call TimerStart(NewTimer(), 0.0, false, function lateInit)
set PLAYER_COLOR_R[0] = 255
set PLAYER_COLOR_G[0] = 3
set PLAYER_COLOR_B[0] = 3
set PLAYER_COLOR_R[1] = 0
set PLAYER_COLOR_G[1] = 66
set PLAYER_COLOR_B[1] = 255
set PLAYER_COLOR_R[2] = 28
set PLAYER_COLOR_G[2] = 230
set PLAYER_COLOR_B[2] = 185
set PLAYER_COLOR_R[3] = 84
set PLAYER_COLOR_G[3] = 0
set PLAYER_COLOR_B[3] = 129
set CharacterLevelPower = (Pow(CHARACTER_LEVEL_POWER, MAXIMUM_LEVEL) - 1.)
set StatusValuePower = (Pow(STATUS_LEVEL_POWER, MAXIMUM_LEVEL) - 1.)
set StatsSetCount[2][Items.HEAD] = 10
set StatsSetCount[2][Items.CHEST] = 10
set StatsSetCount[2][Items.SHOULDER] = 10
set StatsSetCount[2][Items.ARM] = 10
set StatsSetCount[2][Items.LEGS] = 10
set StatsSetCount[2][Items.FEET] = 10
set StatsSetCount[2][Items.RIGHT_HAND] = 10
set StatsSetCount[2][Items.LEFT_HAND] = 10
set StatsSetCount[2][Items.RING] = 10
set StatsSetCount[2][Items.NECK] = 10
set StatsSetCount[3][Items.HEAD] = 5
set StatsSetCount[3][Items.CHEST] = 5
set StatsSetCount[3][Items.SHOULDER] = 5
set StatsSetCount[3][Items.ARM] = 5
set StatsSetCount[3][Items.LEGS] = 5
set StatsSetCount[3][Items.FEET] = 5
set StatsSetCount[3][Items.RIGHT_HAND] = 5
set StatsSetCount[3][Items.LEFT_HAND] = 5
set StatsSetCount[3][Items.RING] = 5
set StatsSetCount[3][Items.NECK] = 5
set RarityPool = IPool.create()
call RarityPool.add(1, 130)
call RarityPool.add(2, 50)
call RarityPool.add(3, 15)
call RarityPool.add(4, 4)
call RarityPool.add(5, 1)
set ItemQualityPool[0] = IPool.create()
call ItemQualityPool[0].add(0, 15)
call ItemQualityPool[0].add(1, 5)
set ItemQualityPool[1] = IPool.create()
call ItemQualityPool[1].add(0, 15)
call ItemQualityPool[1].add(1, 10)
call ItemQualityPool[1].add(2, 2)
set ItemQualityPool[2] = IPool.create()
call ItemQualityPool[2].add(0, 30)
call ItemQualityPool[2].add(1, 30)
call ItemQualityPool[2].add(2, 10)
call ItemQualityPool[2].add(3, 5)
call ItemQualityPool[3].add(4, 1)
set ItemQualityPool[3] = IPool.create()
call ItemQualityPool[3].add(0, 20)
call ItemQualityPool[3].add(1, 25)
call ItemQualityPool[3].add(2, 10)
call ItemQualityPool[3].add(3, 7)
call ItemQualityPool[3].add(4, 3)
set ItemLevelPool = IPool.create()
call ItemLevelPool.add(0, 10)
call ItemLevelPool.add(1, 9)
call ItemLevelPool.add(2, 8)
call ItemLevelPool.add(3, 7)
call ItemLevelPool.add(4, 5)
call ItemLevelPool.add(5, 3)
set ItemBonusLevelPool = IPool.create()
call ItemBonusLevelPool.add(-3, 1)
call ItemBonusLevelPool.add(-2, 1)
call ItemBonusLevelPool.add(-1, 2)
call ItemBonusLevelPool.add(0, 2)
call ItemBonusLevelPool.add(1, 3)
call ItemBonusLevelPool.add(2, 3)
call ItemBonusLevelPool.add(3, 4)
call ItemBonusLevelPool.add(4, 4)
call ItemBonusLevelPool.add(5, 5)
call ItemBonusLevelPool.add(6, 3)
call ItemBonusLevelPool.add(7, 2)
set QualityBonus[0] = 0.00
set QualityBonus[1] = 0.05
set QualityBonus[2] = 0.10
set QualityBonus[3] = 0.15
set QualityBonus[4] = 0.2
set SoulHarvestChance[0] = 0.10
set SoulHarvestChance[1] = 0.25
set SoulHarvestChance[2] = 0.25
set SoulHarvestChance[3] = 0.0
set DropChance[0] = 0.03
set DropChance[1] = 0.15
set DropChance[2] = 0.30
set DropChance[3] = 1.0
set GemDropChance[0] = 0.0
set GemDropChance[1] = 0.02
set GemDropChance[2] = 0.05
set GemDropChance[3] = 0.15
set PotionDropChance[0] = 0.01
set PotionDropChance[1] = 0.05
set PotionDropChance[2] = 0.33
set PotionDropChance[3] = 4.0
set GoldDropChance[0] = 0.0
set GoldDropChance[1] = 0.5
set GoldDropChance[2] = 1.0
set GoldDropChance[3] = 1.0
set GoldAmountBonus[0] = 0.0
set GoldAmountBonus[1] = 1.0
set GoldAmountBonus[2] = 2.0
set GoldAmountBonus[3] = 5.0
set OreDropChance[0] = 0.0
set OreDropChance[1] = 0.01
set OreDropChance[2] = 0.03
set OreDropChance[3] = 0.07
set GemstoneDropChance[0] = 0.0
set GemstoneDropChance[1] = 0.0
set GemstoneDropChance[2] = 0.02
set GemstoneDropChance[3] = 0.05
set OreTypeRarity[1] = 30
set OreTypeRarity[2] = 30
set OreTypeRarity[3] = 50
set OreTypeRarity[4] = 50
set GemstoneTypeRarity[2] = 30 // jade
set GemstoneTypeRarity[3] = 50 // quartz
set GemstoneTypeRarity[4] = 40 // crystal
set GemstoneTypeRarity[5] = 40 // topaz
set ScrollPriceTier[0] = 0
set ScrollPriceTier[1] = 30
set ScrollPriceTier[2] = 60
set ScrollPriceTier[3] = 90
set ScrollPriceTier[4] = 120
set ScrollPriceTier[5] = 150
set ScrollPriceTier[6] = 180
set SocketCountPool = IPool.create()
call SocketCountPool.add(0, 16)
call SocketCountPool.add(1, 14)
call SocketCountPool.add(2, 11)
call SocketCountPool.add(3, 7)
call SocketCountPool.add(4, 2)
set UpgradeOrePrice[1] = 25.0
set UpgradeOrePrice[2] = 50.0
set UpgradeOrePrice[3] = 100.0
set UpgradeOrePrice[4] = 150.0
set UpgradeGemstonePrice[1] = 5.0
set UpgradeGemstonePrice[2] = 10.0
set UpgradeGemstonePrice[3] = 25.0
set UpgradeGemstonePrice[4] = 40.0
set UpgradeImprovementBase[1] = 0.01
set UpgradeImprovementBase[2] = 0.02
set UpgradeImprovementBase[3] = 0.03
set UpgradeImprovementBase[4] = 0.04
set UpgradeValueIncrement[1] = 0.02
set UpgradeValueIncrement[2] = 0.04
set UpgradeValueIncrement[3] = 0.06
set UpgradeValueIncrement[4] = 0.08
set UpgradeQualityBonus[0] = 0.95
set UpgradeQualityBonus[1] = 1.0
set UpgradeQualityBonus[2] = 1.01
set UpgradeQualityBonus[3] = 1.02
set UpgradeQualityBonus[4] = 1.03
set UpgradeChanceBonus[1] = 1.05
set UpgradeChanceBonus[2] = 1.1
set UpgradeChanceBonus[3] = 1.15
set UpgradeChanceBonus[4] = 1.2
set UpgradeChanceBase[0] = 3.0
set UpgradeChanceBase[1] = 2.5
set UpgradeChanceBase[2] = 2.0
set UpgradeChanceBase[3] = 1.5
set UpgradeChanceBase[4] = 1.0
set UpgradeChanceBase[5] = 0.9
set UpgradeChanceBase[6] = 0.8
set UpgradeChanceBase[7] = 0.7
set UpgradeChanceBase[8] = 0.5
set UpgradeChanceBase[9] = 0.3
set UpgradeChanceBase[10] = 0.2
set UpgradeChanceBase[11] = 0.15
/*set UpgradeChanceBase[0] = 10.0
set UpgradeChanceBase[1] = 10.5
set UpgradeChanceBase[2] = 10.0
set UpgradeChanceBase[3] = 10.5
set UpgradeChanceBase[4] = 10.0
set UpgradeChanceBase[5] = 10.9
set UpgradeChanceBase[6] = 10.8
set UpgradeChanceBase[7] = 10.7
set UpgradeChanceBase[8] = 10.5
set UpgradeChanceBase[9] = 10.3
set UpgradeChanceBase[10] = 10.2
set UpgradeChanceBase[11] = 10.15*/
set UpgradeDestroyChance[0] = 0.0
set UpgradeDestroyChance[1] = 0.0
set UpgradeDestroyChance[2] = 0.0
set UpgradeDestroyChance[3] = 0.0
set UpgradeDestroyChance[4] = 0.0
set UpgradeDestroyChance[5] = 0.0
set UpgradeDestroyChance[6] = 0.05
set UpgradeDestroyChance[7] = 0.1
set UpgradeDestroyChance[8] = 0.15
set UpgradeDestroyChance[9] = 0.2
set UpgradeDestroyChance[10] = 0.25
set UpgradeDestroyChance[11] = 0.3
set UpgradeResetChance[0] = 0.0
set UpgradeResetChance[1] = 0.0
set UpgradeResetChance[2] = 0.0
set UpgradeResetChance[3] = 0.0
set UpgradeResetChance[4] = 0.0
set UpgradeResetChance[5] = 0.05
set UpgradeResetChance[6] = 0.1
set UpgradeResetChance[7] = 0.15
set UpgradeResetChance[8] = 0.2
set UpgradeResetChance[9] = 0.25
set UpgradeResetChance[10] = 0.3
set UpgradeResetChance[11] = 0.35
set UpgradeDowngradeChance[0] = 0.0
set UpgradeDowngradeChance[1] = 0.0
set UpgradeDowngradeChance[2] = 0.0
set UpgradeDowngradeChance[3] = 0.0
set UpgradeDowngradeChance[4] = 0.1
set UpgradeDowngradeChance[5] = 0.2
set UpgradeDowngradeChance[6] = 0.3
set UpgradeDowngradeChance[7] = 0.4
set UpgradeDowngradeChance[8] = 0.5
set UpgradeDowngradeChance[9] = 0.6
set UpgradeDowngradeChance[10] = 0.7
set UpgradeDowngradeChance[11] = 0.8
set MasteryGrowthTime[1] = 60.0
set MasteryGrowthTime[2] = 120.0
set MasteryGrowthTime[3] = 240.0
set MasteryGrowthTime[4] = 480.0
set MasteryGrowthTime[5] = 780.0
set MasteryGrowthTime[6] = 1380.0
set MasteryGrowthTime[7] = 1980.0
set MasteryGrowthTime[8] = 2280.0
set MasteryGrowthTime[9] = 2880.0
set MasteryGrowthTime[10] = 3480.0
set MasteryGrowthTime[11] = 4380.0
set MasteryGrowthTime[12] = 5280.0
set MasteryGrowthTime[13] = 6180.0
set MasteryGrowthTime[14] = 7080.0
set MasteryGrowthTime[15] = 7980.0
set MasteryGrowthRate[1] = 100.0
set MasteryGrowthRate[2] = 95.0
set MasteryGrowthRate[3] = 90.0
set MasteryGrowthRate[4] = 82.5
set MasteryGrowthRate[5] = 75.0
set QualityValueFactor[0] = 0.9
set QualityValueFactor[1] = 1.0
set QualityValueFactor[2] = 1.1
set QualityValueFactor[3] = 1.25
set QualityValueFactor[4] = 1.5
set SocketCountValueFactor[0] = 1.0
set SocketCountValueFactor[1] = 1.05
set SocketCountValueFactor[2] = 1.1
set SocketCountValueFactor[3] = 1.2
set SocketCountValueFactor[4] = 1.3
set SocketCountRandomizer[1] = IPool.create()
call SocketCountRandomizer[1].add(0, 100)
call SocketCountRandomizer[1].add(1, 50)
set SocketCountRandomizer[2] = IPool.create()
call SocketCountRandomizer[2].add(0, 100)
call SocketCountRandomizer[2].add(1, 50)
call SocketCountRandomizer[2].add(2, 25)
set SocketCountRandomizer[3] = IPool.create()
call SocketCountRandomizer[3].add(0, 100)
call SocketCountRandomizer[3].add(1, 50)
call SocketCountRandomizer[3].add(2, 25)
call SocketCountRandomizer[3].add(3, 12)
set SocketCountRandomizer[4] = IPool.create()
call SocketCountRandomizer[4].add(0, 100)
call SocketCountRandomizer[4].add(1, 50)
call SocketCountRandomizer[4].add(2, 25)
call SocketCountRandomizer[4].add(3, 12)
call SocketCountRandomizer[4].add(4, 5)
set QualityNames[0] = "Low"
set QualityNames[1] = "Normal"
set QualityNames[2] = "High"
set QualityNames[3] = "Superior"
set QualityNames[4] = "Mastercraft"
set RarityNames[0] = "Unknown"
set RarityNames[1] = "Common"
set RarityNames[2] = "Unique"
//set RarityNames[3] = "Rare"
set RarityNames[3] = "Rare"
set RarityNames[4] = "Ancient"
set RarityNames[5] = "Legendary"
set RarityNames[6] = "Premium"
set RarityColor[0] = "|cff000000"
set RarityColor[1] = "|cffcccccc"
set RarityColor[2] = "|cff00ff5a"
//set RarityColor[3] = "|cff004cbd"
set RarityColor[3] = "|cff4e00ff"
set RarityColor[4] = "|cffff7800"
set RarityColor[5] = "|cffff0000"
set RarityColor[6] = "|cffffd700"
set RarityColorR[0] = 0
set RarityColorR[1] = 255
set RarityColorR[2] = 0
//set RarityColorR[3] = 0
set RarityColorR[3] = 78
set RarityColorR[4] = 255
set RarityColorR[5] = 255
set RarityColorR[6] = 255
set RarityColorG[0] = 0
set RarityColorG[1] = 255
set RarityColorG[2] = 255
//set RarityColorG[3] = 76
set RarityColorG[3] = 0
set RarityColorG[4] = 120
set RarityColorG[5] = 5
set RarityColorG[6] = 255
set RarityColorB[0] = 0
set RarityColorB[1] = 255
set RarityColorB[2] = 90
//set RarityColorB[3] = 189
set RarityColorB[3] = 255
set RarityColorB[4] = 0
set RarityColorB[5] = 0
set RarityColorB[6] = 0
set CategoryNames[Items.HEAD] = "Head"
set CategoryNames[Items.CHEST] = "Chest"
set CategoryNames[Items.LEGS] = "Legs"
set CategoryNames[Items.FEET] = "Feet"
set CategoryNames[Items.NECK] = "Necklace"
set CategoryNames[Items.SHOULDER] = "Shoulder"
set CategoryNames[Items.ARM] = "Arm"
set CategoryNames[Items.RING] = "Ring"
set DungeonSizeNames[0] = "Tiny"
set DungeonSizeNames[1] = "Small"
set DungeonSizeNames[2] = "Medium"
set DungeonSizeNames[3] = "Large"
set DungeonSizeNames[4] = "Huge"
set DungeonSizeNames[5] = "Epic"
set SkillClassNames[PlayerSkill.ACTIVE] = "Active"
set SkillClassNames[PlayerSkill.BUFF] = "Buff"
set SkillClassNames[PlayerSkill.PASSIVE] = "Passive"
set SkillClassNames[PlayerSkill.FUNCTION] = "Control"
set CreepRankColor[0] = "|cffcccccc"
set CreepRankColor[1] = "|cff21c08a"
set CreepRankColor[2] = "|cff4c1eb3"
set CreepRankColor[3] = "|cffec1346"
set PassiveSkillLevelReq[0][1] = 1
set PassiveSkillLevelReq[0][2] = 5
set PassiveSkillLevelReq[0][3] = 10
set PassiveSkillLevelReq[0][4] = 20
set PassiveSkillLevelReq[0][5] = 35
set PassiveSkillLevelReq[0][6] = 35
set PassiveSkillLevelReq[1][1] = 7
set PassiveSkillLevelReq[1][2] = 15
set PassiveSkillLevelReq[1][3] = 25
set PassiveSkillLevelReq[1][4] = 40
set PassiveSkillLevelReq[1][5] = 55
set PassiveSkillLevelReq[1][6] = 55
set PassiveSkillLevelReq[2][1] = 15
set PassiveSkillLevelReq[2][2] = 25
set PassiveSkillLevelReq[2][3] = 40
set PassiveSkillLevelReq[2][4] = 55
set PassiveSkillLevelReq[2][5] = 75
set PassiveSkillLevelReq[2][6] = 75
endfunction
endlibrary
scope SoundLib initializer init
globals
RSound array SwingSounds
RSound array CriticalHit
RSound array BlockSfx
RSound PickUpItemSfx
RSound GateBirthSound
RSound GateDeathSound
RSound QuestStartSound
RSound UpgradeSuccessSound
RSound UpgradeFailedSound
RSound ItemTemperSound
RSound ItemSocketSound
RSound ItemBuySound
RSound InventorySwapSound
RSound InventoryDropSound
RSound InventorySellSound
RSound TooltipsDisplaySound
RSound SkillLearnSound
RSound KoboldNestDeathSound
endglobals
private function init takes nothing returns nothing
set SwingSounds[0] = RSound.create("war3mapImported\\swing1.wav", true, true, 12700, 12700)
set SwingSounds[1] = RSound.create("war3mapImported\\swing2.wav", true, true, 12700, 12700)
set SwingSounds[2] = RSound.create("war3mapImported\\swing3.wav", true, true, 12700, 12700)
set BlockSfx[0] = RSound.create("Sound\\Units\\Combat\\MetalLightChopMetal1.wav", true, true, 12700, 12700)
set BlockSfx[1] = RSound.create("Sound\\Units\\Combat\\MetalLightChopMetal2.wav", true, true, 12700, 12700)
set BlockSfx[2] = RSound.create("Sound\\Units\\Combat\\MetalLightChopMetal3.wav", true, true, 12700, 12700)
set CriticalHit[0] = RSound.create("war3mapImported\\crit1.wav", true, true, 12700, 12700)
set CriticalHit[1] = RSound.create("war3mapImported\\crit2.wav", true, true, 12700, 12700)
set CriticalHit[2] = RSound.create("war3mapImported\\crit3.wav", true, true, 12700, 12700)
set PickUpItemSfx = RSound.create("Sound\\Interface\\PickUpItem.wav", false, true, 12700, 12700)
set QuestStartSound = RSound.create("Sound\\Interface\\Rescue.wav", false, false, 12700, 12700)
set GateDeathSound = RSound.create("Sound\\Interface\\BattlenetDeath1.wav", false, false, 12700, 12700)
set GateBirthSound = RSound.create("Abilities\\Spells\\Human\\Banish\\BanishCaster.wav", false, false, 12700, 12700)
set ItemTemperSound = RSound.create("Sound\\Interface\\BattleNetDoorsStereo2.wav", false, false, 12700, 12700)
set UpgradeSuccessSound = RSound.create("Sound\\Interface\\GoodJob.wav", false, false, 12700, 12700)
set UpgradeFailedSound = RSound.create("Sound\\Interface\\QuestFailed.wav", false, false, 12700, 12700)
set ItemSocketSound = RSound.create("Sound\\Interface\\ItemReceived.wav", false, false, 12700, 12700)
set ItemBuySound = RSound.create("Abilities\\Spells\\Items\\ResourceItems\\ReceiveGold.wav", false, false, 12700, 12700)
set InventorySwapSound = RSound.create("Sound\\Interface\\OverViewSelectionChange1.wav", false, false, 12700, 12700)
set InventoryDropSound = RSound.create("Sound\\Interface\\HeroDropItem1.wav", false, false, 12700, 12700)
set InventorySellSound = RSound.create("Abilities\\Spells\\Items\\ResourceItems\\ReceiveGold.wav", false, false, 12700, 12700)
set TooltipsDisplaySound = RSound.create("Sound\\Interface\\WayPointBling.wav", false, false, 12700, 12700)
set SkillLearnSound = RSound.create("Sound\\Interface\\QuestLog.wav", false, false, 12700, 12700)
set KoboldNestDeathSound = RSound.create("Abilities\\Spells\\Items\\ResourceItems\\BundleOfLumber.wav", true, false, 12700, 12700)
endfunction
endscope
library InteriorPortal
globals
boolean array InDoor
private Table BonusTable
public CustomText array Texts
public integer Count = 0
endglobals
function RefreshPortalText takes nothing returns nothing
local integer i = 0
loop
exitwhen i > Count
call Texts[i].refresh()
set i = i + 1
endloop
endfunction
function RefreshNPCText takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= NPCNameTagCount
call NPCNameTag[i].refresh()
set i = i + 1
endloop
endfunction
function RefreshItemNames takes nothing returns nothing
local group g = CreateGroup()
local unit fog
loop
set fog = FirstOfGroup(ItemObject.AllItem)
exitwhen fog == null
call GroupRemoveUnit(ItemObject.AllItem, fog)
call GroupAddUnit(g, fog)
call ItemObject[fog].nameTag.refresh()
endloop
call DestroyGroup(ItemObject.AllItem)
set ItemObject.AllItem = g
set g = null
endfunction
function RelocateSubordinates takes unit u returns nothing
local Combatant c = Combatant[u]
local group gr
local unit fog
local real a = GetRandomReal(-bj_PI, bj_PI)
local real x = GetUnitX(u) + 128 * Cos(a)
local real y = GetUnitY(u) + 128 * Sin(a)
set gr = CreateGroup()
loop
set fog = FirstOfGroup(c.subordinate)
exitwhen fog == null
call GroupRemoveUnit(c.subordinate, fog)
call GroupAddUnit(gr, fog)
call SetUnitPosition(fog, x, y)
//call SetUnitX(fog, x)
//call SetUnitY(fog, y)
endloop
call DestroyGroup(c.subordinate)
set c.subordinate = gr
set gr = null
endfunction
private function ScaleUp takes unit u, integer uid returns nothing
local real factor = 1.35
if uid == 'h004' then
call SetUnitScale(u, 1.1*factor, 1.1*factor, 1.1*factor)
elseif uid == 'h00C' then
call SetUnitScale(u, 0.6*factor, 0.6*factor, 0.6*factor)
endif
set BonusTable.real[GetHandleId(u)] = GetUnitMoveSpeed(u)*(factor-1.)
call SetUnitMoveSpeed(u, GetUnitMoveSpeed(u)+BonusTable.real[GetHandleId(u)])
set InDoor[GetPlayerId(GetOwningPlayer(u))] = true
endfunction
private function ScaleDown takes unit u, integer uid returns nothing
if uid == 'h004' then
call SetUnitScale(u, 1.1, 1.1, 1.1)
elseif uid == 'h00C' then
call SetUnitScale(u, 0.6, 0.6, 0.6)
endif
call SetUnitMoveSpeed(u, GetUnitMoveSpeed(u)-BonusTable.real[GetHandleId(u)])
set InDoor[GetPlayerId(GetOwningPlayer(u))] = false
endfunction
private function Shop1Enter takes nothing returns boolean
local unit u = GetTriggerUnit()
if IsUnitInGroup(u, MainGroup) then
call ScaleUp(u, GetUnitTypeId(u))
//call SetTerrainFogEx(0,0,100000,0,0,0,0)
call IssueImmediateOrder(u, "stop")
call ShowUnit(u, false)
call SetUnitPosition(u, GetRectCenterX(gg_rct_ExitShop1), GetRectCenterY(gg_rct_ExitShop1)+100)
call RelocateSubordinates(u)
call ShowUnit(u, true)
//set CamRot = 90.0
endif
set u = null
return false
endfunction
private function Shop1Exit takes nothing returns boolean
local unit u = GetTriggerUnit()
if IsUnitInGroup(u, MainGroup) then
call ScaleDown(u, GetUnitTypeId(u))
//call SetTerrainFogEx(0,0,7500,0.5,45./255.,45./255.,45./255.)
call IssueImmediateOrder(u, "stop")
call ShowUnit(u, false)
call SetUnitPosition(u, GetRectCenterX(gg_rct_EnterShop1)+100, GetRectCenterY(gg_rct_EnterShop1))
call RelocateSubordinates(u)
call ShowUnit(u, true)
//set CamRot = 163.97
endif
set u = null
return false
endfunction
private function Shop2Enter takes nothing returns boolean
local unit u = GetTriggerUnit()
if IsUnitInGroup(u, MainGroup) then
call ScaleUp(u, GetUnitTypeId(u))
//call SetTerrainFogEx(0,0,100000,0,0,0,0)
call IssueImmediateOrder(u, "stop")
call ShowUnit(u, false)
call SetUnitPosition(u, GetRectCenterX(gg_rct_ExitShop2), GetRectCenterY(gg_rct_ExitShop2)+100)
call RelocateSubordinates(u)
call ShowUnit(u, true)
//set CamRot = 90.0
endif
set u = null
return false
endfunction
private function Shop2Exit takes nothing returns boolean
local unit u = GetTriggerUnit()
if IsUnitInGroup(u, MainGroup) then
call ScaleDown(u, GetUnitTypeId(u))
//call SetTerrainFogEx(0,0,7500,0.5,45./255.,45./255.,45./255.)
call IssueImmediateOrder(u, "stop")
call ShowUnit(u, false)
call SetUnitPosition(u, GetRectCenterX(gg_rct_EnterShop2)+100, GetRectCenterY(gg_rct_EnterShop2)-100)
call RelocateSubordinates(u)
call ShowUnit(u, true)
//set CamRot = 163.97
endif
set u = null
return false
endfunction
function InitTrig_Doors takes nothing returns nothing
set BonusTable = Table.create()
set gg_trg_Doors = CreateTrigger()
call TriggerRegisterEnterRectSimple(gg_trg_Doors, gg_rct_EnterShop1)
call TriggerAddCondition(gg_trg_Doors, Condition(function Shop1Enter))
set gg_trg_Doors = CreateTrigger()
call TriggerRegisterEnterRectSimple(gg_trg_Doors, gg_rct_ExitShop1)
call TriggerAddCondition(gg_trg_Doors, Condition(function Shop1Exit))
set gg_trg_Doors = CreateTrigger()
call TriggerRegisterEnterRectSimple(gg_trg_Doors, gg_rct_EnterShop2)
call TriggerAddCondition(gg_trg_Doors, Condition(function Shop2Enter))
set gg_trg_Doors = CreateTrigger()
call TriggerRegisterEnterRectSimple(gg_trg_Doors, gg_rct_ExitShop2)
call TriggerAddCondition(gg_trg_Doors, Condition(function Shop2Exit))
set Texts[0] = CustomText.create("Go to The Pub", GetRectCenterX(gg_rct_EnterShop1), GetRectCenterY(gg_rct_EnterShop1), 128., ITEM_NAMETAG_SIZE, 0.5)
set Texts[1] = CustomText.create("Go to Town", GetRectCenterX(gg_rct_ExitShop1), GetRectCenterY(gg_rct_ExitShop1), 128., ITEM_NAMETAG_SIZE, 0.5)
set Texts[2] = CustomText.create("Go to Arsenal", GetRectCenterX(gg_rct_EnterShop2), GetRectCenterY(gg_rct_EnterShop2), 128., ITEM_NAMETAG_SIZE, 0.5)
set Texts[3] = CustomText.create("Go to Town", GetRectCenterX(gg_rct_ExitShop2), GetRectCenterY(gg_rct_ExitShop2), 128., ITEM_NAMETAG_SIZE, 0.5)
call Texts[0].setColor(PORTAL_TAG_COLOR_R, PORTAL_TAG_COLOR_G, PORTAL_TAG_COLOR_B, 255)
call Texts[1].setColor(PORTAL_TAG_COLOR_R, PORTAL_TAG_COLOR_G, PORTAL_TAG_COLOR_B, 255)
call Texts[2].setColor(PORTAL_TAG_COLOR_R, PORTAL_TAG_COLOR_G, PORTAL_TAG_COLOR_B, 255)
call Texts[3].setColor(PORTAL_TAG_COLOR_R, PORTAL_TAG_COLOR_G, PORTAL_TAG_COLOR_B, 255)
set Count = 3
endfunction
endlibrary
library PlayerInit uses CharacterWindow, ShortcutBar
globals
integer array PLAYER_COLOR_R
integer array PLAYER_COLOR_G
integer array PLAYER_COLOR_B
boolean array CreateNew
string array CharacterName
integer InitPlayerId = 0
timer array ReminderTimer
group PlayerUnits = CreateGroup()
group AllUnits = CreateGroup()
group CreepUnits = CreateGroup()
endglobals
public function remind takes nothing returns nothing
local integer id = GetTimerData(GetExpiredTimer())
if not GeneratingDungeon then
call DisplayTimedTextToPlayer(Player(id), 0, 0, 5, "Warning! You haven't saved your character for more than 5 minutes!")
call TimerStart(ReminderTimer[id], 120, false, function remind)
else
call TimerStart(ReminderTimer[id], 15, false, function remind)
endif
endfunction
function ResetPetStats takes integer uid, integer id returns nothing
if uid == 'h028' then // Dog
set PetFighter[id].melee = true
set PetFighter[id].missileHoming = false
set PetFighter[id].missilePiercing = false
set PetFighter[id].missile = ""
set PetFighter[id].missileCollision = 0.0
set PetFighter[id].missileScale = 0.0
set PetFighter[id].missileSpeed = 0.0
set PetFighter[id].missileArch = 0
set PetFighter[id].missileTurn = 0
set PetFighter[id].missileXY = 0
set PetFighter[id].missileZ = 0
set PetFighter[id].dmgAoE = 0
set PetFighter[id].attackRadius = 5.0*bj_DEGTORAD
set PetFighter[id].attackRange = 160.0
set PetFighter[id].dmgPoint = 0.5
set PetFighter[id].attackRateDef = 1.9
set PetFighter[id].physicDmgMin = 2
set PetFighter[id].physicDmgMax = 4
set PetFighter[id].physicDefense = 6.
set PetFighter[id].magicDmgMin = 0
set PetFighter[id].magicDmgMax = 0
set PetFighter[id].magicDefense = 3.
set PetFighter[id].criticalRate = 0.05
set PetFighter[id].criticalPower = 0.5
set PetFighter[id].blockRate = 0.0
set PetFighter[id].evasionRate = 0.0
set PetFighter[id].knockback = 0.0
set PetFighter[id].knockbackResist = 0.0
set PetFighter[id].interrupt = 0.0
set PetFighter[id].interruptResist = 0.0
set PetFighter[id].stun = 0.0
set PetFighter[id].stunResist = 0.0
set PetFighter[id].hpMax = 300
set PetFighter[id].hpRegen = 0.0
set PetFighter[id].spMax = 0
set PetFighter[id].spRegen = 0.0
set PetFighter[id].wType = WEAPON_TYPE_METAL_LIGHT_CHOP
elseif uid == 'h029' then // Crab
set PetFighter[id].melee = true
set PetFighter[id].missileHoming = false
set PetFighter[id].missilePiercing = false
set PetFighter[id].missile = ""
set PetFighter[id].missileCollision = 0.0
set PetFighter[id].missileScale = 0.0
set PetFighter[id].missileSpeed = 0.0
set PetFighter[id].missileArch = 0
set PetFighter[id].missileTurn = 0
set PetFighter[id].missileXY = 0
set PetFighter[id].missileZ = 0
set PetFighter[id].dmgAoE = 0
set PetFighter[id].attackRadius = 5.0*bj_DEGTORAD
set PetFighter[id].attackRange = 160.0
set PetFighter[id].dmgPoint = 0.5
set PetFighter[id].attackRateDef = 2.3
set PetFighter[id].physicDmgMin = 1
set PetFighter[id].physicDmgMax = 2
set PetFighter[id].physicDefense = 8.
set PetFighter[id].magicDmgMin = 0
set PetFighter[id].magicDmgMax = 0
set PetFighter[id].magicDefense = 3
set PetFighter[id].criticalRate = 0.05
set PetFighter[id].criticalPower = 0.5
set PetFighter[id].blockRate = 0.10
set PetFighter[id].evasionRate = 0.0
set PetFighter[id].knockback = 0.0
set PetFighter[id].knockbackResist = 10.0
set PetFighter[id].interrupt = 0.0
set PetFighter[id].interruptResist = 0.15
set PetFighter[id].stun = 0.0
set PetFighter[id].stunResist = 0.15
set PetFighter[id].hpMax = 325
set PetFighter[id].hpRegen = 0.0
set PetFighter[id].spMax = 0
set PetFighter[id].spRegen = 0.0
set PetFighter[id].wType = WEAPON_TYPE_METAL_MEDIUM_CHOP
elseif uid == 'h02B' then // Boar
set PetFighter[id].melee = true
set PetFighter[id].missileHoming = false
set PetFighter[id].missilePiercing = false
set PetFighter[id].missile = ""
set PetFighter[id].missileCollision = 0.0
set PetFighter[id].missileScale = 0.0
set PetFighter[id].missileSpeed = 0.0
set PetFighter[id].missileArch = 0
set PetFighter[id].missileTurn = 0
set PetFighter[id].missileXY = 0
set PetFighter[id].missileZ = 0
set PetFighter[id].dmgAoE = 0
set PetFighter[id].attackRadius = 60.0*bj_DEGTORAD
set PetFighter[id].attackRange = 160.0
set PetFighter[id].dmgPoint = 0.5
set PetFighter[id].attackRateDef = 2.5
set PetFighter[id].physicDmgMin = 2
set PetFighter[id].physicDmgMax = 4
set PetFighter[id].physicDefense = 6.
set PetFighter[id].magicDmgMin = 0
set PetFighter[id].magicDmgMax = 0
set PetFighter[id].magicDefense = 4
set PetFighter[id].criticalRate = 0.05
set PetFighter[id].criticalPower = 0.5
set PetFighter[id].blockRate = 0.0
set PetFighter[id].evasionRate = 0.0
set PetFighter[id].knockback = 0.0
set PetFighter[id].knockbackResist = 40.0
set PetFighter[id].interrupt = 0.0
set PetFighter[id].interruptResist = 0.0
set PetFighter[id].stun = 0.0
set PetFighter[id].stunResist = 0.05
set PetFighter[id].hpMax = 340
set PetFighter[id].hpRegen = 0.0
set PetFighter[id].spMax = 0
set PetFighter[id].spRegen = 0.0
set PetFighter[id].wType = WEAPON_TYPE_WOOD_MEDIUM_BASH
elseif uid == 'h02D' then // Viper
set PetFighter[id].melee = true
set PetFighter[id].missileHoming = false
set PetFighter[id].missilePiercing = false
set PetFighter[id].missile = ""
set PetFighter[id].missileCollision = 0.0
set PetFighter[id].missileScale = 0.0
set PetFighter[id].missileSpeed = 0.0
set PetFighter[id].missileArch = 0
set PetFighter[id].missileTurn = 0
set PetFighter[id].missileXY = 0
set PetFighter[id].missileZ = 0
set PetFighter[id].dmgAoE = 0
set PetFighter[id].attackRadius = 5.0*bj_DEGTORAD
set PetFighter[id].attackRange = 160.0
set PetFighter[id].dmgPoint = 0.5
set PetFighter[id].attackRateDef = 1.85
set PetFighter[id].physicDmgMin = 3
set PetFighter[id].physicDmgMax = 5
set PetFighter[id].physicDefense = 4.
set PetFighter[id].magicDmgMin = 0
set PetFighter[id].magicDmgMax = 0
set PetFighter[id].magicDefense = 2.
set PetFighter[id].criticalRate = 0.05
set PetFighter[id].criticalPower = 0.5
set PetFighter[id].blockRate = 0.0
set PetFighter[id].evasionRate = 0.0
set PetFighter[id].knockback = 0.0
set PetFighter[id].knockbackResist = 0.0
set PetFighter[id].interrupt = 0.0
set PetFighter[id].interruptResist = 0.0
set PetFighter[id].stun = 0.0
set PetFighter[id].stunResist = 0.0
set PetFighter[id].hpMax = 290
set PetFighter[id].hpRegen = 0.0
set PetFighter[id].spMax = 0
set PetFighter[id].spRegen = 0.0
set PetFighter[id].wType = WEAPON_TYPE_METAL_LIGHT_CHOP
call PetFighter[id].applyBuff(13, 0, null)
elseif uid == 'h02A' then // Deer
set PetFighter[id].melee = true
set PetFighter[id].missileHoming = false
set PetFighter[id].missilePiercing = false
set PetFighter[id].missile = ""
set PetFighter[id].missileCollision = 0.0
set PetFighter[id].missileScale = 0.0
set PetFighter[id].missileSpeed = 0.0
set PetFighter[id].missileArch = 0
set PetFighter[id].missileTurn = 0
set PetFighter[id].missileXY = 0
set PetFighter[id].missileZ = 0
set PetFighter[id].dmgAoE = 0
set PetFighter[id].attackRadius = 5.0*bj_DEGTORAD
set PetFighter[id].attackRange = 160.0
set PetFighter[id].dmgPoint = 0.5
set PetFighter[id].attackRateDef = 2.1
set PetFighter[id].physicDmgMin = 2
set PetFighter[id].physicDmgMax = 4
set PetFighter[id].physicDefense = 6.
set PetFighter[id].magicDmgMin = 0
set PetFighter[id].magicDmgMax = 0
set PetFighter[id].magicDefense = 5.
set PetFighter[id].criticalRate = 0.05
set PetFighter[id].criticalPower = 0.5
set PetFighter[id].blockRate = 0.0
set PetFighter[id].evasionRate = 0.15
set PetFighter[id].knockback = 0.0
set PetFighter[id].knockbackResist = 0.0
set PetFighter[id].interrupt = 0.0
set PetFighter[id].interruptResist = 0.0
set PetFighter[id].stun = 0.0
set PetFighter[id].stunResist = 0.0
set PetFighter[id].hpMax = 310
set PetFighter[id].hpRegen = 0.0
set PetFighter[id].spMax = 0
set PetFighter[id].spRegen = 0.0
set PetFighter[id].wType = WEAPON_TYPE_WOOD_MEDIUM_BASH
elseif uid == 'h02C' then // Hawk
set PetFighter[id].melee = true
set PetFighter[id].missileHoming = false
set PetFighter[id].missilePiercing = false
set PetFighter[id].missile = ""
set PetFighter[id].missileCollision = 0.0
set PetFighter[id].missileScale = 0.0
set PetFighter[id].missileSpeed = 0.0
set PetFighter[id].missileArch = 0
set PetFighter[id].missileTurn = 0
set PetFighter[id].missileXY = 0
set PetFighter[id].missileZ = 0
set PetFighter[id].dmgAoE = 0
set PetFighter[id].attackRadius = 5.0*bj_DEGTORAD
set PetFighter[id].attackRange = 160.0
set PetFighter[id].dmgPoint = 0.5
set PetFighter[id].attackRateDef = 1.9
set PetFighter[id].physicDmgMin = 3
set PetFighter[id].physicDmgMax = 6
set PetFighter[id].physicDefense = 3.
set PetFighter[id].magicDmgMin = 0
set PetFighter[id].magicDmgMax = 0
set PetFighter[id].magicDefense = 3.
set PetFighter[id].criticalRate = 0.15
set PetFighter[id].criticalPower = 0.5
set PetFighter[id].blockRate = 0.0
set PetFighter[id].evasionRate = 0.0
set PetFighter[id].knockback = 0.0
set PetFighter[id].knockbackResist = 0.0
set PetFighter[id].interrupt = 0.0
set PetFighter[id].interruptResist = 0.0
set PetFighter[id].stun = 0.0
set PetFighter[id].stunResist = 0.0
set PetFighter[id].hpMax = 290
set PetFighter[id].hpRegen = 0.0
set PetFighter[id].spMax = 0
set PetFighter[id].spRegen = 0.0
set PetFighter[id].wType = WEAPON_TYPE_METAL_LIGHT_CHOP
elseif uid == 'h02E' then // Elk
set PetFighter[id].melee = true
set PetFighter[id].missileHoming = false
set PetFighter[id].missilePiercing = false
set PetFighter[id].missile = ""
set PetFighter[id].missileCollision = 0.0
set PetFighter[id].missileScale = 0.0
set PetFighter[id].missileSpeed = 0.0
set PetFighter[id].missileArch = 0
set PetFighter[id].missileTurn = 0
set PetFighter[id].missileXY = 0
set PetFighter[id].missileZ = 0
set PetFighter[id].dmgAoE = 0
set PetFighter[id].attackRadius = 5.0*bj_DEGTORAD
set PetFighter[id].attackRange = 160.0
set PetFighter[id].dmgPoint = 0.5
set PetFighter[id].attackRateDef = 2.0
set PetFighter[id].physicDmgMin = 2
set PetFighter[id].physicDmgMax = 4
set PetFighter[id].physicDefense = 5.
set PetFighter[id].magicDmgMin = 0
set PetFighter[id].magicDmgMax = 0
set PetFighter[id].magicDefense = 6.
set PetFighter[id].criticalRate = 0.05
set PetFighter[id].criticalPower = 0.5
set PetFighter[id].blockRate = 0.0
set PetFighter[id].evasionRate = 0.0
set PetFighter[id].knockback = 0.0
set PetFighter[id].knockbackResist = 0.0
set PetFighter[id].interrupt = 0.0
set PetFighter[id].interruptResist = 0.0
set PetFighter[id].stun = 0.0
set PetFighter[id].stunResist = 0.0
set PetFighter[id].hpMax = 320
set PetFighter[id].hpRegen = 0.0
set PetFighter[id].spMax = 0
set PetFighter[id].spRegen = 0.0
set PetFighter[id].wType = WEAPON_TYPE_WOOD_MEDIUM_BASH
endif
endfunction
private function InitPet takes nothing returns nothing
local player p = GetEnumPlayer()
local integer id = GetPlayerId(p)
local unit u = Pet[id]
local integer uid = GetUnitTypeId(u)
local CompanionAI ai
set PetFighter[id] = Combatant.create(u)
set PetFighter[id].noRemove = true
//call AddSpecialEffectTarget("war3mapImported\\LightOrangeLt60.mdx", u, "origin")
call ResetPetStats(uid, id)
set PetFighter[id].hp = PetFighter[id].hpMax
set PetFighter[id].sp = PetFighter[id].spMax
set PetFighter[id].attackRate = PetFighter[id].attackRateDef
set PetFighter[id].level = 1
set ai = CompanionAI.create(Fighter[id], PetFighter[id])
set ai.id = 0
call GroupAddUnit(PlayerUnits, u)
call UnitAddAbility(u, 'Aloc')
call UnitRemoveAbility(u, 'Aloc')
call ShowUnit(u, false)
call ShowUnit(u, true)
call UnitAddAbility(u, 'Amrf')
call UnitRemoveAbility(u, 'Amrf')
call UnitAddAbility(u, 'Aeth')
call SetUnitPathing(u, false)
call SetUnitPosition(u, CREATE_X, CREATE_Y)
endfunction
private function InitMain takes nothing returns nothing
local player p = GetEnumPlayer()
local integer id = GetPlayerId(p)
local unit u = MainUnit[id]
local integer uid = GetUnitTypeId(u)
local string s
local real x
local real y
local integer i
local ItemObject obj
call ClassSelection_UI_LoadEntry[id].destroy()
call ClassSelection_UI_LoadControl[id].destroy()
call ClassSelection_UI_Selection[id].destroy()
call ClassSelection_UI_Header[id].destroy()
call ClassSelection_UI_Control[id].destroy()
call MainMenu_MainPanel[id].destroy()
set CameraShaker_Intensity[id] = 1.0
set CameraOn[id] = true
call GroupAddUnit(MainGroup, u)
call GroupAddUnit(PlayerUnits, u)
call AddSpecialEffectTarget("war3mapImported\\LightOrangeLt60.mdx", u, "origin")
call RefreshPortalText()
set ReminderTimer[id] = NewTimerEx(id)
call TimerStart(ReminderTimer[id], 300, false, function remind)
set PlayerNameTag[id] = CustomText.create(CharacterName[id], 0, 0, 200, 0.5, 0.5)
call PlayerNameTag[id].setColor(69, 65, 229, 255)
call PlayerNameTag[id].show(Locale != p)
set Level[id] = 1
set EXPTarget[id] = EXP_BASE
set Tooltips1[id] = Tooltips.create(id)
set Tooltips1[id].playSound = true
set Tooltips2[id] = Tooltips.create(id)
set Tooltips2[id].header.texture = 'B04B'
call CharacterWindow_Create(id)
set ShopUI[id] = Shop.create(u)
call ShopUI[id].show(false)
call ShortcutBar_Create(id)
set Bag[id] = Inventory.create(u)
call Bag[id].show(false)
call StatusBox.create(p)
call XPBar_Create(id)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, 500)
set Fighter[id] = Combatant.create(u)
set x = -590.0
set TeamBars[id] = Panel.create(p, 0, 0, 0, 0, 0)
set TeamBarHPTexture[id] = 'TB00'
set TeamBarMPTexture[id] = 'TB00'
set i = 0
loop
exitwhen i > 3
if i != id and IsPlaying[i] then//
call TeamBar.create(TeamBars[id], i, x)
set x = x + 87
endif
set i = i + 1
endloop
call TeamBars[i].show(true)
call TeamBars[i].refresh()
set Fighter[id].noRemove = true
if uid == 'h004' then
set Fighter[id].melee = true
set Fighter[id].missileHoming = false
set Fighter[id].missilePiercing = false
set Fighter[id].missile = ""
set Fighter[id].missileCollision = 0.0
set Fighter[id].missileScale = 0.0
set Fighter[id].missileSpeed = 0.0
set Fighter[id].missileArch = 0
set Fighter[id].missileTurn = 0
set Fighter[id].missileXY = 0
set Fighter[id].missileZ = 0
set Fighter[id].dmgAoE = 0
set Fighter[id].attackRadius = 40.0*bj_DEGTORAD
set Fighter[id].attackRange = 160.0
set Fighter[id].dmgPoint = 0.5
set Fighter[id].attackRateDef = 1.15
set Fighter[id].physicDmgMin = 7
set Fighter[id].physicDmgMax = 12
set Fighter[id].physicDefense = 4.
set Fighter[id].magicDmgMin = 0
set Fighter[id].magicDmgMax = 0
set Fighter[id].magicDefense = 2.
set Fighter[id].criticalRate = 0.0
set Fighter[id].criticalPower = 0.5
set Fighter[id].blockRate = 0.10
set Fighter[id].evasionRate = 0.0
set Fighter[id].knockback = 0.0
set Fighter[id].knockbackResist = 10.0
set Fighter[id].interrupt = 0.0
set Fighter[id].interruptResist = 0.0
set Fighter[id].stun = 0.0
set Fighter[id].stunResist = 0.0
set Fighter[id].hpMax = 200
set Fighter[id].hpRegen = 0.1
set Fighter[id].spMax = 100
set Fighter[id].spRegen = 0.05
set Fighter[id].wType = WEAPON_TYPE_METAL_MEDIUM_SLICE
set Fighter[id].attachSize = "med"
set Fighter[id].attachPoint = "weapon"
call AddAttPoints(id, 0, 15)
call AddAttPoints(id, 1, 9)
call AddAttPoints(id, 2, 6)
call AddAttPoints(id, 3, 20)
set MainSelector[id] = CreateUnit(p, 'H008', WorldBounds.maxX, WorldBounds.maxY, 0)
set HPGrowth[id] = 175.
set MPGrowth[id] = 12.5
elseif uid == 'h00C' then
set Fighter[id].melee = false
set Fighter[id].missileHoming = false
set Fighter[id].missilePiercing = false
set Fighter[id].missile = "Abilities\\Weapons\\Arrow\\ArrowMissile.mdl"
set Fighter[id].missileScale = 0.5
set Fighter[id].missileSpeed = 100.0
set Fighter[id].missileCollision = 70.0
set Fighter[id].missileArch = 0//15.*bj_DEGTORAD
set Fighter[id].missileTurn = 5.*bj_DEGTORAD
set Fighter[id].missileXY = 35
set Fighter[id].missileZ = 100
set Fighter[id].dmgAoE = 0
set Fighter[id].attackRadius = 60.0*bj_DEGTORAD
set Fighter[id].attackRange = 500.0
set Fighter[id].dmgPoint = 0.72
set Fighter[id].attackRateDef = 1.15
set Fighter[id].physicDmgMin = 13
set Fighter[id].physicDmgMax = 21
set Fighter[id].physicDefense = 2.
set Fighter[id].magicDmgMin = 0
set Fighter[id].magicDmgMax = 0
set Fighter[id].magicDefense = 1.
set Fighter[id].criticalRate = 0.0
set Fighter[id].criticalPower = 0.5
set Fighter[id].blockRate = 0.00
set Fighter[id].evasionRate = 0.05
set Fighter[id].knockback = 0.0
set Fighter[id].knockbackResist = 5.0
set Fighter[id].interrupt = 0.0
set Fighter[id].interruptResist = 0.0
set Fighter[id].stun = 0.0
set Fighter[id].stunResist = 0.0
set Fighter[id].hpMax = 260
set Fighter[id].hpRegen = 0.1
set Fighter[id].spMax = 100
set Fighter[id].spRegen = 0.05
set Fighter[id].wType = WEAPON_TYPE_WHOKNOWS
set Fighter[id].attachSize = "small"
set Fighter[id].attachPoint = "weapon"
call AddAttPoints(id, 0, 13)
call AddAttPoints(id, 1, 20)
call AddAttPoints(id, 2, 10)
call AddAttPoints(id, 3, 7)
set MainSelector[id] = CreateUnit(p, 'H014', WorldBounds.maxX, WorldBounds.maxY, 0)
set HPGrowth[id] = 152.
set MPGrowth[id] = 25.
set x = GetUnitX(u)
set y = GetUnitY(u)
call UnitAddAbility(u, PanelCore_TEXTURE_REPLACER_ID)
call PanelCore_ChangeTexture(u, 'BSAL')
call UnitRemoveAbility(u, PanelCore_TEXTURE_REPLACER_ID)
call SetUnitX(u, x)
call SetUnitY(u, y)
endif
set Fighter[id].hp = Fighter[id].hpMax
set Fighter[id].sp = Fighter[id].spMax
set Fighter[id].attackRate = Fighter[id].attackRateDef
set ResearcherShortcut[id] = CreateUnit(p, 'H00M', WorldBounds.maxX, WorldBounds.maxY, 0)
set LearnerShortcut[id] = CreateUnit(p, 'H007', WorldBounds.maxX, WorldBounds.maxY, 0)
call UnitModifySkillPoints(ResearcherShortcut[id], -GetHeroSkillPoints(ResearcherShortcut[id]))
call UnitModifySkillPoints(LearnerShortcut[id], 1-GetHeroSkillPoints(LearnerShortcut[id]))
call XPBar_Update(id)
call IssueImmediateOrderById(LearnerShortcut[id], 'R000')
call IssueImmediateOrderById(MainSelector[id], 'R001')
call IssueImmediateOrderById(ResearcherShortcut[id], 'R002')
call UnitAddAbility(u, 'Aloc')
call UnitRemoveAbility(u, 'Aloc')
call ShowUnit(u, false)
call ShowUnit(u, true)
call UnitAddAbility(u, 'Amrf')
call UnitRemoveAbility(u, 'Amrf')
call SetUnitPosition(u, CREATE_X, CREATE_Y)
//call SetUnitPathing(u, false)
set Controller[id] = CreateUnit(p, 'h001', WorldBounds.maxX, WorldBounds.maxY, 0)
static if USE_MEMORY_HACK then
if IsLAN then
call LeftClick_StartStream(id)
endif
endif
call TriggerRegisterUnitEvent(Selection_RightClick, Controller[id], EVENT_UNIT_ISSUED_POINT_ORDER)
call TriggerRegisterUnitEvent(Selection_OrderItem, Controller[id], EVENT_UNIT_ISSUED_TARGET_ORDER)
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[id], true)
set s = "war3mapImported\\SelectionGreen.mdx"
else
set s = "war3mapImported\\SelectionPlayer" + I2S(id) + ".mdx"
endif
call RegisterPlayerSkill(id, ORDER_ATTACK_SKILL)
call RegisterPlayerSkill(id, ORDER_STOP_SKILL)
call RegisterPlayerSkill(id, ORDER_MOVE_SKILL)
call Learn(id, ORDER_ATTACK_SKILL)
call Learn(id, ORDER_STOP_SKILL)
call Learn(id, ORDER_MOVE_SKILL)
call AddSpecialEffectTarget(s, u, "origin")
call RemoveUnit(Selector[id])
if CreateNew[id] then
set obj = ItemObject.create(ITEM_INDEX_EQUIPMENT+12, 0, 0, 0, 0)
set obj.socketCountMax = 0
call Bag[id].addItem(obj)
set obj = ItemObject.create(ITEM_INDEX_EQUIPMENT+45, 0, 0, 0, 0)
set obj.socketCountMax = 0
call Bag[id].addItem(obj)
set obj = ItemObject.create(ITEM_INDEX_EQUIPMENT+56, 0, 0, 0, 0)
set obj.socketCountMax = 0
call Bag[id].addItem(obj)
if uid == 'h004' then
set obj = ItemObject.create(ITEM_INDEX_EQUIPMENT+78, 0, 0, 0, 0)
set obj.socketCountMax = 0
call Bag[id].addItem(obj)
elseif uid == 'h00C' then
set obj = ItemObject.create(ITEM_INDEX_EQUIPMENT+89, 0, 0, 0, 0)
set obj.socketCountMax = 0
call Bag[id].addItem(obj)
endif
call Bag[id].addItem(ItemObject.create(ITEM_INDEX_SCROLLS+1, 0, 0, 0, 0))
set InitPlayerId = id
set CharacterManager_SaveMode[id] = true
call ExecuteFunc("CharacterManager_ShowEx")
endif
call DisplayTimedTextToPlayer(p, 0, 0, 0., " ")
call DisplayTimedTextToPlayer(p, 0, 0, 30., "New to the map? Open Read Me (|cffffcc00F9|r) to get some basic information.")
call DisplayTimedTextToPlayer(p, 0, 0, 0., " ")
endfunction
function InitPlayer takes unit u returns nothing
local player p = GetOwningPlayer(u)
local integer id = GetPlayerId(p)
if Locale == p then
call ClearTextMessages()
call SetSkyModel("war3mapImported\\LordaeronHillsSky2.mdx")
//call SetTerrainFogEx(0,0,7500,0.5,45./255.,45./255.,45./255.)
call PanCameraToTimed(START_X, START_Y, 0)
endif
set MainUnit[id] = u
call ForForce(bj_FORCE_PLAYER[id], function InitMain)
call ForForce(bj_FORCE_PLAYER[id], function InitPet)
endfunction
endlibrary
library Selection initializer init uses DungeonGeneration, PlayerInit, ClassSelection, MainMenu, IntroScene, UpgradeMenu
globals
integer CineIndex = 0
Inventory array Bag
Shop array ShopUI
Combatant array Fighter
Combatant array PetFighter
unit array Pet
unit array Controller
unit array Selector
unit array Learner
unit array LearnerShortcut
unit array ResearcherShortcut
unit array MainSelector
boolean array IsPlaying
boolean array IsReady
boolean GeneratingDungeon = false
integer PlayerCount = 0
integer ReadyCount = 0
dialog array StartDialog
button array StartDialogButton
group MainGroup = CreateGroup()
boolean IsLAN = false
private group Group = CreateGroup()
private group ReadyGroup = CreateGroup()
public trigger RightClick = CreateTrigger()
public trigger OrderItem = CreateTrigger()
endglobals
private function checkReadyGroup takes nothing returns nothing
local unit fog
local group g = CreateGroup()
local player p
loop
set fog = FirstOfGroup(ReadyGroup)
exitwhen fog == null
call GroupRemoveUnit(ReadyGroup, fog)
if IsUnitInRangeXY(fog, GateX, GateY, 600.) and UnitAlive(fog) then
call GroupAddUnit(g, fog)
else
set p = GetOwningPlayer(fog)
set IsReady[GetPlayerId(p)] = false
set ReadyCount = ReadyCount - 1
call DisplayTimedTextToPlayer(Locale, 0, 0, 5., GetPlayerName(p) + "'s status is set back to not ready. [" + I2S(ReadyCount) + "/" + I2S(PlayerCount) + "]")
endif
endloop
call DestroyGroup(ReadyGroup)
set ReadyGroup = g
set g = null
endfunction
private function enumCreeps takes nothing returns nothing
local integer i
local integer data
local Combatant c
local unit u
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] and IsUnitAlive(MainUnit[i]) and not Fighter[i].isInvulnerable and IsUnitVisible(MainUnit[i], CREEP_PLAYER) then
call GroupEnumUnitsInRange(Group, GetUnitX(MainUnit[i]), GetUnitY(MainUnit[i]), CREEP_VISION_RANGE, null)
loop
set u = FirstOfGroup(Group)
exitwhen u == null
call GroupRemoveUnit(Group, u)
if GetOwningPlayer(u) == CREEP_PLAYER and IsUnitAlive(u) then
call CreepAI[u].enable()
endif
endloop
endif
set i = i + 1
endloop
endfunction
private function startGeneration takes nothing returns nothing
local DungeonUniform dung
local DungeonCavern dung2
//call MiniMap_ClearTexture()
set GeneratingDungeon = true
call ShopItemListLib_FlushSoldItems()
set CamRot = 90
call SetCameraField(CAMERA_FIELD_ROTATION, CamRot, 0)
call ClearTextMessages()
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.9, 0.3, 0, "Working on a nice dungeon...")
if ActiveScroll.id.dungeonType == 0 then
set dung = DungeonUniform.create(0,0,25+ActiveScroll.dungeonSize,25+ActiveScroll.dungeonSize, 10, 35, 0.3, false, 3, 6, 6, 0.2, 0.2) //read the readme for what all these parameters mean
call Dungeon.removeAll(gg_rct_Dungeon_Area) //this function clears existing dungeon destructables and tiles
call Dungeon.clearMap()
call dung.generate()
call Dungeon.verifyMap()
if Dungeon.isMapUsable() then
call Dungeon.clearUnverified()
call Dungeon.build(gg_rct_Dungeon_Area, ActiveScroll.id.dungeonType, function DungeonGeneration_OnFinish)
endif
elseif ActiveScroll.id.dungeonType == 1 then
set dung2 = DungeonCavern.create(0,0,25+ActiveScroll.dungeonSize,25+ActiveScroll.dungeonSize, 40, true, 5, 2, 5, 5)
call Dungeon.removeAll(gg_rct_Dungeon_Area)
call Dungeon.clearMap()
call dung2.generate()
call Dungeon.verifyMap()
if Dungeon.isMapUsable() then
call Dungeon.clearUnverified()
call Dungeon.build(gg_rct_Dungeon_Area, ActiveScroll.id.dungeonType, function DungeonGeneration_OnFinish)
endif
elseif ActiveScroll.id.dungeonType == 2 then
set dung2 = DungeonCavern.create(0,0,25+ActiveScroll.dungeonSize,25+ActiveScroll.dungeonSize, 40, true, 5, 2, 5, 5)
call Dungeon.removeAll(gg_rct_Dungeon_Area)
call Dungeon.clearMap()
call dung2.generate()
call Dungeon.verifyMap()
if Dungeon.isMapUsable() then
call Dungeon.clearUnverified()
call Dungeon.build(gg_rct_Dungeon_Area, ActiveScroll.id.dungeonType, function DungeonGeneration_OnFinish)
endif
endif
call ReleaseTimer(GetExpiredTimer())
endfunction
private function onClick takes nothing returns boolean
local integer id = GetPlayerId(GetTriggerPlayer())
if GetClickedButton() == StartDialogButton[id] then
if IsUnitInRangeXY(MainUnit[id], GateX, GateY, 600.0) then
set IsReady[id] = true
set ReadyCount = ReadyCount + 1
call GroupAddUnit(ReadyGroup, MainUnit[id])
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 5., GetPlayerName(GetTriggerPlayer()) + " is ready. [" + I2S(ReadyCount) + "/" + I2S(PlayerCount) + "]")
if ReadyCount == PlayerCount then
//set ActiveScroll = ItemObject.create(15, 0, 1, 0, 0) // <<== no scroll mode
set id = 0
loop
exitwhen id > 3
set IsReady[id] = false
set id = id + 1
endloop
set ReadyCount = 0
set DungeonIndex = 0
set InDungeon = true
call GroupClear(ReadyGroup)
call ShowInterface(false, 2.0)
call EnableUserControl(false)
call EnableUserUI(false)
call SetCineFilterStartColor(0, 0, 0, 0)
call SetCineFilterEndColor(0, 0, 0, 255)
call SetCineFilterDuration(2.0)
call DisplayCineFilter(true)
call ClearTextMessages()
call StopMusic(true)
call TimerStart(NewTimer(), 3, false, function startGeneration)
endif
else
call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 5., "Failed. You are too far from the gate.")
endif
endif
return false
endfunction
private function onSelect takes nothing returns boolean
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(u)
local integer id = GetPlayerId(p)
local integer uid = GetUnitTypeId(u)
if uid == 'H008' or uid == 'H014' then
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[id], true)
endif
elseif uid == 'H007' then
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[id], true)
endif
call CharacterWindow_Show(id, true)
call CharacterWindow_OpenTab(id, 1)
call ShopUI[id].show(false)
elseif uid == 'H00M' then
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[id], true)
endif
call CharacterWindow_Show(id, true)
call CharacterWindow_OpenTab(id, 0)
call ShopUI[id].show(false)
elseif IsUnitInGroup(u, MainGroup) then
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[id], true)
endif
endif
set u = null
return false
endfunction
private function onGate takes nothing returns boolean
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(u)
local integer id
if IsUnitInGroup(u, MainGroup) then
if GateOpen then // <<== no scroll mode
set id = GetPlayerId(p)
if not IsReady[id] then
call DialogClear(StartDialog[id])
call DialogSetMessage(StartDialog[id], "Are you ready?")
set StartDialogButton[id] = DialogAddButton(StartDialog[id], "Yes", 0)
call DialogAddButton(StartDialog[id], "No", 0)
call DialogDisplay(p, StartDialog[id], true)
endif
elseif not GateAnimating then // <<== no scroll mode
call DisplayTimedTextToPlayer(p, 0, 0, 5., "The gate isn't active yet. You must activate a dungeon scroll first.")
endif
endif
set u = null
return false
endfunction
private function onItem takes nothing returns boolean
local item itm = GetOrderTargetItem()
local unit u = GetTriggerUnit()
local integer pid = GetPlayerId(GetOwningPlayer(u))
if itm != null and pid < 4 and not Fighter[pid].isChanneling and UnitAlive(u) and not IsUnitPaused(u) and not Fighter[pid].isStunned and not Fighter[pid].isImmobilized then
call IssueTargetOrder(MainUnit[pid], "smart", itm)
endif
set u = null
set itm = null
return false
endfunction
private function onEnter takes nothing returns boolean
local unit u = GetSoldUnit()
local player p = GetOwningPlayer(u)
local integer id = GetPlayerId(p)
local integer uid = GetUnitTypeId(u)
if uid == 'h019' then
call RemoveUnit(u)
call CharacterManager_Show(id)
else
set CreateNew[id] = true
call InitPlayer(u)
endif
set u = null
return false
endfunction
private function onLeave takes nothing returns boolean
local player p = GetTriggerPlayer()
local integer id = GetPlayerId(p)
local integer i
local unit fog
call DisplayTimedTextToPlayer(Locale, 0, 0, 5., GetPlayerName(p) + " has left the game. Cleaning up player's data...")
if ReadyCount > 0 then
if InDungeon then
set Departing = false
set ReadyCount = 0
call DialogDisplay(Locale, StairDownDialog, false)
else
set i = 0
loop
exitwhen i > 3
set IsReady[i] = true
set i = i + 1
endloop
set ReadyCount = 0
call GroupClear(ReadyGroup)
endif
call DisplayTimedTextToPlayer(Locale, 0, 0, 5., "Departure canceled. Status is set back to not ready.")
endif
if IsPlaying[id] then
set PlayerCount = PlayerCount - 1
set IsPlaying[id] = false
loop
set fog = FirstOfGroup(Fighter[id].subordinate)
exitwhen fog == null
call GroupRemoveUnit(Fighter[id].subordinate, fog)
call RemoveUnit(fog)
endloop
//call GroupRemoveUnit(MainGroup, MainUnit[id])
//call GroupRemoveUnit(PlayerUnits, MainUnit[id])
call Fighter[id].destroy()
call RemoveUnit(MainUnit[id])
set MainUnit[id] = null
if PlayerNameTag[id] > 0 then
call PlayerNameTag[id].destroy()
call Tooltips1[id].control.destroy()
call Tooltips2[id].control.destroy()
call Bag[id].panel.destroy()
call ShopUI[id].panel.destroy()
call CharWindowGeneral[id].destroy()
call CharWindowStatistic[id].destroy()
call CharWindowSkill[id].destroy()
call CharWindowEquipment[id].destroy()
call ShortcutBar_SkillSelection[id].destroy()
call ShortcutBar_BarPanel[id].destroy()
call XPBar_BarPanel[id].destroy()
endif
endif
return false
endfunction
private function select takes nothing returns nothing
local integer i = 0
set IsLAN = not ReloadGameCachesFromDisk()
if IsLAN then
set CharacterManager_GameMode = "Multi Player"
set CharacterManager_GameModeCode = 35
else
set CharacterManager_GameMode = "Single Player"
set CharacterManager_GameModeCode = 22
/*call CreateQuestBJ(bj_QUESTTYPE_OPT_DISCOVERED, "Chat Commands (SP Mode)", "|cffffcc00-gimme <id>|r: add item to inventory. id = 1-40
|cffffcc00-addexp <amount>|r: add experience.
|cffffcc00-lvlup <amount>|r: add level.
|cffffcc00-str <amount>|r: add strength attribute.
|cffffcc00-dex <amount>|r: add dexterity attribute.
|cffffcc00-wis <amount>|r: add wisdom attribute.
|cffffcc00-for <amount>|r: add fortitude attribute.
|cffffcc00-gold <amount>|r: add golds.
|cffffcc00-attpts <amount>|r: add attribute point.
|cffffcc00-skillpts <amount>|r: add skill point.
|cffffcc00-next|r: instantly moves to the next dungeon.
|cffffcc00-reddot|r: reveals red portal's whereabouts.", "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn.blp" )*/
endif
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local trigger t2 = CreateTrigger()
local integer i = 0
local player p
call SkillData.InitSkills()
call SetTimeOfDayScale(0)
call SetFloatGameState(GAME_STATE_TIME_OF_DAY, 0)
call SetGameSpeed(MAP_SPEED_FASTEST)
call SetMapFlag(MAP_LOCK_SPEED, true)
call SetUnitTimeScale(gg_unit_e01Q_0018, 0.5)
//call SetDayNightModels("war3mapImported\\DNCUnit.mdx", "war3mapImported\\DNCUnit.mdx")
call SetDayNightModels("war3mapImported\\DNCNight.mdx", "war3mapImported\\DNCNight.mdx")
//call SetDayNightModels("war3mapImported\\DNCDay.mdx", "war3mapImported\\DNCDay.mdx")
//call SetDayNightModels("war3mapImported\\DNCSelection.mdx", "war3mapImported\\DNCSelection.mdx")
//call ShowInterface(false, 0.0)
call SetCineFilterTexture("ReplaceableTextures\\CameraMasks\\black_mask.blp")
call SetCineFilterBlendMode(BLEND_MODE_BLEND)
call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
call SetCineFilterStartUV(0, 0, 1, 1)
call SetCineFilterEndUV(0, 0, 1, 1)
//call SetCineFilterStartColor(0, 0, 0, 255)
//call SetCineFilterEndColor(0, 0, 0, 255)
//call SetCineFilterDuration(0.0)
//call DisplayCineFilter(true)
loop
exitwhen i > 3
set p = Player(i)
if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p) == MAP_CONTROL_USER then
set PlayerCount = PlayerCount + 1
set StartDialog[i] = DialogCreate()
set IsPlaying[i] = true
set ItemOn[i] = true
//set CameraOn[i] = true
set Selector[i] = CreateUnit(p, 'hfoo', GetUnitX(gg_unit_nmer_0006), GetUnitY(gg_unit_nmer_0006), 0)
call SetUnitScale(Selector[i], 0, 0, 0)
call PauseUnit(Selector[i], true)
call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_LEAVE)
call TriggerRegisterDialogEvent(t2, StartDialog[i])
if i != 0 then
call SetPlayerAlliance(p, Player(0), ALLIANCE_PASSIVE, true)
call SetPlayerAlliance(Player(0), p, ALLIANCE_PASSIVE, true)
endif
call ClassSelection_Create(i)
call MainMenu_Create(i)
call UpgradeMenu_init(p)
endif
call IntroScene_init(p)
set i = i + 1
endloop
call TriggerAddCondition(t, Condition(function onLeave))
call TriggerAddCondition(t2, Condition(function onClick))
set t = CreateTrigger()
//call TriggerRegisterEnterRectSimple(t, gg_rct_SelectionRect)
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SELL)
call TriggerAddCondition(t, Condition(function onEnter))
set t = CreateTrigger()
call TriggerRegisterEnterRectSimple(t, gg_rct_GateArea)
call TriggerAddCondition(t, Condition(function onGate))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SELECTED)
call TriggerAddCondition(t, Condition(function onSelect))
call TriggerAddCondition(RightClick, Condition(function LeftClick_onOrder))
call TriggerAddCondition(OrderItem, Condition(function onItem))
call TimerStart(CreateTimer(), 0.1, true, function checkReadyGroup)
call TimerStart(CreateTimer(), 0.5, true, function enumCreeps)
call TimerStart(CreateTimer(), 0, false, function select)
set i = 0
loop
exitwhen i > 3
call PlayerCamera[i].applyCameraSetup(gg_cam_Cine8, true, 0)
call PlayerCamera[i].refresh()
set i = i + 1
endloop
call SetSkyModel("Environment\\Sky\\Sky\\SkyLight.mdl")
//call ShowInterface(false, 0)
call EnableUserUI(false)
call IntroScene_Start()
endfunction
endlibrary
scope DeselectTrainer
globals
boolean IntentionalDeselection = false
private group G = CreateGroup()
private timer array Checker
endglobals
private function check takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer pid = GetTimerData(t)
local player p = Player(pid)
call GroupEnumUnitsSelected(G, p, null)
if FirstOfGroup(G) == null then
if Locale == p then
call ClearSelection()
call SelectUnit(Controller[pid], true)
endif
endif
call GroupClear(G)
set t = null
endfunction
private function onAct takes nothing returns boolean
local player p = GetTriggerPlayer()
local integer pid = GetPlayerId(p)
local unit u = GetTriggerUnit()
if u == gg_unit_nmer_0006 and MainUnit[pid] == null and not IntentionalDeselection then
if Locale == p then
call ClearSelection()
call SelectUnit(gg_unit_nmer_0006, true)
endif
elseif u == Controller[pid] then
if Checker[pid] == null then
set Checker[pid] = NewTimerEx(pid)
endif
call TimerStart(Checker[pid], 0, false, function check)
endif
set u = null
return false
endfunction
function InitTrig_Deselection takes nothing returns nothing
set gg_trg_Deselection = CreateTrigger()
/*call TriggerRegisterPlayerSelectionEventBJ(gg_trg_Deselection, Player(0), false)
call TriggerRegisterPlayerSelectionEventBJ(gg_trg_Deselection, Player(1), false)
call TriggerRegisterPlayerSelectionEventBJ(gg_trg_Deselection, Player(2), false)
call TriggerRegisterPlayerSelectionEventBJ(gg_trg_Deselection, Player(3), false)
call TriggerAddCondition(gg_trg_Deselection, Condition(function onAct))*/
endfunction
endscope
scope Cmds initializer init
globals
private integer Sid = 0
private boolean ParticleOn = true
boolean array IsAdmin
private camerasetup array CamSetup1
private camerasetup array CamSetup2
endglobals
private function AddEXPNewThread takes nothing returns nothing
call AddEXP(GetPlayerId(GetEnumPlayer()), 1)
endfunction
private function OnCommand takes nothing returns boolean
local player p = GetTriggerPlayer()
local integer id = GetPlayerId(p)
local string s = GetEventPlayerChatStringMatched()
local string params = SubString(GetEventPlayerChatString(), StringLength(s) + 1, 50)
local integer i
local group g
local unit u
local ItemObject obj
if IsKeyVerified[id] and UnitAlive(MainUnit[id]) then
if s == "#lvlup" then
set i = S2I(params)
if i > 0 then
loop
exitwhen i == 0
set EXPCurrent[id] = EXPTarget[id]-1
call ForForce(bj_FORCE_PLAYER[id], function AddEXPNewThread)
set i = i - 1
endloop
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Level added: " + params)
endif
elseif s == "#addexp" then
call AddEXP(id, S2R(params))
call DisplayTimedTextToPlayer(p, 0, 0, 5, "EXP added: " + params)
elseif s == "#str" then
set i = S2I(params)
call AddAttPoints(id, 0, i)
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Strength added: " + I2S(i))
elseif s == "#dex" then
set i = S2I(params)
call AddAttPoints(id, 1, i)
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Dexterity added: " + I2S(i))
elseif s == "#wis" then
set i = S2I(params)
call AddAttPoints(id, 2, i)
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Wisdom added: " + I2S(i))
elseif s == "#for" then
set i = S2I(params)
call AddAttPoints(id, 3, i)
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Fortitude added: " + I2S(i))
elseif s == "#gold" then
set i = S2I(params)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)+i)
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Gold given: " + I2S(i))
elseif s == "#attpts" then
set i = S2I(params)
call AddAttributePoint(id, i)
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Attribute points added: " + I2S(i))
elseif s == "#skillpts" then
set i = S2I(params)
call AddSkillPoint(id, i)
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Skill points added: " + I2S(i))
elseif s == "#gimme" then
call Bag[id].addItemCreate(S2I(params), 1, 1)
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Item added: " + Items(S2I(params)).name)
elseif s == "#next" then
if ActiveScroll != 0 then
call ShowInterface(false, 2.0)
call EnableUserControl(false)
call EnableUserUI(false)
call SetCineFilterStartColor(0, 0, 0, 0)
call SetCineFilterEndColor(0, 0, 0, 255)
call SetCineFilterDuration(2.0)
call DisplayCineFilter(true)
call ClearTextMessages()
if DungeonIndex < DungeonExtraLevelCount then
call TimerStart(NewTimer(), 3, false, function DungeonGeneration_recreate)
else
call StopMusic(true)
call TimerStart(NewTimer(), 3, false, function DungeonGeneration_returnBase)
endif
set g = CreateGroup()
call GroupEnumUnitsOfPlayer(g, CREEP_PLAYER, Filter(function FilterOutUI))
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g, u)
if u != gg_unit_h002_0010 then
call PauseUnit(u, true)
endif
endloop
call DestroyGroup(g)
set g = null
set DungeonIndex = DungeonIndex + 1
endif
elseif s == "#reddot" then
if InDungeon then
set RedPortalRevealed = not RedPortalRevealed
if RedPortalRevealed then
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Red portal revealed")
else
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Red portal unrevealed")
endif
endif
elseif s == "#heal" then
set Fighter[id].hp = Fighter[id].hpMax
set Fighter[id].sp = Fighter[id].spMax
elseif (s == "#sid") then
set Sid = S2I(params)
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Skill: " + SkillData(Sid).name)
elseif (s == "#slvl") then
set PlayerSkillData[id][Sid].level = S2I(params)
elseif (s == "#nocd") then
set IgnoreCooldown = not IgnoreCooldown
elseif (s == "#items") then
set i = 1
loop
exitwhen StringLength(Items(i).name) == 0
call BJDebugMsg(I2S(i) + " = " + Items(i).name)
set i = i + 1
endloop
call BJDebugMsg("====================")
elseif (s == "#sort") then
call Inventory_InventoryIndex[id].sortContent(true)
elseif (s == "#upg") then
call UpgradeMenu_SlotObject[id][0].upgrade(S2I(params))
elseif (s == "#downg") then
call UpgradeMenu_SlotObject[id][0].downgrade(true)
elseif (s == "#scroll") then
call BaseScroll.clearItem()
set i = 0
loop
exitwhen i >= 20
set obj = ItemObject.create(ITEM_INDEX_SCROLLS+GetRandomInt(1, 3), 1, 1, WorldBounds.maxX, WorldBounds.maxY)
call obj.setScrollStats(GetRandomInt(0, SCROLL_VARIATION))
call BaseScroll.addItem(obj)
set i = i + 1
endloop
elseif (s == "#ui") then
set UIEnabled = not UIEnabled
elseif (s == "#kill") then
call Fighter[S2I(params)].kill()
elseif (s == "#rev") then
call Fighter[S2I(params)].revive()
elseif (s == "#cam") then
set CameraOn[id] = not CameraOn[id]
if CamSetup1[id] == null then
set CamSetup1[id] = CreateCameraSetup()
set CamSetup2[id] = CreateCameraSetup()
endif
elseif (s == "#soul1") then
call SoulHarvest.create(GetUnitX(MainUnit[id])+200, GetUnitY(MainUnit[id])+200, 1000.0, true)
elseif (s == "#soul2") then
call SoulHarvest.create(GetUnitX(MainUnit[id])+200, GetUnitY(MainUnit[id])+200, 1000.0, false)
endif
endif
return false
endfunction
private function Activate takes nothing returns boolean
local SyncData d = GetSyncedData()
if d.readString(0) == "K12@23saZdlkmf#%22saT" then
set IsAdmin[GetPlayerId(d.from)] = true
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#lvlup", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#addexp", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#gimme", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#next", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#str", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#dex", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#wis", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#for", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#gold", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#attpts", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#skillpts", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#reddot", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#heal", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#sid", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#slvl", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#nocd", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#items", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#sort", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#upg", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#downg", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#scroll", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#ui", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#kill", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#rev", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#cam", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#soul1", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Cmds, d.from, "#soul2", false)
call DisplayTimedTextToPlayer(d.from, 0, 0, 5, "|cff00ff00Admin commands activated.|r")
endif
return false
endfunction
private function OnCommandDef takes nothing returns boolean
local player p = GetTriggerPlayer()
local integer id = GetPlayerId(p)
local string s = GetEventPlayerChatStringMatched()
local string params = SubString(GetEventPlayerChatString(), StringLength(s) + 1, 50)
local integer i
local string str
local File f
local string read
local SyncData data
if IsKeyVerified[id] and UnitAlive(MainUnit[id]) then
if s == "-clear" then
if Locale == p then
call ClearTextMessages()
endif
elseif s == "-shake" then
set CameraShaker_Intensity[id] = RMaxBJ(RMinBJ(S2R(params), 2.), 0.)
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Camera shake intensity: " + R2SW(CameraShaker_Intensity[id], 1, 1))
elseif s == "-smooth" then
set i = S2I(params)
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Camera smoothness level: " + I2S(Keyboard_SetCamSmoothness(id, i)))
elseif s == "-soften" then
if Keyboard_Smoothing[id] < 0.2 then
set Keyboard_Smoothing[id] = 0.2
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Camera Softness: On")
else
set Keyboard_Smoothing[id] = 0.0
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Camera Softness: Off")
endif
elseif s == "-admin" then
if not IsAdmin[id] then
set f = File.open(MAP_NAME, "Admin", File.Flag.READ)
set read = f.read()
call f.close()
set data = SyncData.create(p)
call data.addString(read, 22)
set data.timeout = SYNC_TIMEOUT
set data.onComplete = Filter(function Activate)
call data.start()
endif
elseif s == "-tips" then
if Locale == p then
set Tips_Print = not Tips_Print
if Tips_Print then
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Display tips: On")
else
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Display tips: Off")
endif
endif
elseif s == "-save" then
if CharacterManager_SaveEnabled[id] then
if UpgradeMenu_Main[id].visible then
call DisplayTimedTextToPlayer(p, 0, 0, 5, "|cffff0000Unable to save when upgrading.|r")
else
call TimerStart(ReminderTimer[id], 300, false, function PlayerInit_remind)
set PrintSaveMessage = true
call CharacterManager_SaveData(p)
endif
else
call DisplayTimedTextToPlayer(p, 0, 0, 5, "|cffff0000Save/load system is disabled for you. Open Read Me for more informations.|r")
endif
endif
endif
if s == "-particle" then
if Locale == p then
set ParticleOn = not ParticleOn
if ParticleOn then
if MainUnit[id] != null then
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Particle: On")
endif
call SetDoodadAnimationRect(bj_mapInitialPlayableArea, 'D016', "show", false)
call SetDoodadAnimationRect(bj_mapInitialPlayableArea, 'D017', "show", false)
call SetDoodadAnimationRect(bj_mapInitialPlayableArea, 'D018', "show", false)
call SetDoodadAnimationRect(bj_mapInitialPlayableArea, 'D019', "show", false)
call SetDoodadAnimationRect(bj_mapInitialPlayableArea, 'D01A', "show", false)
else
if MainUnit[id] != null then
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Particle: Off")
endif
call SetDoodadAnimationRect(bj_mapInitialPlayableArea, 'D016', "hide", false)
call SetDoodadAnimationRect(bj_mapInitialPlayableArea, 'D017', "hide", false)
call SetDoodadAnimationRect(bj_mapInitialPlayableArea, 'D018', "hide", false)
call SetDoodadAnimationRect(bj_mapInitialPlayableArea, 'D019', "hide", false)
call SetDoodadAnimationRect(bj_mapInitialPlayableArea, 'D01A', "hide", false)
endif
endif
endif
return false
endfunction
private function init takes nothing returns nothing
local integer i = 0
local player p
local trigger t = CreateTrigger()
set gg_trg_Cmds = CreateTrigger()
loop
exitwhen i > 3
set p = Player(i)
call TriggerRegisterPlayerChatEvent(t, p, "-clear", false)
call TriggerRegisterPlayerChatEvent(t, p, "-smooth", false)
call TriggerRegisterPlayerChatEvent(t, p, "-soften", false)
call TriggerRegisterPlayerChatEvent(t, p, "-save", false)
call TriggerRegisterPlayerChatEvent(t, p, "-particle", false)
call TriggerRegisterPlayerChatEvent(t, p, "-shake", false)
call TriggerRegisterPlayerChatEvent(t, p, "-tips", false)
call TriggerRegisterPlayerChatEvent(t, p, "-admin", false)
set i = i + 1
endloop
call TriggerAddCondition(t, Condition(function OnCommandDef))
call TriggerAddCondition(gg_trg_Cmds, Condition(function OnCommand))
//call DisableTrigger(gg_trg_Cmds)
endfunction
endscope
library Tips initializer init
globals
public boolean Print = true
public string array TipsString
public integer Count = 0
endglobals
private function show takes nothing returns nothing
if Print then
call DisplayTimedTextToPlayer(Locale, 0, 0, 15., "\n|cffffcc00Tips:|r\n" + TipsString[GetRandomInt(0, Count)] + "\n")
endif
endfunction
private function init takes nothing returns nothing
set TipsString[0] = "Talk to Ronan the Blacksmith in the Pub to upgrade your equipment."
set TipsString[1] = "Upgrade materials are occasionally dropped by high rank monsters."
set TipsString[2] = "Failed item upgrade might result in item destruction or downgrade."
set TipsString[3] = "Upgrading higher quality item will give better improvements."
set TipsString[4] = "Item's quality might be tempered during upgrade process."
set TipsString[5] = "Higher rank monster gives more experience and better loots."
set TipsString[6] = "Once the red portal is located, it will be visible to everyone else in the minimap."
set TipsString[7] = "Keep using your active skills to increase your skill mastery and level."
set TipsString[8] = "You gain 5 attribute points every 1 level and 1 skill point every 5 levels."
set TipsString[9] = "You can only learn one active skill from each tier."
set TipsString[10] = "Press '|cffffcc00F|r' to toggle item objects visibility on and off to prevent misclicks in combat."
set TipsString[11] = "You can pick nearby items by pressing '|cffffcc00Space|r'. It can pick even when item's visibility is off."
set Count = 11
call TimerStart(CreateTimer(), 180.0, true, function show)
endfunction
endlibrary
function Trig_Instruction_Copy_Actions takes nothing returns nothing
call CreateQuestBJ(bj_QUESTTYPE_OPT_DISCOVERED, "General Instructions", "- Enter the portal to enter the dungeon. Must activate a dungeon scroll first.
- Buy a dungeon scroll from a merchant (with scroll item indicator) next to the portal.
- Activate scroll by using it from your inventory. You must be close to the portal.
- Use left click to attack. Right click to move. Hold the button to repeat the action.
- Open character menu (|cffffcc00C|r) to manage attribute points, equipment, and skills.
- Add your new skill to the macro bar by pressing the desired macro slot then select the desired skill.
- Use key numbers to activate skill or use item on the macro bar.
- Open inventory (|cffffcc00I|r) to manage owned items.
- Left click on custom interface icons to interact. Right click to show tooltips.
- Press '|cffffcc00ESC|r' to close user interfaces one by one.
- When left-clicking user interface components, any slightest cursor movement might cause weird selection issue.", "ReplaceableTextures\\CommandButtons\\BTNBookOfTheDead.blp" )
call CreateQuestBJ(bj_QUESTTYPE_OPT_DISCOVERED, "Chat Commands", "|cffffcc00-save|r: saves game data.
|cffffcc00-particle|r: turn detail particle on/off.
|cffffcc00-shake <rate>|r: set camera shaking intensity (rate ranges from 0.0-2.0 [1.0: default]).
|cffffcc00-smooth <level>|r: makes camera performs more/less smooth (level ranges from 0-4 [2: default]).
|cffffcc00-soften|r: activates extra camera smoothing.
|cffffcc00-clear|r: clears messages on screen.", "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn.blp" )
call CreateQuestBJ(bj_QUESTTYPE_OPT_DISCOVERED, "Save & Load System", "- Requires local files to be enabled. Search on google about how to enable it.
- Datas are stored in your disk in |cffffcc00Documents\\Warcraft III\\CustomMapData\\EmberCraft\\|r.
- There are 6 available slots per player name.
- Save data from singleplayer mode can't be used in multiplayer mode.
- Type \"|cffffcc00-save|r\" to save the game data immediately.", "ReplaceableTextures\\CommandButtons\\BTNUnloadDwarf.blp" )
call CreateQuestBJ(bj_QUESTTYPE_OPT_DISCOVERED, "Dungeon", "- Dungeon is randomly generated.
- To enter a dungeon, buy a dungeon scroll from merchant (with scroll item indicator) and use it when you are close to the portal.
- If you activate a scroll when other scroll is already activated, the active scroll will be replaced and returned to its owner.
- Move to the gate and select 'Yes' if you are ready to depart.
- Mission starts when all players are ready.
- Ready status will be canceled if a player moves too far from the gate, died, or leave the game.
- Each dungeon scroll has different status modifiers that can affect both players and monsters.
- Each dungeon consists of one base floor and one boss room (not yet implemented).
- To move to the next level, you must locate the red portal somewhere in the dungeon.", "ReplaceableTextures\\CommandButtons\\BTNWaygate.blp" )
call CreateQuestBJ(bj_QUESTTYPE_OPT_DISCOVERED, "Shop", "- You can access shop interface by clicking on a merchant.
- Merchants are units with item object mark above their head.
- You can sell items from inventory when opening a shop.
- Sold items can be re-claimed with equal to its sell value.
- Sold items can no longer be re-claimed if you depart on a mission or exit the game.
- Scrolls sold by scroll merchant are randomized and each item can only be bought once.", "ReplaceableTextures\\CommandButtons\\BTNMerchant.blp" )
call CreateQuestBJ(bj_QUESTTYPE_OPT_DISCOVERED, "Combat & Monster Behavior", "- Use number keys (0-9) to activate skills/items in the macro bar.
- Monsters engaged in combat with you/teammate will be marked with red circle.
- Monster's name, level, and health status will be temporarily displayed when you hit them.
- Slaying stronger monster rewards more xp and better item drop.
- Monster's handicap increased based on number of players.", "ReplaceableTextures\\CommandButtons\\BTNGlaiveCrit.blp" )
call CreateQuestBJ(bj_QUESTTYPE_OPT_DISCOVERED, "Level & Experience", "- Each level rewards 5 attribute points.
- 1 skill point is given every 5 levels.
- Gained exp is factored by level difference between player and killed monster.
- Killing a monster with higher or equal level will give 100% experience rate.
- Killing lower level monster will give lower experience rate based on level difference.", "ReplaceableTextures\\CommandButtons\\BTNScepterOfMastery.blp" )
call CreateQuestBJ(bj_QUESTTYPE_OPT_DISCOVERED, "Class & Sub-Class System", "- Currently there are total of 2 classes. Each have unique sub-classes with certain specializations.
- Combine skills from different sub-classes to build the character in a unique way according to your preference.", "ReplaceableTextures\\CommandButtons\\BTNCrusader.blp" )
call CreateQuestBJ(bj_QUESTTYPE_OPT_DISCOVERED, "Skill System", "- Each sub-class has a total of 8 tiers of skills at hand, 5 active and 3 passive skills.
- Player gains 1 skill point every 5 levels.
- Can only learn 1 (one) skill for each tier at a time. Once a skill of a certain tier is learned, other skills at the same tier (from other sub classes) can't be learned anymore.
- Active skills can be trained by using them in combat. While passive skills can be trained using skill points.
- Active skills have max level of 15, while passive skills have max level of 5.
- Active skills will activate a mutation every 5 levels.", "ReplaceableTextures\\CommandButtons\\BTNAbility_Physical_Taunt.blp" )
call CreateQuestBJ(bj_QUESTTYPE_OPT_DISCOVERED, "Attribute System", "- There are 4 attributes: Strength, Dexterity, Wisdom, and Fortitude.
- Player gains 5 attribute points on each level.
- Increasing Strength will improve physical damage and critical power.
- Increasing Dexterity will improve critical rate, evasion, and block rate.
- Increasing Wisdom will improve magic damage, maximum MP, and MP regeneration.
- Increasing Fortitude will improve physical defense, maximum HP, and HP regeneration", "ReplaceableTextures\\CommandButtons\\BTNStatUp.blp" )
call CreateQuestBJ(bj_QUESTTYPE_OPT_DISCOVERED, "Discord", "Join our discord channel to:
- Discuss everything about the map (character builds, secrets, etc.) with other players
- Get news and sneak peek about map's development progression
- Post bug report, criticism, and suggestion
- Arrange multiplayer games
- Etc.
Link: |cffffcc00discord.gg/NWjuCbV|r", "ReplaceableTextures\\CommandButtons\\BTNdiscord.blp" )
//call FlashQuestDialogButton()
endfunction
//===========================================================================
function InitTrig_Instruction takes nothing returns nothing
set gg_trg_Instruction = CreateTrigger( )
call TriggerRegisterTimerEventSingle( gg_trg_Instruction, 1.00 )
call TriggerAddAction( gg_trg_Instruction, function Trig_Instruction_Copy_Actions )
endfunction
//! inject config
call SetMapName("TRIGSTR_034")
call SetMapDescription("TRIGSTR_036")
call SetPlayers(5)
call SetTeams(5)
call SetGamePlacement(MAP_PLACEMENT_TEAMS_TOGETHER)
call DefineStartLocation(0, 6976.0, 11840.0)
call DefineStartLocation(1, 6976.0, 11840.0)
call DefineStartLocation(2, 6976.0, 11840.0)
call DefineStartLocation(3, 6976.0, 11840.0)
call DefineStartLocation(4, 6976.0, 11840.0)
//call PlayMusic("war3mapImported\\Crypt.mp3")
// Player setup
call InitCustomPlayerSlots()
call InitCustomTeams()
call InitAllyPriorities()
//! endinject
function InitTrig_TrainingDummy takes nothing returns nothing
call IndexCreep(gg_unit_h002_0010)
call UnitAddAbility(gg_unit_h002_0010, 'Aloc')
call UnitRemoveAbility(gg_unit_h002_0010, 'Aloc')
call ShowUnit(gg_unit_h002_0010, false)
call ShowUnit(gg_unit_h002_0010, true)
call UnitAddAbility(gg_unit_h002_0010, 'Amrf')
call UnitRemoveAbility(gg_unit_h002_0010, 'Amrf')
call AdjustCreepStrength(Combatant[gg_unit_h002_0010], 1)
endfunction
library CreepAI uses TimerUtils, PanelCore, CreepSfx, CombatSystem
struct CreepAI
Combatant c
unit u
unit target
timer time
integer data
Combatant tdata
integer utype
boolean enabled
boolean channeling
boolean isCoward
boolean isHorde
effect selection
RSound engageSfx
RSound tauntSfx
RSound attackSfx
static constant integer TYPE_DRYAD_ENCHANTRESS = 1
private static group Group = CreateGroup()
private static boolean ShareThreat = true
private static thistype array UnitIndex
private static TableArray ThreatLevel
static method operator [] takes unit whichUnit returns thistype
return UnitIndex[GetUnitUserData(whichUnit)]
endmethod
method resetThreatLevel takes nothing returns nothing
local Combatant c2
local unit fog
local group g = CreateGroup()
loop
set fog = FirstOfGroup(PlayerUnits)
exitwhen fog == null
call GroupRemoveUnit(PlayerUnits, fog)
call GroupAddUnit(g, fog)
set c2 = Combatant[fog]
if IsPlaying[c2.pid] then
set ThreatLevel[.data].real[c2] = 0
endif
endloop
call DestroyGroup(PlayerUnits)
set PlayerUnits = g
set g = null
endmethod
method abort takes nothing returns nothing
call resetThreatLevel()
call TimerStart(.time, 0, false, null)
call DestroyEffect(.selection)
set .selection = null
set .target = null
set .tdata = 0
endmethod
method switchTarget takes unit target returns nothing
if IsUnitAlive(target) then
call enable()
if .target == null and .selection == null then
set .selection = AddSpecialEffectTarget("war3mapImported\\SelectionCreep" + I2S(IMaxBJ(.c.dropQuality, 0)) + ".mdx", .u, "origin")
endif
set .target = target
set .tdata = Combatant[target]
call CreepSfx_alert(.c)
endif
endmethod
method alert takes nothing returns nothing
local CreepAI ai
local integer data2
local unit fog
local real x
local real y
local real dx
local real dy
local real x2
local real y2
if .target != null then
set x = GetUnitX(.target)
set y = GetUnitY(.target)
set x2 = GetUnitX(.u)
set y2 = GetUnitY(.u)
call GroupEnumUnitsInRange(Group, x2, y2, CREEP_ALERT_RADIUS, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if IsUnitAlive(fog) and GetOwningPlayer(fog) == CREEP_PLAYER then
set ai = CreepAI[fog]
if ai.target == null then
set data2 = GetUnitUserData(fog)
set dx = CreepNestX[data2]-x
set dy = CreepNestY[data2]-y
if dx*dx+dy*dy <= CREEP_MAX_CHASE_DISTANCE then
call IssueImmediateOrder(fog, "stop")
call ai.switchTarget(.target)
call ai.enable()
endif
endif
endif
endloop
endif
endmethod
method searchPlayerUnit takes nothing returns nothing
local group g = CreateGroup()
local unit fog
local Combatant c2
local real a = GetUnitFacing(.u)*bj_DEGTORAD
local real x = GetUnitX(.u)
local real y = GetUnitY(.u)
local real rad
local real r
loop
set fog = FirstOfGroup(PlayerUnits)
exitwhen fog == null
call GroupRemoveUnit(PlayerUnits, fog)
call GroupAddUnit(g, fog)
set c2 = Combatant[fog]
if target == null and IsPlaying[c2.pid] and IsUnitAlive(c2.u) and IsUnitVisible(fog, .c.owner) and IsUnitInRangeXY(c2.u, x, y, CREEP_VISION_RANGE) then
set rad = CREEP_VISION_RANGE
if c2.hasBuff(20) then // has Silent Step
set rad = rad - SilentStepAggroRange(c2.pid)
if rad < 0 then
set rad = 0
endif
endif
if IsUnitInRangeXY(c2.u, x, y, rad) then
set r = Atan2(GetUnitY(c2.u)-y, GetUnitX(c2.u)-x)
if RAbsBJ(PanelCore_AngularDifference(a, r)) < CREEP_VISION_ARC or IsUnitInRangeXY(c2.u, x, y, CREEP_SENSE_RADIUS) then
call switchTarget(c2.u)
endif
endif
endif
endloop
call DestroyGroup(PlayerUnits)
set PlayerUnits = g
set g = null
endmethod
private static method onPeriodic takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local unit fog
local group g
local real a
local real a2
local real x
local real y
local real x2
local real y2
local real dx
local real dy
local Combatant c2
if IsUnitAlive(.u) then
if (not .channeling) then
set a = GetUnitFacing(.u)*bj_DEGTORAD
set x = GetUnitX(.u)
set y = GetUnitY(.u)
if .utype == TYPE_DRYAD_ENCHANTRESS then
if not .channeling and not c.isDisarmed and not c.isStunned and not c.isAttacking and not c.isSilenced then
if .c.sp > 25 and .c.hp < .c.hpMax*0.5 then
set .c.sp = .c.sp - 25
call DryadEnchantress_AreaHeal.cast(c)
set .channeling = true
return
endif
endif
endif
if .isCoward then
set .target = null
if GetUnitCurrentOrder(.u) != ORDER_move then
call TimerStart(t, 0, false, null)
endif
else
if .target == null then
if not c.isStunned and GetUnitCurrentOrder(.u) != ORDER_move then
call searchPlayerUnit()
if .target != null then
call alert()
endif
endif
else
if IsUnitAlive(.target) and not .tdata.isInvulnerable and IsUnitVisible(.target, .c.owner) then
set x2 = GetUnitX(.target)
set y2 = GetUnitY(.target)
if not .c.isStunned then
set dx = x2-x
set dy = y2-y
if dx*dx+dy*dy > .c.attackRange*.c.attackRange then
if GetUnitCurrentOrder(.u) != OrderId("move") then
if not .c.isImmobilized then
call .c.follow(.target)
endif
else
set dx = CreepNestX[.data]-x
set dy = CreepNestY[.data]-y
if dx*dx+dy*dy > CREEP_MAX_CHASE_DISTANCE then
call abort()
call .c.move(CreepNestX[.data], CreepNestY[.data])
endif
endif
else
call IssueImmediateOrder(.u, "stop")
set a2 = Atan2(y2-y, x2-x)
call SetUnitFacing(.u, a2*bj_RADTODEG)
if RAbsBJ(PanelCore_AngularDifference(a, a2)) < 30*bj_DEGTORAD then
call .c.attack()
endif
endif
endif
else
call abort()
call searchPlayerUnit()
if .target == null then
call .c.move(CreepNestX[.data], CreepNestY[.data])
endif
endif
endif
endif
endif
else
call abort()
call TimerStart(t, 0, false, null)
endif
set t = null
endmethod
method enable takes nothing returns nothing
local real x
local real y
local real dx
local real dy
if enabled and .time != null then
set x = GetUnitX(.u)
set y = GetUnitY(.u)
set dx = CreepNestX[.data]-x
set dy = CreepNestY[.data]-y
if dx*dx+dy*dy <= CREEP_MAX_CHASE_DISTANCE and TimerGetTimeout(.time) == 0 then
call TimerStart(.time, 0.1, true, function thistype.onPeriodic)
endif
endif
endmethod
method damage takes Combatant c, real amount returns nothing
local unit t
local unit fog
local integer data2
local group g
local real r
local real x
local real y
local real dx
local real dy
local Combatant c2
local CreepAI ai
if IsUnitAlive(c.u) then
if not .channeling then
if .target == null then
if .isCoward then
if GetUnitCurrentOrder(.u) != ORDER_move then
set x = GetUnitX(.u)
set y = GetUnitY(.u)
set r = Atan2(y-GetUnitY(c.u), x-GetUnitX(c.u))
call .c.move(x+200.*Cos(r), y+200.*Sin(r))
endif
else
call switchTarget(c.u)
set ThreatLevel[.data].real[.tdata] = amount
endif
else
set ThreatLevel[.data].real[c] = ThreatLevel[.data].real[c] + amount
set t = .target
set r = ThreatLevel[.data].real[.tdata]
set g = CreateGroup()
loop
set fog = FirstOfGroup(PlayerUnits)
exitwhen fog == null
call GroupRemoveUnit(PlayerUnits, fog)
call GroupAddUnit(g, fog)
set c2 = Combatant[fog]
if IsPlaying[c2.pid] and c2 != .tdata and c2.hp > 0 then
if ThreatLevel[.data].real[c2] > r then
set t = fog
set r = ThreatLevel[.data].real[c2]
endif
endif
endloop
call DestroyGroup(PlayerUnits)
set PlayerUnits = g
if t != .target then
call switchTarget(t)
call resetThreatLevel()
set ThreatLevel[.data].real[.tdata] = amount
endif
set ShareThreat = false
if ShareThreat then
set ShareThreat = false
call GroupEnumUnitsInRange(Group, GetUnitX(.u), GetUnitY(.u), CREEP_SHARED_THREAT_DISTANCE, null)
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if fog != .u and GetOwningPlayer(fog) == CREEP_PLAYER and IsUnitAlive(fog) then
set ai = CreepAI[fog]
if ai.target != null then
set data2 = GetUnitUserData(fog)
set dx = CreepNestX[data2]-x
set dy = CreepNestY[data2]-y
if dx*dx+dy*dy <= CREEP_MAX_CHASE_DISTANCE then
call ai.damage(c, amount*CREEP_SHARED_THREAT_FACTOR)
endif
endif
endif
endloop
set ShareThreat = true
endif
endif
endif
call alert()
endif
endmethod
method destroy takes nothing returns nothing
call abort()
call ReleaseTimer(.time)
call ThreatLevel[.data].flush()
set UnitIndex[.data] = 0
call deallocate()
set .time = null
set .u = null
endmethod
static method create takes unit whichUnit returns thistype
local thistype this = 0
local integer data = GetUnitUserData(whichUnit)
if UnitIndex[data] == 0 then
set this = allocate()
set .u = whichUnit
set .c = Combatant[whichUnit]
set .time = NewTimerEx(this)
set .channeling = false
set .enabled = true
set .data = data
set .target = null
set .tdata = 0
set UnitIndex[data] = this
call TimerStart(.time, 0, false, null)
endif
return this
endmethod
private static method onDeindex takes nothing returns boolean
local thistype this = CreepAI[GetIndexedUnit()]
if this != 0 then
call destroy()
endif
return false
endmethod
private static method onInit takes nothing returns nothing
set ThreatLevel = TableArray[8192]
call RegisterUnitIndexEvent(Condition(function thistype.onDeindex), UnitIndexer.DEINDEX)
endmethod
endstruct
endlibrary
library CreepLib uses PanelCore
globals
private group Group = CreateGroup()
endglobals
function Exponent takes real a, real b returns real
return Pow(a, b)
endfunction
function IndexCreep takes unit u returns nothing
local Combatant c = Combatant.create(u)
local integer id = GetUnitTypeId(u)
local unit fog
if id == 'h00A' then // skeletal warrior
call CreepAI.create(u)
set c.dropQuality = 0
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = true
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 5.0*bj_DEGTORAD
set c.attackRange = 100.0
set c.dmgPoint = 1.0
set c.attackRateDef = 3.0
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 4
set c.physicDmgMax = 7
set c.physicDefense = 3
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 2
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0.05
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 0.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 55.0
set c.hpMax = c.hp
set c.hpRegen = 0.0
set c.sp = 0
set c.spMax = 0
set c.spRegen = 0
set c.xpMultiplier = 0.7
set c.wType = WEAPON_TYPE_METAL_MEDIUM_SLICE
set c.sfxId = 1
elseif id == 'h00B' then // skeletal archer
call CreepAI.create(u)
set c.dropQuality = 0
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = false
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = "Abilities\\Weapons\\Arrow\\ArrowMissile.mdl"
set c.missileCollision = 50.0
set c.missileScale = 0.5
set c.missileSpeed = 25.0
set c.missileArch = 15.*bj_DEGTORAD
set c.missileTurn = 5.*bj_DEGTORAD
set c.missileXY = 35
set c.missileZ = 40
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 600.0
set c.dmgPoint = 0.7
set c.attackRateDef = 3.5
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 3
set c.physicDmgMax = 5
set c.physicDefense = 2
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 1
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 0.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 40.0
set c.hpMax = c.hp
set c.hpRegen = 0.0
set c.sp = 0
set c.spMax = 0
set c.spRegen = 0
set c.xpMultiplier = 0.7
set c.wType = WEAPON_TYPE_WHOKNOWS
set c.sfxId = 2
elseif id == 'h00Q' then // kobold tunneler
call CreepAI.create(u)
set c.dropQuality = 0
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = true
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 5.0*bj_DEGTORAD
set c.attackRange = 100.0
set c.dmgPoint = 0.6
set c.attackRateDef = 2.8
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 4
set c.physicDmgMax = 7
set c.physicDefense = 4.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 1.5
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0.00
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 0.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 50.0
set c.hpMax = c.hp
set c.hpRegen = 1.0
set c.sp = 20
set c.spMax = 20
set c.spRegen = 0
set c.xpMultiplier = 0.8
set c.fireElement = 0.0
set c.waterElement = 0.0
set c.earthElement = 2.0
set c.windElement = 0.0
set c.wType = WEAPON_TYPE_METAL_MEDIUM_CHOP
set c.sfxId = 3
elseif id == 'h010' then // kobold basher
call CreepAI.create(u)
set c.dropQuality = 1
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = true
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 100.0
set c.dmgPoint = 0.6
set c.attackRateDef = 3.1
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 7
set c.physicDmgMax = 15
set c.physicDefense = 6.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 1.6
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0.00
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 50.0
set c.interrupt = 0.0
set c.interruptResist = 0.15
set c.stun = 0.2
set c.stunResist = 0.0
set c.hp = 105.0
set c.hpMax = c.hp
set c.hpRegen = 1.0
set c.sp = 25
set c.spMax = 25
set c.spRegen = 0
set c.xpMultiplier = 2.0
set c.fireElement = 0.0
set c.waterElement = 0.0
set c.earthElement = 5.0
set c.windElement = 0.0
set c.wType = WEAPON_TYPE_METAL_MEDIUM_BASH
set c.sfxId = 4
elseif id == 'h00R' then // kobold geomancer
call CreepAI.create(u)
set c.dropQuality = 1
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = false
set c.missileHoming = true
set c.missilePiercing = false
set c.missile = "Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl"
set c.missileCollision = 50.0
set c.missileScale = 1.0
set c.missileSpeed = 20.0
set c.missileArch = 20.*bj_DEGTORAD
set c.missileTurn = 1.*bj_DEGTORAD
set c.missileXY = 35
set c.missileZ = 40
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 700.0
set c.dmgPoint = 0.6
set c.attackRateDef = 3.5
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 0
set c.physicDmgMax = 0
set c.physicDefense = 2.
set c.magicDmgMin = 8
set c.magicDmgMax = 13
set c.magicDefense = 4.
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 25.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 85.0
set c.hpMax = c.hp
set c.hpRegen = 1.0
set c.sp = 40.0
set c.spMax = 40.0
set c.spRegen = 0
set c.xpMultiplier = 2.0
set c.fireElement = 5.0
set c.waterElement = 0.0
set c.earthElement = 0.0
set c.windElement = 0.0
set c.wType = WEAPON_TYPE_WHOKNOWS
set c.sfxId = 5
elseif id == 'h00X' then // kobold nest
set c.melee = true
set c.dropQuality = 1
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 100.0
set c.dmgPoint = 0.6
set c.attackRateDef = 0.0
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 0
set c.physicDmgMax = 0
set c.physicDefense = 6.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 0.5
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0.00
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 0.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 70.0
set c.hpMax = c.hp
set c.hpRegen = 0.0
set c.sp = 0
set c.spMax = 0
set c.spRegen = 0
set c.xpMultiplier = 0.1
set c.fireElement = 0.0
set c.waterElement = 0.0
set c.earthElement = 5.0
set c.windElement = 0.0
set c.wType = WEAPON_TYPE_METAL_MEDIUM_CHOP
set c.sfxId = 0
call KoboldSpawner.create(u)
call UnitRemoveAbility(u, 'Amov')
call GroupEnumUnitsInRange(Group, GetUnitX(u), GetUnitY(u), 2000., Filter(function FilterOutUI))
loop
set fog = FirstOfGroup(Group)
exitwhen fog == null
call GroupRemoveUnit(Group, fog)
if fog != u and GetUnitTypeId(fog) == 'h00X' and GetOwningPlayer(fog) == CREEP_PLAYER then
call RemoveUnit(fog)
endif
endloop
elseif id == 'h002' then // training dummy
set c.melee = true
set c.dropQuality = -1
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = true
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 100.0
set c.dmgPoint = 0.6
set c.attackRateDef = 3600.0
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 0
set c.physicDmgMax = 0
set c.physicDefense = 1.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 0.6
set c.criticalRate = 0.0
set c.criticalPower = 0.0
set c.blockRate = 0.00
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 0.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 1.0
set c.hpMax = c.hp
set c.hpRegen = 0.0
set c.sp = 0
set c.spMax = 0
set c.spRegen = 0
set c.xpMultiplier = 0.0
set c.wType = WEAPON_TYPE_METAL_MEDIUM_CHOP
set c.sfxId = 0
call UnitRemoveAbility(u, 'Amov')
elseif id == 'h003' then // Pitch Boiler
set c.melee = true
set c.dropQuality = -1
set c.noRemove = false
set c.hitsToKill = true
set c.destructible = true
set c.ignoreDamage = true
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 100.0
set c.dmgPoint = 0.6
set c.attackRateDef = 0.0
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 0
set c.physicDmgMax = 0
set c.physicDefense = 1.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 0.6
set c.criticalRate = 0.0
set c.criticalPower = 0.0
set c.blockRate = 0.00
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 0.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 1.0
set c.hpMax = c.hp
set c.hpRegen = 0.0
set c.sp = 0
set c.spMax = 0
set c.spRegen = 0
set c.xpMultiplier = 0.0
set c.wType = WEAPON_TYPE_METAL_MEDIUM_CHOP
set c.sfxId = 0
call UnitRemoveAbility(u, 'Amov')
elseif id == 'h005' then // Locked Gate
set c.melee = true
set c.dropQuality = -1
set c.hitsToKill = true
set c.noRemove = true
set c.destructible = true
set c.ignoreDamage = true
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 100.0
set c.dmgPoint = 0.6
set c.attackRateDef = 0.0
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 0
set c.physicDmgMax = 0
set c.physicDefense = 1.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 0.6
set c.criticalRate = 0.0
set c.criticalPower = 0.0
set c.blockRate = 0.00
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 0.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 3.0
set c.hpMax = c.hp
set c.hpRegen = 0.0
set c.sp = 0
set c.spMax = 0
set c.spRegen = 0
set c.xpMultiplier = 0.0
set c.wType = WEAPON_TYPE_METAL_MEDIUM_CHOP
set c.sfxId = 0
call UnitRemoveAbility(u, 'Amov')
elseif id == 'h006' then // harpy rogue
call CreepAI.create(u)
set c.dropQuality = 0
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = false
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = "Abilities\\Weapons\\HarpyMissile\\HarpyMissile.mdl"
set c.missileCollision = 50.0
set c.missileScale = 0.5
set c.missileSpeed = 20.0
set c.missileArch = 15.*bj_DEGTORAD
set c.missileTurn = 5.*bj_DEGTORAD
set c.missileXY = 35
set c.missileZ = 30
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 500.0
set c.dmgPoint = 0.3
set c.attackRateDef = 3.35
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 3
set c.physicDmgMax = 5
set c.physicDefense = 1.0
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 0.2
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 0.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 40.0
set c.hpMax = c.hp
set c.hpRegen = 0.0
set c.sp = 20
set c.spMax = 20
set c.spRegen = 0
set c.xpMultiplier = 0.8
set c.fireElement = 0.0
set c.waterElement = 0.0
set c.earthElement = 0.0
set c.windElement = 2.0
set c.wType = WEAPON_TYPE_WHOKNOWS
set c.sfxId = 6
elseif id == 'h00D' then // harpy witch
call CreepAI.create(u)
set c.dropQuality = 1
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = false
set c.missileHoming = true
set c.missilePiercing = false
set c.missile = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
set c.missileCollision = 50.0
set c.missileScale = 1.0
set c.missileSpeed = 20.0
set c.missileArch = 20.*bj_DEGTORAD
set c.missileTurn = 1.*bj_DEGTORAD
set c.missileXY = 35
set c.missileZ = 30
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 600.0
set c.dmgPoint = 0.3
set c.attackRateDef = 3.7
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 0
set c.physicDmgMax = 0
set c.physicDefense = 4.
set c.magicDmgMin = 6
set c.magicDmgMax = 13
set c.magicDefense = 2.
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 10.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 85.0
set c.hpMax = c.hp
set c.hpRegen = 1.0
set c.sp = 45.0
set c.spMax = 45.0
set c.spRegen = 0
set c.xpMultiplier = 3.0
set c.fireElement = 0.0
set c.waterElement = 0.0
set c.earthElement = 0.0
set c.windElement = 2.0
set c.wType = WEAPON_TYPE_WHOKNOWS
set c.sfxId = 6
elseif id == 'h00E' then // harpy queen
call CreepAI.create(u)
set c.dropQuality = 2
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = false
set c.missileHoming = false
set c.missilePiercing = true
set c.missile = "war3mapImported\\FeatherMissile.mdx"
set c.missileCollision = 75.0
set c.missileScale = 3.0
set c.missileSpeed = 30.0
set c.missileArch = 0.0
set c.missileTurn = 1.*bj_DEGTORAD
set c.missileXY = 35
set c.missileZ = 30
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 600.0
set c.dmgPoint = 0.3
set c.attackRateDef = 3.7
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 10
set c.physicDmgMax = 15
set c.physicDefense = 7.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 5.
set c.criticalRate = 0.155
set c.criticalPower = 0.75
set c.blockRate = 0
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 50.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 190.0
set c.hpMax = c.hp
set c.hpRegen = 2.0
set c.sp = 50
set c.spMax = 50
set c.spRegen = 0
set c.xpMultiplier = 7.5
set c.fireElement = 0.0
set c.waterElement = 0.0
set c.earthElement = 0.0
set c.windElement = 10.0
set c.wType = WEAPON_TYPE_WHOKNOWS
set c.sfxId = 6
elseif id == 'h00F' then // Dryad Lancer
call CreepAI.create(u)
set c.dropQuality = 1
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = false
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = "Abilities\\Weapons\\Dryadmissile\\Dryadmissile.mdl"
set c.missileCollision = 50.0
set c.missileScale = 1.0
set c.missileSpeed = 20.0
set c.missileArch = 15.*bj_DEGTORAD
set c.missileTurn = 5.*bj_DEGTORAD
set c.missileXY = 35
set c.missileZ = 30
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 500.0
set c.dmgPoint = 0.3
set c.attackRateDef = 3.6
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 6
set c.physicDmgMax = 9
set c.physicDefense = 1.5
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 4.0
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 20.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 75.0
set c.hpMax = c.hp
set c.hpRegen = 1.0
set c.sp = 30
set c.spMax = 30
set c.spRegen = 0
set c.xpMultiplier = 2.0
set c.fireElement = 0.0
set c.waterElement = 0.0
set c.earthElement = 5.0
set c.windElement = 0.0
set c.wType = WEAPON_TYPE_WHOKNOWS
set c.sfxId = 0
elseif id == 'h00G' then // Dryad Mauler
call CreepAI.create(u)
set c.dropQuality = 1
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = true
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 80.0*bj_DEGTORAD
set c.attackRange = 135.0
set c.dmgPoint = 0.6
set c.attackRateDef = 3.3
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 8
set c.physicDmgMax = 13
set c.physicDefense = 5.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 3.0
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0.00
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 50.0
set c.interrupt = 0.0
set c.interruptResist = 0.25
set c.stun = 0.3
set c.stunResist = 0.0
set c.hp = 110.0
set c.hpMax = c.hp
set c.hpRegen = 1.0
set c.sp = 25
set c.spMax = 25
set c.spRegen = 0
set c.xpMultiplier = 2.0
set c.fireElement = 0.0
set c.waterElement = 0.0
set c.earthElement = 5.0
set c.windElement = 0.0
set c.wType = WEAPON_TYPE_ROCK_HEAVY_BASH
set c.sfxId = 7
elseif id == 'h00H' then // Dryad Enchantress
set CreepAI.create(u).utype = CreepAI.TYPE_DRYAD_ENCHANTRESS
set c.dropQuality = 2
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = false
set c.missileHoming = true
set c.missilePiercing = false
set c.missile = "Abilities\\Weapons\\DragonHawkMissile\\DragonHawkMissile.mdl"
set c.missileCollision = 75.0
set c.missileScale = 1.0
set c.missileSpeed = 25.0
set c.missileArch = 0.0
set c.missileTurn = 1.5*bj_DEGTORAD
set c.missileXY = 50
set c.missileZ = 50
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 700.0
set c.dmgPoint = 0.3
set c.attackRateDef = 3.2
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 0
set c.physicDmgMax = 0
set c.physicDefense = 6.
set c.magicDmgMin = 9
set c.magicDmgMax = 15
set c.magicDefense = 6.
set c.criticalRate = 0.155
set c.criticalPower = 0.75
set c.blockRate = 0
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 50.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 225.0
set c.hpMax = c.hp
set c.hpRegen = 2.0
set c.sp = 200
set c.spMax = c.sp
set c.spRegen = 1.0
set c.xpMultiplier = 7.5
set c.fireElement = 0.0
set c.waterElement = 0.0
set c.earthElement = 10.0
set c.windElement = 0.0
set c.wType = WEAPON_TYPE_WHOKNOWS
set c.sfxId = 0
elseif id == 'h00I' then // Treant
call CreepAI.create(u)
set c.dropQuality = 0
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = true
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 5.0*bj_DEGTORAD
set c.attackRange = 100.0
set c.dmgPoint = 0.467
set c.attackRateDef = 3.4
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 4
set c.physicDmgMax = 9
set c.physicDefense = 10.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 1.5
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0.00
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 10.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 70.0
set c.hpMax = c.hp
set c.hpRegen = 1.0
set c.sp = 10
set c.spMax = 10
set c.spRegen = 0
set c.xpMultiplier = 0.8
set c.fireElement = 0.0
set c.waterElement = 0.0
set c.earthElement = 5.0
set c.windElement = 0.0
set c.wType = WEAPON_TYPE_WOOD_MEDIUM_BASH
set c.sfxId = 8
elseif id == 'h00J' then // skeletal axeman
call CreepAI.create(u)
set c.dropQuality = 1
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = true
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 100.0
set c.dmgPoint = 0.56
set c.attackRateDef = 3.3
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 7
set c.physicDmgMax = 10
set c.physicDefense = 4.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 2.0
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0.00
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 10.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 100.0
set c.hpMax = c.hp
set c.hpRegen = 1.0
set c.sp = 20
set c.spMax = 20
set c.spRegen = 0
set c.xpMultiplier = 2.0
set c.wType = WEAPON_TYPE_METAL_MEDIUM_CHOP
set c.sfxId = 1
elseif id == 'h00K' then // skeletal magus
call CreepAI.create(u)
set c.dropQuality = 1
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = false
set c.missileHoming = true
set c.missilePiercing = false
set c.missile = "Abilities\\Weapons\\SkeletalMageMissile\\SkeletalMageMissile.mdl"
set c.missileCollision = 50.0
set c.missileScale = 1.0
set c.missileSpeed = 20.0
set c.missileArch = 20.*bj_DEGTORAD
set c.missileTurn = 1.*bj_DEGTORAD
set c.missileXY = 35
set c.missileZ = 40
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 700.0
set c.dmgPoint = 0.5
set c.attackRateDef = 3.6
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 0
set c.physicDmgMax = 0
set c.physicDefense = 7.
set c.magicDmgMin = 8
set c.magicDmgMax = 14
set c.magicDefense = 3.
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 0.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 95.0
set c.hpMax = c.hp
set c.hpRegen = 1.0
set c.sp = 60.0
set c.spMax = 60.0
set c.spRegen = 0
set c.xpMultiplier = 2.0
set c.wType = WEAPON_TYPE_WHOKNOWS
set c.sfxId = 2
elseif id == 'h00L' then // sludge monster
call CreepAI.create(u)
set c.dropQuality = 2
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = false
set c.missileHoming = true
set c.missilePiercing = false
set c.missile = "Abilities\\Weapons\\SludgeMissile\\SludgeMissile.mdl"
set c.missileCollision = 50.0
set c.missileScale = 1.0
set c.missileSpeed = 25.0
set c.missileArch = 20.*bj_DEGTORAD
set c.missileTurn = 1.5*bj_DEGTORAD
set c.missileXY = 50
set c.missileZ = 40
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 800.0
set c.dmgPoint = 0.3
set c.attackRateDef = 3.1
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 10
set c.physicDmgMax = 16
set c.physicDefense = 12.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 2.
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 100.0
set c.interrupt = 0.0
set c.interruptResist = 1.0
set c.stun = 0.0
set c.stunResist = 1.0
set c.hp = 260.0
set c.hpMax = c.hp
set c.hpRegen = 2.0
set c.sp = 55
set c.spMax = 55
set c.spRegen = 0
set c.xpMultiplier = 7.5
set c.fireElement = 0.0
set c.waterElement = 15.0
set c.earthElement = 0.0
set c.windElement = 0.0
set c.wType = WEAPON_TYPE_WHOKNOWS
set c.sfxId = 9
call TriggerRegisterUnitEvent(SludgeSplitTrigger, u, EVENT_UNIT_DEATH)
elseif id == 'h00P' then // crawler venom
call CreepAI.create(u)
set c.dropQuality = 1
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = false
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = "Abilities\\Weapons\\ChimaeraAcidMissile\\ChimaeraAcidMissile.mdl"
set c.missileCollision = 50.0
set c.missileScale = 1.0
set c.missileSpeed = 15.0
set c.missileArch = 20.*bj_DEGTORAD
set c.missileTurn = 1.*bj_DEGTORAD
set c.missileXY = 35
set c.missileZ = 30
set c.dmgAoE = 128
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 450.0
set c.dmgPoint = 0.6
set c.attackRateDef = 4.15
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 7
set c.physicDmgMax = 9
set c.physicDefense = 1.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 0.
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 0.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 75.0
set c.hpMax = c.hp
set c.hpRegen = 1.0
set c.sp = 25
set c.spMax = 25
set c.spRegen = 0
set c.xpMultiplier = 1.75
set c.fireElement = 0.0
set c.waterElement = 0.0
set c.earthElement = 5.0
set c.windElement = 0.0
set c.wType = WEAPON_TYPE_WHOKNOWS
set c.sfxId = 10
call c.applyBuff(13, 0, null)
elseif id == 'h00S' then // crawler bane
call CreepAI.create(u)
set c.dropQuality = 1
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = true
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 5.0*bj_DEGTORAD
set c.attackRange = 100.0
set c.dmgPoint = 0.7
set c.attackRateDef = 3.0
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 8
set c.physicDmgMax = 11
set c.physicDefense = 2.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 1.0
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0.00
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 0.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 95.0
set c.hpMax = c.hp
set c.hpRegen = 1.0
set c.sp = 20
set c.spMax = 20
set c.spRegen = 0
set c.xpMultiplier = 2.0
set c.fireElement = 0.0
set c.waterElement = 0.0
set c.earthElement = 5.0
set c.windElement = 0.0
set c.wType = WEAPON_TYPE_WOOD_MEDIUM_BASH
set c.sfxId = 11
call c.applyBuff(13, 0, null)
elseif id == 'h00T' then // Gargoyle statue
set c.melee = true
set c.dropQuality = -1
set c.hitsToKill = true
set c.noRemove = true
set c.destructible = false
set c.ignoreDamage = true
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 100.0
set c.dmgPoint = 0.6
set c.attackRateDef = 0.0
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 0
set c.physicDmgMax = 0
set c.physicDefense = 1.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 0.6
set c.criticalRate = 0.0
set c.criticalPower = 0.0
set c.blockRate = 0.00
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 0.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 5.0
set c.hpMax = c.hp
set c.hpRegen = 0.0
set c.sp = 0
set c.spMax = 0
set c.spRegen = 0
set c.xpMultiplier = 0.0
set c.wType = WEAPON_TYPE_METAL_MEDIUM_CHOP
set c.sfxId = 0
call c.invulnerable(0, 84000, null)
elseif id == 'h00U' then // gargoyle
call CreepAI.create(u)
set c.dropQuality = 1
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = true
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 45.0*bj_DEGTORAD
set c.attackRange = 50.0
set c.dmgPoint = 0.7
set c.attackRateDef = 4.0
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 13
set c.physicDmgMax = 21
set c.physicDefense = 1.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 3.0
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0.00
set c.evasionRate = 0
set c.knockback = 45.0
set c.knockbackResist = 999.0
set c.interrupt = 0.0
set c.interruptResist = 999.0
set c.stun = 0.0
set c.stunResist = 999.0
set c.hp = 110.0
set c.hpMax = c.hp
set c.hpRegen = 1.0
set c.sp = 0
set c.spMax = 0
set c.spRegen = 0
set c.xpMultiplier = 2.0
set c.wType = WEAPON_TYPE_WOOD_MEDIUM_BASH
set c.sfxId = 12
elseif id == 'h02T' then // spiderling
call CreepAI.create(u)
set c.dropQuality = 0
set c.noRemove = false
set c.hitsToKill = false
set c.destructible = false
set c.ignoreDamage = false
set c.melee = true
set c.missileHoming = false
set c.missilePiercing = false
set c.missile = ""
set c.missileCollision = 50.0
set c.missileScale = 0.0
set c.missileSpeed = 0.0
set c.missileArch = 0
set c.missileTurn = 0
set c.missileXY = 0
set c.missileZ = 0
set c.dmgAoE = 0
set c.attackRadius = 5.0*bj_DEGTORAD
set c.attackRange = 100.0
set c.dmgPoint = 0.6
set c.attackRateDef = 2.7
set c.attackRate = c.attackRateDef
set c.physicDmgMin = 3
set c.physicDmgMax = 7
set c.physicDefense = 3.
set c.magicDmgMin = 0
set c.magicDmgMax = 0
set c.magicDefense = 1.5
set c.criticalRate = 0.15
set c.criticalPower = 0.75
set c.blockRate = 0.0
set c.evasionRate = 0
set c.knockback = 0.0
set c.knockbackResist = 0.0
set c.interrupt = 0.0
set c.interruptResist = 0.0
set c.stun = 0.0
set c.stunResist = 0.0
set c.hp = 50.0
set c.hpMax = c.hp
set c.hpRegen = 1.0
set c.sp = 0
set c.spMax = 0
set c.spRegen = 0
set c.xpMultiplier = 0.8
set c.fireElement = 0.0
set c.waterElement = 0.0
set c.earthElement = 2.0
set c.windElement = 0.0
set c.wType = WEAPON_TYPE_METAL_MEDIUM_CHOP
set c.sfxId = 13
endif
endfunction
function AdjustCreepPhysicDefense takes Combatant c, integer level returns nothing
local real b1 /*Value at value min level 1*/ = PA_level_1_val_1
local real b2 /*Value at value min level 100*/ = PA_level_max_val_1
local real t1 /*Value at value max level 1*/ = PA_level_1_val_max
local real t2 /*Value at value max level 100*/ = PA_level_max_val_max
local real f = CalculateStatusBaseFactor(c.physicDefense - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
set c.physicDefense = c.physicDefense + CalculateStatusValue(t, level)
endfunction
function AdjustCreepMagicDefense takes Combatant c, integer level returns nothing
local real b1 /*Value at value min level 1*/ = MA_level_1_val_1
local real b2 /*Value at value min level 100*/ = MA_level_max_val_1
local real t1 /*Value at value max level 1*/ = MA_level_1_val_max
local real t2 /*Value at value max level 100*/ = MA_level_max_val_max
local real f = CalculateStatusBaseFactor(c.magicDefense - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
set c.magicDefense = c.magicDefense + CalculateStatusValue(t, level)
endfunction
function AdjustCreepHealth takes Combatant c, integer level returns nothing
local real b1 /*Value at value min level 1*/ = HP_level_1_val_1
local real b2 /*Value at value min level 100*/ = HP_level_max_val_1
local real t1 /*Value at value max level 1*/ = HP_level_1_val_max
local real t2 /*Value at value max level 100*/ = HP_level_max_val_max
local real f = CalculateStatusBaseFactor(c.hpMax - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
set c.hpMax = c.hpMax + CalculateStatusValue(t, level)
endfunction
function AdjustCreepPDamage takes Combatant c, integer level returns nothing
local real b1 /*Value at value min level 1*/ = PD_level_1_val_1
local real b2 /*Value at value min level 100*/ = PD_level_max_val_1
local real t1 /*Value at value max level 1*/ = PD_level_1_val_max
local real t2 /*Value at value max level 100*/ = PD_level_max_val_max
local real f = CalculateStatusBaseFactor(c.physicDmgMin - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
local real range = c.physicDmgMax - c.physicDmgMin
if (c.physicDmgMin > 0) then
set c.physicDmgMin = c.physicDmgMin + CalculateStatusValue(t, level)
// Calculate dice
set b1 /*Value at value min level 1*/ = DC_level_1_val_1
set b2 /*Value at value min level 100*/ = DC_level_max_val_1
set t1 /*Value at value max level 1*/ = DC_level_1_val_max
set t2 /*Value at value max level 100*/ = DC_level_max_val_max
set b = (range - b1) / (t1 - b1) * (t2 - b2) * (level / MAXIMUM_LEVEL)
set c.physicDmgMax = c.physicDmgMin + (range + b)
else
set c.physicDmgMin = 0
set c.physicDmgMax = 0
endif
endfunction
function AdjustCreepMDamage takes Combatant c, integer level returns nothing
local real b1 /*Value at value min level 1*/ = MD_level_1_val_1
local real b2 /*Value at value min level 100*/ = MD_level_max_val_1
local real t1 /*Value at value max level 1*/ = MD_level_1_val_max
local real t2 /*Value at value max level 100*/ = MD_level_max_val_max
local real f = CalculateStatusBaseFactor(c.magicDmgMin - b1, t1 - b1)
local real b = b1 + (t1 - b1) * f
local real t = (b2 + (t2 - b2) * f) - b
local real range = c.magicDmgMax - c.magicDmgMin
if (c.magicDmgMin > 0) then
set c.magicDmgMin = c.magicDmgMin + CalculateStatusValue(t, level)
// Calculate dice
set b1 /*Value at value min level 1*/ = DC_level_1_val_1
set b2 /*Value at value min level 100*/ = DC_level_max_val_1
set t1 /*Value at value max level 1*/ = DC_level_1_val_max
set t2 /*Value at value max level 100*/ = DC_level_max_val_max
set b = (range - b1) / (t1 - b1) * (t2 - b2) * (level / MAXIMUM_LEVEL)
set c.magicDmgMax = c.magicDmgMin + (range + b)
else
set c.magicDmgMin = 0
set c.magicDmgMax = 0
endif
endfunction
function AdjustCreepStrength takes Combatant c, integer level returns nothing
if c.destructible then
return
endif
//set level = 35
set c.level = level
call AdjustCreepPhysicDefense(c, level)
call AdjustCreepMagicDefense(c, level)
call AdjustCreepHealth(c, level)
call AdjustCreepPDamage(c, level)
call AdjustCreepMDamage(c, level)
set c.physicDmgMin = c.physicDmgMin * (1.+ActiveScroll.physicDmgPctg)
set c.physicDmgMax = c.physicDmgMax * (1.+ActiveScroll.physicDmgPctg)
set c.physicDefense = c.physicDefense * (1.+ActiveScroll.physicDefPctg)
set c.magicDmgMin = c.magicDmgMin * (1.+ActiveScroll.magicDmgPctg)
set c.magicDmgMax = c.magicDmgMax * (1.+ActiveScroll.magicDmgPctg)
set c.magicDefense = c.magicDefense * (1.+ActiveScroll.magicDefPctg)
set c.attackRate = c.attackRate / (1.+ActiveScroll.aspdPctg)
set c.hpMax = c.hpMax * (1.+ActiveScroll.hpPctg)
set c.hp = c.hpMax
set c.spMax = c.sp
call SetUnitMoveSpeed(c.u, GetUnitMoveSpeed(c.u) * (1.+ActiveScroll.mspdPctg))
endfunction
endlibrary
library CreepSfx initializer init uses PanelCore
globals
private sound array AttackSounds[200][4]
private sound array AlertSounds[200][4]
private integer array AttackSoundCt
private integer array AlertSoundCt
private timer array AlertDelay
private timer array AttackDelay
endglobals
private function init takes nothing returns nothing
set AttackSounds [1][0] = null
set AttackSoundCt[1] = 0
set AlertSounds [1][0] = CreateSound("Units\\Undead\\Skeleton\\SkeletonWhat1.wav", false, true, true, 12700, 12700, "")
set AlertSounds [1][1] = CreateSound("Units\\Undead\\Skeleton\\SkeletonWhat2.wav", false, true, true, 12700, 12700, "")
set AlertSounds [1][2] = CreateSound("Units\\Undead\\Skeleton\\SkeletonWhat3.wav", false, true, true, 12700, 12700, "")
set AlertSoundCt [1] = 3
set AttackSounds [2][0] = null
set AttackSoundCt[2] = 0
set AlertSounds [2][0] = CreateSound("Units\\Undead\\Skeleton\\SkeletonYesAttack1.wav", false, true, true, 12700, 12700, "")
set AlertSounds [2][1] = CreateSound("Units\\Undead\\Skeleton\\SkeletonYesAttack2.wav", false, true, true, 12700, 12700, "")
set AlertSoundCt [2] = 2
set AttackSounds [3][0] = CreateSound("Units\\Creeps\\Kobold\\KoboldYes1.wav", false, true, true, 12700, 12700, "")
set AttackSounds [3][1] = CreateSound("Units\\Creeps\\Kobold\\KoboldYes2.wav", false, true, true, 12700, 12700, "")
set AttackSounds [3][2] = CreateSound("Units\\Creeps\\Kobold\\KoboldYes3.wav", false, true, true, 12700, 12700, "")
set AttackSoundCt[3] = 3
set AlertSounds [3][0] = CreateSound("Units\\Creeps\\Kobold\\KoboldYesAttack1.wav", false, true, true, 12700, 12700, "")
set AlertSounds [3][1] = CreateSound("Units\\Creeps\\Kobold\\KoboldYesAttack2.wav", false, true, true, 12700, 12700, "")
set AlertSounds [3][2] = CreateSound("Units\\Creeps\\Kobold\\KoboldYesAttack3.wav", false, true, true, 12700, 12700, "")
set AlertSoundCt [3] = 3
set AttackSounds [4][0] = CreateSound("Units\\Creeps\\Furbolg\\FurbolgYesAttack1.wav", false, true, true, 12700, 12700, "")
set AttackSounds [4][1] = CreateSound("Units\\Creeps\\Furbolg\\FurbolgYesAttack2.wav", false, true, true, 12700, 12700, "")
set AttackSounds [4][2] = CreateSound("Units\\Creeps\\Furbolg\\FurbolgYesAttack3.wav", false, true, true, 12700, 12700, "")
set AttackSoundCt[4] = 3
set AlertSounds [4][0] = CreateSound("Units\\Creeps\\Furbolg\\FurbolgWhat1.wav", false, true, true, 12700, 12700, "")
set AlertSounds [4][1] = CreateSound("Units\\Creeps\\Furbolg\\FurbolgWhat2.wav", false, true, true, 12700, 12700, "")
set AlertSounds [4][2] = CreateSound("Units\\Creeps\\Furbolg\\FurbolgWhat3.wav", false, true, true, 12700, 12700, "")
set AlertSoundCt [4] = 3
set AttackSounds [5][0] = CreateSound("Units\\Creeps\\Kobold\\KoboldPissed1.wav", false, true, true, 12700, 12700, "")
set AttackSounds [5][1] = CreateSound("Units\\Creeps\\Kobold\\KoboldPissed2.wav", false, true, true, 12700, 12700, "")
set AttackSounds [5][2] = CreateSound("Units\\Creeps\\Kobold\\KoboldPissed3.wav", false, true, true, 12700, 12700, "")
set AttackSounds [5][3] = CreateSound("Units\\Creeps\\Kobold\\KoboldPissed4.wav", false, true, true, 12700, 12700, "")
set AttackSoundCt[5] = 4
set AlertSounds [5][0] = CreateSound("Units\\Creeps\\Kobold\\KoboldReady1.wav", false, true, true, 12700, 12700, "")
set AlertSoundCt [5] = 1
set AttackSounds [6][0] = CreateSound("Units\\Creeps\\Harpy\\HarpyYesAttack1.wav", false, true, true, 12700, 12700, "")
set AttackSounds [6][1] = CreateSound("Units\\Creeps\\Harpy\\HarpyYesAttack2.wav", false, true, true, 12700, 12700, "")
set AttackSounds [6][2] = CreateSound("Units\\Creeps\\Harpy\\HarpyYes2.wav", false, true, true, 12700, 12700, "")
set AttackSounds [6][3] = CreateSound("Units\\Creeps\\Harpy\\HarpyYes3.wav", false, true, true, 12700, 12700, "")
set AttackSoundCt[6] = 4
set AlertSounds [6][0] = CreateSound("Units\\Creeps\\Harpy\\HarpyWhat1.wav", false, true, true, 12700, 12700, "")
set AlertSounds [6][1] = CreateSound("Units\\Creeps\\Harpy\\HarpyWhat2.wav", false, true, true, 12700, 12700, "")
set AlertSoundCt [6] = 2
set AttackSounds [7][0] = CreateSound("Units\\Creeps\\Beastmaster\\BeastmasterAttackEffort1.wav", false, true, true, 12700, 12700, "")
set AttackSounds [7][1] = CreateSound("Units\\Creeps\\Beastmaster\\BeastmasterAttackEffort2.wav", false, true, true, 12700, 12700, "")
set AttackSoundCt[7] = 2
set AlertSounds [7][0] = null
set AlertSoundCt [7] = 0
set AttackSounds [8][0] = null
set AttackSoundCt[8] = 0
set AlertSounds [8][0] = CreateSound("Units\\NightElf\\Ent\\EntWhat1.wav", false, true, true, 12700, 12700, "")
set AlertSoundCt [8] = 1
set AttackSounds [9][0] = CreateSound("Units\\Creeps\\Lobstrokkblue\\LobstrokkYes2.wav", false, true, true, 12700, 12700, "")
set AttackSoundCt[9] = 1
set AlertSounds [9][0] = null
set AlertSoundCt [9] = 0
set AttackSounds [10][0] = null
set AttackSoundCt[10] = 0
set AlertSounds [10][0] = CreateSound("Units\\Critters\\Hydralisk\\HydraliskYes1.wav", false, true, true, 12700, 12700, "")
set AlertSounds [10][1] = CreateSound("Units\\Critters\\Hydralisk\\HydraliskYes2.wav", false, true, true, 12700, 12700, "")
set AlertSounds [10][2] = CreateSound("Units\\Critters\\Hydralisk\\HydraliskYes3.wav", false, true, true, 12700, 12700, "")
set AlertSoundCt [10] = 3
set AttackSounds [11][0] = null
set AttackSoundCt[11] = 0
set AlertSounds [11][0] = CreateSound("Units\\Critters\\Hydralisk\\HydraliskYesAttack1.wav", false, true, true, 12700, 12700, "")
set AlertSounds [11][1] = CreateSound("Units\\Critters\\Hydralisk\\HydraliskYesAttack2.wav", false, true, true, 12700, 12700, "")
set AlertSoundCt [11] = 2
set AttackSounds [12][0] = CreateSound("Units\\Undead\\Gargoyle\\GargoyleYesAttack1.wav", false, true, true, 12700, 12700, "")
set AttackSounds [12][1] = CreateSound("Units\\Undead\\Gargoyle\\GargoyleYesAttack2.wav", false, true, true, 12700, 12700, "")
set AttackSoundCt[12] = 2
set AlertSounds [12][0] = CreateSound("Units\\Undead\\Gargoyle\\GargoyleReady1.wav", false, true, true, 12700, 12700, "")
set AlertSoundCt [12] = 1
set AttackSounds [13][0] = null
set AttackSoundCt[13] = 0
set AlertSounds [13][0] = CreateSound("Units\\Creeps\\Spider\\SpiderWhat1.wav", false, true, true, 12700, 12700, "")
set AlertSounds [13][1] = CreateSound("Units\\Creeps\\Spider\\SpiderWhat2.wav", false, true, true, 12700, 12700, "")
set AlertSoundCt [13] = 2
endfunction
public function attack takes Combatant c returns nothing
local integer dex
if c.owner == CREEP_PLAYER and AttackSoundCt[c.sfxId] > 0 then
if AttackDelay[c.sfxId] == null then
set AttackDelay[c.sfxId] = CreateTimer()
endif
if TimerGetRemaining(AttackDelay[c.sfxId]) <= 0.01 then
set dex = GetRandomInt(0, AttackSoundCt[c.sfxId] - 1)
call SetSoundPosition(AttackSounds[c.sfxId][dex], GetUnitX(c.u), GetUnitY(c.u), PanelCore_GetUnitZ(c.u))
call SetSoundVolume(AttackSounds[c.sfxId][dex], 200)
call StartSound(AttackSounds[c.sfxId][dex])
call TimerStart(AttackDelay[c.sfxId], 1.0, false, null)
endif
endif
endfunction
public function alert takes Combatant c returns nothing
local integer dex
if c.owner == CREEP_PLAYER and AlertSoundCt[c.sfxId] > 0 then
if AlertDelay[c.sfxId] == null then
set AlertDelay[c.sfxId] = CreateTimer()
endif
if TimerGetRemaining(AlertDelay[c.sfxId]) <= 0.01 then
set dex = GetRandomInt(0, AlertSoundCt[c.sfxId] - 1)
call SetSoundPosition(AlertSounds[c.sfxId][dex], GetUnitX(c.u), GetUnitY(c.u), PanelCore_GetUnitZ(c.u))
call SetSoundVolume(AlertSounds[c.sfxId][dex], 200)
call StartSound(AlertSounds[c.sfxId][dex])
call TimerStart(AlertDelay[c.sfxId], 1.0, false, null)
endif
endif
endfunction
endlibrary
library CreepDeathHandler uses TimerUtils, GameConstants, Items
globals
private integer array UnitAlpha
private integer CreateId
private integer CreateQuality
private integer CreateAmount
private real CreateX
private real CreateY
private ItemObject CreatedItem
endglobals
private function remove takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer data = GetTimerData(t)
if UnitAlpha[data] > 9 then
set UnitAlpha[data] = UnitAlpha[data] - 9
call SetUnitVertexColor(GetUnitById(data), 255, 255, 255, UnitAlpha[data])
call TimerStart(t, 0.1, false, function remove)
else
call RemoveUnit(GetUnitById(data))
call ReleaseTimer(t)
endif
set t = null
endfunction
private function CreateItem takes nothing returns nothing
set CreatedItem = ItemObject.create(CreateId, CreateAmount, CreateQuality, CreateX, CreateY)
endfunction
function OnCreepDead takes unit u returns nothing
local integer data
local integer level
local Combatant c
local Items itm
local integer i
local integer tLevel
local integer sc
local integer max
local integer rare
local real gold
local real goldPart
local real chance
local real chance2
local real chance3
local real chance4
local real chance5
local real chance6
local real rand
local real x
local real y
set data = GetUnitUserData(u)
set UnitAlpha[data] = 255
call TimerStart(NewTimerEx(data), 30.0, false, function remove)
set c = Combatant[u]
set level = TargetLevel[c.level]
set chance = DropChance[c.dropQuality]
set chance2 = GemDropChance[c.dropQuality]
set chance3 = PotionDropChance[c.dropQuality]
set chance4 = OreDropChance[c.dropQuality]
set chance5 = GemstoneDropChance[c.dropQuality]
set chance6 = SoulHarvestChance[c.dropQuality]
if chance > 0. then
set chance = chance + ActiveScroll.dropRate
endif
if chance2 > 0. then
set chance2 = chance2 + ActiveScroll.dropRate
endif
if chance3 > 0. then
set chance3 = chance3 + ActiveScroll.dropRate
endif
if (GetRandomReal(0.000, 1.000) <= GoldDropChance[c.dropQuality]) then
set gold = GetGoldenDropAmount(c.level, c.dropQuality)*(1.+ActiveScroll.goldRate)
else
set gold = 0
endif
set max = c.dropQuality + 2
set x = GetUnitX(u)
set y = GetUnitY(u)
if (GetUnitAbilityLevel(c.u, 'Amov') > 0 and GetRandomReal(0.000, 1.000) <= chance6) then
set rand = GetRandomReal(0.000, 1.000)
if (c.spMax > 0 and rand <= 0.5) then
call SoulHarvest.create(x, y, c.spMax, false)
else
call SoulHarvest.create(x, y, c.hpMax*0.5, true)
endif
set x = GetUnitX(u)+GetRandomReal(-200.0, 200.0)
set y = GetUnitY(u)+GetRandomReal(-200.0, 200.0)
endif
loop
exitwhen gold <= 0
// Gold drop
set goldPart = RMinBJ(GetGoldenDropPart(c.level), gold)
set gold = gold - goldPart
set CreateX = x
set CreateY = y
set CreateQuality = 0
set CreateAmount = 1
set CreateId = 21
call ForForce(bj_FORCE_PLAYER[0], function CreateItem)
set CreatedItem.goldGiven = IMaxBJ(R2I(goldPart), 1)
call CreatedItem.refreshName()
set x = GetUnitX(u)+GetRandomReal(-200.0, 200.0)
set y = GetUnitY(u)+GetRandomReal(-200.0, 200.0)
endloop
set i = 0
loop
exitwhen i >= 2
// Equipment drop
if (GetRandomReal(0.000, 1.000) <= chance) then
set tLevel = c.level + GetRandomInt(0, ItemLevelPool.getItem())
if (tLevel > 100) then
set tLevel = 100
endif
set rare = RarityPool.getItem()
loop
exitwhen DropList[rare][TargetLevel[tLevel]] > 0 or rare <= 0
set rare = rare-1
endloop
if DropList[rare][TargetLevel[tLevel]] > 0 then
set itm = DropList[rare][TargetLevel[tLevel]].getItem()
set CreateX = x
set CreateY = y
set CreateQuality = ItemQualityPool[c.dropQuality].getItem()
set CreateAmount = 1
set CreateId = itm
call ForForce(bj_FORCE_PLAYER[0], function CreateItem)
set tLevel = IMinBJ(IMinBJ(IMaxBJ(c.level + ItemBonusLevelPool.getItem(), CreatedItem.reqLevel), CreatedItem.reqLevel + 8), 100)
set sc = SocketCountPool.getItem()
if (sc > CreatedItem.socketCountMax) then
set sc = CreatedItem.socketCountMax
endif
set CreatedItem.socketCountMax = sc
call Items_AdjustItemObjectLevel(CreatedItem, tLevel)
// Apply quality price bonus
if CreatedItem.id.category < Items.CONSUMABLE then
set CreatedItem.gold = R2I(I2R(CreatedItem.gold)*SocketCountValueFactor[CreatedItem.socketCountMax]*QualityValueFactor[CreatedItem.quality])
endif
set chance = chance * 0.5
set x = GetUnitX(u)+GetRandomReal(-200.0, 200.0)
set y = GetUnitY(u)+GetRandomReal(-200.0, 200.0)
if CreatedItem.quality > 1 or CreatedItem.rarity > 2 then
call DisplayTimedTextToPlayer(Locale, 0, 0, 10, RarityColor[CreatedItem.rarity] + itm.name + " |cffffcc00(" + QualityNames[CreatedItem.quality] + " quality - Level " + I2S(CreatedItem.reqLevel) + ") was dropped!|r")
endif
endif
endif
// Gem drop
if (GetRandomReal(0.000, 1.000) <= chance2) then
set itm = GemDropList[IMinBJ(c.level/20, 4)].getItem()
set CreateX = x
set CreateY = y
set CreateQuality = 0
set CreateAmount = 1
set CreateId = itm
call ForForce(bj_FORCE_PLAYER[0], function CreateItem)
set chance2 = chance2 * 0.3
set x = GetUnitX(u)+GetRandomReal(-200.0, 200.0)
set y = GetUnitY(u)+GetRandomReal(-200.0, 200.0)
endif
// Potion drop
if (GetRandomReal(0.000, 1.000) <= chance3) then
set itm = PotionDropList[IMinBJ(c.level/10, 8)].getItem()
set CreateX = x
set CreateY = y
set CreateQuality = 0
set CreateAmount = 1
set CreateId = itm
call ForForce(bj_FORCE_PLAYER[0], function CreateItem)
set chance3 = chance3 * 0.5
set x = GetUnitX(u)+GetRandomReal(-200.0, 200.0)
set y = GetUnitY(u)+GetRandomReal(-200.0, 200.0)
endif
// Ore drop
if (GetRandomReal(0.000, 1.000) <= chance4) then
set itm = OreDropList.getItem()
set CreateX = x
set CreateY = y
set CreateQuality = 0
set CreateAmount = 1
set CreateId = itm
call ForForce(bj_FORCE_PLAYER[0], function CreateItem)
set chance3 = chance3 * 0.4
set x = GetUnitX(u)+GetRandomReal(-200.0, 200.0)
set y = GetUnitY(u)+GetRandomReal(-200.0, 200.0)
endif
// Gemstone drop
if (GetRandomReal(0.000, 1.000) <= chance5) then
set itm = GemstoneDropList.getItem()
set CreateX = x
set CreateY = y
set CreateQuality = 0
set CreateAmount = 1
set CreateId = itm
call ForForce(bj_FORCE_PLAYER[0], function CreateItem)
set chance5 = chance5 * 0.5
set x = GetUnitX(u)+GetRandomReal(-200.0, 200.0)
set y = GetUnitY(u)+GetRandomReal(-200.0, 200.0)
endif
set i = i + 1
endloop
endfunction
function InitTrig_CreepDeathHandler takes nothing returns nothing
//set gg_trg_CreepDeathHandler = CreateTrigger( )
//call TriggerRegisterAnyUnitEventBJ( gg_trg_CreepDeathHandler, EVENT_PLAYER_UNIT_DEATH )
//call TriggerAddAction( gg_trg_CreepDeathHandler, function Trig_AutoRemoveCorpse_Actions )
endfunction
endlibrary
library MonsterPack initializer init
globals
IPool DungeonMonsters
IPool ForestMonsters
IPool array MonsterPack
integer array MonsterCountMin
integer array MonsterCountMax
endglobals
private function init takes nothing returns nothing
// kobold tunneler & boiler
set MonsterPack[0] = IPool.create()
call MonsterPack[0].add('h00Q', 7)
call MonsterPack[0].add('h003', 1)
set MonsterCountMin[0] = 3
set MonsterCountMax[0] = 5
// skeleton warrior & skeleton archer
set MonsterPack[1] = IPool.create()
call MonsterPack[1].add('h00A', 4)
call MonsterPack[1].add('h00B', 3)
set MonsterCountMin[1] = 3
set MonsterCountMax[1] = 5
// geomancer & holigan
set MonsterPack[2] = IPool.create()
call MonsterPack[2].add('h00R', 1)
call MonsterPack[2].add('h010', 1)
set MonsterCountMin[2] = 1
set MonsterCountMax[2] = 2
// kobold nest
set MonsterPack[3] = IPool.create()
call MonsterPack[3].add('h00X', 1)
set MonsterCountMin[3] = 1
set MonsterCountMax[3] = 1
// harpy rogues
set MonsterPack[4] = IPool.create()
call MonsterPack[4].add('h006', 1)
set MonsterCountMin[4] = 1
set MonsterCountMax[4] = 3
// harpy rogues + witch
set MonsterPack[5] = IPool.create()
call MonsterPack[5].add('h006', 7)
call MonsterPack[5].add('h00D', 1)
set MonsterCountMin[5] = 1
set MonsterCountMax[5] = 3
// harpy witch
set MonsterPack[6] = IPool.create()
call MonsterPack[6].add('h00D', 1)
set MonsterCountMin[6] = 1
set MonsterCountMax[6] = 1
// harpy queen
set MonsterPack[7] = IPool.create()
call MonsterPack[7].add('h00E', 1)
set MonsterCountMin[7] = 1
set MonsterCountMax[7] = 1
// harpy rogues + kobold tunnelers
set MonsterPack[8] = IPool.create()
call MonsterPack[8].add('h006', 3)
call MonsterPack[8].add('h00Q', 5)
set MonsterCountMin[8] = 3
set MonsterCountMax[8] = 5
// lancer & mauler
set MonsterPack[9] = IPool.create()
call MonsterPack[9].add('h00F', 1)
call MonsterPack[9].add('h00G', 1)
set MonsterCountMin[9] = 1
set MonsterCountMax[9] = 2
// enchantress
set MonsterPack[10] = IPool.create()
call MonsterPack[10].add('h00H', 1)
set MonsterCountMin[10] = 1
set MonsterCountMax[10] = 1
// treant
set MonsterPack[11] = IPool.create()
call MonsterPack[11].add('h00I', 1)
set MonsterCountMin[11] = 2
set MonsterCountMax[11] = 5
// skeleton warrior
set MonsterPack[12] = IPool.create()
call MonsterPack[12].add('h00A', 1)
set MonsterCountMin[12] = 3
set MonsterCountMax[12] = 5
// skeleton archer
set MonsterPack[13] = IPool.create()
call MonsterPack[13].add('h00B', 1)
set MonsterCountMin[13] = 2
set MonsterCountMax[13] = 4
// skeleton axeman
set MonsterPack[14] = IPool.create()
call MonsterPack[14].add('h00J', 1)
set MonsterCountMin[14] = 1
set MonsterCountMax[14] = 1
// skeleton magus
set MonsterPack[15] = IPool.create()
call MonsterPack[15].add('h00K', 1)
set MonsterCountMin[15] = 1
set MonsterCountMax[15] = 1
// skeleton axeman & magus
set MonsterPack[16] = IPool.create()
call MonsterPack[16].add('h00J', 1)
call MonsterPack[16].add('h00K', 1)
set MonsterCountMin[16] = 1
set MonsterCountMax[16] = 2
// sludge monster (crypt)
set MonsterPack[17] = IPool.create()
call MonsterPack[17].add('h00L', 1)
set MonsterCountMin[17] = 1
set MonsterCountMax[17] = 1
// crawler venom & bane
set MonsterPack[18] = IPool.create()
call MonsterPack[18].add('h00P', 1)
call MonsterPack[18].add('h00S', 1)
set MonsterCountMin[18] = 1
set MonsterCountMax[18] = 2
// spiderling
set MonsterPack[19] = IPool.create()
call MonsterPack[19].add('h02T', 1)
set MonsterCountMin[19] = 3
set MonsterCountMax[19] = 5
set DungeonMonsters = IPool.create()
call DungeonMonsters.add(1, 7)
call DungeonMonsters.add(12, 6)
call DungeonMonsters.add(13, 6)
call DungeonMonsters.add(14, 3)
call DungeonMonsters.add(15, 3)
call DungeonMonsters.add(16, 3)
call DungeonMonsters.add(17, 2)
set ForestMonsters = IPool.create()
call ForestMonsters.add(0, 7)
call ForestMonsters.add(2, 3)
call ForestMonsters.add(3, 3)
call ForestMonsters.add(4, 7)
call ForestMonsters.add(5, 4)
call ForestMonsters.add(6, 3)
call ForestMonsters.add(7, 1)
call ForestMonsters.add(8, 5)
call ForestMonsters.add(9, 3)
call ForestMonsters.add(10, 1)
call ForestMonsters.add(11, 6)
call ForestMonsters.add(18, 5)
call ForestMonsters.add(19, 7)
endfunction
endlibrary
library BossGaia
struct BossGaia
CreepAI ai
static method create takes unit u returns thistype
endmethod
endstruct
endlibrary
library SoulHarvest uses Missile, TimerUtils, DamageText
private struct SoulMissile
Combatant c
unit dummy
effect sfx
timer t
boolean hp
real speed
real turn
real amount
real distance
real x
real y
real z
real zVel
real a
private static constant real MIN_Z = 40.0
private static constant real SPEED = 10.0
private static constant real MAX_SPEED = 12.5
private static constant real COLLISION = 20.0
private static constant real GRAVITY = 5*0.03125
private static constant real TURN_RATE = 0.1
private static constant real TURN_RATE_ADD = 0.1*0.03125
private static group Group = CreateGroup()
method destroy takes nothing returns nothing
call RecycleMissile(.dummy)
call DestroyEffect(.sfx)
call ReleaseTimer(.t)
call deallocate()
set .dummy = null
set .sfx = null
set .t = null
endmethod
static method onTick takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local unit fog
local real xt
local real yt
local real at
local real dmg
local Combatant c2
if .distance > .speed then
set .distance = .distance - .speed
set xt = GetUnitX(c.u)
set yt = GetUnitY(c.u)
set at = Atan2(yt-.y, xt-.x)
if .z <= MIN_Z then
set .turn = .turn + TURN_RATE_ADD
set .speed = .speed + SOUL_ACCELERATION
if .speed > SOUL_MAX_SPEED then
set .speed = SOUL_MAX_SPEED
endif
endif
// Adjust missile's angle to the target
if Cos(.a-at) < Cos(.turn) then
if Sin(at-.a) >= 0 then
set .a = .a + .turn
else
set .a = .a - .turn
endif
else
set .a = at
endif
set .x = .x + .speed*Cos(.a)
set .y = .y + .speed*Sin(.a)
if .zVel > 0 then
set .z = .z - RMinBJ(.zVel, MAX_SPEED)
else
set .z = .z - RMaxBJ(.zVel, -MAX_SPEED)
endif
set .zVel = .zVel + GRAVITY
if .x > WorldBounds.minX and .x < WorldBounds.maxX and .y > WorldBounds.minY and .y < WorldBounds.maxY then
call SetUnitX(.dummy, .x)
call SetUnitY(.dummy, .y)
if .zVel > 0 and .z < MIN_Z then
call SetUnitFlyHeight(.dummy, MIN_Z, 0.)
else
call SetUnitFlyHeight(.dummy, .z, 0.)
endif
call SetUnitFacing(.dummy, .a*bj_RADTODEG)
if .zVel > 0 and IsUnitInRangeXY(.c.u, .x, .y, COLLISION) and (.z < MIN_Z or RAbsBJ(.z-GetUnitFlyHeight(.c.u)) < COLLISION) then
if IsUnitAlive(.c.u) then
if .hp then
call DamageText_Show(I2S(R2I(.amount)), 0, .c.u, HEAL_R, HEAL_G, HEAL_B, TEXTTAG_NORMAL_SIZE)
set .c.hp = .c.hp + .amount
if .c.hp > .c.hpMax then
set .c.hp = .c.hpMax
endif
call DestroyEffectTimed(AddSpecialEffectTarget("war3mapImported\\RedHeal.mdx", .c.u, "origin"), 5)
else
call DamageText_Show(I2S(R2I(.amount)), 0, .c.u, MANA_R, MANA_G, MANA_B, TEXTTAG_NORMAL_SIZE)
set .c.sp = .c.sp + .amount
if .c.sp > .c.spMax then
set .c.sp = .c.spMax
endif
call DestroyEffectTimed(AddSpecialEffectTarget("war3mapImported\\BlueHeal.mdx", .c.u, "origin"), 5)
endif
endif
call destroy()
endif
endif
else
call destroy()
endif
endmethod
static method create takes Combatant c, real x, real y, real a, real amount, string model, boolean hp returns thistype
local thistype this = allocate()
set .c = c
set .dummy = GetRecycledMissile(x, y, 0, a)
call SetUnitScale(.dummy, 0.25, 1, 1)
set .sfx = AddSpecialEffectTarget(model, .dummy, "origin")
set .amount = amount
set .turn = TURN_RATE
set .hp = hp
set .speed = SPEED
set .a = a * bj_DEGTORAD
set .x = x
set .y = y
set .z = 0
set .zVel = -10.0
set .distance = 4000.0
set .t = NewTimerEx(this)
call TimerStart(.t, 0.03125, true, function thistype.onTick)
return this
endmethod
endstruct
struct SoulHarvest
integer start
effect sfx
boolean hp
timer t
real dur
real value
real give
real x
real y
Legend legend
static real INTERVAL = 0.25
static boolean WantDestroy = false
method destroy takes nothing returns nothing
call .legend.destroy()
call ReleaseTimer(.t)
call DestroyEffect(.sfx)
call deallocate()
set .sfx = null
set .t = null
endmethod
static method periodic takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local integer i
local integer j
if .dur > INTERVAL and not WantDestroy then
set .dur = .dur - INTERVAL
set i = 0
loop
exitwhen i > 3
set j = ModuloInteger(i + .start, 4)
if IsPlaying[j] and IsUnitAlive(MainUnit[j]) and IsUnitInRangeXY(MainUnit[j], .x, .y, SOUL_HARVEST_RANGE) then
set .start = .start + 1
if .start > 3 then
set .start = 0
endif
set .value = .value - .give
if hp then
call SoulMissile.create(Fighter[j], .x, .y, GetRandomReal(0, 359.9), .give, "war3mapImported\\RedHarvestMissile.mdx", .hp)
else
call SoulMissile.create(Fighter[j], .x, .y, GetRandomReal(0, 359.9), .give, "war3mapImported\\BlueHarvestMissile.mdx", .hp)
endif
exitwhen true
endif
set i = i + 1
endloop
if .value <= 0 then
call destroy()
endif
else
call destroy()
endif
endmethod
static method createSoul takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
set .start = 0
set .dur = 300.0
if .hp then
set .sfx = AddSpecialEffect("war3mapImported\\RedHarvest2.mdx", .x, .y)
else
set .sfx = AddSpecialEffect("war3mapImported\\BlueHarvest2.mdx", .x, .y)
endif
call TimerStart(.t, INTERVAL, true, function thistype.periodic)
endmethod
static method create takes real x, real y, real value, boolean hp returns thistype
local thistype this = allocate()
set WantDestroy = false
set .x = x
set .y = y
set .value = value*(0.66+0.333*PlayerCount)
set .give = value/10.
set .hp = hp
if hp then
call DestroyEffect(AddSpecialEffect("war3mapImported\\Soul Discharge Red2.mdx", x, y))
else
call DestroyEffect(AddSpecialEffect("war3mapImported\\Soul Discharge Blue.mdx", x, y))
endif
if hp then
set .legend = MinimapLegend.addStatic(x, y, "war3mapImported\\SoulRed.blp", 0.2, false)
else
set .legend = MinimapLegend.addStatic(x, y, "war3mapImported\\SoulBlue.blp", 0.2, false)
endif
set .t = NewTimerEx(this)
call TimerStart(.t, 0.25, false, function thistype.createSoul)
return this
endmethod
endstruct
endlibrary
library CameraShaker uses TimerUtils
globals
public real array HMagnitude
public real array Intensity
public real array VMagnitude
private real array HRate
private real array VRate
private timer array HTimer
private timer array VTimer
private constant real INTERVAL = 0.03125
endglobals
private function shakeH takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
local real sign = RSignBJ(HMagnitude[id])
set HMagnitude[id] = (RAbsBJ(HMagnitude[id]) - HRate[id])
if HMagnitude[id] <= 0 then
set HMagnitude[id] = 0
call PauseTimer(t)
else
set HMagnitude[id] = HMagnitude[id]*-sign
endif
set t = null
endfunction
public function StartH takes integer id, real magnitude, real duration returns nothing
if HTimer[id] == null then
set HTimer[id] = NewTimerEx(id)
endif
set HMagnitude[id] = RMinBJ(HMagnitude[id] + magnitude, magnitude*2)*(-1.+2.*I2R(GetRandomInt(0, 1)))
set HRate[id] = magnitude/(duration/INTERVAL)
call TimerStart(HTimer[id], INTERVAL, true, function shakeH)
endfunction
private function shakeV takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
local real sign = RSignBJ(VMagnitude[id])
if id > 3 then
return
endif
set VMagnitude[id] = (RAbsBJ(VMagnitude[id]) - VRate[id])
if VMagnitude[id] <= 0 then
set VMagnitude[id] = 0
call PauseTimer(t)
else
set VMagnitude[id] = VMagnitude[id]*-sign
endif
set t = null
endfunction
public function StartV takes integer id, real magnitude, real duration returns nothing
if id > 3 then
return
endif
if VTimer[id] == null then
set VTimer[id] = NewTimerEx(id)
endif
set VMagnitude[id] = RMinBJ(VMagnitude[id] + magnitude, magnitude*2)*(-1.+2.*I2R(GetRandomInt(0, 1)))
set VRate[id] = magnitude/(duration/INTERVAL)
call TimerStart(VTimer[id], INTERVAL, true, function shakeV)
endfunction
endlibrary
library ChainGenerator initializer init uses DestructableHider
globals
private constant real PARTITION_LENGTH = 40
private constant real ACCURACY = 2
private constant real EVEN_ACCURACY = 0.005
private constant real SMOOTHNESS = 10
private constant real BRAMBLE_SCALE = 1
private constant real E = 2.718281
private integer array Chains
private integer array Brambles
endglobals
private function Log takes real Power, real Base returns real
local real Whole
local real N
local real Sign = 1.0
if (Power <= 1.0 or Base <= 1.0) then
if (Power <= 0.0 or Base <= 0.0 ) then
return 0.0
endif
if (Power < 1.0) then
set Power = 1.0 / Power
set Sign = -Sign
endif
if (Base < 1.0) then
set Sign = -Sign
set Base = 1.0 / Base
endif
if (Power == 1.0) then
if (Base != 1.0) then
return 0.0
endif
return 1.0
endif
endif
set Whole = Power
set N = 0.0
loop
exitwhen (Whole < Base)
set Whole = Whole / Base
set N = N + 1
endloop
if (Whole == 1.0) then
return (Sign * N)
endif
return Sign * (N + (1.0 / Log(Base, Whole)))
endfunction
private function Cosh takes real x returns real
return (1 + Pow(E, -2 * x)) / (2 * Pow(E, -x))
endfunction
private function Catenary takes real x, real a returns real
return a * (Cosh(x / a) - Cosh(0.5 / a))
endfunction
private function UnevenCatenary takes real x, real k, real m, real a returns real
return a * Cosh((x + k) / a) + m
endfunction
private function ElementHeightAt takes real x, real z, real groundz, real height, real a returns real
return RMaxBJ(z + Catenary(x, a) * height, groundz)
endfunction
function GenerateUnevenChain takes real x1, real y1, real z1, real x2, real y2, real z2, real groundz, real length, real size, real shift, real a, integer object returns nothing
local real ang = Atan2(y2 - y1, x2 - x1)
local real d = SquareRoot((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1))
local real h = z2 - z1
local real h1 = 1/2*(a*Log((length+h)/(length-h), 10)-d)
local real m = z1 - a*Cosh(h1/a)
local real x = d * shift
local real xt = (d * shift) + d
local real xr = 0
local real cx
local real cy
local real cz
local real px = x1
local real py = y1
local real pz
local real d2
local real pitch
local integer dex
set pz = RMaxBJ(UnevenCatenary(x, h1, m, a), groundz)
loop
exitwhen x > xt
set x = x + ACCURACY*size
set xr = xr + ACCURACY*size
set cx = x1 + xr * Cos(ang)
set cy = y1 + xr * Sin(ang)
set cz = RMaxBJ(UnevenCatenary(x, h1, m, a), groundz)
if SquareRoot((cx-px)*(cx-px)+(cy-py)*(cy-py)+(cz-pz)*(cz-pz)) > PARTITION_LENGTH*size then
set d2 = SquareRoot((cx-px)*(cx-px)+(cy-py)*(cy-py))/2
set pitch = Atan((RAbsBJ(cz - pz) / 2) / d2) * bj_RADTODEG
set dex = R2I(pitch / SMOOTHNESS)
if (x < 0) then
if (object == 0) then
call DestructableHider_register(CreateDestructableZ(Chains[dex], px + (cx - px) / 2, py + (cy - py) / 2, pz + (cz - pz) / 2, ang * bj_RADTODEG, size, 0))
elseif (object == 1) then
call DestructableHider_register(CreateDestructableZ(Brambles[dex], px + (cx - px) / 2, py + (cy - py) / 2, pz + (cz - pz) / 2, ang * bj_RADTODEG, size*BRAMBLE_SCALE, 0))
endif
else
if (object == 0) then
call DestructableHider_register(CreateDestructableZ(Chains[dex], px + (cx - px) / 2, py + (cy - py) / 2, pz + (cz - pz) / 2, ang * bj_RADTODEG + 180, size, 0))
elseif (object == 1) then
call DestructableHider_register(CreateDestructableZ(Brambles[dex], px + (cx - px) / 2, py + (cy - py) / 2, pz + (cz - pz) / 2, ang * bj_RADTODEG + 180, size*BRAMBLE_SCALE, 0))
endif
endif
set px = cx
set py = cy
set pz = cz
endif
endloop
endfunction
function GenerateEvenChain takes real x1, real y1, real z1, real x2, real y2, real z2, real groundz, real height, real size, real a, integer object returns nothing
local real x
local real cx
local real cy
local real cz
local real px = x1
local real py = y1
local real pz = ElementHeightAt(-0.5, z1, groundz, height, a)
local real d = SquareRoot((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1) + (z2 - z1)*(z2 - z1))
local real d2
local real ang = Atan2(y2 - y1, x2 - x1)
local real length = (PARTITION_LENGTH * size)
local real pitch
local integer dex
set length = length * length
set x = -0.5
loop
exitwhen x > 0.5
set d2 = 0
loop
exitwhen d2 > length
set x = x + EVEN_ACCURACY
set cx = x1 + ((x + 0.5) * d) * Cos(ang)
set cy = y1 + ((x + 0.5) * d) * Sin(ang)
set cz = ElementHeightAt(x, z1, groundz, height, a)
set d2 = (cx - px)*(cx - px) + (cy - py)*(cy - py) + (cz - pz)*(cz - pz)
endloop
set d2 = SquareRoot((cx - px)*(cx - px) + (cy - py)*(cy - py)) / 2
set pitch = Atan((RAbsBJ(cz - pz) / 2) / d2) * bj_RADTODEG
set dex = R2I(pitch / 10)
if (x < 0) then
if (object == 0 or object == 2) then
call DestructableHider_register(CreateDestructableZ(Chains[dex], px + (cx - px) / 2, py + (cy - py) / 2, pz + (cz - pz) / 2, ang * bj_RADTODEG, size, 0))
endif
if (object == 1 or object == 2) then
call DestructableHider_register(CreateDestructableZ(Brambles[dex], px + (cx - px) / 2, py + (cy - py) / 2, pz + (cz - pz) / 2, ang * bj_RADTODEG, size*BRAMBLE_SCALE, 0))
endif
else
if (object == 0 or object == 2) then
call DestructableHider_register(CreateDestructableZ(Chains[dex], px + (cx - px) / 2, py + (cy - py) / 2, pz + (cz - pz) / 2, ang * bj_RADTODEG + 180, size, 0))
endif
if (object == 1 or object == 2) then
call DestructableHider_register(CreateDestructableZ(Brambles[dex], px + (cx - px) / 2, py + (cy - py) / 2, pz + (cz - pz) / 2, ang * bj_RADTODEG + 180, size*BRAMBLE_SCALE, 0))
endif
endif
set px = cx
set py = cy
set pz = cz
endloop
endfunction
private function init takes nothing returns nothing
set Chains[0] = 'CHA0'
set Chains[1] = 'CHA1'
set Chains[2] = 'CHA2'
set Chains[3] = 'CHA3'
set Chains[4] = 'CHA4'
set Chains[5] = 'CHA5'
set Chains[6] = 'CHA6'
set Chains[7] = 'CHA7'
set Chains[8] = 'CHA8'
set Chains[9] = 'CHA9'
set Brambles[0] = 'CHB0'
set Brambles[1] = 'CHB1'
set Brambles[2] = 'CHB2'
set Brambles[3] = 'CHB3'
set Brambles[4] = 'CHB4'
set Brambles[5] = 'CHB5'
set Brambles[6] = 'CHB6'
set Brambles[7] = 'CHB7'
set Brambles[8] = 'CHB8'
set Brambles[9] = 'CHB9'
endfunction
endlibrary
function Trig_Catenary_Actions takes nothing returns nothing
call BJDebugMsg(R2S(Catenary(S2R(GetEventPlayerChatString()), 1)))
endfunction
//===========================================================================
function InitTrig_CatenaryTest takes nothing returns nothing
set gg_trg_CatenaryTest = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_CatenaryTest, Player(0), "", false )
call TriggerAddAction( gg_trg_CatenaryTest, function Trig_Catenary_Actions )
endfunction
scope ChainTest
globals
private real length = 500
private real offset = 500
private real zStart = 0
private real zEnd = 400
private real aConstant = 500
private real size = 0.5
private real shift = 0
private integer obj = 0
endglobals
function Trig_Catenary_Actions takes nothing returns nothing
local real x = GetUnitX(MainUnit[0])
local real y = GetUnitY(MainUnit[0])
local real minz = PanelCore_GetUnitZ(MainUnit[0])
local real z = minz
local real a = GetUnitFacing(MainUnit[0]) * bj_DEGTORAD
local string s = GetEventPlayerChatStringMatched()
if (s == "c1") then
call GenerateUnevenChain(x, y, z+zStart, x + offset * Cos(a), y + offset * Sin(a), z + zEnd, minz, length, size, shift, aConstant, obj)
call BJDebugMsg("Generation done.")
elseif (s == "c2") then
call GenerateEvenChain(x, y, z+zStart, x + offset * Cos(a), y + offset * Sin(a), z + zEnd, minz, length, size, aConstant, obj)
call BJDebugMsg("Generation done.")
elseif (s == "len") then
set length = S2R(SubString(GetEventPlayerChatString(), 4, 99))
call BJDebugMsg("Length/height: " + R2S(length))
elseif (s == "ofs") then
set offset = S2R(SubString(GetEventPlayerChatString(), 4, 99))
call BJDebugMsg("Offset: " + R2S(offset))
elseif (s == "str") then
set zStart = S2R(SubString(GetEventPlayerChatString(), 4, 99))
call BJDebugMsg("Z Start: " + R2S(zStart))
elseif (s == "end") then
set zEnd = S2R(SubString(GetEventPlayerChatString(), 4, 99))
call BJDebugMsg("Z End: " + R2S(zEnd))
elseif (s == "const") then
set aConstant = S2R(SubString(GetEventPlayerChatString(), 6, 99))
call BJDebugMsg("Constant: " + R2S(aConstant))
elseif (s == "sz") then
set size = S2R(SubString(GetEventPlayerChatString(), 3, 99))
call BJDebugMsg("Size: " + R2S(size))
elseif (s == "sft") then
set shift = S2R(SubString(GetEventPlayerChatString(), 4, 99))
elseif (s == "obj") then
set shift = S2R(SubString(GetEventPlayerChatString(), 4, 99))
call BJDebugMsg("Object: " + I2S(obj))
elseif (s == "print") then
call BJDebugMsg("Length: " + R2S(length))
call BJDebugMsg("Offset: " + R2S(offset))
call BJDebugMsg("Z Start: " + R2S(zStart))
call BJDebugMsg("Z End: " + R2S(zEnd))
call BJDebugMsg("Constant: " + R2S(aConstant))
call BJDebugMsg("Size: " + R2S(size))
call BJDebugMsg("Shift: " + R2S(shift))
endif
endfunction
//===========================================================================
function InitTrig_ChainTest takes nothing returns nothing
set gg_trg_ChainTest = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_ChainTest, Player(0), "len", false )
call TriggerRegisterPlayerChatEvent( gg_trg_ChainTest, Player(0), "ofs", false )
call TriggerRegisterPlayerChatEvent( gg_trg_ChainTest, Player(0), "str", false )
call TriggerRegisterPlayerChatEvent( gg_trg_ChainTest, Player(0), "end", false )
call TriggerRegisterPlayerChatEvent( gg_trg_ChainTest, Player(0), "const", false )
call TriggerRegisterPlayerChatEvent( gg_trg_ChainTest, Player(0), "sz", false )
call TriggerRegisterPlayerChatEvent( gg_trg_ChainTest, Player(0), "sft", false )
call TriggerRegisterPlayerChatEvent( gg_trg_ChainTest, Player(0), "print", false )
call TriggerRegisterPlayerChatEvent( gg_trg_ChainTest, Player(0), "c1", false )
call TriggerRegisterPlayerChatEvent( gg_trg_ChainTest, Player(0), "c2", false )
call TriggerAddAction( gg_trg_ChainTest, function Trig_Catenary_Actions )
endfunction
endscope
library CustomText uses PanelCore
globals
private group PreloadGroup = CreateGroup()
public constant integer PRELOAD_COUNT = 100
endglobals
private function GetDummy takes nothing returns unit
set bj_lastCreatedUnit = FirstOfGroup(PreloadGroup)
if bj_lastCreatedUnit == null then
set bj_lastCreatedUnit = CreateUnit(PanelCore_PASSIVE, 'e02I', 0, 0, 0)
static if not LIBRARY_AutoFly then
if UnitAddAbility(bj_lastCreatedUnit, 'Amrf') and UnitRemoveAbility(bj_lastCreatedUnit, 'Amrf') then
endif
endif
call UnitAddAbility(bj_lastCreatedUnit, 'Aeth')
call UnitAddAbility(bj_lastCreatedUnit, PanelCore_TEXTURE_REPLACER_ID)
call UnitRemoveAbility(bj_lastCreatedUnit, 'Amov')
call SetUnitPathing(bj_lastCreatedUnit, false)
else
call GroupRemoveUnit(PreloadGroup, bj_lastCreatedUnit)
endif
return bj_lastCreatedUnit
endfunction
private function RecycleDummy takes unit u returns nothing
call SetUnitX(u, WorldBounds.maxX)
call SetUnitY(u, WorldBounds.maxY)
call GroupAddUnit(PreloadGroup, u)
endfunction
private struct CustomTextComponent extends array
implement LinkedList
string char
real width
real height
real depth
unit dum
method show takes boolean b returns nothing
if b then
call SetUnitScale(dum, 1, 1, 1)
else
call SetUnitScale(dum, 0, 0, 0)
endif
endmethod
endstruct
struct CustomText
readonly string text
readonly real x
readonly real y
readonly real z
readonly real align
readonly real size
readonly real width
readonly real height
readonly real depth
readonly integer r
readonly integer g
readonly integer b
readonly integer a
readonly integer length
readonly boolean visible
readonly CustomTextComponent chars
static constant real ALIGNMENT_LEFT = 0
static constant real ALIGNMENT_MIDDLE = 0.5
static constant real ALIGNMENT_RIGHT = 1
private method getCharTexture takes string s returns integer
return LoadInteger(PanelTextEx.FontData, 0, Char2Ascii(s))
endmethod
public method getCharWidth takes string s returns real
return LoadReal(PanelTextEx.FontData, 1, Char2Ascii(s))
endmethod
private method getCharHeight takes string s returns real
return LoadReal(PanelTextEx.FontData, 2, Char2Ascii(s))
endmethod
private method getCharDepth takes string s returns real
return LoadReal(PanelTextEx.FontData, 3, Char2Ascii(s))
endmethod
method operator alignment takes nothing returns real
return .align
endmethod
method operator alignment= takes real a returns nothing
set .align = a
call refresh()
endmethod
method operator scale takes nothing returns real
return .size
endmethod
method operator scale= takes real r returns nothing
set .size = r
call refresh()
endmethod
method refresh takes nothing returns nothing
local CustomTextComponent c = .chars.next
local real xOffset = 0
local real a = PlayerCamera[PNumb].Rotation-PanelCore_HP
local real xs = .x-(.width*.align)*Cos(a)
local real ys = .y-(.width*.align)*Sin(a)
local real offset
local real offset2
set .width = 0
set .height = 0
set .depth = 0
loop
exitwhen c.head or c == 0
set offset = c.width*.size
if c.dum != null then
set offset2 = xOffset+offset/2
if .visible then
call SetUnitScale(c.dum, .size, .size, .size)
endif
call SetUnitX(c.dum, xs+offset2*Cos(a))
call SetUnitY(c.dum, ys+offset2*Sin(a))
call SetUnitFlyHeight(c.dum, .z, 0)
endif
set xOffset = xOffset+offset+1
set .width = .width+offset+1
if c.height > .height then
set .height = c.height*.size
endif
if c.depth > .depth then
set .depth = c.depth*.size
endif
set c = c.next
endloop
set .width = .width-1
endmethod
private method clear takes nothing returns nothing
local CustomTextComponent c = .chars.next
loop
exitwhen c.head or c == 0
if c.dum != null then
call RecycleDummy(c.dum)
set c.dum = null
endif
set c = c.next
endloop
call chars.clearNode()
endmethod
method destroy takes nothing returns nothing
call clear()
call chars.flushNode()
call deallocate()
endmethod
method move takes real x, real y, real z returns nothing
set .x = x
set .y = y
set .z = z
if .visible then
call refresh()
endif
endmethod
method setColor takes integer r, integer g, integer b, integer a returns nothing
local CustomTextComponent c = .chars.next
loop
exitwhen c.head or c == 0
call SetUnitVertexColor(c.dum, r, g, b, a)
set c = c.next
endloop
set .r = r
set .g = g
set .b = b
set .a = a
endmethod
method show takes boolean b returns nothing
local CustomTextComponent c
set .visible = b
set c = .chars.next
loop
exitwhen c.head or c == 0
call c.show(b)
set c = c.next
endloop
if b then
call refresh()
endif
endmethod
private method initText takes nothing returns nothing
local integer i = 0
local string s
local real xOffset = .x
local real yOffset
local real offset
local CustomTextComponent c
set .width = 0
set .height = 0
set .depth = 0
loop
exitwhen i == .length
set s = SubString(.text, i, i+1)
set c = CustomTextComponent.allocate()
if s == " " then
set c.char = " "
set c.width = 8.0
set c.height = 0.0
set c.depth = 0.0
set offset = c.width*.size
set c.dum = null
else
set c.char = s
set c.width = getCharWidth(s)
set c.height = getCharHeight(s)
set c.depth = getCharDepth(s)
set offset = c.width*.size
set c.dum = GetDummy()/*CreateUnit(PASSIVE, 'e02I', 0, .y, 0)
call SetUnitPathing(c.dum, false)
call UnitAddAbility(c.dum, 'Aeth')
call UnitAddAbility(c.dum, PanelCore_TEXTURE_REPLACER_ID)
static if not LIBRARY_AutoFly then
if UnitAddAbility(c.dum, 'Amrf') and UnitRemoveAbility(c.dum, 'Amrf') then
endif
endif*/
call PanelCore_ChangeTexture(c.dum, getCharTexture(s))
call ShowUnit(c.dum, .visible)
endif
set xOffset = xOffset+offset+1
set .width = .width+offset+1
if c.height > .height then
set .height = c.height*.size
endif
if c.depth > .depth then
set .depth = c.depth*.size
endif
call .chars.insertNode(c)
set i = i + 1
endloop
set .width = .width-1
endmethod
method setText takes string text returns nothing
if .text != text then
call clear()
set .text = text
set .length = StringLength(text)
call initText()
endif
endmethod
static method create takes string text, real x, real y, real z, real size, real alignment returns thistype
local thistype this = allocate()
set .size = size
set .x = x
set .y = y
set .z = z
set .text = text
set .align = alignment
set .visible = true
set .length = StringLength(text)
set .chars = CustomTextComponent.createNode()
call initText()
return this
endmethod
private static method PreloadDummy takes nothing returns nothing
call RecycleDummy(GetDummy())
endmethod
private static method onInit takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= PRELOAD_COUNT
call ForForce(bj_FORCE_PLAYER[0], function thistype.PreloadDummy)
set i = i + 1
endloop
endmethod
endstruct
endlibrary
library DamageText initializer init uses TimerUtils, PanelCore
globals
public constant integer PRELOAD_COUNT = 100
private real array DamageTextWidth
private integer array DamageTextRaw
private group array PreloadGroup[13]
private integer PreloadIndex
endglobals
private function GetDummy takes integer index returns unit
set bj_lastCreatedUnit = FirstOfGroup(PreloadGroup[index])
if bj_lastCreatedUnit == null then
set bj_lastCreatedUnit = CreateUnit(PanelCore_PASSIVE, 'e01F', 0, 0, 0)
static if not LIBRARY_AutoFly then
if UnitAddAbility(bj_lastCreatedUnit, 'Amrf') and UnitRemoveAbility(bj_lastCreatedUnit, 'Amrf') then
endif
endif
call UnitAddAbility(bj_lastCreatedUnit, 'Aeth')
call UnitAddAbility(bj_lastCreatedUnit, PanelCore_TEXTURE_REPLACER_ID)
call UnitRemoveAbility(bj_lastCreatedUnit, 'Amov')
call SetUnitPathing(bj_lastCreatedUnit, false)
if index == 10 then
call PanelCore_ChangeTexture(bj_lastCreatedUnit, 'DT0A')
elseif index == 11 then
call PanelCore_ChangeTexture(bj_lastCreatedUnit, 'DT0B')
elseif index == 12 then
call PanelCore_ChangeTexture(bj_lastCreatedUnit, 'DT0C')
else
call PanelCore_ChangeTexture(bj_lastCreatedUnit, DamageTextRaw[index])
endif
call PauseUnit(bj_lastCreatedUnit, true)
else
call GroupRemoveUnit(PreloadGroup[index], bj_lastCreatedUnit)
endif
return bj_lastCreatedUnit
endfunction
private function RecycleDummy takes unit u, integer index returns nothing
call SetUnitX(u, WorldBounds.maxX)
call SetUnitY(u, WorldBounds.maxY)
call GroupAddUnit(PreloadGroup[index], u)
endfunction
private struct FadingText
unit u
integer r
integer g
integer b
integer index
real alpha
real rate
real dirC
real dirS
real spd
real x
real y
private static method onTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
set .alpha = .alpha - .rate
call SetUnitVertexColor(.u, .r, .g, .b, R2I(.alpha))
set .x = .x + .spd * .dirC
set .y = .y + .spd * .dirS
call SetUnitX(.u, .x)
call SetUnitY(.u, .y)
if (.alpha <= 0) then
call RecycleDummy(.u, .index)
call Fly[.u].destroy()
call ReleaseTimer(t)
call deallocate()
set .u = null
endif
set t = null
endmethod
static method create takes unit whichUnit, real start, real rate, real range, real direction, integer index returns thistype
local thistype this = allocate()
set .r = 255
set .g = 255
set .b = 255
set .x = GetUnitX(whichUnit)
set .y = GetUnitY(whichUnit)
set .dirC = Cos(direction)
set .dirS = Sin(direction)
set .alpha = start
set .rate = rate
set .spd = (range / (start / rate))*0.03125
set .u = whichUnit
set .index = index
call TimerStart(NewTimerEx(this), 0.03125, true, function thistype.onTick)
return this
endmethod
endstruct
public function Show takes string s, integer id, unit u, integer r, integer g, integer b, real size returns nothing
local integer amt
local integer i
local integer len
local real a = PlayerCamera[PNumb].Rotation-90*bj_DEGTORAD
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real z = PanelCore_GetUnitZ(u)
local real scale = 0.75*(size/9.)
local real sway = 0//256
local unit dummy
local FadingText fade
if s == "BLOCK" then
set dummy = GetDummy(10)
call SetUnitScale(dummy, 3*scale, 1, 1)
call SetUnitVertexColor(dummy, r, g, b, 255)
call SetUnitX(dummy, x)
call SetUnitY(dummy, y)
call PanelCore_SetUnitZ(dummy, z)
call Fly.create(dummy, 5)
set fade = FadingText.create(dummy, 350, 5, sway, PlayerCamera[id].Rotation * bj_DEGTORAD, 10)
set fade.r = r
set fade.g = g
set fade.b = b
elseif s == "COUNTER" then
set dummy = GetDummy(11)
call SetUnitScale(dummy, 3*scale, 1, 1)
call SetUnitVertexColor(dummy, r, g, b, 255)
call SetUnitX(dummy, x)
call SetUnitY(dummy, y)
call PanelCore_SetUnitZ(dummy, z)
call Fly.create(dummy, 5)
set fade = FadingText.create(dummy, 350, 5, sway, PlayerCamera[id].Rotation * bj_DEGTORAD, 11)
set fade.r = r
set fade.g = g
set fade.b = b
elseif s == "MISS" then
set dummy = GetDummy(12)
call SetUnitScale(dummy, 3*scale, 1, 1)
call SetUnitVertexColor(dummy, r, g, b, 255)
call SetUnitX(dummy, x)
call SetUnitY(dummy, y)
call PanelCore_SetUnitZ(dummy, z)
call Fly.create(dummy, 5)
set fade = FadingText.create(dummy, 350, 5, sway, PlayerCamera[id].Rotation * bj_DEGTORAD, 12)
set fade.r = r
set fade.g = g
set fade.b = b
else
set i = 0
set len = StringLength(s)
loop
exitwhen i == len
set amt = S2I(SubString(s, i, i+1))
if i > 0 then
set x = x + DamageTextWidth[amt]/2*scale*Cos(a)
set y = y + DamageTextWidth[amt]/2*scale*Sin(a)
endif
set dummy = GetDummy(amt)
call SetUnitScale(dummy, 3*scale, 1, 1)
call SetUnitVertexColor(dummy, r, g, b, 255)
call SetUnitX(dummy, x)
call SetUnitY(dummy, y)
call PanelCore_SetUnitZ(dummy, z)
call Fly.create(dummy, 5)
set fade = FadingText.create(dummy, 350, 5, sway, PlayerCamera[id].Rotation * bj_DEGTORAD, amt)
set fade.r = r
set fade.g = g
set fade.b = b
set x = x + (DamageTextWidth[amt]/2 + 1)*scale*Cos(a)
set y = y + (DamageTextWidth[amt]/2 + 1)*scale*Sin(a)
set i = i + 1
endloop
endif
set dummy = null
endfunction
private function PreloadDummy takes nothing returns nothing
call RecycleDummy(GetDummy(PreloadIndex), PreloadIndex)
endfunction
private function init takes nothing returns nothing
local integer i = 0
local integer j
set DamageTextRaw[0] = 'DT00'
set DamageTextRaw[1] = 'DT01'
set DamageTextRaw[2] = 'DT02'
set DamageTextRaw[3] = 'DT03'
set DamageTextRaw[4] = 'DT04'
set DamageTextRaw[5] = 'DT05'
set DamageTextRaw[6] = 'DT06'
set DamageTextRaw[7] = 'DT07'
set DamageTextRaw[8] = 'DT08'
set DamageTextRaw[9] = 'DT09'
set DamageTextRaw[10] = 'DT0A'
set DamageTextRaw[11] = 'DT0B'
set DamageTextRaw[12] = 'DT0C'
set DamageTextWidth[0] = 27.0
set DamageTextWidth[1] = 27.0
set DamageTextWidth[2] = 25.6
set DamageTextWidth[3] = 27.0
set DamageTextWidth[4] = 28.0
set DamageTextWidth[5] = 25.6
set DamageTextWidth[6] = 27.5
set DamageTextWidth[7] = 26.0
set DamageTextWidth[8] = 25.6
set DamageTextWidth[9] = 27.5
loop
exitwhen i > 12
set PreloadGroup[i] = CreateGroup()
set PreloadIndex = i
set j = 0
loop
exitwhen j >= PRELOAD_COUNT
call ForForce(bj_FORCE_PLAYER[0], function PreloadDummy)
set j = j + 1
endloop
set i = i + 1
endloop
endfunction
endlibrary
library MiniHealthBar initializer init uses TimerUtils, PanelCore
globals
public integer array alpha
public unit array bar
public texttag array name
public timer array time
public Table nameDisplayed
string array CreepRankColor
private group PreloadGroup = CreateGroup()
public constant integer PRELOAD_COUNT = 15
endglobals
private function GetDummy takes nothing returns unit
set bj_lastCreatedUnit = FirstOfGroup(PreloadGroup)
if bj_lastCreatedUnit == null then
set bj_lastCreatedUnit = CreateUnit(PanelCore_PASSIVE, 'e00G', 0, 0, 0)
static if not LIBRARY_AutoFly then
if UnitAddAbility(bj_lastCreatedUnit, 'Amrf') and UnitRemoveAbility(bj_lastCreatedUnit, 'Amrf') then
endif
endif
call UnitAddAbility(bj_lastCreatedUnit, PanelCore_TEXTURE_REPLACER_ID)
call UnitRemoveAbility(bj_lastCreatedUnit, 'Amov')
call SetUnitPathing(bj_lastCreatedUnit, false)
else
call GroupRemoveUnit(PreloadGroup, bj_lastCreatedUnit)
endif
return bj_lastCreatedUnit
endfunction
private function RecycleDummy takes unit u returns nothing
call SetUnitX(u, WorldBounds.maxX)
call SetUnitY(u, WorldBounds.maxY)
call GroupAddUnit(PreloadGroup, u)
endfunction
private function onPeriodic takes nothing returns nothing
local timer t = GetExpiredTimer()
local Combatant c = GetTimerData(t)
local boolean alive
local real x
local real y
if alpha[c] > 15 then
set alive = IsUnitAlive(c.u)
set alpha[c] = alpha[c]-10
if alive then
set x = GetUnitX(c.u)
set y = GetUnitY(c.u)
call SetUnitX(bar[c], x)
call SetUnitY(bar[c], y)
if name[c] != null then
if (c.u == gg_unit_h002_0010) then
call SetTextTagPos(name[c], x-20, y-65, 100.)
else
call SetTextTagPos(name[c], x-65, y, 100.)
endif
endif
endif
if alpha[c] > 250 then
if not alive then
set alpha[c] = 250
endif
if c.owner == CREEP_PLAYER then
call SetUnitVertexColor(bar[c], 255, 0, 0, 250)
else
call SetUnitVertexColor(bar[c], 0, 255, 0, 250)
endif
if name[c] != null then
if alive then
call SetTextTagColor(name[c], 235, 235, 235, 255)
else
set nameDisplayed.boolean[c.uid] = false
call SetTextTagFadepoint(name[c], 0.)
call SetTextTagLifespan(name[c], 0.75)
set name[c] = null
endif
endif
else
if c.owner == CREEP_PLAYER then
call SetUnitVertexColor(bar[c], 255, 0, 0, alpha[c])
else
call SetUnitVertexColor(bar[c], 0, 255, 0, alpha[c])
endif
if name[c] != null then
call SetTextTagColor(name[c], 235, 235, 235, alpha[c])
endif
endif
else
if name[c] != null then
set nameDisplayed.boolean[c.uid] = false
call DestroyTextTag(name[c])
set name[c] = null
endif
call ReleaseTimer(t)
call RecycleDummy(bar[c])
set time[c] = null
set bar[c] = null
endif
set t = null
endfunction
public function Show takes player p, Combatant c, real hpr returns nothing
local integer pid = GetPlayerId(p)
local integer i
local integer index
local BJObjectId skin
local real x = GetUnitX(c.u)
local real y = GetUnitY(c.u)
local string color
if hpr < 0 then
set hpr = 0
elseif hpr > 1 then
set hpr = 1
endif
if time[c] == null then
set time[c] = NewTimerEx(c)
set bar[c] = GetDummy()
call SetUnitX(bar[c], x)
call SetUnitY(bar[c], y)
call SetUnitFlyHeight(bar[c], 100., 0)
if c.owner == CREEP_PLAYER then
call SetUnitVertexColor(bar[c], 255, 0, 0, 250)
else
call SetUnitVertexColor(bar[c], 0, 255, 0, 250)
endif
endif
set alpha[c] = 1000
set skin = BJObjectId('MH00')
set index = R2I(75.*hpr + 0.5)
set i = 0
loop
exitwhen i == index
set skin = skin.plus_1()
set i = i + 1
endloop
call PanelCore_ChangeTexture(bar[c], skin)
if name[c] == null and (not nameDisplayed.boolean[c.uid] or IsUnitInGroup(c.u, PlayerUnits)) then
set nameDisplayed.boolean[c.uid] = true
set name[c] = CreateTextTag()
call SetTextTagPermanent(name[c], false)
if c.destructible then
call SetTextTagText(name[c], GetUnitName(c.u), 0.018)
elseif IsUnitInGroup(c.u, PlayerUnits) then
call SetTextTagText(name[c], "|cff00dd00Lv. " + I2S(c.level) + " " + GetUnitName(c.u) + "|r", 0.018)
else
if c.level-Level[PNumb] >= 6 then
set color = "|cffff0000"
elseif c.level-Level[PNumb] >= 3 then
set color = "|cffffd200"
elseif c.level-Level[PNumb] >= 0 then
set color = "|cff5aff00"
else
set color = "|cffcccccc"
endif
call SetTextTagText(name[c], color + "Lv. " + I2S(c.level) + CreepRankColor[IMaxBJ(c.dropQuality, 0)] + " " + GetUnitName(c.u) + "|r", 0.018)
endif
if (c.u == gg_unit_h002_0010) then
call SetTextTagPos(name[c], x-20, y-65, 100.)
else
call SetTextTagPos(name[c], x-65, y, 100.)
endif
call SetTextTagVisibility(name[c], true)
endif
call SetUnitX(bar[c], x)
call SetUnitY(bar[c], y)
call TimerStart(time[c], 0.03125, true, function onPeriodic)
endfunction
private function PreloadDummy takes nothing returns nothing
call RecycleDummy(GetDummy())
endfunction
private function init takes nothing returns nothing
local integer i = 0
set nameDisplayed = Table.create()
loop
exitwhen i >= PRELOAD_COUNT
call ForForce(bj_FORCE_PLAYER[0], function PreloadDummy)
set i = i + 1
endloop
endfunction
endlibrary
//! textmacro CreateBarObject takes TYPE, CODE, INDEX, FILEPATH, EXTENSION
//! external ObjectMerger w3b YTlb $TYPE$$CODE$ bnam "(MiniHealthBar) $TYPE$ Bar $INDEX$" bfxr -1 bfil ".mdl" boch 0 btxf "$FILEPATH$$INDEX$$EXTENSION$" btxi 33 bfvi 1 bsel 0 bgsc 0 bshd "" barm "Ethereal" btar "tree" bcpr 0 bcpd 0 buch 0 bptx "" bsuf "" bcat "D"
//! endtextmacro
//! runtextmacro CreateBarObject ("MH", "00", "0", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "01", "1", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "02", "2", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "03", "3", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "04", "4", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "05", "5", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "06", "6", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "07", "7", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "08", "8", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "09", "9", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0A", "10", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0B", "11", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0C", "12", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0D", "13", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0E", "14", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0F", "15", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0G", "16", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0H", "17", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0I", "18", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0J", "19", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0K", "20", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0L", "21", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0M", "22", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0N", "23", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0O", "24", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0P", "25", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0Q", "26", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0R", "27", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0S", "28", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0T", "29", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0U", "30", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0V", "31", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0W", "32", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0X", "33", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0Y", "34", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "0Z", "35", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "10", "36", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "11", "37", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "12", "38", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "13", "39", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "14", "40", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "15", "41", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "16", "42", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "17", "43", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "18", "44", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "19", "45", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1A", "46", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1B", "47", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1C", "48", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1D", "49", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1E", "50", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1F", "51", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1G", "52", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1H", "53", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1I", "54", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1J", "55", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1K", "56", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1L", "57", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1M", "58", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1N", "59", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1O", "60", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1P", "61", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1Q", "62", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1R", "63", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1S", "64", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1T", "65", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1U", "66", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1V", "67", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1W", "68", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1X", "69", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1Y", "70", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "1Z", "71", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "20", "72", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "21", "73", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "22", "74", "war3mapImported\MiniHealthBar", ".blp")
//! runtextmacro CreateBarObject ("MH", "23", "75", "war3mapImported\MiniHealthBar", ".blp")
library Sync requires SyncInteger, optional PlayerUtils
/***************************************************************
*
* v1.3.0, by TriggerHappy
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*
* This library allows you to quickly synchronize async data such as
* the contents of a local file to all players in the map by using the game cache.
*
* Full Documentation: -http://www.hiveworkshop.com/forums/pastebin.php?id=p4f84s
*
* _________________________________________________________________________
* 1. Installation
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Copy the script to your map and save it (requires JassHelper *or* JNGP)
*
* SyncInteger: https://www.hiveworkshop.com/threads/syncinteger.278674/
* PlayerUtils: https://www.hiveworkshop.com/threads/playerutils.278559/
* _________________________________________________________________________
* 2. API
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* struct SyncData
*
* method start takes nothing returns nothing
* method startChunk takes integer i, integer end returns nothing
* method refresh takes nothing returns nothing
* method destroy takes nothing returns nothing
*
* method addInt takes integer i returns nothing
* method addReal takes integer i returns nothing
* method addString takes string s, integer len returns nothing
* method addBool takes booleanflag returns nothing
*
* method readInt takes integer index returns integer
* method readReal takes integer index returns integer
* method readString takes integer index returns string
* method readBool takes integer index returns boolean
*
* method hasInt takes integer index returns boolean
* method hasReal takes integer index returns boolean
* method hasString takes integer index returns boolean
* method hasBool takes integer index returns boolean
*
* method isPlayerDone takes player p returns boolean
* method isPlayerIdDone takes integer pid returns boolean
*
* method addEventListener takes filterfunc func returns nothing
*
* ---------
*
* filterfunc onComplete
* filterfunc onError
* filterfunc onUpdate
* trigger trigger
*
* readonly player from
*
* readonly real timeStarted
* readonly real timeFinished
* readonly real timeElapsed
*
* readonly integer intCount
* readonly integer boolCount
* readonly integer strCount
* readonly integer realCount
* readonly integer playersDone
*
* readonly boolean buffering
*
* readonly static integer last
* readonly static player LocalPlayer
* readonly static boolean Initialized
*
* static method create takes player from returns SyncData
* static method destroy takes nothing returns nothing
* static method gameTime takes nothing returns real
*
* function GetSyncedData takes nothing returns SyncData
*
***************************************************************/
globals
// characters that can be synced (ascii)
private constant string ALPHABET = " !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\"\t\n"
// safe characters for use in game cache keys
// (case sensitive)
private constant string SAFE_KEYS = " !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`{|}~\"\t\n"
// stop reading the string buffer when reaching this char (this char cannot be synced)
private constant string TERM_CHAR = "~"
// how fast the buffer updates
private constant real UPDATE_PERIOD = 0.03125
// automatically recycle indices when the syncing player leaves
private constant boolean AUTO_DESTROY_ON_LEAVE = true
// automatically stop buffering when an error occurs
private constant boolean STOP_BUFFERING_ON_ERROR = true
// preload game cache key strings on init
private constant boolean PRELOAD_STR_CACHE = true
// size of the alphabet
private constant integer ALPHABET_BASE = StringLength(ALPHABET)
// maximum number of strings *per instance*
private constant integer MAX_STRINGS = 100000 // or any arbitrary high number
// filenames for gc (short names have faster sync time)
private constant string CACHE_FILE = "i"
private constant string CACHE_FILE_STR = "s"
// don't edit below this line
constant integer EVENT_SYNC_CACHE = 3
constant integer SYNC_ERROR_TIMEOUT = 1
constant integer SYNC_ERROR_PLAYERLEFT = 2
private SelectionSync Synchronizer
endglobals
//**************************************************************
function GetSyncedData takes nothing returns SyncData
return SyncData(SyncData.Last)
endfunction
public function I2Char takes string alphabet, integer i returns string
return SubString(alphabet, i, i + 1)
endfunction
public function Char2I takes string alphabet, string c returns integer
local integer i = 0
local string s
local integer l = StringLength(alphabet)
loop
set s = I2Char(alphabet, i)
exitwhen i == l
if (s == c) then
return i
endif
set i = i + 1
endloop
return 0
endfunction
public function ConvertBase takes string alphabet, integer i returns string
local integer b
local string s = ""
local integer l = StringLength(alphabet)
if i < l then
return I2Char(alphabet, i)
endif
loop
exitwhen i <= 0
set b = i - ( i / l ) * l
set s = I2Char(alphabet, b) + s
set i = i / l
endloop
return s
endfunction
public function PopulateString takes string s, integer makeLen returns string
local integer i = 0
local integer l = StringLength(s)
if (l == makeLen) then
return s
endif
set l = makeLen-l
loop
exitwhen i > l
set s = s + TERM_CHAR
set i = i + 1
endloop
return s
endfunction
//**************************************************************
globals
// string table keys
private constant integer KEY_STR_POS = (0*MAX_STRINGS)
private constant integer KEY_STR_LEN = (1*MAX_STRINGS)
// pending data storage space
private constant integer KEY_STR_CACHE = (2*MAX_STRINGS)
endglobals
struct SyncData
real timeout
filterfunc onComplete
filterfunc onError
filterfunc onUpdate
trigger trigger
readonly integer lastError
readonly player from
readonly real timeStarted
readonly real timeFinished
readonly real timeElapsed
readonly integer intCount
readonly integer boolCount
readonly integer strCount
readonly integer realCount
readonly integer playersDone
readonly boolean buffering
readonly static boolean Initialized = false
readonly static integer Last = 0
readonly static player LocalPlayer
readonly static integer LocalPlayerID
private static integer Running = 0
private static real timeCounter = 0.00
private static trigger EventTrig = CreateTrigger()
private static hashtable Table
private static hashtable CharTable
private static gamecache array Cache
private static integer array PendingCount
private static timer Elapsed
private static timer BufferTimer
private static integer AlphaHash
private integer strBufferLen
private trigger eventTrig
private string mkey
private boolean localFinished
private thistype next
private thistype prev
static method bool2I takes boolean b returns integer
if (b) then
return 1
endif
return 0
endmethod
private static method hashString takes string c returns integer
return StringHash(I2S(bool2I(StringCase(c, true) == c)) + c)
endmethod
static method char2I takes string alphabet, string c returns integer // requires preloading table with data
return LoadInteger(SyncData.CharTable, .AlphaHash, .hashString(c))
endmethod
private method resetVars takes nothing returns nothing
set this.intCount = 0
set this.strCount = 0
set this.boolCount = 0
set this.realCount = 0
set this.playersDone = 0
set this.strBufferLen = 0
set this.timeStarted = 0
set this.timeFinished = 0
set this.lastError = 0
set this.onComplete = null
set this.onError = null
set this.onUpdate = null
set this.timeout = 0.00
set this.buffering = false
set this.localFinished = false
set this.trigger = null
endmethod
private static method getKey takes integer pos returns string
local string position=""
if (HaveSavedString(Table, KEY_STR_CACHE, pos)) then
return LoadStr(Table, KEY_STR_CACHE, pos)
endif
set position = ConvertBase(SAFE_KEYS, pos)
call SaveStr(Table, KEY_STR_CACHE, pos, position)
return position
endmethod
static method create takes player from returns thistype
local thistype this
// Player has to be playing because of GetLocalPlayer use.
if (GetPlayerController(from) != MAP_CONTROL_USER or GetPlayerSlotState(from) != PLAYER_SLOT_STATE_PLAYING) then
return 0
endif
set this = thistype.allocate()
set this.from = from
set this.mkey = getKey(this-1)
call this.resetVars()
set thistype(0).next.prev = this
set this.next = thistype(0).next
set thistype(0).next = this
set this.prev = 0
return this
endmethod
method refresh takes nothing returns nothing
local integer i = 0
local integer p = 0
loop
static if (LIBRARY_PlayerUtils) then
exitwhen i == User.AmountPlaying
set p = User.fromPlaying(i).id
else
exitwhen i == bj_MAX_PLAYER_SLOTS
set p = i
endif
call RemoveSavedInteger(Table, this, KEY_STR_POS + p)
call RemoveSavedInteger(Table, this, KEY_STR_LEN + p)
call RemoveSavedBoolean(Table, p, this) // playerdone
set i = i + 1
endloop
call FlushStoredMission(Cache[0], this.mkey)
call FlushStoredMission(Cache[1], this.mkey)
call this.resetVars()
endmethod
method destroy takes nothing returns nothing
if (this.eventTrig != null) then
call DestroyTrigger(this.eventTrig)
set this.eventTrig=null
endif
call this.refresh()
set this.next.prev = this.prev
set this.prev.next = this.next
call this.deallocate()
endmethod
method hasInt takes integer index returns boolean
return HaveStoredInteger(Cache[0], this.mkey, getKey(index))
endmethod
method hasReal takes integer index returns boolean
return HaveStoredReal(Cache[0], this.mkey, getKey(index))
endmethod
method hasBool takes integer index returns boolean
return HaveStoredBoolean(Cache[0], this.mkey, getKey(index))
endmethod
method hasString takes integer index returns boolean
local integer i = LoadInteger(Table, this, KEY_STR_POS+index)
if (index > 0 and i == 0) then
return false
endif
return HaveStoredInteger(Cache[1], this.mkey, getKey(i + LoadInteger(Table, this, KEY_STR_LEN+index)))
endmethod
method addInt takes integer i returns nothing
local string position=getKey(intCount)
if (LocalPlayer == this.from) then
call StoreInteger(Cache[0], this.mkey, position, i)
endif
set intCount=intCount+1
endmethod
method addReal takes real i returns nothing
local string position=getKey(realCount)
if (LocalPlayer == this.from) then
call StoreReal(Cache[0], this.mkey, position, i)
endif
set realCount=realCount+1
endmethod
method addBool takes boolean flag returns nothing
local string position=getKey(boolCount)
if (LocalPlayer == this.from) then
call StoreBoolean(Cache[0], this.mkey, position, flag)
endif
set boolCount=boolCount+1
endmethod
// SyncStoredString doesn't work
method addStringEx takes string s, integer maxLen, boolean doSync returns nothing
local string position
local integer i = 0
local integer strPos = 0
local integer strLen = 0
if (StringLength(s) < maxLen) then
set s = PopulateString(s, maxLen)
endif
// store the string position in the table
if (strCount == 0) then
call SaveInteger(Table, this, KEY_STR_POS, 0)
else
set strLen = LoadInteger(Table, this, KEY_STR_LEN + (strCount-1)) + 1
set strPos = LoadInteger(Table, this, KEY_STR_POS + (strCount-1)) + strLen
call SaveInteger(Table, this, KEY_STR_POS + strCount, strPos)
endif
// convert each character in the string to an integer
loop
exitwhen i > maxLen
set position = getKey(strPos + i)
if (LocalPlayer == this.from) then
call StoreInteger(Cache[1], this.mkey, position, .char2I(ALPHABET, SubString(s, i, i + 1)))
if (doSync and LocalPlayer == this.from) then
call SyncStoredInteger(Cache[1], this.mkey, position)
endif
endif
set i = i + 1
endloop
set strBufferLen = strBufferLen + maxLen
call SaveInteger(Table, this, KEY_STR_LEN+strCount, maxLen) // store the length as well
set strCount=strCount+1
endmethod
method addString takes string s, integer maxLen returns nothing
call addStringEx(s, maxLen, false)
endmethod
method readInt takes integer index returns integer
return GetStoredInteger(Cache[0], this.mkey, getKey(index))
endmethod
method readReal takes integer index returns real
return GetStoredReal(Cache[0], this.mkey, getKey(index))
endmethod
method readBool takes integer index returns boolean
return GetStoredBoolean(Cache[0], this.mkey, getKey(index))
endmethod
method readString takes integer index returns string
local string s = ""
local string c
local integer i = 0
local integer strLen = LoadInteger(Table, this, KEY_STR_LEN+index)
local integer strPos
if (not hasString(index)) then
return null
endif
set strLen = LoadInteger(Table, this, KEY_STR_LEN+index)
set strPos = LoadInteger(Table, this, KEY_STR_POS+index)
loop
exitwhen i > strLen
set c = I2Char(ALPHABET, GetStoredInteger(Cache[1], this.mkey, getKey(strPos + i)))
if (c == TERM_CHAR) then
return s
endif
set s = s + c
set i = i + 1
endloop
return s
endmethod
private method fireListeners takes nothing returns nothing
set Last = this
if (this.eventTrig != null) then
call TriggerEvaluate(this.eventTrig)
endif
if (this.trigger != null and TriggerEvaluate(this.trigger)) then
call TriggerExecute(this.trigger)
endif
endmethod
private method fireEvent takes filterfunc func returns nothing
set Last = this
call TriggerAddCondition(EventTrig, func)
call TriggerEvaluate(EventTrig)
call TriggerClearConditions(EventTrig)
endmethod
method addEventListener takes filterfunc func returns nothing
if (this.eventTrig == null) then
set this.eventTrig = CreateTrigger()
endif
call TriggerAddCondition(this.eventTrig, func)
endmethod
public static method gameTime takes nothing returns real
return timeCounter + TimerGetElapsed(Elapsed)
endmethod
private method error takes integer errorId returns nothing
set this.lastError = errorId
if (this.onError != null) then
call this.fireEvent(this.onError)
endif
call this.fireListeners()
static if (STOP_BUFFERING_ON_ERROR) then
set this.buffering = false
endif
endmethod
private static method readBuffer takes nothing returns nothing
local boolean b = true
local integer i = 0
local thistype data = thistype(0).next
loop
exitwhen data == 0
// find the nearest instance that is still buffering
loop
exitwhen data.buffering or data == 0
set data=data.next
endloop
// if none are found, exit
if (not data.buffering) then
return
endif
set data.timeElapsed = data.timeElapsed + UPDATE_PERIOD
if (data.onUpdate != null) then
call data.fireEvent(data.onUpdate)
endif
if (data.timeout > 0 and data.timeElapsed > data.timeout) then
call data.error(SYNC_ERROR_TIMEOUT)
endif
// if the player has left, destroy the instance
if (GetPlayerSlotState(data.from) != PLAYER_SLOT_STATE_PLAYING) then
call data.error(SYNC_ERROR_PLAYERLEFT)
static if (AUTO_DESTROY_ON_LEAVE) then
call data.destroy()
endif
endif
set b = true
// make sure all integers have been synced
if (data.intCount > 0 and not data.hasInt(data.intCount-1)) then
set b = false
endif
// make sure all reals have been synced
if (data.realCount > 0 and not data.hasReal(data.realCount-1)) then
set b = false
endif
// check strings too
if (data.strCount > 0 and not data.hasString(data.strCount-1)) then
set b = false
endif
// and booleans
if (data.boolCount > 0 and not data.hasBool(data.boolCount-1)) then
set b = false
endif
// if everything has been synced
if (b) then
if (not data.localFinished) then // async
set data.localFinished = true
// notify everyone that the local player has recieved all of the data
call Synchronizer.syncValue(LocalPlayer, data)
endif
endif
set data = data.next
endloop
endmethod
public method initInstance takes nothing returns nothing
if (this.timeStarted != 0.00) then
return
endif
set this.timeStarted = gameTime()
set this.playersDone = 0
set this.buffering = true
set this.timeElapsed = (UPDATE_PERIOD - TimerGetElapsed(BufferTimer)) * -1
if (Running==0) then
call TimerStart(BufferTimer, UPDATE_PERIOD, true, function thistype.readBuffer)
call thistype.readBuffer()
endif
set Running=Running+1
endmethod
method syncInt takes integer i returns nothing
local string position = getKey(intCount)
call this.addInt(i)
if (LocalPlayer == this.from) then
call SyncStoredInteger(Cache[0], this.mkey, position)
endif
call this.initInstance()
endmethod
method syncReal takes real r returns nothing
local string position = getKey(realCount)
call this.addReal(r)
if (LocalPlayer == this.from) then
call SyncStoredReal(Cache[0], this.mkey, position)
endif
call this.initInstance()
endmethod
method syncBoolean takes boolean b returns nothing
local string position = getKey(boolCount)
call this.addBool(b)
if (LocalPlayer == this.from) then
call SyncStoredReal(Cache[0], this.mkey, position)
endif
call this.initInstance()
endmethod
method syncString takes string s, integer maxLen returns nothing
local string position = getKey(strCount)
call this.addStringEx(s, maxLen, true)
call this.initInstance()
endmethod
method startChunk takes integer i, integer end returns boolean
local integer n = 0
local integer j = 0
local integer p = 0
local string position
if (this.timeStarted != 0.00) then
return false
endif
// Begin syncing
loop
exitwhen i > end
set position = LoadStr(Table, KEY_STR_CACHE, i)
if (i < intCount and LocalPlayer == this.from) then
call SyncStoredInteger(Cache[0], this.mkey, position)
endif
if (i < realCount and LocalPlayer == this.from) then
call SyncStoredReal(Cache[0], this.mkey, position)
endif
if (i < boolCount and LocalPlayer == this.from) then
call SyncStoredBoolean(Cache[0], this.mkey, position)
endif
if (i < strCount and LocalPlayer == this.from) then
set n = LoadInteger(Table, this, KEY_STR_LEN + i)
set p = LoadInteger(Table, this, KEY_STR_POS + i)
set j = 0
loop
exitwhen j > n
set position = LoadStr(Table, KEY_STR_CACHE, p + j)
if (LocalPlayer == this.from) then
call SyncStoredInteger(Cache[1], this.mkey, position)
endif
set j = j + 1
endloop
endif
set i = i + 1
endloop
call this.initInstance()
return true
endmethod
method start takes nothing returns boolean
local integer l = intCount
// Find the highest count
if (l < realCount) then
set l = realCount
endif
if (l < strCount) then
set l = strCount
endif
if (l < boolCount) then
set l = boolCount
endif
return startChunk(0, l)
endmethod
method isPlayerIdDone takes integer pid returns boolean
return LoadBoolean(Table, pid, this)
endmethod
method isPlayerDone takes player p returns boolean
return isPlayerIdDone(GetPlayerId(p))
endmethod
private static method updateStatus takes nothing returns boolean
local integer i = 0
local integer p = GetSyncedPlayerId()
local boolean b = true
local boolean c = true
local thistype data = GetSyncedInteger()
local triggercondition tc
if (GetSyncedInstance() != Synchronizer or not data.buffering) then
return false
endif
set data.playersDone = data.playersDone + 1
call SaveBoolean(Table, p, data, true) // set playerdone
// check if everyone has received the data
loop
static if (LIBRARY_PlayerUtils) then
exitwhen i == User.AmountPlaying
set p = User.fromPlaying(i).id
set c = User.fromPlaying(i).isPlaying
else
exitwhen i == bj_MAX_PLAYER_SLOTS
set p = i
set c = (GetPlayerController(Player(p)) == MAP_CONTROL_USER and GetPlayerSlotState(Player(p)) == PLAYER_SLOT_STATE_PLAYING)
endif
if (c and not data.isPlayerIdDone(p)) then
set b = false // someone hasn't
endif
set i = i + 1
endloop
// if everyone has recieved the data
if (b) then
set Running = Running-1
if (Running == 0) then
call PauseTimer(BufferTimer)
endif
set data.buffering = false
set data.timeFinished = gameTime()
set data.timeElapsed = data.timeFinished - data.timeStarted
// fire events
if (data.onComplete != null) then
call data.fireEvent(data.onComplete)
endif
call data.fireListeners()
call SyncInteger_FireEvents(EVENT_SYNC_CACHE)
endif
return false
endmethod
private static method trackTime takes nothing returns nothing
set timeCounter = timeCounter + 10
endmethod
private static method preloadChar2I takes nothing returns nothing
local integer i = 0
local string c
set .AlphaHash = .hashString(ALPHABET)
loop
exitwhen i >= ALPHABET_BASE
set c = I2Char(ALPHABET, i)
call SaveInteger(SyncData.CharTable, .AlphaHash, .hashString(c), Char2I(ALPHABET, c))
set i = i + 1
endloop
endmethod
private static method onInit takes nothing returns nothing
static if (SyncInteger_DEFAULT_INSTANCE) then
set Synchronizer = SyncInteger_DefaultInstance
else
set Synchronizer = SelectionSync.create()
endif
set Table = InitHashtable()
set CharTable = InitHashtable()
set Cache[0] = InitGameCache(CACHE_FILE)
set Cache[1] = InitGameCache(CACHE_FILE_STR)
set Elapsed = CreateTimer()
set BufferTimer = CreateTimer()
static if (LIBRARY_PlayerUtils) then
set LocalPlayer = User.Local
set LocalPlayerID = User.fromLocal().id
else
set LocalPlayer = GetLocalPlayer()
set LocalPlayerID = GetPlayerId(LocalPlayer)
endif
call OnSyncInteger(Filter(function thistype.updateStatus))
call TimerStart(Elapsed, 10., true, function thistype.trackTime)
static if (PRELOAD_STR_CACHE) then
loop
exitwhen Last == ALPHABET_BASE
call getKey(Last)
set Last = Last + 1
endloop
set Last = 0
endif
call preloadChar2I()
set Initialized = true
endmethod
endstruct
endlibrary
library SyncInteger uses optional UnitDex /*or any unit indexer*/, optional GroupUtils, optional xebasic, optional PlayerUtils
/***************************************************************
*
* v1.2.1, by TriggerHappy
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*
* This library allows you to send integers to all other players through
* unit selections.
*
* _________________________________________________________________________
* 1. Installation
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Copy the script to your map and save it (requires JassHelper *or* JNGP)
* _________________________________________________________________________
* 2. How it works
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* 1. Creates {DUMMY_COUNT} units and assigns {BASE} of them an integer from 0-{BASE}.
* The 2nd to last dummy is used to signal when the sequence of numbers is over and
* the last dummy signifies a negative number.
*
* 2. Breaks down the number you want to sync to one or more {BASE} integers,
* then selects each dummy unit assoicated with that integer.
*
* 4. The selection event fires for all players when the selection has been sycned
*
* 5. The ID of the selected unit is one of the {BASE} numbers. The current
* total (starts at 0) is multiplied by {BASE} and the latest synced integer is
* added to that. The process will repeat until it selects the 2nd to last dummy,
* and the total is our result.
* _________________________________________________________________________
* 3. Proper Usage
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* - Dummies must be select-able (no locust)
*
* - Run the script in debug mode while testing
*
* _________________________________________________________________________
* 4. Struct API
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* struct SelectionSync
*
* static method create takes nothing returns thistype
*
* method syncValue takes player p, integer number returns boolean
* method destroy takes nothing returns nothing
* _________________________________________________________________________
* 5. Function API
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* function SyncInteger takes player p, integer number returns boolean
*
* function GetSyncedInteger takes nothing returns integer
* function GetSyncedInstance takes nothing returns integer
* function GetSyncedPlayer takes nothing returns player
* function GetSyncedPlayerId takes nothing returns integer
* function IsPlayerSyncing takes player p returns boolean
* function IsPlayerIdSyncing takes integer pid returns boolean
* function IsSyncEnabled takes nothing returns boolean
* function SyncIntegerToggle takes boolean flag returns nothing
* function SyncIntegerEnable takes nothing returns nothing
* function SyncIntegerDisable takes nothing returns nothing
*
* function OnSyncInteger takes filterfunc func returns triggercondition
* function RemoveSyncEvent takes triggercondition action returns nothing
* function TriggerRegisterSyncEvent takes trigger t, integer eventtype returns nothing
*
* function SyncTerminate takes boolean destroyEvent returns nothing
*
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* -http://www.hiveworkshop.com/threads/syncinteger.278674/
*
*/
globals
// create a struct instance for global use
public constant boolean DEFAULT_INSTANCE = true
// owner of the dummy units
public constant player DUMMY_PLAYER = Player(PLAYER_NEUTRAL_PASSIVE)
// Dummy can *not* have locust and must be selectabe.
public constant integer DUMMY_ID = 'hfoo'
// allow debug messages (also requries JassHelper Debug Mode)
public constant boolean ALLOW_DEBUGGING = true
// higher == more dummies but less selections (faster)
public constant integer BASE = 10
// two higher than BASE (jasshelper doesn't allow BASE + 2)
public constant integer DUMMY_COUNT = 12
// endconfig
constant integer EVENT_SYNC_INTEGER = 1
public integer DefaultInstance = 0
private trigger OnSelectTrigger = CreateTrigger()
private trigger EventTrig = CreateTrigger()
private real FireEvent = 0
private group SelectionGroup
private integer LastPlayer
private integer LastSync
private integer LastInstance
private player LocalPlayer
private integer array ActiveSyncs
private real DUMMY_X = 0
private real DUMMY_Y = 0
private integer array DummyInstance
endglobals
function GetSyncedInteger takes nothing returns integer
return LastSync
endfunction
function GetSyncedPlayer takes nothing returns player
return Player(LastPlayer)
endfunction
function GetSyncedInstance takes nothing returns integer
return LastInstance
endfunction
function GetSyncedPlayerId takes nothing returns integer
return LastPlayer
endfunction
function IsPlayerIdSyncing takes integer pid returns boolean
return ActiveSyncs[pid] > 0
endfunction
function IsPlayerSyncing takes player p returns boolean
return ActiveSyncs[GetPlayerId(p)] > 0
endfunction
function IsSyncEnabled takes nothing returns boolean
return IsTriggerEnabled(OnSelectTrigger)
endfunction
function SyncIntegerEnable takes nothing returns nothing
call EnableTrigger(OnSelectTrigger)
endfunction
function SyncIntegerDisable takes nothing returns nothing
call DisableTrigger(OnSelectTrigger)
endfunction
function SyncIntegerToggle takes boolean flag returns nothing
if (flag) then
call EnableTrigger(OnSelectTrigger)
else
call DisableTrigger(OnSelectTrigger)
endif
endfunction
function OnSyncInteger takes filterfunc func returns triggercondition
return TriggerAddCondition(EventTrig, func)
endfunction
function RemoveSyncEvent takes triggercondition action returns nothing
call TriggerRemoveCondition(EventTrig, action)
endfunction
function TriggerRegisterSyncEvent takes trigger t, integer eventtype returns nothing
call TriggerRegisterVariableEvent(t, SCOPE_PREFIX + "FireEvent", EQUAL, eventtype)
endfunction
public function FireEvents takes real eventtype returns nothing
set FireEvent = eventtype
set FireEvent = 0
endfunction
// This function is called when a unit is selected.
private function OnSelect takes nothing returns boolean
local unit u = GetTriggerUnit()
local player p = GetTriggerPlayer()
local integer id = GetPlayerId(p)
local integer udata = GetUnitUserData(u)
local SelectionSync this = DummyInstance[udata]
local boolean isNeg = (this.Dummy[DUMMY_COUNT-1] == u)
local integer index = this.DummyID[udata] - 1
if (this <= 0) then
return false
endif
if (isNeg) then
set this.SyncingValue[id] = this.SyncingValue[id]*-1
endif
if (isNeg or this.Dummy[DUMMY_COUNT-2] == u) then
set ActiveSyncs[id] = ActiveSyncs[id] - 1
// The number is finished syncing, fire the events
set LastPlayer = id
set LastSync = this.SyncingValue[id]
set LastInstance = this
set FireEvent = EVENT_SYNC_INTEGER
call TriggerEvaluate(EventTrig)
// Reset variables
set FireEvent = 0
set this.SyncingValue[id] = -1
else
if (this.SyncingValue[id] == -1) then
set this.SyncingValue[id] = 0
endif
// Build the number we are trying to sync
set this.SyncingValue[id] = this.SyncingValue[id] * BASE + index
endif
set u = null
return false
endfunction
private keyword SyncIntegerInit
// This struct allows us to dynamically create a group of units
// which we can use to synchronize our integer through unit selections.
struct SelectionSync
public unit array Dummy[DUMMY_COUNT]
public integer array DummyID[DUMMY_COUNT]
public integer array SyncingValue[12]
public static method debugger takes boolean b, string s returns nothing
static if (ALLOW_DEBUGGING and DEBUG_MODE) then
if (b) then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "|c00FF0000" + SCOPE_PREFIX + s + "|r")
endif
endif
endmethod
static method create takes nothing returns thistype
local thistype this = thistype.allocate()
local integer i = 0
local integer uid
debug call .debugger(OnSelectTrigger == null, "[SelectionSync.create()] OnSelectTrigger is null and has no events attached to it.")
debug call .debugger(this.Dummy[0] != null, "[SelectionSync.create()] Dummy not null!")
loop
exitwhen i >= DUMMY_COUNT
set this.Dummy[i] = CreateUnit(DUMMY_PLAYER, DUMMY_ID, DUMMY_X, DUMMY_Y, i)
set uid = GetUnitUserData(this.Dummy[i])
if (uid == 0) then
set uid = ( (this-1) * DUMMY_COUNT ) + (i + 1)
call SetUnitUserData(this.Dummy[i], uid)
endif
debug call .debugger((i == 0) and (this.Dummy[i] == null), "[SelectionSync.create()] Dummy unit is null (check DUMMY_ID).")
debug call .debugger((i == 0) and (GetUnitAbilityLevel(this.Dummy[i], 'Aloc') > 0), "[SelectionSync.create()] Dummy units must be selectable (detected locust).")
set this.DummyID[uid] = i + 1
set DummyInstance[uid] = this
// Make dummy only selectable through triggers
call UnitAddAbility(this.Dummy[i], 'Amrf')
call SetUnitFlyHeight(this.Dummy[i], 5000, 0)
call UnitAddAbility(this.Dummy[i], 'Aeth')
call SetUnitScale(this.Dummy[i], 0, 0, 0)
call PauseUnit(this.Dummy[i], true)
// Hide health bar
call UnitAddAbility(this.Dummy[i], 'Aloc')
call ShowUnit(this.Dummy[i], false)
call UnitRemoveAbility(this.Dummy[i], 'Aloc')
call ShowUnit(this.Dummy[i], true)
set i = i + 1
endloop
return this
endmethod
method syncValue takes player p, integer number returns boolean
local integer x = number
local integer i = 0
local integer d = BASE
local integer j = 0
local integer n = 0
local integer l = 0
local integer playerId = GetPlayerId(p)
local unit u
local unit last
debug call .debugger(OnSelectTrigger == null, "[SelectionSync.syncValue()] OnSelectTrigger is destroyed.")
debug call .debugger(IsSyncEnabled() == false, "[SelectionSync.syncValue()] OnSelectTrigger is disabled.")
if (not IsSyncEnabled()) then
return false
endif
set ActiveSyncs[playerId] = ActiveSyncs[playerId] + 1
// Check if the number is negative
if (number < 0) then
set d = DUMMY_COUNT-1
set number = number * -1
endif
loop
set x = x/(BASE)
exitwhen x==0
set i=i+1
endloop
// Count how many units are selected
call GroupEnumUnitsSelected(SelectionGroup, p, null)
set bj_groupCountUnits = 0
set u = FirstOfGroup(SelectionGroup)
loop
exitwhen u == null
set last = u
call GroupRemoveUnit(SelectionGroup, u)
set bj_groupCountUnits = bj_groupCountUnits + 1
set u = FirstOfGroup(SelectionGroup)
endloop
// If the queue is full, de-select the last unit which
// will allow us to select a dummy, and hopefully
// avoid a flickering effect.
if (bj_groupCountUnits >= 12 and LocalPlayer == p) then
call SelectUnit(last, false)
endif
set j=R2I(Pow(BASE, i))
loop
set n = j
set x = number/n
set j = j / BASE
if (LocalPlayer == p) then
call SelectUnit(this.Dummy[x], true)
call SelectUnit(this.Dummy[x], false)
endif
set number = number-x*n
exitwhen i == 0
set i = i - 1
endloop
if (LocalPlayer == p) then
call SelectUnit(this.Dummy[d], true)
call SelectUnit(this.Dummy[d], false)
if (bj_groupCountUnits >= 12) then
call SelectUnit(last, true)
endif
endif
set u = null
set last = null
return true
endmethod
method destroy takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= DUMMY_COUNT
call RemoveUnit(this.Dummy[i])
set this.Dummy[i] = null
set i = i + 1
endloop
endmethod
implement SyncIntegerInit
endstruct
function SyncInteger takes player p, integer number returns boolean
debug call SelectionSync.debugger(DefaultInstance == 0, "[SyncInteger()] DefaultInstance is not initialized (make sure DEFAULT_INSTANCE is true")
return SelectionSync(DefaultInstance).syncValue(p, number)
endfunction
function SyncTerminate takes boolean destroyEvents returns boolean
local integer i = 0
if (OnSelectTrigger == null and EventTrig == null) then
return false
endif
if (destroyEvents) then
call DestroyTrigger(OnSelectTrigger)
call DestroyTrigger(EventTrig)
set OnSelectTrigger = null
set EventTrig = null
static if not LIBRARY_GroupUtils then
call DestroyGroup(SelectionGroup)
set SelectionGroup = null
endif
else
call SyncIntegerDisable()
endif
if (DefaultInstance > 0) then
call SelectionSync(DefaultInstance).destroy()
endif
return true
endfunction
//===========================================================================
private module SyncIntegerInit
private static method onInit takes nothing returns nothing
local integer i = 0
local integer j
loop
call TriggerRegisterPlayerUnitEvent(OnSelectTrigger, Player(i), EVENT_PLAYER_UNIT_SELECTED, null)
set i = i + 1
exitwhen i==bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(OnSelectTrigger, Filter(function OnSelect))
static if (LIBRARY_GroupUtils) then
set SelectionGroup=ENUM_GROUP
else
set SelectionGroup=CreateGroup()
endif
static if (LIBRARY_PlayerUtils) then
set LocalPlayer=User.Local
else
set LocalPlayer=GetLocalPlayer()
endif
set DUMMY_X = GetCameraBoundMaxX() + 2000
set DUMMY_Y = GetCameraBoundMaxY() + 2000
static if (DEFAULT_INSTANCE) then
set DefaultInstance = SelectionSync.create()
endif
endmethod
endmodule
endlibrary
// few modifications by triggerhappy
library FileIO /* v2.0.0.1
*************************************************************************************
*
* Used read/write data to/from files
*
************************************************************************************
*
* struct File extends array
*
* Description
* -----------------------
*
* This is used to read data from files and write data to files
*
* Creators/Destructors
* -----------------------
*
* static method open takes string mapName, string fileName, integer flag returns File
* - Used to open a file. Pass read/write flag in to open file for reading or writing.
*
* method close takes nothing returns nothing
*
* Fields
* -----------------------
*
* readonly boolean enabled
* - This is a local value. It is true if the player can read files, false if the player can't read files.
* readonly string localFileScriptName
* - This contains the name and path to a bat file that is automatically created
* - on the player's computer in the event that they can't read files. Output this filename
* - and tell them to run the script so that they can read files.
*
* integer Flag.READ
* integer Flag.WRITE
* - These are the read/write flags. Pass these into File.open
*
* Methods
* -----------------------
*
* method read takes nothing returns string
* - Reads next line from file. Returns null when there are no more lines.
*
* method write takes string data returns nothing
* - Writes line to file. The only limit is wc3 max string size.
*
************************************************************************************/
//Tests if the player can read files
private module LocalFileTestInit
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(),0,false,function thistype.init)
endmethod
endmodule
private struct LocalFileTest extends array
private static constant string FLAG_FOLDER = "Flag"
private static constant string FLAG_FILE = "flag.pld"
readonly static boolean success = false
private static method testForLocalEnabled takes nothing returns nothing
local string playerName = GetPlayerName(GetLocalPlayer())
call Preloader(FLAG_FILE)
set success = GetPlayerName(GetLocalPlayer()) != playerName
if not success then
call Preloader(FLAG_FOLDER + "\\" + FLAG_FILE)
set success = GetPlayerName(GetLocalPlayer()) != playerName
endif
call SetPlayerName(GetLocalPlayer(), playerName)
endmethod
private static method writeLocalFileTest takes nothing returns nothing
call PreloadGenClear()
call PreloadGenStart()
call Preload("\")\r\n\tcall SetPlayerName(GetLocalPlayer(), \"FLAG TEST LOCAL CHECK\")\r\n//")
call Preload("\" )\r\nendfunction\r\nfunction AAA takes nothing returns nothing \r\n//")
call PreloadGenEnd(FLAG_FILE)
call PreloadGenClear()
call PreloadGenStart()
call Preload("\")\r\n\tcall SetPlayerName(GetLocalPlayer(), \"FLAG TEST LOCAL CHECK\")\r\n//")
call Preload("\" )\r\nendfunction\r\nfunction AAA takes nothing returns nothing \r\n//")
call PreloadGenEnd(FLAG_FOLDER + "\\" + FLAG_FILE)
endmethod
private static method writeEnableLocalRegistry takes string fname returns nothing
call PreloadGenClear()
call PreloadGenStart()
call Preload("\")\r\necho Set Reg = CreateObject(\"wscript.shell\") > download.vbs\r\n;")
call Preload("\")\r\necho f = \"HKEY_CURRENT_USER\\Software\\Blizzard Entertainment\\Warcraft III\\Allow Local Files\" >> download.vbs\r\n;")
call Preload("\")\r\necho f = Replace(f,\"\\\",Chr(92)) >> download.vbs\r\n;") //"
call Preload("\")\r\necho Reg.RegWrite f, 1, \"REG_DWORD\" >> download.vbs\r\n;")
call Preload("\")\r\nstart download.vbs\r\n;")
call PreloadGenEnd(fname)
endmethod
private static method writeMapLink takes string fname returns nothing
call PreloadGenClear()
call PreloadGenStart()
call Preload("\")\r\nexplorer \"http://hiveworkshop.com/threads/294870\"\n")
call PreloadGenEnd(fname)
endmethod
private static method init takes nothing returns nothing
call DestroyTimer(GetExpiredTimer())
call writeLocalFileTest()
call testForLocalEnabled()
//call writeMapLink("Go to Embercraft website.bat")
if (not success) then
call writeEnableLocalRegistry(File.localFileScriptName)
call writeEnableLocalRegistry("C:\\!! AllowLocalFiles\\" + File.localFileScriptName) // for pre 128
//call writeEnableLocalRegistry("C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\" + File.localFileScriptName)
endif
endmethod
implement LocalFileTestInit
endstruct
private struct FlagG extends array
static constant integer READ = 1
static constant integer WRITE = 2
endstruct
private module FileInit
private static method onInit takes nothing returns nothing
call init()
endmethod
endmodule
struct File extends array
private static constant integer MAX_LINE_LENGTH = 209 //max amount of data per line
private static hashtable stringTable //stores lines from file, 16 lines per file
private static integer instanceCount = 0
private static integer array recycler
private string mapName
private string fileName
private string data //data buffer
private integer fileIndex //current file index, -2147483648 to 2147483647
private integer dataIndex //current data index for file, 0-15
private integer flag //read/write flag
private static string array extra0 //extra 0s on string lengths to make digits = 4
static method operator Flag takes nothing returns FlagG
return 0
endmethod
static method operator enabled takes nothing returns boolean
return LocalFileTest.success
endmethod
static method operator localFileScriptName takes nothing returns string
return "AllowLocalFiles.bat.txt"
endmethod
static method operator localFileScriptNameFull takes nothing returns string
return localFileScriptName
endmethod
static method open takes string mapName, string fileName, integer flag returns File
local thistype this = recycler[0]
if (0 == this) then
set this = instanceCount + 1
set instanceCount = this
else
set recycler[0] = recycler[this]
endif
set fileIndex = -2147483648
set this.mapName = mapName
set this.fileName = fileName + ".pld"
set this.flag = flag
if (flag == Flag.READ) then
//if reading, go to previous file index so that the reader can auto load up the file
set fileIndex = fileIndex - 1
set dataIndex = 16
elseif (flag == Flag.WRITE) then
//open file for writing
call PreloadGenClear()
call PreloadGenStart()
endif
return this
endmethod
//loads file and returns lines out of file
private static string array pname
private method loadline takes nothing returns nothing
local integer i
//if there are no more lines in the file, load next file
if (16 == dataIndex) then
set dataIndex = 0
set fileIndex = fileIndex + 1
//store current player names
set i = 15
loop
set pname[i] = GetPlayerName(Player(i))
exitwhen 0 == i
set i = i - 1
endloop
//load file (sets the player names to lines in file)
call Preloader(mapName + "\\" + fileName)
//flush file buffer
call FlushChildHashtable(stringTable, this)
//load lines from file to file buffer and return player names to normal
set i = 15
loop
if (pname[i] != GetPlayerName(Player(i))) then
call SaveStr(stringTable, this, i, SubString(GetPlayerName(Player(i)), 1, StringLength(GetPlayerName(Player(i)))))
call SetPlayerName(Player(i), pname[i])
endif
exitwhen 0 == i
set i = i - 1
endloop
endif
//add next line of file to data
set this.data = this.data + LoadStr(stringTable, this, dataIndex)
set dataIndex = dataIndex + 1
endmethod
method read takes nothing returns string
local integer length
local string data = ""
debug if (flag != Flag.READ) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60000,"FILE IO ERROR: ATTEMPT TO READ TO FILE OPEN FOR WRITING")
debug return null
debug endif
//if there is no data at the moment, get next line from file
if (StringLength(this.data) < 4) then
call loadline()
//if there is no next line, return null
if (StringLength(this.data) < 4) then
return null
endif
endif
//get the length of the data (# of characters that make it up)
set length = S2I(SubString(this.data, 0, 4))
set this.data = SubString(this.data, 4, StringLength(this.data))
loop
if (length > StringLength(this.data)) then
//if the length is greater than the data currently in the buffer, dump the
//entire buffer to the data being returned and get the next line
set length = length - StringLength(this.data)
set data = data + this.data
set this.data = ""
call loadline()
else
//if the length is less than the data in the buffer, dump that data
//from the buffer
set data = data + SubString(this.data, 0, length)
set this.data = SubString(this.data, length, StringLength(this.data))
set length = 0
return data
endif
endloop
return null
endmethod
method write takes string data returns nothing
local integer length = StringLength(data)
local integer digits = 0
local boolean done = false
debug if (flag != Flag.WRITE) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60000,"FILE IO ERROR: ATTEMPT TO WRITE TO FILE OPEN FOR READING")
debug return
debug endif
//first, retrieve the # of digits for the length
loop
set digits = digits + 1
set length = length/10
exitwhen 0 == length
endloop
//add the extra digits to and length to buffer
set this.data = this.data + extra0[digits] + I2S(StringLength(data))
loop
if (StringLength(data) > 400) then
//if the length of the data is greater than 400, throw first 400 chars into buffer
set this.data = this.data + SubString(data, 0, 400)
set data = SubString(data, 400, StringLength(data))
else
//if the length isn't greater than 400, throw it all into the buffer
set this.data = this.data + data
set data = ""
set done = true
endif
loop
//throw the data into file in sets of MAX_LINE_LENGTH chars until there is not
//enough data in the buffer to completely fill a line
exitwhen StringLength(this.data) < MAX_LINE_LENGTH
call Preload("\")\r\n\tcall SetPlayerName(Player("+I2S(dataIndex)+"), \" "+SubString(this.data, 0, MAX_LINE_LENGTH)+"\")\r\n//")
set this.data = SubString(this.data, MAX_LINE_LENGTH, StringLength(this.data))
set dataIndex = dataIndex + 1
if (dataIndex == 16) then
//start a new file
set dataIndex = 0
call Preload( "\" )\r\nendfunction\r\nfunction AAA takes nothing returns nothing \r\n//")
call PreloadGenEnd(mapName + "\\" + fileName)
set fileIndex = fileIndex + 1
call PreloadGenClear()
call PreloadGenStart()
endif
endloop
exitwhen done
endloop
endmethod
method close takes nothing returns nothing
if (flag == Flag.READ) then
//flush the read buffer
call FlushChildHashtable(stringTable, this)
elseif (flag == Flag.WRITE) then
//write remaining of data to file and close it out
call Preload("\")\r\n\tcall SetPlayerName(Player("+I2S(dataIndex)+"), \" "+data+"\")\r\n//")
call Preload( "\" )\r\nendfunction\r\nfunction AAA takes nothing returns nothing \r\n//")
call PreloadGenEnd(mapName + "\\" + fileName)
endif
//deallocate and reset
set recycler[this] = recycler[0]
set recycler[0] = this
set dataIndex = 0
set data = ""
endmethod
private static method init takes nothing returns nothing
set extra0[1] = "000"
set extra0[2] = "00"
set extra0[3] = "0"
set extra0[4] = ""
set stringTable = InitHashtable()
endmethod
implement FileInit
endstruct
endlibrary
library Savecode requires BigNum
globals
string SaveFolder = ""
string SaveFormat = ""
endglobals
private constant function uppercolor takes nothing returns string
return "|cffff0000"
endfunction
private constant function lowercolor takes nothing returns string
return "|cff00ff00"
endfunction
private constant function numcolor takes nothing returns string
return "|cff0000ff"
endfunction
private function player_charset takes nothing returns string
return "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
endfunction
private function player_charsetlen takes nothing returns integer
return StringLength(player_charset())
endfunction
private function charset takes nothing returns string
return "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
endfunction
private function charsetlen takes nothing returns integer
return StringLength(charset())
endfunction
private function BASE takes nothing returns integer
return charsetlen()
endfunction
private constant function HASHN takes nothing returns integer
return 5000 //1./HASHN() is the probability of a random code being valid
endfunction
private constant function MAXINT takes nothing returns integer
return 2147483647
endfunction
private function player_chartoi takes string c returns integer
local integer i = 0
local string cs = player_charset()
local integer len = player_charsetlen()
loop
exitwhen i>=len or c == SubString(cs,i,i+1)
set i = i + 1
endloop
return i
endfunction
private function chartoi takes string c returns integer
local integer i = 0
local string cs = charset()
local integer len = charsetlen()
loop
exitwhen i>=len or c == SubString(cs,i,i+1)
set i = i + 1
endloop
return i
endfunction
private function itochar takes integer i returns string
return SubString(charset(),i,i+1)
endfunction
//You probably want to use a different char set for this
//Also, use a hash that doesn't suck so much
private function scommhash takes string s returns integer
local integer array count
local integer i = 0
local integer len = StringLength(s)
local integer x
set s = StringCase(s,true)
loop
exitwhen i >= len
set x = player_chartoi(SubString(s,i,i+1))
set count[x] = count[x] + 1
set i = i + 1
endloop
set i = 0
set len = player_charsetlen()
set x = 0
loop
exitwhen i>= len
set x = count[i]*count[i]*i+count[i]*x+x+199
// call BJDebugMsg(I2S(x)+" "+I2S(count[i]))
// call TriggerSleepAction(0.)
set i = i + 1
endloop
if x < 0 then
set x = -x
endif
return x
endfunction
private function modb takes integer x returns integer
if x >= BASE() then
return x - BASE()
elseif x < 0 then
return x + BASE()
else
return x
endif
endfunction
struct Savecode
real digits //logarithmic approximation
BigNum bignum
static method create takes nothing returns Savecode
local Savecode sc = Savecode.allocate()
set sc.digits = 0.
set sc.bignum = BigNum.create(BASE())
return sc
endmethod
method onDestroy takes nothing returns nothing
call .bignum.destroy()
endmethod
method Encode takes integer val, integer max returns nothing
set .digits = .digits + log(max+1,BASE())
call .bignum.MulSmall(max+1)
call .bignum.AddSmall(val)
endmethod
method Decode takes integer max returns integer
return .bignum.DivSmall(max+1)
endmethod
method IsEmpty takes nothing returns boolean
return .bignum.IsZero()
endmethod
method Length takes nothing returns real
return .digits
endmethod
method Clean takes nothing returns nothing
call .bignum.Clean()
endmethod
//These functions get too intimate with BigNum_l
method Pad takes nothing returns nothing
local BigNum_l cur = .bignum.list
local BigNum_l prev
local integer maxlen = R2I(1.0 + .Length())
loop
exitwhen cur == 0
set prev = cur
set cur = cur.next
set maxlen = maxlen - 1
endloop
loop
exitwhen maxlen <= 0
set prev.next = BigNum_l.create()
set prev = prev.next
set maxlen = maxlen - 1
endloop
endmethod
method ToString takes nothing returns string
local BigNum_l cur = .bignum.list
local string s = ""
loop
exitwhen cur == 0
set s = itochar(cur.leaf) + s
set cur = cur.next
endloop
return s
endmethod
method FromString takes string s returns nothing
local integer i = StringLength(s)-1
local BigNum_l cur = BigNum_l.create()
set .bignum.list = cur
loop
set cur.leaf = chartoi(SubString(s,i,i+1))
exitwhen i <= 0
set cur.next = BigNum_l.create()
set cur = cur.next
set i = i - 1
endloop
endmethod
method Hash takes nothing returns integer
local integer hash = 0
local integer x
local BigNum_l cur = .bignum.list
loop
exitwhen cur == 0
set x = cur.leaf
set hash = ModuloInteger(hash+79*hash/(x+1) + 293*x/(1+hash - (hash/BASE())*BASE()) + 479,HASHN())
set cur = cur.next
endloop
return hash
endmethod
//this is not cryptographic which is fine for this application
//sign = 1 is forward
//sign = -1 is backward
method Obfuscate takes integer key, integer sign returns nothing
local integer seed = GetRandomInt(0,MAXINT())
local integer advance
local integer x
local BigNum_l cur = .bignum.list
if sign == -1 then
call SetRandomSeed(.bignum.LastDigit())
set cur.leaf = modb(cur.leaf + sign*GetRandomInt(0,BASE()-1))
set x = cur.leaf
endif
call SetRandomSeed(key)
loop
exitwhen cur == 0
if sign == -1 then
set advance = cur.leaf
endif
set cur.leaf = modb(cur.leaf + sign*GetRandomInt(0,BASE()-1))
if sign == 1 then
set advance = cur.leaf
endif
set advance = advance + GetRandomInt(0,BASE()-1)
call SetRandomSeed(advance)
set x = cur.leaf
set cur = cur.next
endloop
if sign == 1 then
call SetRandomSeed(x)
set .bignum.list.leaf = modb(.bignum.list.leaf + sign*GetRandomInt(0,BASE()-1))
endif
call SetRandomSeed(seed)
endmethod
method Dump takes nothing returns nothing
local BigNum_l cur = .bignum.list
local string s = ""
set s = "max: "+R2S(.digits)
loop
exitwhen cur == 0
set s = I2S(cur.leaf)+" "+s
set cur = cur.next
endloop
call BJDebugMsg(s)
endmethod
method Save takes player p, integer loadtype returns string
local integer key = scommhash(GetPlayerName(p))+loadtype*73
local string s
local integer hash
call .Clean()
set hash = .Hash()
call .Encode(hash,HASHN())
call .Clean()
/////////////////////// Save code information. Comment out next two lines in implementation
//call BJDebugMsg("Expected length: " +I2S(R2I(1.0+.Length())))
//call BJDebugMsg("Room left in last char: "+R2S(1.-ModuloReal((.Length()),1)))
///////////////////////
call .Pad()
call .Obfuscate(key,1)
return .ToString()
endmethod
method Load takes player p, string s, integer loadtype returns boolean
local integer ikey = scommhash(GetPlayerName(p))+loadtype*73
local integer inputhash
call .FromString(s)
call .Obfuscate(ikey,-1)
set inputhash = .Decode(HASHN())
call .Clean()
return inputhash == .Hash()
endmethod
endstruct
private function isupper takes string c returns boolean
return c == StringCase(c,true)
endfunction
private function ischar takes string c returns boolean
return S2I(c) == 0 and c!= "0"
endfunction
private function chartype takes string c returns integer
if(ischar(c)) then
if isupper(c) then
return 0
else
return 1
endif
else
return 2
endif
endfunction
private function testchar takes string c returns nothing
if(ischar(c)) then
if isupper(c) then
call BJDebugMsg(c+" isupper")
else
call BJDebugMsg(c+" islower")
endif
else
call BJDebugMsg(c+ " isnumber")
endif
endfunction
public function colorize takes string s returns string
local string out = ""
local integer i = 0
local integer len = StringLength(s)
local integer ctype
local string c
loop
exitwhen i >= len
set c = SubString(s,i,i+1)
set ctype = chartype(c)
if ctype == 0 then
set out = out + uppercolor()+c+"|r"
elseif ctype == 1 then
set out = out + lowercolor()+c+"|r"
else
set out = out + numcolor()+c+"|r"
endif
set i = i + 1
endloop
return out
endfunction
/*
private function prop_Savecode takes nothing returns boolean
local string s
local Savecode loadcode
//--- Data you want to save ---
local integer medal1 = 10
local integer medal2 = 3
local integer medalmax = 13
local integer XP = 1337
local integer XPmax = 1000000
local Savecode savecode = Savecode.create()
call SetPlayerName(Player(0),"yomp")
call SetPlayerName(Player(1),"fruitcup")
call savecode.Encode(medal1,medalmax)
call savecode.Encode(medal2,medalmax)
call savecode.Encode(XP,XPmax)
//--- Savecode_save generates the savecode for a specific player ---
set s = savecode.Save(Player(0),1)
call savecode.destroy()
// call BJDebugMsg("Savecode: " + Savecode_colorize(s))
//--- User writes down code, inputs again ---
set loadcode = Savecode.create()
if loadcode.Load(Player(0),s,1) then
// call BJDebugMsg("load ok")
else
call BJDebugMsg("load failed")
return false
endif
//Must decode in reverse order of encodes
// load object : max value that data can take
if XP != loadcode.Decode(XPmax) then
return false
elseif medal2 != loadcode.Decode(medalmax) then
return false
elseif medal1 != loadcode.Decode(medalmax) then
return false
endif
call loadcode.destroy()
return true
endfunction
*/
endlibrary
//===========================================================================
function InitTrig_save_system takes nothing returns nothing
endfunction
library BigNum
//prefer algebraic approach because of real subtraction issues
function log takes real y, real base returns real
local real x
local real factor = 1.0
local real logy = 0.0
local real sign = 1.0
if(y < 0.) then
return 0.0
endif
if(y < 1.) then
set y = 1.0/y
set sign = -1.0
endif
//Chop out powers of the base
loop
exitwhen y < 1.0001 //decrease this ( bounded below by 1) to improve precision
if(y > base) then
set y = y / base
set logy = logy + factor
else
set base = SquareRoot(base) //If you use just one base a lot, precompute its squareroots
set factor = factor / 2.
endif
endloop
return sign*logy
endfunction
struct BigNum_l
integer leaf
BigNum_l next
debug static integer nalloc = 0
static method create takes nothing returns BigNum_l
local BigNum_l bl = BigNum_l.allocate()
set bl.next = 0
set bl.leaf = 0
debug set BigNum_l.nalloc = BigNum_l.nalloc + 1
return bl
endmethod
method onDestroy takes nothing returns nothing
debug set BigNum_l.nalloc = BigNum_l.nalloc - 1
endmethod
//true: want destroy
method Clean takes nothing returns boolean
if .next == 0 and .leaf == 0 then
return true
elseif .next != 0 and .next.Clean() then
call .next.destroy()
set .next = 0
return .leaf == 0
else
return false
endif
endmethod
method DivSmall takes integer base, integer denom returns integer
local integer quotient
local integer remainder = 0
local integer num
if .next != 0 then
set remainder = .next.DivSmall(base,denom)
endif
set num = .leaf + remainder*base
set quotient = num/denom
set remainder = num - quotient*denom
set .leaf = quotient
return remainder
endmethod
endstruct
struct BigNum
BigNum_l list
integer base
static method create takes integer base returns BigNum
local BigNum b = BigNum.allocate()
set b.list = 0
set b.base = base
return b
endmethod
method onDestroy takes nothing returns nothing
local BigNum_l cur = .list
local BigNum_l next
loop
exitwhen cur == 0
set next = cur.next
call cur.destroy()
set cur = next
endloop
endmethod
method IsZero takes nothing returns boolean
local BigNum_l cur = .list
loop
exitwhen cur == 0
if cur.leaf != 0 then
return false
endif
set cur = cur.next
endloop
return true
endmethod
method Dump takes nothing returns nothing
local BigNum_l cur = .list
local string s = ""
loop
exitwhen cur == 0
set s = I2S(cur.leaf)+" "+s
set cur = cur.next
endloop
call BJDebugMsg(s)
endmethod
method Clean takes nothing returns nothing
local BigNum_l cur = .list
call cur.Clean()
endmethod
//fails if bignum is null
//BASE() + carry must be less than MAXINT()
method AddSmall takes integer carry returns nothing
local BigNum_l next
local BigNum_l cur = .list
local integer sum
if cur == 0 then
set cur = BigNum_l.create()
set .list = cur
endif
loop
exitwhen carry == 0
set sum = cur.leaf + carry
set carry = sum / .base
set sum = sum - carry*.base
set cur.leaf = sum
if cur.next == 0 then
set cur.next = BigNum_l.create()
endif
set cur = cur.next
endloop
endmethod
//x*BASE() must be less than MAXINT()
method MulSmall takes integer x returns nothing
local BigNum_l cur = .list
local integer product
local integer remainder
local integer carry = 0
loop
exitwhen cur == 0 and carry == 0
set product = x * cur.leaf + carry
set carry = product/.base
set remainder = product - carry*.base
set cur.leaf = remainder
if cur.next == 0 and carry != 0 then
set cur.next = BigNum_l.create()
endif
set cur = cur.next
endloop
endmethod
//Returns remainder
method DivSmall takes integer denom returns integer
return .list.DivSmall(.base,denom)
endmethod
method LastDigit takes nothing returns integer
local BigNum_l cur = .list
local BigNum_l next
loop
set next = cur.next
exitwhen next == 0
set cur = next
endloop
return cur.leaf
endmethod
endstruct
private function prop_Allocator1 takes nothing returns boolean
local BigNum b1
local BigNum b2
set b1 = BigNum.create(37)
call b1.destroy()
set b2 = BigNum.create(37)
call b2.destroy()
return b1 == b2
endfunction
private function prop_Allocator2 takes nothing returns boolean
local BigNum b1
local boolean b = false
set b1 = BigNum.create(37)
call b1.AddSmall(17)
call b1.MulSmall(19)
debug if BigNum_l.nalloc < 1 then
debug return false
debug endif
call b1.destroy()
debug set b = BigNum_l.nalloc == 0
return b
endfunction
private function prop_Arith takes nothing returns boolean
local BigNum b1
set b1 = BigNum.create(37)
call b1.AddSmall(73)
call b1.MulSmall(39)
call b1.AddSmall(17)
//n = 2864
if b1.DivSmall(100) != 64 then
return false
elseif b1.DivSmall(7) != 0 then
return false
elseif b1.IsZero() then
return false
elseif b1.DivSmall(3) != 1 then
return false
elseif b1.DivSmall(3) != 1 then
return false
elseif not b1.IsZero() then
return false
endif
return true
endfunction
endlibrary
//===========================================================================
function InitTrig_bignum_lib takes nothing returns nothing
endfunction
library CharacterManager initializer init uses Sync, GameConstants, ClassSelection, PlayerInit
globals
integer SavingPlayerID = -1
boolean PrintSaveMessage = false
private boolean DebugMode = false
private integer DebugStart = 9
private integer DebugEnd = 12
public integer SKILL_PER_PLAYER
public integer array CODE_BLOCK_COUNT
public integer array DATA_COUNT
public string GameMode = ""
public boolean array SaveMode
public boolean array ErrorNotified
public boolean array SaveEnabled
public boolean array DataVersionRestricted
public string array RestrictReason
public integer GameModeCode = 0
public integer array LoadedData
public integer array SaveSlot
public integer array MaxValue[100][1000]
public integer array SaveDataBlock[100][1000]
public string array ButtonTitle[4][MAX_SAVE_SLOT]
public boolean array IsEmpty[4][MAX_SAVE_SLOT]
public button array ManagerButton[4][25]
public dialog array ManagerDialog
public dialog LoadingDialog
private player TempPlayer = null
private integer TempInt = 0
private string TempStr = ""
private integer LoadVersion
private integer LoadCodeIndex
private integer EncodeValue
private integer EncodeIndex
private integer DecodeVersion
private integer DecodeIndex
private integer SyncID
private boolean CodeValid
private string array Code
private string CompiledCode
endglobals
function GetStringLine takes string source, integer whichLine returns string
local integer length = StringLength(source)
local integer i = 0
local integer currentline = 0
local string currentlinestr=""
loop
exitwhen i > length
if (SubString(source, i, i+2) == "|n") then
set currentline=currentline+1
if (currentline==whichLine) then
return currentlinestr
else
set currentlinestr = ""
set i = i + 1
endif
else
set currentlinestr = currentlinestr + SubString(source, i, i+1)
endif
set i = i + 1
endloop
return currentlinestr
endfunction
public function EncodeNewThread takes nothing returns nothing
call Savecode(SaveDataBlock[SAVE_DATA_VERSION][EncodeIndex]).Encode(EncodeValue, MaxValue[SAVE_DATA_VERSION][EncodeIndex])
endfunction
private function EncodeEx takes integer val returns nothing
set EncodeIndex = EncodeIndex + 1
if EncodeIndex > 0 and SaveDataBlock[SAVE_DATA_VERSION][EncodeIndex] > SaveDataBlock[SAVE_DATA_VERSION][EncodeIndex-1] then
set Code[SaveDataBlock[SAVE_DATA_VERSION][EncodeIndex-1]-1] = Savecode(SaveDataBlock[SAVE_DATA_VERSION][EncodeIndex-1]).Save(TempPlayer, 1)
call Savecode(SaveDataBlock[SAVE_DATA_VERSION][EncodeIndex-1]).destroy()
endif
if val > MaxValue[SAVE_DATA_VERSION][EncodeIndex] then
set val = MaxValue[SAVE_DATA_VERSION][EncodeIndex]
elseif val < 0 then
set val = 0
endif
set EncodeValue = val
call ForForce(bj_FORCE_PLAYER[0], function EncodeNewThread)
if DebugMode and SaveDataBlock[SAVE_DATA_VERSION][EncodeIndex] >= DebugStart and SaveDataBlock[SAVE_DATA_VERSION][EncodeIndex] <= DebugEnd then
call BJDebugMsg("[version " + I2S(SAVE_DATA_VERSION) + "] encode " + I2S(EncodeIndex) + ": " + I2S(val) + "/" + I2S(MaxValue[SAVE_DATA_VERSION][EncodeIndex]))
endif
endfunction
private function SaveGeneralData takes nothing returns nothing
local integer gold1
local integer gold2
local integer id = GetPlayerId(TempPlayer)
local integer uid = GetTypeIndex(GetUnitTypeId(MainUnit[id]))
// General data
set EncodeIndex = -1
call EncodeEx(SAVE_DATA_VERSION) // Save data version
call EncodeEx(GameModeCode) // Game mode code
call EncodeEx(uid) // Unit type
call EncodeEx(Level[id]) // Level
call EncodeEx(R2I((EXPCurrent[id]/EXPTarget[id])*10000.)) // EXP pctg
call EncodeEx(AttributePoint[id]) // Attribute pts
call EncodeEx(SkillPoint[id]) // Skill pts
call EncodeEx(Fame[id]) // Fame
call EncodeEx(0) // Pvp kills
call EncodeEx(0) // Monster kills
call EncodeEx(0) // Play time
call EncodeEx(Strength[id]) // Str
call EncodeEx(Dexterity[id]) // Dex
call EncodeEx(Wisdom[id]) // Wis
call EncodeEx(Fortitude[id]) // For
set gold1 = GetPlayerState(TempPlayer, PLAYER_STATE_RESOURCE_GOLD)
set gold2 = R2I(gold1/10000.)
call EncodeEx(gold2) // Gold pt 1
call EncodeEx(gold1-gold2*10000) // Gold pt 2
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "General data saved.")
endif
endfunction
private function SaveInventoryData takes nothing returns nothing
local ItemObject obj
local integer id = GetPlayerId(TempPlayer)
local integer i
// Inventory data
set i = 0
loop
exitwhen i == 20
set obj = Inventory_SlotIndex[Bag[id]][i].object
call EncodeEx(obj.id-GetItemCategoryIndex(obj.id.category)) // Inventory id
set i = i + 1
endloop
set i = 0
loop
exitwhen i == 20
set obj = Inventory_SlotIndex[Bag[id]][i].object
call EncodeEx(obj.charge) // Inventory charge
set i = i + 1
endloop
set i = 0
loop
exitwhen i == 20
set obj = Inventory_SlotIndex[Bag[id]][i].object
call EncodeEx(obj.quality) // Inventory quality
set i = i + 1
endloop
set i = 0
loop
exitwhen i == 20
set obj = Inventory_SlotIndex[Bag[id]][i].object
call EncodeEx(obj.socketCountMax) // Inventory socket count max
set i = i + 1
endloop
set i = 0
loop
exitwhen i == 20
set obj = Inventory_SlotIndex[Bag[id]][i].object
call EncodeEx(R2I(obj.gold/1000.)) // Inventory gold pt 1
set i = i + 1
endloop
set i = 0
loop
exitwhen i == 20
set obj = Inventory_SlotIndex[Bag[id]][i].object
call EncodeEx(obj.gold-R2I(obj.gold/1000.)*1000) // Inventory gold pt 2
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Inventory data saved.")
endif
endfunction
private function SaveEquipmentData takes nothing returns nothing
local ItemObject obj
local integer id = GetPlayerId(TempPlayer)
local integer i
// Equipment data
set i = 0
loop
exitwhen i == 10
set obj = CharacterWindow_SlotObject[id][i+1]
call EncodeEx(obj.id-GetItemCategoryIndex(obj.id.category)) // Equip id
set i = i + 1
endloop
set i = 0
loop
exitwhen i == 10
set obj = CharacterWindow_SlotObject[id][i+1]
call EncodeEx(obj.quality) // Equip quality
set i = i + 1
endloop
set i = 0
loop
exitwhen i == 10
set obj = CharacterWindow_SlotObject[id][i+1]
call EncodeEx(obj.socketCountMax) // Equip socket count max
set i = i + 1
endloop
set i = 0
loop
exitwhen i == 10
set obj = CharacterWindow_SlotObject[id][i+1]
call EncodeEx(R2I(obj.gold/1000.)) // Equip gold pt 1
set i = i + 1
endloop
set i = 0
loop
exitwhen i == 10
set obj = CharacterWindow_SlotObject[id][i+1]
call EncodeEx(obj.gold-R2I(obj.gold/1000.)*1000) // Equip gold pt 2
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Equipment data saved.")
endif
endfunction
private function SaveShortcutData takes nothing returns nothing
local integer data
local integer id = GetPlayerId(TempPlayer)
local integer i
// Shortcut bar data
set i = 0
loop
exitwhen i == 10
set data = GetUnitUserData(ShortcutBar_Button[id][i].dummy)
call EncodeEx(ShortcutBar_ButtonType[data]) // Shortcut type
set i = i + 1
endloop
set i = 0
loop
exitwhen i == 10
set data = GetUnitUserData(ShortcutBar_Button[id][i].dummy)
call EncodeEx(ShortcutBar_ButtonSkill[data]) // Shortcut skill
set i = i + 1
endloop
set i = 0
loop
exitwhen i == 10
set data = GetUnitUserData(ShortcutBar_Button[id][i].dummy)
call EncodeEx(ShortcutBar_ButtonTarget[data]) // Shortcut target
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Shortcut bar data saved.")
endif
endfunction
private function SaveSkillLevel takes nothing returns nothing
local integer id = GetPlayerId(TempPlayer)
local SkillRow node
local PlayerSkill skill
local integer i
local integer j
set i = 0
set j = 0
loop
exitwhen i == 3
set node = CharacterWindow_SkillRows[id][i].first
loop
exitwhen node == 0
set skill = node.skill
call EncodeEx(skill.level) // Skill level
set node = node.next
set j = j + 1
endloop
set i = i + 1
endloop
loop
exitwhen j == SKILL_PER_PLAYER
call EncodeEx(0) // Skill level (unlearned)
set j = j + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Skill data saved.")
endif
endfunction
private function SaveSkillMasteryLeft takes nothing returns nothing
local integer id = GetPlayerId(TempPlayer)
local SkillRow node
local PlayerSkill skill
local integer i
local integer j
set i = 0
set j = 0
loop
exitwhen i == 3
set node = CharacterWindow_SkillRows[id][i].first
loop
exitwhen node == 0
//call BJDebugMsg("saved " + node.id.name + " level: " + I2S(LoadedData[217+j]) + " mastery: " + R2S(node.skill.mastery) + " index: " + I2S(j))
set skill = node.skill
call EncodeEx(R2I(skill.mastery)) // Skill mastery left
set node = node.next
set j = j + 1
endloop
set i = i + 1
endloop
loop
exitwhen j == SKILL_PER_PLAYER
call EncodeEx(0) // Skill mastery (unlearned)
set j = j + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Skill mastery 1 saved.")
endif
endfunction
private function SaveSkillMasteryRight takes nothing returns nothing
local integer id = GetPlayerId(TempPlayer)
local SkillRow node
local PlayerSkill skill
local integer i
local integer j
local integer mastery
set i = 0
set j = 0
loop
exitwhen i == 3
set node = CharacterWindow_SkillRows[id][i].first
loop
exitwhen node == 0
set skill = node.skill
set mastery = R2I((skill.mastery - I2R(R2I(skill.mastery)))*10000.+0.0005)
call EncodeEx(mastery) // Skill mastery right
set node = node.next
set j = j + 1
endloop
set i = i + 1
endloop
loop
exitwhen j == SKILL_PER_PLAYER
call EncodeEx(0) // Skill mastery (unlearned)
set j = j + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Skill mastery 2 saved.")
endif
endfunction
private function SaveInventoryItemSocket takes nothing returns nothing
local ItemObject obj
local ItemSocket iSocket
local integer id = GetPlayerId(TempPlayer)
local integer i = 0
local integer j
loop
exitwhen i == 20
set obj = Inventory_SlotIndex[Bag[id]][i].object
set j = 0
if obj > 0 then
set iSocket = obj.socketData.first
loop
exitwhen iSocket == 0
call EncodeEx(iSocket.gem.id) // Inventory item socket
set iSocket = iSocket.next
set j = j + 1
endloop
endif
loop
exitwhen j == 4
call EncodeEx(0) // Inventory item socket (empty)
set j = j + 1
endloop
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Inventory socket data saved.")
endif
endfunction
private function SaveEquipmentItemSocket takes nothing returns nothing
local ItemObject obj
local ItemSocket iSocket
local integer id = GetPlayerId(TempPlayer)
local integer i = 0
local integer j
loop
exitwhen i == 10
set obj = CharacterWindow_SlotObject[id][i+1]
set j = 0
if obj > 0 then
set iSocket = obj.socketData.first
loop
exitwhen iSocket == 0
call EncodeEx(iSocket.gem.id) // Equipment item socket
set iSocket = iSocket.next
set j = j + 1
endloop
endif
loop
exitwhen j == 4
call EncodeEx(0) // Equipment item socket (empty)
set j = j + 1
endloop
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Equipment socket data saved.")
endif
endfunction
private function SaveInventoryItemLevel takes nothing returns nothing
local ItemObject obj
local integer id = GetPlayerId(TempPlayer)
local integer i
set i = 0
loop
exitwhen i == 20
set obj = Inventory_SlotIndex[Bag[id]][i].object
call EncodeEx(obj.reqLevel) // Inventory level
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Inventory item level data saved.")
endif
endfunction
private function SaveEquipmentItemLevel takes nothing returns nothing
local ItemObject obj
local integer id = GetPlayerId(TempPlayer)
local integer i
set i = 0
loop
exitwhen i == 10
set obj = CharacterWindow_SlotObject[id][i+1]
call EncodeEx(obj.reqLevel) // Equip level
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Equipment item level data saved.")
endif
endfunction
private function SaveInventoryItemRarity takes nothing returns nothing
local ItemObject obj
local integer id = GetPlayerId(TempPlayer)
local integer i
set i = 0
loop
exitwhen i == 20
set obj = Inventory_SlotIndex[Bag[id]][i].object
call EncodeEx(obj.rarity) // Inventory rarity
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Inventory item rarity data saved.")
endif
endfunction
private function SaveEquipmentItemRarity takes nothing returns nothing
local ItemObject obj
local integer id = GetPlayerId(TempPlayer)
local integer i
set i = 0
loop
exitwhen i == 10
set obj = CharacterWindow_SlotObject[id][i+1]
call EncodeEx(obj.rarity) // Equip rarity
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Equipment item rarity data saved.")
endif
endfunction
private function SavePetData takes nothing returns nothing
local integer id = GetPlayerId(TempPlayer)
local integer uid = GetPetIndex(GetUnitTypeId(Pet[id]))
call EncodeEx(uid) // Pet type
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Pet data saved.")
endif
endfunction
private function SaveInventoryCategory takes nothing returns nothing
local ItemObject obj
local integer id = GetPlayerId(TempPlayer)
local integer i
set i = 0
loop
exitwhen i == 20
set obj = Inventory_SlotIndex[Bag[id]][i].object
call EncodeEx(obj.id.category) // Inventory Category
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Inventory item category data saved.")
endif
endfunction
private function SaveEquipmentCategory takes nothing returns nothing
local ItemObject obj
local integer id = GetPlayerId(TempPlayer)
local integer i
set i = 0
loop
exitwhen i == 10
set obj = CharacterWindow_SlotObject[id][i+1]
call EncodeEx(obj.id.category) // Equipment Category
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Equipment item category data saved.")
endif
endfunction
private function SaveInventoryUpgradeOre takes nothing returns nothing
local ItemObject obj
local ItemUpgrade iUpgrade
local integer id = GetPlayerId(TempPlayer)
local integer i = 0
local integer j
loop
exitwhen i == 20
set obj = Inventory_SlotIndex[Bag[id]][i].object
set j = 0
if obj > 0 then
set iUpgrade = obj.upgradeData.first
loop
exitwhen iUpgrade == 0
//call BJDebugMsg("[" + I2S(i) + "] Save (" + I2S(iUpgrade) + "->" + I2S(iUpgrade.next) + "): " + iUpgrade.ore.name)
call EncodeEx(iUpgrade.ore) // Inventory upgrade ore
set iUpgrade = iUpgrade.next
set j = j + 1
endloop
endif
loop
exitwhen j == UPGRADE_MAX_LEVEL
call EncodeEx(0) // Inventory upgrade ore (empty)
set j = j + 1
endloop
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Inventory upgrade ore data saved.")
endif
endfunction
private function SaveEquipmentUpgradeOre takes nothing returns nothing
local ItemObject obj
local ItemUpgrade iUpgrade
local integer id = GetPlayerId(TempPlayer)
local integer i = 0
local integer j
loop
exitwhen i == 10
set obj = CharacterWindow_SlotObject[id][i+1]
set j = 0
if obj > 0 then
set iUpgrade = obj.upgradeData.first
loop
exitwhen iUpgrade == 0
call EncodeEx(iUpgrade.ore) // Equipment upgrade ore
set iUpgrade = iUpgrade.next
set j = j + 1
endloop
endif
loop
exitwhen j == UPGRADE_MAX_LEVEL
call EncodeEx(0) // Equipment upgrade ore (empty)
set j = j + 1
endloop
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Equipment upgrade ore data saved.")
endif
endfunction
private function SaveInventoryStatsSet takes nothing returns nothing
local ItemObject obj
local integer id = GetPlayerId(TempPlayer)
local integer i
set i = 0
loop
exitwhen i == 20
set obj = Inventory_SlotIndex[Bag[id]][i].object
call EncodeEx(obj.statsSet) // Inventory Stats Set
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Inventory item status set data saved.")
endif
endfunction
private function SaveEquipmentStatsSet takes nothing returns nothing
local ItemObject obj
local integer id = GetPlayerId(TempPlayer)
local integer i
set i = 0
loop
exitwhen i == 10
set obj = CharacterWindow_SlotObject[id][i+1]
call EncodeEx(obj.statsSet) // Equipment Stats Set
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Equipment item status set data saved.")
endif
endfunction
private function CompileCode takes nothing returns nothing
local integer id = GetPlayerId(TempPlayer)
local integer uid = GetPetIndex(GetUnitTypeId(Pet[id]))
local integer i = 0
set CompiledCode = ""
loop
exitwhen i == CODE_BLOCK_COUNT[SAVE_DATA_VERSION]
set CompiledCode = CompiledCode + Code[i] + "|n"
set i = i + 1
endloop
if PrintSaveMessage then
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 5, "Code is compiled.")
endif
endfunction
public function SaveData takes player p returns nothing
local File f
local integer id = GetPlayerId(p)
local integer i
local string s
if not SaveEnabled[id] then
if PrintSaveMessage then
call DisplayTimedTextToPlayer(p, 0, 0, 5, "|cffff0000Saving is disabled!|r")
endif
return
endif
if SaveSlot[id] < 0 then
set InitPlayerId = id
set SaveMode[id] = true
call ExecuteFunc("CharacterManager_ShowEx")
return
endif
set i = 0
loop
exitwhen i == CODE_BLOCK_COUNT[SAVE_DATA_VERSION]
call Savecode.create()
set i = i + 1
endloop
set TempPlayer = p
call ForForce(bj_FORCE_PLAYER[0], function SaveGeneralData)
call ForForce(bj_FORCE_PLAYER[0], function SaveInventoryData)
call ForForce(bj_FORCE_PLAYER[0], function SaveEquipmentData)
call ForForce(bj_FORCE_PLAYER[0], function SaveShortcutData)
call ForForce(bj_FORCE_PLAYER[0], function SaveSkillLevel)
call ForForce(bj_FORCE_PLAYER[0], function SaveInventoryItemSocket)
call ForForce(bj_FORCE_PLAYER[0], function SaveEquipmentItemSocket)
call ForForce(bj_FORCE_PLAYER[0], function SaveInventoryItemLevel)
call ForForce(bj_FORCE_PLAYER[0], function SaveEquipmentItemLevel)
call ForForce(bj_FORCE_PLAYER[0], function SaveInventoryItemRarity)
call ForForce(bj_FORCE_PLAYER[0], function SaveEquipmentItemRarity)
call ForForce(bj_FORCE_PLAYER[0], function SaveSkillMasteryLeft)
call ForForce(bj_FORCE_PLAYER[0], function SaveSkillMasteryRight)
call ForForce(bj_FORCE_PLAYER[0], function SavePetData)
call ForForce(bj_FORCE_PLAYER[0], function SaveInventoryCategory)
call ForForce(bj_FORCE_PLAYER[0], function SaveEquipmentCategory)
call ForForce(bj_FORCE_PLAYER[0], function SaveInventoryUpgradeOre)
call ForForce(bj_FORCE_PLAYER[0], function SaveEquipmentUpgradeOre)
call ForForce(bj_FORCE_PLAYER[0], function SaveInventoryStatsSet)
call ForForce(bj_FORCE_PLAYER[0], function SaveEquipmentStatsSet)
set Code[CODE_BLOCK_COUNT[SAVE_DATA_VERSION]-1] = Savecode(CODE_BLOCK_COUNT[SAVE_DATA_VERSION]).Save(TempPlayer, 1)
call Savecode(CODE_BLOCK_COUNT[SAVE_DATA_VERSION]).destroy()
call ForForce(bj_FORCE_PLAYER[0], function CompileCode)
if PrintSaveMessage and Locale == p then
call ClearTextMessages()
endif
if Locale == p then
if SaveSlot[id] > -1 then
set f = File.open(MAP_NAME, GetPlayerName(p)+"\\"+GameMode+"\\Slot-"+I2S(SaveSlot[id]), File.Flag.WRITE)
call f.write(CharacterName[id] + "|n" + GetUnitName(MainUnit[id]) + " - Level " + I2S(Level[id]) + "|n" + I2S(GetTypeIndex(GetUnitTypeId(MainUnit[id]))) + "|n" + I2S(GetPetIndex(GetUnitTypeId(Pet[id]))) + "|n" + I2S(SAVE_DATA_VERSION) + "|n" + CompiledCode + "a#s#d")
call f.close()
if PrintSaveMessage then
call DisplayTimedTextToPlayer(p, 0, 0, 5, "Saved.")
endif
endif
endif
set PrintSaveMessage = false
endfunction
private function CreateNewSaveThread takes nothing returns nothing
call SaveData(GetEnumPlayer())
endfunction
function CreateNewSaveThreadEx takes nothing returns nothing
call ForForce(bj_FORCE_PLAYER[SavingPlayerID], function CreateNewSaveThread)
endfunction
private function LoadInventoryData takes nothing returns nothing
local ItemObject obj
local ItemObject gem
local ItemUpgrade upgrade
local integer id = GetPlayerId(TempPlayer)
local integer i
local integer j
// Inventory data
set i = 0
loop
exitwhen i == 20
if LoadedData[17+i] != 0 then
set ItemObject.NoRandom = true
set obj = ItemObject.create(LoadedData[17+i]+GetItemCategoryIndex(LoadedData[488+i]), LoadedData[37+i], LoadedData[57+i], 0, 0)
if obj.id.randomStats then
call obj.setStatsSet(LoadedData[878+i])
endif
call Items_AdjustItemObjectLevel(obj, LoadedData[367+i])
set j = UPGRADE_MAX_LEVEL - 1
loop
exitwhen j < 0
if LoadedData[(518+UPGRADE_MAX_LEVEL*i)+j] > 0 then
call obj.upgrade(LoadedData[(518+UPGRADE_MAX_LEVEL*i)+j])
//call BJDebugMsg("[" + I2S(j) + "] Load " + Items(LoadedData[(518+UPGRADE_MAX_LEVEL*i)+j]).name)
endif
set j = j - 1
endloop
set obj.socketCountMax = LoadedData[77+i]
set j = 0
loop
exitwhen j == 4
if LoadedData[(247+4*i)+j] > 0 then
set gem = ItemObject.create(LoadedData[(247+4*i)+j], 0, 0, 0, 0)
if obj.socket(gem) then
call gem.show(false)
else
call gem.destroy()
endif
endif
set j = j + 1
endloop
set obj.gold = LoadedData[97+i]*1000+LoadedData[117+i]
//set obj.rarity = LoadedData[397+i]
call Bag[id].addItemToSlot(obj, i)
endif
set i = i + 1
endloop
endfunction
private function LoadEquipmentData takes nothing returns nothing
local ItemObject obj
local ItemObject gem
local integer id = GetPlayerId(TempPlayer)
local integer i
local integer j
// Equipment data
set i = 0
loop
exitwhen i == 10
if LoadedData[137+i] != 0 then
set ItemObject.NoRandom = true
set obj = ItemObject.create(LoadedData[137+i]+GetItemCategoryIndex(LoadedData[508+i]), 1, LoadedData[147+i], 0, 0)
if obj.id.randomStats then
call obj.setStatsSet(LoadedData[898+i])
endif
call Items_AdjustItemObjectLevel(obj, LoadedData[387+i])
set j = UPGRADE_MAX_LEVEL - 1
loop
exitwhen j < 0
if LoadedData[(758+UPGRADE_MAX_LEVEL*i)+j] > 0 then
call obj.upgrade(LoadedData[(758+UPGRADE_MAX_LEVEL*i)+j])
endif
set j = j - 1
endloop
set obj.socketCountMax = LoadedData[157+i]
set j = 0
loop
exitwhen j == 4
if LoadedData[(327+4*i)+j] > 0 then
set gem = ItemObject.create(LoadedData[(327+4*i)+j], 0, 0, 0, 0)
if obj.socket(gem) then
call gem.show(false)
else
call gem.destroy()
endif
endif
set j = j + 1
endloop
set obj.gold = LoadedData[167+i]*1000+LoadedData[177+i]
//set obj.rarity = LoadedData[417+i]
call obj.show(false)
call CharacterWindow_AttachEx(id, obj)
call AddAttPoints(id, 0, -obj.strength)
call AddAttPoints(id, 1, -obj.dexterity)
call AddAttPoints(id, 2, -obj.wisdom)
call AddAttPoints(id, 3, -obj.fortitude)
endif
set i = i + 1
endloop
endfunction
private function LoadSkillData takes nothing returns nothing
local SkillRow node
local PlayerSkill skill
local SkillData data
local integer id = GetPlayerId(TempPlayer)
local integer i
local integer j
local integer level
// Skill level data
set i = 0
set j = 0
loop
exitwhen i == 3
set node = CharacterWindow_SkillRows[id][i].first
loop
exitwhen node == 0
//call BJDebugMsg("loading: " + node.id.name)
if LoadedData[217+j] > 0 then
set level = LoadedData[217+j]
loop
exitwhen level == 0
call Learn(id, node.id)
set level = level - 1
endloop
set data = node.id
if data.tier < 6 then
set CharacterWindow_TierLearned[id][data.tier] = true
endif
call node.setMastery(I2R(LoadedData[427+j]) + I2R(LoadedData[427+SKILL_PER_PLAYER+j])*0.0001)
endif
//call BJDebugMsg("loaded " + node.id.name + " level: " + I2S(LoadedData[217+j]) + " mastery: " + R2S(node.skill.mastery) + " index: " + I2S(j))
set node = node.next
set j = j + 1
endloop
set i = i + 1
endloop
call EvaluateSkillList(id)
endfunction
private function LoadShortcutBarData takes nothing returns nothing
local InventoryContent slot
local integer data
local integer id = GetPlayerId(TempPlayer)
local integer i
local integer j
// Shortcut bar data
set i = 0
loop
exitwhen i == 10
if LoadedData[187+i] != 0 then
set data = GetUnitUserData(ShortcutBar_Button[id][i].dummy)
set ShortcutBar_ButtonType[data] = LoadedData[187+i]
if LoadedData[187+i] == 0 then
call ShortcutBar_ChargeText[id][i].show(false)
set ShortcutBar_Button[id][i].texture = 'BSAL'
set ShortcutBar_ButtonType[data] = 0
elseif LoadedData[187+i] == 1 then
call ShortcutBar_ChargeText[id][i].show(false)
set ShortcutBar_ButtonSkill[data] = LoadedData[197+i]
set ShortcutBar_Button[id][i].texture = ShortcutBar_ButtonSkill[data].icon
elseif LoadedData[187+i] == 2 then
set slot = Inventory_SlotIndex[Bag[id]][LoadedData[207+i]]
set ShortcutBar_Button[id][i].texture = slot.object.id.texture
set ShortcutBar_ButtonTarget[data] = LoadedData[207+i]
call ShortcutBar_ChargeText[id][i].show(true)
call ShortcutBar_ChargeText[id][i].setText(I2S(slot.object.charge), FONTSTYLE_FrizQTShaded)
call ShortcutBar_ChargeText[id][i].refresh()
endif
call ShortcutBar_Button[id][i].refresh()
endif
set i = i + 1
endloop
endfunction
private function DecodeNewThreadEx takes nothing returns nothing
set LoadedData[DecodeIndex] = Savecode(SaveDataBlock[DecodeVersion][DecodeIndex]).Decode(MaxValue[DecodeVersion][DecodeIndex])
//call BJDebugMsg("decode " + I2S(DecodeIndex) + " " + I2S(MaxValue[DecodeVersion][DecodeIndex]))
if DebugMode and SaveDataBlock[DecodeVersion][DecodeIndex] >= DebugStart and SaveDataBlock[DecodeVersion][DecodeIndex] <= DebugEnd then
call BJDebugMsg("[version " + I2S(DecodeVersion) + "] decode " + I2S(DecodeIndex) + ": " + I2S(LoadedData[DecodeIndex]) + "/" + I2S(MaxValue[DecodeVersion][DecodeIndex]))
endif
endfunction
private function LoadCodeNewThread2 takes nothing returns nothing
set CodeValid = Savecode(LoadCodeIndex).Load(TempPlayer, Code[LoadCodeIndex], 1)
endfunction
private function LoadCodeNewThread takes nothing returns nothing
local integer i = CODE_BLOCK_COUNT[DecodeVersion]
local integer j
loop
exitwhen i == 0
set LoadCodeIndex = i
call ForForce(bj_FORCE_PLAYER[0], function LoadCodeNewThread2)
if CodeValid then
loop
exitwhen SaveDataBlock[DecodeVersion][DecodeIndex] < i
call ForForce(bj_FORCE_PLAYER[0], function DecodeNewThreadEx)
set DecodeIndex = DecodeIndex - 1
endloop
call Savecode(i).destroy()
else
call DisplayTimedTextToPlayer(TempPlayer, 0, 0, 10, "Unable to load (block " + I2S(i) + ") :: Save data is corrupted.")
set SaveSlot[GetPlayerId(TempPlayer)] = -1
return
endif
set i = i - 1
endloop
endfunction
private function OnLoad takes nothing returns boolean
local SkillRow node
local PlayerSkill skill
local InventoryContent slot
local ItemObject obj
local ItemObject gem
local Combatant c
local SyncData d = GetSyncedData()
local player p = d.from
local boolean wantSave = false
local boolean failed = false
local integer id = GetPlayerId(p)
local string name
local integer data
local integer i
local integer j
local unit u
local real cool
local real factor
//call BJDebugMsg("Sync completed!")
set i = 0
loop
exitwhen i > 3
call DialogDisplay(Player(i), LoadingDialog, false)
set i = i + 1
endloop
set TempPlayer = p
set name = d.readString(0)
set CodeValid = true
set DecodeVersion = LoadVersion
set DecodeIndex = DATA_COUNT[DecodeVersion] - 1
call ForForce(bj_FORCE_PLAYER[0], function LoadCodeNewThread)
call d.destroy()
if not CodeValid then
call ClassSelection_UI_LoadControl[id].show(true)
call ClassSelection_UI_LoadEntry[id].show(true)
call ClassSelection_UI_LoadControl[id].refresh()
call ClassSelection_UI_LoadEntry[id].refresh()
call EnableTrigger(ClassSelection_NameInputTrigger[id])
call DisplayTimedTextToPlayer(p, 0, 0, 10, "Unable to load :: invalid code.")
return false
endif
if LoadVersion == LoadedData[0] then
if not DataVersionRestricted[LoadVersion] then
if LoadedData[1] >= GameModeCode then
set IsDataLoading = true
if LoadVersion < SAVE_DATA_VERSION then
set wantSave = true
call DisplayTimedTextToPlayer(p, 0, 0, 10, "|cff00ff00Save data has been ported successfully from version " + I2S(LoadVersion) + " to version " + I2S(SAVE_DATA_VERSION) + "!|r")
elseif LoadVersion > SAVE_DATA_VERSION then
call DisplayTimedTextToPlayer(p, 0, 0, 10, "Unable to load :: data was saved on higher map version.")
set SaveSlot[id] = -1
return false
endif
set CharacterName[id] = name
set u = CreateUnit(p, GetIndexType(LoadedData[2]), 0, 0, 0)
set Pet[id] = CreateUnit(p, GetPetType(LoadedData[487]), 0, 0, 0)
call InitPlayer(u)
set Level[id] = LoadedData[3]
call AdjustCreepStrength(PetFighter[id], Level[id])
call CharacterWindow_UpdateLevel(id, Level[id])
set EXPTarget[id] = EXP_BASE
set i = 1
loop
exitwhen i == Level[id]
set factor = CalculateStatusBaseFactor(I2R(i), 100.)
set Fighter[id].hpMax = Fighter[id].hpMax + HPGrowth[id]*factor
set Fighter[id].spMax = Fighter[id].spMax + MPGrowth[id]*factor
set EXPTarget[id] = (EXPTarget[id]/EXP_GROWTH+EXP_GROWTH_CONST)*EXP_GROWTH
set i = i + 1
endloop
set EXPCurrent[id] = EXPTarget[id]*(LoadedData[4]/10000.)
call XPBar_Update(id)
call AddAttributePoint(id, LoadedData[5]-AttributePoint[id])
call AddSkillPoint(id, LoadedData[6]-SkillPoint[id])
set Fame[id] = LoadedData[7]
call AddAttPoints(id, 0, 999)
call AddAttPoints(id, 1, 999)
call AddAttPoints(id, 2, 999)
call AddAttPoints(id, 3, 999)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, (LoadedData[15]*10000)+LoadedData[16])
call ForForce(bj_FORCE_PLAYER[0], function LoadEquipmentData)
call ForForce(bj_FORCE_PLAYER[0], function LoadInventoryData)
call ForForce(bj_FORCE_PLAYER[0], function LoadSkillData)
call ForForce(bj_FORCE_PLAYER[0], function LoadShortcutBarData)
call AddAttPoints(id, 0, LoadedData[11]-Strength[id])
call AddAttPoints(id, 1, LoadedData[12]-Dexterity[id])
call AddAttPoints(id, 2, LoadedData[13]-Wisdom[id])
call AddAttPoints(id, 3, LoadedData[14]-Fortitude[id])
set c = Combatant[u]
set c.hp = c.hpMax
set c.sp = c.spMax
set SavingPlayerID = id
call ForForce(bj_FORCE_PLAYER[SavingPlayerID], function CreateNewSaveThread)
set IsDataLoading = false
call DisplayTimedTextToPlayer(Locale, 0, 0, 10., GetPlayerName(p) + " loaded a level " + I2S(Level[id]) + " " + GetUnitName(u) + ".")
else
set failed = true
call DisplayTimedTextToPlayer(p, 0, 0, 10, "Unable to load :: can't load singleplayer data in multiplayer mode.")
set SaveSlot[id] = -1
endif
else
set failed = true
call DisplayTimedTextToPlayer(p, 0, 0, 10, "Unable to load :: save data version is restricted. (Reason: " + RestrictReason[LoadVersion] +")")
set SaveSlot[id] = -1
endif
else
set failed = true
call DisplayTimedTextToPlayer(p, 0, 0, 10, "Unable to load :: the file has been externally modified.")
set SaveSlot[id] = -1
endif
if failed then
call ClassSelection_UI_LoadControl[id].show(true)
call ClassSelection_UI_LoadEntry[id].show(true)
call ClassSelection_UI_LoadControl[id].refresh()
call ClassSelection_UI_LoadEntry[id].refresh()
call EnableTrigger(ClassSelection_NameInputTrigger[id])
endif
if wantSave then
call ForForce(bj_FORCE_PLAYER[id], function CreateNewSaveThread)
endif
return false
endfunction
public function SyncError takes nothing returns boolean
local SyncData d = GetSyncedData()
local integer i
local integer id = GetPlayerId(d.from)
call DisplayTimedTextToPlayer(d.from, 0, 0, 5, "|cffff0000Sync data failure occured. Please try again.|r")
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] then
call DialogDisplay(Player(i), LoadingDialog, false)
endif
set i = i + 1
endloop
call ClassSelection_UI_LoadControl[id].show(true)
call ClassSelection_UI_LoadEntry[id].show(true)
call ClassSelection_UI_LoadControl[id].refresh()
call ClassSelection_UI_LoadEntry[id].refresh()
call EnableTrigger(ClassSelection_NameInputTrigger[id])
return false
endfunction
public function SyncCode takes nothing returns boolean
local SyncData d = GetSyncedData()
local player p = d.from
call Savecode.create()
set Code[TempInt + 1] = d.readString(0)
call d.destroy()
set TempInt = TempInt + 1
call ClearTextMessages()
call BJDebugMsg("Syncing data... (" + I2S(R2I(I2R(TempInt)/I2R(CODE_BLOCK_COUNT[LoadVersion])*100.)) + "%)")
if TempInt < CODE_BLOCK_COUNT[LoadVersion] then
set d = SyncData.create(p)
call d.addString(GetStringLine(TempStr, 6+TempInt), 125)
set d.timeout = SYNC_TIMEOUT
set d.onComplete = Filter(function SyncCode)
set d.onError = Filter(function SyncError)
call d.start()
else
set d = SyncData.create(p)
call d.addString(GetStringLine(TempStr, 1), 13)
set d.timeout = SYNC_TIMEOUT
set d.onComplete = Filter(function OnLoad)
set d.onError = Filter(function SyncError)
call d.start()
endif
return false
endfunction
public function StartSync takes nothing returns nothing
local SyncData d = GetSyncedData()
local player p = d.from
local integer i = 0
call ClearTextMessages()
call BJDebugMsg("Syncing data... (0%)")
set LoadVersion = d.readInt(0)
call d.destroy()
set TempInt = 0
set d = SyncData.create(p)
call d.addString(GetStringLine(TempStr, 6+TempInt), 125)
set d.timeout = SYNC_TIMEOUT
set d.onComplete = Filter(function SyncCode)
set d.onError = Filter(function SyncError)
call d.start()
endfunction
public function LoadData takes player p returns nothing
local integer id = GetPlayerId(p)
local integer i = 0
local integer ver
local File f
local SyncData data
if not SaveEnabled[id] then
return
endif
set TempStr = ""
if Locale == p then
set f = File.open(MAP_NAME, GetPlayerName(p)+"\\"+GameMode+"\\Slot-"+I2S(SaveSlot[id]), File.Flag.READ)
set TempStr = f.read()
call f.close()
endif
set ver = S2I(GetStringLine(TempStr, 5))
call ClearTextMessages()
call BJDebugMsg("Syncing data version...")
set data = SyncData.create(p)
call data.addInt(ver)
set data.timeout = SYNC_TIMEOUT
set data.onComplete = Filter(function StartSync)
set data.onError = Filter(function SyncError)
call data.start()
endfunction
private function DataPopulated takes nothing returns boolean
local SyncData d = GetSyncedData()
local integer id = GetPlayerId(d.from)
local integer i = 0
local string title
loop
exitwhen i == MAX_SAVE_SLOT
set IsEmpty[id][i+1] = d.readBool(i)
if IsEmpty[id][i+1] then
set ButtonTitle[id][i+1] = "|cffcccccc- Empty Slot -|r"
else
set ButtonTitle[id][i+1] = d.readString(i)
endif
set ManagerButton[id][i+1] = DialogAddButton(ManagerDialog[id], "|cffffffff[|cffffcc00" + I2S(i+1) + "|r|cffffffff] " + ButtonTitle[id][i+1] + "|R", 49+i)
set i = i + 1
endloop
if SaveMode[id] then
set ManagerButton[id][MAX_SAVE_SLOT+8] = DialogAddButton(ManagerDialog[id], "|cffffffffCancel|r", 0)
else
set ManagerButton[id][MAX_SAVE_SLOT+1] = DialogAddButton(ManagerDialog[id], "|cffffffffCancel|r", 0)
endif
call DialogDisplay(d.from, ManagerDialog[id], true)
call d.destroy()
return false
endfunction
private function SyncError2 takes nothing returns boolean
local SyncData d = GetSyncedData()
call DisplayTimedTextToPlayer(d.from, 0, 0, 5, "|cffff0000Sync data failure occured. Please try again.|r")
return false
endfunction
private function PopulateData takes integer id returns nothing
local integer i = 0
local player p = Player(id)
local string read
local string title
local File f
local SyncData data = SyncData.create(p)
loop
exitwhen i == MAX_SAVE_SLOT
set title = ""
if Locale == p and SaveEnabled[id] then
set f = File.open(MAP_NAME, GetPlayerName(p)+"\\"+GameMode+"\\Slot-"+I2S(i), File.Flag.READ)
set read = f.read()
set title = GetStringLine(read, 1) + " (" + GetStringLine(read, 2) + ")"
call f.close()
endif
call data.addString(title, 30)
call data.addBool(StringLength(title) < 4)
set i = i + 1
endloop
set data.timeout = SYNC_TIMEOUT
set data.onComplete = Filter(function DataPopulated)
set data.onError = Filter(function SyncError2)
call data.start()
endfunction
public function Show takes integer id returns nothing
if SaveEnabled[id] then
call DialogClear(ManagerDialog[id])
if SaveMode[id] then
call DialogSetMessage(ManagerDialog[id], "|cffffcc00Save Character|r")
else
call DialogSetMessage(ManagerDialog[id], "|cffffcc00Character List|r")
endif
call PopulateData(id)
elseif not ErrorNotified[id] then
set ErrorNotified[id] = true
call DisplayTimedTextToPlayer(Player(id), 0, 0, 30, "|cffff0000Local files are not allowed in your system. Save/load system is disabled. Open Read Me for more informations.|r")
endif
endfunction
public function ShowEx takes nothing returns nothing
call Show(InitPlayerId)
endfunction
private function onClick takes nothing returns boolean
local File f
local button but = GetClickedButton()
local player p = GetTriggerPlayer()
local integer id = GetPlayerId(p)
local integer i = 1
loop
exitwhen i > MAX_SAVE_SLOT
if but == ManagerButton[id][i] then
if IsEmpty[id][i] then
if SaveMode[id] then
set SaveSlot[id] = i-1
call DialogClear(ManagerDialog[id])
call DialogSetMessage(ManagerDialog[id], "|cffffcc00Create new character at slot " + I2S(i) + "?|r")
set ManagerButton[id][MAX_SAVE_SLOT+3] = DialogAddButton(ManagerDialog[id], "|cffffffffYes|r", 0)
set ManagerButton[id][MAX_SAVE_SLOT+2] = DialogAddButton(ManagerDialog[id], "|cffffffffCancel|r", 0)
call DialogDisplay(p, ManagerDialog[id], true)
else
call DialogDisplay(p, ManagerDialog[id], true)
endif
else
if SaveMode[id] then
set SaveSlot[id] = i-1
call DialogClear(ManagerDialog[id])
call DialogSetMessage(ManagerDialog[id], "|cffff0000Overwrite existing character data?|r")
set ManagerButton[id][MAX_SAVE_SLOT+2] = DialogAddButton(ManagerDialog[id], "|cffffffffNo|r", 0)
set ManagerButton[id][MAX_SAVE_SLOT+7] = DialogAddButton(ManagerDialog[id], "|cffffffffYes|r", 0)
call DialogDisplay(p, ManagerDialog[id], true)
else
set SaveSlot[id] = i-1
call DialogClear(ManagerDialog[id])
call DialogSetMessage(ManagerDialog[id], "|cffffcc00" + ButtonTitle[id][i] + "|r")
set ManagerButton[id][MAX_SAVE_SLOT+4] = DialogAddButton(ManagerDialog[id], "|cff00ff00Load|r", 0)
set ManagerButton[id][MAX_SAVE_SLOT+5] = DialogAddButton(ManagerDialog[id], "|cffff0000Delete|r", 0)
set ManagerButton[id][MAX_SAVE_SLOT+2] = DialogAddButton(ManagerDialog[id], "|cffffffffCancel|r", 0)
call DialogDisplay(p, ManagerDialog[id], true)
endif
endif
return false
endif
set i = i + 1
endloop
if but == ManagerButton[id][MAX_SAVE_SLOT+1] then // cancel
/*if Locale == p then
call SelectUnit(gg_unit_nmer_0006, true)
set IntentionalDeselection = false
endif*/
elseif but == ManagerButton[id][MAX_SAVE_SLOT+2] then // no, redisplay dialog
set SaveSlot[id] = -1
call Show(id)
elseif but == ManagerButton[id][MAX_SAVE_SLOT+3] then // yes, close dialog, save data
call SaveData(p)
elseif but == ManagerButton[id][MAX_SAVE_SLOT+4] then // yes, close dialog, load data
call DialogSetMessage(LoadingDialog, "Loading character for\n" + GetPlayerName(p) + " ...\n\nPlease wait...")
set i = 0
loop
exitwhen i > 3
if IsPlaying[i] then
if i != id then
call DialogDisplay(Player(i), ManagerDialog[i], false)
endif
if PlayerCount > 1 then
call DialogDisplay(Player(i), LoadingDialog, true)
endif
endif
set i = i + 1
endloop
if PlayerCount <= 1 then
call DisplayTimedTextToPlayer(p, 0, 0, 0, "Loading...")
endif
call ClassSelection_UI_LoadControl[id].show(false)
call ClassSelection_UI_LoadEntry[id].show(false)
call DisableTrigger(ClassSelection_NameInputTrigger[id])
call LoadData(p)
elseif but == ManagerButton[id][MAX_SAVE_SLOT+5] then // delete confirmation
call DialogClear(ManagerDialog[id])
call DialogSetMessage(ManagerDialog[id], "|cffff0000Delete character data at slot " + I2S(i) + "?|r")
set ManagerButton[id][MAX_SAVE_SLOT+2] = DialogAddButton(ManagerDialog[id], "|cffffffffNo|r", 0)
set ManagerButton[id][MAX_SAVE_SLOT+6] = DialogAddButton(ManagerDialog[id], "|cffffffffYes|r", 0)
call DialogDisplay(p, ManagerDialog[id], true)
elseif but == ManagerButton[id][MAX_SAVE_SLOT+6] then // delete yes
if Locale == p and SaveEnabled[id] then
set f = File.open(MAP_NAME, GetPlayerName(p)+"\\"+GameMode+"\\Slot-"+I2S(SaveSlot[id]), File.Flag.WRITE)
call f.write("")
call f.close()
endif
call ClassSelection_RefreshLoadEntries(id)
set SaveSlot[id] = -1
//call Show(id)
elseif but == ManagerButton[id][MAX_SAVE_SLOT+7] then // yes, overwrite
// Create backup
if Locale == p and SaveEnabled[id] then
set f = File.open(MAP_NAME, GetPlayerName(p)+"\\"+GameMode+"\\Slot-"+I2S(SaveSlot[id]), File.Flag.READ)
set TempStr = f.read()
call f.close()
set f = File.open(MAP_NAME, GetPlayerName(p)+"\\"+GameMode+"\\Slot-"+I2S(SaveSlot[id]) + " (backup)", File.Flag.WRITE)
call f.write(TempStr)
call f.close()
endif
call SaveData(p)
elseif but == ManagerButton[id][MAX_SAVE_SLOT+8] then // dont save, hide dialog
set SaveSlot[id] = -1
endif
set but = null
return false
endfunction
private function onSync takes nothing returns boolean
local SyncData d = GetSyncedData()
local integer id = GetPlayerId(d.from)
set SaveEnabled[id] = d.readBool(0)
call d.destroy()
call ExecuteFunc("CharacterManager_reSync")
return false
endfunction
private function init2 takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
local SyncData data
if IsPlaying[id] then
set data = SyncData.create(Player(id))
call data.addBool(File.enabled)
set data.onComplete = Filter(function onSync)
//call data.addEventListener(Filter(function onSync))
call data.start()
call ReleaseTimer(t)
else
call ExecuteFunc("CharacterManager_reSync")
endif
set t = null
endfunction
public function reSync takes nothing returns nothing
set SyncID = SyncID + 1
if SyncID <= 3 then
call TimerStart(NewTimerEx(SyncID), 0.1, false, function init2)
endif
endfunction
private function SetUnitPositionCatcher takes unit whichUnit, real newX, real newY returns nothing
local integer id
if IsUnitInGroup(whichUnit, MainGroup) then
set id = GetPlayerId(GetOwningPlayer(whichUnit))
call PlayerCamera[id].move(newX, newY, 0)
call PlayerCamera[id].refresh()
if IsKeyVerified[id] and SaveSlot[id] > -1 then
call TimerStart(ReminderTimer[id], 300, false, function PlayerInit_remind)
call ForForce(bj_FORCE_PLAYER[id], function CreateNewSaveThread)
endif
endif
endfunction
hook SetUnitPosition SetUnitPositionCatcher
private function init takes nothing returns nothing
local integer i = 0
local trigger t = CreateTrigger()
set LoadingDialog = DialogCreate()
set SKILL_PER_PLAYER = 30
set CODE_BLOCK_COUNT[0] = 3
set CODE_BLOCK_COUNT[3] = 7
call ForForce(bj_FORCE_PLAYER[0], function sdc.initMaxValuesv3)
call ForForce(bj_FORCE_PLAYER[0], function sdc.initMaxValues2v3)
call ForForce(bj_FORCE_PLAYER[0], function sdc.initBlocksv3)
call ForForce(bj_FORCE_PLAYER[0], function sdc.initBlocks2v3)
set CODE_BLOCK_COUNT[4] = 16
call ForForce(bj_FORCE_PLAYER[0], function sdc.initMaxValuesv4)
call ForForce(bj_FORCE_PLAYER[0], function sdc.initMaxValues2v4)
call ForForce(bj_FORCE_PLAYER[0], function sdc.initBlocksv4)
call ForForce(bj_FORCE_PLAYER[0], function sdc.initBlocks2v4)
// Save data restrictions
set DataVersionRestricted[1] = true
set RestrictReason[1] = "Item database reconstruction (v0.6)"
set DataVersionRestricted[2] = true
set RestrictReason[2] = "System structure modification (v0.7)"
set DataVersionRestricted[3] = true
set RestrictReason[3] = "System structure modification (v1.0)"
set DataVersionRestricted[4] = false
set SyncID = 0
set i = 0
loop
exitwhen i > 3
set SaveSlot[i] = -1
set ManagerDialog[i] = DialogCreate()
call TriggerRegisterDialogEvent(t, ManagerDialog[i])
set i = i + 1
endloop
call TriggerAddCondition(t, Condition(function onClick))
call TimerStart(NewTimerEx(SyncID), 0.1, false, function init2)
endfunction
struct sdc
implement sdcModule
endstruct
endlibrary
module sdcModule
static integer i
static method initBlocksv3 takes nothing returns nothing
set s__sdc_i = 0
loop
exitwhen s__sdc_i > 56
set CharacterManager_SaveDataBlock[3][s__sdc_i] = 1
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 136
set CharacterManager_SaveDataBlock[3][s__sdc_i] = 2
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 206
set CharacterManager_SaveDataBlock[3][s__sdc_i] = 3
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 276
set CharacterManager_SaveDataBlock[3][s__sdc_i] = 4
set s__sdc_i = s__sdc_i + 1
endloop
endmethod
static method initBlocks2v3 takes nothing returns nothing
loop
exitwhen s__sdc_i > 326
set CharacterManager_SaveDataBlock[3][s__sdc_i] = 5
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 366
set CharacterManager_SaveDataBlock[3][s__sdc_i] = 6
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > CharacterManager_DATA_COUNT[3]
set CharacterManager_SaveDataBlock[3][s__sdc_i] = 7
set s__sdc_i = s__sdc_i + 1
endloop
endmethod
static method initMaxValuesv3 takes nothing returns nothing
local integer i
local integer j
set CharacterManager_MaxValue[3][0] = 999 // save data version
set CharacterManager_MaxValue[3][1] = 50 // game mode code
set CharacterManager_MaxValue[3][2] = 50 // unit type
set CharacterManager_MaxValue[3][3] = 500 // level
set CharacterManager_MaxValue[3][4] = 10000 // exp current pctg
set CharacterManager_MaxValue[3][5] = 1000 // attribute pts
set CharacterManager_MaxValue[3][6] = 100 // skill pts
set CharacterManager_MaxValue[3][7] = 10000 // fame
set CharacterManager_MaxValue[3][8] = 10000 // pvp kills
set CharacterManager_MaxValue[3][9] = 10000 // monster kills
set CharacterManager_MaxValue[3][10] = 1000 // play time
set CharacterManager_MaxValue[3][11] = 1000 // str
set CharacterManager_MaxValue[3][12] = 1000 // dex
set CharacterManager_MaxValue[3][13] = 1000 // wis
set CharacterManager_MaxValue[3][14] = 1000 // for
set CharacterManager_MaxValue[3][15] = 10000 // gold pt 1
set CharacterManager_MaxValue[3][16] = 10000 // gold pt 2
set CharacterManager_DATA_COUNT[3] = 17
set i = 0
loop
exitwhen i == 20
set CharacterManager_MaxValue[3][17+i] = 1000 // inventory slot (item id)
set CharacterManager_MaxValue[3][37+i] = 100 // inventory slot (charge)
set CharacterManager_MaxValue[3][57+i] = 5 // inventory slot (quality)
set CharacterManager_MaxValue[3][77+i] = 5 // inventory slot (socket count max)
set CharacterManager_MaxValue[3][97+i] = 1000 // inventory slot (gold pt1)
set CharacterManager_MaxValue[3][117+i] = 1000 // inventory slot (gold pt2)
set CharacterManager_MaxValue[3][367+i] = 500 // inventory slot (level)
set CharacterManager_MaxValue[3][397+i] = 10 // inventory slot (rarity)
set CharacterManager_DATA_COUNT[3] = CharacterManager_DATA_COUNT[3] + 8
set j = 0
loop
exitwhen j == 4
set CharacterManager_MaxValue[3][(247+4*i)+j] = 1000 // inventory item (socket)
set CharacterManager_DATA_COUNT[3] = CharacterManager_DATA_COUNT[3] + 1
set j = j + 1
endloop
set i = i + 1
endloop
endmethod
static method initMaxValues2v3 takes nothing returns nothing
local integer i
local integer j
set i = 0
loop
exitwhen i == 10
set CharacterManager_MaxValue[3][137+i] = 999 // equipment slot (item id)
set CharacterManager_MaxValue[3][147+i] = 10 // equipment slot (quality)
set CharacterManager_MaxValue[3][157+i] = 10 // equipment slot (socket count max)
set CharacterManager_MaxValue[3][167+i] = 999 // equipment slot (gold pt 1)
set CharacterManager_MaxValue[3][177+i] = 999 // equipment slot (gold pt 2)
set CharacterManager_MaxValue[3][387+i] = 500 // equipment slot (level)
set CharacterManager_MaxValue[3][417+i] = 10 // equipment slot (rarity) <============== LAST
set CharacterManager_MaxValue[3][187+i] = 10 // shortcut bar (type)
set CharacterManager_MaxValue[3][197+i] = 150 // shortcut bar (skill)
set CharacterManager_MaxValue[3][207+i] = 50 // shortcut bar (target)
set CharacterManager_DATA_COUNT[3] = CharacterManager_DATA_COUNT[3] + 10
set j = 0
loop
exitwhen j == 4
set CharacterManager_MaxValue[3][(327+4*i)+j] = 1000 // equipment item (socket)
set CharacterManager_DATA_COUNT[3] = CharacterManager_DATA_COUNT[3] + 1
set j = j + 1
endloop
set i = i + 1
endloop
set i = 0
loop
exitwhen i == CharacterManager_SKILL_PER_PLAYER
set CharacterManager_MaxValue[3][217+i] = 10 // skill level
set CharacterManager_DATA_COUNT[3] = CharacterManager_DATA_COUNT[3] + 1
set i = i + 1
endloop
endmethod
static method initBlocksv4 takes nothing returns nothing
set s__sdc_i = 0
loop
exitwhen s__sdc_i > 56
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 1
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 136
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 2
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 206
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 3
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 276
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 4
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 326
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 5
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 366
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 6
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 416
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 7
set s__sdc_i = s__sdc_i + 1
endloop
//call BJDebugMsg("block 1")
endmethod
static method initBlocks2v4 takes nothing returns nothing
loop
exitwhen s__sdc_i > 488
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 8
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 558
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 9
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 618
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 10
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 678
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 11
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 738
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 12
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 798
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 13
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 858
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 14
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > 898
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 15
set s__sdc_i = s__sdc_i + 1
endloop
loop
exitwhen s__sdc_i > CharacterManager_DATA_COUNT[4]
set CharacterManager_SaveDataBlock[4][s__sdc_i] = 16
set s__sdc_i = s__sdc_i + 1
endloop
//call BJDebugMsg("block 2")
endmethod
static method initMaxValuesv4 takes nothing returns nothing
local integer i
local integer j
set CharacterManager_MaxValue[4][0] = 999 // save data version
set CharacterManager_MaxValue[4][1] = 50 // game mode code
set CharacterManager_MaxValue[4][2] = 50 // unit type
set CharacterManager_MaxValue[4][3] = 500 // level
set CharacterManager_MaxValue[4][4] = 10000 // exp current pctg
set CharacterManager_MaxValue[4][5] = 1000 // attribute pts
set CharacterManager_MaxValue[4][6] = 100 // skill pts
set CharacterManager_MaxValue[4][7] = 10000 // fame
set CharacterManager_MaxValue[4][8] = 10000 // pvp kills
set CharacterManager_MaxValue[4][9] = 10000 // monster kills
set CharacterManager_MaxValue[4][10] = 1000 // play time
set CharacterManager_MaxValue[4][11] = 1000 // str
set CharacterManager_MaxValue[4][12] = 1000 // dex
set CharacterManager_MaxValue[4][13] = 1000 // wis
set CharacterManager_MaxValue[4][14] = 1000 // for
set CharacterManager_MaxValue[4][15] = 10000 // gold pt 1
set CharacterManager_MaxValue[4][16] = 10000 // gold pt 2
set CharacterManager_DATA_COUNT[4] = 17
set i = 0
loop
exitwhen i == 20
set CharacterManager_MaxValue[4][17+i] = 1000 // inventory slot (item id)
set CharacterManager_MaxValue[4][37+i] = 300 // inventory slot (charge)
set CharacterManager_MaxValue[4][57+i] = 300 // inventory slot (quality)
set CharacterManager_MaxValue[4][77+i] = 5 // inventory slot (socket count max)
set CharacterManager_MaxValue[4][97+i] = 1000 // inventory slot (gold pt1)
set CharacterManager_MaxValue[4][117+i] = 1000 // inventory slot (gold pt2)
set CharacterManager_MaxValue[4][367+i] = 500 // inventory slot (level)
set CharacterManager_MaxValue[4][397+i] = 10 // inventory slot (rarity)
set CharacterManager_MaxValue[4][488+i] = 15 // inventory slot (item category)
set CharacterManager_MaxValue[4][878+i] = 100 // inventory slot (item stats set)
set CharacterManager_DATA_COUNT[4] = CharacterManager_DATA_COUNT[4] + 10
set j = 0
loop
exitwhen j == 4
set CharacterManager_MaxValue[4][(247+4*i)+j] = 1000 // inventory item (socket)
set CharacterManager_DATA_COUNT[4] = CharacterManager_DATA_COUNT[4] + 1
set j = j + 1
endloop
set j = 0
loop
exitwhen j == UPGRADE_MAX_LEVEL
set CharacterManager_MaxValue[4][(518+UPGRADE_MAX_LEVEL*i)+j] = 1000 // inventory item (upgrade ore)
set CharacterManager_DATA_COUNT[4] = CharacterManager_DATA_COUNT[4] + 1
set j = j + 1
endloop
set i = i + 1
endloop
//call BJDebugMsg("value 1")
endmethod
static method initMaxValues2v4 takes nothing returns nothing
local integer i
local integer j
set i = 0
loop
exitwhen i == 10
set CharacterManager_MaxValue[4][137+i] = 999 // equipment slot (item id)
set CharacterManager_MaxValue[4][147+i] = 10 // equipment slot (quality)
set CharacterManager_MaxValue[4][157+i] = 10 // equipment slot (socket count max)
set CharacterManager_MaxValue[4][167+i] = 999 // equipment slot (gold pt 1)
set CharacterManager_MaxValue[4][177+i] = 999 // equipment slot (gold pt 2)
set CharacterManager_MaxValue[4][387+i] = 500 // equipment slot (level)
set CharacterManager_MaxValue[4][417+i] = 10 // equipment slot (rarity)
set CharacterManager_MaxValue[4][187+i] = 10 // shortcut bar (type)
set CharacterManager_MaxValue[4][197+i] = 150 // shortcut bar (skill)
set CharacterManager_MaxValue[4][207+i] = 50 // shortcut bar (target)
set CharacterManager_MaxValue[4][508+i] = 15 // equipment slot (item category)
set CharacterManager_MaxValue[4][898+i] = 100 // equipment slot (item stats set) <============== LAST
set CharacterManager_DATA_COUNT[4] = CharacterManager_DATA_COUNT[4] + 12
set j = 0
loop
exitwhen j == 4
set CharacterManager_MaxValue[4][(327+4*i)+j] = 1000 // equipment item (socket)
set CharacterManager_DATA_COUNT[4] = CharacterManager_DATA_COUNT[4] + 1
set j = j + 1
endloop
set j = 0
loop
exitwhen j == UPGRADE_MAX_LEVEL
set CharacterManager_MaxValue[4][(758+UPGRADE_MAX_LEVEL*i)+j] = 1000 // equipment item (upgrade ore)
set CharacterManager_DATA_COUNT[4] = CharacterManager_DATA_COUNT[4] + 1
set j = j + 1
endloop
set i = i + 1
endloop
set i = 0
loop
exitwhen i == CharacterManager_SKILL_PER_PLAYER
set CharacterManager_MaxValue[4][217+i] = 20 // skill level
set CharacterManager_MaxValue[4][427+i] = 100 // skill mastery left
set CharacterManager_MaxValue[4][427+CharacterManager_SKILL_PER_PLAYER+i] = 10000 // skill mastery right
set CharacterManager_DATA_COUNT[4] = CharacterManager_DATA_COUNT[4] + 3
set i = i + 1
endloop
set CharacterManager_MaxValue[4][487] = 50 // pet type
set CharacterManager_DATA_COUNT[4] = CharacterManager_DATA_COUNT[4] + 1
//call BJDebugMsg("value 2")
endmethod
endmodule