• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Trigger] Yet another question by me

Status
Not open for further replies.
Level 6
Joined
Feb 10, 2011
Messages
188
Ok, so i deleted my original post, i am now editing because i was really tired when i made it. I fixed the problems now and cleaned it up, it now works but causes extreme delay after around 10 minutes.

What this trigger does is check every .15 seconds to make sure that each base (a base is a county and a CoP, with a tower) has a defender in its CoP. It loops through by baseDefender Unit group and if it is the only available defender owned by the owner of the base then the current defender will be moved to the center of the circle. If there is other units within range of the circle owned by the owner of the base it will change the defender to one of those units.

TLDR version: this trigger keeps a bases defender in its CoP.

  • Change Defender Range
    • Events
      • Time - Every 0.15 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in baseDefenders and do (Actions)
        • Loop - Actions
          • Set tempUnit1 = (Picked unit)
          • Set tempPoint1 = (Position of tempUnit1)
          • Set tempGroup1 = (Units within 300.00 of tempPoint1 matching ((Unit-type of (Matching unit)) Equal to Tower))
          • Set tempUnit2 = (Random unit from tempGroup1)
          • Set tempPoint2 = (Position of tempUnit2)
          • Set tempPlayer1 = (Owner of tempUnit1)
          • Set tempGroup2 = (Units within 175.00 of tempPoint2 matching ((((Matching unit) is A structure) Equal to False) and (((Owner of (Matching unit)) Equal to tempPlayer1) and ((Matching unit) Not equal to tempUnit1))))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between tempPoint1 and tempPoint2) Greater than or equal to 175.00
              • (Number of units in tempGroup2) Equal to 0
            • Then - Actions
              • -------- Move the defender back to the center of the CoP for his base, if he is the only unit around. --------
              • Unit - Move tempUnit1 instantly to tempPoint2
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Distance between tempPoint1 and tempPoint2) Greater than or equal to 175.00
                  • (Number of units in tempGroup2) Greater than or equal to 1
                • Then - Actions
                  • -------- This will switch the defender is there is another in the range. --------
                  • Unit Group - Remove tempUnit1 from baseDefenders
                  • Set tempUnit3 = (Random unit from tempGroup2)
                  • Unit Group - Add tempUnit3 to baseDefenders
                • Else - Actions
          • Custom script: set udg_tempUnit1 = null
          • Custom script: set udg_tempUnit2 = null
          • Custom script: set udg_tempUnit3 = null
          • Custom script: set udg_tempPlayer1 = null
          • Custom script: call DestroyGroup( udg_tempGroup1 )
          • Custom script: set udg_tempGroup1 = null
          • Custom script: call DestroyGroup( udg_tempGroup2 )
          • Custom script: set udg_tempGroup2 = null
          • Custom script: call RemoveLocation( udg_tempPoint1 )
          • Custom script: set udg_tempPoint1 = null
          • Custom script: call RemoveLocation( udg_tempPoint2 )
          • Custom script: set udg_tempPoint2 = null

Why does this trigger cause huge delay after about 10 minutes?





edited to fix the trigger.
 
Last edited:
Level 19
Joined
Aug 8, 2007
Messages
2,765
you dont have to null the variables.

what exactly are you trying to do with this trigger?
 
Level 6
Joined
Feb 10, 2011
Messages
188
Im sorry i was really tired when i made that, i fixed it now. I also updated the first post because i have a new question, why does this trigger make the game have delay after about 10 minutes? Do i have leaks?
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Im sorry i was really tired when i made that, i fixed it now. I also updated the first post because i have a new question, why does this trigger make the game have delay after about 10 minutes? Do i have leaks?


use a UnitIndexer and set it to a variable
based on the custom value of the defender

move the second if into the first if's else.

add a check to make sure that tempgroup1 isnt null, else you would
threadcrash

