• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[JASS] How to remove leak on this ?

Status
Not open for further replies.
Level 8
Joined
Apr 26, 2011
Messages
403
It is a tower defend map, with many wave.

for every wave, I execute the code below to start the trigger :

JASS:
call TriggerExecute( gg_trg_Fight_Start_Add_Events )

JASS:
function Trig_Unpause_Fighters_Function takes nothing returns nothing
    call SetUnitMoveSpeed( GetTriggerUnit(), GetUnitDefaultMoveSpeed(GetTriggerUnit()) )
    
    //call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Trig_Unpause_Fighters_Add_Events_Function takes nothing returns nothing
    local trigger t = CreateTrigger( )
    call TriggerRegisterUnitEvent( t, GetEnumUnit(), EVENT_UNIT_ACQUIRED_TARGET )
    call TriggerAddAction( t, function Trig_Unpause_Fighters_Function )
    
endfunction

function Trig_Unpause_Fighters_Add_Events_Actions takes nothing returns nothing
    call ForGroup(udg_Fighter_Group, function Trig_Unpause_Fighters_Add_Events_Function)
endfunction


function InitTrig_Fight_Start_Add_Events takes nothing returns nothing
    set gg_trg_Fight_Start_Add_Events = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Fight_Start_Add_Events, function Trig_Unpause_Fighters_Add_Events_Actions )
endfunction

as you can see:
- the trigger for "EVENT_UNIT_ACQUIRED_TARGET" is register again and again for every wave,
- I never need them for later wave, because "udg_Fighter_Group" is destroy at the end of each wave, and created again for next wave

so how can I safely remove leak on this ?
 
Level 8
Joined
Apr 26, 2011
Messages
403
If I enable the line, it will work right ?

JASS:
//call DestroyTrigger(GetTriggeringTrigger())


because I register for every unit in my "udg_Fighter_Group" , I still not understand how destory trigger work :

- do it destory my trigger "t" after first unit ACQUIRED_TARGET , and cause remain unit not working ?
 
Level 26
Joined
Mar 19, 2008
Messages
3,140
JASS:
function Trig_Unpause_Fighters_Function takes nothing returns nothing
    call SetUnitMoveSpeed(GetTriggerUnit(), GetUnitDefaultMoveSpeed(GetTriggerUnit()))
endfunction

function Trig_Unpause_Fighters_Add_Events_Function takes nothing returns nothing
    call TriggerRegisterUnitEvent(udg_Trig, GetEnumUnit(), EVENT_UNIT_ACQUIRED_TARGET)
endfunction

function InitTrig_Fight_Start_Add_Events takes nothing returns nothing
    call DestroyTrigger(udg_Trig)
    set udg_Trig = CreateTrigger()
    call ForGroup(udg_Fighter_Group, function Trig_Unpause_Fighters_Add_Events_Function)
    call TriggerAddAction(udg_Trig, function Trig_Unpause_Fighters_Function )
endfunction
Where 'Trig' is global trigger variable from GUI variable editor.
PS. Shorten the function names, such long ones lose readability.

Instead of executing trigger write: call InitTrig_Fight_Start_Add_Events()
 
Level 8
Joined
Apr 26, 2011
Messages
403
JASS:
function Trig_Unpause_Fighters_Function takes nothing returns nothing
    call SetUnitMoveSpeed(GetTriggerUnit(), GetUnitDefaultMoveSpeed(GetTriggerUnit()))
endfunction

function Trig_Unpause_Fighters_Add_Events_Function takes nothing returns nothing
    call TriggerRegisterUnitEvent(udg_Trig, GetEnumUnit(), EVENT_UNIT_ACQUIRED_TARGET)
endfunction

function InitTrig_Fight_Start_Add_Events takes nothing returns nothing
    call DestroyTrigger(udg_Trig)
    set udg_Trig = CreateTrigger()
    call ForGroup(udg_Fighter_Group, function Trig_Unpause_Fighters_Add_Events_Function)
    call TriggerAddAction(udg_Trig, function Trig_Unpause_Fighters_Function )
endfunction
Where 'Trig' is global trigger variable from GUI variable editor.
PS. Shorten the function names, such long ones lose readability.

Instead of executing trigger write: call InitTrig_Fight_Start_Add_Events()


I think you are out of topic.

when I compress map with Vex's tool, he will did that for me(eg, shortern trigger & variable's name)
 
Level 8
Joined
Apr 26, 2011
Messages
403
When all units in the wave are dead, destroy the trigger. Create a new one, and register the events for the next wave's units.

I think you didn't read my trigger. or answer my question

