HungerGames/src/main/java/com/alttd/hunger_games/services/RoundService.java

149 lines
5.5 KiB
Java
Raw Normal View History

package com.alttd.hunger_games.services;
import com.alttd.hunger_games.Main;
import com.alttd.hunger_games.config.Messages;
import com.alttd.hunger_games.data_objects.DESTINATION;
import com.alttd.hunger_games.data_objects.PLAYER_STATE;
import com.alttd.hunger_games.data_objects.ROUND_STATE;
import com.alttd.hunger_games.event_listeners.PlayerMovementListener;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
public class RoundService implements RoundListener {
private static RoundService instance = null;
private PlayerMovementListener playerMovementListener;
private final PlayerTeleporterService playerTeleporterService;
private final Main main;
private final LootService lootService;
private final StatService statService;
@Getter
private ROUND_STATE roundState;
private final HashMap<UUID, PLAYER_STATE> players = new HashMap<>();
private final Round round;
@Setter
private BossBarService bossBarService;
public static RoundService createSingletonInstance(Round round, Main main, LootService lootService, StatService statService, PlayerTeleporterService playerTeleporterService) {
if (instance != null) {
throw new IllegalStateException("RoundService is already initialized.");
}
instance = new RoundService(round, main, lootService, statService, playerTeleporterService);
return instance;
}
private RoundService(Round round, Main main, LootService lootService, StatService statService, PlayerTeleporterService playerTeleporterService) {
this.round = round;
this.roundState = round.register(this);
this.main = main;
this.lootService = lootService;
this.statService = statService;
this.playerTeleporterService = playerTeleporterService;
}
public Set<UUID> getPlayers(PLAYER_STATE playerState) {
return players.entrySet().stream()
.filter(entry -> entry.getValue().equals(playerState))
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
protected void setPlayerState(UUID uuid, PLAYER_STATE playerState) {
PLAYER_STATE oldState = players.put(uuid, playerState);
if (playerState == PLAYER_STATE.SPECTATING && oldState == PLAYER_STATE.REGISTERED) {
int remaining = getPlayers(PLAYER_STATE.REGISTERED).size();
statService.setPlacement(uuid, remaining + 1);
if (roundState == ROUND_STATE.FINALE && bossBarService != null) {
bossBarService.updateFinale(remaining);
}
}
if (!roundState.equals(ROUND_STATE.KILL_PHASE) && !roundState.equals(ROUND_STATE.FINALE)) {
return;
}
Set<UUID> uuidSet = getPlayers(PLAYER_STATE.REGISTERED);
if (uuidSet.size() != 1) {
return;
}
declareWinner(uuidSet.iterator().next());
}
private void declareWinner(UUID winnerUUID) {
Player player = Bukkit.getPlayer(winnerUUID);
if (player == null) {
log.error("Winner {} not found", winnerUUID);
Bukkit.broadcast(MiniMessage.miniMessage().deserialize("<red>Winner not found</red>"));
return;
}
statService.setPlacement(winnerUUID, 1);
statService.setWon(winnerUUID, true);
Bukkit.broadcast(MiniMessage.miniMessage().deserialize(Messages.GAME.WINNER, Placeholder.component("player", player.name())));
playerTeleporterService.teleportPlayer(player, DESTINATION.SPECTATOR_AREA);
player.setHealth(20);
player.setFoodLevel(20);
player.getInventory().clear();
round.endRound();
}
protected void clear() {
players.clear();
}
public Optional<PLAYER_STATE> getPlayerState(UUID uuid) {
return Optional.ofNullable(players.get(uuid));
}
@Override
public void stateChange(ROUND_STATE roundState) {
this.roundState = roundState;
stopFreeze();
if (roundState.equals(ROUND_STATE.PLAYER_REGISTRATION)) {
clear();
lootService.clear();
}
if (roundState.equals(ROUND_STATE.COUNTDOWN)) {
Bukkit.getOnlinePlayers().stream()
.filter(player -> PLAYER_STATE.REGISTERED.equals(getPlayerState(player.getUniqueId()).orElse(null)))
.forEach(player -> {
player.setHealth(20);
player.setFoodLevel(20);
player.setGameMode(GameMode.SURVIVAL);
player.getInventory().clear();
});
startFreeze();
}
Bukkit.broadcast(MiniMessage.miniMessage().deserialize(Messages.GAME.NEXT_STATE, Placeholder.parsed("round", roundState.getHumanReadableName())));
}
private void stopFreeze() {
if (playerMovementListener == null) {
return;
}
HandlerList.unregisterAll(playerMovementListener);
playerMovementListener = null;
}
private void startFreeze() {
stopFreeze();
Set<UUID> uuidSet = getPlayers(PLAYER_STATE.REGISTERED);
playerMovementListener = new PlayerMovementListener(uuidSet);
main.getServer().getPluginManager().registerEvents(playerMovementListener, main);
}
}