set the timer to something much higher, like 1 second. (this goes with the first suggestion, linking every defender to the tower physically. you could
just loop through every tower and check it that way, rather than checking
for base defender and linking the last defender.
 
Level 6
Joined
Feb 10, 2011
Messages
188
use a UnitIndexer and set it to a variable
based on the custom value of the defender

move the second if into the first if's else.

add a check to make sure that tempgroup1 isnt null, else you would
threadcrash

set the timer to something much higher, like 1 second. (this goes with the first suggestion, linking every defender to the tower physically. you could
just loop through every tower and check it that way, rather than checking
for base defender and linking the last defender.

Alright i been away for a few days, i was actually told you use an Unit Indexer before and i tried and well failed. I just give my self a big headache when trying to use it. But i did move the the second if.

so besides trying to use a unit indexer. How else would it be possible to do this without making the game lag.

Or

Why does this generate lag after a little while

Oh and just a side note, there is 146 Units in the base defender group at all times

Last thing, when i make the event timer higher, units are able to get out of the circle they are in.

to death: i did what you said to.


If you guys want to see the newest v, just look at top post. i edited it in
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
using unit indexer is very easy.

All you do is have arrays for the info you want to store.
damage / time / abi lvl / whatever you want.
you then give it a global group ( only use for this spell never destroy the group)

then when casting you store everything in the arrays using custom value of unit as the key value.

for a loop trigger you use a group loop and load data from arrays using custom value of picked unit.
 
Level 6
Joined
Feb 10, 2011
Messages
188
using unit indexer is very easy.

All you do is have arrays for the info you want to store.
damage / time / abi lvl / whatever you want.
you then give it a global group ( only use for this spell never destroy the group)

then when casting you store everything in the arrays using custom value of unit as the key value.

for a loop trigger you use a group loop and load data from arrays using custom value of picked unit.

I get the basics of it (i think), but i just cant get it to work. I just attempted to make a spell called roar that is susposed to damage units for 25 health per second for 30 seconds. it doesnt work

here is the triggers, lmk what i did wrong. maybe it will help me use it(the indexer) in my map

  • Custom Roar Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Custom Roar
    • Actions
      • Set Key = (Custom value of (Target unit of ability being cast))
      • Set RoarTime[Key] = 35
      • Set RoarDmg[Key] = 25.00
      • Unit Group - Add (Target unit of ability being cast) to RoarUnits
  • Custom Roar Loop
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in RoarUnits and do (Actions)
        • Loop - Actions
          • Set Key = (Custom value of (Picked unit))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • RoarTime[Key] Greater than or equal to 1
            • Then - Actions
              • Set RoarTime[Key] = (RoarTime[Key] - 1)
              • Unit - Set life of (Picked unit) to ((Life of (Picked unit)) - RoarDmg[Key])
            • Else - Actions
              • Unit Group - Remove (Picked unit) from RoarUnits
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
if you mean that you want to damage a unit 25 damage every second for 30 seconds then your problem is in your counter.
You need another integer array called counter
and a temp unit variable to store picked unit
after you store key in the second trigger you then need to reduce the counter and damage the unit. Also you should use 0.03 not 0.10
remember that at 0.03 your counter needs to be at integer 34 that will be for one second.

Right now your spell is only lasting about 3.5 seconds because of the counters.
 
Level 6
Joined
Feb 10, 2011
Messages
188
if you mean that you want to damage a unit 25 damage every second for 30 seconds then your problem is in your counter.
You need another integer array called counter
and a temp unit variable to store picked unit
after you store key in the second trigger you then need to reduce the counter and damage the unit. Also you should use 0.03 not 0.10
remember that at 0.03 your counter needs to be at integer 34 that will be for one second.

Right now your spell is only lasting about 3.5 seconds because of the counters.

Yes that is what i meant sorry.
How come i cant use my RoarTime as my timer? thats what i intended it for.
So what do i even do with Roartime if im going to add another integer array called counter?
I stored the unit to tempunit (although this isnt necessary right, just for optimizing?)
how come i should use .03 instead of .10, i thought that .10 was the lowest you could go and anything lower is read as .10?

Right now it doesnt seem to be lasting for any time, as no units are being damaged?

eh fuck it wanna give me an example of the counter variable using my triggers posted above
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
Yes that is what i meant sorry.
How come i cant use my RoarTime as my timer? thats what i intended it for.
So what do i even do with Roartime if im going to add another integer array called counter?
I stored the unit to tempunit (although this isnt necessary right, just for optimizing?)
how come i should use .03 instead of .10, i thought that .10 was the lowest you could go and anything lower is read as .10?

Right now it doesnt seem to be lasting for any time, as no units are being damaged?

its easier if you label questions as 1 / 2 and so on.

1) you can't use it as your timer because you actually need 2 timers one for interval time ( every second) and one for timeout time ( when spell ends)

2) this is just for speed and efficiency

3) 0.03 should be used because it gives the best visual time. Not sure were you heard that as you can actually use times all the way down to somewere in this area 0.00001
0.03 is the time were efficiency and visual effects become close 0.03125 is actually better but you can't use that in GUI.

4) It's not lasting because the timer period is disappearing is going fast.
0.10 means that the trigger runs 10 times every second so your spell will only last 3.5 seconds.
 
Level 6
Joined
Feb 10, 2011
Messages
188
its easier if you label questions as 1 / 2 and so on.

1) you can't use it as your timer because you actually need 2 timers one for interval time ( every second) and one for timeout time ( when spell ends)

2) this is just for speed and efficiency

3) 0.03 should be used because it gives the best visual time. Not sure were you heard that as you can actually use times all the way down to somewere in this area 0.00001
0.03 is the time were efficiency and visual effects become close 0.03125 is actually better but you can't use that in GUI.

