• 🏆 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!

[JASS] Having trouble with Unit Groups in JASS

Status
Not open for further replies.
Level 4
Joined
Jan 19, 2008
Messages
69
I'm trying to create a spring that will launch a specific unit type up in the air once it gets close (provided that certain conditions are met). Once the spring has activated it will be disabled for a few seconds. I've already created a system that handles the movement for the launch.

I'll try to explain what I've attempted to do below:
Once the specific unit type gets close to a spring the trigger calls GroupEnumUnitsInRange to find a nearby spring. This was supposed to be done by filtering all the units of a specific type (the spring) and only units that have 100 mana (I intended to use mana as a method of deciding whether or not the spring would be ready to launch the unit).

JASS:
function GroupFilter takes nothing returns boolean
    return GetUnitTypeId(GetFilterUnit()) == 'n002'
endfunction

function Trig_Collision_Spring_Actions takes nothing returns nothing
    local real x = GetUnitX(GetTriggerUnit())
    local real y = GetUnitY(GetTriggerUnit())
    local integer i = GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))
    local group g = CreateGroup()
    if (GetUnitTypeId(GetTriggerUnit()) == 'e000' and udg_BOOLEAN_PlayerStatus[i] == false) then
        call GroupEnumUnitsInRange(g, 125, x, y, Filter(function GroupFilter))
        call DestroyGroup(g)
        set g = null
    endif
endfunction

If the picked unit is a spring and it currently has 100 mana this should run:
JASS:
        if (udg_REAL_Gravity[i] == 0.50) then
            set udg_REAL_VerticalSpeed[i] = 15.00
        else
            set udg_REAL_VerticalSpeed[i] = -15.00
        endif

Now the problem is that I don't much about Unit Groups in JASS (or JASS in general, I suppose). Currently the filter only checks for the spring's rawcode - how would I get it to for check mana aswell? Can a single filter function return multiple booleans? Also, how would I go about incorporating the actions? And last, would there be a better/easier way of doing this?
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
return GetUnitTypeId(GetFilterUnit()) == 'n002' and GetUnitState(GetFilterUnit(), UNIT_STATE_MANA) >= 100
 
Level 4
Joined
Jan 19, 2008
Messages
69
Thanks to both of you!

Still I'm wondering how I should get this to run when all the conditions are met?
JASS:
if (udg_REAL_Gravity[i] == 0.50) then
            set udg_REAL_VerticalSpeed[i] = 15.00
        else
            set udg_REAL_VerticalSpeed[i] = -15.00
        endif

Should I put the actions be in the filter?
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Thanks to both of you!

Still I'm wondering how I should get this to run when all the conditions are met?
JASS:
if (udg_REAL_Gravity[i] == 0.50) then
            set udg_REAL_VerticalSpeed[i] = 15.00
        else
            set udg_REAL_VerticalSpeed[i] = -15.00
        endif

Should I put the actions be in the filter?

they should just be inside of the if-then-else...
 
Level 4
Joined
Jan 19, 2008
Messages
69
Like this?

JASS:
function GroupFilter takes nothing returns boolean
    local integer i = GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))
    return GetUnitTypeId(GetFilterUnit()) == 'n002' and GetUnitState(GetFilterUnit(), UNIT_STATE_MANA) >= 100
endfunction

function Trig_Collision_Spring_Actions takes nothing returns nothing
    local real x = GetUnitX(GetTriggerUnit())
    local real y = GetUnitY(GetTriggerUnit())
    local integer i = GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))
    local group g = CreateGroup()
    if (GetUnitTypeId(GetTriggerUnit()) == 'e000' and udg_BOOLEAN_PlayerStatus[i] == false) then
        set udg_REAL_VerticalSpeed[i] = 15.00
        call GroupEnumUnitsInRange(g, 125, x, y, Filter(function GroupFilter))
        if (udg_REAL_Gravity[i] == 0.50) then
            set udg_REAL_VerticalSpeed[i] = 15.00
        else
            set udg_REAL_VerticalSpeed[i] = -15.00
        endif
        call DestroyGroup(g)
        set g = null
    endif
endfunction

//===========================================================================
function InitTrig_Collision_Spring takes nothing returns nothing
    set gg_trg_Collision_Spring = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Collision_Spring, function Trig_Collision_Spring_Actions )
endfunction
If so, then it's not what I intended to do. Currently the unit is being launched regardless of the spring's mana.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
oh your trying to launch the enum'd units?

JASS:
    if GetUnitTypeId(GetFilterUnit()) == 'n002' and GetUnitState(GetFilterUnit(), UNIT_STATE_MANA) >= 100 then
          (do whatever you wanted to do)
   endif
   return false
 
Level 4
Joined
Jan 19, 2008
Messages
69
I'm sorry to keep bothering you :<

What I'm trying to do is launch the triggering unit if the enum'd unit meets the conditions (is a spring and has 100 mana).

So this is the movement-related stuff that launches the triggering unit:
JASS:
        if (udg_REAL_Gravity[i] == 0.50) then
            set udg_REAL_VerticalSpeed[i] = 15.00
        else
            set udg_REAL_VerticalSpeed[i] = -15.00
        endif
It should run once the enum'd unit has been confirmed to meet the conditions. Thank you once again for the help.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
JASS:
function GroupFilter takes nothing returns boolean
    return GetUnitTypeId(GetFilterUnit()) == 'n002' and GetUnitState(GetFilterUnit(), UNIT_STATE_MANA) >= 100
endfunction

