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!