Wie einige von euch vermutlich bereits wissen, verursachen Einheitengruppen Memory Leaks, wenn sie nicht zerstört werden( DestroyGroup ). Jedoch muss man dadurch immer wieder eine neue Gruppe erstellen – was ein wenig Zeit benötigt – und unter gewissen Umständen können auch durch das Zerstören Memory Leaks übrig bleiben.
Die Lösung dafür ist eine globale Gruppe (wie man sie z.B. in
GroupUtils zur Verfügung gestellt wird -> ENUM_GROUP ), die wir dann nur leeren müssen ( ClearGroup ) und uns somit das dauernde Erstellen/Zerstören, was v.a. bei periodischen Dingen vorkommen kann, ersparen.
Beispiel von Themerion:
scope GroupEx
globals
private group tempGroup
endglobals
function DoSomething takes nothing returns nothing
call ClearGroup(tempGroup)
call GroupEnumUnitsInRange(tempGroup,X,Y,500,null)
call GroupIssuePointOrder(tempGroup,0,0,"attack")
endfunction
public function InitTrig takes nothing returns nothing
set tempGroup=CreateGroup()
endfunction
endscope
Manchmal hat man mit nur einer Gruppe natürlich nicht genug, jedoch kann man sich einfach einen eigenen GroupStack basteln.
Beispiel von Themereion:
struct Data
group g
method create takes nothing returns Data
local Data d=Data.allocate()
if d.g==null then
set d.g=CreateGroup()
endif
return d
endmethod
method onDestroy takes nothing returns nothing
call GroupClear(.g)
endmethod
endstruct
oder mittels GroupUtils:
struct Data
group g
method create takes nothing returns Data
local Data d=Data.allocate()
set d.g=NewGroup()
return d
endmethod
method onDestroy takes nothing returns nothing
call ReleaseGroup(.g)
endmethod
endstruct
Eine auch sehr häufig benutzte Funktion ist das Durchgehen aller Einheiten in einer Einheitengruppe und dementsprechende Aktionen mit der betroffenen Einheit anstellen. Dabei gibt es grundsätzlich zwei Möglichkeiten:
function foo takes group g returns nothing
local unit u = null
loop
set u = FirstOfGroup( g )
exitwhen u == null
call GroupRemoveUnit( g, u )
endloop
endfunction
oder:
function actions takes nothing returns nothing
endfunction
function foo takes group g returns nothing
call ForGroup( g, function actions )
endfunction
Dabei stellt die zweite Möglichkeit nicht nur eine sicherere Variante dar (NULL-Lücken bringen das Durchlaufen der Gruppe nicht frühzeitig zum Beenden), sondern auch eine schnellere Variante. Um auch auf externe Dinge in der group_callback Funktion Zugriff zu haben, können wir einfach temporäre globale Variablen verwenden.
Eine weitere, sehr praktische Möglichkeit schnell und effizient Aktionen an einer Gruppe von Einheiten auszuüben ist es, den BoolExpr Parameter zu „missbrauchen“. Diese Möglichkeit bietet sich aber nur an, wenn man nur einmal über eine Gruppe iterieren will und sie nicht auf Dauer speichern will.
Ein Beispiel an Hand GroupUtils, vJass structs und der neuesten JassHelper Version:
struct spell
unit caster
static spell tempthis
static method group_filter takes nothing returns boolean
local spell this = spell.tempthis
call UnitDamageTarget( this.caster, GetFilterUnit(), 800, false, false, null, null, null )
return false
endmethod
static method create takes unit c, real tx, real ty returns spell
local spell this = spell.allocate()
set this.caster = c
set spell.tempthis = this
call GroupEnumUnitsInRange( ENUM_GROUP, tx, ty, 800, function spell.group_filter )
return this
endmethod
endstruct
Das war nun eine kleine Einführung der wichtigsten Dinge, die man bezüglich triggern beachten sollte, wenn man effizient und sicher bleiben will. Natürlich gäbe es noch viele andere Themen, die man hier erwähnen könnte, aber das würde den Rahmen eines kleinen Tutorials bei weitem sprengen und ich denke, dass die angeführten Dinge, vor allem für "Neueinsteiger", am Interessantestem sein dürften.