| 08-09-2006, 03:17 AM | #1 |
I'm trying to figure out a way to build a unit group without leaks, but I'm stuck at the point of having to use a filter function and I'm not exactly sure how to go about it since there's no passing of variables to a filter function and hence no way of giving the filter function the unit I'm testing without assigning a global which seems a bit messy to me. JASS:function AssignAll takes nothing returns nothing local group ugroup = CreateGroup() local unit u call GroupEnumUnitsOfType(ugroup,"hmtt",null) loop set u = FirstOfGroup(ugroup) exitwhen u == null call AssignIndex(u) //DEBUG call DisplayTextToForce( GetPlayersAll(), "Assigning Index to: " + GetUnitName(u) ) //DEBUG call GroupRemoveUnit(ugroup, u) endloop call DestroyGroup(ugroup) set ugroup = null endfunction In the above code I tried to use GroupEnumUnitsOfType but apparantly the "Type" that their referring to is not unittype but something a bit broader, I'm curious if it's referring to unit types like "giant" or "ethereal". Finally, is there a standard way of doing this nowadays? |
| 08-09-2006, 03:22 AM | #2 |
JASS:local boolean B = IsUnitType(SomeLocalUnit,Unit_Type_Giant) == true or local boolexpr X = Condition(function some) DestroyBoolexpr(X) First is boolean with arguments second can be done from first by some funny way JASS:local boolexpr Z = And(null,X) this will parse arguments inside any function. |
| 08-09-2006, 03:42 AM | #3 |
DioD, can you please explain your answer a little clearer and make sure you understood my question correctly. I'm completely unsure of what you're referring to in your answer or what it accomplishes. Essentially my question is such... 1) How do I create a group of units containing every unit on the map of a certain unittype? 2) Can GroupEnumUnitsOfType be used to accomplish this, or is the type string that it recieves different from unittype? 3) If using either GroupEnumUnitsOfPlayer or GroupEnumUnitsInRect how do I use the filter boolexpr that it takes to check the type of the unit? Does this require a global to "pass" the unit I'm currently checking to the function? |
| 08-09-2006, 04:02 AM | #4 |
Functions used JASS:constant native GetUnitTypeId takes unit whichUnit returns integer constant native GetOwningPlayer takes unit whichUnit returns player native GroupEnumUnitsInRect takes group whichGroup, rect r, boolexpr filter returns nothing Trigger JASS:function FilterMain takes nothing returns boolean if GetUnitTypeId(GetFilterUnit()) == 'hpea' then if GetOwningPlayer(GetFilterUnit()) == Player(0) then return true endif endif return false endfunction call GroupEnumUnitsInRect(udg_Group,bj_mapInitialPlayableArea,Condition(function Filtermain)) it will be much more longer with local boolexpr. |
| 08-09-2006, 04:03 AM | #5 |
This will grab all footman units in the map. JASS:function GroupActions takes nothing returns nothing local group g=CreateGroup() local boolean b=GetUnitTypeId(GetFilterUnit())=='hfoo' call GroupEnumUnitsInRect(g,GetPlayableMapRect(),b) // Then the rest of your stuff endfunction Boolean Express way. JASS:function GroupBool takes nothing returns nothing return GetUnitTypeId(GetFilterUnit())=='hfoo' endfunction function GroupActions takes nothing returns nothing local group g=CreateGroup local boolexpr b=Condition(function GroupBool) local unit u call GroupEnumUnitsInRect(g,GetPlayableMapRect(),b) loop set u=FirstOfGroup(g) exitwhen u==null // Your actions call GroupRemoveUnit(g,u) endloop call DestroyGroup(g) call DestroyBoolExpr(b) set g=null set u=null set b=null endfunction On another note, I have a question of my own about a leak with the boolean. If I were to do this without using a local, would it leak? JASS:call GroupEnumUnitsInRect(g,GetPlayableMapRect(),Condition(function whatever)) |
| 08-09-2006, 04:17 AM | #6 |
Thanks both of you. I didn't initially realize the connection between GetFilterUnit() and GroupEnum and wanted to avoid using it at first. I suppose there's not much other choice. |
| 08-09-2006, 04:18 AM | #7 |
Data parsed to functions do not leak. (only strings cause it always leak) |
| 08-09-2006, 10:46 AM | #8 |
The string for the unittype of GroupEnumUnitsOfType can be found in UnitUI.slk or UnitData.slk. Example: JASS:call GroupEnumUnitsOfType(ugroup,"waterelemental",null) ... adds all water elementals to the group. |
| 08-09-2006, 02:31 PM | #9 | |
Quote:
If this is true then I should definatly be using GroupEnumUnitsOfType instead of: call GroupEnumUnitsInRect(g,GetPlayableMapRect(),b) But I do have a question, how would custom units be determined in this way? Do they not have a unit name at all, or do they use the unit name of their base unit? It also seems kindof weird that it would use a descriptive string name to filter by, especially since in the SLK that column is marked "comment(s)" implying it to be more of a descriptive field rather than a data field. |
| 08-09-2006, 03:30 PM | #10 |
Strings don't leak... |
| 08-09-2006, 10:04 PM | #11 |
It is not the comment(s) column. It's the name column in UnitUI.slk For customs you'd have to add that field to the unit editor to be able to change it. I think by default it inherits the value from the base unit. |
| 08-09-2006, 10:44 PM | #12 | |
Quote:
So am I right in thinking it would be more effecient than using the filter function? |
| 08-09-2006, 11:32 PM | #13 |
It would definitely be cleaner, but not really more efficient. You are still choosing units conditionally either way. BTW, you have to use a boolean express instead of a boolean. I made a bad post earlier in showing a way to use a local boolean. Just do the express way. |
| 08-10-2006, 11:55 AM | #14 | |
Quote:
Yes. It will still go through all units on the map but checking for the unit type is definitely faster than checking the in-rect-condition + a callback. |
| 08-10-2006, 01:20 PM | #15 | |
Quote:
I will return bug string, and string "waterelemental" will be returned from its ID. I have demo map for string leaks, it will kill any PC in few seconds. I will post it if some one need... |
