• 🏆 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!

Patroling Creep Respawn vs. Leak

Status
Not open for further replies.
Level 2
Joined
Feb 1, 2011
Messages
11
So I'v stolen my Creep-Respawn from a tutorial on this site and it works fine.
Then I tought sitting Creeps arn't that cool and I made them patrol.

So I used a Trigger that sends every 5 seconds all Units from one Location to patrol so the other Location. That gets every Unit patroling even after Respawn and is (a first glance) realy time-efficient.

And would look like this:

  • Event
    • Time - Every 5.00 seconds of game time
  • Contitions
  • Actions
    • UnitGroup - Pick every unit in (Units in zPatrolG11 <gen>) and do (Unit - Order (Picked unit) to patrol to (Center of zPatrolG18 <gen>))
One line for every patroling Unitgroup. But (at least I think so) that solution leaks like hell.
After fixing this I get:

  • Event
    • Time - Every 5.00 seconds of game time
  • Contitions
  • Actions
    • Set TempLoc = (Center of zPatrolG11 <gen>)
    • Set TempUnitGroup = (Units in zPatrolG12 <gen> owned by Player 12 (Brown))
    • UnitGroup - Pick every unit in TempUnitGroup and do (Unit - order (Picked unit) to patrol to TempLoc)
    • Custom script: call RemoveLocation(udg_TempLoc)
    • Custom script: call DestroyGroup(udg_TempUnitGroup)
5 Lines per patroling Unitgroup.


Is my understanding of Leaks correct?
Does anyone have a better idea how to make this work?
 
Level 7
Joined
May 18, 2010
Messages
264
pick units in a region and put them to the group
And do loop actions
order them to patrol to the point .
and remove them from group.




or scy fy as i call it
u can add a unit to unit group*added*
and when causing unit to move to a location make if then else actions
and check that unit isent in the *added* unit group,do youre actions
if not do the patrol actions

just figure it out
 
Level 7
Joined
Apr 12, 2009
Messages
188
You got it right. Also, I wouldn't worry about how many lines of actions you create in any GUI scripting, most of them consist of functions containing several lines of JASS anyway. The only efficiency issues to worry about in WC3 GUI script are memory leaks in repetitive actions (which you seem to understand) and doing massive volumes of simultaneous actions (careful using loops, repeating timers, etc)... unless your computer is from 1995.
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
The trigger is correct, but this is a slightly faster solution.

  • Event
    • Time - Every 5.00 seconds of game time
  • Contitions
  • Actions
    • Set TempLoc = (Center of zPatrolG11 <gen>)
    • Custom script: set bj_wantDestroyGroup = true
    • UnitGroup - Pick every unit in (Units in zPatrolG12 <gen> owned by Player 12 (Brown)) and do (Unit - order (Picked unit) to patrol to TempLoc)
    • Custom script: call RemoveLocation(udg_TempLoc)
 
Level 2
Joined
Feb 1, 2011
Messages
11
@tw3ye: could you please explain "scy fy"'ing a little better?

@Svensky: I do now worry about how many lines I get for performance's sake - I worry about my mapping time ;)
Also I do not like copy&pasting hundreds of lines of code - it's just bad programming.

I'v come up with a new idea with a loop (example with 5 Units):

  • Patrol
    • Event
      • Time - Every 5.00 seconds of game time
    • Conditions
    • Actions
      • Set PatrolStart[1] = (Units in zPatrol1 <gen> owned by Player 12 (Brown))
      • Set PatrolStart[2] = (Units in zPatrol3 <gen> owned by Player 12 (Brown))
      • Set PatrolStart[3] = (Units in zPatrol5 <gen> owned by Player 12 (Brown))
      • Set PatrolStart[4] = (Units in zPatrol7 <gen> owned by Player 12 (Brown))
      • Set PatrolStart[5] = (Units in zPatrol9 <gen> owned by Player 12 (Brown))
      • Set PatrolTarget[1] = (Center of zPatrol2 <gen>)
      • Set PatrolTarget[2] = (Center of zPatrol4 <gen>)
      • Set PatrolTarget[3] = (Center of zPatrol6 <gen>)
      • Set PatrolTarget[4] = (Center of zPatrol8 <gen>)
      • Set PatrolTarget[5] = (Center of zPatrol10 <gen>)
      • For each (Integer A) from 1 to 5, do (Actions)
        • Loop - Actions
          • UnitGroup - Pick every unit in PatrolStart[(Integer A)] and do (Unit - Order (Picked unit) to patrol to PatrolTarget[(Integer A)])
