added AbstractEvent and basic Scoreboard functionality
This commit is contained in:
@@ -10,6 +10,7 @@ import org.bukkit.plugin.java.JavaPlugin;
|
|||||||
import org.reflections.Reflections;
|
import org.reflections.Reflections;
|
||||||
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@@ -49,7 +50,7 @@ public final class Main extends JavaPlugin {
|
|||||||
Main.logger().info(String.format("Loaded %d repositories!", this.repositoryLoader.getRepositories().size()));
|
Main.logger().info(String.format("Loaded %d repositories!", this.repositoryLoader.getRepositories().size()));
|
||||||
|
|
||||||
Main.logger().info("Loading appliances...");
|
Main.logger().info("Loading appliances...");
|
||||||
this.appliances = this.findSubtypesOf(Appliance.class).stream()
|
this.appliances = new ArrayList<>(this.findSubtypesOf(Appliance.class).stream()
|
||||||
.filter(applianceClass -> !disabledAppliances.contains(applianceClass.getSimpleName()))
|
.filter(applianceClass -> !disabledAppliances.contains(applianceClass.getSimpleName()))
|
||||||
.filter(appliance -> {
|
.filter(appliance -> {
|
||||||
Appliance.Flags flags = appliance.getAnnotation(Appliance.Flags.class);
|
Appliance.Flags flags = appliance.getAnnotation(Appliance.Flags.class);
|
||||||
@@ -63,7 +64,7 @@ public final class Main extends JavaPlugin {
|
|||||||
throw new RuntimeException(String.format("Failed to create instance of '%s'", applianceClass.getName()), e);
|
throw new RuntimeException(String.format("Failed to create instance of '%s'", applianceClass.getName()), e);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.toList();
|
.toList());
|
||||||
Main.logger().info(String.format("Loaded %d appliances!", this.appliances.size()));
|
Main.logger().info(String.format("Loaded %d appliances!", this.appliances.size()));
|
||||||
|
|
||||||
Main.logger().info("Initializing appliances...");
|
Main.logger().info("Initializing appliances...");
|
||||||
|
|||||||
@@ -1,22 +1,36 @@
|
|||||||
package eu.mhsl.craftattack.spawn.event.appliances.deathrun;
|
package eu.mhsl.craftattack.spawn.event.appliances.deathrun;
|
||||||
|
|
||||||
|
import eu.mhsl.craftattack.spawn.core.Main;
|
||||||
import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
|
import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
|
||||||
import eu.mhsl.craftattack.spawn.event.appliances.eventController.Event;
|
import eu.mhsl.craftattack.spawn.event.appliances.eventController.AbstractEvent;
|
||||||
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 net.kyori.adventure.util.Ticks;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
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 Appliance implements Event {
|
public class Deathrun extends AbstractEvent {
|
||||||
|
private int scoreboardUpdateTaskId;
|
||||||
|
|
||||||
@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
|
||||||
|
public void onDisable() {
|
||||||
|
if(this.scoreboardUpdateTaskId != -1) Bukkit.getScheduler().cancelTask(this.scoreboardUpdateTaskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -26,6 +40,18 @@ public class Deathrun extends Appliance implements Event {
|
|||||||
|
|
||||||
World world = Bukkit.getWorlds().getFirst();
|
World world = Bukkit.getWorlds().getFirst();
|
||||||
world.getWorldBorder().setSize(world.getWorldBorder().getMaxSize());
|
world.getWorldBorder().setSize(world.getWorldBorder().getMaxSize());
|
||||||
|
|
||||||
|
this.updateScoreboards();
|
||||||
|
this.scoreboardUpdateTaskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(
|
||||||
|
Main.instance(),
|
||||||
|
this::updateScoreboards,
|
||||||
|
Ticks.TICKS_PER_SECOND,
|
||||||
|
Ticks.TICKS_PER_SECOND
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateScoreboards() {
|
||||||
|
Bukkit.getOnlinePlayers().forEach(this::updateScoreboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -43,4 +69,11 @@ public class Deathrun extends Appliance implements Event {
|
|||||||
public String displayName() {
|
public String displayName() {
|
||||||
return "Deathrun";
|
return "Deathrun";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @NotNull List<Listener> listeners() {
|
||||||
|
return List.of(
|
||||||
|
new DeathrunListener()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package eu.mhsl.craftattack.spawn.event.appliances.deathrun;
|
||||||
|
|
||||||
|
import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
|
||||||
|
class DeathrunListener extends ApplianceListener<Deathrun> {
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerMove(PlayerMoveEvent event) {
|
||||||
|
if(!event.hasChangedPosition()) return;
|
||||||
|
if(event.getTo().clone().subtract(event.getFrom()).x() == 0) return;
|
||||||
|
|
||||||
|
this.getAppliance().updateScore(event.getPlayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
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(3, 2, 3);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<UUID, Scoreboard> getPlayerScoreboards() {
|
||||||
|
return this.playerScoreboards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EventScoreEntry> getPlayerScores() {
|
||||||
|
return this.playerScores;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EventScoreboardBuilder getScoreboardBuilder() {
|
||||||
|
return this.scoreboardBuilder;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,31 @@
|
|||||||
package eu.mhsl.craftattack.spawn.event.appliances.eventController;
|
package eu.mhsl.craftattack.spawn.event.appliances.eventController;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import eu.mhsl.craftattack.spawn.event.appliances.eventController.Scoreboard.EventScoreEntry;
|
||||||
|
import eu.mhsl.craftattack.spawn.event.appliances.eventController.Scoreboard.EventScoreboardBuilder;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.scoreboard.Scoreboard;
|
import org.bukkit.scoreboard.Scoreboard;
|
||||||
|
|
||||||
public interface Event {
|
import java.util.List;
|
||||||
Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface Event {
|
||||||
String displayName();
|
String displayName();
|
||||||
|
Map<UUID, Scoreboard> getPlayerScoreboards();
|
||||||
|
List<EventScoreEntry> getPlayerScores();
|
||||||
|
EventScoreboardBuilder getScoreboardBuilder();
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
int getScore(Player p);
|
int getScore(Player p);
|
||||||
|
default void updateScore(Player p) {
|
||||||
public default void updateSidebar() {
|
System.out.println(this.getPlayerScores().removeIf(entry -> entry.playerUuid().equals(p.getUniqueId())));
|
||||||
|
this.getPlayerScores().add(new EventScoreEntry(p.getUniqueId(), p.getName(), this.getScore(p)));
|
||||||
|
}
|
||||||
|
default void updateScoreboard(Player p) {
|
||||||
|
this.updateScore(p);
|
||||||
|
Scoreboard scoreboard = this.getScoreboardBuilder().buildFor(p, this);
|
||||||
|
this.getPlayerScoreboards().put(p.getUniqueId(), scoreboard);
|
||||||
|
p.setScoreboard(scoreboard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,14 @@ public class EventController extends Appliance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<Appliance> getEventAppliances() {
|
public List<Appliance> getEventAppliances() {
|
||||||
if(eventAppliances == null) throw new IllegalStateException("Event appliances were not initialized");
|
if(this.eventAppliances == null) throw new IllegalStateException("Event appliances were not initialized");
|
||||||
return eventAppliances;
|
return this.eventAppliances;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enableEvent(Appliance event) {
|
public void enableEvent(Appliance event) {
|
||||||
getEventAppliances().forEach(appliance -> appliance.disableSequence(Main.instance()));
|
this.getEventAppliances().forEach(appliance -> appliance.disableSequence(Main.instance()));
|
||||||
Main.instance().restartAppliance(event.getClass());
|
Main.instance().restartAppliance(event.getClass());
|
||||||
|
// Main.instance().getAppliance(event.getClass())
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disableEvent(Appliance event) {
|
public void disableEvent(Appliance event) {
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package eu.mhsl.craftattack.spawn.event.appliances.eventController.Scoreboard;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public record EventScoreEntry(UUID playerUuid, String name, int score) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
package eu.mhsl.craftattack.spawn.event.appliances.eventController.Scoreboard;
|
||||||
|
|
||||||
|
import eu.mhsl.craftattack.spawn.event.appliances.eventController.Event;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.scoreboard.DisplaySlot;
|
||||||
|
import org.bukkit.scoreboard.Objective;
|
||||||
|
import org.bukkit.scoreboard.Scoreboard;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public class EventScoreboardBuilder {
|
||||||
|
private final int topPlaces;
|
||||||
|
private final int aroundPlaces;
|
||||||
|
private final int bottomPlaces;
|
||||||
|
|
||||||
|
public EventScoreboardBuilder(int topPlaces, int aroundPlaces, int bottomPlaces) {
|
||||||
|
this.topPlaces = topPlaces;
|
||||||
|
this.aroundPlaces = aroundPlaces;
|
||||||
|
this.bottomPlaces = bottomPlaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Scoreboard buildFor(Player p, Event event) {
|
||||||
|
List<EventScoreEntry> scoreMap = event.getPlayerScores();
|
||||||
|
Scoreboard newScoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
|
||||||
|
|
||||||
|
Objective objective = newScoreboard.registerNewObjective(
|
||||||
|
"event", "dummy",
|
||||||
|
Component.text("Scoreboard %s".formatted(event.displayName()), NamedTextColor.GOLD)
|
||||||
|
);
|
||||||
|
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
|
||||||
|
|
||||||
|
if(scoreMap.isEmpty()) return newScoreboard;
|
||||||
|
|
||||||
|
scoreMap.sort(Comparator.comparingInt(EventScoreEntry::score).reversed());
|
||||||
|
System.out.print(scoreMap);
|
||||||
|
|
||||||
|
EventScoreEntry playerScoreEntry = scoreMap.stream()
|
||||||
|
.filter(entry -> entry.playerUuid().equals(p.getUniqueId()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
if(playerScoreEntry == null) {
|
||||||
|
playerScoreEntry = new EventScoreEntry(p.getUniqueId(), p.getName(), event.getScore(p));
|
||||||
|
scoreMap.add(playerScoreEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
int playerIndex = scoreMap.indexOf(playerScoreEntry);
|
||||||
|
|
||||||
|
IntStream topStream = IntStream.range(0, this.topPlaces);
|
||||||
|
IntStream aroundStream = IntStream.range(playerIndex - this.aroundPlaces, playerIndex + this.aroundPlaces);
|
||||||
|
IntStream bottomStream = IntStream.range(scoreMap.size() - this.bottomPlaces, scoreMap.size());
|
||||||
|
|
||||||
|
if(playerIndex <= this.topPlaces + this.aroundPlaces) {
|
||||||
|
aroundStream = IntStream.empty();
|
||||||
|
topStream = IntStream.range(0, playerIndex + this.aroundPlaces);
|
||||||
|
}
|
||||||
|
if(playerIndex >= scoreMap.size() - this.bottomPlaces - this.aroundPlaces) {
|
||||||
|
aroundStream = IntStream.empty();
|
||||||
|
bottomStream = IntStream.range(playerIndex - this.aroundPlaces, scoreMap.size());
|
||||||
|
}
|
||||||
|
if(scoreMap.size() <= this.topPlaces + this.aroundPlaces * 2 + this.bottomPlaces + 2) {
|
||||||
|
topStream = IntStream.range(0, scoreMap.size());
|
||||||
|
aroundStream = IntStream.empty();
|
||||||
|
bottomStream = IntStream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
IntStream indices = IntStream.concat(
|
||||||
|
IntStream.concat(topStream, aroundStream),
|
||||||
|
bottomStream
|
||||||
|
).distinct().sorted();
|
||||||
|
|
||||||
|
indices.forEach(place -> {
|
||||||
|
EventScoreEntry entry = scoreMap.get(place);
|
||||||
|
String line = this.formattedLine(place, entry.name(), entry.score());
|
||||||
|
objective.getScore(line).setScore(place);
|
||||||
|
});
|
||||||
|
|
||||||
|
return newScoreboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formattedLine(int place, String name, int score) {
|
||||||
|
name = this.trimName(name);
|
||||||
|
return name + ": " + score;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String trimName(String name) {
|
||||||
|
if (name == null) return "Unknown";
|
||||||
|
if (name.length() > 12) {
|
||||||
|
return name.substring(0, 12);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,12 +26,12 @@ public class EventCommand extends ApplianceCommand<EventController> {
|
|||||||
}
|
}
|
||||||
case "start": {
|
case "start": {
|
||||||
if(args.length == 1) throw new Error("Not enough arguments for start.");
|
if(args.length == 1) throw new Error("Not enough arguments for start.");
|
||||||
this.getAppliance().enableEvent(findApplianceFromString(args[1]));
|
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.");
|
if(args.length == 1) throw new Error("Not enough arguments for stop.");
|
||||||
this.getAppliance().disableEvent(findApplianceFromString(args[1]));
|
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]));
|
||||||
@@ -49,6 +49,9 @@ public class EventCommand extends ApplianceCommand<EventController> {
|
|||||||
@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", "start", "stop");
|
||||||
|
if(args.length == 2) return this.getAppliance().getEventAppliances().stream()
|
||||||
|
.map(appliance -> appliance.getClass().getSimpleName().toLowerCase())
|
||||||
|
.toList();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user