• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJASS] Library Questions

Status
Not open for further replies.
Level 16
Joined
Mar 27, 2011
Messages
1,349
I'm starting to tackle vJass and I'm now creating a library. To give you an idea of what I'm trying to achieve, here is my incomplete code. I cant find any tutorials on libraries, so was hoping someone could explain a couple of things for me.

JASS:
library MusicLibrary

//************************************
// Variable Setup
//************************************


globals

    // Globals
    integer musicKey // Music Key. See "Music Mappings" for reference
    constant integer MUSICINDEXSIZE = 10 // Each key can only store indexSize number of values.
    constant string array MUSICPATHS
    constant integer array MUSICLENGTHS
    hashtable udg_TimerHash
 

    set musicKey = 1
    set MUSICPATHS[musicKey] = "Music\\06 Pallet Town Theme.mp3"
    set MUSICLENGTHS[musicKey * MUSICINDEXSIZE + 1] = 0050
    set MUSICLENGTHS[musicKey * MUSICINDEXSIZE + 2] = 43886

    set musicKey = 4
    set MUSICPATHS[musicKey] = "Music\\08 Professor Oak's Laboratory.mp3"
    set MUSICLENGTHS[musicKey * MUSICINDEXSIZE + 1] = 1076
    set MUSICLENGTHS[musicKey * MUSICINDEXSIZE + 2] = 17138

endglobals


//************************************
// Function List
//************************************

endlibrary

A few questions:

1.) What is the scope of of the "global" variables? Are they actual global or only use-able in this library? If global, could I make them static private instead?
2.) When are the global variables created? On map init, or each time the library is used in real time?
3.) I want to initialize the variables to store data in them upon the map loading. It seems I can't do that within the global nest. What's the best way to init the variables?

If there are any tutorials you know of, I'd also be happy if you could share a link :)

Edit: I remembered someone saying vJass supports 2D arrays. Can someone show me the correct syntax for that so I don't use funky emulating 1D arrays anymore like shown above?
 
Last edited:
Level 39
Joined
Feb 27, 2007
Messages
4,994
You should have the JASSHelper Manual for easy reference: JassHelper 0.A.0.0

1. Globals have the scope they're given. If you use Private only that library/scope can see it via <variablename>. If you use Public, that scope can use it via <variablename>; other libraries and scopes see it as <scopename>_<variablename>. If you use neither, all code can see it as <variablename> (not recommended in most cases). Most of your globals in libraries will be private. AFAIK the public name scheme is also recursive for scopes in libraries/other scopes, so it will add a prefix for each encapsulating library/scope.

Static is a keyword for struct members to make them act like a global variable instead of a struct member:
JASS:
struct s
  integer a
  static integer b
endstruct

local s Yours = s.create()
set Yours.a = 15    //correct
set Yours.b = 30    //incorrect, syntax error because b is not a member of Yours
set s.b = 30        //correct

2. They are merged into the globals block that contains all the trigger variables, unit variables, rects/regions, etc. that the game automatically makes. Variables cannot be "created", only "declared" in code. JassHelper 0.A.0.0

3. You cannot put any code in globals blocks. If you want something to run on map init, you need to put it into a scope or library with the initializer keyword. JassHelper 0.A.0.0
JASS:
library L initializer callthisanythingyouwantmostpeopleuseinit
  globals
    private constant integer a = 19
    public integer array b //no way to initialize arrays in globals blocks
    private trigger t // = CreateTrigger() function calls like this in globals blocks usually fail, you must do them manually in your own intializer
  endglobals

  private function callthisanythingyouwantmostpeopleuseinit takes nothing returns nothing
      set b[0] = 3
      set b[1] = b[0]*15
      call BJDebugMsg(I2S(a)) //prints 19
      set t = CreateTrigger() //fine to do this now
  endfunction
endlibrary

