• 🏆 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] Unit group attack random unit owned by random player does not work

Status
Not open for further replies.
Level 2
Joined
Jun 13, 2020
Messages
16
Hey guys, I am having trouble with my trigger at the below

Basically,the enemy_group only attack the player 1 units only,although I had put other player's units in the map.


NOPlayer is a integer variable.
Allies of player 1 is player 1 to 6

Rich (BB code):
  • Demon Creep
    • Events
    • Conditions
    • Actions
      • Set Enemy_player = (Random player from (All allies of Player 1 (Red)))
      • Set Temp_Group[1] = (Units owned by Player 7 (Green) matching (((Matching unit) is alive) Equal to True))
      • Set Temp_Group[2] = (Units owned by Enemy_player matching (((Matching unit) is alive) Equal to True))
      • Set Temp_Unit = (Random unit from Temp_Group[2])
      • Set attack_group = (Random ((Random integer number between 3 and 6) x NOPlayer) units from Temp_Group[1])
      • Custom script: set bj_wantDestroyGroup =true
      • Unit Group - Pick every unit in attack_group and do (Actions)
        • Loop - Actions
          • Unit - Order (Picked unit) to Attack-Move To (Position of Temp_Unit)
  • Demon Creep
    • Events
    • Conditions
    • Actions
      • Set Enemy_player = (Random player from (All allies of Player 1 (Red)))
      • Set Temp_Group[1] = (Units owned by Player 7 (Green) matching (((Matching unit) is alive) Equal to True))
      • Set Temp_Group[2] = (Units owned by Enemy_player matching (((Matching unit) is alive) Equal to True))
      • Set Temp_Unit = (Random unit from Temp_Group[2])
      • Set attack_group = (Random ((Random integer number between 3 and 6) x NOPlayer) units from Temp_Group[1])
      • Custom script: set bj_wantDestroyGroup =true
      • Unit Group - Pick every unit in attack_group and do (Actions)
        • Loop - Actions
          • Unit - Order (Picked unit) to Attack-Move To (Position of Temp_Unit)
  • Temp Dies
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Dying unit) Equal to (Random unit from attack_group)
        • Then - Actions
          • Unit Group - Remove (Dying unit) from attack_group
          • Trigger - Run Demon Creep <gen> (ignoring conditions)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Dying unit) Equal to Temp_Unit
        • Then - Actions
          • Unit Group - Remove (Dying unit) from Temp_Group[2]
          • Trigger - Run Demon Creep <gen> (ignoring conditions)
        • Else - Actions
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,534
1) Delete all of these:
  • Custom script: set bj_wantDestroyGroup = true
You don't want to destroy any of these Unit Groups except for TempGroup[1]. TempGroup[1] can be destroyed after you create attack_group:
  • Custom script: call DestroyGroup(udg_Temp_Group[1])

2) TempGroup[2] shouldn't be a Temp variable. It's used in the Temp Dies trigger so it's not TEMPorary at all, it's something you intend to keep around and it holds a unique purpose.

3) You're leaking a Point whenever you do: (Position of Temp_Unit)

4) This condition doesn't make any sense, it'll hardly ever be true since there could be 20+ different units in that unit group, the odds that it finds itself are slim:
  • (Dying unit) Equal to (Random unit from attack_group)
Instead, use this Boolean to check if the dying unit is in the unit group:
  • Dying unit is in attack_group Equal to True
A Temp variable example:
  • Set Variable Temp_Point = Center of playable map area
  • Unit - Create 1 Footman at Temp_Point facing 270 degrees
  • Custom script: call RemoveLocation(udg_Temp_Point)
This is how you use a Temp variable. It's Set, used, and then IMMEDIATELY removed when it's done. The variable must be removed (aka destroyed) before you Set it again or it will leak (if it's a leakable variable type, units, integers, reals, strings, and booleans don't leak). If it's not a leak issue it can still cause problems if it's intended for MUI use.

