- Joined
- Jun 17, 2007
- Messages
- 1,433
Complete list of things that leak
This is a complete list of everything that leaks. I haven't found a complete tutorial elsewhere, so I decided to write my own.
- Unit Groups
- Locations
- Special Effects
- Player Groups
- Misc.
Unit Groups
GUI
Creating groups leaks, and thus we must find a way to prevent that. There is two options. The first of which is putting this line before using any group
- Custom script: set bj_wantDestroyGroup=true
-
Set Group = (Units in (Playable map area))
-
Unit Group - Pick every unit in Group and do (Actions)
-
Loop - Actions
- Unit - Remove (Picked unit) from the game
-
Loop - Actions
- Custom script: call DestroyGroup(udg_Group)
-
Unit Group - Pick every unit in Group and do (Actions)
JASS
JASS:
function GroupExample takes nothing returns nothing
local group g = CreateGroup()
local unit f
call GroupEnumUnitsInRange(x, y, 150, null)
loop
set f = FirstOfGroup(g)
exitwhen f == null
call KillUnit(f)
call GroupRemoveUnit(g, f)
endloop
call DestroyGroup(g)
endfunction
As you can see, groups in JASS aren't much of a problem. However, using a null boolexp also leaks. This can be solved two ways (one being clearly more ideal). The first of which is using a global boolexp that is always going to return true in place of null.
JASS:
function TrueBoolexpr takes nothing returns boolean
return true
endfunction
The other alternative is using the enum function to perform your actions. It might not make much sense, so here's an example:
JASS:
function BE takes nothing returns boolean
call RemoveUnit(GetFilterUnit())
return false
endfunction
function GroupExample takes nothing returns nothing
local group g = CreateGroup()
call GroupEnumUnitsInRange(x, y, 150, Filter(function BE))
call DestroyGroup(g)
endfunction
Locations
GUI
Locations (points) leak, and must be removed. They can be avoided all together in most situations for those who use JASS. Unfortunately, GUI users are not as lucky, and are forced to deal with them. Storing and removing a location variable is quite simple.
-
Set Loc = (Center of (Playable map area))
- Unit - Create 1 Footman for Player 1 (Red) at Loc facing Default building facing (270.0) degrees
- Custom script: call RemoveLocation(udg_Loc)
- Set Loc = (Position of (Triggering unit))
- Set Loc2 = (Loc offset by 256.00 towards 0.00 degrees)
- Unit - Create 1 Footman for Player 1 (Red) at Loc2 facing Default building facing (270.0) degrees
- Custom script: call RemoveLocation(udg_Loc)
- Custom script: call RemoveLocation(udg_Loc2)
JASS
JASS opens the user to the world of coordinates. This allows them to almost avoid the use of locations entirely.
JASS:
call CreateUnit(Player(0), 'h000', GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 270)
With the use of coordinates, we can easily shave off two lines. Easy, right? Locations can be converted to coordinates, and vice-versa.
JASS:
native Location takes real x, real y returns location
JASS:
native GetLocationX takes location whichLocation returns real
native GetLocationY takes location whichLocation returns real
It's also worth noting how to use 'Point with Polar Offset' in JASS.
JASS:
local real x2 = x + dist * Cos(angle * bj_DEGTORAD)
local real y2 = y + dist * Sin(angle * bj_DEGTORAD)
x2 and y2 become your x and y coordinates, with x and y the source coordinates.
Special Effects
GUI
Special effects leak, but they are by far the easiest to remove, without requiring any variable. They can be destroyed instantly, and in most cases will still play the animation.
- Special Effect - Create a special effect at (Center of (Playable map area)) using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
- Special Effect - Destroy (Last created special effect)
JASS
Special effects are even easier to destroy in JASS than they are in GUI. It doesn't even required an extra line.
JASS:
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl",x,y))
Player Groups
Player groups also leak, but are easier to deal with than unit groups. This is because (All Players) does not leak (bj_FORCE_ALL_PLAYERS in JASS). A variable can be assigned and than destroyed, just as with locations and groups.
-
Set PG = (All allies of Player 1 (Red))
-
Player Group - Pick every player in PG and do (Actions)
-
Loop - Actions
- Player - Change color of (Picked player) to Red, Changing color of existing units
-
Loop - Actions
- Custom script: call DestroyForce(udg_PG)
-
Player Group - Pick every player in PG and do (Actions)
Force 1:
Player 1
Player 2
Player 3
Force 2:
Player 4
Player 5
Player 6
The above example work perfectly.
Force 1:
Player 1
Player 2
Player 6
Force 2:
Player 4
Player 5
Player 3
The above example will not work.
To avoid the force, use a loop:
-
For each (Integer A) from 1 to 3, do (Actions)
-
Loop - Actions
- Player - Change color of (Player((Integer A))) to Red, Changing color of existing units
-
Loop - Actions
Misc.
Sounds
Sounds also leak. Prevent this by destroying them similar to the way locations are destroyed.
-
Sound - Play (Last played sound)
- Sound - Destroy (Last played sound)
Local handle variables
When using local handle variables in JASS, they cause a small leak. A handle is everything except real, string, integer, and boolean. If I'm not mistaken, this only occurs if the handle is ever destroyed or removed from the game. This means that if you are certain a handle will never cease to exist, it's safe not to null the variable. Althought players are handles, they should never need to be nulled.
JASS:
local unit u = GetTriggerUnit()
call SetUnitFacing(u, 270)
call SetUnitFlyHeight(u, 300, 50)
set u = null
This tutorial is basically done. I'll make any improvements that are required. There's bound to be a few, as I'm fairly tired while writing this.
Last edited by a moderator: