# Small Code Snippets

#### Nestharus

Level 31
JASS:
``````library SphericalProjection /* v1.0.0.1
*************************************************************************************
*
*   */uses/*
*
*       */ AutoFly /*       hiveworkshop.com/forums/submissions-414/autofly-unitindexer-version-195563/
*
************************************************************************************
*
*   function SphericalProjection takes real x, real y, real z, real facing, verticalFacing, unit whichUnit, real distance, real theta, real phi returns nothing
*       -   x,y,z,facing,verticalFacing     source position. Vertical facing is z facing of unit, normally 0.
*       -   whichUnit                       unit to project
*       -   distance                        distance from position
*       -   theta                           x,y angle, 0 radians would be directly in front
*       -   phi                             z angle, 0 radians would be flat, pi/2 directly above,
*       -                                   -pi/2 directly below
*
************************************************************************************/
function SphericalProjection takes real x, real y, real z, real f, real vf, unit u, real d, real t, real p returns nothing
set t=t+f
set f=d*Sin(p+vf)
call SetUnitX(u,Cos(t)*f)
call SetUnitY(u,Sin(t)*f)
call SetUnitFlyHeight(u,d*Cos(p+vf),10000)
endfunction
endlibrary``````

Last edited:

#### Bribe

Level 51
Should execute more quickly like this:

JASS:
``````function SphericalProjection takes real x, real y, real z, real f, real vf, unit u, real d, real t, real p returns nothing
local real pvf = Sin(p+vf)
call SetUnitX(u, d*Cos(t+f)*pvf)
call SetUnitY(u, d*Sin(t+f)*pvf)
call SetUnitZ(u, d*pvf)
endfunction``````

#### PurgeandFire

Level 44
Probably better like this:
JASS:
``````function SphericalProjection takes real x, real y, real z, real f, real vf, unit u, real d, real t, real p returns nothing
set t = t + f
set d = d*Sin(p+vf)
call SetUnitX(u, d*Cos(t))
call SetUnitY(u, d*Sin(t))
call SetUnitZ(u, d)
endfunction``````

#### Magtheridon96

Level 36
JASS:
``````/*******************************************
*   Clock
*   v1.0.0.0
*   Magtheridon96
*
*   - A clock system that stores hours, minutes and seconds.
*
*   API:
*   ----
*
*       - function GetGameSeconds takes nothing returns integer
*       - function GetGameMinutes takes nothing returns integer
*       - function GetGameHours takes nothing returns integer
*
*       - function GetGameTimeString takes nothing returns string
*           - Returns the game-time string formatted: HH:MM:SS
*
*******************************************/
library Clock

private struct Clock extends array

static integer hours = 0
static integer minutes = 0
static integer seconds = 0

static method buffer takes nothing returns nothing
set seconds = seconds + 1
if seconds == 60 then
set seconds = 0
set minutes = minutes + 1
if minutes == 60
set minutes = 0
set hours = hours + 1
endif
endif
endmethod

private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(), 1, true, function thistype.buffer)
endmethod
endstruct

function GetGameSeconds takes nothing returns integer
return Clock.seconds
endfunction
function GetGameMinutes takes nothing returns integer
return Clock.minutes
endfunction
function GetGameHours takes nothing returns integer
return Clock.hours
endfunction
function GetGameTimeString takes nothing returns string
local string t = I2S(Clock.seconds)
if Clock.seconds <= 9 then
set t = "0" + t
endif
set t = I2S(Clock.minutes) + ":" + t
if Clock.minutes <= 9 then
set t = "0" + t
endif
set t = I2S(Clock.hours) + ":" + t
if Clock.hours <= 9 then
set t = "0" + t
endif
return t
endfunction
endlibrary``````

I think it's pretty good

edit
- Made the struct extend an array and removed the module initializer + changed the variable names and the documentation.

Oh and you shouldn't be using this, you should be using this: http://www.hiveworkshop.com/forums/submissions-414/system-elapsedgametime-209231/

Last edited:

#### Bribe

Level 51
Nestharus' AddCommas significantly optimized:

JASS:
``````function AddCommas takes integer i returns string
local string read = I2S(i)
local string val = ""
local integer pos = StringLength(read)
loop
set pos = pos - 3
if pos < 0 then
set val = SubString(read, 0, pos + 3) + val
exitwhen true
endif
set val = "," + SubString(read, pos, pos + 3) + val
endloop
if SubString(val, 0, 1) == "," then
return SubString(val, 1, StringLength(val))
elseif SubString(val, 0, 2) == "-," then
return "-" + SubString(val, 2, StringLength(val))
endif
return val
endfunction``````