4) It's not lasting because the timer period is disappearing is going fast.
0.10 means that the trigger runs 10 times every second so your spell will only last 3.5 seconds.

  • Custom Roar Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Custom Roar
    • Actions
      • Set Key = (Custom value of (Target unit of ability being cast))
      • Set RoarTime[Key] = 30
      • Set RoarDmg[Key] = 25.00
      • Unit Group - Add (Target unit of ability being cast) to RoarUnits
  • Custom Roar Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in RoarUnits and do (Actions)
        • Loop - Actions
          • Set tu = (Picked unit)
          • Set Key = (Custom value of tu)
          • Set Counter[Key] = 0.00
          • Set Counter[Key] = (Counter[Key] + 0.03)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Counter[Key] Less than 30.00
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • RoarTime[Key] Greater than 0
                • Then - Actions
                  • Set RoarTime[Key] = (RoarTime[Key] - 1)
                  • Unit - Set life of tu to ((Life of tu) - RoarDmg[Key])
                • Else - Actions
                  • Unit Group - Remove tu from RoarUnits
            • Else - Actions

well this is what i did, it still doesnt work. but im guessing im doing the counter var wrong?
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
Here is the right way.

  • Custom Roar Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Custom Roar
    • Actions
      • Set Key = (Custom value of (Target unit of ability being cast))
      • Set Counter[Key] = 0.00
      • Set RoarTime[Key] = 30
      • Set RoarDmg[Key] = 25.00
      • Unit Group - Add (Target unit of ability being cast) to RoarUnits
  • Custom Roar Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in RoarUnits and do (Actions)
        • Loop - Actions
          • Set tu = (Picked unit)
          • Set Key = (Custom value of tu)
          • Set Counter[Key] = (Counter[Key] + 0.03)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Counter[Key] Greater than or equal to 1.00
            • Then - Actions
              • Set Counter[Key] = 0.00
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • RoarTime[Key] Greater than 0
                • Then - Actions
                  • Set RoarTime[Key] = (RoarTime[Key] - 1)
                  • Unit - Set life of tu to ((Life of tu) - RoarDmg[Key])
                • Else - Actions
                  • Unit Group - Remove tu from RoarUnits
            • Else - Actions
 
Level 6
Joined
Feb 10, 2011
Messages
188
Here is the right way.

  • Custom Roar Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Custom Roar
    • Actions
      • Set Key = (Custom value of (Target unit of ability being cast))
      • Set Counter[Key] = 0.00
      • Set RoarTime[Key] = 30
      • Set RoarDmg[Key] = 25.00
      • Unit Group - Add (Target unit of ability being cast) to RoarUnits
  • Custom Roar Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in RoarUnits and do (Actions)
        • Loop - Actions
          • Set tu = (Picked unit)
          • Set Key = (Custom value of tu)
          • Set Counter[Key] = (Counter[Key] + 0.03)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Counter[Key] Greater than or equal to 1.00
            • Then - Actions
              • Set Counter[Key] = 0.00
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • RoarTime[Key] Greater than 0
                • Then - Actions
                  • Set RoarTime[Key] = (RoarTime[Key] - 1)
                  • Unit - Set life of tu to ((Life of tu) - RoarDmg[Key])
                • Else - Actions
                  • Unit Group - Remove tu from RoarUnits
            • Else - Actions

alright so i wasnt to far off. it makes a little more sense now and i just an idea on how to keep units within a certain range of there circle.

But on the other hand, the spell still doesnt work lol.

any idea why? did i do something else wrong?
 
Level 6
Joined
Feb 10, 2011
Messages
188
do you use bribes unit indexer ?

if you do then post the map or send it to me by pm and ill check it out tomorrow.

ya i am, im actually literally using his example map

i pm'd u

by the way, why do you have to use an indexer for things like this?

dont units already have a set custom value?
 
Level 6
Joined
Feb 10, 2011
Messages
188
Nope they are not.
Unit has 0 values because of the word "custom", meaning it is intended to be customized and used by the map maker.

If you are asking to their Handle Id then yes they have, though this count all of the child handles, includes units, buffs, events, destructables, effects, and more.

Oh, ok thanks for that!

So guys, back to my original question

Is there a reason that my trigger slowly adds lag to the game, Im guessing it a leak of some kind, but I don't seen anymore?
 
Level 6
Joined
Feb 10, 2011
Messages
188
Post the triggers so that I can inspect it.

