Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package net.onelitefeather.cygnus.common.strategy;

import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

/**
* Functional interface to define which strategy should be used for the player teleportation.
*
* @author theEvilReaper
* @version 1.0.0
* @since 2.6.6
*/
@FunctionalInterface
public interface TeleportStrategy {

/**
* A strategy that shuffles the spawn points and distributes players evenly (round-robin) among them.
*/
TeleportStrategy ROUND_ROBIN_RANDOM = (players, instance, spawns) -> {
if (spawns.isEmpty()) {
throw new IllegalStateException("The game map does not define any spawn points!");
}
var spawnList = new ArrayList<>(spawns);
Collections.shuffle(spawnList);
int index = 0;
for (Player player : players) {
Pos spawnPos = spawnList.get(index % spawnList.size());
if (player.getInstance() != null && player.getInstance().equals(instance)) {
player.teleport(spawnPos);
} else {
player.setInstance(instance, spawnPos);
}
index++;
}
};

/**
* A strategy that teleports all players to the first available spawn point.
*/
TeleportStrategy SINGLE = (players, instance, spawns) -> {
if (spawns.isEmpty()) {
throw new IllegalStateException("The game map does not define any spawn points!");
}
Pos spawnPos = spawns.iterator().next();
for (Player player : players) {
if (player.getInstance() != null && player.getInstance().equals(instance)) {
player.teleport(spawnPos);
} else {
player.setInstance(instance, spawnPos);
}
}
};

/**
* Teleports a collection of players to a set of spawn positions within an instance.
*
* @param players the players to teleport
* @param instance the target instance
* @param spawns the available spawn locations
*/
void teleport(Collection<Player> players, Instance instance, Collection<Pos> spawns);
}
25 changes: 18 additions & 7 deletions game/src/main/java/net/onelitefeather/cygnus/team/TeamHelper.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.onelitefeather.cygnus.team;

import net.onelitefeather.cygnus.common.strategy.TeleportStrategy;
import net.onelitefeather.cygnus.utils.ViewRuleUpdater;
import net.theevilreaper.aves.util.Players;
import net.theevilreaper.xerus.api.team.Team;
Expand Down Expand Up @@ -107,23 +108,33 @@ private static void assignSurvivors(Set<Player> survivors, Team survivorTeam) {
}

/**
* Teleport the teams to their spawn points
* Teleport the teams to their spawn points using the default round-robin random strategy.
*
* @param teamService the service to get the teams
* @param gameMap the map to get the spawn points
* @param gameInstance the instance to teleport the players
*/
public static void teleportTeams(TeamService teamService, GameMap gameMap, Instance gameInstance) {
TeleportStrategy strategy = gameMap.getSurvivorSpawns().size() == 1
? TeleportStrategy.SINGLE
: TeleportStrategy.ROUND_ROBIN_RANDOM;
teleportTeams(teamService, gameMap, gameInstance, strategy);
}

/**
* Teleport the teams to their spawn points using the specified teleportation strategy.
*
* @param teamService the service to get the teams
* @param gameMap the map to get the spawn points
* @param gameInstance the instance to teleport the players
* @param strategy the strategy to use for survivor teleportation
*/
public static void teleportTeams(TeamService teamService, GameMap gameMap, Instance gameInstance, TeleportStrategy strategy) {
Team slenderTeam = teamService.getTeams().getFirst();
slenderTeam.getPlayers().forEach(player -> updateInstance(player, gameInstance, gameMap.getSlenderSpawn()));

Team survivorTeam = teamService.getTeams().getLast();
if (gameMap.getSurvivorSpawns().size() == 1) {
Pos position = gameMap.getSurvivorSpawns().iterator().next();
survivorTeam.getPlayers().forEach(player -> updateInstance(player, gameInstance, position));
}

//throw new UnsupportedOperationException("Multiple survivor spawns are not supported yet");
strategy.teleport(survivorTeam.getPlayers(), gameInstance, gameMap.getSurvivorSpawns());
}

/**
Expand Down
Loading