diff --git a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/deathrun/Deathrun.java b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/deathrun/Deathrun.java index a3cefdc..43625af 100644 --- a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/deathrun/Deathrun.java +++ b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/deathrun/Deathrun.java @@ -19,6 +19,8 @@ import java.util.List; public class Deathrun extends Appliance implements Event, Scorable { private final EventScoreboardBuilder scoreboardBuilder = new EventScoreboardBuilder(this, 3, 2, 3); private final double borderDistance = 100; + private final int borderVisibilityDistance = 8; + private long durationSeconds; @Override public void onEnable() { @@ -31,6 +33,10 @@ public class Deathrun extends Appliance implements Event, Scorable { return this.borderDistance; } + public int getBorderVisibilityDistance() { + return this.borderVisibilityDistance; + } + public void spawnParticleWall(Player p, double xMin, double xMax, double yMin, double yMax, double zMin, double zMax) { Particle particle = Particle.WAX_ON; @@ -50,7 +56,8 @@ public class Deathrun extends Appliance implements Event, Scorable { } @Override - public void start() { + public void start(long durationSeconds) { + this.durationSeconds = durationSeconds; Title title = Title.title(Component.text("Start"), Component.text("Erreiche die höchste x-Koordinate!")); Bukkit.getOnlinePlayers().forEach(player -> player.showTitle(title)); @@ -73,6 +80,11 @@ public class Deathrun extends Appliance implements Event, Scorable { }); } + @Override + public long getDurationSeconds() { + return this.durationSeconds; + } + @Override public String getScoreboardName() { return "Deathrun"; diff --git a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/deathrun/DeathrunPlayerMoveListener.java b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/deathrun/DeathrunPlayerMoveListener.java index 45941fd..e65ab71 100644 --- a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/deathrun/DeathrunPlayerMoveListener.java +++ b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/deathrun/DeathrunPlayerMoveListener.java @@ -13,19 +13,19 @@ public class DeathrunPlayerMoveListener extends ApplianceListener { double minX = spawnLocation.x() - this.getAppliance().getBorderDistance(); double minZ = spawnLocation.z() - this.getAppliance().getBorderDistance(); double maxZ = spawnLocation.z() + this.getAppliance().getBorderDistance(); - if(event.getTo().x() < minX + 5) { + if(event.getTo().x() < minX + this.getAppliance().getBorderVisibilityDistance()) { this.getAppliance().spawnParticleWall(event.getPlayer(), minX-0.2, minX-0.2, event.getTo().y()-0.5, event.getTo().y()+2.5, event.getTo().z()-1.5, event.getTo().z()+1.5); if(event.getTo().x() < minX) { event.setTo(event.getTo().clone().set(minX, event.getTo().y(), event.getTo().z())); } } - if(event.getTo().z() < minZ + 5) { + if(event.getTo().z() < minZ + this.getAppliance().getBorderVisibilityDistance()) { this.getAppliance().spawnParticleWall(event.getPlayer(), event.getTo().x()-1.5, event.getTo().x()+1.5, event.getTo().y()-0.5, event.getTo().y()+2.5, minZ-0.2, minZ-0.2); if(event.getTo().z() < minZ) { event.setTo(event.getTo().clone().set(event.getTo().x(), event.getTo().y(), minZ)); } } - if(event.getTo().z() > maxZ - 5) { + if(event.getTo().z() > maxZ - this.getAppliance().getBorderVisibilityDistance()) { this.getAppliance().spawnParticleWall(event.getPlayer(), event.getTo().x()-1.5, event.getTo().x()+1.5, event.getTo().y()-0.5, event.getTo().y()+2.5, maxZ+0.2, maxZ+0.2); if(event.getTo().z() > maxZ) { event.setTo(event.getTo().clone().set(event.getTo().x(), event.getTo().y(), maxZ)); diff --git a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/Event.java b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/Event.java index d457efa..59af224 100644 --- a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/Event.java +++ b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/Event.java @@ -1,6 +1,7 @@ package eu.mhsl.craftattack.spawn.event.appliances.eventController; public interface Event { - void start(); + void start(long durationSeconds); void stop(); + long getDurationSeconds(); } diff --git a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/EventController.java b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/EventController.java index a156f42..26c16e1 100644 --- a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/EventController.java +++ b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/EventController.java @@ -4,6 +4,10 @@ import eu.mhsl.craftattack.spawn.core.Main; import eu.mhsl.craftattack.spawn.core.appliance.Appliance; import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.event.appliances.eventController.commands.EventCommand; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.util.Ticks; +import org.bukkit.Bukkit; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -11,6 +15,8 @@ import java.util.List; public class EventController extends Appliance { private List eventAppliances = null; private Event selectedEvent = null; + private long timerStart; + private int timerTaskId = -1; @Override public void onEnable() { @@ -41,15 +47,25 @@ public class EventController extends Appliance { this.selectedEvent = null; } - public void startEvent() { + public void startEvent(long durationMinutes) { if(this.selectedEvent == null) throw new ApplianceCommand.Error("There is no event selected!"); - this.selectedEvent.start(); + this.selectedEvent.start(durationMinutes * 60); if(this.selectedEvent instanceof Scorable scorable && scorable.automaticUpdates()) scorable.getScoreboardBuilder().startAutomaticUpdates(); + // TODO: possibility for other dimensions + this.timerStart = Bukkit.getWorlds().getFirst().getFullTime(); + this.timerTaskId = Bukkit.getScheduler().scheduleSyncRepeatingTask( + Main.instance(), + this::updateTimer, + Ticks.TICKS_PER_SECOND, + Ticks.TICKS_PER_SECOND + ); } public void stopEvent() { if(this.selectedEvent == null) throw new ApplianceCommand.Error("There is no event selected!"); this.selectedEvent.stop(); + if(this.timerTaskId != -1) Bukkit.getScheduler().cancelTask(this.timerTaskId); + this.timerTaskId = -1; } public String getSelectedEvent() { @@ -57,6 +73,25 @@ public class EventController extends Appliance { return this.selectedEvent.getClass().getSimpleName().toLowerCase(); } + private void updateTimer() { + long ticksLeft = this.timerStart - (Bukkit.getWorlds().getFirst().getFullTime() - this.selectedEvent.getDurationSeconds() * Ticks.TICKS_PER_SECOND); + if(ticksLeft <= 0) { + if(this.timerTaskId != -1) Bukkit.getScheduler().cancelTask(this.timerTaskId); + this.timerTaskId = -1; + this.selectedEvent.stop(); + Bukkit.getOnlinePlayers().forEach(player -> player.sendActionBar(Component.text("Fertig!"))); + return; + } + + Bukkit.getOnlinePlayers().forEach(player -> player.sendActionBar( + Component.text(formatSeconds(ticksLeft / Ticks.TICKS_PER_SECOND), NamedTextColor.GOLD) + )); + } + + public static String formatSeconds(long seconds){ + return String.format("%02d:%02d:%02d", seconds / 3600, (seconds / 60) % 60, seconds % 60); + } + @Override protected @NotNull List> commands() { return List.of( diff --git a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/commands/EventCommand.java b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/commands/EventCommand.java index a3aa611..9b66702 100644 --- a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/commands/EventCommand.java +++ b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/commands/EventCommand.java @@ -34,7 +34,17 @@ public class EventCommand extends ApplianceCommand { break; } case "start": { - this.getAppliance().startEvent(); + if(args.length == 1) { + this.getAppliance().startEvent(60 * 2); + break; + } + if(args.length == 2) { + try { + this.getAppliance().startEvent(Long.parseLong(args[1])); + } catch(NumberFormatException e) { + throw new Error("Last argument has to be a long."); + } + } break; } case "stop": { @@ -59,6 +69,7 @@ public class EventCommand extends ApplianceCommand { if(args.length == 2 && args[0].equals("load")) return this.getAppliance().getEventAppliances().stream() .map(appliance -> appliance.getClass().getSimpleName().toLowerCase()) .toList(); + if(args.length == 2 && args[0].equals("start")) return List.of(""); return null; } } diff --git a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/scoreboard/EventScoreboardBuilder.java b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/scoreboard/EventScoreboardBuilder.java index 187d4cd..14a9675 100644 --- a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/scoreboard/EventScoreboardBuilder.java +++ b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/scoreboard/EventScoreboardBuilder.java @@ -42,7 +42,7 @@ public class EventScoreboardBuilder { Objective objective = newScoreboard.registerNewObjective( "event", "dummy", - Component.text("Scoreboard %s".formatted(this.scorable.getScoreboardName()), NamedTextColor.GOLD) + Component.text("Scoreboard %s".formatted(this.scorable.getScoreboardName()), NamedTextColor.DARK_PURPLE) ); objective.setDisplaySlot(DisplaySlot.SIDEBAR); objective.numberFormat(NumberFormat.blank());