2026-05-23 22:13:25 +00:00
|
|
|
package com.alttd.hunger_games.services;
|
|
|
|
|
|
2026-05-23 23:30:11 +00:00
|
|
|
import com.alttd.hunger_games.config.Config;
|
|
|
|
|
import com.alttd.hunger_games.data_objects.GameStage;
|
2026-05-23 22:13:25 +00:00
|
|
|
import com.alttd.hunger_games.data_objects.ROUND_STATE;
|
2026-05-23 23:30:11 +00:00
|
|
|
import com.alttd.hunger_games.game.GameStageHandler;
|
2026-05-23 22:13:25 +00:00
|
|
|
|
2026-05-23 23:30:11 +00:00
|
|
|
import java.time.Duration;
|
2026-05-23 22:13:25 +00:00
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Optional;
|
2026-05-23 23:30:11 +00:00
|
|
|
import java.util.concurrent.Executors;
|
|
|
|
|
import java.util.concurrent.ScheduledExecutorService;
|
|
|
|
|
import java.util.concurrent.TimeUnit;
|
2026-05-23 22:13:25 +00:00
|
|
|
|
|
|
|
|
public class Round {
|
|
|
|
|
|
|
|
|
|
private static Round instance = null;
|
|
|
|
|
private final List<RoundListener> listeners = new ArrayList<>();
|
2026-05-23 23:30:11 +00:00
|
|
|
private ROUND_STATE roundState = ROUND_STATE.PLAYER_REGISTRATION;
|
|
|
|
|
private ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
|
2026-05-23 22:13:25 +00:00
|
|
|
|
|
|
|
|
private Round() {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Round createSingletonInstance() throws IllegalStateException {
|
|
|
|
|
if (instance != null) {
|
|
|
|
|
throw new IllegalStateException("Round is already initialized.");
|
|
|
|
|
}
|
|
|
|
|
instance = new Round();
|
|
|
|
|
return instance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ROUND_STATE register(RoundListener listener) {
|
|
|
|
|
listeners.add(listener);
|
|
|
|
|
return roundState;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void unregister(RoundListener listener) {
|
|
|
|
|
listeners.remove(listener);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-23 23:30:11 +00:00
|
|
|
public void stop() {
|
2026-05-23 22:13:25 +00:00
|
|
|
roundState = ROUND_STATE.PLAYER_REGISTRATION;
|
|
|
|
|
listeners.forEach(roundListener -> roundListener.stateChange(roundState));
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-23 23:30:11 +00:00
|
|
|
private void nextStage() {
|
2026-05-23 22:13:25 +00:00
|
|
|
Optional<ROUND_STATE> optionalNextRoundState = roundState.next();
|
|
|
|
|
if (optionalNextRoundState.isEmpty()) {
|
2026-05-23 23:30:11 +00:00
|
|
|
roundState = ROUND_STATE.PLAYER_REGISTRATION;
|
|
|
|
|
listeners.forEach(roundListener -> roundListener.stateChange(roundState));
|
2026-05-23 22:13:25 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
roundState = optionalNextRoundState.get();
|
|
|
|
|
listeners.forEach(roundListener -> roundListener.stateChange(roundState));
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-23 23:30:11 +00:00
|
|
|
public void startRound() {
|
|
|
|
|
if (roundState.equals(ROUND_STATE.PLAYER_REGISTRATION)) {
|
|
|
|
|
throw new IllegalStateException("Round can not be started before player registration.");
|
|
|
|
|
}
|
|
|
|
|
roundState = ROUND_STATE.COUNTDOWN;
|
|
|
|
|
listeners.forEach(roundListener -> roundListener.stateChange(roundState));
|
|
|
|
|
GameStageHandler.handleWarmup();
|
|
|
|
|
Duration warmupDuration = Config.ROUND.COUNTDOWN;
|
|
|
|
|
scheduledExecutorService.schedule(() -> {
|
|
|
|
|
GameStageHandler.handleCountdownEnd();
|
|
|
|
|
nextStage();
|
|
|
|
|
scheduleNextStage(0);
|
|
|
|
|
}, warmupDuration.toSeconds(), TimeUnit.SECONDS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void scheduleNextStage(int index) {
|
|
|
|
|
List<GameStage> gameStageList = Config.ROUND.STAGES;
|
|
|
|
|
if (gameStageList.size() <= index) {
|
|
|
|
|
nextStage();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GameStage gameStage = gameStageList.get(index);
|
|
|
|
|
Duration duration = gameStage.getDuration();
|
|
|
|
|
scheduledExecutorService.schedule(() -> {
|
|
|
|
|
GameStageHandler.handleStageChange(gameStage.getWorldBorderSize());
|
|
|
|
|
scheduleNextStage(index + 1);
|
|
|
|
|
}, duration.toSeconds(), TimeUnit.SECONDS);
|
|
|
|
|
}
|
2026-05-23 22:13:25 +00:00
|
|
|
}
|