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

Stupid question, How to select all players in the game?

Level 8
Joined
Dec 1, 2010
Messages
316
So i triggered quite a bit today and to my suprise most of it worked. However after updating the forces and adding 8 slots for the players in the game i noticed the following trigger seems to be incorrectly spawning units for players that don't have an active user in them.

I want the player group to pick only players that are controlled by a human and currently in the game.

What would be the best way to go about this.? I assumed all players controlled by a user player would be correct but it also spawns units for empty player slots. for reference here are my player properties. after adding players here my trigger stopped working like intended.

1708040738821.png



  • deploy1
    • Events
      • Game - waveDeploy becomes Equal to 1.00
    • Conditions
      • waveNumber Equal to 0
    • Actions
      • Player Group - Pick every player in (All players controlled by a User player) and do (Actions)
        • Loop - Actions
          • Unit - Create 1 Bandit for Player 21 (Coal) at (Center of creepIsland[(Player number of (Picked player))]) facing Default building facing degrees
          • Hashtable - Save (Player number of (Picked player)) as 1 of (Key (Last created unit).) in hashtable.
          • Set VariableSet waveUnit[(Integer(((String((Player number of (Picked player)))) + (String(1)))))] = (Last created unit)
          • Unit - Create 1 Bandit for Player 21 (Coal) at (Center of creepIsland[(Player number of (Picked player))]) facing Default building facing degrees
          • Hashtable - Save (Player number of (Picked player)) as 1 of (Key (Last created unit).) in hashtable.
          • Set VariableSet waveUnit[(Integer(((String((Player number of (Picked player)))) + (String(2)))))] = (Last created unit)
          • Unit - Create 1 Bandit for Player 21 (Coal) at (Center of creepIsland[(Player number of (Picked player))]) facing Default building facing degrees
          • Hashtable - Save (Player number of (Picked player)) as 1 of (Key (Last created unit).) in hashtable.
          • Set VariableSet waveUnit[(Integer(((String((Player number of (Picked player)))) + (String(3)))))] = (Last created unit)
          • Unit - Create 1 Bandit for Player 21 (Coal) at (Center of creepIsland[(Player number of (Picked player))]) facing Default building facing degrees
          • Hashtable - Save (Player number of (Picked player)) as 1 of (Key (Last created unit).) in hashtable.
          • Set VariableSet waveUnit[(Integer(((String((Player number of (Picked player)))) + (String(4)))))] = (Last created unit)
          • Unit - Create 1 Bandit for Player 21 (Coal) at (Center of creepIsland[(Player number of (Picked player))]) facing Default building facing degrees
          • Hashtable - Save (Player number of (Picked player)) as 1 of (Key (Last created unit).) in hashtable.
          • Set VariableSet waveUnit[(Integer(((String((Player number of (Picked player)))) + (String(5)))))] = (Last created unit)
          • Set VariableSet waveUnitMax[(waveNumber + 1)] = 5
      • Set VariableSet waveDeploy = 0.00
      • Set VariableSet waveNumber = 1
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,552
It's doing exactly what you told it to do -> Loop over all Players that have been set as Users. In your picture you can see you've set Players 1 -> 8 as Users.

But I understand the confusion, what you want to do is check if the Player is a User AND if it's actually playing the game. There's a Condition for this under the category Player Slot Status, which can be Unused, Is playing, or Has left the game. You're after the Is playing condition.

