split Event into Scorable and Event; removed AbstractEvent; added list, select and unselect commands

This commit is contained in:
2025-12-12 19:30:21 +01:00
parent 04cb233604
commit dd1518fce4
7 changed files with 83 additions and 74 deletions

View File

@@ -1,7 +1,9 @@
package eu.mhsl.craftattack.spawn.event.appliances.deathrun; package eu.mhsl.craftattack.spawn.event.appliances.deathrun;
import eu.mhsl.craftattack.spawn.core.appliance.Appliance; 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.text.Component;
import net.kyori.adventure.title.Title; import net.kyori.adventure.title.Title;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -10,17 +12,15 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.*;
@Appliance.Flags(autoload = false) @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 @Override
public void initialize(@NotNull JavaPlugin plugin) { public void initialize(@NotNull JavaPlugin plugin) {
World world = Bukkit.getWorlds().getFirst(); World world = Bukkit.getWorlds().getFirst();
world.getWorldBorder().setCenter(world.getSpawnLocation()); world.getWorldBorder().setCenter(world.getSpawnLocation());
world.getWorldBorder().setSize(20); world.getWorldBorder().setSize(20);
this.start();
} }
@Override @Override
@@ -31,27 +31,31 @@ public class Deathrun extends AbstractEvent {
World world = Bukkit.getWorlds().getFirst(); World world = Bukkit.getWorlds().getFirst();
world.getWorldBorder().setSize(world.getWorldBorder().getMaxSize()); world.getWorldBorder().setSize(world.getWorldBorder().getMaxSize());
this.getScoreboardBuilder().updateScoreboards(); this.getScoreboardBuilder().startAutomaticUpdates();
} }
@Override @Override
public int getScore(Player p) { 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 @Override
public void stop() { public void stop() {
this.getScoreboardBuilder().stopAutomaticUpdates();
Title title = Title.title(Component.text("Ende!"), Component.empty()); 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 @Override
public List<Player> getPlayers() { public String getScoreboardName() {
return List.of();
}
@Override
public String displayName() {
return "Deathrun"; return "Deathrun";
} }
@Override
public EventScoreboardBuilder getScoreboardBuilder() {
return this.scoreboardBuilder;
}
} }

View File

@@ -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<UUID, Scoreboard> playerScoreboards = new HashMap<>();
private final List<EventScoreEntry> playerScores = new ArrayList<>();
private final EventScoreboardBuilder scoreboardBuilder = new EventScoreboardBuilder(this, 3, 2, 3);
@Override
public EventScoreboardBuilder getScoreboardBuilder() {
return this.scoreboardBuilder;
}
}

View File

@@ -1,16 +1,6 @@
package eu.mhsl.craftattack.spawn.event.appliances.eventController; 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 { public interface Event {
String displayName();
EventScoreboardBuilder getScoreboardBuilder();
void start(); void start();
void stop(); void stop();
List<Player> getPlayers();
int getScore(Player p);
} }

View File

