hey @_H121 how are you?!
I took this post as a challenge and tried to implemente it in the best way possible. My approach uses more Verse and less devices (only the Reference Devices, actually).
First of all, instead of looping to check if the player is still on a team, you should identify the cases where the player leaves the team. For example, the player leaves the team when disconnecting from the game, or you can change the players team when it dies.
Then you references your Reference Devices in arrays that corresponds to differente teams, something like this:
# Editable arrays of reference devices for each team @editable MyReferenceTeam1 : []player_reference_device = array{} @editable MyReferenceTeam2 : []player_reference_device = array{}
You also need a map to store the players and their teams, so you can keep track of the changes:
# MAP variable to store the current team for each player var PlayersTeams : [agent]int = map{}
After that, you will need to initialize that map with all the players that are in your island, as well as subscribe to players joining and leaving it:
OnBegin<override>()<suspends>:void= # Iterate over all players currently in the playspace for ( Agent : GetPlayspace().GetPlayers() ): # Add all players to Players' Teams map InitializePlayersMap( Agent ) # Register all players to available Reference Devices RegisterToEmptyReferenceDevice( Agent ) # Subscribe to new players joining the game GetPlayspace().PlayerAddedEvent().Subscribe( OnPlayerAdded ) # Subscribe to players leaving the game GetPlayspace().PlayerRemovedEvent().Subscribe( RemoveIfNotInTeam )
The functions to populate the map and add players to that map when joining the game are:
# Triggered when a new player joins OnPlayerAdded ( Agent : agent ) : void = # Add new player to Players' Teams map InitializePlayersMap( Agent ) # Register new player to available Reference Device RegisterToEmptyReferenceDevice( Agent )
# Adds a player and their team to the PlayersTeams map InitializePlayersMap( Agent : agent ) : void = # Get all the teams in the island TeamCollection := GetPlayspace().GetTeamCollection() # Create teams array Teams := TeamCollection.GetTeams() # Check Agent's current team if ( PlayersTeam := TeamCollection.GetTeam[Agent] ): # Compare against each team to find the correct index for ( TeamIndex := 0..Teams.Length - 1 ): if ( Team := Teams[ TeamIndex ] ): if ( PlayersTeam = Team ): # Store player -> team index in the map if ( set PlayersTeams[ Agent ] = TeamIndex ):
Then you have the functions to register the players to the reference devices. You should call the main function (RegisterToEmptyReferenceDevice) whenever you want to add a player to a new device:
# Assigns a player to the first empty reference device of their team RegisterToEmptyReferenceDevice( Agent : agent ) : void = # Get all the teams in the island TeamCollection := GetPlayspace().GetTeamCollection() # Create teams array Teams := TeamCollection.GetTeams() # Check Agent's current team if ( PlayersTeam := TeamCollection.GetTeam[Agent] ): # Check which team the player belongs to and register accordingly for ( TeamIndex := 0..Teams.Length - 1 ): if ( Team := Teams[ TeamIndex ] ): if ( PlayersTeam = Team ): # Match team index to corresponding reference device array case ( TeamIndex ): # You should add as many "cases" as Reference Devices arrays you have 0 => RegisterToTeam( Agent, TeamIndex, MyReferenceTeam1 ) 1 => RegisterToTeam( Agent, TeamIndex, MyReferenceTeam2 ) _ => {} # Do nothing for other team indices # Helper function that registers a player to a specific team's reference device RegisterToTeam( Agent : agent, TeamIndex : int, ReferenceDevices : []player_reference_device ) : void = var Index : int = 0 # Iterate over all Reference Devices of the corresponding team loop: if (Index >= ReferenceDevices.Length): break # Get the current reference device if(RefDevice := ReferenceDevices[Index]): # Check if it's already holding a player HasReference := RefDevice.GetAgent() if ( HasReference = false ): # If empty, register this player RefDevice.Register( Agent ) break set Index += 1
Lastly, you need to add the functions to remove the players from the corresponding Reference Devices. You only need to call “RemoveIfNotInTeam” when you want to remove a player:
# Triggered when a player leaves or changes teams RemoveIfNotInTeam( Agent : agent ) : void = # Get all the teams in the island TeamCollection := GetPlayspace().GetTeamCollection() # Create teams array Teams := TeamCollection.GetTeams() # Check Agent's current team if ( PlayersTeam := TeamCollection.GetTeam[Agent] ): if (PlayersPreviousTeamInt := PlayersTeams[ Agent ] ): # Get the team they previously belonged to if ( PreviousTeam := Teams[PlayersPreviousTeamInt] ): # If their team has changed if ( PlayersTeam <> PreviousTeam ): # Clear from old reference device case ( PlayersPreviousTeamInt ): 0 => ClearRefDevice( Agent, PlayersPreviousTeamInt, MyReferenceTeam1, PlayersTeam ) 1 => ClearRefDevice( Agent, PlayersPreviousTeamInt, MyReferenceTeam2, PlayersTeam ) _ => {} # Do nothing for other team indices / Keep adding teams avobe this line # Clears a player's reference device when they leave or switch teams ClearRefDevice( Agent : agent, TeamIndex : int, ReferenceDevices : []player_reference_device, CurrentTeam : team ) : void = # Search through all Reference Devices of the team for ( RefDevice : ReferenceDevices ): ReferencedAgent := RefDevice.GetAgent() if(ActualAgent := ReferencedAgent?): if ( ActualAgent = Agent ): # Clear the device if it belongs to this agent RefDevice.Clear() # Check if the player's character still exists and is active if ( Char := Agent.GetFortCharacter[] ): if ( Char.IsActive[] ): # Re-register the player into a free reference device RegisterToEmptyReferenceDevice( Agent ) # Get all the teams in the island TeamCollection := GetPlayspace().GetTeamCollection() # Create teams array Teams := TeamCollection.GetTeams() for ( Index := 0..Teams.Length - 1 ): if ( Team := Teams[ Index ] ): if ( CurrentTeam = Team ): # Update their new team index in the map if ( set PlayersTeams[ Agent ] = Index ): else: # If player is gone, rebuild the map without them var NewMap : [agent]int = map{} for ( Key -> Value : PlayersTeams ): if ( Key <> Agent ): if ( set NewMap[Key] = Value ): set PlayersTeams = NewMap
And that’s it. You only need to call the corresponding functions when someone leaves a team or joins the island. This way you don’t need to check in a loop. And you don’t need a lot of devices!
Hope this helps you! Let me know if you need more help with this! I’ll be glad to give you a hand!