However, I suggest creating a Player Group variable or better yet multiple Player Groups and storing your Players in them at the start of the game:
  • Events
    • Time - Elapsed game time is 0.01 seconds
  • Conditions
  • Actions
    • Set Variable PG_Users_All = (All players matching ((((Matching player) controller) Equal to User))
    • Set Variable PG_Users_Playing = (All players matching ((((Matching player) controller) Equal to User) and (((Matching player) slot status) Equal to Is playing)))
Let's also manage Users_Playing when a Player leaves the game:
  • Events
    • Player - Player 1 (Red) leaves the game
    • Player - Player 2 (Blue) leaves the game
    • Player - Player 3 (Teals) leaves the game
  • Conditions
  • Actions
    • Player Group - Remove (Triggering player) from PG_Users_Playing
    • Player Group - Add (Triggering player) to PG_Users_Has_Left
So I'm using 3 Player Group variables to keep track of our Users:
PG_Users_All: Contains all of our Users regardless of their slot status.
PG_Users_Playing: Contains all of our Users that are still actively playing the game.
PG_Users_Has_Left: Contains all of our Users that have left the game.

Setting these up at the start is useful since all of your future triggers can take advantage of it - assuming they run after the 0.01 second mark.
Here's your Loop using our new variable:
  • Player Group - Pick every player in PG_Users_Playing and do (Actions)
    • Loop - Actions

Edit: Also, a bit unrelated and I'm about to get off for the night, but this looks like a major mistake and NOT what you intended to do:
  • Set VariableSet waveUnit[(Integer(((String((Player number of (Picked player)))) + (String(5)))))] = (Last created unit)
In fact, most of what's happening in your Loop - Actions section seems wrong. If it works, I fear it works for the wrong reasons and almost definitely won't play nice in multiplayer.
 
Last edited:
Level 8
Joined
Dec 1, 2010
Messages
316
try this:
  • Player Group - Pick every player in (All players matching ((((Matching player) controller) Equal to User) and (((Matching player) slot status) Equal to Is playing)).) and do (Actions)
    • Loop - Actions
yup, that was what I was looking for. Now i just have to update every player loop i used D: But the issue itself got fixed immediately
 
Level 8
Joined
Dec 1, 2010
Messages
316
It's doing exactly what you told it to do -> Loop over all Players that have been set as Users. In your picture you can see you've set Players 1 -> 8 as Users.

But I understand the confusion, what you want to do is check if the Player is a User AND if it's actually playing the game. There's a Condition for this under the category Player Slot Status, which can be Unused, Is playing, or Has left the game. You're after the Is playing condition.

However, I suggest creating a Player Group variable or better yet multiple Player Groups and storing your Players in them at the start of the game:
  • Events
    • Time - Elapsed game time is 0.01 seconds
  • Conditions
  • Actions
    • Set Variable PG_Users_All = (All players matching ((((Matching player) controller) Equal to User))
    • Set Variable PG_Users_Playing = (All players matching ((((Matching player) controller) Equal to User) and (((Matching player) slot status) Equal to Is playing)))
Let's also manage Users_Playing when a Player leaves the game:
  • Events
    • Player - Player 1 (Red) leaves the game
    • Player - Player 2 (Blue) leaves the game
    • Player - Player 3 (Teals) leaves the game
  • Conditions
  • Actions
  • Player Group - Remove (Triggering player) from PG_Users_Playing
    • Player Group - Add (Triggering player) to PG_Users_Has_Left
So I'm using 3 Player Group variables to keep track of our Users:
PG_Users_All: Contains all of our Users regardless of their slot status.
PG_Users_Playing: Contains all of our Users that are still actively playing the game.
PG_Users_Has_Left: Contains all of our Users that have left the game.

Setting this up at the start is useful since all of your future triggers can take advantage of it - assuming it's after the 0.01 second mark. Here's your Loop using our new variable:
  • Player Group - Pick every player in PG_Users_Playing and do (Actions)
    • Loop - Actions
Any reason to not just do it at map initialisation? I've set up quite a bit of variables for basically everything else I do, but
you're right this will probably save me some time in the long run.
 
Level 8
Joined
Dec 1, 2010
Messages
316
There's a potential desync when checking Player slot status controller status during Map Initialization, I assume because not everyone has been accounted for yet. At least that's what I've read.
ah, that's good to know. Especially since I might actually publish this project for once.

Are you aware of any other settings that cause desync on map init?
 
Last edited:
Level 8
Joined
Dec 1, 2010
Messages
316
It's doing exactly what you told it to do -> Loop over all Players that have been set as Users. In your picture you can see you've set Players 1 -> 8 as Users.

But I understand the confusion, what you want to do is check if the Player is a User AND if it's actually playing the game. There's a Condition for this under the category Player Slot Status, which can be Unused, Is playing, or Has left the game. You're after the Is playing condition.

However, I suggest creating a Player Group variable or better yet multiple Player Groups and storing your Players in them at the start of the game:
  • Events
    • Time - Elapsed game time is 0.01 seconds
  • Conditions
  • Actions
    • Set Variable PG_Users_All = (All players matching ((((Matching player) controller) Equal to User))
    • Set Variable PG_Users_Playing = (All players matching ((((Matching player) controller) Equal to User) and (((Matching player) slot status) Equal to Is playing)))
Let's also manage Users_Playing when a Player leaves the game:
  • Events
    • Player - Player 1 (Red) leaves the game
    • Player - Player 2 (Blue) leaves the game
    • Player - Player 3 (Teals) leaves the game
  • Conditions
  • Actions
    • Player Group - Remove (Triggering player) from PG_Users_Playing
    • Player Group - Add (Triggering player) to PG_Users_Has_Left
So I'm using 3 Player Group variables to keep track of our Users:
PG_Users_All: Contains all of our Users regardless of their slot status.
PG_Users_Playing: Contains all of our Users that are still actively playing the game.
PG_Users_Has_Left: Contains all of our Users that have left the game.

Setting these up at the start is useful since all of your future triggers can take advantage of it - assuming they run after the 0.01 second mark.
Here's your Loop using our new variable:
  • Player Group - Pick every player in PG_Users_Playing and do (Actions)
    • Loop - Actions

Edit: Also, a bit unrelated and I'm about to get off for the night, but this looks like a major mistake and NOT what you intended to do:
  • Set VariableSet waveUnit[(Integer(((String((Player number of (Picked player)))) + (String(5)))))] = (Last created unit)
In fact, most of what's happening in your Loop - Actions section seems wrong. If it works, I fear it works for the wrong reasons and almost definitely won't play nice in multiplayer.
about the last comment, Initially i was making waveunit a var array with about max array size and using a combination of player number and a hand set variable as an ID. I learned how to use hashtables later ( like today) and basically stopped using this outside of a single trigger that still uses it which i've been too lazy to replace. Since it still worked.

I basically started off this map designing my own weird system of ID's using variables arrays which worked but i also completely ditched once i realized how much easier it was to just use a hashtable.
 
Level 39
Joined
Feb 27, 2007
Messages
5,016
Are you aware of any other settings that cause desync on map init?
It is generally a bad idea to run anything on map init because of issues like that and the possibility of an overloaded init function hitting the OP limit. Instead you should use this event:
  • Events
    • Time - Elapsed game-time is 0.50 seconds
The actual delay isn’t important as long as it’s greater than 0.
 
Top