It would be nice if I could assign the Areas on the loop too since if I name them correctly its "patrol all Units from 2*A-1 to center of 2*A" all the time.
If this is possible I could use my first solution or Maker's faster one.


And I do not know if my Array leaks, and IF it leaks - I do not know how to write the index in JASS.
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
@tw3ye: could you please explain "scy fy"'ing a little better?

@Svensky: I do now worry about how many lines I get for performance's sake - I worry about my mapping time ;)
Also I do not like copy&pasting hundreds of lines of code - it's just bad programming.

I'v come up with a new idea with a loop (example with 5 Units):

  • Patrol
    • Event
      • Time - Every 5.00 seconds of game time
    • Conditions
    • Actions
      • Set PatrolStart[1] = (Units in zPatrol1 <gen> owned by Player 12 (Brown))
      • Set PatrolStart[2] = (Units in zPatrol3 <gen> owned by Player 12 (Brown))
      • Set PatrolStart[3] = (Units in zPatrol5 <gen> owned by Player 12 (Brown))
      • Set PatrolStart[4] = (Units in zPatrol7 <gen> owned by Player 12 (Brown))
      • Set PatrolStart[5] = (Units in zPatrol9 <gen> owned by Player 12 (Brown))
      • Set PatrolTarget[1] = (Center of zPatrol2 <gen>)
      • Set PatrolTarget[2] = (Center of zPatrol4 <gen>)
      • Set PatrolTarget[3] = (Center of zPatrol6 <gen>)
      • Set PatrolTarget[4] = (Center of zPatrol8 <gen>)
      • Set PatrolTarget[5] = (Center of zPatrol10 <gen>)
      • For each (Integer A) from 1 to 5, do (Actions)
        • Loop - Actions
          • UnitGroup - Pick every unit in PatrolStart[(Integer A)] and do (Unit - Order (Picked unit) to patrol to PatrolTarget[(Integer A)])
It would be nice if I could assign the Areas on the loop too since if I name them correctly its "patrol all Units from 2*A-1 to center of 2*A" all the time.
If this is possible I could use my first solution or Maker's faster one.


And I do not know if my Array leaks, and IF it leaks - I do not know how to write the index in JASS.

JASS:
call RemoveLocation(udg_PatrolTarget[GetForLoopIndexA()])
call DestroyGroup(udg_PatrolStart[GetForLoopIndexA()])
set bj_wantDestroyGroup = true //can also be used as maker showed. It destroys the next group created. And it's faster then call DestroyGroup ;) 
//I have no idea if this works for group defined variables though (not necessary ofcourse). Could someone show me a list of pre-defined globals? I would like to know how every pre-defined global works.

put that inside your loop
 
Last edited:
Level 2
Joined
Feb 1, 2011
Messages
11
JASS:
call RemoveLocation(udg_PatrolTarget[GetForLoopIndexA()])
call DestroyGroup(udg_PatrolStart[GetForLoopIndexA()])
set bj_wantDestroyGroup = true //can also be used as maker showed. It destroys the next group created. And it's faster then call DestroyGroup ;) 
//I have no idea if this works for group defined variables though. Could someone show me this pre-defined global in blizzard.j? Where is it :S?

put that inside your loop

big thanks!

The would be the best is could get the Areas inside the Loop without saving them as Array - but i guess its simply not possible to construct a variable from String / Integer.
 
Level 7
Joined
Apr 12, 2009
Messages
188
JASS:
call RemoveLocation(udg_PatrolTarget[GetForLoopIndexA()])
call DestroyGroup(udg_PatrolStart[GetForLoopIndexA()])
set bj_wantDestroyGroup = true //can also be used as maker showed. It destroys the next group created. And it's faster then call DestroyGroup ;) 
//I have no idea if this works for group defined variables though (not necessary ofcourse). Could someone show me a list of pre-defined globals? I would like to know how every pre-defined global works.

put that inside your loop