Post it like :
  • Haha
    • Events
    • Conditions
    • Actions

  • Change Defender Range
    • Events
      • Time - Every 0.15 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in baseDefenders and do (Actions)
        • Loop - Actions
          • Set tempUnit1 = (Picked unit)
          • Set tempPoint1 = (Position of tempUnit1)
          • Set tempGroup1 = (Units within 300.00 of tempPoint1 matching ((Unit-type of (Matching unit)) Equal to Tower))
          • Set tempUnit2 = (Random unit from tempGroup1)
          • Set tempPoint2 = (Position of tempUnit2)
          • Set tempPlayer1 = (Owner of tempUnit1)
          • Set tempGroup2 = (Units within 175.00 of tempPoint2 matching ((((Matching unit) is A structure) Equal to False) and (((Owner of (Matching unit)) Equal to tempPlayer1) and ((Matching unit) Not equal to tempUnit1))))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between tempPoint1 and tempPoint2) Greater than or equal to 175.00
              • (Number of units in tempGroup2) Equal to 0
            • Then - Actions
              • -------- Move the defender back to the center of the CoP for his base, if he is the only unit around. --------
              • Unit - Move tempUnit1 instantly to tempPoint2
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Distance between tempPoint1 and tempPoint2) Greater than or equal to 175.00
                  • (Number of units in tempGroup2) Greater than or equal to 1
                • Then - Actions
                  • -------- This will switch the defender is there is another in the range. --------
                  • Unit Group - Remove tempUnit1 from baseDefenders
                  • Set tempUnit3 = (Random unit from tempGroup2)
                  • Unit Group - Add tempUnit3 to baseDefenders
                • Else - Actions
          • Custom script: set udg_tempUnit1 = null
          • Custom script: set udg_tempUnit2 = null
          • Custom script: set udg_tempUnit3 = null
          • Custom script: set udg_tempPlayer1 = null
          • Custom script: call DestroyGroup( udg_tempGroup1 )
          • Custom script: set udg_tempGroup1 = null
          • Custom script: call DestroyGroup( udg_tempGroup2 )
          • Custom script: set udg_tempGroup2 = null
          • Custom script: call RemoveLocation( udg_tempPoint1 )
          • Custom script: set udg_tempPoint1 = null
          • Custom script: call RemoveLocation( udg_tempPoint2 )
          • Custom script: set udg_tempPoint2 = null
its also on the first post btw.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
I don't think it's wise to dont remove the location and only null it.

what are you talking about ?

@rollindoubles
The reason that spell doesn't work is that is based from an Aoe spell not based off of channel with a unit target.
What that means is that target unit of ability being cast returns null.
Which means it's not attacking any specific unit.
Change to channel with target as unit target only if you want a one unit target.
If you want it to be Aoe then you need a unit group to pick units in range and then add them to the other unit group so their health gets reduced every second.

Please pay more attention to what you do rather than saying someone elses work doesn't work.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
again, you dont need to null them. theyre globals. you only need to null local handles

if you want to make it more efficient, move the if in the "else" into the "then", remove the distance check on it, and put the current "then" actions in the "else" of the second if. (if you can follow that :p)

you also dont need to set tempunit3, just use the (Random unit from blah)
 
Level 6
Joined
Feb 10, 2011
Messages
188
@ Almia haha well thanks anyways
@ deathismyfriend that was my first ever attempt at making a spell, i didnt know that about spells. and sorry didnt mean to offend you if i did.
@ daffa i really have no idea what u mean
@ arhowk 1. so the custom scripts where i nulled things like tempunit/points/groups are not needed?
2. by local handles you mean when using jass and using locals right? as you can use locals in GUI correct?
3. I thought that if i did not use tempunit3 and just used random unit from w/e it created a leak? Is that not the case?

and when i have time in a little bit i will try that out (the moving around of conditions my blocks)

After i do the suggested edits, I will edit this post and put the trigger in.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
1. so the custom scripts where i nulled things like tempunit/points/groups are not needed?
2. by local handles you mean when using jass and using locals right? as you can use locals in GUI correct?
3. I thought that if i did not use tempunit3 and just used random unit from w/e it created a leak? Is that not the case?

and when i have time in a little bit i will try that out (the moving around of conditions my blocks)

After i do the suggested edits, I will edit this post and put the trigger in.

Naa you didn't offend me i was just saying.

1) you don't have to null things. Nulling variables just clears the variable so it doesn't point to anything. I null all variables that won't be used that often.

2) Yes you can use locals in GUI look at my tutorial things a guier should know. It shows you local variables how to use them and it shows you how to shadow global variables.

3) Unit variables do not create a leak.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
@ Almia haha well thanks anyways
@ deathismyfriend that was my first ever attempt at making a spell, i didnt know that about spells. and sorry didnt mean to offend you if i did.
@ daffa i really have no idea what u mean
@ arhowk 1. so the custom scripts where i nulled things like tempunit/points/groups are not needed?
2. by local handles you mean when using jass and using locals right? as you can use locals in GUI correct?
3. I thought that if i did not use tempunit3 and just used random unit from w/e it created a leak? Is that not the case?

and when i have time in a little bit i will try that out (the moving around of conditions my blocks)

After i do the suggested edits, I will edit this post and put the trigger in.

above is right. only groups, forces, timers, locations (mightve forgotten one) leak and have to be destroyed via Destroy#
 