So you shouldn't use Temp variables this way. For information that you want to keep track of over time you should use unique variables, something like DemonCreep_Group to keep track of the enemy units. And you wouldn't constantly Set this Unit Group but instead Add/Remove units from it. Setting a Unit Group is most often used because you intend to either NEVER Set it again, or Destroy it soon after.

Another big issue here is that it's not designed to be MUI. But I don't know if you want it to be or not... Does Demon Creep run more than once? And if yes, you need to account for that by clearing all of it's variables before setting them again or using Add/Remove with your Unit Group instead of Setting it.
 
Last edited:
Level 2
Joined
Jun 13, 2020
Messages
16
Ya,this trigger is always running through out the entire game.In fact,I am making the game that have the similar spawning mechanic to the Infection attack.

Basically,the units(Demon Creeps) will spwan at the specific region and when this trigger is executed,the trigger I stated at the above will be executed too.Each wave (each 220 second s) will add in the new unit type of demon creep that have different spawn rate.
The problem now is the demon creeps don't attack the other player. But since you help me so many times,I want to do this by myself.If possible can you send the tutorials about the unit wave trigger.I tried to search it by myself but I can't find a really useful one.
Besides that,I have other off topic question
1. When using the dynamic indexing system (MUI spell system),what is the size of variable (like unit_group) needed to assign?
2. Is the hastable only save ONE data?Example when I like to save the angle for each units in a unit_group,will angle of each units will be saved or only angle one units will be saved.

Thks for reply btw 😀😀😀
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,534
1. The Size determines how many Unit Groups you can use. But you can also manually create the Unit Groups yourself with Custom script which removes the need for changing the Size. The Size just initializes X number of Unit Groups for use (Initialize = Creates them, like I'm doing below):
  • Custom script: set udg_SomeGroup[10] = CreateGroup()

2. If you really know what you're doing you could use a single Hashtable to save just about everything. So yes, you can save the angle of each unit in the Hashtable. Understand that each object (unit, item, location, etc) has it's own unique Handle Id, this is an Integer id that'll look something like 102459674 (just an example number). This Handle Id is ALWAYS different for each object. So when you save the Handle of some Unit to a Hashtable, you're basically saving that unique Integer (again, let's pretend it's 102459674 for the sake of this example).

Save Handle of (Triggering Unit) as 100 of 1 in SomeHashtable translates to: Save 102459674 as 100 of 1 in SomeHasthable.

102459674 is the Handle of (Triggering Unit). No other Unit (or other type of game object) will have this Handle.


If I get the chance I can try and create some working examples of your system.
 
Last edited:
Level 2
Joined
Jun 13, 2020
Messages
16
Ok,I give up :(.
These are the triggers I try to create and its turn out really bad:(.

UnpickedGroup variable is the group of units that are not in attack_group
Surviver is the units that determine the win/lose of players


[
Rich (BB code):
  • Untitled Trigger 001
    • Events
      • Time - Elapsed game time is 5.00 seconds
    • Conditions
    • Actions
      • Player Group - Pick every player in (All allies of Player 1 (Red)) and do (Actions)
        • Loop - Actions
          • Set player = (Player number of (Picked player))
          • Set GroupInteger = 0
          • For each (Integer player) from 1 to 6, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Player(player)) slot status) Equal to Is playing
                • Then - Actions
                  • Set GroupInteger = (GroupInteger + 1)
                  • Set Temp_Unit[GroupInteger] = (Random unit from (Units owned by (Player(player)) of type Surviver))
                • Else - Actions
  • Demon Creep
    • Events
    • Conditions
    • Actions
      • For each (Integer GroupInteger) from 1 to GroupInteger, do (Actions)
        • Loop - Actions
          • Set Temp_Group[1] = (Units owned by Player 7 (Green) matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) is in UnPickedGroup) Equal to True)))
          • Set Temp_Group[2] = (Random (Random integer number between Integer and (4 + (Integer x 2))) units from Temp_Group[1])
          • Set Temp_point[GroupInteger] = (Position of Temp_Unit[GroupInteger])
          • Unit Group - Add all units of Temp_Group[1] to attack_group[GroupInteger]
          • Unit Group - Order attack_group[GroupInteger] to Attack-Move To Temp_point[GroupInteger]
          • Custom script: call DestroyGroup(udg_Temp_Group[1])
          • Custom script: call DestroyGroup(udg_Temp_Group[2])
  • Temp Dies
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • For each (Integer GroupInteger) from 1 to GroupInteger, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Dying unit) is in attack_group[GroupInteger]) Equal to True
            • Then - Actions
              • Trigger - Run Demon Creep <gen> (ignoring conditions)
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Dying unit) Equal to Temp_Unit[GroupInteger]
                • Then - Actions
                  • Unit Group - Pick every unit in attack_group[GroupInteger] and do (Actions)
                    • Loop - Actions
                      • Unit Group - Add (Picked unit) to UnPickedGroup
                  • Unit Group - Remove all units from attack_group[GroupInteger]
                  • Custom script: call DestroyGroup(udg_attack_group[udg_GroupInteger])
                  • Trigger - Run Demon Creep <gen> (ignoring conditions)
                • Else - Actions
 
