Introduce singleton pattern for services, add safe phase to round state, and implement PlayerTeleporterService with destination-based teleporting
This commit is contained in:
@@ -19,7 +19,7 @@ public class PlayerService implements RoundListener {
|
||||
public void stateChange(ROUND_STATE roundState) {
|
||||
this.roundState = roundState;
|
||||
switch (roundState) {
|
||||
case PLAYER_REGISTRATION, KILL_PHASE -> {
|
||||
case PLAYER_REGISTRATION, KILL_PHASE, SAFE_PHASE -> {
|
||||
//Nothing
|
||||
}
|
||||
case COUNTDOWN -> {
|
||||
@@ -94,7 +94,7 @@ public class PlayerService implements RoundListener {
|
||||
}
|
||||
return switch (roundState) {
|
||||
case PLAYER_REGISTRATION, COUNTDOWN -> Optional.of(PLAYER_STATE.REGISTERED);
|
||||
case KILL_PHASE, FINALE, ENDED -> Optional.of(PLAYER_STATE.SPECTATING);
|
||||
case KILL_PHASE, FINALE, ENDED, SAFE_PHASE -> Optional.of(PLAYER_STATE.SPECTATING);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.alttd.hunger_games.services;
|
||||
|
||||
import com.alttd.hunger_games.config.Config;
|
||||
import com.alttd.hunger_games.data_objects.DESTINATION;
|
||||
import com.alttd.hunger_games.data_objects.ROUND_STATE;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@NoArgsConstructor
|
||||
public class PlayerTeleporterService implements RoundListener {
|
||||
|
||||
private static PlayerTeleporterService instance = null;
|
||||
|
||||
private final Map<DESTINATION, Integer> placementCount = new HashMap<>();
|
||||
private final Map<DESTINATION, Set<Location>> usedLocations = new HashMap<>();
|
||||
|
||||
public static PlayerTeleporterService createSingletonInstance() {
|
||||
if (instance != null) {
|
||||
throw new IllegalStateException("PlayerTeleporterService is already initialized.");
|
||||
}
|
||||
instance = new PlayerTeleporterService();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void teleportPlayer(Player player, DESTINATION destination) {
|
||||
player.teleport(getLocationFromDestination(destination));
|
||||
}
|
||||
|
||||
private Location getLocationFromDestination(DESTINATION destination) {
|
||||
return switch (destination) {
|
||||
case START_AREA -> {
|
||||
Location startCenter = Config.DESTINATION.START_CENTER;
|
||||
if (startCenter == null) {
|
||||
throw new IllegalStateException("Start center is not set.");
|
||||
}
|
||||
int startRadius = Config.DESTINATION.START_RADIUS;
|
||||
yield calculateLocation(destination, startCenter, startRadius);
|
||||
}
|
||||
case FINALE_AREA -> {
|
||||
Location finaleCenter = Config.DESTINATION.FINALE_CENTER;
|
||||
if (finaleCenter == null) {
|
||||
throw new IllegalStateException("Finale center is not set.");
|
||||
}
|
||||
int finaleRadius = Config.DESTINATION.FINALE_RADIUS;
|
||||
yield calculateLocation(destination, finaleCenter, finaleRadius);
|
||||
}
|
||||
case SPECTATOR_AREA -> {
|
||||
Location spectatorArea = Config.DESTINATION.SPECTATOR_AREA;
|
||||
if (spectatorArea == null) {
|
||||
throw new IllegalStateException("Spectator area is not set.");
|
||||
}
|
||||
yield spectatorArea;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Location calculateLocation(DESTINATION destination, Location center, int radius) {
|
||||
int count = placementCount.merge(destination, 1, Integer::sum);
|
||||
double angleDegrees = vanDerCorput(count - 1) * 360.0;
|
||||
double angleRadians = Math.toRadians(angleDegrees);
|
||||
double x = center.getX() + radius * Math.cos(angleRadians);
|
||||
double z = center.getZ() + radius * Math.sin(angleRadians);
|
||||
Location location = new Location(center.getWorld(), x, center.getY(), z);
|
||||
usedLocations.computeIfAbsent(destination, k -> new HashSet<>()).add(location);
|
||||
return location;
|
||||
}
|
||||
|
||||
private static double vanDerCorput(int n) {
|
||||
double result = 0.0;
|
||||
double denominator = 1.0;
|
||||
while (n > 0) {
|
||||
denominator *= 2.0;
|
||||
result += (n % 2) / denominator;
|
||||
n /= 2;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChange(ROUND_STATE roundState) {
|
||||
placementCount.clear();
|
||||
usedLocations.clear();
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,21 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class RoundService implements RoundListener {
|
||||
|
||||
private static RoundService instance = null;
|
||||
|
||||
@Getter
|
||||
private ROUND_STATE roundState;
|
||||
private final HashMap<UUID, PLAYER_STATE> players = new HashMap<>();
|
||||
|
||||
public RoundService(Round round) {
|
||||
public static RoundService createSingletonInstance(Round round) {
|
||||
if (instance != null) {
|
||||
throw new IllegalStateException("RoundService is already initialized.");
|
||||
}
|
||||
instance = new RoundService(round);
|
||||
return instance;
|
||||
}
|
||||
|
||||
private RoundService(Round round) {
|
||||
this.roundState = round.register(this);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user