Level 6
Joined
Feb 10, 2011
Messages
188
Alright so i had some time to edit the trigger a little bit
here it is
  • Change Defender Range
    • Events
      • Time - Every 0.15 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in baseDefenders and do (Actions)
        • Loop - Actions
          • Set tempUnit1 = (Picked unit)
          • Set tempPoint1 = (Position of tempUnit1)
          • Set tempGroup1 = (Units within 300.00 of tempPoint1 matching ((Unit-type of (Matching unit)) Equal to Tower))
          • Set tempUnit2 = (Random unit from tempGroup1)
          • Set tempPoint2 = (Position of tempUnit2)
          • Set tempPlayer1 = (Owner of tempUnit1)
          • Set tempGroup2 = (Units within 175.00 of tempPoint2 matching ((((Matching unit) is A structure) Equal to False) and (((Owner of (Matching unit)) Equal to tempPlayer1) and ((Matching unit) Not equal to tempUnit1))))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between tempPoint1 and tempPoint2) Greater than or equal to 175.00
              • (Number of units in tempGroup2) Equal to 0
            • Then - Actions
              • -------- Move the defender back to the center of the CoP for his base, if he is the only unit around. --------
              • Unit - Move tempUnit1 instantly to tempPoint2
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Number of units in tempGroup2) Greater than or equal to 1
                • Then - Actions
                  • -------- This will switch the defender is there is another in the range. --------
                  • Unit Group - Remove tempUnit1 from baseDefenders
                  • Unit Group - Add (Random unit from tempGroup2) to baseDefenders
                • Else - Actions
            • Else - Actions
          • Custom script: call DestroyGroup( udg_tempGroup1 )
          • Custom script: call DestroyGroup( udg_tempGroup2 )
          • Custom script: call RemoveLocation( udg_tempPoint1 )
          • Custom script: call RemoveLocation( udg_tempPoint2 )
@death i just read your tutorial on using local calls in GUI, but i didnt see this answer in your tut.
Is it faster to use local or global variables? I feel like locals would be, am i right?

@arhowk So i did what u suggested with moving my blocks around, but this confused me a little: and put the current "then" actions in the "else" of the second if. by current then did u mean the then in the first ITE block? and if i that is what u meant, how would that work? (as in would the trigger work?) just for an example this is what im reading it as
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (Distance between tempPoint1 and tempPoint2) Greater than or equal to 175.00
      • (Number of units in tempGroup2) Equal to 0
    • Then - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in tempGroup2) Greater than or equal to 1
        • Then - Actions
          • -------- This will switch the defender is there is another in the range. --------
          • Unit Group - Remove tempUnit1 from baseDefenders
          • Unit Group - Add (Random unit from baseDefenders) to baseDefenders
        • Else - Actions
          • -------- Move the defender back to the center of the CoP for his base, if he is the only unit around. --------
          • Unit - Move tempUnit1 instantly to tempPoint2
    • Else - Actions
Now i have a question for you arhowk in your first post in this thread you said to do this:
add a check to make sure that tempgroup1 isnt null, else you would
threadcrash

I just want to know why and what is a threadcrash.
The reason i want to know why is because the way this trigger works is that since it loops through the defender and they are always kept within 175 distance of the base, should i still check to see if it is null? since it picks all units within 300 of the defender.

Also i am trying to do this using a unit indexer, but im still a noob when it comes to indexing (ok ya im a noob at triggering period, thats besides the point :p ) So until i figure it out, whats a better way to do what this trigger does.
Also, i been looking into jass a little. If i was to make a function that took an integer and a unit and return a boolean. could i make it work?
my idea of the function would be to take the integer (distance between the unit and the base) and the unit (defender) and return true if it (the defender) is within the right range, and return false if it is not? (although i really note sure how i would write the function so that is not viable... yet)

on a side note, from what i know the things that make a game lag is when a trigger leaks and after so much build of of those leaks u get noticeable lag.
So when i disable this trigger i get no lag at all even after of sitting afk in the game for a few hours, when this trigger is enabled i start to see the lag after about 5 minutes.

1.Why is it generating lag if there is no more leaks (as far as i know)
2. Is it just bad coding?


