• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

[JASS] Global Functions (Reusable Functions)

Status
Not open for further replies.
Level 4
Joined
Nov 24, 2007
Messages
55
Hi, I was wondering if there is a way to write a "global" function that I can call in other triggers?

For example, many of my spells end by doing some floating combat text to show the number of damage that ability did. This takes approximately 5 lines of code to do, and I hate copy/pasting these over and over, because then when i decide i need to change the way i do all floating text, i have to find and hunt down every single time i had done it.

For instance, I would love to have the following function accessible to all my triggers:

Code:
function GlobalFloatingCombatText takes unit targ, string msg, real red, real green, real blue returns nothing
    call CreateTextTagLocBJ( msg, GetUnitLoc(targ), 0, 10.00, 0.00, red, green, blue )
    call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
    call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 32.00, 90 )
    call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 1.00 )
    call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 2.00 )

is this possible? Can i then in another trigger completely tell it via Jass just "call GlobalFloatingCombatText( target, R2S(damage), 100, 0, 0)" or something like that?

Thanks
 
Level 11
Joined
Feb 18, 2004
Messages
394
The World Editor's trigger editor is actually an interface for editing portions of a larger script. Some crap such as preplaced units get generated in to part of the script, GUI triggers have JASS components which get used in the script, and custom text triggers get inserted in to the script as-is. The order triggers get placed in to the script can be considered indeterminate.

Functions in JASS have one scope, variables have two scopes. All functions are in the global scope. You may call a function anywhere below where it is defined. (Barring roundabout methods which use the code data type, or ExecuteFunc()) Variables have two scopes: global and local. Globals are defined in a single "globals" block at the top of the script, locals are defined at the top of the function they are local to.

You likely want to use the JASS NewGen editor. (Link in my signature.) It includes a better syntax checker, a better JASS editor within the trigger editor, and JASS Helper which allows you to use vJASS. (An online version of a slightly out of date vJASS manual is located here: http://wc3campaigns.net/vexorian/jasshelpermanual.html The latest version of the manual is included in NewGen in the jasshelper folder.) The specific vJASS feature you want are libraries. (Read the manual for more information about libraries and vJASS.)

If you are using a mac and thus can not use NewGen, you can use the custom script header which may be edited by selecting your maps name in the trigger editors trigger list. (The header is inserted in to the script before any triggers.) Note that the custom script header is considered deprecated by vJASS libraries. You should use vJASS if you can.
 
Level 4
Joined
Nov 24, 2007
Messages
55
Oh, that is exactly what i was looking for i think! (I am indeed on a macbook. >_< ) I have a desktop computer, but I have to do a lot of my coding while travelling...so while i "could" use the NewGen editor, i'd 'prefer' to be able to do this on my mac whenever possible.

However, I tried putting in the following, and it threw quite some errors

Code:
function GlobalFloatingCombatText takes unit targ, string msg, real red, real green, real blue returns nothing
   call CreateTextTagLocBJ( msg, GetUnicLoc(targ), 0, 10.00, 0.00, red, green, blue )
   call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
   call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 32.00, 90 )
   call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 1.00 )
   call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 2.00 )
endfunction

in that header, it didn't throw a compilation error until the 2nd line ( is it trying to run this code immediately? I highly doubt it...but, regardless, it said the error was on the second line (not the function declaration) and it said it was expecting a name.

I'm wondering, is this like a header declaration for declaring functions? I'm going to keep playing around with this (although if it is jsut a header declaration, where do i declare the body of the function?) thanks again for your help though, this is very helpful.

(Random side question: I originally tried testing with the concept of a 'global' function by putting a function in JASS in my first trigger and calling it in another trigger further down the list. It said it didn't know what the function is.)
 
Level 11
Joined
Feb 18, 2004
Messages
394
GetUnicLoc(targ) Is misspelled.

call CreateTextTagLocBJ( msg, GetUnitLoc(targ), 0, 10.00, 0.00, red, green, blue )
its Red Green Blue Alpha, not Alpha Red Green Blue.

You also leak the location: GetUnicLoc(targ)

And please use [code=jass] tags, not code tags

You also use an obscene number of Blizzard.j functions... use natives instead... I don't know of any JASS editors with a function list that work on mac, sorry. You can always check out http://jass.sourceforge.net/ or view the common.j and blizzard.j files directly in any text editor.

Avoid most blizzard.j functions... they mostly do nothing thats worth doing, and its almost always best to simply use the native functions instead of the shittily written BJ functions. (most blizzard.j functions are poorly written, useless, and used mainly for the GUI... Don't use em when coding in pure JASS...)

Lets see now, you use directly or indirectly all of these non-native functions:
JASS:
function CreateTextTagLocBJ takes string s, location loc, real zOffset, real size, real red, real green, real blue, real transparency returns texttag
    set bj_lastCreatedTextTag = CreateTextTag()
    call SetTextTagTextBJ(bj_lastCreatedTextTag, s, size)
    call SetTextTagPosBJ(bj_lastCreatedTextTag, loc, zOffset)
    call SetTextTagColorBJ(bj_lastCreatedTextTag, red, green, blue, transparency)

    return bj_lastCreatedTextTag
endfunction

JASS:
function SetTextTagTextBJ takes texttag tt, string s, real size returns nothing
    local real textHeight = TextTagSize2Height(size)

    call SetTextTagText(tt, s, textHeight)
endfunction

JASS:
function TextTagSize2Height takes real size returns real
    return size * 0.023 / 10
endfunction

JASS:
function SetTextTagPosBJ takes texttag tt, location loc, real zOffset returns nothing
    call SetTextTagPos(tt, GetLocationX(loc), GetLocationY(loc), zOffset)
endfunction

JASS:
function SetTextTagColorBJ takes texttag tt, real red, real green, real blue, real transparency returns nothing
    call SetTextTagColor(tt, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
endfunction

JASS:
function PercentTo255 takes real percentage returns integer
    return PercentToInt(percentage, 255)
endfunction

function PercentToInt takes real percentage, integer max returns integer
    local integer result = R2I(percentage * I2R(max) * 0.01)

    if (result < 0) then
        set result = 0
    elseif (result > max) then
        set result = max
    endif

    return result
endfunction

JASS:
function SetTextTagPermanentBJ takes texttag tt, boolean flag returns nothing
    call SetTextTagPermanent(tt, flag)
endfunction

JASS:
function GetLastCreatedTextTag takes nothing returns texttag
    return bj_lastCreatedTextTag
endfunction
bj_lastCreatedTextTag is a global variable.

JASS:
function SetTextTagVelocityBJ takes texttag tt, real speed, real angle returns nothing
    local real vel = TextTagSpeed2Velocity(speed)
    local real xvel = vel * Cos(angle * bj_DEGTORAD)
    local real yvel = vel * Sin(angle * bj_DEGTORAD)

    call SetTextTagVelocity(tt, xvel, yvel)
endfunction

JASS:
function SetTextTagFadepointBJ takes texttag tt, real fadepoint returns nothing
    call SetTextTagFadepoint(tt, fadepoint)
endfunction

JASS:
function SetTextTagLifespanBJ takes texttag tt, real lifespan returns nothing
    call SetTextTagLifespan(tt, lifespan)
endfunction


Inlining all of those functions yeilds...
JASS:
function GlobalFloatingCombatText takes unit targ, string msg, real red, real green, real blue returns nothing
    local texttag t = CreateTextTag()
    
    call SetTextTagText(t, msg, 0.023)
    call SetTextTagPos(t, GetUnitX(targ), GetUnitY(targ), 0)
    call SetTextTagColor(t, PercentToInt(red, 255), PercentToInt(green, 255), PercentToInt(blue, 255), 255)
    call SetTextTagPermanent(t, false)
    call SetTextTagVelocity(t, 0, 0.0177) // Math is fun!
    call SetTextTagFadepoint(t, 1.0)
    call SetTextTagLifespan(t, 2.0)
endfunction

The location leak is gone as using GetUnitX/Y() doesnt create a location. You likely want to start using colours that are 0-255 integers, instead of 0-100 reals.
 
Level 4
Joined
Nov 24, 2007
Messages
55
Wow, thanks a bunch for all that info. I have always wondered what "BJ" functions were (i could never find an answer) but it sounds like they are "blizzard" functions in their .j file?

And thank you for the pointer on where to look all of them up. The reason I was using all of them was that I had simply written the code in GUI then converted to see what the function is (without knowing this other stuff, thatss about the only way to see what functions exist).

I will definitely be using 255 values for the colors instead of the percentages (i thought that was the only way)

As for looking up the "natives", are those in the common.j, or shoudl i jsut download newgen on my PC and look 'em up there? I assume that's what your comment about the sourceforge and common.j was an allusion to.

And yea, I def. misspelled htat one, becuase when i tried it again (before reading this) i got it to work. This will definitely clean up a Lot of my trigger code, having common functions to call. I'm surprised this is not mentioned in the JASS tutorial.

Random Questions: do you know of any way to access an ability's data values form within the script? Say, for instance, i want some code to be based on a spell, and apply a .5x damage to the thing, say like <A007,DataA1> x 0.5 damage, in the JASS script. Can i call that?

Random Question 2: i can't seem to use the local variables for an ability. I tried

JASS:
local ability anAbil
set anAbil = GetSpellAbilityID()
I had to instead use a global of type Ability, which it did allow
JASS:
set udg_theAbil = GetSpellAbilityID()
which did not make a whole lot of sense. I'm not overly concerned with Multi-instanceable, as this is an 'instant' trigger, but i do not like globals in general.

If you don't know, i guess i should probably make a new thread with these questions, or just do work on my PC with a good JASS editor which can tell me these things
 
Last edited:
Level 11
Joined
Feb 18, 2004
Messages
394
Wow, thanks a bunch for all that info. I have always wondered what "BJ" functions were (i could never find an answer) but it sounds like they are "blizzard" functions in their .j file?

And thank you for the pointer on where to look all of them up. The reason I was using all of them was that I had simply written the code in GUI then converted to see what the function is (without knowing this other stuff, thatss about the only way to see what functions exist).

I will definitely be using 255 values for the colors instead of the percentages (i thought that was the only way)

As for looking up the "natives", are those in the common.j, or shoudl i jsut download newgen on my PC and look 'em up there? I assume that's what your comment about the sourceforge and common.j was an allusion to.

And yea, I def. misspelled htat one, becuase when i tried it again (before reading this) i got it to work. This will definitely clean up a Lot of my trigger code, having common functions to call. I'm surprised this is not mentioned in the JASS tutorial.

There are multiple files where functions are defined for JASS. every function and variable available to you is defined in one of a few files:
common.j holds native functions (functions implemented in C++ within the game itself. common.j simply holds prototypes for these functions such as:
JASS:
native AddLightning takes string codeName,boolean checkVisibility,real x1,real y1,real x2,real y2 returns lightning

blizzard.j holds functions written in JASS that use the native functions. Most blizzard.j functions suck.

common.ai holds natives used in ai scripts. (Not available to war3map.j)

war3map.j is the script file within a map file. It's where all the stuff you define in the world editor goes.

Quite frankly, if you really want to get in to JASS, you should use a PC and NewGen. vJASS adds a _lot_ of useful stuff to JASS, and NewGen adds countless useful features to the editor. (Including War3err for the game, which tells you at run time when some rather common errors occur) NewGen also uses pJASS instead of the WE's default syntax checker. (The thing that tells you about syntax errors when you save your map.) pJASS is both better, and less prone to crashing the editor when there is a syntax error. (The default syntax checker is know for loving to crash WE.)

You may wish to look in to a VM for running JASSHelper.exe. It will at least let you write up some scripts while running your mac, even if you can't test them till you get to your PC.

jass.sourceforge.net holds a full list of functions: http://jass.sourceforge.net/doc/api/functions.shtml However using NewGen and the function finder added to the trigger editor is defiantly preferable.

And, just to make something fundamentally clear, converting GUI to JASS is not a good way to learn JASS or look up functions. Code in pure JASS from the start of something till the end. (It will take a lot of time at first, but eventually coding in JASS will be faster than using the GUI.)
 
Status
Not open for further replies.
Top