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 ed6abef..a88ebfc 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 @@ -1,7 +1,9 @@ package eu.mhsl.craftattack.spawn.event.appliances.deathrun; import eu.mhsl.craftattack.spawn.core.appliance.Appliance; -import eu.mhsl.craftattack.spawn.event.appliances.eventController.AbstractEvent; +import eu.mhsl.craftattack.spawn.event.appliances.eventController.Event; +import eu.mhsl.craftattack.spawn.event.appliances.eventController.Scorable; +import eu.mhsl.craftattack.spawn.event.appliances.eventController.scoreboard.EventScoreboardBuilder; import net.kyori.adventure.text.Component; import net.kyori.adventure.title.Title; import org.bukkit.Bukkit; @@ -10,17 +12,15 @@ import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; -import java.util.*; - @Appliance.Flags(autoload = false) -public class Deathrun extends AbstractEvent { +public class Deathrun extends Appliance implements Event, Scorable { + private final EventScoreboardBuilder scoreboardBuilder = new EventScoreboardBuilder(this, 3, 2, 3); + @Override public void initialize(@NotNull JavaPlugin plugin) { World world = Bukkit.getWorlds().getFirst(); world.getWorldBorder().setCenter(world.getSpawnLocation()); world.getWorldBorder().setSize(20); - - this.start(); } @Override @@ -31,27 +31,31 @@ public class Deathrun extends AbstractEvent { World world = Bukkit.getWorlds().getFirst(); world.getWorldBorder().setSize(world.getWorldBorder().getMaxSize()); - this.getScoreboardBuilder().updateScoreboards(); + this.getScoreboardBuilder().startAutomaticUpdates(); } @Override public int getScore(Player p) { - return (int) Math.ceil(p.getLocation().subtract(Bukkit.getWorlds().getFirst().getSpawnLocation()).x()); + return (int) Math.ceil(p.getLocation().x()); } @Override public void stop() { + this.getScoreboardBuilder().stopAutomaticUpdates(); Title title = Title.title(Component.text("Ende!"), Component.empty()); - Bukkit.getOnlinePlayers().forEach(player -> player.showTitle(title)); + Bukkit.getOnlinePlayers().forEach(player -> { + player.showTitle(title); + player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); + }); } @Override - public List getPlayers() { - return List.of(); - } - - @Override - public String displayName() { + public String getScoreboardName() { return "Deathrun"; } + + @Override + public EventScoreboardBuilder getScoreboardBuilder() { + return this.scoreboardBuilder; + } } diff --git a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/AbstractEvent.java b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/AbstractEvent.java deleted file mode 100644 index 540974b..0000000 --- a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/AbstractEvent.java +++ /dev/null @@ -1,20 +0,0 @@ -package eu.mhsl.craftattack.spawn.event.appliances.eventController; - -import eu.mhsl.craftattack.spawn.core.appliance.Appliance; -import eu.mhsl.craftattack.spawn.event.appliances.eventController.scoreboard.EventScoreEntry; -import eu.mhsl.craftattack.spawn.event.appliances.eventController.scoreboard.EventScoreboardBuilder; -import org.bukkit.scoreboard.Scoreboard; - -import java.util.*; - -@Appliance.Flags(enabled = false, autoload = false) -public abstract class AbstractEvent extends Appliance implements Event { - private final Map playerScoreboards = new HashMap<>(); - private final List playerScores = new ArrayList<>(); - private final EventScoreboardBuilder scoreboardBuilder = new EventScoreboardBuilder(this, 3, 2, 3); - - @Override - public EventScoreboardBuilder getScoreboardBuilder() { - return this.scoreboardBuilder; - } -} 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 70e4f4d..d457efa 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,16 +1,6 @@ package eu.mhsl.craftattack.spawn.event.appliances.eventController; -import eu.mhsl.craftattack.spawn.event.appliances.eventController.scoreboard.EventScoreboardBuilder; -import org.bukkit.entity.Player; - -import java.util.List; - public interface Event { - String displayName(); - EventScoreboardBuilder getScoreboardBuilder(); - void start(); void stop(); - List getPlayers(); - int getScore(Player p); } 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 0e92a99..f11f6af 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 @@ -6,10 +6,12 @@ import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.event.appliances.eventController.commands.EventCommand; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.List; public class EventController extends Appliance { private List eventAppliances = null; + private final List selectedEvents = new ArrayList<>(); @Override public void onEnable() { @@ -23,13 +25,32 @@ public class EventController extends Appliance { return this.eventAppliances; } - public void enableEvent(Appliance event) { - this.getEventAppliances().forEach(appliance -> appliance.disableSequence(Main.instance())); - Main.instance().restartAppliance(event.getClass()); + public void loadEvent(Appliance appliance) { + if(!(appliance instanceof Event event)) throw new IllegalArgumentException("Appliance has to implement Event."); + this.getEventAppliances().forEach(appliance1 -> appliance1.disableSequence(Main.instance())); + Main.instance().restartAppliance(appliance.getClass()); + this.selectedEvents.add(event); } - public void disableEvent(Appliance event) { - event.disableSequence(Main.instance()); + public void unloadEvent(Appliance appliance) { + if(!(appliance instanceof Event event)) throw new Error("Appliance does not implement Event."); + event.stop(); + appliance.disableSequence(Main.instance()); + this.selectedEvents.remove(event); + } + + public void startEvents() { + this.selectedEvents.forEach(Event::start); + } + + public void stopEvents() { + this.selectedEvents.forEach(Event::stop); + } + + public List getSelectedEvents() { + return this.selectedEvents.stream() + .map(event -> event.getClass().getSimpleName().toLowerCase()) + .toList(); } @Override diff --git a/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/Scorable.java b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/Scorable.java new file mode 100644 index 0000000..6b0ebd9 --- /dev/null +++ b/event/src/main/java/eu/mhsl/craftattack/spawn/event/appliances/eventController/Scorable.java @@ -0,0 +1,10 @@ +package eu.mhsl.craftattack.spawn.event.appliances.eventController; + +import eu.mhsl.craftattack.spawn.event.appliances.eventController.scoreboard.EventScoreboardBuilder; +import org.bukkit.entity.Player; + +public interface Scorable { + String getScoreboardName(); + EventScoreboardBuilder getScoreboardBuilder(); + int getScore(Player p); +} 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 a6610ac..826bdbd 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 @@ -20,18 +20,26 @@ public class EventCommand extends ApplianceCommand { if(args.length == 0) throw new Error("No argument selected!"); switch(args[0]) { + case "unselect": { + if(args.length == 1) throw new Error("Not enough arguments for unselect."); + this.getAppliance().unloadEvent(this.findApplianceFromString(args[1])); + break; + } case "select": { - sender.sendMessage("select"); + if(args.length == 1) throw new Error("Not enough arguments for select."); + this.getAppliance().loadEvent(this.findApplianceFromString(args[1])); + break; + } + case "list": { + sender.sendMessage("These Events are currently selected: \n%s".formatted(this.getAppliance().getSelectedEvents())); break; } case "start": { - if(args.length == 1) throw new Error("Not enough arguments for start."); - this.getAppliance().enableEvent(this.findApplianceFromString(args[1])); + this.getAppliance().startEvents(); break; } case "stop": { - if(args.length == 1) throw new Error("Not enough arguments for stop."); - this.getAppliance().disableEvent(this.findApplianceFromString(args[1])); + this.getAppliance().stopEvents(); break; } default: throw new Error("No such option: '%s' !".formatted(args[0])); @@ -43,13 +51,13 @@ public class EventCommand extends ApplianceCommand { return this.getAppliance().getEventAppliances().stream() .filter(appliance -> appliance.getClass().getSimpleName().equalsIgnoreCase(name)) .findFirst() - .orElseThrow(); + .orElseThrow(() -> new Error("Event appliance '%s' not found.".formatted(name))); } @Override public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if(args.length == 1) return List.of("select", "start", "stop"); - if(args.length == 2) return this.getAppliance().getEventAppliances().stream() + if(args.length == 1) return List.of("select", "unselect", "list", "start", "stop"); + if(args.length == 2 && List.of("select", "unselect").contains(args[0])) return this.getAppliance().getEventAppliances().stream() .map(appliance -> appliance.getClass().getSimpleName().toLowerCase()) .toList(); 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 80133d4..187d4cd 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 @@ -1,7 +1,8 @@ package eu.mhsl.craftattack.spawn.event.appliances.eventController.scoreboard; import eu.mhsl.craftattack.spawn.core.Main; -import eu.mhsl.craftattack.spawn.event.appliances.eventController.Event; +import eu.mhsl.craftattack.spawn.event.appliances.eventController.Scorable; +import io.papermc.paper.scoreboard.numbers.NumberFormat; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.util.Ticks; @@ -18,22 +19,17 @@ public class EventScoreboardBuilder { private final int topPlaces; private final int aroundPlaces; private final int bottomPlaces; - private final Event event; + private final Scorable scorable; private final Comparator scoreComparator; private final List playerScores = new ArrayList<>(); - private final Map playerScoreboardMap = new HashMap<>(); private int scoreboardUpdateTaskId = -1; - public EventScoreboardBuilder(Event event) { - this(event, 3, 2, 3); + public EventScoreboardBuilder(Scorable scorable, int topPlaces, int aroundPlaces, int bottomPlaces) { + this(scorable, topPlaces, aroundPlaces, bottomPlaces, Comparator.comparingInt(EventScoreEntry::score).reversed()); } - public EventScoreboardBuilder(Event event, int topPlaces, int aroundPlaces, int bottomPlaces) { - this(event, topPlaces, aroundPlaces, bottomPlaces, Comparator.comparingInt(EventScoreEntry::score).reversed()); - } - - public EventScoreboardBuilder(Event event, int topPlaces, int aroundPlaces, int bottomPlaces, Comparator scoreComparator) { - this.event = event; + public EventScoreboardBuilder(Scorable scorable, int topPlaces, int aroundPlaces, int bottomPlaces, Comparator scoreComparator) { + this.scorable = scorable; this.topPlaces = topPlaces; this.aroundPlaces = aroundPlaces; this.bottomPlaces = bottomPlaces; @@ -46,9 +42,10 @@ public class EventScoreboardBuilder { Objective objective = newScoreboard.registerNewObjective( "event", "dummy", - Component.text("Scoreboard %s".formatted(this.event.displayName()), NamedTextColor.GOLD) + Component.text("Scoreboard %s".formatted(this.scorable.getScoreboardName()), NamedTextColor.GOLD) ); objective.setDisplaySlot(DisplaySlot.SIDEBAR); + objective.numberFormat(NumberFormat.blank()); if(scoreMap.isEmpty()) return newScoreboard; @@ -60,7 +57,7 @@ public class EventScoreboardBuilder { .findFirst() .orElse(null); if(playerScoreEntry == null) { - playerScoreEntry = new EventScoreEntry(p.getUniqueId(), p.getName(), this.event.getScore(p)); + playerScoreEntry = new EventScoreEntry(p.getUniqueId(), p.getName(), this.scorable.getScore(p)); scoreMap.add(playerScoreEntry); } @@ -95,7 +92,6 @@ public class EventScoreboardBuilder { objective.getScore(line).setScore(place); }); - this.playerScoreboardMap.put(p.getUniqueId(), newScoreboard); return newScoreboard; } @@ -115,7 +111,7 @@ public class EventScoreboardBuilder { private void updateScore(Player p) { this.playerScores.removeIf(entry -> entry.playerUuid().equals(p.getUniqueId())); - this.playerScores.add(new EventScoreEntry(p.getUniqueId(), p.getName(), this.event.getScore(p))); + this.playerScores.add(new EventScoreEntry(p.getUniqueId(), p.getName(), this.scorable.getScore(p))); } public void updateScoreboards() { @@ -128,7 +124,7 @@ public class EventScoreboardBuilder { private String formattedLine(int place, String name, int score) { name = this.trimName(name); - return name + ": " + score; + return "%s. %s: %s".formatted(place+1, name, score); } private String trimName(String name) {