Had to edit what i did before, maybe i mis read what arhowk suggested, but when i had the trigger the way it is at the top of this post, it doesnt work correctly. When switching defenders the new defender would be able to leave the circle.
here is what is it currently (working 100 percent, but causes lag)
  • Change Defender Range
    • Events
      • Time - Every 0.15 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in baseDefenders and do (Actions)
        • Loop - Actions
          • Set tempUnit1 = (Picked unit)
          • Set tempPoint1 = (Position of tempUnit1)
          • Set tempGroup1 = (Units within 300.00 of tempPoint1 matching ((Unit-type of (Matching unit)) Equal to Tower))
          • Set tempUnit2 = (Random unit from tempGroup1)
          • Set tempPoint2 = (Position of tempUnit2)
          • Set tempPlayer1 = (Owner of tempUnit1)
          • Set tempGroup2 = (Units within 175.00 of tempPoint2 matching ((((Matching unit) is A structure) Equal to False) and (((Owner of (Matching unit)) Equal to tempPlayer1) and ((Matching unit) Not equal to tempUnit1))))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between tempPoint1 and tempPoint2) Greater than or equal to 175.00
              • (Number of units in tempGroup2) Equal to 0
            • Then - Actions
              • -------- Move the defender back to the center of the CoP for his base, if he is the only unit around. --------
              • Unit - Move tempUnit1 instantly to tempPoint2
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Number of units in tempGroup2) Greater than or equal to 1
                • Then - Actions
                  • -------- This will switch the defender is there is another in the range. --------
                  • Unit Group - Remove tempUnit1 from baseDefenders
                  • Unit Group - Add (Random unit from tempGroup2) to baseDefenders
                • Else - Actions
          • Custom script: call DestroyGroup( udg_tempGroup1 )
          • Custom script: call DestroyGroup( udg_tempGroup2 )
          • Custom script: call RemoveLocation( udg_tempPoint1 )
          • Custom script: call RemoveLocation( udg_tempPoint2 )

by the way guys, thanks ton for all the help, + rep for both of u
 
Last edited:
Level 19
Joined
Aug 8, 2007
Messages
2,765
im not going to quote that post because its long..

ignore the group comment, im used to JASS where GroupEnumUnitsInRange doesn't create the group for you

in ur "ITE Blocks" trigger, the issue is that the first "number of units in group" check shouldnt be there. it should be

if distance > 175
then (see how i left out the num units in group == 0)
if num units in group == 0
move unit back
else
set new unit as defender
endif
endif

I'd still recommend setting the timer higher, to like 0.4 or 0.5. A unit can walk (movespeed) range every second, so a unit with capped movespeed (522) will be able to walk 261 in 0.5 seconds, 175+261=436, which means you increase the distance check for the initial defender to 436, or leave it at 300 and change time to 0.22 seconds (exact time is 0.239) which is the bare minimum if u want the range to be 300.

Unit indexing is pretty simple, you can get an array-friendly integer based on the unit (after implementing the system), and every unit's integer is different with
Custom value of (x)

so if you would do

set towers[custom value of guardian] = custom value of tower

to get the tower that the unit is chained to

UDexUnits[towers[custom value of guardian]] is your tower (UDexUnits is a variable generated by the unit indexer that is essentially the reverse of custom value, it takes the integer custom value of the unit and returns what unit has that custom value assigned)

E/ just spent ten minutes staring at Almia and daffa's avatars
 
Level 6
Joined
Feb 10, 2011
Messages
188
im not going to quote that post because its long..

ignore the group comment, im used to JASS where GroupEnumUnitsInRange doesn't create the group for you

in ur "ITE Blocks" trigger, the issue is that the first "number of units in group" check shouldnt be there. it should be

if distance > 175
then (see how i left out the num units in group == 0)
if num units in group == 0
move unit back
else
set new unit as defender
endif
endif

I'd still recommend setting the timer higher, to like 0.4 or 0.5. A unit can walk (movespeed) range every second, so a unit with capped movespeed (522) will be able to walk 261 in 0.5 seconds, 175+261=436, which means you increase the distance check for the initial defender to 436, or leave it at 300 and change time to 0.22 seconds (exact time is 0.239) which is the bare minimum if u want the range to be 300.

Unit indexing is pretty simple, you can get an array-friendly integer based on the unit (after implementing the system), and every unit's integer is different with
Custom value of (x)

so if you would do

set towers[custom value of guardian] = custom value of tower

to get the tower that the unit is chained to

UDexUnits[towers[custom value of guardian]] is your tower (UDexUnits is a variable generated by the unit indexer that is essentially the reverse of custom value, it takes the integer custom value of the unit and returns what unit has that custom value assigned)

E/ just spent ten minutes staring at Almia and daffa's avatars

I been busy with other things lately. I just re organized the way you said it, I will try the custom value thing next, but ill have to redo most my other triggers to.

So im watching my memory while letting the game run, it jumps up by around 20-100kb every second, (or less idk i cant tell) currently its at 180,000 kb
Without the trigger, it sits around 165,000 kb total memory. moves up and down a lil bit.

  • Change Defender Range
    • Events
      • Time - Every 0.50 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in baseDefenders and do (Actions)
        • Loop - Actions
          • Set tempUnit1 = (Picked unit)
          • Set tempPoint1 = (Position of tempUnit1)
          • Set tempGroup1 = (Units within 436.00 of tempPoint1 matching ((Unit-type of (Matching unit)) Equal to Tower))
          • Set tempUnit2 = (Random unit from tempGroup1)
          • Set tempPoint2 = (Position of tempUnit2)
          • Set tempPlayer1 = (Owner of tempUnit1)
          • Set tempGroup2 = (Units within 175.00 of tempPoint2 matching ((((Matching unit) is A structure) Equal to False) and (((Owner of (Matching unit)) Equal to tempPlayer1) and ((Matching unit) Not equal to tempUnit1))))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between tempPoint1 and tempPoint2) Greater than or equal to 175.00
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Number of units in tempGroup2) Equal to 0
                • Then - Actions
                  • Unit - Move tempUnit1 instantly to tempPoint2
                • Else - Actions
                  • Unit Group - Remove tempUnit1 from baseDefenders
                  • Unit Group - Add (Random unit from tempGroup2) to baseDefenders
            • Else - Actions
          • Custom script: call DestroyGroup( udg_tempGroup1 )
          • Custom script: call DestroyGroup( udg_tempGroup2 )
          • Custom script: call RemoveLocation( udg_tempPoint1 )
          • Custom script: call RemoveLocation( udg_tempPoint2 )
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
(Is it just me, or are
  • tags not working anymore? I can't collapse the windows on his tags)
  • I don't see a leak, but if I re-write the trigger in JASS would you implement it? (just so I'm not wasting my time)
 