Would "set bj_wantDestroyGroup = true" have to be placed before each group creation? Like...

  • Patrol
    • Event
      • Time - Every 5.00 seconds of game time
    • Conditions
    • Actions
      • Custom script: set bj_wantDestroyGroup = true
      • Set PatrolStart[1] = (Units in zPatrol1 <gen> owned by Player 12 (Brown))
      • Custom script: set bj_wantDestroyGroup = true
      • Set PatrolStart[2] = (Units in zPatrol3 <gen> owned by Player 12 (Brown))
      • Custom script: set bj_wantDestroyGroup = true
      • Set PatrolStart[3] = (Units in zPatrol5 <gen> owned by Player 12 (Brown))
Just wondering... I usually just call DestroyGroup.

Also I do not like copy&pasting hundreds of lines of code - it's just bad programming.

How is copy paste bad exactly? :xxd:
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
No, don't use it there.

Setting that will destroy the group used in the next
  • UnitGroup - Pick every unit in (some group) and do...

could you give me an example on how to use it correctly please?
How this pre-defined global works perhaps?
I know it destroys the next group, but how does this work for variables?
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
  • Untitled Trigger 068
    • Actions
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
        • Loop - Actions
          • Unit - Kill (Picked unit)
or with a variable:

You have set some group to a variable in some trigger:

  • Set Explode_Group = (Units in (Playable map area))
then in some other (or the same) trigger, this destroys the group:

  • Untitled Trigger 068
    • Actions
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in Explode_Group and do (Actions)
        • Loop - Actions
          • Unit - Kill (Picked unit)
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
  • Untitled Trigger 068
    • Actions
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
        • Loop - Actions
          • Unit - Kill (Picked unit)
or with a variable:

You have set some group to a variable in some trigger:

  • Set Explode_Group = (Units in (Playable map area))
then in some other (or the same) trigger, this destroys the group:

  • Untitled Trigger 068
    • Actions
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in Explode_Group and do (Actions)
        • Loop - Actions
          • Unit - Kill (Picked unit)

thank you, this was quite usefull :)

Would "set bj_wantDestroyGroup = true" have to be placed before each group creation? Like...

  • Patrol
    • Event
      • Time - Every 5.00 seconds of game time
    • Conditions
    • Actions
      • Custom script: set bj_wantDestroyGroup = true
      • Set PatrolStart[1] = (Units in zPatrol1 <gen> owned by Player 12 (Brown))
      • Custom script: set bj_wantDestroyGroup = true
      • Set PatrolStart[2] = (Units in zPatrol3 <gen> owned by Player 12 (Brown))
      • Custom script: set bj_wantDestroyGroup = true
      • Set PatrolStart[3] = (Units in zPatrol5 <gen> owned by Player 12 (Brown))
Just wondering... I usually just call DestroyGroup.


Quote:
Also I do not like copy&pasting hundreds of lines of code - it's just bad programming.

How is copy paste bad exactly?

setting a variable is not the same as creating a group.
 
Level 7
Joined
Apr 12, 2009
Messages
188
Yeah that was my bad I'm retarded sometimes :eekani:

Makes perfect sense. I'm just used to using call DestroyGroup() because it's how I clear all my other leaks. Eg. call RemoveLocation() call DestroyLightning() etc...

[EDIT] Here's the JASS of the ForGroupBJ function, EG:
  • Unit Group - Pick every unit in (CREATE SOME GROUP HERE) and do (Actions)
JASS:
function ForGroupBJ takes group whichGroup, code callback returns nothing
    // If the user wants the group destroyed, remember that fact and clear
    // the flag, in case it is used again in the callback.
    local boolean wantDestroy = bj_wantDestroyGroup

    set bj_wantDestroyGroup = false

    call ForGroup(whichGroup, callback)

    // If the user wants the group destroyed, do so now.
    if (wantDestroy) then

        call DestroyGroup(whichGroup)

    endif

endfunction

Again, makes sense with how Maker described the usage.
I remember why I stuck with the 'call DestroyGroup()' option; because later if I want to change what I'm setting the variable to it's a little bit easier to understand the script and modify it than if you generate the group within the ForGroupBJ action.
 
Level 2
Joined
Feb 1, 2011
Messages
11
I'm sorry I missunderstood, what did you mean by this :)?
you want to use a integer/string to construct a variable :S?

With the actual solution I have to write
"set variable UnitGroup[index] = all Units in Area1"
"set variable TargetPoint[index] = center of Area2"
"set variable UnitGroup[index+1] = all Units in Area3"
"set variable TargetPoint[index+1] = center of Area4"
etc.
"Loop index
"Unitgroup[index] patrol to TargetPoint[index]"
"destroy Unitgroup[index]"
"destroy TargetPoint[index]"
Loop end"