Last edited:
Level 25
Joined
Sep 26, 2009
Messages
2,378
well, your triggers are a mess, that's why they don't work.

First of all, you should make sure that your players are even set up correctly. You can check it via trigger like this:
  • Debug players
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Player Group - Pick every player in (All allies of Player 1 (Red).) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked player) slot status) Equal to Is playing
            • Then - Actions
              • Game - Display to (All players) the text: (Player + ((String((Player number of (Picked player)))) + is playing))
            • Else - Actions
              • Game - Display to (All players) the text: (Player + ((String((Player number of (Picked player)))) + is NOT playing))
If you are player 1, then pressing Esc key should write if all allies of said player are playing or not.

You seem to misunderstand how loops work. The loop signature is:
  • For each (Integer CURRENT) from START to END, do (Actions)
Loop basics are as following:
  1. The first loop iteration starts at number START
  2. The value in START is assigned to variable CURRENT
  3. If number in CURRENT is greater than value in END, the loop ends. If the condition is not true, then the loop body is executed
  4. When loop body has been executed, the value in CURRENT is increased by 1
  5. We go back to step 3, effectively looping so long as the condition I described in step 3 is not true.
So if you have this piece of code:
  • For each (Integer x) from 40 to 42, do (Actions)
    • Loop - Actions
      • Game - Display to (All players) the text: (String(x))
This will be printed in your game:
40
41
42

Now, in your Demon Creep and Temp Dies triggers this is how your loops are set up:
  • For each (Integer GroupInteger) from 1 to GroupInteger, do (Actions)
If your GroupInteger is 0, then the loop won't execute at all, however if GroupInteger is at least 1, then you may experience a lag or even game crash.
If you go by the steps I wrote earlier, since the value in CURRENT is increased by 1 each time the loop body is executed and since you use same variable for CURRENT and END, then you also increase the END value by 1 each time loop body is executed. So what you end up is an endless loop.


Your Untitled Trigger 001 trigger does not make much sense. For each ally of player 1 (which as you wrote should be players 1 to 6) you execute a loop in which you check if player 1 to 6 are playing. So you are effectively checking each player (1 to 6) 6 times, ending up with 36 checks instead of 6.
You also assign the player number of currently iterated player into variable "player", only to overwrite the variable two rows later:
  • Set player = (Player number of (Picked player))
  • ...
  • For each (Integer player) from 1 to 6, do (Actions)
Your Temp_Unit[GroupInteger] will get overwritten by each player picked in the action
  • Player Group - Pick every player in (All allies of Player 1 (Red)) and do (Actions)