Level 6
Joined
Feb 10, 2011
Messages
188
(Is it just me, or are
  • tags not working anymore? I can't collapse the windows on his tags)
  • I don't see a leak, but if I re-write the trigger in JASS would you implement it? (just so I'm not wasting my time)[/QUOTE]
  • yes, i will take u up on this offer :P even though im late
 
Level 6
Joined
Feb 10, 2011
Messages
188
Oh sorry I haven't been on in a while because my internet is being trippy. Yeah I'll post it ASAP

thanks man

hey, i dont want to post a new thread atm, maybe u guys will see this. I was looking at GUI coding on wc3c and i seen a guy do like a custom script event type thing it was A unit enters a region is there a way to do this? or was he just editing the code in the tags he posted? here is what he posted
  • Events
    • A Unit enters a region
  • Conditions
  • Actions
    • For each integer A beteen 0 and <arraysize>, do actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Triggering Unit) is in Region[Integer A]
        • Then - Actions
          • (Your Actions Here)
        • Else - Actions
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
thanks man

hey, i dont want to post a new thread atm, maybe u guys will see this. I was looking at GUI coding on wc3c and i seen a guy do like a custom script event type thing it was A unit enters a region is there a way to do this? or was he just editing the code in the tags he posted? here is what he posted
  • Events
    • A Unit enters a region
  • Conditions
  • Actions
    • For each integer A beteen 0 and <arraysize>, do actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Triggering Unit) is in Region[Integer A]
        • Then - Actions
          • (Your Actions Here)
        • Else - Actions

You can just use (playable map area) if you needed to. This would run when the unit is created. If you need only specific regions, you can do

  • Trigger - Add (Any unit enters <Your Region>) to <Your Trigger>
Is there a function for when a unit enters any region currently in memory? no.

E/ for your trigger, do you care if the checking area is a square instead of a circle? it would make it alot faster
 
Last edited:
Level 6
Joined
Feb 10, 2011
Messages
188
You can just use (playable map area) if you needed to. This would run when the unit is created. If you need only specific regions, you can do

  • Trigger - Add (Any unit enters <Your Region>) to <Your Trigger>
Is there a function for when a unit enters any region currently in memory? no.

E/ for your trigger, do you care if the checking area is a square instead of a circle? it would make it alot faster

I wasn't aware that you could check in a square radius, If you want to do that its fine with me, really you can do any modifications you need to. Ill be pretty interested to learn from it.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
I wasn't aware that you could check in a square radius, If you want to do that its fine with me, really you can do any modifications you need to. Ill be pretty interested to learn from it.

Ok sorry its been a while and im lost so I can't remember lol. This seems to work without lag, havent tested leaks
 

Attachments

  • BD.w3x
    17.7 KB · Views: 31
Level 19
Joined
Aug 8, 2007
Messages
2,765
you may post the triggers as well, so we can help finding those leaks too

Please don't post in white... i purposely run on low graphics so the page loads faster and i have to highlight your text to see what it is.

JASS:
library BaseDefenders initializer onBDInit
    globals
        private real radius = 175
        private real checkRadius = 375
        private real period = 0.7
        private unit host
        private filterfunc checkFilter
    endglobals
    
    private function enumFilter takes nothing returns boolean
        return GetFilterUnit() != host and GetOwningPlayer(host) == GetOwningPlayer(GetFilterUnit())
    endfunction
    
    private function looper takes nothing returns nothing
        local unit u
        local item i
        local group g = CreateGroup()
        local group g2 = CreateGroup()
        call GroupAddGroup(udg_BD_Bases, g)
        loop  
            set host = FirstOfGroup(g)
            exitwhen host == null
            call GroupClear(g2)
            call GroupEnumUnitsInRange(g2, GetUnitX(host), GetUnitY(host), radius, checkFilter)
            if FirstOfGroup(g2) == null then
                call GroupClear(g2)
                call GroupEnumUnitsInRange(g2, GetUnitX(host), GetUnitY(host), checkRadius, checkFilter)
                set u = FirstOfGroup(g2)
                if u != null then
                    set i = CreateItem('hval', GetUnitX(host), GetUnitY(host))
                    call IssueImmediateOrder(u, "stop" )
                    call SetUnitX(u, GetItemX(i))
                    call SetUnitY(u, GetItemY(i))
                    call RemoveItem(i)
                endif
            endif
            call GroupRemoveUnit(g,host)
        endloop
        set u = null
        set i = null
        call DestroyGroup(g)
        call DestroyGroup(g2)
        set g = null
        set g2 = null
    endfunction
    private function onBDInit takes nothing returns nothing
        set checkFilter = Filter(function enumFilter)
        call TimerStart(CreateTimer(), period, true, function looper)
    endfunction
