primitive: [ integer, real, boolean, string, code, handle, ], intresting: [ string, // any string when displayed can be colored using a code: |cffFF0000<this-text-will-be-displayed-in-red>|r unit, item, ability, buff, destructable, trigger, event, timer, timerdialog, rect, sound, camerasetup, effect, weathereffect, terraindeformation, fogmodifier, dialog, button, multiboard, multiboarditem, leaderboard, trackable, gamecache, texttag, lightning, image, <text-to-player>, // DisplayTimedTextToPlayer <cine-filter>, <cinematic-cine>, ], unintresting: [ player, // glorified integer agent, widget, force, group, triggercondition, triggeraction, quest, questitem, defeatcondition, location, region, boolexpr, conditionfunc, filterfunc, unitpool, itempool, ubersplat, hashtable, ], not-savable-in-hashtable: [ // code, // can't have code arrays (modulo bug) either so... camerasetup, weathereffect, terraindeformation, gamecache, ], enums: [ race, alliancetype, racepreference, gamestate, igamestate, fgamestate, playerstate, playerscore, playergameresult, unitstate, aidifficulty, eventid, gameevent, playerevent, playerunitevent, unitevent, limitop, widgetevent, dialogevent, unittype, gamespeed, gamedifficulty, gametype, mapflag, mapvisibility, mapsetting, mapdensity, mapcontrol, fogstate, playerslotstate, volumegroup, camerafield, playercolor, placement, startlocprio, raritycontrol, blendmode, texmapflags, effecttype, version, itemtype, attacktype, damagetype, weapontype, soundtype, pathingtype, ], @TODO: which of the handle extending types (non-enum) use handle-ids >= 0x00_10_00_00 and which use their own specific handle-id pool (e.g: texttag(s))
Like I said, the list is biased, but lets see:
uninteresting: [ // I don't see the point of this type not being an integer or implicitly convertable to one. // Its just annothing having to call GetPlayerId (player -> integer) and Player (integer -> player) // manually all the time. I think in SC2 this type is indeed an integer. player, // I don't know why this type was introduced when Blizzard made the hashtable natives. // It seems pretty pointless. agent, // Units, items and destructables are widgets... so we have inheritance there... I just don't like // inheritance (I do like tagged/discriminated unions =), instead), but at least its only 1 level // of inheritance (I guess Blizzard learned their lesson from SC1 :P). // So okay, maybe not that uninteresting. widget, // A non-random-access collection of player(s) with callback iteration... force, // A non-random-access collection of unit(s) with optional callback iteration, // slightly better than force, thanks to FirstOfGroup, but FirstOfGroup has // issues of its own (GroupRefresh), so yeah... not really interesting. group, // Removing an event listener (trigger)'s handler functions... triggercondition, triggeraction, // These are here because they are cumbersome to read when one wants to put // a lot of text in the quests menu. quest, questitem, defeatcondition, // I wish location was a primitive type (like integer/real), i.e not having to bother // calling RemoveLocation and nulling them, but they are not, which makes them annoying to use, // unfortunately. location, // Just because of the confusion it creates with using the event "unit enters rect". region, // Code pointing to a function with a boolean return value? boolexpr, conditionfunc, filterfunc, // I don't think Blizzard used these in WE's jass generation, I guess they are kind of // intersting from algorithmic point of view. unitpool, itempool, // Image, ubersplat, what's the difference? ubersplat, // I think we have to thank dota's ubiquitous use of gamecache (and not structs, I don't think "dota knows" what a struct is) // and the return bug for this overused type. It's occasionally useful, but not as interesting as gamecahe. hashtable, ],
function [URL='http://wiki.thehelper.net/wc3/jass/Blizzard.j/ForGroupBJ']ForGroupBJ[/URL] takes [URL='http://wiki.thehelper.net/wc3/jass/common.j/group']group[/URL] whichGroup, [URL='http://wiki.thehelper.net/wc3/jass/common.j/code']code[/URL] callback returns [URL='http://wiki.thehelper.net/wc3/jass/common.j/nothing']nothing[/URL] // If the user wants the group destroyed, remember that fact and clear // the flag, in case it is used again in the callback. local [URL='http://wiki.thehelper.net/wc3/jass/common.j/boolean']boolean[/URL] wantDestroy = [URL='http://wiki.thehelper.net/wc3/bj_wantDestroyGroup']bj_wantDestroyGroup[/URL] set [URL='http://wiki.thehelper.net/wc3/bj_wantDestroyGroup']bj_wantDestroyGroup[/URL] = false call [URL='http://wiki.thehelper.net/wc3/jass/common.j/ForGroup']ForGroup[/URL](whichGroup, callback) // If the user wants the group destroyed, do so now. if (wantDestroy) then call [URL='http://wiki.thehelper.net/wc3/jass/common.j/DestroyGroup']DestroyGroup[/URL](whichGroup) endif endfunction
function [URL='http://wiki.thehelper.net/wc3/jass/Blizzard.j/GetUnitsInRangeOfLocMatching']GetUnitsInRangeOfLocMatching[/URL] takes [URL='http://wiki.thehelper.net/wc3/jass/common.j/real']real[/URL] radius, [URL='http://wiki.thehelper.net/wc3/jass/common.j/location']location[/URL] whichLocation, [URL='http://wiki.thehelper.net/wc3/jass/common.j/boolexpr']boolexpr[/URL] filter returns [URL='http://wiki.thehelper.net/wc3/jass/common.j/group']group[/URL] local [URL='http://wiki.thehelper.net/wc3/jass/common.j/group']group[/URL] g = [URL='http://wiki.thehelper.net/wc3/jass/common.j/CreateGroup']CreateGroup[/URL]() call [URL='http://wiki.thehelper.net/wc3/jass/common.j/GroupEnumUnitsInRangeOfLoc']GroupEnumUnitsInRangeOfLoc[/URL](g, whichLocation, radius, filter) call [URL='http://wiki.thehelper.net/wc3/jass/common.j/DestroyBoolExpr']DestroyBoolExpr[/URL](filter) return g endfunction
Sounds can leak. Though, JASS is needed to really create new sounds, which happens automatically in background only once, when used in GUI. So one is safe in GUI.
There's no leak like this. There's nothing like a destructible group for storage, but only the mere enumeration of destructibles.By the way up to this day I'm still curious if Destructible Groups can leak.
function GetUnitsOfTypeIdAll takes integer unitid returns group local group result = CreateGroup() local group g = CreateGroup() local integer index set index = 0 loop set bj_groupEnumTypeId = unitid call GroupClear(g) call GroupEnumUnitsOfPlayer(g, Player(index), filterGetUnitsOfTypeIdAll) call GroupAddGroup(g, result) set index = index + 1 exitwhen index == bj_MAX_PLAYER_SLOTS endloop call DestroyGroup(g) return result endfunction
is this similar to picking all units in the map and adding condition to only get Footman units?
function GetUnitsInRectMatching takes rect r, boolexpr filter returns group local group g = CreateGroup() call GroupEnumUnitsInRect(g, r, filter) call DestroyBoolExpr(filter) return g endfunction
As there are so many GUI functions with reference leaks included I decided not to give some a special platform, even 2 of ref leaks are included, and just mentioned:but this wasn't mentioned/missing at the main post,
For now it looks like you maybe meant only to have one random location, So eaither point_x, or point_y, should be enough.How many variables do I need to define (and then remove) here?
Yes you need to destroy the group, that will be used in condition. Ste the group to a variable, before you use the condition to count units. And destroy after:I suppose that you need to create a temporary variable for UnitGroup (it wouldn't be freed automatically) and "destroying" int_i does not accomplish anything (if it is even possible)?
That's a pure integer comparisons, which don't leak. And getting the level of ability does not create an internal leak, too. It's leak-safe!Another question: what's about leaks in conditions? I have a trigger with the following condition:
- (Level of Some_Ability for (Reviving Hero)) Greater than or equal to 1
do I need to change something here?
Let's assume that I need two different random points and a region for some esoteric reason (to make more nested brackets here; I agree that this is not the best way to accomplish this).For now it looks like you maybe meant only to have one random location, So eaither point_x, or point_y, should be enough.
Is a new region required per se, or you only need it for the centered creation?