• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Missing Something?

Status
Not open for further replies.
Level 26
Joined
Aug 18, 2009
Messages
4,097
ForGroup respectively ForGroupBJ takes a function pointer as 2nd argument. So you have to write another function that takes and returns nothing and does what you want.

JASS:
function abc takes nothing returns nothing
    call GroupAddUnitSimple( GetEnumUnit(), UG_TMP )
endfunction

...
    call ForGroupBJ( GetUnitsInRectAll(RectFromCenterSizeBJ(GetUnitLoc(GetTriggerUnit()), 900.00, 900.00)), function abc )

Of course, thus, you have to pass your UG_TMP group globally.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
The code callback should not require parameters.
ForGroupBJ(Group,function FunctionName)
 
Level 9
Joined
Nov 19, 2011
Messages
516
ForGroup respectively ForGroupBJ takes a function pointer as 2nd argument. So you have to write another function that takes and returns nothing and does what you want.

JASS:
function abc takes nothing returns nothing
    call GroupAddUnitSimple( GetEnumUnit(), UG_TMP )
endfunction

...
    call ForGroupBJ( GetUnitsInRectAll(RectFromCenterSizeBJ(GetUnitLoc(GetTriggerUnit()), 900.00, 900.00)), function abc )

Of course, thus, you have to pass your UG_TMP group globally.

Hmm.. Any idea how I can keep it local then?
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
You could use FirstOfGroup and a loop to iterate through the units stored on the group.

EDIT: Sample
JASS:
function Test takes nothing returns nothing
    local group g = CreateGroup()
    local unit  u = null
    // populate group
    loop
    set u = FirstOfGroup(g)
    exitwhen u==null
        // Do Actions Here
    call GroupRemoveUnit(g,u)
    endloop
    
    // Cleanup, You could also use a global group
    // if you don't want to use a dynamic(local) one.
    call DestroyGroup(g)
    set g = null
    set u = null
endfunction
 
You won't find much documentation on Blizzard's functions aside from the GUI documentation/little notes in common.j or blizzard.j. A lot of the stuff is figured out through trial and error. However, I'll throw a quick documentation of the functions your way since the group API is easy. Here is the group API:
JASS:
//============================================================================
// Group API
//
native CreateGroup                          takes nothing returns group
native DestroyGroup                         takes group whichGroup returns nothing
native GroupAddUnit                         takes group whichGroup, unit whichUnit returns nothing
native GroupRemoveUnit                      takes group whichGroup, unit whichUnit returns nothing
native GroupClear                           takes group whichGroup returns nothing
native GroupEnumUnitsOfType                 takes group whichGroup, string unitname, boolexpr filter returns nothing
native GroupEnumUnitsOfPlayer               takes group whichGroup, player whichPlayer, boolexpr filter returns nothing
native GroupEnumUnitsOfTypeCounted          takes group whichGroup, string unitname, boolexpr filter, integer countLimit returns nothing
native GroupEnumUnitsInRect                 takes group whichGroup, rect r, boolexpr filter returns nothing
native GroupEnumUnitsInRectCounted          takes group whichGroup, rect r, boolexpr filter, integer countLimit returns nothing
native GroupEnumUnitsInRange                takes group whichGroup, real x, real y, real radius, boolexpr filter returns nothing
native GroupEnumUnitsInRangeOfLoc           takes group whichGroup, location whichLocation, real radius, boolexpr filter returns nothing
native GroupEnumUnitsInRangeCounted         takes group whichGroup, real x, real y, real radius, boolexpr filter, integer countLimit returns nothing
native GroupEnumUnitsInRangeOfLocCounted    takes group whichGroup, location whichLocation, real radius, boolexpr filter, integer countLimit returns nothing
native GroupEnumUnitsSelected               takes group whichGroup, player whichPlayer, boolexpr filter returns nothing

native GroupImmediateOrder                  takes group whichGroup, string order returns boolean
native GroupImmediateOrderById              takes group whichGroup, integer order returns boolean
native GroupPointOrder                      takes group whichGroup, string order, real x, real y returns boolean
native GroupPointOrderLoc                   takes group whichGroup, string order, location whichLocation returns boolean
native GroupPointOrderById                  takes group whichGroup, integer order, real x, real y returns boolean
native GroupPointOrderByIdLoc               takes group whichGroup, integer order, location whichLocation returns boolean
native GroupTargetOrder                     takes group whichGroup, string order, widget targetWidget returns boolean
native GroupTargetOrderById                 takes group whichGroup, integer order, widget targetWidget returns boolean

// This will be difficult to support with potentially disjoint, cell-based regions
// as it would involve enumerating all the cells that are covered by a particularregion
// a better implementation would be a trigger that adds relevant units as they enter
// and removes them if they leave...
native ForGroup                 takes group whichGroup, code callback returns nothing
native FirstOfGroup             takes group whichGroup returns unit