To contrast:

JASS:
``````function AddCommas takes integer n returns string
local integer m = 0
local string s = ""
local boolean b = false
if (n < 0) then
set n = -n
set b = true
endif
loop
exitwhen n == 0
if (m > 0) then
set s = "," + s
endif
set m = n
set n = n/1000
set m = m-n*1000
if (n > 0) then
if (m < 10) then
set s = "00" + I2S(m) + s
elseif (m < 100) then
set s = "0" + I2S(m) + s
else
set s = I2S(m) + s
endif
set m = 1
else
set s = I2S(m) + s
set m = 0
endif
endloop
if (s == "") then
return "0"
endif
if (b) then
set s = "-" + s
endif
return s
endfunction``````

Last edited:

#### Nestharus

Level 31
I wouldn't call that optimized in the slightest... your version runs on strings >.>.

Furthermore, you have to loop forwards, not backwards.

Yours would bug up on this-
12345678

It'd do this
123,456,78

#### Troll-Brain

Level 17
Hmm, i would say that is slower because of SubString and StringLength and string concatenation.
A such function is not supposed to be used in heavy loop or rapid timers though, so that wouldn't matter so much.

Even if i hate the habit of Nestharus (use short names for variables because of speed freak), i would prefer his code, just because the way how string are handled in jass, the less you use, the best it is.

#### Bribe

Level 51
I have tested this plenty in-game. It does not bug at all

Also, it is heavily faster. Nestharus uses lots of math on top of concatenation, whereas this uses far fewer operations & lines to achieve the same end-result.

This also uses fewer loops. Nestharus runs it all char-by-char and this handles everything in blocks of three at a time.

#### Nestharus

Level 31
Mine doesn't run char by char at all... it does the exact same amount of loops as yours..

The best way to test is to run on a stress test timer to see which one lags first.

Run a timer 32x a second and push the instances up until one lags =), then say which one is faster =P.

#### Troll-Brain

Level 17
But if you care about a such test you would "wc3mapoptimize" the map before.

#### Nestharus

Level 31
You can't use it to optimize the map's script since a good portion of maps can't use it to optimize their scripts >.>.

It'd be a pretty fail test since it wouldn't be the case in an actual map =P.

Just make ur var names 1 char each =D

edit
mine could be optimized a little
JASS:
``````function AddCommas takes integer n returns string
local integer m = 0
local string s = ""
local boolean b = false
if (n < 0) then
set n = -n
set b = true
endif
loop
exitwhen n == 0
if (m > 0) then
set s = "," + s
endif
set m = n
set n = n/1000
set m = m-n*1000
if (n > 0) then
if (m < 10) then
set s = "00" + I2S(m) + s
elseif (m < 100) then
set s = "0" + I2S(m) + s
else
set s = I2S(m) + s
endif
else
set s = I2S(m) + s
endif
endloop
if (s == "") then
return "0"
endif
if (b) then
set s = "-" + s
endif
return s
endfunction``````

#### Troll-Brain

Level 17
You can't use it to optimize the map's script since a good portion of maps can't use it to optimize their scripts >.>.

It'd be a pretty fail test since it wouldn't be the case in an actual map =P.

Just make ur var names 1 char each =D

"a good portion of maps" seems far away from the truth, i guess only few (including yours).
Plus for this test it's perfectly possible.

Also, instead of keeping complaining about it, what about making a new one ? (you don't really need a GUI and all the wc3mapoptimizer stuff)

#### Bribe

Level 51
Ran some tests. The results were surprisingly close - it seemed Nestharus' script was a tiny bit faster, but then I shortened the variable names in my script and now mine is consistently a little bit faster.

The above results were when I passed the value 1,000,000,000.

When I passed the value as a negative number (-1,000,000,000) my script was at least 10-15% faster.

Tests:

JASS:
``````globals
integer loopint = 0
endglobals

function AddCommas takes integer i returns string
local string r = I2S(i)
local string s = ""
local integer p = StringLength(r)
loop
set p = p - 3
if p < 0 then
set s = SubString(r, 0, p + 3) + s
if SubString(s, 0, 1) == "," then
return SubString(s, 1, StringLength(s))
elseif SubString(s, 0, 2) == "-," then
return "-" + SubString(s, 2, StringLength(s))
endif
return s
endif
set s = "," + SubString(r, p, p + 3) + s
endloop
return "" //Parser thinks a return is missing -_-
endfunction

/*
function AddCommas takes integer n returns string
local integer m = 0
local string s = ""
local boolean b = false
if (n < 0) then
set n = -n
set b = true
endif
loop
exitwhen n == 0
if (m > 0) then
set s = "," + s
endif
set m = n
set n = n/1000
set m = m-n*1000
if (n > 0) then
if (m < 10) then
set s = "00" + I2S(m) + s
elseif (m < 100) then
set s = "0" + I2S(m) + s
else
set s = I2S(m) + s
endif
else
set s = I2S(m) + s
endif
endloop
if (s == "") then
return "0"
endif
if (b) then
set s = "-" + s
endif
return s
endfunction
*/
function go takes nothing returns nothing
local integer i = 200
loop
call AddCommas(-1000000000)
set i = i - 1
exitwhen i == 0
endloop
set loopint = loopint + 1
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0,0,60,I2S(loopint))
if loopint == 32 then
set loopint = 0
endif
endfunction