In your Demon Creep trigger you are not using Temp_Group[2] at all.
You assign units to Temp_Group[1] which are in UnPickedGroup, but I don't see you managing that group anywhere in your triggers. You only ever add units to UnPickedGroup, but I assume you should also be removing units from that group if they are picked.
You assing units to attack_group like this:
  • Unit Group - Add all units of Temp_Group[1] to attack_group[GroupInteger]
and later, in your other trigger you destroy the group via
  • Custom script: call DestroyGroup(udg_attack_group[udg_GroupInteger])
However you are not creating new unit groups anywhere. The "Unit Group - Add all units" actions attempts to add unit to existing unit group, which will not be your case later in the game.


In your Temp Dies trigger you have this loop:
  • For each (Integer GroupInteger) from 1 to GroupInteger, do (Actions)
in which you start another trigger via this action:
  • Trigger - Run Demon Creep <gen> (ignoring conditions)
In your Demon Creep trigger you have another loop that uses the same global variable GroupInteger.
Since GroupInteger is global, then the loop inside your Demon Creep trigger cause your loop in Temp Dies trigger to exit prematurely.
 
Level 2
Joined
Jun 13, 2020
Messages
16
Thks for reply and reviewing such a bad trigger! When see my trigger back, it was truly a mess haha😗.At that time I feel very unmotivated and tired cause I was struggling with quite a long time.Next time I will check again my trigger before I post it.
 
Level 2
Joined
Jun 13, 2020
Messages
16
I come out with a new trigger but I don't know whether it is working or not.As far as I knew the possible problem with these triggers is each time it executed will leak one unit group and point(seem like these leaks cannot be prevent)

Q: Does this function cause the point/location to leak?
Unit-order the unit to attack move to Hastable-load unit location

Rich (BB code):
  • Demon Creep
    • Events
    • Conditions
    • Actions
      • Set Alliance_Group = (All allies of Player 1 (Red))
      • Player Group - Pick every player in Alliance_Group and do (Actions)
        • Loop - Actions
          • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is alive) Equal to True
                  • (Owner of (Picked unit)) Equal to Player 7 (Green)
                  • ((Picked unit) is in UnPickableGroup) Equal to False
                • Then - Actions
                  • Set Targeted_unit = (Random unit from (Units owned by (Random player from Alliance_Group) matching (((Matching unit) Not equal to Targeted_unit) and (((Matching unit) is alive) Equal to True))))
                  • Unit Group - Add Targeted_unit to TargetedGroup
                  • Unit Group - Pick every unit in TargetedGroup and do (Actions)
                    • Loop - Actions
                      • Set Targeted_unit = (Picked unit)
                      • Set Targeted_unit_Point = (Position of Targeted_unit)
                      • Hashtable - Save Handle OfTargeted_unit_Point as (Key (Picked unit)) of (Key (Picked unit)) in UnitHastable
                      • Unit Group - Remove (Picked unit) from TargetedGroup
                  • Unit - Order (Picked unit) to Attack-Move To Targeted_unit_Point
                  • Unit Group - Add (Picked unit) to UnPickableGroup
                • Else - Actions
      • Custom script: call DestroyForce(udg_Alliance_Group)
  • Temp Dies
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Triggering unit) Equal to Targeted_unit
        • Then - Actions
          • Set Targeted_unit_Point = (Load (Key (Triggering unit)) of (Key (Triggering unit)) in UnitHastable)
          • Custom script: call RemoveLocation(udg_Targeted_unit_Point)
          • Hashtable - Clear all child hashtables of child (Key (Triggering unit)) in (Last created hashtable)
          • Unit Group - Remove (Killing unit) from UnPickableGroup
          • Trigger - Run Demon Creep <gen> (ignoring conditions)
        • Else - Actions
 
Last edited:
Status
Not open for further replies.
Top