HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Seeking help with JASS.

03-24-2007, 11:08 PM#1
Valaran
EDIT: Thanks for moving the thread.
If you do not want to read my lifestory jump down a few lines

Hello, I'm new to these forums, in fact, I'm new to the whole map-making thing. Anyway, as soon as I started, I realized that I wasn't to fond of the GUI in the Wc3 WE. Obviously JASS was my way to go. Anyway, after reading numerous of beginner tutorials found on this forum (Thank you) I still find no info regarding my issue. or well... its probably some error I made somewhere... anyway to the point.

Problem!

Just to show you were I'm standing right now:
My initialize function, basicly sets the following globals and moves on..

Collapse JASS:
globals
    group array             udg_sg
    location array          udg_sNC
endglobals

function Trig_Init_Actions takes nothing returns nothing
    call ConditionalTriggerExecute( gg_trg_sNI )
endfunction

//===========================================================================
function InitTrig_Init takes nothing returns nothing
    set gg_trg_Init = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Init, function Trig_Init_Actions )
endfunction

In this part the problems shows up, read below for description.

Collapse JASS:
function Trig_sNI_Func001C takes nothing returns boolean
    return ( GetOwningPlayer(GetFilterUnit()) == Player(PLAYER_NEUTRAL_PASSIVE) )
endfunction

function Trig_sNI_Func001A takes nothing returns nothing
    local unit         u = GetEnumUnit()
    local group        g = udg_sg[0]
    local integer      a = CountUnitsInGroup(g)
    
    call GroupAddUnitSimple( u, g )
    set udg_sNC[a] = GetUnitLoc(u)
    call DisplayTextToPlayer( Player(0),0,0,(I2S(a) + ". " + GetUnitName(u)) )
endfunction

function Trig_sNI_Actions takes nothing returns nothing
    call ForGroupBJ( GetUnitsInRangeOfLocMatching(3500.00, GetUnitLoc(gg_unit_h000_0003), Condition(function Trig_sNI_Func001C)), function Trig_sNI_Func001A )
endfunction

//===========================================================================
function InitTrig_sNI takes nothing returns nothing
    set gg_trg_sNI = CreateTrigger(  )
    call TriggerAddAction( gg_trg_sNI, function Trig_sNI_Actions )
endfunction

Collapse JASS:
call GroupAddUnitSimple( u, g )

This function is supposed to add designated unit to designated group, right?
Well, it doesn't, or to be more precise, its like it doesn't find the globals I set earlier.

I did some experimenting, and by setting the global udg_sg (UnitGroup global) in the variables window, it does work... am I declaring the global variables in the wrong place? since they are not getting through correctly when I set them like I do.

NOTE: I'm using Vexorian's Jass NewGen Pack v2

P.S: While I'm at it, is there anyway to convert a point (location) to string, for message purposes?
03-24-2007, 11:14 PM#2
Vexorian
You are not ever initializing the variables, how do you expect to use them? It is causing a thread crash.

Also, one purpose of the global declaration syntax is to stop the necessity of the udg_ prefix
03-24-2007, 11:20 PM#3
Valaran
Could you specify what you mean please, as I said, I'm quiet new to this. and the linking of the globals above, is just the globals, nothing of the actual function, if that is of any matter..
Also, the udg_ prefix, I just find it easier to remember them that way :) and thanks for such a quick reply.
EDIT: put the whole "Init" function into the first JASS quoting.
03-24-2007, 11:21 PM#4
wyrmlord
Quote:
Originally Posted by Valaran
P.S: While I'm at it, is there anyway to convert a point (location) to string, for message purposes?

For message purposes, a location is a point made up of 3 coordinates. Those coordinates are X/Y/Z (usually you'll only need X/Y coordinates). You have 3 functions to get the X/Y/Z coordinates of a location: GetLocationX, GetLocationY, and GetLocationZ. For each of those real values, all you need to do is simply use the R2S function and you'll have strings ready to be displayed.

Quote:
Originally Posted by Valaran
Could you specify what you mean please, as I said, I'm quiet new to this. and the linking of the globals above, is just the globals, nothing of the actual function, if that is of any matter..
And thanks for such a quick reply.

In other words, the variable needs to have a value before you can use it. If you want to use a global as a group, you need to set the variable to the group returned by the CreateGroup function. The reason for this is that you're not adding the units to the variable, but instead a group.
03-24-2007, 11:33 PM#5
Valaran
Soo basicly what I forgot was something like
Collapse JASS:
set udg_sg[0]   = CreateGroup(  )

To actually create the group?
or did I missunderstand again, I'm sorry for being such a let down ._.

DoubleEdit:
Thank you that worked great, I'll probably be back with new questions soon :)
Is there any way to create multidimensional arrays?
03-24-2007, 11:57 PM#6
Jazradel
Not really, but vJass lets you extend an array. You'd have to look at the documentation for that I'm not sure of the exact details.

Or you basically have to use a 1 dimensional array:
a[i][n] = a[i*(no of elements of n)+n]
03-25-2007, 12:02 AM#7
Valaran
Thank you, that was helpful aswell, onto the next thing :)

Collapse JASS:
call ForGroupBJ( CONDITION, function Trig_Name_Action)

Is there any way I can pass a variable to Trig_Name_Action through a call like this?
Collapse JASS:
call ForGroupBJ( CONDITION, function Trig_Name_Action(PassedVar) )

