Refactor phase transitions and add particle effects for flags
Simplified phase transition logic by removing unnecessary parameters and added proper executor shutdown at the end of the game. Enhanced visuals by introducing particle effects around flags when a team wins. Also implemented a method to skip the current game phase.
This commit is contained in:
parent
66c24d852d
commit
aad63f174e
|
|
@ -96,12 +96,40 @@ public class Flag implements Runnable {
|
|||
Bukkit.getScheduler().runTask(main, () -> flagLocation.getBlock().setType(flagItem.getType()));
|
||||
}
|
||||
|
||||
private void spawnFlagParticleRing() {
|
||||
Location center = flagLocation.clone();
|
||||
World world = center.getWorld();
|
||||
double radius = 0.7;
|
||||
double gap = 0.2;
|
||||
double circumference = 2 * Math.PI * radius;
|
||||
int particleCount = (int) (circumference / gap);
|
||||
|
||||
Particle particle = Particle.DUST;
|
||||
TeamColor color = winningTeam.getColor();
|
||||
// Generate particle positions
|
||||
for (double heightOffset = 0; heightOffset < 2; heightOffset += 0.5) {
|
||||
center.setY(center.getY() + 0.5);
|
||||
for (int i = 0; i < particleCount; i++) {
|
||||
double angle = 2 * Math.PI * i / particleCount;
|
||||
double x = center.getX() + radius * Math.cos(angle);
|
||||
double z = center.getZ() + radius * Math.sin(angle);
|
||||
double y = center.getY();
|
||||
|
||||
world.spawnParticle(particle, x, y, z, 1, 0, 0, 0, new Particle.DustOptions(Color.fromRGB(color.r(), color.g(), color.b()), 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (flagCarrier != null) {
|
||||
checkFlagCarrier();
|
||||
return;
|
||||
}
|
||||
if (winningTeam != null) {
|
||||
spawnFlagParticleRing();
|
||||
return;
|
||||
}
|
||||
if (flagLocation == null) {
|
||||
log.warn("Tried to run Flag without a flag location, spawn it first");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ public class GameManager {
|
|||
executorService.shutdown();
|
||||
executorService = Executors.newSingleThreadScheduledExecutor();
|
||||
}
|
||||
runningGame = new RunningGame(this, duration, flag);
|
||||
runningGame = new RunningGame(this, duration, flag, executorService);
|
||||
executorService.scheduleAtFixedRate(runningGame, 0, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import javax.annotation.Nullable;
|
|||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
@Slf4j
|
||||
public class RunningGame implements Runnable {
|
||||
|
|
@ -20,14 +21,16 @@ public class RunningGame implements Runnable {
|
|||
private final HashMap<GamePhase, Duration> phaseDurations = GameConfig.PHASES.getGAME_PHASE_DURATION();
|
||||
private final GameManager gameManager;
|
||||
private final Flag flag;
|
||||
private final ScheduledExecutorService executorService;
|
||||
@Getter
|
||||
private GamePhase currentPhase = GamePhase.values()[0];
|
||||
private Instant phaseStartTime = null;
|
||||
private int lastMinuteBroadcast = 0;
|
||||
|
||||
public RunningGame(GameManager gameManager, Duration gameDuration, Flag flag) {
|
||||
public RunningGame(GameManager gameManager, Duration gameDuration, Flag flag, ScheduledExecutorService executorService) {
|
||||
this.gameManager = gameManager;
|
||||
this.flag = flag;
|
||||
this.executorService = executorService;
|
||||
phaseDurations.put(GamePhase.COMBAT, gameDuration);
|
||||
}
|
||||
|
||||
|
|
@ -37,16 +40,16 @@ public class RunningGame implements Runnable {
|
|||
GamePhase nextPhase = (currentPhase.ordinal() + 1 < GamePhase.values().length) ? GamePhase.values()[currentPhase.ordinal() + 1] : null;
|
||||
if (phaseStartTime == null) {
|
||||
phaseStartTime = Instant.now();
|
||||
nextPhaseActions(null, currentPhase, nextPhase);
|
||||
nextPhaseActions(null, currentPhase);
|
||||
}
|
||||
|
||||
if (Duration.between(phaseStartTime, Instant.now()).compareTo(phaseDurations.get(currentPhase)) >= 0) {
|
||||
GamePhase previousPhase = currentPhase;
|
||||
currentPhase = GamePhase.values()[currentPhase.ordinal() + 1]; //TODO fix this running out of bounds
|
||||
nextPhaseActions(previousPhase, currentPhase, nextPhase);
|
||||
if (nextPhase != null && Duration.between(phaseStartTime, Instant.now()).compareTo(phaseDurations.get(currentPhase)) >= 0) {
|
||||
nextPhaseActions(currentPhase, nextPhase);
|
||||
phaseStartTime = Instant.now();
|
||||
} else if (nextPhase != null) {
|
||||
broadcastNextPhaseStartTime(currentPhase, nextPhase);
|
||||
} else {
|
||||
executorService.shutdown();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Unexpected error in running game", e);
|
||||
|
|
@ -54,15 +57,13 @@ public class RunningGame implements Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
private void nextPhaseActions(@Nullable GamePhase previousPhase, @NotNull GamePhase phase, @Nullable GamePhase nextPhase) {
|
||||
private void nextPhaseActions(@Nullable GamePhase previousPhase, @NotNull GamePhase phase) {
|
||||
//TODO command to go to next phase
|
||||
this.currentPhase = phase;
|
||||
if (previousPhase != null) {
|
||||
gameManager.getPhaseExecutor(previousPhase).end(phase);
|
||||
}
|
||||
gameManager.getPhaseExecutor(phase).start(flag);
|
||||
if (nextPhase != null) {
|
||||
broadcastNextPhaseStartTime(phase, nextPhase);
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcastNextPhaseStartTime(GamePhase currentPhase, GamePhase nextPhase) {//TODO check how this works/what it should do
|
||||
|
|
@ -86,9 +87,17 @@ public class RunningGame implements Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
public void skipCurrentPhase() {
|
||||
GamePhase nextPhase = (currentPhase.ordinal() + 1 < GamePhase.values().length) ? GamePhase.values()[currentPhase.ordinal() + 1] : null;
|
||||
if (nextPhase == null) {
|
||||
log.warn("Tried to skip phase {} but there is no next phase", currentPhase);
|
||||
return;
|
||||
}
|
||||
nextPhaseActions(currentPhase, nextPhase);
|
||||
}
|
||||
|
||||
public void end() {
|
||||
//TODO say the phase ended early?
|
||||
currentPhase = GamePhase.ENDED;
|
||||
nextPhaseActions(null, currentPhase, null);
|
||||
nextPhaseActions(currentPhase, GamePhase.ENDED);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user