function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
call TimerStart(CreateTimer(), 0.03125, true, function go)
endfunction``````

#### Troll-Brain

Level 17
And what if you increase it in each loop iteration instead of keeping a constant value ?
(this way the string functions won't use the same string stored in the string table, so it would be slower)

#### Bribe

Level 51
And what if you increase it in each loop iteration instead of keeping a constant value ?
(this way the string functions won't use the same string stored in the string table, so it would be slower)

That would simply slow down the game as a whole, it wouldn't affect benchmarks.

#### Troll-Brain

Level 17
So no regard about the efficiency, Nestharus' way is better, just because as i said when we don't need strings it's lame to use them, and this function is not defined to be used heavily.

#### Bribe

Level 51
You know that Nestharus' script is using as much, if not more, concatenation than this does? We are both running this using lots of strings.

One stupid thing I have noticed is WarCraft III's built-in S2I() functionality doesn't produce a result higher than 2 ** 31 - 1.

#### Troll-Brain

Level 17
Hmm, you are probably right, i was focalised on SubString usage in a loop, but on a second watch you have only few loop iterations, especially with low integers.
And since your code is shorter i would vote for you now

#### Nestharus

Level 31
Ahem, Bribe, yours leaks way, way more strings....

I just tested it and after like 1.5 seconds using Troll-Brain's idea of a changing variable, yours went down to <1 fps. It took mine like 25 seconds to get down to 3fps >.>.

edit
for constant, Bribe is right that his is faster, but it again leaks masses of strings compared to mine.

I think the string leaks here are a bigger issue than speed.

edit
updated

JASS:
``````function AddCommas takes integer n returns string
local integer m = 0
local string s = ""
local boolean b = false
if (n == 0) then
return "0"
elseif (n < 0) then
set n = -n
set b = true
endif
loop
set m = n
set n = n/1000
set m = m-n*1000
if (n > 0) then
if (m < 10) then
set s = ",00" + I2S(m) + s
elseif (m < 100) then
set s = ",0" + I2S(m) + s
else
set s = "," + I2S(m) + s
endif
elseif (b) then
return "-" + I2S(m) + s
else
return I2S(m) + s
endif
endloop
return ""
endfunction``````

Mine is now consistently faster than Bribe's + leaks way less (tested).

Updated the snippet post as well

gg

edit
1 minute 43 seconds on new version to get to 3 fps.

Case closed.

Last edited:

#### Bribe

Level 51
See what happens when you challenge Nestharus? He finds a way to make his script even better, building the best possible resource. Win/win situation ^^

And he's right with the string leaks, this build won't leak nearly as much as mine! So I guess this proves that strings are still leaking even after the return bug was fixed. Why is WarCraft III still caching strings to that table when it's 100% useless now?

#### Troll-Brain

Level 17
Why is WarCraft III still caching strings to that table when it's 100% useless now?

They follow Murphy's law when they add/revome jass stuff in a patch.

Also since the begin i couldn't find about any really usefull case where typecasting string to integer to get the string "pointer" was really useful.
Only code <-> integer is a real lost, and also the typcast widget <-> unit/destructable/item (but it can be done with an hashtable)

#### Troll-Brain

Level 17
It was possible to get a unique value from a string - you now must rely on the much slower StringHash native.

I know, but for what ?
There wasn't the hashtable type but only gamecache.

#### Bribe

Level 51
Getting the ordinal value of a string is a useful thing, so is getting the hex value of a string. This is because Blizzard forgot or didn't care enough (or both) to add such a useful thing.

#### Troll-Brain

Level 17
Any concrete example in jass ?

#### Troll-Brain

Level 17
Ok, that would indeed be good to have the position in the string table of a string, for the ASCII library we would be able to use directly the integer array variable (i mean without maths).
Hopefully even if it's not perfect StringHash is enough in most of cases, anyway it's not like we have other ways.

#### Weep

Level 10
but anyway, it could be useful to
SOMEONE =P

I don't think so...considering it doesn't actually work, at least not when I tested it.

1. Leaks a timer
2. Example won't even work due to uninitialized integer crashing the thread
3. Function itself won't even work due to no TriggerSleepAction meaning the loop will just run until the condition is satisfied, which will never happen since no time is passing during the loop, so it'll just terminate the thread due to an infinite loop
3b. Even if I'm wrong about the reason, I tried your function and no actions listed after set i = Wait(0.25) ran, so no matter what it for sure doesn't work
4. If you added TSA then it won't work for low values meaning this has no advantage over PolledWait

I was hoping there was some kind of magic with setting a local to a function's value rather than doing call Function, but, not as far as I can tell. Did you even test this? If it worked for you, can you upload a test map?

#### Magtheridon96

Level 36
Nah, I didn't test it
Thanks for telling me it doesn't work :L
.. I guess Jass sux then ^^ lol
I'll remove it ( that's gonna be an awkward post )

#### Troll-Brain

Level 17
The only way to use a timer as friendly as TSA is to build a preprocessor which will split the code in as many functions as needed and also convert locals variables in globals. (and use a timer recycling or whatever)
It wouldn't be for speedfreaks but that would still be cool.

#### D4RK_G4ND4LF

Level 19
[...]and also convert locals variables in globals[...]

indexed globals of course
but someone made something like that with macros already (maybe you can find it with forum search)
edit:
http://www.wc3c.net/showthread.php?t=101988
even found that with hive forum search...weird
edit2:
and this is the one which was in my mind
http://www.hiveworkshop.com/forums/graveyard-418/vjass-sleepaction-new-wait-178185/
not perfect though (if it was everybody would use it and you would know about it )

and to contribute something:
rotate a vector by the angle of another vector
A will be rotated by the angle between x-axis and B
a is the length of A
you can remove everything with a if you normalize A
this is an image of what the first function does
returns the coordinates of C

JASS:
``````function subtractVectorAngleX takes real ax, real ay, real bx, real by, real a returns real
return ax/a*bx + ay/a*by
endfunction

function subtractVectorAngleY takes real ax, real ay, real bx, real by, real a returns real
return ay/a*bx - ax/a*by
endfunction

function addVectorAngleX takes real ax, real ay, real bx, real by, real a returns real
return ax/a*bx - ay/a*by
endfunction

function addVectorAngleY takes real ax, real ay, real bx, real by, real a returns real
return ay/a*bx + ax/a*by
endfunction``````
probably quite simple but I had a need for it
I also requested a 3D version and maybe someone is kind enough to answer my biddings
you can find the derivation there
http://www.hiveworkshop.com/forums/requests-341/formula-request-3d-vector-rotation-196220/

#### Troll-Brain

Level 17
I know these solutions but that's hardly the same thing as using a timer like a TriggerSleepAction.

Just to prove that i know what i'm talking about :

http://www.wc3c.net/showthread.php?t=106581

But i actually i have not the skills to make an efficient preprocessor (learning C when i'm in the mood of it), nor the desire.

#### Nestharus

Level 31
Useful values for dummy spell making. Max coords are the maximum possible coordinate on a map. Max range is the maximum possible distance on a map (don't need 99999 on spells).

JASS:
``````MAX_COORD = 32556
MIN_COORD = -32556
MAX_RANGE = 92083``````

#### Magtheridon96

Level 36
JASS:
``````MAX_COORD = 32556
MIN_COORD = -32556
MAX_RANGE = 92083``````

Yeah!
Those are useful

-> In library form:

JASS:
``````library Constants
globals
real MAX_COORD = 32556.
real MIN_COORD = -MAX_COORD
real MAX_RANGE = 92083.
endglobals
endlibrary``````

This may be useful too:

An array lookup is much faster than a function call:
JASS:
``````library Players
globals
player array PLAYER
endglobals
private module Init
private static method onInit takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 15
set PLAYER[i] = Player(i)
set i = i + 1
endloop
endmethod
endmodule
private struct Inits
implement Init
endstruct
endlibrary``````

#### xD.Schurke

Level 16
doesnt matter, if you use 99999 or those values.

#### Magtheridon96

Level 36
@xD.Schurke

Yeah, but it's better to use MAX_RANGE for ... senseless reasons
MAX_COORD and MIN_COORD are VERY useful (That way you don't have to call WorldBounds() that often anymore :])

#### Nestharus

Level 31
But you could use 99,999

And Magtheridon, the Player library in JASS section already does what Players does but better =P.

#### Magtheridon96

Level 36
Here's a small "Clipboard" library
JASS:
``````library Clipboard
private module Init
private static method onInit takes nothing returns nothing
set Clipboard.i = 0
set Clipboard.s = ""
set Clipboard.b = false
set Clipboard.r = 0.0
endmethod
endmodule
struct Clipboard extends array
static integer i
static string s
static boolean b
static real r

static method copyI takes integer d returns nothing
set thistype.i = d
endmethod
static method pasteI takes nothing returns integer
return thistype.i
endmethod

static method copyS takes string d returns nothing
set thistype.s = d
endmethod
static method pasteS takes nothing returns string
return thistype.s
endmethod

static method copyB takes boolean d returns nothing
set thistype.b = d
endmethod
static method pasteB takes nothing returns boolean
return thistype.b
endmethod

static method copyR takes real d returns nothing
set thistype.r = d
endmethod
static method pasteR takes nothing returns real
return thistype.r
endmethod

implement Init
endstruct
endlibrary``````

It's similar to Copy/Paste, but it only works for primitive values (For simplicity)

#### xD.Schurke

Level 16
@xD.Schurke

Yeah, but it's better to use MAX_RANGE for ... senseless reasons
MAX_COORD and MIN_COORD are VERY useful (That way you don't have to call WorldBounds() that often anymore :])

just use 99999 instead of WorldBounds()

#### Magtheridon96

Level 36
Here's a small math oriented snippet:

JASS:
``````library Powers
function isPowerX takes real i, integer j returns boolean
loop
exitwhen i<j
set i=i/j
endloop
return i==1.0
endfunction

// wrappers
function isSquare takes real i returns boolean
return isPowerX(i,2)
endfunction

function isCube takes real i returns boolean
return isPowerX(i,3)
endfunction
endlibrary``````

#### Bribe

Level 51
All of those could be simplified using `ModuloInteger`.

JASS:
``````struct integer:
boolean isPowerX(integer i): return this.mod(i) == 0

boolean isSquare(): return this.mod(2) == 0

boolean isCube(): return this.mod(3) == 0``````

#### Nestharus

Level 31
No Bribe, that would not work.

62%2 = 0, but 62 isn't a power of 2.

#### Magtheridon96

Level 36
I think that's a fine example of why evaluating submissions should be illegal for me in the mornings -_-
I knew it

@ Bribe:
At least you were referring to something that actually makes sense
JASS:
``````function isDivisible takes integer i, integer j returns boolean
local integer m=i-(i/j)*j
if m<0 then
return m+j==0
endif
return m==0
endfunction``````

#### busterkomo

Level 17
JASS:
``````library SphericalProjection /* v1.0.0.1
*************************************************************************************
*
*   */uses/*
*
*       */ AutoFly /*       hiveworkshop.com/forums/submissions-414/autofly-unitindexer-version-195563/
*
************************************************************************************
*
*   function SphericalProjection takes real x, real y, real z, real facing, verticalFacing, unit whichUnit, real distance, real theta, real phi returns nothing
*       -   x,y,z,facing,verticalFacing     source position. Vertical facing is z facing of unit, normally 0.
*       -   whichUnit                       unit to project
*       -   distance                        distance from position
*       -   theta                           x,y angle, 0 radians would be directly in front
*       -   phi                             z angle, 0 radians would be flat, pi/2 directly above,
*       -                                   -pi/2 directly below
*
************************************************************************************/
function SphericalProjection takes real x, real y, real z, real f, real vf, unit u, real d, real t, real p returns nothing
set t=t+f
set f=d*Sin(p+vf)
call SetUnitX(u,Cos(t)*f)
call SetUnitY(u,Sin(t)*f)
call SetUnitFlyHeight(u,d*Cos(p+vf),10000)
endfunction
endlibrary``````
If I remember correctly, `SetUnitFlyHeight(u,d*Cos(p+vf),0)` is equivalent to `call SetUnitFlyHeight(u,d*Cos(p+vf),<some arbitrarily high number>)`

Replies
2
Views
769
Replies
7
Views
1K
Replies
1
Views
173
Replies
5
Views
751
Replies
7
Views
1K