endlibrary

E/ noticed that the GroupAddGroup can be changed to this

JASS:
        set bj_groupAddGroupDest = g
        call ForGroup(udg_BD_Bases, function GroupAddGroupEnum)
 
Level 6
Joined
Feb 10, 2011
Messages
188
Ok, I just did some editing with my recently learned very basic knowledge of jass and it is working as intended. Units were able to get away before, So far no units have got away.

Thankyou a ton arhawk, this kinda inspires me to really learn (v)jass

Ok here is the code with all my edits
1. changed radius to 150
2. changed checkradius to 400
3. changed the filter to filter structures instead of just the host building.
4. added another filter to select units not owned by the current owner
5. removed the use of the item
6. (hopefully) made it so that if there is no units in the radius, another player can take the base over by moving into the checkradius, let me know if this is done correctly

JASS:
library BaseDefenders initializer onBDInit
    globals
        private real radius = 150
        private real checkRadius = 400
        private real period = 0.7
        private unit host
        private unit tower
        private filterfunc checkFilter
        private filterfunc checkFilterTwo
    endglobals
    
    private function enumFilter takes nothing returns boolean
        return IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) !=true and GetOwningPlayer(host) == GetOwningPlayer(GetFilterUnit())
    endfunction
    
    private function enumFilterTwo takes nothing returns boolean
        return IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) !=true and GetOwningPlayer(host) != GetOwningPlayer(GetFilterUnit())
    endfunction
    
    private function looper takes nothing returns nothing
        local unit u
        local item i
        local group g = CreateGroup()
        local group g2 = CreateGroup()
        local group g3 = CreateGroup()
        set bj_groupAddGroupDest = g
        call ForGroup(udg_BD_Bases, function GroupAddGroupEnum)
        set bj_groupAddGroupDest = g3
        call ForGroup(udg_BD_Bases, function GroupAddGroupEnum)
        loop  
            set host = FirstOfGroup(g)
            exitwhen host == null
            set tower = FirstOfGroup(g3)
            call GroupClear(g2)
            call GroupEnumUnitsInRange(g2, GetUnitX(host), GetUnitY(host), radius, checkFilter)
            if FirstOfGroup(g2) == null then
                call GroupClear(g2)
                call GroupEnumUnitsInRange(g2, GetUnitX(host), GetUnitY(host), checkRadius, checkFilter)
                set u = FirstOfGroup(g2)
                if u != null then
                    call SetUnitX(u, GetUnitX(host))
                    call SetUnitY(u, GetUnitY(host))
                    call IssueImmediateOrder (u, "stop")
                else
                    call GroupClear(g2)
                    call GroupEnumUnitsInRange(g2, GetUnitX(host), GetUnitY(host), checkRadius, checkFilterTwo)
                    set u = FirstOfGroup(g2)
                    call SetUnitX(u, GetUnitX(host))
                    call SetUnitY(u, GetUnitY(host))
                    call IssueImmediateOrder (u, "stop")
                    call SetUnitOwner (host, GetOwningPlayer(u),true)
                    call SetUnitOwner (tower,GetOwningPlayer(u),true)
                endif
            endif
            call GroupRemoveUnit(g,host)
            call GroupRemoveUnit(g3,tower)
        endloop
        set u = null
        set i = null
        call DestroyGroup(g)
        call DestroyGroup(g2)
        set g = null
        set g2 = null
    endfunction
    private function onBDInit takes nothing returns nothing
        set checkFilter = Filter(function enumFilter)
        set checkFilterTwo = Filter(function enumFilterTwo)
        call TimerStart(CreateTimer(), period, true, function looper)
    endfunction
endlibrary

Ok, so i found one last problem. It seems to stop working once there is a few dead units in the radius and checkradius. How would i make it check for alive units only, im pretty sure its this, because i made a trigger to remove dead units and it works. if i turn it off and let units decay it messes up.
 
Last edited:
Level 19
Joined
Aug 8, 2007
Messages
2,765
o_O im sorry that post never showed up on my notifications bar. Have you gotten it working? else i can fix it
 
Status
Not open for further replies.
Top