Obviously doesn't work, is there any other ways round it?
03-25-2007, 12:29 AM#8
wyrmlord
You cannot pass a parameter in that case. Also, I would recommend using ForGroup instead of ForGroupBJ. All you have to do is remove the BJ and swap the order of the parameters. Also, what you have labeled as "CONDITION" is really a group.
03-25-2007, 12:33 AM#9
Valaran
Haha, indeed I labeled it condition ._. must be because I used a conditional loop thing initially... or maybe its just getting late, anyway thanks once again, and is there any clear reason for using ForGroup instead of ForGroupBJ? just curious.
03-25-2007, 12:36 AM#10
wyrmlord
Here's the ForGroupBJ function:
Collapse JASS:
function ForGroupBJ takes group whichGroup, code callback returns nothing
    // If the user wants the group destroyed, remember that fact and clear
    // the flag, in case it is used again in the callback.
    local boolean wantDestroy = bj_wantDestroyGroup
    set bj_wantDestroyGroup = false

    call ForGroup(whichGroup, callback)

    // If the user wants the group destroyed, do so now.
    if (wantDestroy) then
        call DestroyGroup(whichGroup)
    endif
endfunction
As you can see, it does more than necessary.
03-25-2007, 12:43 AM#11
Valaran
Most interesting, and indeed, it sure does more than needed.
Anyway thanks again, and by the way, should I updated my old replies with new questions, or does it matter if I reply with new ones all along?
03-25-2007, 12:47 AM#12
The)TideHunter(
To pass variables like that, you could use Return bug and multiple methods, such as gamecache, dynamic arrays, and even structs.
I'm sticking with gamecache though cause i find it easier to set up.

You can use this method:
If you add the following code inside your maps main script section, and then you can use it to store values using handles reference as a key.
For this, you obviously need a gamecache.
So create a gamecache variable, call it whatever, say udg_GameCache
Collapse JASS:
function Cache takes nothing returns gamecache
    if(udg_GameCache==null)then
        call FlushGameCache(InitGameCache("Cache"))
        set udg_GameCache=InitGameCACHE("Cache"))
    endif
    return udg_GameCache
endfunction

function HtoI takes handle h returns integer
    return h
    return 0
endfunction

function ItoUnit takes integer i returns unit
    return i
    return null
endfunction

Then, on your function:

Collapse JASS:
function FreshPajamas takes nothing returns nothing
    local unit u = ItoUnit(GetStoredInteger(Cache(),I2S(HtoI(bj_groupLastCreatedDest)),"SomeEnumKk")
endfunction

...
    call ForGroupBJ( CONDITION, function FreshPajamas)
    set bj_groupLastCreatedDest=CONDITION
    call StoreInteger(Cache(),I2S(HtoI(bj_groupLastCreatedDest)),"SomeEnumKk",HtoI(TheUnitIWantToPass))
...

You can also to, say attach a unit, and get it back in another function
03-25-2007, 12:53 AM#13
Pyrogasm
There is an easy way to pass things from a function into a loop that imitates a ForGroup() call. You'll need another group and a free unit variable; here's the outline for it:
Collapse JASS:
loop
    set u = FirstOfGroup(g) //u being the unit variable and g being our group
    exitwhen u == null //So we can exit when the group is empty
    //Do some stuff with u
    GroupRemoveUnit(g, u) //Removing it from the group
endloop

With this function, you can imitate the ForGroup() and pass variables to it. Albeit it is a bit slow and you can't use the ExecuteFunc() native with it (tutorial here).

Just put the above outline in place of your ForGroup() call, and go from there. You should be able to figure out how to apply it to your function.

A few other things you could change:
DisplayTextToPlayer( Player(0),0,0,(I2S(a) + ". " + GetUnitName(u)) ) could be replaced with the BJDebugMsg() native. If, as I am assuming you're doing, you need to debug something, this function allows you to type less
call GroupAddUnitSimple( u, g ) should be replaced with call GroupAddUnit( g, u), seeing as it is the native.


EDIT:
Quote:
Originally Posted by Valaran
Anyway thanks again, and by the way, should I updated my old replies with new questions, or does it matter if I reply with new ones all along?
Just pile the questions on; we all like to help :D

And Tide, I think my solution owns yours.
03-25-2007, 12:55 AM#14
The)TideHunter(
Quote:
Originally Posted by Pyrogasm
There is an easy way to pass things from a function into a loop that imitates a ForGroup() call. You'll need another group and a free unit variable; here's the outline for it:
Collapse JASS:
loop
    set u = FirstOfGroup(g) //u being the unit variable and g being our group
    exitwhen u == null //So we can exit when the group is empty
    //Do some stuff with u
    GroupRemoveUnit(g, u) //Removing it from the group
endloop

With this function, you can imitate the ForGroup() and pass variables to it. Albeit it is a bit slow and you can't use the ExecuteFunc() native with it (tutorial here).

You should be able to figure out how to apply it to your function.

A few other things you could change:
DisplayTextToPlayer( Player(0),0,0,(I2S(a) + ". " + GetUnitName(u)) ) could be replaced with the BJDebugMsg() native. If, as I am assuming you're doing, you need to debug something, this function allows you to type less
call GroupAddUnitSimple( u, g ) should be replaced with call GroupAddUnit( g, u), seeing as it is the native.

I do agree, i never use ForGroup, i just don't like having to create a new function for some actions, i always use to loop too. Still does the job fine.
03-25-2007, 01:06 AM#15
Pyrogasm
It is pretty useful for running parallel threads for units, etc. though.