From fcc5c30bb145702479161106d3f1d8faeabf0cad Mon Sep 17 00:00:00 2001 From: theEvilReaper Date: Mon, 13 Jul 2026 17:42:38 +0200 Subject: [PATCH 1/2] feat(teleport): add strategy interface --- .../common/strategy/TeleportStrategy.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 common/src/main/java/net/onelitefeather/cygnus/common/strategy/TeleportStrategy.java diff --git a/common/src/main/java/net/onelitefeather/cygnus/common/strategy/TeleportStrategy.java b/common/src/main/java/net/onelitefeather/cygnus/common/strategy/TeleportStrategy.java new file mode 100644 index 0000000..82e269e --- /dev/null +++ b/common/src/main/java/net/onelitefeather/cygnus/common/strategy/TeleportStrategy.java @@ -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 players, Instance instance, Collection spawns); +} From 30edc745db874129e2bc3bdadf87e9959a8b0b41 Mon Sep 17 00:00:00 2001 From: theEvilReaper Date: Mon, 13 Jul 2026 17:42:49 +0200 Subject: [PATCH 2/2] chore(team): update teleport logic --- .../cygnus/team/TeamHelper.java | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/game/src/main/java/net/onelitefeather/cygnus/team/TeamHelper.java b/game/src/main/java/net/onelitefeather/cygnus/team/TeamHelper.java index 34c1a7f..a483d7d 100644 --- a/game/src/main/java/net/onelitefeather/cygnus/team/TeamHelper.java +++ b/game/src/main/java/net/onelitefeather/cygnus/team/TeamHelper.java @@ -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; @@ -107,23 +108,33 @@ private static void assignSurvivors(Set 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()); } /**