4. Manual section on 2-D arrays: JassHelper 0.A.0.0, yours would look something like this. AFAIK arrays can't be constant, since the constant keyword is really for things set in globals blocks that can be inlined by JASSHelper.
JASS:
globals
    private constant integer MUSICINDEXSIZE = 10 // Each key can only store indexSize number of values.
    private constant integer MUSICKEYSIZE = 4
    private string array MUSICPATHS //regular array
    private integer array MUSICLENGTHS [MUSICKEYSIZE][MUSICINDEXSIZE] //allows indexes [0-4][0-9]
endglobals

private function init takes nothing returns nothing
    local integer musicKey

    //don't forget JASS arrays start at 0, not 1...
    //so [4][<anything>] and [<anything>][10] are out of the array's bounds
    //I believe only the second will actually throw an error though

    set musicKey = 0
    set MUSICPATHS[musicKey] = "Music\\06 Pallet Town Theme.mp3"
    set MUSICLENGTHS[musicKey][0] = 0051
    set MUSICLENGTHS[musicKey][1] = 43886

    set musicKey = 3
    set MUSICPATHS[musicKey] = "Music\\08 Professor Oak's Laboratory.mp3"
    set MUSICLENGTHS[musicKey][0] = 1076
    set MUSICLENGTHS[musicKey][1] = 17138
endfunction
 
Last edited:
Level 12
Joined
Jun 15, 2016
Messages
472
A few questions:

1.) What is the scope of of the "global" variables? Are they actual global or only use-able in this library? If global, could I make them static private instead?
2.) When are the global variables created? On map init, or each time the library is used in real time?
3.) I want to initialize the variables to store data in them upon the map loading. It seems I can't do that within the global nest. What's the best way to init the variables?

If there are any tutorials you know of, I'd also be happy if you could share a link :)

Edit: I remembered someone saying vJass supports 2D arrays. Can someone show me the correct syntax for that so I don't use funky emulating 1D arrays anymore like shown above?

1. These variables are actually global. If you want to make them available to the library only you can use the private keyword to achieve that.
2. If I recall correctly, there is only one global block in the pure JASS map script. A part of the work done by JASShelper when precompiling is to merge your global block with the actual global block. In other words, the globals are created once during map initialization, but their values can of course be changed unless the have the constant keyword first.

3. That is because you're using the globals block wrong. The only thing inside the globals block should be the variable creation itself, and every line that starts with set should go in a trigger/function/everything that is not the global block. For that, you can use another neat aspect of vJASS libraries, and give your library the initializer keyword like this:

JASS:
library MusicLibrary initializer init

//************************************
// Variable Setup
//************************************


globals

    // Globals
    integer musicKey // Music Key. See "Music Mappings" for reference
    constant integer MUSICINDEXSIZE = 10 // Each key can only store indexSize number of values.
    constant string array MUSICPATHS
    constant integer array MUSICLENGTHS
    hashtable udg_TimerHash

endglobals


//************************************
// Function List
//************************************

    private function init takes nothing returns nothing
    
    // PUT ALL THE STUFF YOU NEED TO DO ON MAP INIT HERE

    set musicKey = 1
    set MUSICPATHS[musicKey] = "Music\\06 Pallet Town Theme.mp3"
    set MUSICLENGTHS[musicKey * MUSICINDEXSIZE + 1] = 0050
    set MUSICLENGTHS[musicKey * MUSICINDEXSIZE + 2] = 43886

    set musicKey = 4
    set MUSICPATHS[musicKey] = "Music\\08 Professor Oak's Laboratory.mp3"
    set MUSICLENGTHS[musicKey * MUSICINDEXSIZE + 1] = 1076
    set MUSICLENGTHS[musicKey * MUSICINDEXSIZE + 2] = 17138
    endfunction

endlibrary

Lastly, I dunno about 2D arrays, but there are 2 other nuggets I can give you:

1. This is the JASShelper manual and it contains information about all of the features in vJASS.
2. If you have an error in your script (or create one on purpose), you can actually see the entire script of your map (when the debugger shows you the line with the bug), and furthermore you'll see the code after it was precompiled. That means you get to see what your vJASS actually turns into. This can also be very helpful to catch problems, although you'll need to work a bit in order to make sense of it, especially at the start.
 
Status
Not open for further replies.
Top