My wish-thinking lazy Solution would be

"Loop index
"set variable temp_UnitGroup = all Units in Area from String("Area"+String(2*index-1)+" <gen>")
"set variable temp_TargetPoint = center of Area from String("Area"+String(2*index)+" <gen>")
temp_Unitgroup patrol to temp_TargetPoint"
"destroy temp_Unitgroup"
"destroy temp_TargetPoint"
Loop end"

It would simply save the time to manualy set each UnitGroup- and TargetPoint-Index to the Areas. Also it would save some memory considering I don't need an array.
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
With the actual solution I have to write
"set variable UnitGroup[index] = all Units in Area1"
"set variable TargetPoint[index] = center of Area2"
"set variable UnitGroup[index+1] = all Units in Area3"
"set variable TargetPoint[index+1] = center of Area4"
etc.
"Loop index
"Unitgroup[index] patrol to TargetPoint[index]"
"destroy Unitgroup[index]"
"destroy TargetPoint[index]"
Loop end"


My wish-thinking lazy Solution would be

"Loop index
"set variable temp_UnitGroup = all Units in Area from String("Area"+String(2*index-1)+" <gen>")
"set variable temp_TargetPoint = center of Area from String("Area"+String(2*index)+" <gen>")
temp_Unitgroup patrol to temp_TargetPoint"
"destroy temp_Unitgroup"
"destroy temp_TargetPoint"
Loop end"

It would simply save the time to manualy set each UnitGroup- and TargetPoint-Index to the Areas. Also it would save some memory considering I don't need an array.

why will this not be possible :S If you created all the regions with the correct names then you can use this right?
To make sure you have the right region names, display a text message... ;)
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
I didn't found a way to do this with GUI (maybe I overlooked it - help apriciated).
And JASS... I have no clue of JASS at all (ok, 3 functions to clear leak, but thats it).

hmm there probably is no way in gui to convert a region to string. (You will have to use jass to convert this I'm affraid)
Here's a work-around which might help:

  • init regions
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set Regions[1] = Region 000 <gen>
      • Set Regions[2] = Region 001 <gen>
      • Set Regions[3] = Region 002 <gen>
      • Set Regions[4] = Region 003 <gen>
      • Set Regions[5] = Region 004 <gen>
      • Set Regions[6] = Region 005 <gen>
  • Start guarding u fking minions >.<!!!
    • Events
      • Time - Every 4.00 seconds of game time
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 3, do (Actions)
        • Loop - Actions
          • Set temp_UnitGroup = (Units in Regions[(2 x ((Integer A) - 1))])
          • Set temp_TargetPoint = (Center of Regions[(2 x (Integer A))])
          • Unit Group - Pick every unit in temp_UnitGroup and do (Actions)
            • Loop - Actions
              • Unit - Order (Picked unit) to Patrol To temp_TargetPoint
          • Custom script: call DestroyGroup(udg_temp_UnitGroup)
          • Custom script: call RemoveLocation(udg_temp_TargetPoint)
          • ----- Destroy them here if neccesary -----
the trigger works as followed:
Integer A = 1
temp_UnitGroup = all units in Regions[1]
temp_TargetPoint = center of Regions[2]
order units from temp_UnitGroup to Patrol to temp_TargetPoint

Integer A = 2
temp_UnitGroup = all units in Regions[3]
temp_TargetPoint = center of Regions[4]
order units from temp_UnitGroup to Patrol to temp_TargetPoint

etc...

you do not have to remove the regions[1-6] if your going to use them the entire game (this will not leak. Further explenation is here: http://www.hiveworkshop.com/forums/world-editor-help-zone-98/question-about-leak-189062/).

If your not, you might want to destroy them too...

EDIT: It should work now, made a few adjustments :)
 
Last edited:
Level 2
Joined
Feb 1, 2011
Messages
11
Thanks, looks good ;)

I'm not even sure if the string-solution is possible in JASS - I know some languages where its not possible at all.
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
yes it is, I've seen it before... It was a system for maze regions. I forgot where it was but it used a system that could target all the regions from region 000 <gen>

till a few thousand if I'm correct. Then you would only have to create the regions for your maze and the system would automatically create a (unit dies when enters region) trigger for the maze.

I forgot where I last saw it though :S
 
Status
Not open for further replies.
Top