@@ -6,10 +6,12 @@ import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.event.appliances.eventController.commands.EventCommand; import eu.mhsl.craftattack.spawn.event.appliances.eventController.commands.EventCommand;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class EventController extends Appliance { public class EventController extends Appliance {
private List<Appliance> eventAppliances = null; private List<Appliance> eventAppliances = null;
private final List<Event> selectedEvents = new ArrayList<>();
@Override @Override
public void onEnable() { public void onEnable() {
@@ -23,13 +25,32 @@ public class EventController extends Appliance {
return this.eventAppliances; return this.eventAppliances;
} }
public void enableEvent(Appliance event) { public void loadEvent(Appliance appliance) {
this.getEventAppliances().forEach(appliance -> appliance.disableSequence(Main.instance())); if(!(appliance instanceof Event event)) throw new IllegalArgumentException("Appliance has to implement Event.");
Main.instance().restartAppliance(event.getClass()); this.getEventAppliances().forEach(appliance1 -> appliance1.disableSequence(Main.instance()));
Main.instance().restartAppliance(appliance.getClass());
this.selectedEvents.add(event);
} }
public void disableEvent(Appliance event) { public void unloadEvent(Appliance appliance) {
event.disableSequence(Main.instance()); 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<String> getSelectedEvents() {
return this.selectedEvents.stream()
.map(event -> event.getClass().getSimpleName().toLowerCase())
.toList();
} }
@Override @Override

View File

@@ -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);
}

View File

@@ -20,18 +20,26 @@ public class EventCommand extends ApplianceCommand<EventController> {
if(args.length == 0) throw new Error("No argument selected!"); if(args.length == 0) throw new Error("No argument selected!");
switch(args[0]) { 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": { 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; break;
} }
case "start": { case "start": {
if(args.length == 1) throw new Error("Not enough arguments for start."); this.getAppliance().startEvents();
this.getAppliance().enableEvent(this.findApplianceFromString(args[1]));
break; break;
} }
case "stop": { case "stop": {
if(args.length == 1) throw new Error("Not enough arguments for stop."); this.getAppliance().stopEvents();
this.getAppliance().disableEvent(this.findApplianceFromString(args[1]));
break; break;
} }
default: throw new Error("No such option: '%s' !".formatted(args[0])); default: throw new Error("No such option: '%s' !".formatted(args[0]));
@@ -43,13 +51,13 @@ public class EventCommand extends ApplianceCommand<EventController> {
return this.getAppliance().getEventAppliances().stream() return this.getAppliance().getEventAppliances().stream()
.filter(appliance -> appliance.getClass().getSimpleName().equalsIgnoreCase(name)) .filter(appliance -> appliance.getClass().getSimpleName().equalsIgnoreCase(name))
.findFirst() .findFirst()
.orElseThrow(); .orElseThrow(() -> new Error("Event appliance '%s' not found.".formatted(name)));
} }
@Override @Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { public @Nullable List<String> 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 == 1) return List.of("select", "unselect", "list", "start", "stop");
if(args.length == 2) return this.getAppliance().getEventAppliances().stream() if(args.length == 2 && List.of("select", "unselect").contains(args[0])) return this.getAppliance().getEventAppliances().stream()
.map(appliance -> appliance.getClass().getSimpleName().toLowerCase()) .map(appliance -> appliance.getClass().getSimpleName().toLowerCase())
.toList(); .toList();
return null; return null;

View File

@@ -1,7 +1,8 @@
package eu.mhsl.craftattack.spawn.event.appliances.eventController.scoreboard; package eu.mhsl.craftattack.spawn.event.appliances.eventController.scoreboard;
import eu.mhsl.craftattack.spawn.core.Main; 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.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.util.Ticks; import net.kyori.adventure.util.Ticks;
@@ -18,22 +19,17 @@ public class EventScoreboardBuilder {
private final int topPlaces; private final int topPlaces;
private final int aroundPlaces; private final int aroundPlaces;
private final int bottomPlaces; private final int bottomPlaces;
private final Event event; private final Scorable scorable;
private final Comparator<EventScoreEntry> scoreComparator; private final Comparator<EventScoreEntry> scoreComparator;
private final List<EventScoreEntry> playerScores = new ArrayList<>(); private final List<EventScoreEntry> playerScores = new ArrayList<>();
private final Map<UUID, Scoreboard> playerScoreboardMap = new HashMap<>();
private int scoreboardUpdateTaskId = -1; private int scoreboardUpdateTaskId = -1;
public EventScoreboardBuilder(Event event) { public EventScoreboardBuilder(Scorable scorable, int topPlaces, int aroundPlaces, int bottomPlaces) {
this(event, 3, 2, 3); this(scorable, topPlaces, aroundPlaces, bottomPlaces, Comparator.comparingInt(EventScoreEntry::score).reversed());
} }
public EventScoreboardBuilder(Event event, int topPlaces, int aroundPlaces, int bottomPlaces) { public EventScoreboardBuilder(Scorable scorable, int topPlaces, int aroundPlaces, int bottomPlaces, Comparator<EventScoreEntry> scoreComparator) {
this(event, topPlaces, aroundPlaces, bottomPlaces, Comparator.comparingInt(EventScoreEntry::score).reversed()); this.scorable = scorable;
}
public EventScoreboardBuilder(Event event, int topPlaces, int aroundPlaces, int bottomPlaces, Comparator<EventScoreEntry> scoreComparator) {
this.event = event;
this.topPlaces = topPlaces; this.topPlaces = topPlaces;
this.aroundPlaces = aroundPlaces; this.aroundPlaces = aroundPlaces;
this.bottomPlaces = bottomPlaces; this.bottomPlaces = bottomPlaces;
@@ -46,9 +42,10 @@ public class EventScoreboardBuilder {
Objective objective = newScoreboard.registerNewObjective( Objective objective = newScoreboard.registerNewObjective(
"event", "dummy", "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.setDisplaySlot(DisplaySlot.SIDEBAR);
objective.numberFormat(NumberFormat.blank());
if(scoreMap.isEmpty()) return newScoreboard; if(scoreMap.isEmpty()) return newScoreboard;
@@ -60,7 +57,7 @@ public class EventScoreboardBuilder {
.findFirst() .findFirst()
.orElse(null); .orElse(null);
if(playerScoreEntry == 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); scoreMap.add(playerScoreEntry);
} }
@@ -95,7 +92,6 @@ public class EventScoreboardBuilder {
objective.getScore(line).setScore(place); objective.getScore(line).setScore(place);
}); });
this.playerScoreboardMap.put(p.getUniqueId(), newScoreboard);
return newScoreboard; return newScoreboard;
} }
@@ -115,7 +111,7 @@ public class EventScoreboardBuilder {
private void updateScore(Player p) { private void updateScore(Player p) {
this.playerScores.removeIf(entry -> entry.playerUuid().equals(p.getUniqueId())); 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() { public void updateScoreboards() {
@@ -128,7 +124,7 @@ public class EventScoreboardBuilder {
private String formattedLine(int place, String name, int score) { private String formattedLine(int place, String name, int score) {
name = this.trimName(name); name = this.trimName(name);
return name + ": " + score; return "%s. %s: %s".formatted(place+1, name, score);
} }
private String trimName(String name) { private String trimName(String name) {