FunctionDescription
CreateGroupCreates a new group handle.
DestroyGroupDestroys a group handle.
GroupAddUnitAdds a unit to the group's list of units.
GroupRemoveUnitRemoves a unit from the group's list of units.
GroupClearRemoves all units from the group.
GroupEnum FunctionsThese functions clear the group, and then pick the units
depending on the native used. The units are then passed to the
filter. If the filter returns true for that unit, the unit is added.
The filter unit can be referred to through GetFilterUnit().
Else, it is not added.
GroupEnumUnitsOfTypeGroups units of a particular type, based on a given unit name.
GroupEnumUnitsOfPlayerGroups all units of a player.
GroupEnumUnitsOfTypeCountedGroups units of a particular type, but limits the number
of units in the group.
GroupEnumUnitsInRectGroups the units within a rect.
GroupEnumUnitsInRectCountedGroups the units within a rect, but limits the number
of units in the group.
GroupEnumUnitsInRangeGroups all units within radius of the coordinates (x, y).
GroupEnumUnitsInRangeOfLocGroups all units within radius of the location.
GroupEnumUnitsInRangeCountedGroups all units within radius of the coordinates,
but limits the number of units in the group.
GroupEnumUnitsInRangeOfLocCountedGroups all units within radius of the location,
but limits the number of units in the group.
GroupEnumUnitsSelectedGroups the units that are selected by the player.
Group Order FunctionsOrders the entire group to carry out an order. It will
either be a string order (e.g. "smart", "stormbolt", etc.)
or an integer order (see Order Id List). Returns whether
the order was successful. (assumed)
GroupImmediateOrderOrders the entire group an immediate order (e.g. "stop").
GroupImmediateOrderByIdOrders the entire group an immediate order by ID.
GroupPointOrderIssues a group order towards a point.
GroupPointOrderLocIssues a group order towards a location.
GroupPointOrderByIdIssues a group order by ID towards a point.
GroupPointOrderByIdLocIssues a group order by ID towards a location.
GroupTargetOrderIssues a group order towards a widget.
GroupTargetOrderByIdIssues a group order by ID towards a widget.
Iteration FunctionsAssist in iterating through groups.
ForGroupIterates through the group on a separate thread
in a separate function. The picked unit can be referred to
through GetEnumUnit().
FirstOfGroupRefers to the first unit in the group's list. Returns the same unit
each time, unless the unit is removed from the group.

Note: The radius-based enumeration functions will exclude units that have the ability locust ('Aloc').

Here are examples of different group iteration methods. There are 3 standard implementations that serve different purposes:
  1. Iterating through a group's filter (can both preserve and clear group)
  2. Iterating through a ForGroup() (preserves the group, unless you remove the units explicitly)
  3. Iterating through FirstOfGroup() (clears the group)

JASS:
globals 
    group g = CreateGroup()
    integer tempId = 0
endglobals

function GroupFilter takes nothing returns boolean
    if GetUnitTypeId(GetFilterUnit()) == tempId then
        call KillUnit(GetFilterUnit())
        return true // adds the filter unit to the group
    endif
    return false // does not add the unit to the group
endfunction

function KillUnitsOfTypeInRange takes integer id, real x, real y, real radius returns nothing 
    set tempId = id // store 'id' in a global so we can reference it in the filter
    call GroupEnumUnitsInRange(g, x, y, radius, Filter(function GroupFilter))
endfunction
JASS:
globals 
    group g = CreateGroup()
    integer tempId = 0
endglobals

function GroupFilter takes nothing returns boolean
    return GetUnitTypeId(GetFilterUnit()) == tempId
endfunction

function GroupIterate takes nothing returns nothing 
    call KillUnit(GetEnumUnit())
endfunction

function KillUnitsOfTypeInRange takes integer id, real x, real y, real radius returns nothing 
    set tempId = id // store 'id' in a global so we can reference it in the filter
    call GroupEnumUnitsInRange(g, x, y, radius, Filter(function GroupFilter))
    call ForGroup(g, function GroupIterate)
endfunction
JASS:
globals 
    group g = CreateGroup()
endglobals

function KillUnitsOfTypeInRange takes integer id, real x, real y, real radius returns nothing 
    local unit fog
    call GroupEnumUnitsInRange(g, x, y, radius, null)
    loop
        set fog = FirstOfGroup(g) // first of group
        exitwhen fog == null
        if GetUnitTypeId(fog) == id then // perform checks within the loop
            call KillUnit(fog)
        endif
        call GroupRemoveUnit(g, fog) // remove unit, FirstOfGroup() -> next unit
    endloop
endfunction

I couldn't perform proper tests so some of the information is assumed (with reason)/off memory. However, hopefully this will serve as a nice reference for you to work off of.
 
Level 9
Joined
Nov 19, 2011
Messages
516
Depending on the depths you go, you should not need to keep the parameters local. As long as you do not nest calls of the same function and the function executes atomically with other functions that use the global it is as good as using a local.

I am afraid that I am forced to use local. I am trying to create custom poison spell. I could do the same with Roar, but then its not count it as kill. :( Thanks a lot anyway.
 
Status
Not open for further replies.
Top