if you read my trigger, it is more advance than standard trigger convert from GUI :
- It have 1 parent trigger (I don't want to destroy parent trigger)
- The parent trigger will create & register event for every unit when wave start.

my questions is :
- how to destroy children trigger, while leave parent alone.
- in my code, do those children share same trigger ? or each children have their own trigger ? (because I don't want to accident destroy them after 1st children use the trigger)

I am waiting for more professional answer on these question rather than "destory trigger after used" (I already knew that and disable the line for destroy because unsure about answer).

I think I'm not - Have you wrote anything about optimizer? No. Thus my adivice was in right place. Plus my solution should help you archieving the leak removal.


JASS:
call InitTrig_Fight_Start_Add_Events()

calling above line won't work, you should know why.

I though my code should be easy to read.

will check for answer tomorrow
 
Last edited by a moderator:
Level 26
Joined
Mar 19, 2008
Messages
3,140
Have you even read my solution?

EDIT: Then move systems code at the top? Or just leave the TriggerExecute with standard init. Once again, using global trigger parameter just like I did can fix your problem.

Don't be rude, Maker and I trying to help you, if you don't want to listen or check the solutions, don't create new thread nor ask for help.
 
Level 8
Joined
Apr 26, 2011
Messages
403
Have you even read my solution?

EDIT: Then move systems code at the top? Or just leave the TriggerExecute with standard init. Once again, using global trigger parameter just like I did can fix your problem.

Don't be rude, Maker and I trying to help you, if you don't want to listen or check the solutions, don't create new thread nor ask for help.


sorry, I did quick read before went to bed, so I only read your text and didn't know JASS is not a quote :vw_death:


thank, I will try it out.


Edit: if I have 100 unit in that group. do my code create 100 trigger or just 1 ?
JASS:
call TriggerRegisterUnitEvent(udg_Trig, GetEnumUnit(), EVENT_UNIT_ACQUIRED_TARGET)
 
Level 8
Joined
Apr 26, 2011
Messages
403
It'd add exactly 100 events to that trigger, but wouldn't create 100 triggers - there will be one trigger "Trig" afterall.

I see.

I just try your code, with debug message (every time SetUnitMoveSpeed is call)

I get so many messages :grin:

are there anyway to destroy it after the event happen once for each unit ?

because it is massive fight (100-200's unit), so I try avoid lag from this trigger.
 
I see.

I just try your code, with debug message (every time SetUnitMoveSpeed is call)

I get so many messages :grin:

are there anyway to destroy it after the event happen once for each unit ?

because it is massive fight (100-200's unit), so I try avoid lag from this trigger.

You can either:
A) Remove units from that group, and then in your actions check if they are in the group before performing the action.
B) Add all the units (that the event is registered for) into a separate group, and then add a condition in the actions to check if they are in that group. If they are, then remove them from the group after changing their movement speed.

Ehh, so something like this:
JASS:
// make a global named udg_Unpause_Group

function Trig_Unpause_Fighters_Function takes nothing returns nothing
    local unit u = GetTriggerUnit()
    if IsUnitInGroup(u, udg_Unpause_Group) then
        call SetUnitMoveSpeed(u, GetUnitDefaultMoveSpeed(u))
        call GroupRemoveUnit(u)
    endif
    set u = null
endfunction

function Trig_Unpause_Fighters_Add_Events_Function takes nothing returns nothing
    call TriggerRegisterUnitEvent(udg_Trig, GetEnumUnit(), EVENT_UNIT_ACQUIRED_TARGET)
    call GroupAddUnit(udg_Unpause_Group, GetEnumUnit()) //copies the group to udg_Unpause_Group
endfunction

function InitTrig_Fight_Start_Add_Events takes nothing returns nothing
    call DestroyTrigger(udg_Trig)
    set udg_Trig = CreateTrigger()
    call ForGroup(udg_Fighter_Group, function Trig_Unpause_Fighters_Add_Events_Function)
    call TriggerAddAction(udg_Trig, function Trig_Unpause_Fighters_Function )
endfunction

That would make sure that it only runs once for each unit that it was registered for. Of course you can use the existing group, udg_Fighter_Group, but I figured you might want to use that later so I used a separate group.

If you want to destroy the trigger after the trigger has been ran for each unit, then you can just do this:
JASS:
// make a global named udg_Unpause_Group
// make a global integer named udg_Unpause_Group_Count 

function Trig_Unpause_Fighters_Function takes nothing returns nothing
    local unit u = GetTriggerUnit()
    if IsUnitInGroup(u, udg_Unpause_Group) then
        call SetUnitMoveSpeed(u, GetUnitDefaultMoveSpeed(u))
        call GroupRemoveUnit(u)
        set udg_Unpause_Group_Count = udg_Unpause_Group_Count - 1
        if udg_Unpause_Group_Count == 0 then
            call DestroyGroup(udg_Unpause_Group)
            call DestroyTrigger(udg_Trig)
        endif
    endif
    set u = null
endfunction

function Trig_Unpause_Fighters_Add_Events_Function takes nothing returns nothing
    call TriggerRegisterUnitEvent(udg_Trig, GetEnumUnit(), EVENT_UNIT_ACQUIRED_TARGET)
    call GroupAddUnit(udg_Unpause_Group, GetEnumUnit()) //copies the group to udg_Unpause_Group
    set udg_Unpause_Group_Count = udg_Unpause_Group_Count + 1 //count how many are in the group
endfunction

function InitTrig_Fight_Start_Add_Events takes nothing returns nothing
    call DestroyTrigger(udg_Trig)
    set udg_Trig = CreateTrigger()
    set udg_Unpause_Group_Count = 0 
    call ForGroup(udg_Fighter_Group, function Trig_Unpause_Fighters_Add_Events_Function)
    call TriggerAddAction(udg_Trig, function Trig_Unpause_Fighters_Function )
endfunction

And it should work fine. Good luck.
 
Level 26
Joined
Mar 19, 2008
Messages
3,140
Purge, call GroupRemoveUnit(u) requires two parameters, doesn't it? :p It should be: call GroupRemoveUnit(udg_Unpause_Group, u)

@HuanAk, better don't destroy it in such case (if in fact you need it in any wave). Or you can just add (after setting udg_Trig = CreateTrigger()): set udg_Unpause_Group = CreateGroup()
 
Level 8
Joined
Apr 26, 2011
Messages
403
Thank all for help

I learn something new: global variable trigger.

JASS:
function Trig_Unpause_Fighters_Function takes nothing returns nothing
    local unit u = GetTriggerUnit()
    if IsUnitInGroup(u, udg_Unpause_Group) then
        call IssuePointOrderLoc( u, "attack", udg_PathingPointArray[GetUnitUserData(u)] )
        call GroupRemoveUnit(udg_Unpause_Group, u)
        //call SetUnitMoveSpeed(u, GetUnitDefaultMoveSpeed(u))

        // destroy trigger if group is empty
        set bj_isUnitGroupEmptyResult = true
        call ForGroup(udg_Unpause_Group, function IsUnitGroupEmptyBJEnum)
        if bj_isUnitGroupEmptyResult == true then
            call GroupClear(udg_Unpause_Group)
            call DestroyTrigger(udg_Unpause_trig)
        endif
    endif
    set u = null
endfunction

function Trig_Unpause_Fighters_Add_Events_Function takes nothing returns nothing
    call TriggerRegisterUnitEvent(udg_Unpause_trig, GetEnumUnit(), EVENT_UNIT_ACQUIRED_TARGET)
    call GroupAddUnit(udg_Unpause_Group, GetEnumUnit()) //copies the group to udg_Unpause_Group
endfunction

function InitTrig_Fight_Start_Add_Events takes nothing returns nothing
    call DestroyTrigger(udg_Unpause_trig)
    set udg_Unpause_trig = CreateTrigger()
    call ForGroup(udg_Fighter_Group, function Trig_Unpause_Fighters_Add_Events_Function)
    call TriggerAddAction(udg_Unpause_trig, function Trig_Unpause_Fighters_Function )
endfunction
 
Level 8
Joined
Apr 26, 2011
Messages
403
got another question:

in my first post on page one. if I enable this line
JASS:
 //call DestroyTrigger(GetTriggeringTrigger())

do it do same job ? I am a bit lost on
JASS:
local trigger t = CreateTrigger( )
and
GetTriggeringTrigger()
 
Level 26
Joined
Mar 19, 2008
Messages
3,140
HuakAk, why don't you use global integer parameter, just like Purge have shwon you? you do not need IsUnitGroupEmptyBJEnum().

JASS:
// global integer udg_Unpause_Counter
function Trig_Unpause_Fighters_Function takes nothing returns nothing
    local unit u = GetTriggerUnit()
    if IsUnitInGroup(u, udg_Unpause_Group) then
        call IssuePointOrderByIdLoc(u, 851983, udg_PathingPointArray[GetUnitUserData(u)])
        call GroupRemoveUnit(udg_Unpause_Group, u)
        set udg_Unpause_Counter = udg_Unpause_Counter - 1
        //call SetUnitMoveSpeed(u, GetUnitDefaultMoveSpeed(u))

        // destroy trigger if group is empty
        if 0 == udg_Unpause_Counter then
            call DestroyTrigger(udg_Unpause_trig)
        endif
    endif
    set u = null
endfunction

function Trig_Unpause_Fighters_Add_Events_Function takes nothing returns nothing
    call TriggerRegisterUnitEvent(udg_Unpause_trig, GetEnumUnit(), EVENT_UNIT_ACQUIRED_TARGET)
    call GroupAddUnit(udg_Unpause_Group, GetEnumUnit()) //copies the group to udg_Unpause_Group
    set udg_Unpause_Counter = udg_Unpause_Counter + 1
endfunction

function InitTrig_Fight_Start_Add_Events takes nothing returns nothing
    call DestroyTrigger(udg_Unpause_trig)
    set udg_Unpause_trig = CreateTrigger()
    set udg_Unpause_Counter = 0
    call ForGroup(udg_Fighter_Group, function Trig_Unpause_Fighters_Add_Events_Function)
    call TriggerAddAction(udg_Unpause_trig, function Trig_Unpause_Fighters_Function )
endfunction

About Destroying trigger in script at first page; You have been creating one trigger for each unit in udg_Fight_Group - meaning there were ton of them >.>
After any of those fired, it's actions has been executed and then that trigger (only that one, not the main from init trigger nor any of other locals registered per unit) got destroyed.
 
Level 8
Joined
Apr 26, 2011
Messages
403
HuakAk, why don't you use global integer parameter, just like Purge have shwon you? you do not need IsUnitGroupEmptyBJEnum().

JASS:
// global integer udg_Unpause_Counter
function Trig_Unpause_Fighters_Function takes nothing returns nothing
    local unit u = GetTriggerUnit()
    if IsUnitInGroup(u, udg_Unpause_Group) then
        call IssuePointOrderByIdLoc(u, 851983, udg_PathingPointArray[GetUnitUserData(u)])
        call GroupRemoveUnit(udg_Unpause_Group, u)
        set udg_Unpause_Counter = udg_Unpause_Counter - 1
        //call SetUnitMoveSpeed(u, GetUnitDefaultMoveSpeed(u))

        // destroy trigger if group is empty
        if 0 == udg_Unpause_Counter then
            call DestroyTrigger(udg_Unpause_trig)
        endif
    endif
    set u = null
endfunction

function Trig_Unpause_Fighters_Add_Events_Function takes nothing returns nothing
    call TriggerRegisterUnitEvent(udg_Unpause_trig, GetEnumUnit(), EVENT_UNIT_ACQUIRED_TARGET)
    call GroupAddUnit(udg_Unpause_Group, GetEnumUnit()) //copies the group to udg_Unpause_Group
    set udg_Unpause_Counter = udg_Unpause_Counter + 1
endfunction

function InitTrig_Fight_Start_Add_Events takes nothing returns nothing
    call DestroyTrigger(udg_Unpause_trig)
    set udg_Unpause_trig = CreateTrigger()
    set udg_Unpause_Counter = 0
    call ForGroup(udg_Fighter_Group, function Trig_Unpause_Fighters_Add_Events_Function)
    call TriggerAddAction(udg_Unpause_trig, function Trig_Unpause_Fighters_Function )
endfunction

About Destroying trigger in script at first page; You have been creating one trigger for each unit in udg_Fight_Group - meaning there were ton of them >.>
After any of those fired, it's actions has been executed and then that trigger (only that one, not the main from init trigger nor any of other locals registered per unit) got destroyed.


I still have 1 question:

it will work if :
- I copy above code,
- put inside top of the map as JASS,
- call InitTrig_Fight_Start_Add_Events()

it WON"T work if
- I copy above code, and
- paste into an trigger call "InitTrig_Fight_Start_Add_Events"
- call TriggerExecute( gg_trg_Fight_Start_Add_Events )

then it won't work :(

and my code on first page will work (by copy & paste into trigger).

I been try out many way to make the code work for 2nd method, but fail :(

anyway I am give up and using first method now.... but still don't understand why the code don't work if I copy/paste into trigger.
 
Level 26
Joined
Mar 19, 2008
Messages
3,140
Please, post the map here (no matter the size), I'll fix for you.
- call TriggerExecute( gg_trg_Fight_Start_Add_Events )
Won't work only because there is no trigger named "gg_trg_Fight_Start_Add_Events" declared (and as you know TriggerExecute() function actually executes trigger, not other fuction). Additionaly events and actions are applied to comppletely other trigger, the 'Trig' one.
 
Status
Not open for further replies.
Top