Name | Type | is_array | initial_value |
DamageBlockingAbility | abilcode | No | |
DamageEvent | real | No | |
DamageEventAmount | real | No | |
DamageEventExplodesUnit | boolean | No | |
DamageEventOverride | boolean | No | |
DamageEventPrevAmt | real | No | |
DamageEventSource | unit | No | |
DamageEventsWasted | integer | No | |
DamageEventTarget | unit | No | |
DamageEventTrigger | trigger | No | |
DamageEventType | integer | No | |
DamageModifierEvent | real | No | |
DamageTypeDOT | integer | No | |
DamageTypeRanged | integer | No | |
DamageTypeSpell | integer | No | |
DmgEvLife | real | No | |
DmgEvN | integer | No | |
DmgEvStack | unit | Yes | |
DmgEvTimer | timer | No | |
DmgTypPrev | integer | No | |
str | string | No | |
TempUnit | unit | No | |
UDex | integer | No | |
UDexGen | integer | No | |
UDexNext | integer | Yes | |
UDexPrev | integer | Yes | |
UDexRecycle | integer | No | |
UDexUnits | unit | Yes | |
UDexWasted | integer | No | |
UnitDamageRegistered | boolean | Yes | |
UnitIndexerEnabled | boolean | No | |
UnitIndexEvent | real | No | |
UnitIndexLock | integer | Yes |
//TESH.scrollpos=24
//TESH.alwaysfold=0
library Ascii /* v1.1.0.0 Nestharus/Bribe
************************************************************************************
*
* 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 integer array h //hash2
private integer array y //hash3
private string array c //char
endglobals
function Char2Ascii takes string p returns integer
local integer z = i[StringHash(p)/0x1F0748+0x40D]
if (c[z] != p) then
if (c[z - 32] != p) then
if (c[h[z]] != p) then
if (c[y[z]] != p) then
if (c[83] != p) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"ASCII ERROR: INVALID CHARACTER: " + p)
return 0
endif
return 83
endif
return y[z]
endif
return h[z]
endif
return z - 32
endif
return z
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 a = a*256 + Char2Ascii(SubString(s,j,j+1))
set j=j+1
endloop
return a
endfunction
private module Init
private static method onInit takes nothing returns nothing
set i[966] = 8
set i[1110] = 9
set i[1621] = 10
set i[1375] = 12
set i[447] = 13
set i[233] = 32
set i[2014] = 33
set i[1348] = 34
set i[1038] = 35
set i[1299] = 36
set i[1018] = 37
set i[1312] = 38
set i[341] = 39
set i[939] = 40
set i[969] = 41
set i[952] = 42
set i[2007] = 43
set i[1415] = 44
set i[2020] = 45
set i[904] = 46
set i[1941] = 47
set i[918] = 48
set i[1593] = 49
set i[719] = 50
set i[617] = 51
set i[703] = 52
set i[573] = 53
set i[707] = 54
set i[1208] = 55
set i[106] = 56
set i[312] = 57
set i[124] = 58
set i[1176] = 59
set i[74] = 60
set i[1206] = 61
set i[86] = 62
set i[340] = 63
set i[35] = 64
set i[257] = 65
set i[213] = 66
set i[271] = 67
set i[219] = 68
set i[1330] = 69
set i[1425] = 70
set i[1311] = 71
set i[238] = 72
set i[1349] = 73
set i[244] = 74
set i[1350] = 75
set i[205] = 76
set i[1392] = 77
set i[1378] = 78
set i[1432] = 79
set i[1455] = 80
set i[1454] = 81
set i[1431] = 82
set i[1409] = 83
set i[1442] = 84
set i[534] = 85
set i[1500] = 86
set i[771] = 87
set i[324] = 88
set i[1021] = 89
set i[73] = 90
set i[1265] = 91
set i[1941] = 92
set i[1671] = 93
set i[1451] = 94
set i[1952] = 95
set i[252] = 96
set i[257] = 97
set i[213] = 98
set i[271] = 99
set i[219] = 100
set i[1330] = 101
set i[1425] = 102
set i[1311] = 103
set i[238] = 104
set i[1349] = 105
set i[244] = 106
set i[1350] = 107
set i[205] = 108
set i[1392] = 109
set i[1378] = 110
set i[1432] = 111
set i[1455] = 112
set i[1454] = 113
set i[1431] = 114
set i[1409] = 115
set i[1442] = 116
set i[534] = 117
set i[1500] = 118
set i[771] = 119
set i[324] = 120
set i[1021] = 121
set i[73] = 122
set i[868] = 123
set i[1254] = 124
set i[588] = 125
set i[93] = 126
set i[316] = 161
set i[779] = 162
set i[725] = 163
set i[287] = 164
set i[212] = 165
set i[7] = 166
set i[29] = 167
set i[1958] = 168
set i[1009] = 169
set i[1580] = 170
set i[1778] = 171
set i[103] = 172
set i[400] = 174
set i[1904] = 175
set i[135] = 176
set i[1283] = 177
set i[469] = 178
set i[363] = 179
set i[550] = 180
set i[1831] = 181
set i[1308] = 182
set i[1234] = 183
set i[1017] = 184
set i[1093] = 185
set i[1577] = 186
set i[606] = 187
set i[1585] = 188
set i[1318] = 189
set i[980] = 190
set i[1699] = 191
set i[1292] = 192
set i[477] = 193
set i[709] = 194
set i[1600] = 195
set i[2092] = 196
set i[50] = 197
set i[546] = 198
set i[408] = 199
set i[853] = 200
set i[205] = 201
set i[411] = 202
set i[1311] = 203
set i[1422] = 204
set i[1808] = 205
set i[457] = 206
set i[1280] = 207
set i[614] = 208
set i[1037] = 209
set i[237] = 210
set i[1409] = 211
set i[1023] = 212
set i[1361] = 213
set i[695] = 214
set i[161] = 215
set i[1645] = 216
set i[1822] = 217
set i[644] = 218
set i[1395] = 219
set i[677] = 220
set i[1677] = 221
set i[881] = 222
set i[861] = 223
set i[1408] = 224
set i[1864] = 225
set i[1467] = 226
set i[1819] = 227
set i[1971] = 228
set i[949] = 229
set i[774] = 230
set i[1828] = 231
set i[865] = 232
set i[699] = 233
set i[786] = 234
set i[1806] = 235
set i[1286] = 236
set i[1128] = 237
set i[1490] = 238
set i[1720] = 239
set i[1817] = 240
set i[729] = 241
set i[1191] = 242
set i[1164] = 243
set i[413] = 244
set i[349] = 245
set i[1409] = 246
set i[660] = 247
set i[2016] = 248
set i[1087] = 249
set i[1497] = 250
set i[753] = 251
set i[1579] = 252
set i[1456] = 253
set i[606] = 254
set i[1625] = 255
set h[92] = 47
set h[201] = 108
set h[201] = 76
set h[203] = 103
set h[203] = 71
set h[246] = 115
set h[246] = 83
set h[246] = 211
set h[254] = 187
set y[201] = 108
set y[203] = 103
set y[246] = 115
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[91]="["
set c[92]="\\"
set c[93]="]"
set c[94]="^"
set c[95]="_"
set c[96]="`"
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[123]="{"
set c[124]="|"
set c[125]="}"
set c[126]="~"
set c[128] = "€"
set c[130] = "‚"
set c[131] = "ƒ"
set c[132] = "„"
set c[133] = "…"
set c[134] = "†"
set c[135] = "‡"
set c[136] = "ˆ"
set c[137] = "‰"
set c[138] = "Š"
set c[139] = "‹"
set c[140] = "Œ"
set c[142] = "Ž"
set c[145] = "‘"
set c[146] = "’"
set c[147] = "“"
set c[148] = "”"
set c[149] = "•"
set c[150] = "–"
set c[151] = "—"
set c[152] = "˜"
set c[153] = "™"
set c[154] = "š"
set c[155] = "›"
set c[156] = "œ"
set c[158] = "ž"
set c[159] = "Ÿ"
set c[160] = " "
set c[161] = "¡"
set c[162] = "¢"
set c[163] = "£"
set c[164] = "¤"
set c[165] = "¥"
set c[166] = "¦"
set c[167] = "§"
set c[168] = "¨"
set c[169] = "©"
set c[170] = "ª"
set c[171] = "«"
set c[172] = "¬"
set c[174] = "®"
set c[175] = "¯"
set c[176] = "°"
set c[177] = "±"
set c[178] = "²"
set c[179] = "³"
set c[180] = "´"
set c[181] = "µ"
set c[182] = "¶"
set c[183] = "·"
set c[184] = "¸"
set c[185] = "¹"
set c[186] = "º"
set c[187] = "»"
set c[188] = "¼"
set c[189] = "½"
set c[190] = "¾"
set c[191] = "¿"
set c[192] = "À"
set c[193] = "Á"
set c[194] = "Â"
set c[195] = "Ã"
set c[196] = "Ä"
set c[197] = "Å"
set c[198] = "Æ"
set c[199] = "Ç"
set c[200] = "È"
set c[201] = "É"
set c[202] = "Ê"
set c[203] = "Ë"
set c[204] = "Ì"
set c[205] = "Í"
set c[206] = "Î"
set c[207] = "Ï"
set c[208] = "Ð"
set c[209] = "Ñ"
set c[210] = "Ò"
set c[211] = "Ó"
set c[212] = "Ô"
set c[213] = "Õ"
set c[214] = "Ö"
set c[215] = "×"
set c[216] = "Ø"
set c[217] = "Ù"
set c[218] = "Ú"
set c[219] = "Û"
set c[220] = "Ü"
set c[221] = "Ý"
set c[222] = "Þ"
set c[223] = "ß"
set c[224] = "à"
set c[225] = "á"
set c[226] = "â"
set c[227] = "ã"
set c[228] = "ä"
set c[229] = "å"
set c[230] = "æ"
set c[231] = "ç"
set c[232] = "è"
set c[233] = "é"
set c[234] = "ê"
set c[235] = "ë"
set c[236] = "ì"
set c[237] = "í"
set c[238] = "î"
set c[239] = "ï"
set c[240] = "ð"
set c[241] = "ñ"
set c[242] = "ò"
set c[243] = "ó"
set c[244] = "ô"
set c[245] = "õ"
set c[246] = "ö"
set c[247] = "÷"
set c[248] = "ø"
set c[249] = "ù"
set c[250] = "ú"
set c[251] = "û"
set c[252] = "ü"
set c[253] = "ý"
set c[254] = "þ"
set c[255] = "ÿ"
endmethod
endmodule
private struct Inits extends array
implement Init
endstruct
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
//**
//* Credits:
//* - Nestharus ( Ascii, ErrorMessage )
//* - Bribe ( Ascii, Table )
//* - Deaod ( original Font )
//**
//* Written by BPower
library Font/*v1.0
*************************************************************************************
*
* Creates custom fonts in Warcraft III.
* Fonts are used to translate strings into a sequence of images.
*
* A custom fonts may contain every character of the Ascii chart,
* as well as file paths to textures inside your map.
*
* Has full backwards compatibility to Deaods Font library.
*
*************************************************************************************
*
* Creating custom fonts:
* ======================
* Refer to wc3c.net/showthread.php?t=87798
* You can change the file paths to your needs, but don't forget to copy
* the width of each individual chars from the .j file that the program creates.
*
*************************************************************************************
*
* */ requires /*
*
* */ Ascii /* hiveworkshop.com/forums/jass-resources-412/snippet-ascii-190746/
* */ Table /* hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
* */ optional ErrorMessage /* github.com/nestharus/JASS/tree/master/jass/Systems/ErrorMessage
*
************************************************************************************
*
* Import instruction:
* ===================
* Copy & paste library Font into your map.
* Make sure your map also has library Table and library Ascii.
* Otherwise copy those two required libraries aswell.
*
* API:
* ====
* struct Font extends array
*
* static method create takes Font parentFont returns Font
* - A parent font is accessed, if a char or file is not available in this font.
*
* method addChar takes string char, real widthInPixel, string filePath returns nothing
* - adds a new char to the font. The char must be part of the Ascii chart.
*
* method getChar takes string char returns FontChar
* - FontChar fields are "width" and "path".
*
* method addImage takes string tag, real widthInPixel, string filePath returns nothing
* - adds an image to the font. Images are fully compatible with parents.
* - to access an image you have to use myFont.getImage(tag)
* - tags are case-insensitive ( myTag is equal to MYtAg )
*
* method getImage takes string tag returns FontImage
* - pass in the tag defined in addImage() to access a FontImage
* - FontImage fields are "width" and "path"
*/
globals
//* Struct font has an instance limit of 31.
//* Only if you need more than 31 fonts in your map set MORE to true.
private constant boolean MORE = false
endglobals
//**
//* Naming convention:
//* ==================
//* Due to backwards compatibility to Deaods Font library
//* I didn't use medial capitalization.
//* Personally I prefer struct names using PascalCase.
private struct fontchar extends array
private static integer alloc = 0
string path
real width
static method create takes string strPath, real strWidth returns thistype
local thistype this = thistype.alloc + 1
set thistype.alloc = integer(this)
set path = strPath
set width = strWidth
return this
endmethod
endstruct
private struct fontimage extends array
private static integer alloc = 0
string path
real width
static method create takes string strPath, real strWidth returns thistype
local thistype this = thistype.alloc + 1
set thistype.alloc = integer(this)
set path = strPath
set width = strWidth
return this
endmethod
endstruct
static if MORE then
private module InitFontTable
private static method onInit takes nothing returns nothing
set thistype.chars = Table.create()
endmethod
endmodule
endif
struct font extends array
private static integer alloc = 0
static if MORE then
private static Table chars
implement optional InitFontTable
else
private static integer array chars//* (this - 1)*256
endif
private thistype parent
private Table imgs
method getChar takes string char returns fontchar
local integer fc = chars[(this - 1)*256 + Char2Ascii(char)]
if (fc != 0) then
return fc
elseif (0 != parent) then
return parent.getChar(char)
endif
static if LIBRARY_ErrorMessage then
debug call ThrowWarning(true, "Font", "getChar", "char", this, "Char [" + char + "] is not available in this font!")
endif
return 0
endmethod
method addChar takes string char, real width, string path returns nothing
local integer index = (this - 1)*256 + Char2Ascii(char)
local fontchar fc = chars[index]
//*
static if LIBRARY_ErrorMessage then
debug call ThrowError((index - ((this - 1)*256) <= 0), "Font", "addChar", "ascii", this, "Char [" + char + "] is not part of the Ascii chart!")
endif
if (fc == 0) then
set chars[index] = fontchar.create(path, width)
else
set fc.path = path
set fc.width = width
endif
endmethod
method getImage takes string file returns fontimage
local integer fi = imgs[StringHash(file)]
if (0 != fi) then
return fi
elseif (0 != parent) then
return parent.getImage(file)
endif
static if LIBRARY_ErrorMessage then
debug call ThrowWarning(true, "Font", "getImage", "file", this, "File [" + file + "] is not available in this font!")
endif
return 0
endmethod
//* To works with both Tables I didn't use t.exists(index) nor t.has(index).
//* Luckily hashtables return 0 for not existant entries.
method addImage takes string file, real width, string path returns nothing
local integer index = StringHash(file)
local fontimage img
if (imgs[index] == 0) then
set imgs[index] = fontimage.create(path, width)
else
set img = imgs[index]
set img.path = path
set img.width = width
endif
endmethod
static method create takes thistype parentFont returns thistype
local thistype this = thistype.alloc + 1
static if LIBRARY_ErrorMessage and not MORE then
debug call ThrowError((this == 32), "Font", "create", "thistype", this, "Overflow. Go to library Font and set boolean MORE to true!")
endif
set thistype.alloc = integer(this)
set parent = parentFont
set imgs = Table.create()
return this
endmethod
//* Backwards compatibility to Deaods Font.
method operator [] takes string char returns fontchar
return getChar(char)
endmethod
endstruct
endlibrary
//TESH.scrollpos=381
//TESH.alwaysfold=0
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
//TESH.scrollpos=-1
//TESH.alwaysfold=0
library ARGB initializer init
//******************************************************************************
//*
//* ARGB 1.1
//* ====
//* For your color needs.
//*
//* An ARGB object is a by-value struct, this means that assigning copies the
//* contents of the struct and that you don't have to use .destroy(), the
//* downside is that you cannot assign its members (can't do set c.r= 123 )
//*
//* This library should have plenty of uses, for example, if your spell involves
//* some unit recoloring you can allow users to input the color in the config
//* section as 0xAARRGGBB and you can then use this to decode that stuff.
//*
//* You can also easily merge two colors and make fading effects using ARGB.mix
//*
//* There's ARGB.fromPlayer which gets an ARGB object containing the player's
//* color. Then you can use the previous utilities on it.
//*
//* The .str() instance method can recolor a string, and the recolorUnit method
//* will apply the ARGB on a unit
//*
//* For other uses, you can use the .red, .green, .blue and .alpha members to get
//* an ARGB object's color value (from 0 to 255).
//*
//* structs that have a recolor method that takes red,green,blue and alpha as 0.255
//* integers can implement the ARGBrecolor module to gain an ability to quickly
//* recolor using an ARGB object.
//*
//********************************************************************************
//=================================================================================
globals
private string array i2cc
endglobals
//this double naming stuff is beginning to make me insane, if only TriggerEvaluate() wasn't so slow...
struct ARGB extends array
static method create takes integer a, integer r, integer g, integer b returns ARGB
return ARGB(b + g*0x100 + r*0x10000 + a*0x1000000)
endmethod
static method fromPlayer takes player p returns ARGB
local playercolor pc=GetPlayerColor(p)
if(pc==PLAYER_COLOR_RED) then
return 0xFFFF0303
elseif(pc==PLAYER_COLOR_BLUE) then
return 0xFF0042FF
elseif(pc==PLAYER_COLOR_CYAN) then
return 0xFF1CB619
elseif(pc==PLAYER_COLOR_PURPLE) then
return 0xFF540081
elseif(pc==PLAYER_COLOR_YELLOW) then
return 0xFFFFFF01
elseif(pc==PLAYER_COLOR_ORANGE) then
return 0xFFFE8A0E
elseif(pc==PLAYER_COLOR_GREEN) then
return 0xFF20C000
elseif(pc==PLAYER_COLOR_PINK) then
return 0xFFE55BB0
elseif(pc==PLAYER_COLOR_LIGHT_GRAY) then
return 0xFF959697
elseif(pc==PLAYER_COLOR_LIGHT_BLUE) then
return 0xFF7EBFF1
elseif(pc==PLAYER_COLOR_AQUA) then
return 0xFF106246
elseif(pc==PLAYER_COLOR_BROWN) then
return 0xFF4E2A04
endif
return 0xFF111111
endmethod
method operator alpha takes nothing returns integer
if( integer(this) <0) then
return 0x80+(-(-integer(this)+0x80000000))/0x1000000
else
return (integer(this))/0x1000000
endif
endmethod
method operator alpha= takes integer na returns ARGB
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
return ARGB(b + g*0x100 + r*0x10000 + na*0x1000000)
endmethod
method operator red takes nothing returns integer
local integer c=integer(this)*0x100
if(c<0) then
return 0x80+(-(-c+0x80000000))/0x1000000
else
return c/0x1000000
endif
endmethod
method operator red= takes integer nr returns ARGB
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
return ARGB(b + g*0x100 + nr*0x10000 + a*0x1000000)
endmethod
method operator green takes nothing returns integer
local integer c=integer(this)*0x10000
if(c<0) then
return 0x80+(-(-c+0x80000000))/0x1000000
else
return c/0x1000000
endif
endmethod
method operator green= takes integer ng returns ARGB
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
return ARGB(b + ng*0x100 + r*0x10000 + a*0x1000000)
endmethod
//=======================================================
//
//
method operator blue takes nothing returns integer
local integer c=integer(this)*0x1000000
if(c<0) then
return 0x80+(-(-c+0x80000000))/0x1000000
else
return c/0x1000000
endif
endmethod
method operator blue= takes integer nb returns ARGB
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
return ARGB(nb + g*0x100 + r*0x10000 + a*0x1000000)
endmethod
//====================================================================
// Mixes two colors, s would be a number 0<=s<=1 that determines
// the weight given to color c2.
//
// mix(c1,c2,0) = c1
// mix(c1,c2,1) = c2
// mix(c1,c2,0.5) = Mixing the colors c1 and c2 in equal proportions.
//
static method mix takes ARGB c1, ARGB c2, real s returns ARGB
//widest function ever
return ARGB( R2I(c2.blue*s+c1.blue*(1-s)+0.5) + R2I(c2.green*s+c1.green*(1-s)+0.5)*0x100 + R2I(c2.red*s+c1.red*(1-s)+0.5)*0x10000 + R2I((c2.alpha*s)+(c1.alpha*(1-s))+0.5)*0x1000000)
endmethod
method str takes string s returns string
return "|c"+i2cc[.alpha]+i2cc[.red]+i2cc[.green]+i2cc[.blue]+s+"|r"
endmethod
method recolorUnit takes unit u returns nothing
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
call SetUnitVertexColor(u,r,g,b,a)
endmethod
endstruct
module ARGBrecolor
method ARGBrecolor takes ARGB color returns nothing
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
call this.recolor(r, g , b, a)
endmethod
endmodule
private function init takes nothing returns nothing
local integer i=0
// Don't run textmacros you don't own!
//! textmacro ARGB_CHAR takes int, chr
set i=0
loop
exitwhen i==16
set i2cc[$int$*16+i]="$chr$"+i2cc[$int$*16+i]
set i2cc[i*16+$int$]=i2cc[i*16+$int$]+"$chr$"
set i=i+1
endloop
//! endtextmacro
//! runtextmacro ARGB_CHAR( "0","0")
//! runtextmacro ARGB_CHAR( "1","1")
//! runtextmacro ARGB_CHAR( "2","2")
//! runtextmacro ARGB_CHAR( "3","3")
//! runtextmacro ARGB_CHAR( "4","4")
//! runtextmacro ARGB_CHAR( "5","5")
//! runtextmacro ARGB_CHAR( "6","6")
//! runtextmacro ARGB_CHAR( "7","7")
//! runtextmacro ARGB_CHAR( "8","8")
//! runtextmacro ARGB_CHAR( "9","9")
//! runtextmacro ARGB_CHAR("10","A")
//! runtextmacro ARGB_CHAR("11","B")
//! runtextmacro ARGB_CHAR("12","C")
//! runtextmacro ARGB_CHAR("13","D")
//! runtextmacro ARGB_CHAR("14","E")
//! runtextmacro ARGB_CHAR("15","F")
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
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
//TESH.scrollpos=447
//TESH.alwaysfold=0
//**
//* Credits:
//* - Vexorian ( ARGB )
//* - Nestharus ( ErrorMessage )
//* - Bribe ( Table )
//* - PitzerMike ( original TextSplat system )
//* - Deaod ( TextSplat system of the second generation )
//**
//* Written by BPower
library TextSplat2 /*v2.0
*************************************************************************************
*
* Creates objects of type "textsplat", which are strings displayed in a sequence of images.
* In API textsplats have a remarkable resemblance to the texttag handle.
* Only the creation of a textsplat requires an extra argument ( a font ).
*
*************************************************************************************
*
* */ requires /*
*
* */ ARGB /* wc3c.net/showthread.php?t=101858
* */ Font /* hiveworkshop.com/forums/submissions-414/textsplat2-273717/
* */ Table /* hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
* */ Queue /* github.com/nestharus/JASS/blob/master/jass/Data%20Structures/Queue/script.j
* */ optional ImageUtils /* wc3c.net/showthread.php?t=107707[/url]
* */ optional ImageTools /* hiveworkshop.com/forums/submissions-414/imagetools-271099/
* */ optional ErrorMessage /* github.com/nestharus/JASS/tree/master/jass/Systems/ErrorMessage
*
************************************************************************************/
//**
//* Import instruction:
//* ===================
//* Copy the TextSplat2, Font and their requirements into your map.
//**
//* API:
//* ====
//* The API is similar to the texttag API with one exception.
//* "CreateTextsplat(font)" expects a font as argument, while CreateTextTag() doesn't require any argument.
//* Below the object orientated API is listed, as it offers some cool feature texttags don't have.
//! novjass ( Disables the compiler until the next endnovjass )
struct textsplat
//**
//* Methods:
//* ========
static method create takes font f returns textsplat
method destroy takes nothing returns nothing
method setText takes string s, real height, integer aligntype returns nothing
//* Available aligntype are TEXTSPLAT_TEXT_ALIGN_LEFT, TEXTSPLAT_TEXT_ALIGN_CENTER and TEXTSPLAT_TEXT_ALIGN_RIGHT
//*
//* Hint: You can bind images into a text ( if added to the font ) by using "|i" as identifier.
//* Example: "The price is 2000 |igold|i"
//* Output: Textsplat will translate "|igold|i" into the gold coin image.
method setVelocity takes real xvel, real yvel, real zvel returns nothing
method setColor takes integer red, integer green, integer blue, integer alpha returns nothing
method setPosition takes real x, real y, real z return nothing
method setPosUnit takes unit u, real z returns nothing
method setSuspended takes boolean flag returns nothing
method setVisible takes boolean flag returns nothing
//**
//* Fields you may manipulate directly:
//* ===================================
font fontType
real age
real lifespan
real fadepoint
boolean permanent
//**
//* Fields you may read:
//* ====================
readonly integer charCount
//* Position values.
readonly real x
readonly real y
readonly real z
//* Velocity values.
readonly real dX
readonly real dY
readonly real dZ
//* Width and height of a text are very useful.
readonly real width
readonly real height
readonly boolean suspended
readonly boolean visible
readonly string text
readonly ARGB color
//! endnovjass
//**
//* User configuration:
//* ===================
globals
//* Set the timer accuracy.
private constant real ACCURACY = 1./32.
//* Set the default color for textsplats. If unsure use 0xFFFFFFFF.
private constant integer DEFAULT_COLOR = 0xFFFFFFFF
//* Set the default image type for textsplats.
private constant integer DEFAULT_IMAGE_TYPE = IMAGE_TYPE_SELECTION
//* Set how many chars can be parsed per function evaluation.
//* Use lower values if you use many |cAARRGGBB strings in textsplats. Maximum working value is about 65.
private constant integer TOKENS_PER_CHUNK = 40
//**
//* Globals you can read:
//* =====================
//* ( Do not change these global values )
constant integer DEFAULT_IMAGE_SIZE = 32
constant integer TEXTSPLAT_TEXT_ALIGN_LEFT = 0
constant integer TEXTSPLAT_TEXT_ALIGN_CENTER = 1
constant integer TEXTSPLAT_TEXT_ALIGN_RIGHT = 2
constant real TEXT_SIZE_TO_IMAGE_SIZE = 4.146479
endglobals
//========================================================================
//* Textsplat2 system code. Make changes carefully.
//========================================================================
//**
//* Terrain offset z:
//* =================
//* Native SetImageConstantHeight() expects an absolute z value.
globals
private constant location LOC = Location(0, 0)
endglobals
private function GetLocZ takes real x, real y returns real
call MoveLocation(LOC, x, y)
return GetLocationZ(LOC)
endfunction
//**
//* Struct Char:
//* ============
//* The data struture is a queue. You can replace the module
//* with any data structure module which supports
//* create(), destroy(), enqueue() and clear()
private struct Char extends array
implement Queue
//* Struct members.
image img
integer imageType
string path
real sizeX
real sizeY
real x
real y
real z
boolean show
boolean colorize//* Non char images are not colorized.
integer alpha
integer red
integer blue
integer green
private method draw takes nothing returns nothing
if (img != null) then
call ReleaseImage(img)
endif
static if LIBRARY_ImageTools then
set img = NewImage(path, sizeX, sizeY, x, y, 0, imageType)
elseif LIBRARY_ImageUtils then
set img = NewImage(path, sizeX, sizeY, 0, x, y, 0, 0, 0, 0, imageType)
endif
call SetImageConstantHeight(img, true, z + GetLocZ(x, y))
call SetImageColor(img, red, green, blue, alpha)
call SetImageRenderAlways(img, show)
endmethod
method setColor takes ARGB value returns nothing
set alpha = value.alpha
set red = value.red
set green = value.green
set blue = value.blue
call SetImageColor(img, red, green, blue, alpha)
endmethod
private method new takes string strPath, real sX, real sY, real posX, real posY, real posZ returns thistype
local ARGB val = DEFAULT_COLOR
set this = enqueue()//* New node.
set path = strPath
set sizeX = sX
set sizeY = sY
set x = posX
set y = posY
set z = posZ
set show = true
set imageType = DEFAULT_IMAGE_TYPE
set alpha = val.alpha
set red = val.red
set green = val.green
set blue = val.blue
call draw()
return this
endmethod
method createChar takes font ft, string symbol, real x, real y, real z, real size returns thistype
return new(ft.getChar(symbol).path, size*TEXT_SIZE_TO_IMAGE_SIZE, size*TEXT_SIZE_TO_IMAGE_SIZE, x, y, z)
endmethod
method createImage takes font ft, string img, real x, real y, real z, real size returns thistype
return new(ft.getImage(img).path, size*TEXT_SIZE_TO_IMAGE_SIZE, size*TEXT_SIZE_TO_IMAGE_SIZE, x, y, z)
endmethod
endstruct
globals
//* Globals to transfer variable values between functions, which use
//* either function.evaluate or ForForce to not hit the OOP limit.
private integer strLength
private integer currentLength
private integer tokenAmount
private real maxLineWidth
private integer currentLine
private boolean defaultColor
private ARGB currentColor
private real sourceX
private real sourceY
//*
private string array textChars
private real array lineWidth
endglobals
//**
//* Hex to Decimal:
//* ===============
globals
private Table Hex2Dec
private Table IsHex
endglobals
private function IsHexadecimal takes integer i returns boolean
local integer l = i + 8
loop
exitwhen (i >= l)
if not IsHex.has(StringHash(textChars[i])) then
return false
endif
set i = i + 1
endloop
return true
endfunction
//**
//* Perpare source string:
//* ======================
private function SplitString takes string text returns nothing
local integer i = 0
loop
exitwhen (i == strLength)
set textChars[i] = SubString(text, i, i + 1)
set i = i + 1
endloop
set textChars[i] = null//* Will indicate the end of the text.
endfunction
//**
//* String parsing:
//* ===============
globals
private constant integer TOKEN_TYPE_INVALID = 0
private constant integer TOKEN_TYPE_NORMAL = 1
private constant integer TOKEN_TYPE_NEWLINE = 2
private constant integer TOKEN_TYPE_COLOR = 3
private constant integer TOKEN_TYPE_COLOREND = 4
private constant integer TOKEN_TYPE_IMAGE = 5
endglobals
private struct TextToken extends array
static thistype current
integer tokenType
string value
ARGB color
boolean isDefaultColor
integer line
real posX
real posY
endstruct
private function TokenizeText takes nothing returns nothing
local integer i = currentLength
local TextToken base = TextToken.current
local TextToken token = base
local string char
loop
exitwhen (integer(token) - integer(base) >= TOKENS_PER_CHUNK) or (i >= strLength)
set char = textChars[i]
//* Check for \n or \r\n or |n
if (char == "\n") or (char == "\r" and textChars[i + 1] == "\n") or (char=="|" and textChars[i + 1]=="n") then
set token.tokenType = TOKEN_TYPE_NEWLINE
if (char != "\n") then
set i = i + 1
endif
//* Check for color start and color code.
elseif (char=="|") and (textChars[i + 1] == "c") and (strLength - i >= 10) and (IsHexadecimal(i + 2)) then
set token.tokenType = TOKEN_TYPE_COLOR
set token.color = ARGB.create(Hex2Dec[StringHash(textChars[i + 2] + textChars[i + 3])], Hex2Dec[StringHash(textChars[i + 4] + textChars[i + 5])], Hex2Dec[StringHash(textChars[i + 6] + textChars[i + 7])], Hex2Dec[StringHash(textChars[i + 8] + textChars[i + 9])])
set i = i + 9
//* Check for color end
elseif (char=="|") and (textChars[i + 1] == "r") then
set token.tokenType = TOKEN_TYPE_COLOREND
set i = i + 1
//* Check for image start, path and end.
elseif (char == "|") and (textChars[i + 1] == "i") then
set token.tokenType = TOKEN_TYPE_IMAGE
set token.value = ""
set i = i + 2
loop
exitwhen (textChars[i] == "|" and textChars[i + 1] == "i") or (i >= strLength)
set token.value = token.value + textChars[i]
set i = i + 1
endloop
set i = i + 1
//* Otherwise it is a normal ascii char.
else
set token.tokenType = TOKEN_TYPE_NORMAL
set token.value = char
endif
set token = token + 1
set i = i + 1
endloop
set TextToken.current = token
set currentLength = i
endfunction
private function LayoutText takes ARGB backgroundColor, font textFont, real lineHeight returns nothing
local TextToken base = TextToken.current
local TextToken token = base
local real width
loop
exitwhen (integer(token) - integer(base) >= TOKENS_PER_CHUNK) or (integer(token) >= tokenAmount)
if (token.tokenType == TOKEN_TYPE_NEWLINE) then
if (lineWidth[currentLine] > maxLineWidth) or (currentLine == 0) then
set maxLineWidth = lineWidth[currentLine]
endif
set currentLine = currentLine + 1
set lineWidth[currentLine] = 0
elseif (token.tokenType == TOKEN_TYPE_COLOR) then
set currentColor = token.color
set defaultColor = false
elseif (token.tokenType == TOKEN_TYPE_COLOREND) then
set currentColor = backgroundColor
set defaultColor = true
elseif (token.tokenType == TOKEN_TYPE_IMAGE) or (token.tokenType == TOKEN_TYPE_NORMAL) then
set token.color = currentColor
set token.isDefaultColor = defaultColor
set token.line = currentLine
if (token.tokenType == TOKEN_TYPE_IMAGE) then
set width = (textFont.getImage(token.value).width*TEXT_SIZE_TO_IMAGE_SIZE*lineHeight/DEFAULT_IMAGE_SIZE)
else
set width = (textFont.getChar(token.value).width*TEXT_SIZE_TO_IMAGE_SIZE*lineHeight/DEFAULT_IMAGE_SIZE)
endif
set token.posY = currentLine*lineHeight*TEXT_SIZE_TO_IMAGE_SIZE
set token.posX = lineWidth[currentLine]
set lineWidth[currentLine] = lineWidth[currentLine] + width
endif
set token = token + 1
endloop
set TextToken.current = token
endfunction
private function DisplayText takes real lineHeight, real bonus, real z, boolean visible, font fontType, Char chars returns nothing
local TextToken token = TextToken.current
local real x
local real y
local Char char
loop
exitwhen (integer(token) - integer(TextToken.current) >= TOKENS_PER_CHUNK) or (integer(token) >= tokenAmount)
if (token.tokenType == TOKEN_TYPE_IMAGE) or (token.tokenType == TOKEN_TYPE_NORMAL) then
set x = sourceX + token.posX + (bonus*(maxLineWidth - lineWidth[token.line]))
set y = sourceY - token.posY
if (token.tokenType == TOKEN_TYPE_IMAGE) then
set char = chars.createImage(fontType, token.value, x, y, z, lineHeight)
else
set char = chars.createChar(fontType, token.value, x, y, z, lineHeight)
endif
set char.colorize = token.isDefaultColor
call char.setColor(token.color)
set char.show = visible
call SetImageRenderAlways(char.img, visible)
set currentLength = currentLength + 1
endif
set token = token + 1
endloop
set TextToken.current = token
endfunction
//**
//* Struct textsplat:
//* =================
struct textsplat
private static constant timer TMR = CreateTimer()
//* Linked list data structure.
private static integer array next
private static integer array prev
private static boolean array inList
//**
//* Members:
//* ========
private Char chars
//* Fields you may read.
readonly integer charCount
readonly real x
readonly real y
readonly real z
readonly real dX
readonly real dY
readonly real dZ
readonly real width
readonly real height
readonly boolean suspended
readonly boolean visible
readonly string text
readonly ARGB color
//* Fields you may manipulate directly.
font fontType
real age
real lifespan
real fadepoint
boolean permanent
private method clear takes nothing returns nothing
local Char char = chars.first
loop
exitwhen (0 == char)
if (char.img != null) then
call ReleaseImage(char.img)
set char.img = null
endif
set char = char.next
endloop
call chars.clear()
endmethod
private method remove takes nothing returns nothing
if (inList[this]) then
set inList[this] = false
set next[prev[this]] = next[this]
set prev[next[this]] = prev[this]
if (0 == next[0]) then
call PauseTimer(TMR)
endif
endif
endmethod
method destroy takes nothing returns nothing
call clear()
call chars.destroy()
call remove()
call deallocate()
endmethod
private static method onPeriodic takes nothing returns nothing
local thistype this = next[0]
local Char char
local boolean hasZ
local real val
loop
exitwhen (0 == this)
set char = chars.first
//* Update position.
set x = x + dX
set y = y + dY
set z = z + dZ
set hasZ = (0. != dZ)
//* Update alpha channel.
set val = 1.
if not (permanent) then
set age = age + ACCURACY
if (age >= lifespan) then
call destroy()
set char = 0//* Does not enter the loop.
elseif (age > fadepoint) then
set val = 1. - (age - fadepoint)/(lifespan - fadepoint)
endif
endif
loop
exitwhen (0 == char)
set char.x = char.x + dX
set char.y = char.y + dY
//* Unlike units, image handles may move out of WorldBounds without producing issues.
call SetImagePosition(char.img, char.x, char.y, 0.)
if (hasZ) then
set char.z = char.z + dZ
call SetImageConstantHeight(char.img, true, char.z + GetLocZ(char.x, char.y))
endif
call SetImageColor(char.img, char.red, char.green, char.blue, R2I(char.alpha*val))
set char = char.next
endloop
set this = next[this]
endloop
endmethod
private method enqueue takes nothing returns nothing
if not (inList[this]) then
set inList[this] = true
set next[this] = 0
set prev[this] = prev[0]
set next[prev[0]] = this
set prev[0] = this
if (0 == prev[this]) then
call TimerStart(TMR, ACCURACY, true, function thistype.onPeriodic)
endif
endif
endmethod
method setText takes string s, real h, integer aligntype returns nothing
set strLength = StringLength(s)
set currentLine = 0
set currentColor = color
set defaultColor = true
set maxLineWidth = 0
call clear()//* First clean the previous text.
call SplitString(s)//* Split string into single chars.
//* Tokenize.
set lineWidth[0] = 0
set currentLength = 0
set TextToken.current = 0
loop
exitwhen (currentLength >= strLength)
call ForForce(bj_FORCE_PLAYER[0], function TokenizeText)
endloop
//* Layout.
set tokenAmount = TextToken.current
set TextToken.current = 0
loop
exitwhen integer(TextToken.current) >= tokenAmount
call LayoutText.evaluate(color, fontType, h)
endloop
if (currentLine == 0) or (lineWidth[currentLine] > maxLineWidth) then
set maxLineWidth = lineWidth[currentLine]
endif
//* Display.
set sourceX = x
set sourceY = y + currentLine*h*TEXT_SIZE_TO_IMAGE_SIZE
set currentLength = 0
set TextToken.current = 0
loop
exitwhen integer(TextToken.current) >= tokenAmount
call DisplayText.evaluate(h, aligntype*.5, z, visible, fontType, chars)
endloop
set charCount = currentLength
set text = s
set width = maxLineWidth
set height = (currentLine + 1)*h*TEXT_SIZE_TO_IMAGE_SIZE
endmethod
method setVelocity takes real xvel, real yvel, real zvel returns nothing
set dX = xvel*ACCURACY
set dY = yvel*ACCURACY
set dZ = zvel*ACCURACY
endmethod
method setColor takes integer red, integer green, integer blue, integer alpha returns nothing
local Char char = chars.first
local integer val = alpha
if (age > fadepoint) and (lifespan != fadepoint) and not (permanent) then
set val = R2I((1 - (age - fadepoint)/(lifespan - fadepoint))*alpha)
endif
set color = ARGB.create(alpha, red, green, blue)
loop
exitwhen (0 == char)
if (char.colorize) then
set char.red = red
set char.green = green
set char.blue = blue
set char.alpha = alpha
call SetImageColor(char.img, red, green, blue, val)
endif
set char = char.next
endloop
endmethod
method setPosition takes real posX, real posY, real posZ returns nothing
local real newX = posX - x
local real newY = posY - y
local real newZ = posZ - z
local Char char = chars.first
loop
exitwhen (0 == char)
set char.x = char.x + newX
set char.y = char.y + newY
set char.z = char.z + newZ
call SetImagePosition(char.img, char.x, char.y, 0)
call SetImageConstantHeight(char.img, true, char.z + GetLocZ(char.x, char.y))
set char = char.next
endloop
set x = posX
set y = posY
set z = posZ
endmethod
method setPosUnit takes unit u, real z returns nothing
call setPosition(GetUnitX(u), GetUnitY(u), z)
endmethod
method setSuspended takes boolean flag returns nothing
set suspended = flag
if (flag) then
call remove()
else
call enqueue()
endif
endmethod
method setVisible takes boolean flag returns nothing
local Char char = chars.first
set visible = flag
loop
exitwhen (0 == char)
set char.show = flag
call SetImageRenderAlways(char.img, flag)
set char = char.next
endloop
endmethod
static method create takes font f returns thistype
local thistype this = thistype.allocate()
set fontType = f
set color = DEFAULT_COLOR
set visible = true
set permanent = true
set suspended = false
set chars = Char.create()//* Queue.
//* Reset position and fading members.
set dX = 0.
set dY = 0.
set dZ = 0.
set x = 0.
set y = 0.
set z = 0.
set age = 0.
set fadepoint = 0.
set lifespan = 0.
set width = 0.
set height = 0.
//* Add to iterating textsplats.
call enqueue()
return this
endmethod
endstruct
function CreateTextSplat takes font fontType returns textsplat
return textsplat.create(fontType)
endfunction
function DestroyTextSplat takes textsplat t returns nothing
call t.destroy()
endfunction
function SetTextSplatFont takes textsplat t, font new returns nothing
set t.fontType = new
endfunction
function SetTextSplatAge takes textsplat t, real value returns nothing
set t.age = value
endfunction
function SetTextSplatColor takes textsplat t, integer red, integer green, integer blue, integer alpha returns nothing
call t.setColor(red, green, blue, alpha)
endfunction
function SetTextSplatFadepoint takes textsplat t, real value returns nothing
set t.fadepoint = value
endfunction
function SetTextSplatLifespan takes textsplat t, real value returns nothing
set t.lifespan = value
endfunction
function SetTextSplatPermanent takes textsplat t, boolean flag returns nothing
set t.permanent = flag
endfunction
function SetTextSplatPos takes textsplat t, real x, real y, real heightOffset returns nothing
call t.setPosition(x, y, heightOffset)
endfunction
function SetTextSplatPosUnit takes textsplat t, unit whichUnit, real heightOffset returns nothing
call t.setPosUnit(whichUnit, heightOffset)
endfunction
function SetTextSplatSuspended takes textsplat t, boolean flag returns nothing
call t.setSuspended(flag)
endfunction
function SetTextSplatText takes textsplat t, string s, real height returns nothing
call t.setText(s, height, TEXTSPLAT_TEXT_ALIGN_CENTER)
endfunction
function SetTextSplatVelocity takes textsplat t, real xvel, real yvel returns nothing
call t.setVelocity(xvel, yvel, 0)
endfunction
function SetTextSplatVisibility takes textsplat t, boolean flag returns nothing
call t.setVisible(flag)
endfunction
//**
//* Hex to Dec:
//* ===========
//! textmacro Hex2DecUpper_Macro takes L
set Hex2Dec[StringHash("$L$0")]=0x$L$0
set Hex2Dec[StringHash("$L$1")]=0x$L$1
set Hex2Dec[StringHash("$L$2")]=0x$L$2
set Hex2Dec[StringHash("$L$3")]=0x$L$3
set Hex2Dec[StringHash("$L$4")]=0x$L$4
set Hex2Dec[StringHash("$L$5")]=0x$L$5
set Hex2Dec[StringHash("$L$6")]=0x$L$6
set Hex2Dec[StringHash("$L$7")]=0x$L$7
set Hex2Dec[StringHash("$L$8")]=0x$L$8
set Hex2Dec[StringHash("$L$9")]=0x$L$9
set Hex2Dec[StringHash("$L$A")]=0x$L$A
set Hex2Dec[StringHash("$L$B")]=0x$L$B
set Hex2Dec[StringHash("$L$C")]=0x$L$C
set Hex2Dec[StringHash("$L$D")]=0x$L$D
set Hex2Dec[StringHash("$L$E")]=0x$L$E
set Hex2Dec[StringHash("$L$F")]=0x$L$F
//! endtextmacro
private module InitHex2Dec
private static method onInit takes nothing returns nothing
set Hex2Dec = Table.create()
set IsHex = Table.create()
//! runtextmacro Hex2DecUpper_Macro("0")
//! runtextmacro Hex2DecUpper_Macro("1")
//! runtextmacro Hex2DecUpper_Macro("2")
//! runtextmacro Hex2DecUpper_Macro("3")
//! runtextmacro Hex2DecUpper_Macro("4")
//! runtextmacro Hex2DecUpper_Macro("5")
//! runtextmacro Hex2DecUpper_Macro("6")
//! runtextmacro Hex2DecUpper_Macro("7")
//! runtextmacro Hex2DecUpper_Macro("8")
//! runtextmacro Hex2DecUpper_Macro("9")
//! runtextmacro Hex2DecUpper_Macro("A")
//! runtextmacro Hex2DecUpper_Macro("B")
//! runtextmacro Hex2DecUpper_Macro("C")
//! runtextmacro Hex2DecUpper_Macro("D")
//! runtextmacro Hex2DecUpper_Macro("E")
//! runtextmacro Hex2DecUpper_Macro("F")
set IsHex[StringHash("0")]=1
set IsHex[StringHash("1")]=1
set IsHex[StringHash("2")]=1
set IsHex[StringHash("3")]=1
set IsHex[StringHash("4")]=1
set IsHex[StringHash("5")]=1
set IsHex[StringHash("6")]=1
set IsHex[StringHash("7")]=1
set IsHex[StringHash("8")]=1
set IsHex[StringHash("9")]=1
set IsHex[StringHash("A")]=1
set IsHex[StringHash("B")]=1
set IsHex[StringHash("C")]=1
set IsHex[StringHash("D")]=1
set IsHex[StringHash("E")]=1
set IsHex[StringHash("F")]=1
endmethod
endmodule
private struct Inits extends array
implement InitHex2Dec
endstruct
endlibrary
library_once TextSplat uses TextSplat2
endlibrary
//TESH.scrollpos=57
//TESH.alwaysfold=0
// Written by BPower.
library ImageTools /*v2.0
*************************************************************************************
*
* For your image needs.
*
* Strictly speaking it provides two wrapper function for CreateImage & DestroyImage,
* named function NewImage & function ReleaseImage.
*
* You always want to use these wrapper functions! Why so? See required know-how.
*
*************************************************************************************
*
* Required know-how [ Image extends handles for Dummies ]:
* -----------------
*
* 1. An invalid filepath crashes the game.
* 2. An invalid image type crashes the game.
* 3. DestroyImage native on an invalid image handle crashes the game.
*
* ImageTools prevents you from these fatal errors
* plus prints out debug messages, so you can quickly fix your code.
*
* Hint: A very nice image tutorial link - [url]http://www.wc3c.net/showthread.php?t=107737[/url]
*
*************************************************************************************
*
* To Deaod
* -----------------------
*
* For the original ImageUtils library ( [url]http://www.wc3c.net/showthread.php?t=107707[/url] )
*
* To Bribe
* -----------------------
*
* For Table
*
* To Vexorian
* -----------------------
*
* For ARGB
*
*************************************************************************************
*
* */ uses /*
*
* */ Table /* [url]http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/[/url]
*
************************************************************************************
*
* 1. Import instruction
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Copy the ImageTools script and library Table into your map.
* 2. API
* ¯¯¯¯¯¯
* function NewImage takes string file, real sizeX, real sizeY, real posX, real posY, real posZ, integer imageType returns image
* - Wrapper to the CreateImage native.
* - Does not crash the game, if the created image handle is invalid.
*
* function ReleaseImage takes image whichImage retuns nothing
* - Wrapper to the DestroyImage native
* - Does not crash the game if whichImage is invalid.
* - Does not crash the game if whichImage is the first ever created image in the map.
*
* function CreateImageCenter takes string file, real sizeX, real sizeY, real centerX, real centerY, real posZ, integer imageType returns image
* - Wrapper to the NewImage. It creates the image centered at centerX, centerY equal to other handle objects ( i.e. units ).
*
* 3. Configuration
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* You don't have to setup anything.
*/
globals
/**
* The following are valid image types
* sorted from highest to lowest layer:
*/
constant integer IMAGE_TYPE_SELECTION = 1// above all other image types.
constant integer IMAGE_TYPE_OCCLUSION_MASK = 3// above image type 2 and 4
constant integer IMAGE_TYPE_INDICATOR = 2// above image type 4
constant integer IMAGE_TYPE_UBERSPLAT = 4// lowest layer. Tinting affected by time of day
// and is drawn below fog of war.
/**
* Those two are image types options in GUI's "Image - Create" wrapper of CreateImageBJ.
* Both are invalid image types and should not be used in any case.
* While an image with IMAGE_TYPE_SHADOW instantly crashes the game,
* an image using IMAGE_TYPE_TOPMOST will simply not be render-able.
* The game season however will continue normally.
*/
constant integer IMAGE_TYPE_SHADOW = 0// Will create an invalid image handle with an handle id of -1.
constant integer IMAGE_TYPE_TOPMOST = 5// Will create an invalid image handle, which can't be rendered.
/**
* If an image handle is invalid, it gets the handle id -1.
* Once you are using this handle somewhere, Warcraft III crashes,
* hence ALWAYS create an image handle via function NewImage.
*/
private constant integer INVALID_IMAGE_ID = -1
/**
* When using ARGB, this is the default color set on Image.create()
*/
endglobals
static if DEBUG_MODE then
private function DebugMsg takes string s returns nothing
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "|cffff0000IMAGE UTILS ERROR:|r\n " + "|cff99b4d1" + "[" + s + "]|r" )
endfunction
endif
globals
private Table table = 0
endglobals
function NewImage takes string file, real sizeX, real sizeY, real posX, real posY, real posZ, integer imageType returns image
local image i = CreateImage(file, sizeX, sizeY, 0, posX, posY, posZ, 0, 0, 0, imageType)
if (0 > GetHandleId(i)) then
debug if (imageType < IMAGE_TYPE_SELECTION) or (imageType > IMAGE_TYPE_UBERSPLAT) then
debug call DebugMsg("function NewImage: Invalid image type [" + I2S(imageType) + "] for: " + file)
debug else
debug call DebugMsg("function NewImage: Can't find string path in data: " + file)
debug endif
return null
else
set table.boolean[GetHandleId(i)] = true
return i
endif
endfunction
function ReleaseImage takes image i returns nothing
local integer id = GetHandleId(i)
if (id > 0) and (table.boolean.has(id)) then
call table.boolean.remove(id)
call DestroyImage(i)
debug elseif (id > 0) then
debug call DebugMsg("function ReleaseImage: Attempt to double destroy an image handle: [" + I2S(id) + "]!" )
debug call DebugMsg("function ReleaseImage: Or even worse, you created an image without using NewImage!" )
debug else
debug call DebugMsg("function ReleaseImage: Attempt to destroy an invalid image handle! ( null )")
endif
endfunction
function CreateImageCenter takes string file, real sizeX, real sizeY, real centerX, real centerY, real centerZ, integer imageType returns image
return NewImage(file, sizeX, sizeY, centerX - sizeX*.5, centerY - sizeY*.5, centerZ, imageType)
endfunction
private module InitImageTools
private static method onInit takes nothing returns nothing
set table = Table.create()
endmethod
endmodule
private struct I extends array
implement InitImageTools
endstruct
//! runtextmacro optional IMAGE_TOOLS_IMPORT_STRUCT_CODE()
endlibrary
//TESH.scrollpos=24
//TESH.alwaysfold=0
library ErrorMessage /* v1.0.2.0
*************************************************************************************
*
* Issue Compliant Error Messages
*
************************************************************************************
*
* 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
*
* function ThrowWarning takes boolean expression, string libraryName, string functionName, string objectName, integer objectInstance, string description returns nothing
*
************************************************************************************/
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
endlibrary
//TESH.scrollpos=45
//TESH.alwaysfold=0
library ArcingTextSplat uses TextSplat2//* v1.2.1
//**
//* Performance:
//* ============
//* The creation of textsplat objects is a bit expensive, hence
//* ArcingTextSplat is slower than the similar library Arcing Floating Text,
//* which uses the texttag handle. Use ArcingTextSplat only if:
//* - Your map hits the maximum texttag count of 100.
//* - You want to bind in images into the text ( |ipath|i ).
//* - You have a liking for the image handle.
//**
//* Import instruction:
//* ===================
//* Copy ArcingTextSplat, TextSplat2, Font and their requirements into your map.
//* Install a custom font of your choice. For more information look into library Font.
//**
//* API:
//* ====
//! novjass
function CreateArcingTextSplat takes string s, real x, real y returns nothing
function CreateArcingTextSplatForForce takes string s, real x, real y, force forForce returns nothing
//* For local traffic code. Is only displayed for force "forForce".
//! endnovjass
//**
//* User settings:
//* ==============
globals
private constant real TEXTSIZE = 8 //* Set the size of the text.
private constant real TIME_LIFE = 1.0 //* Set how long the text lasts.
private constant real TIME_FADE = 0.5 //* Set when the text starts to fade.
private constant real Z_OFFSET = 50 //* Set the height above the unit.
private constant real Z_OFFSET_BON = 70 //* Set how much extra height the text gains.
private constant real VELOCITY = 2 //* Set how fast the text move in x/y plane.
private constant real FIX_ANGLE = bj_PI/2 //* Set the movement angle of the text. Does not apply if ANGLE_RND is true.
private constant boolean ANGLE_RND = true //* Set if the angle random or fixed.
endglobals
//========================================================================
//* Arcing TextSplat system code. Make changes carefully.
//========================================================================
globals
private constant timer TMR = CreateTimer()
//* Indexing.
private integer max = 0
//* Array.
private textsplat array splat
endglobals
private function OnPeriodic takes nothing returns nothing
local integer dex = 0
local textsplat t
loop
exitwhen (dex == max)
set t = splat[dex]
if (t.lifespan - t.age > 0.) then
call t.setPosition(t.x, t.y, Z_OFFSET + Z_OFFSET_BON*Sin(bj_PI*(t.lifespan - t.age)))
else
set max = max - 1
set splat[dex] = splat[max]
set dex = dex - 1
if (0 == max) then
call PauseTimer(TMR)
endif
endif
set dex = dex + 1
endloop
endfunction
function CreateArcingTextSplatForForce takes string s, font f, real x, real y, force forForce returns nothing
static if ANGLE_RND then
local real a = GetRandomReal(-bj_PI, bj_PI)
else
local real a = FIX_ANGLE
endif
//* textsplat API.
local textsplat t = textsplat.create(f)
set t.lifespan = TIME_LIFE
set t.fadepoint = TIME_FADE
set t.permanent = false
call t.setText(s, TEXTSIZE, TEXTSPLAT_TEXT_ALIGN_CENTER)
call t.setPosition(x, y, Z_OFFSET)
call t.setVelocity(Sin(a)*VELOCITY*32, Cos(a)*VELOCITY*32, 0.)
call t.setVisible(IsVisibleToPlayer(x, y, GetLocalPlayer()) and IsPlayerInForce(GetLocalPlayer(), forForce))
//* Set members.
set splat[max] = t
//* Start timer.
if (0 == max) then
call TimerStart(TMR, .031250000, true, function OnPeriodic)
endif
set max = max + 1
endfunction
function CreateArcingTextSplat takes string s, font f, real x, real y returns nothing
call CreateArcingTextSplatForForce(s, f, x, y, bj_FORCE_ALL_PLAYERS)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library InitCustomFont initializer Init uses Font
globals
font TREBUCHET_MS = 0
endglobals
private function Init takes nothing returns nothing
set TREBUCHET_MS = font.create(0)
call TREBUCHET_MS.addChar(" ", 16, "war3mapImported\\TrebuchetMS32.blp")
call TREBUCHET_MS.addChar("!", 8, "war3mapImported\\TrebuchetMS33.blp")
call TREBUCHET_MS.addChar("\"", 10, "war3mapImported\\TrebuchetMS34.blp")
call TREBUCHET_MS.addChar("#", 19, "war3mapImported\\TrebuchetMS35.blp")
call TREBUCHET_MS.addChar("$", 16, "war3mapImported\\TrebuchetMS36.blp")
call TREBUCHET_MS.addChar("%", 20, "war3mapImported\\TrebuchetMS37.blp")
call TREBUCHET_MS.addChar("&", 22, "war3mapImported\\TrebuchetMS38.blp")
call TREBUCHET_MS.addChar("'", 6, "war3mapImported\\TrebuchetMS39.blp")
call TREBUCHET_MS.addChar("(", 11, "war3mapImported\\TrebuchetMS40.blp")
call TREBUCHET_MS.addChar(")", 10, "war3mapImported\\TrebuchetMS41.blp")
call TREBUCHET_MS.addChar("*", 14, "war3mapImported\\TrebuchetMS42.blp")
call TREBUCHET_MS.addChar("+", 16, "war3mapImported\\TrebuchetMS43.blp")
call TREBUCHET_MS.addChar(",", 9, "war3mapImported\\TrebuchetMS44.blp")
call TREBUCHET_MS.addChar("-", 10, "war3mapImported\\TrebuchetMS45.blp")
call TREBUCHET_MS.addChar(".", 8, "war3mapImported\\TrebuchetMS46.blp")
call TREBUCHET_MS.addChar("/", 15, "war3mapImported\\TrebuchetMS47.blp")
call TREBUCHET_MS.addChar("0", 18, "war3mapImported\\TrebuchetMS48.blp")
call TREBUCHET_MS.addChar("1", 11, "war3mapImported\\TrebuchetMS49.blp")
call TREBUCHET_MS.addChar("2", 18, "war3mapImported\\TrebuchetMS50.blp")
call TREBUCHET_MS.addChar("3", 16, "war3mapImported\\TrebuchetMS51.blp")
call TREBUCHET_MS.addChar("4", 19, "war3mapImported\\TrebuchetMS52.blp")
call TREBUCHET_MS.addChar("5", 16, "war3mapImported\\TrebuchetMS53.blp")
call TREBUCHET_MS.addChar("6", 18, "war3mapImported\\TrebuchetMS54.blp")
call TREBUCHET_MS.addChar("7", 18, "war3mapImported\\TrebuchetMS55.blp")
call TREBUCHET_MS.addChar("8", 18, "war3mapImported\\TrebuchetMS56.blp")
call TREBUCHET_MS.addChar("9", 17, "war3mapImported\\TrebuchetMS57.blp")
call TREBUCHET_MS.addChar(":", 8, "war3mapImported\\TrebuchetMS58.blp")
call TREBUCHET_MS.addChar(";", 9, "war3mapImported\\TrebuchetMS59.blp")
call TREBUCHET_MS.addChar("<", 15, "war3mapImported\\TrebuchetMS60.blp")
call TREBUCHET_MS.addChar("=", 17, "war3mapImported\\TrebuchetMS61.blp")
call TREBUCHET_MS.addChar(">", 15, "war3mapImported\\TrebuchetMS62.blp")
call TREBUCHET_MS.addChar("?", 13, "war3mapImported\\TrebuchetMS63.blp")
call TREBUCHET_MS.addChar("@", 24, "war3mapImported\\TrebuchetMS64.blp")
call TREBUCHET_MS.addChar("A", 22, "war3mapImported\\TrebuchetMS65.blp")
call TREBUCHET_MS.addChar("B", 18, "war3mapImported\\TrebuchetMS66.blp")
call TREBUCHET_MS.addChar("C", 20, "war3mapImported\\TrebuchetMS67.blp")
call TREBUCHET_MS.addChar("D", 19, "war3mapImported\\TrebuchetMS68.blp")
call TREBUCHET_MS.addChar("E", 17, "war3mapImported\\TrebuchetMS69.blp")
call TREBUCHET_MS.addChar("F", 18, "war3mapImported\\TrebuchetMS70.blp")
call TREBUCHET_MS.addChar("G", 21, "war3mapImported\\TrebuchetMS71.blp")
call TREBUCHET_MS.addChar("H", 20, "war3mapImported\\TrebuchetMS72.blp")
call TREBUCHET_MS.addChar("I", 7, "war3mapImported\\TrebuchetMS73.blp")
call TREBUCHET_MS.addChar("J", 15, "war3mapImported\\TrebuchetMS74.blp")
call TREBUCHET_MS.addChar("K", 20, "war3mapImported\\TrebuchetMS75.blp")
call TREBUCHET_MS.addChar("L", 17, "war3mapImported\\TrebuchetMS76.blp")
call TREBUCHET_MS.addChar("M", 26, "war3mapImported\\TrebuchetMS77.blp")
call TREBUCHET_MS.addChar("N", 19, "war3mapImported\\TrebuchetMS78.blp")
call TREBUCHET_MS.addChar("O", 22, "war3mapImported\\TrebuchetMS79.blp")
call TREBUCHET_MS.addChar("P", 18, "war3mapImported\\TrebuchetMS80.blp")
call TREBUCHET_MS.addChar("Q", 26, "war3mapImported\\TrebuchetMS81.blp")
call TREBUCHET_MS.addChar("R", 19, "war3mapImported\\TrebuchetMS82.blp")
call TREBUCHET_MS.addChar("S", 16, "war3mapImported\\TrebuchetMS83.blp")
call TREBUCHET_MS.addChar("T", 21, "war3mapImported\\TrebuchetMS84.blp")
call TREBUCHET_MS.addChar("U", 19, "war3mapImported\\TrebuchetMS85.blp")
call TREBUCHET_MS.addChar("V", 21, "war3mapImported\\TrebuchetMS86.blp")
call TREBUCHET_MS.addChar("W", 29, "war3mapImported\\TrebuchetMS87.blp")
call TREBUCHET_MS.addChar("X", 20, "war3mapImported\\TrebuchetMS88.blp")
call TREBUCHET_MS.addChar("Y", 21, "war3mapImported\\TrebuchetMS89.blp")
call TREBUCHET_MS.addChar("Z", 18, "war3mapImported\\TrebuchetMS90.blp")
call TREBUCHET_MS.addChar("[", 11, "war3mapImported\\TrebuchetMS91.blp")
call TREBUCHET_MS.addChar("\\", 14, "war3mapImported\\TrebuchetMS92.blp")
call TREBUCHET_MS.addChar("]", 11, "war3mapImported\\TrebuchetMS93.blp")
call TREBUCHET_MS.addChar("^", 15, "war3mapImported\\TrebuchetMS94.blp")
call TREBUCHET_MS.addChar("_", 20, "war3mapImported\\TrebuchetMS95.blp")
call TREBUCHET_MS.addChar("`", 9, "war3mapImported\\TrebuchetMS96.blp")
call TREBUCHET_MS.addChar("a", 16, "war3mapImported\\TrebuchetMS97.blp")
call TREBUCHET_MS.addChar("b", 13, "war3mapImported\\TrebuchetMS98.blp")
call TREBUCHET_MS.addChar("c", 15, "war3mapImported\\TrebuchetMS99.blp")
call TREBUCHET_MS.addChar("d", 14, "war3mapImported\\TrebuchetMS100.blp")
call TREBUCHET_MS.addChar("e", 12, "war3mapImported\\TrebuchetMS101.blp")
call TREBUCHET_MS.addChar("f", 13, "war3mapImported\\TrebuchetMS102.blp")
call TREBUCHET_MS.addChar("g", 16, "war3mapImported\\TrebuchetMS103.blp")
call TREBUCHET_MS.addChar("h", 14, "war3mapImported\\TrebuchetMS104.blp")
call TREBUCHET_MS.addChar("i", 5, "war3mapImported\\TrebuchetMS105.blp")
call TREBUCHET_MS.addChar("j", 11, "war3mapImported\\TrebuchetMS106.blp")
call TREBUCHET_MS.addChar("k", 15, "war3mapImported\\TrebuchetMS107.blp")
call TREBUCHET_MS.addChar("l", 13, "war3mapImported\\TrebuchetMS108.blp")
call TREBUCHET_MS.addChar("m", 19, "war3mapImported\\TrebuchetMS109.blp")
call TREBUCHET_MS.addChar("n", 14, "war3mapImported\\TrebuchetMS110.blp")
call TREBUCHET_MS.addChar("o", 16, "war3mapImported\\TrebuchetMS111.blp")
call TREBUCHET_MS.addChar("p", 14, "war3mapImported\\TrebuchetMS112.blp")
call TREBUCHET_MS.addChar("q", 18, "war3mapImported\\TrebuchetMS113.blp")
call TREBUCHET_MS.addChar("r", 14, "war3mapImported\\TrebuchetMS114.blp")
call TREBUCHET_MS.addChar("s", 12, "war3mapImported\\TrebuchetMS115.blp")
call TREBUCHET_MS.addChar("t", 16, "war3mapImported\\TrebuchetMS116.blp")
call TREBUCHET_MS.addChar("u", 14, "war3mapImported\\TrebuchetMS117.blp")
call TREBUCHET_MS.addChar("v", 16, "war3mapImported\\TrebuchetMS118.blp")
call TREBUCHET_MS.addChar("w", 21, "war3mapImported\\TrebuchetMS119.blp")
call TREBUCHET_MS.addChar("x", 15, "war3mapImported\\TrebuchetMS120.blp")
call TREBUCHET_MS.addChar("y", 16, "war3mapImported\\TrebuchetMS121.blp")
call TREBUCHET_MS.addChar("z", 13, "war3mapImported\\TrebuchetMS122.blp")
call TREBUCHET_MS.addChar("{", 14, "war3mapImported\\TrebuchetMS123.blp")
call TREBUCHET_MS.addChar("|", 6, "war3mapImported\\TrebuchetMS124.blp")
call TREBUCHET_MS.addChar("}", 14, "war3mapImported\\TrebuchetMS125.blp")
call TREBUCHET_MS.addChar("~", 15, "war3mapImported\\TrebuchetMS126.blp")
endfunction
endlibrary
//TESH.scrollpos=3
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
local unit u1
local unit u2
local unit u3
local unit u4
local real x = -555
local real y = -1000
set u1 = CreateUnit(Player(0), 'hfoo', x, y, 0)
call SetUnitPropWindow(u1, 0)
set x = x + 100 * Cos(-3*bj_PI/4)
set y = y + 100 * Sin(-3*bj_PI/4)
set u2 = CreateUnit(Player(0), 'hfoo', x, y, 0)
call SetUnitPropWindow(u2, 0)
set x = x + 100 * Cos(-bj_PI/4)
set y = y + 100 * Sin(-bj_PI/4)
set u3 = CreateUnit(Player(0), 'hfoo', x, y, 0)
call SetUnitPropWindow(u3, 0)
set x = x + 100 * Cos(bj_PI/4)
set y = y + 100 * Sin(bj_PI/4)
set u4 = CreateUnit(Player(0), 'hfoo', x, y, 0)
call SetUnitPropWindow(u4, 0)
call IssueTargetOrder(u1, "attack", u2)
call IssueTargetOrder(u2, "attack", u3)
call IssueTargetOrder(u3, "attack", u4)
call IssueTargetOrder(u4, "attack", u1)
set u1 = null
set u2 = null
set u3 = null
set u4 = null
endfunction
//===========================================================================
function InitTrig_CreateUntis takes nothing returns nothing
call Trig_Untitled_Trigger_001_Actions()
endfunction