Compare commits

...

5 Commits

Author SHA1 Message Date
Teriuihi 56455b4c50 Fix executor handling in phase transitions and game ending
Ensure proper management of executor service during CombatPhase and shutdown when the game ends. Avoids potential resource leaks or invalid executor state during phase transitions.
2025-02-11 23:17:10 +01:00
Teriuihi 3b4beefb37 Remove redundant TODO comment in CombatPhase.java
The comment about adding players to the boss bar list was removed as it is completed.
2025-02-11 23:10:06 +01:00
Teriuihi 9ae63ba1e4 Refine title message for flag capture notification.
Adjusted the title message to simplify formatting and better align with gameplay context. Removed redundant text and ensured proper use of placeholders for dynamic content.
2025-02-11 23:08:59 +01:00
Teriuihi c3b11995c7 Update phase transition notifications with detailed timing
Introduced specific second-based notifications for better accuracy as a phase approaches. Added distinct messaging for the game ending phase to improve clarity for players. Simplified code by replacing hard-coded values with a predefined list of notification intervals.
2025-02-11 23:06:05 +01:00
Teriuihi 8b09e54106 Fix flag capture and game phase timing bugs
Adjusted the flag capture sequence to ensure proper update of the carrier before notifying about the capture. Fixed the phaseStartTime initialization to correctly track phase transitions. Updated the build number for the new changes.
2025-02-11 23:02:38 +01:00
4 changed files with 33 additions and 17 deletions

View File

@ -8,6 +8,7 @@ import com.alttd.ctf.team.TeamColor;
import com.alttd.ctf.team.TeamPlayer;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
@ -81,8 +82,8 @@ public class Flag implements Runnable {
//TODO add de-buffs and enable buffs for others?
player.getInventory().setItem(EquipmentSlot.HEAD, flagItem);
Bukkit.getScheduler().runTask(main, () -> flagLocation.getBlock().setType(Material.AIR));
notifyAboutCapture();
flagCarrier = player;
notifyAboutCapture();
resetFlag();
}
@ -224,10 +225,10 @@ public class Flag implements Runnable {
Bukkit.broadcast(miniMessage.deserialize("<player> captured the flag for <team>!",
Placeholder.component("player", flagCarrier.displayName()),
Placeholder.component("team", winningTeam.getName())));
Title title = Title.title(miniMessage.deserialize("<green><player> captured the flag for team <team>!</green>",
Placeholder.component("team", winningTeam.getName())),
miniMessage.deserialize("<green>protect <player> while they bring it to your base.</green>",
Placeholder.component("player", flagCarrier.displayName())));
Title title = Title.title(Component.empty(),
miniMessage.deserialize("<green><player> captured the flag for <team> team</green>",
Placeholder.component("player", flagCarrier.displayName()),
Placeholder.component("team", winningTeam.getName())));
Bukkit.getOnlinePlayers().forEach(player -> player.showTitle(title));
}

View File

@ -13,6 +13,7 @@ import javax.annotation.Nullable;
import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
@Slf4j
@ -39,7 +40,6 @@ public class RunningGame implements Runnable {
try {
GamePhase nextPhase = (currentPhase.ordinal() + 1 < GamePhase.values().length) ? GamePhase.values()[currentPhase.ordinal() + 1] : null;
if (phaseStartTime == null) {
phaseStartTime = Instant.now();
nextPhaseActions(null, currentPhase);
}
@ -58,15 +58,19 @@ public class RunningGame implements Runnable {
}
private void nextPhaseActions(@Nullable GamePhase previousPhase, @NotNull GamePhase phase) {
//TODO command to go to next phase
this.currentPhase = phase;
this.phaseStartTime = Instant.now();
if (previousPhase != null) {
gameManager.getPhaseExecutor(previousPhase).end(phase);
}
gameManager.getPhaseExecutor(phase).start(flag);
if (phase.equals(GamePhase.ENDED)) {
executorService.shutdown();
}
}
private void broadcastNextPhaseStartTime(GamePhase currentPhase, GamePhase nextPhase) {//TODO check how this works/what it should do
private static final List<Integer> NOTIFY_SECONDS = List.of(45, 30, 15, 10, 5, 3, 2, 1);
private void broadcastNextPhaseStartTime(GamePhase currentPhase, GamePhase nextPhase) {
//Remaining time for this phase
Duration duration = phaseDurations.get(currentPhase).minus(Duration.between(phaseStartTime, Instant.now()));
log.debug(duration.toString());//TODO remove debug
@ -75,11 +79,21 @@ public class RunningGame implements Runnable {
return;
}
lastMinuteBroadcast = (int) duration.toMinutes();
if (nextPhase.equals(GamePhase.ENDED)) {
Bukkit.broadcast(MiniMessage.miniMessage().deserialize(
"<green>The game will end in <bold><red>" + duration.toMinutes() + "</red> minutes</bold></green>"));
return;
}
Bukkit.broadcast(MiniMessage.miniMessage().deserialize(
"<green>The <phase> will start in <bold><red>" + duration.toMinutes() + "</red> minutes</bold></green>",
Placeholder.component("phase", nextPhase.getDisplayName())
));
} else if (duration.toMinutes() < 1 && duration.toSeconds() % 15 == 0) {
} else if (duration.toMinutes() < 1 && NOTIFY_SECONDS.contains(duration.toSecondsPart())) {
if (nextPhase.equals(GamePhase.ENDED)) {
Bukkit.broadcast(MiniMessage.miniMessage().deserialize(
"<green>The game will end in <bold><red>" + duration.toSeconds() + "</red> seconds</bold></green>"));
return;
}
Bukkit.broadcast(MiniMessage.miniMessage().deserialize(
"<green>The <phase> will start in <bold><red>" + duration.toSeconds() + "</red> seconds</bold></green>",
Placeholder.component("phase", nextPhase.getDisplayName())

View File

@ -15,17 +15,18 @@ public class CombatPhase implements GamePhaseExecutor {
private ScheduledExecutorService executorService = null;
@Override
public void start(Flag flag) {
public synchronized void start(Flag flag) {
Bukkit.broadcast(MiniMessage.miniMessage().deserialize("<green>CAPTURE THE FLAG</green>"));
flag.spawnFlag();
if (executorService == null || !executorService.isShutdown()) {
if (executorService != null) {
executorService.shutdown();
}
if (executorService == null) {
executorService = Executors.newSingleThreadScheduledExecutor();
} else if (executorService.isTerminated() || executorService.isShutdown()) {
executorService = Executors.newSingleThreadScheduledExecutor();
} else {
executorService.shutdown();
executorService = Executors.newSingleThreadScheduledExecutor();
}
executorService.scheduleAtFixedRate(flag, 0, 1, TimeUnit.SECONDS);
// TODO Add players to bossbar list for capture progress(or maybe only when any progress is made)
}
@Override

View File

@ -1,3 +1,3 @@
#Tue Feb 11 22:04:16 CET 2025
buildNumber=42
#Tue Feb 11 22:21:13 CET 2025
buildNumber=45
version=0.1