function Trig_Collision_Spring_Actions takes nothing returns nothing
    local real x = GetUnitX(GetTriggerUnit())
    local real y = GetUnitY(GetTriggerUnit())
    local integer i = GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))
    local group g = CreateGroup()
    if (GetUnitTypeId(GetTriggerUnit()) == 'e000' and udg_BOOLEAN_PlayerStatus[i] == false) then
        set udg_REAL_VerticalSpeed[i] = 15.00
        call GroupEnumUnitsInRange(g, 125, x, y, Filter(function GroupFilter))
        if (udg_REAL_Gravity[i] == 0.50) and CountUnitsInGroup(g) != 0 then
            set udg_REAL_VerticalSpeed[i] = 15.00
        else
            set udg_REAL_VerticalSpeed[i] = -15.00
        endif
        call DestroyGroup(g)
        set g = null
    endif
endfunction

//===========================================================================
function InitTrig_Collision_Spring takes nothing returns nothing
    set gg_trg_Collision_Spring = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Collision_Spring, function Trig_Collision_Spring_Actions )
endfunction
 
Level 4
Joined
Jan 19, 2008
Messages
69
Alright, I've run across a new problem... This is the current code:

JASS:
function GroupFilter takes nothing returns boolean
    return GetUnitTypeId(GetFilterUnit()) == 'n002' and GetUnitState(GetFilterUnit(), UNIT_STATE_MANA) >= 100
endfunction

function Trig_Collision_Spring_Actions takes nothing returns nothing
    local real x = GetUnitX(GetTriggerUnit())
    local real y = GetUnitY(GetTriggerUnit())
    local integer i = GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))
    local group g = CreateGroup()
    local unit u
    if (GetUnitTypeId(GetTriggerUnit()) == 'e000' and udg_BOOLEAN_PlayerStatus[i] == false) then
        set udg_REAL_VerticalSpeed[i] = 15.00
        call GroupEnumUnitsInRange(g, 125, x, y, Filter(function GroupFilter))
        if CountUnitsInGroup(g) != 0 then
            set u = GroupPickRandomUnit(g)
            call SetUnitManaBJ(u, 0 )
            if (udg_REAL_Gravity[i] == 0.50) then
                set udg_REAL_VerticalSpeed[i] = 15.00
            else
                set udg_REAL_VerticalSpeed[i] = -15.00
            endif
        endif
        call DestroyGroup(g)
        set g = null
    endif
endfunction

//===========================================================================
function InitTrig_Collision_Spring takes nothing returns nothing
    set gg_trg_Collision_Spring = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Collision_Spring, function Trig_Collision_Spring_Actions )
endfunction

Everything is working properly except for the fact that the triggering unit is being launched even though the spring's mana is less than 100. Being launched by the spring does infact set the spring's mana to 0 so I'm kinda puzzled as to what might cause the problem.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
GroupPickRandomUnit > FirstOfGroup
SetUnitManaBJ > SetUnitMana

which unit is the "spring" and which is the unit being launched?
 
Level 4
Joined
Jan 19, 2008
Messages
69
What the schnitzel..

EDIT: Alright so I tried a couple of things. The filter is definitly working.
JASS:
if CountUnitsInGroup(g) != 0 then
I believe the problem is with this line. The actions below are being executed even though the amount of units in g is 0.

Also I can't seem to get the SetUnitMana function to work without giving me script errors.

JASS:
function GroupFilter takes nothing returns boolean
    return GetUnitTypeId(GetFilterUnit()) == 'n002' and GetUnitState(GetFilterUnit(), UNIT_STATE_MANA) == 100
endfunction

function Trig_Collision_Spring_Actions takes nothing returns nothing
    local real x = GetUnitX(GetTriggerUnit())
    local real y = GetUnitY(GetTriggerUnit())
    local integer i = GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))
    local group g = CreateGroup()
    local unit u
    if (GetUnitTypeId(GetTriggerUnit()) == 'e000' and udg_BOOLEAN_PlayerStatus[i] == false) then
        call GroupEnumUnitsInRange(g, 125, x, y, Filter(function GroupFilter))
        call DisplayTextToForce( GetPlayersAll(), I2S(CountUnitsInGroup(g)) )
        if CountUnitsInGroup(g) != 0 then
            set u = FirstOfGroup(g)
            call SetUnitManaBJ(u, 0 )
            if (udg_REAL_Gravity[i] == 0.50) then
                set udg_REAL_VerticalSpeed[i] = 15.00
            else
                set udg_REAL_VerticalSpeed[i] = -15.00
            endif
        endif
        call DestroyGroup(g)
        set g = null
        set u = null
    endif
endfunction

//===========================================================================
function InitTrig_Collision_Spring takes nothing returns nothing
    set gg_trg_Collision_Spring = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Collision_Spring, function Trig_Collision_Spring_Actions )
endfunction
 
Last edited:
Level 4
Joined
Jan 19, 2008
Messages
69
I have solved it. Turns out the problem actually was the filter. There are multiple springs on the map and because the filter itself didn't check for the distance between triggering unit and spring it resulted in g never being == 0. I suppose the filter would've worked with only one spring, which explains why it would work for you Arhowk. Thanks for all the help you provided.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
I have solved it. Turns out the problem actually was the filter. There are multiple springs on the map and because the filter itself didn't check for the distance between triggering unit and spring it resulted in g never being == 0. I suppose the filter would've worked with only one spring, which explains why it would work for you Arhowk. Thanks for all the help you provided.

referring to your SetUnitMana syntax errors, the arguments are flipped.

so SetUnitManaBJ(unit,mana) would be SetUnitMana(mana,unit)
 
Status
Not open for further replies.
Top