Upload folder via GUI - src
This commit is contained in:
88
src/main/java/dev/viper/eventengine/EventEngine.java
Normal file
88
src/main/java/dev/viper/eventengine/EventEngine.java
Normal file
@@ -0,0 +1,88 @@
|
||||
package dev.viper.eventengine;
|
||||
|
||||
import dev.viper.eventengine.command.EventCommand;
|
||||
import dev.viper.eventengine.command.RegionSetupManager;
|
||||
import dev.viper.eventengine.config.ConfigManager;
|
||||
import dev.viper.eventengine.gui.EventGUI;
|
||||
import dev.viper.eventengine.listener.EventCreateListener;
|
||||
import dev.viper.eventengine.listener.EventProtectionListener;
|
||||
import dev.viper.eventengine.manager.EventManager;
|
||||
import dev.viper.eventengine.manager.EventRegistry;
|
||||
import dev.viper.eventengine.scheduler.EventScheduler;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class EventEngine extends JavaPlugin {
|
||||
|
||||
private static EventEngine instance;
|
||||
|
||||
private ConfigManager configManager;
|
||||
private EventRegistry eventRegistry;
|
||||
private EventManager eventManager;
|
||||
private EventScheduler eventScheduler;
|
||||
private EventGUI eventGUI;
|
||||
private EventCreateListener eventCreateListener;
|
||||
private RegionSetupManager regionSetupManager;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
|
||||
// Config
|
||||
configManager = new ConfigManager(this);
|
||||
configManager.load();
|
||||
|
||||
// Registry (builtin + custom)
|
||||
eventRegistry = new EventRegistry(this);
|
||||
eventRegistry.init();
|
||||
|
||||
// Event-Manager (Lifecycle)
|
||||
eventManager = new EventManager(this);
|
||||
|
||||
// Scheduler
|
||||
eventScheduler = new EventScheduler(this);
|
||||
eventScheduler.start();
|
||||
|
||||
// GUI
|
||||
eventGUI = new EventGUI(this);
|
||||
getServer().getPluginManager().registerEvents(eventGUI, this);
|
||||
|
||||
// Create-Listener (Custom Event Builder)
|
||||
eventCreateListener = new EventCreateListener(this);
|
||||
getServer().getPluginManager().registerEvents(eventCreateListener, this);
|
||||
|
||||
// Region-Schutz Listener
|
||||
getServer().getPluginManager().registerEvents(new EventProtectionListener(this), this);
|
||||
|
||||
// Region-Setup Manager
|
||||
regionSetupManager = new RegionSetupManager(this);
|
||||
|
||||
// Command
|
||||
EventCommand cmd = new EventCommand(this);
|
||||
getCommand("event").setExecutor(cmd);
|
||||
getCommand("event").setTabCompleter(cmd);
|
||||
|
||||
getLogger().info("EventEngine gestartet — " + eventRegistry.count() + " Events geladen.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (eventScheduler != null) eventScheduler.stop();
|
||||
if (eventManager != null && eventManager.isRunning()) {
|
||||
eventManager.endEvent("Server-Shutdown");
|
||||
}
|
||||
getLogger().info("EventEngine deaktiviert.");
|
||||
}
|
||||
|
||||
// ─── Getter ────────────────────────────────────────────────────────────
|
||||
|
||||
public static EventEngine getInstance() { return instance; }
|
||||
public ConfigManager getConfigManager() { return configManager; }
|
||||
public EventRegistry getEventRegistry() { return eventRegistry; }
|
||||
public EventManager getEventManager() { return eventManager; }
|
||||
public EventScheduler getEventScheduler() { return eventScheduler; }
|
||||
public EventGUI getEventGUI() { return eventGUI; }
|
||||
public EventCreateListener getEventCreateListener() { return eventCreateListener; }
|
||||
public RegionSetupManager getRegionSetupManager() { return regionSetupManager; }
|
||||
|
||||
public String prefix() { return configManager.getPrefix(); }
|
||||
}
|
||||
318
src/main/java/dev/viper/eventengine/command/EventCommand.java
Normal file
318
src/main/java/dev/viper/eventengine/command/EventCommand.java
Normal file
@@ -0,0 +1,318 @@
|
||||
package dev.viper.eventengine.command;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.command.RegionSetupManager;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import dev.viper.eventengine.model.EventDefinition;
|
||||
import dev.viper.eventengine.model.ScheduleEntry;
|
||||
import dev.viper.eventengine.manager.EventManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EventCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
private final EventEngine plugin;
|
||||
|
||||
public EventCommand(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
String p = plugin.prefix();
|
||||
|
||||
if (args.length == 0) {
|
||||
if (sender instanceof Player player) {
|
||||
plugin.getEventGUI().openMain(player);
|
||||
} else {
|
||||
sendHelp(sender);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (args[0].toLowerCase()) {
|
||||
|
||||
// ─── GUI ───────────────────────────────────────────────────────
|
||||
case "gui" -> {
|
||||
requirePlayer(sender, () -> plugin.getEventGUI().openMain((Player) sender));
|
||||
}
|
||||
|
||||
// ─── START ─────────────────────────────────────────────────────
|
||||
case "start" -> {
|
||||
requirePerm(sender, () -> {
|
||||
if (args.length < 2) { sender.sendMessage(p + "§cUsage: /event start <id|random>"); return; }
|
||||
String id = args[1].toLowerCase();
|
||||
EventDefinition def;
|
||||
if (id.equals("random")) {
|
||||
def = plugin.getEventRegistry().getWeightedRandom().orElse(null);
|
||||
} else {
|
||||
def = plugin.getEventRegistry().get(id).orElse(null);
|
||||
}
|
||||
if (def == null) { sender.sendMessage(p + "§cEvent nicht gefunden: §f" + id); return; }
|
||||
Player initiator = sender instanceof Player pl ? pl : null;
|
||||
plugin.getEventManager().startEvent(def, initiator);
|
||||
});
|
||||
}
|
||||
|
||||
// ─── STOP ──────────────────────────────────────────────────────
|
||||
case "stop" -> {
|
||||
requirePerm(sender, () -> {
|
||||
String reason = args.length > 1 ? String.join(" ", Arrays.copyOfRange(args, 1, args.length)) : "Admin";
|
||||
if (!plugin.getEventManager().endEvent(reason)) {
|
||||
sender.sendMessage(p + "§cKein Event läuft.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ─── JOIN/LEAVE ────────────────────────────────────────────────
|
||||
case "join" -> requirePlayer(sender, () -> plugin.getEventManager().join((Player) sender));
|
||||
case "leave" -> requirePlayer(sender, () -> plugin.getEventManager().leave((Player) sender));
|
||||
|
||||
// ─── INFO ──────────────────────────────────────────────────────
|
||||
case "info" -> {
|
||||
if (args.length >= 2) {
|
||||
// Event-Info
|
||||
plugin.getEventRegistry().get(args[1]).ifPresentOrElse(def -> {
|
||||
sender.sendMessage("§8§m══════════════════════════════");
|
||||
sender.sendMessage("§6 " + def.getDisplayName() + " §8[" + def.getId() + "]");
|
||||
sender.sendMessage("§7 Kategorie: §f" + def.getCategory().getDisplayName());
|
||||
sender.sendMessage("§7 Beschreibung: §f" + def.getDescription());
|
||||
sender.sendMessage("§7 Dauer: §f" + EventManager.formatTime(def.getDurationSeconds()));
|
||||
sender.sendMessage("§7 Spieler: §f" + def.getMinPlayers() + "–" + def.getMaxPlayers());
|
||||
sender.sendMessage("§7 Custom: §f" + def.isCustom());
|
||||
sender.sendMessage("§7 Start-Befehle: §f" + def.getStartCommands().size());
|
||||
sender.sendMessage("§7 Belohnungen: §f" + def.getRewards().size());
|
||||
sender.sendMessage("§8§m══════════════════════════════");
|
||||
}, () -> sender.sendMessage(p + "§cEvent nicht gefunden."));
|
||||
} else {
|
||||
// Aktuelles Event
|
||||
ActiveEvent current = plugin.getEventManager().getCurrentEvent();
|
||||
if (current == null) {
|
||||
sender.sendMessage(p + "§cKein Event aktiv.");
|
||||
} else {
|
||||
sender.sendMessage("§8§m══════════════════════════════");
|
||||
sender.sendMessage("§6 Aktuelles Event: §e" + current.getDefinition().getDisplayName());
|
||||
sender.sendMessage("§7 Teilnehmer: §f" + current.getParticipantCount());
|
||||
sender.sendMessage("§7 Verbleibend: §f" + EventManager.formatTime((int) current.getRemainingSeconds()));
|
||||
sender.sendMessage("§7 Status: §f" + current.getState());
|
||||
sender.sendMessage("§8§m══════════════════════════════");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─── LIST ──────────────────────────────────────────────────────
|
||||
case "list" -> {
|
||||
int page = args.length >= 2 ? parseIntSafe(args[1], 1) - 1 : 0;
|
||||
List<EventDefinition> all = new ArrayList<>(plugin.getEventRegistry().getAll());
|
||||
int perPage = 12;
|
||||
int totalPages = Math.max(1, (int) Math.ceil(all.size() / (double) perPage));
|
||||
page = Math.max(0, Math.min(page, totalPages - 1));
|
||||
|
||||
sender.sendMessage("§8§m══════════════════════════════");
|
||||
sender.sendMessage("§6 EventEngine – Events §8(" + (page + 1) + "/" + totalPages + ") §7[" + all.size() + " total]");
|
||||
all.stream().skip((long) page * perPage).limit(perPage).forEach(def ->
|
||||
sender.sendMessage(" §7- §e" + def.getId() + " §8│ §f" + def.getDisplayName() + " §8│ §7" + def.getCategory().getDisplayName())
|
||||
);
|
||||
sender.sendMessage("§8§m══════════════════════════════");
|
||||
if (totalPages > 1) sender.sendMessage("§7Nächste Seite: §f/event list " + (page + 2));
|
||||
}
|
||||
|
||||
// ─── SCHEDULE ──────────────────────────────────────────────────
|
||||
case "schedule" -> {
|
||||
List<ScheduleEntry> schedule = plugin.getConfigManager().getSchedule();
|
||||
sender.sendMessage("§8§m══════════════════════════════");
|
||||
sender.sendMessage("§6 Geplante Events §8(" + schedule.size() + ")");
|
||||
if (schedule.isEmpty()) {
|
||||
sender.sendMessage("§7 Kein Zeitplan konfiguriert.");
|
||||
sender.sendMessage("§7 Füge Einträge in der config.yml hinzu.");
|
||||
} else {
|
||||
schedule.forEach(e -> sender.sendMessage(" §7• §f" + e));
|
||||
}
|
||||
sender.sendMessage("§8§m══════════════════════════════");
|
||||
}
|
||||
|
||||
// ─── CREATE ────────────────────────────────────────────────────
|
||||
case "create" -> {
|
||||
requirePerm(sender, () -> {
|
||||
requirePlayer(sender, () -> {
|
||||
if (args.length < 2) { sender.sendMessage(p + "§cUsage: /event create <id>"); return; }
|
||||
String id = args[1].toLowerCase().replaceAll("[^a-z0-9_]", "_");
|
||||
if (plugin.getEventRegistry().exists(id)) {
|
||||
sender.sendMessage(p + "§cID bereits vorhanden: §f" + id);
|
||||
return;
|
||||
}
|
||||
if (plugin.getEventCreateListener().hasSession((Player) sender)) {
|
||||
sender.sendMessage(p + "§cDu hast bereits einen laufenden Builder.");
|
||||
return;
|
||||
}
|
||||
plugin.getEventCreateListener().startSession((Player) sender, id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ─── DELETE ────────────────────────────────────────────────────
|
||||
case "delete" -> {
|
||||
requirePerm(sender, () -> {
|
||||
if (args.length < 2) { sender.sendMessage(p + "§cUsage: /event delete <id>"); return; }
|
||||
String id = args[1].toLowerCase();
|
||||
EventDefinition def = plugin.getEventRegistry().get(id).orElse(null);
|
||||
if (def == null) { sender.sendMessage(p + "§cEvent nicht gefunden."); return; }
|
||||
if (!def.isCustom()) { sender.sendMessage(p + "§cEingebaute Events können nicht gelöscht werden."); return; }
|
||||
plugin.getEventRegistry().remove(id);
|
||||
sender.sendMessage(p + "§aCustom Event §e'" + id + "' §agelöscht.");
|
||||
});
|
||||
}
|
||||
|
||||
// ─── SCORE ─────────────────────────────────────────────────────
|
||||
case "score" -> {
|
||||
requirePerm(sender, () -> {
|
||||
if (args.length < 3) { sender.sendMessage(p + "§cUsage: /event score <spieler> <punkte>"); return; }
|
||||
Player target = Bukkit.getPlayer(args[1]);
|
||||
if (target == null) { sender.sendMessage(p + "§cSpieler nicht gefunden."); return; }
|
||||
int points = parseIntSafe(args[2], 0);
|
||||
ActiveEvent ev = plugin.getEventManager().getCurrentEvent();
|
||||
if (ev == null) { sender.sendMessage(p + "§cKein Event aktiv."); return; }
|
||||
ev.addScore(target.getUniqueId(), points);
|
||||
sender.sendMessage(p + "§a+" + points + " Punkte für §e" + target.getName());
|
||||
});
|
||||
}
|
||||
|
||||
// ─── ROTATION ──────────────────────────────────────────────────
|
||||
case "rotation" -> {
|
||||
requirePerm(sender, () -> {
|
||||
if (args.length < 3) { sender.sendMessage(p + "§cUsage: /event rotation <add|remove> <id>"); return; }
|
||||
String action = args[1].toLowerCase();
|
||||
String id = args[2].toLowerCase();
|
||||
plugin.getEventRegistry().get(id).ifPresentOrElse(def -> {
|
||||
boolean rotState = action.equals("add");
|
||||
def.setInRotation(rotState);
|
||||
if (def.isCustom()) plugin.getConfigManager().saveCustomEvent(def);
|
||||
sender.sendMessage(p + "§e" + def.getDisplayName() + " §7→ Rotation: " + (rotState ? "§aAktiv" : "§cInaktiv"));
|
||||
}, () -> sender.sendMessage(p + "§cEvent nicht gefunden."));
|
||||
});
|
||||
}
|
||||
|
||||
// ─── RELOAD ────────────────────────────────────────────────────
|
||||
case "reload" -> {
|
||||
requirePerm(sender, () -> {
|
||||
plugin.getConfigManager().load();
|
||||
plugin.getEventRegistry().init();
|
||||
plugin.getEventScheduler().restart();
|
||||
sender.sendMessage(p + "§aKonfiguration neu geladen. §7(" + plugin.getEventRegistry().count() + " Events)");
|
||||
});
|
||||
}
|
||||
|
||||
// ─── REGION ────────────────────────────────────────────────
|
||||
case "region" -> {
|
||||
requirePerm(sender, () -> {
|
||||
requirePlayer(sender, () -> {
|
||||
if (args.length < 3) {
|
||||
sender.sendMessage(p + "§cUsage: /event region <pos1|pos2|clear|info> <id>");
|
||||
return;
|
||||
}
|
||||
String sub = args[1].toLowerCase();
|
||||
String id = args[2].toLowerCase();
|
||||
RegionSetupManager rsm = plugin.getRegionSetupManager();
|
||||
switch (sub) {
|
||||
case "pos1" -> rsm.handlePos1((Player) sender, id);
|
||||
case "pos2" -> rsm.handlePos2((Player) sender, id);
|
||||
case "clear" -> rsm.handleClear((Player) sender, id);
|
||||
case "info" -> rsm.handleInfo((Player) sender, id);
|
||||
default -> sender.sendMessage(p + "§cUnbekannte Sub-Option. pos1 | pos2 | clear | info");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
default -> sendHelp(sender);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ─── Tab-Completer ─────────────────────────────────────────────────────
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return filter(args[0], "gui", "start", "stop", "join", "leave", "info", "list",
|
||||
"schedule", "create", "delete", "score", "rotation", "region", "reload");
|
||||
}
|
||||
if (args.length == 2) {
|
||||
return switch (args[0].toLowerCase()) {
|
||||
case "start", "info", "delete" -> {
|
||||
List<String> ids = plugin.getEventRegistry().getAll().stream()
|
||||
.map(EventDefinition::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (args[0].equalsIgnoreCase("start")) ids.add(0, "random");
|
||||
yield filter(args[1], ids.toArray(new String[0]));
|
||||
}
|
||||
case "rotation" -> filter(args[1], "add", "remove");
|
||||
case "score" -> null; // Spielernamen
|
||||
case "region" -> filter(args[1], "pos1", "pos2", "clear", "info");
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
if (args.length == 3 && args[0].equalsIgnoreCase("rotation")) {
|
||||
return plugin.getEventRegistry().getAll().stream()
|
||||
.map(EventDefinition::getId)
|
||||
.filter(id -> id.startsWith(args[2].toLowerCase()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ─── Hilfsmethoden ─────────────────────────────────────────────────────
|
||||
|
||||
private void sendHelp(CommandSender sender) {
|
||||
sender.sendMessage("§8§m══════════════════════════════");
|
||||
sender.sendMessage("§6 EventEngine Befehle");
|
||||
sender.sendMessage("§e /event gui §7- GUI öffnen");
|
||||
sender.sendMessage("§e /event start <id|random> §7- Event starten");
|
||||
sender.sendMessage("§e /event stop [grund] §7- Event beenden");
|
||||
sender.sendMessage("§e /event join/leave §7- Am Event teilnehmen");
|
||||
sender.sendMessage("§e /event info [id] §7- Event-Info anzeigen");
|
||||
sender.sendMessage("§e /event list [seite] §7- Alle Events auflisten");
|
||||
sender.sendMessage("§e /event schedule §7- Zeitplan anzeigen");
|
||||
sender.sendMessage("§e /event create <id> §7- Custom Event erstellen");
|
||||
sender.sendMessage("§e /event delete <id> §7- Custom Event löschen");
|
||||
sender.sendMessage("§e /event score <spieler> <punkte> §7- Punkte vergeben");
|
||||
sender.sendMessage("§e /event rotation <add|remove> <id> §7- Rotation steuern");
|
||||
sender.sendMessage("§e /event reload §7- Config neu laden");
|
||||
sender.sendMessage("§e /event region <pos1|pos2|clear|info> <id> §7- Event-Arena setzen");
|
||||
sender.sendMessage("§8§m══════════════════════════════");
|
||||
}
|
||||
|
||||
private void requirePerm(CommandSender sender, Runnable r) {
|
||||
if (!sender.hasPermission("eventengine.admin")) {
|
||||
sender.sendMessage(plugin.prefix() + "§cKeine Berechtigung.");
|
||||
return;
|
||||
}
|
||||
r.run();
|
||||
}
|
||||
|
||||
private void requirePlayer(CommandSender sender, Runnable r) {
|
||||
if (!(sender instanceof Player)) {
|
||||
sender.sendMessage(plugin.prefix() + "§cNur für Spieler.");
|
||||
return;
|
||||
}
|
||||
r.run();
|
||||
}
|
||||
|
||||
private List<String> filter(String prefix, String... options) {
|
||||
return Arrays.stream(options)
|
||||
.filter(s -> s.toLowerCase().startsWith(prefix.toLowerCase()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private int parseIntSafe(String s, int def) {
|
||||
try { return Integer.parseInt(s); } catch (Exception e) { return def; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package dev.viper.eventengine.command;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.EventDefinition;
|
||||
import dev.viper.eventengine.model.EventRegion;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Stellt Pos1/Pos2-Auswahl für Event-Regionen bereit.
|
||||
* Eingebaut in EventCommand via sub-commands:
|
||||
*
|
||||
* /event region pos1 <id> → Pos1 auf Spieler-Position setzen
|
||||
* /event region pos2 <id> → Pos2 setzen + Region speichern
|
||||
* /event region clear <id> → Region entfernen
|
||||
* /event region info <id> → Region anzeigen
|
||||
*/
|
||||
public class RegionSetupManager {
|
||||
|
||||
private final EventEngine plugin;
|
||||
// Temporäre Pos1-Speicher pro Spieler: UUID → [eventId, Location]
|
||||
private final Map<UUID, Object[]> pos1Selection = new HashMap<>();
|
||||
|
||||
public RegionSetupManager(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void handlePos1(Player player, String eventId) {
|
||||
EventDefinition def = plugin.getEventRegistry().get(eventId).orElse(null);
|
||||
if (def == null) { player.sendMessage(plugin.prefix() + "§cEvent nicht gefunden: §f" + eventId); return; }
|
||||
|
||||
pos1Selection.put(player.getUniqueId(), new Object[]{eventId, player.getLocation().clone()});
|
||||
player.sendMessage(plugin.prefix() + "§aPos1 gesetzt: §f" + formatLoc(player));
|
||||
player.sendMessage(plugin.prefix() + "§7Jetzt: §f/event region pos2 " + eventId);
|
||||
}
|
||||
|
||||
public void handlePos2(Player player, String eventId) {
|
||||
EventDefinition def = plugin.getEventRegistry().get(eventId).orElse(null);
|
||||
if (def == null) { player.sendMessage(plugin.prefix() + "§cEvent nicht gefunden: §f" + eventId); return; }
|
||||
|
||||
Object[] sel = pos1Selection.get(player.getUniqueId());
|
||||
if (sel == null || !sel[0].equals(eventId)) {
|
||||
player.sendMessage(plugin.prefix() + "§cZuerst Pos1 setzen: §f/event region pos1 " + eventId);
|
||||
return;
|
||||
}
|
||||
|
||||
org.bukkit.Location pos1 = (org.bukkit.Location) sel[1];
|
||||
org.bukkit.Location pos2 = player.getLocation().clone();
|
||||
|
||||
if (!pos1.getWorld().equals(pos2.getWorld())) {
|
||||
player.sendMessage(plugin.prefix() + "§cBeide Positionen müssen in der gleichen Welt sein!");
|
||||
return;
|
||||
}
|
||||
|
||||
EventRegion region = new EventRegion(pos1, pos2);
|
||||
def.setRegion(region);
|
||||
|
||||
// Custom Events direkt speichern; builtin: in memory (gilt bis Reload)
|
||||
if (def.isCustom()) plugin.getConfigManager().saveCustomEvent(def);
|
||||
|
||||
pos1Selection.remove(player.getUniqueId());
|
||||
|
||||
player.sendMessage(plugin.prefix() + "§a✔ Region gesetzt für §e" + def.getDisplayName() + "§a:");
|
||||
player.sendMessage("§7 Welt: §f" + region.getWorldName());
|
||||
player.sendMessage("§7 Von: §f" + region.getMinX() + ", " + region.getMinY() + ", " + region.getMinZ());
|
||||
player.sendMessage("§7 Bis: §f" + region.getMaxX() + ", " + region.getMaxY() + ", " + region.getMaxZ());
|
||||
player.sendMessage("§7 Größe: §f" + region.getSizeX() + "x" + region.getSizeY() + "x" + region.getSizeZ());
|
||||
}
|
||||
|
||||
public void handleClear(Player player, String eventId) {
|
||||
EventDefinition def = plugin.getEventRegistry().get(eventId).orElse(null);
|
||||
if (def == null) { player.sendMessage(plugin.prefix() + "§cEvent nicht gefunden: §f" + eventId); return; }
|
||||
def.setRegion(null);
|
||||
if (def.isCustom()) plugin.getConfigManager().saveCustomEvent(def);
|
||||
player.sendMessage(plugin.prefix() + "§7Region für §e" + def.getDisplayName() + " §7entfernt (gesamte Welt).");
|
||||
}
|
||||
|
||||
public void handleInfo(Player player, String eventId) {
|
||||
EventDefinition def = plugin.getEventRegistry().get(eventId).orElse(null);
|
||||
if (def == null) { player.sendMessage(plugin.prefix() + "§cEvent nicht gefunden: §f" + eventId); return; }
|
||||
if (!def.hasRegion()) {
|
||||
player.sendMessage(plugin.prefix() + "§e" + def.getDisplayName() + " §7hat keine Region (gesamte Welt).");
|
||||
return;
|
||||
}
|
||||
EventRegion r = def.getRegion();
|
||||
player.sendMessage("§8§m══════════════════════════════");
|
||||
player.sendMessage("§6 Region: §e" + def.getDisplayName());
|
||||
player.sendMessage("§7 Welt: §f" + r.getWorldName());
|
||||
player.sendMessage("§7 Von: §f" + r.getMinX() + ", " + r.getMinY() + ", " + r.getMinZ());
|
||||
player.sendMessage("§7 Bis: §f" + r.getMaxX() + ", " + r.getMaxY() + ", " + r.getMaxZ());
|
||||
player.sendMessage("§7 Größe: §f" + r.getSizeX() + "×" + r.getSizeY() + "×" + r.getSizeZ() + " Blöcke");
|
||||
player.sendMessage("§8§m══════════════════════════════");
|
||||
}
|
||||
|
||||
private String formatLoc(Player p) {
|
||||
return p.getWorld().getName() + " "
|
||||
+ p.getLocation().getBlockX() + ", "
|
||||
+ p.getLocation().getBlockY() + ", "
|
||||
+ p.getLocation().getBlockZ();
|
||||
}
|
||||
}
|
||||
169
src/main/java/dev/viper/eventengine/config/ConfigManager.java
Normal file
169
src/main/java/dev/viper/eventengine/config/ConfigManager.java
Normal file
@@ -0,0 +1,169 @@
|
||||
package dev.viper.eventengine.config;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.EventDefinition;
|
||||
import dev.viper.eventengine.model.ScheduleEntry;
|
||||
import dev.viper.eventengine.util.ColorUtil;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class ConfigManager {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private final Logger log;
|
||||
|
||||
private FileConfiguration mainConfig;
|
||||
private File customEventsFile;
|
||||
private FileConfiguration customEventsConfig;
|
||||
|
||||
// Geladene Zeitplan-Einträge
|
||||
private final List<ScheduleEntry> schedule = new ArrayList<>();
|
||||
|
||||
// Intervall-Fallback (Minuten), wenn kein Zeitplan aktiv
|
||||
private int intervalMinutes;
|
||||
private boolean useInterval;
|
||||
private boolean randomOnInterval;
|
||||
private String defaultEventId;
|
||||
|
||||
// Ankündigungs-Vorlauf in Sekunden
|
||||
private int announceBefore;
|
||||
// Ob Events im Chat-Log erscheinen
|
||||
private boolean logEvents;
|
||||
// Prefix für alle Nachrichten
|
||||
private String prefix;
|
||||
// Schutz-Einstellungen
|
||||
private boolean enforceRegionBoundary;
|
||||
private boolean noExplosionBlockDamage;
|
||||
private boolean restrictBlockInteraction;
|
||||
|
||||
public ConfigManager(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
this.log = plugin.getLogger();
|
||||
}
|
||||
|
||||
// ─── Laden ─────────────────────────────────────────────────────────────
|
||||
|
||||
public void load() {
|
||||
plugin.saveDefaultConfig();
|
||||
plugin.reloadConfig();
|
||||
mainConfig = plugin.getConfig();
|
||||
|
||||
loadSchedule();
|
||||
loadGeneral();
|
||||
loadCustomEventsFile();
|
||||
}
|
||||
|
||||
private void loadGeneral() {
|
||||
intervalMinutes = mainConfig.getInt("settings.interval-minutes", 60);
|
||||
useInterval = mainConfig.getBoolean("settings.use-interval", false);
|
||||
randomOnInterval = mainConfig.getBoolean("settings.random-on-interval", true);
|
||||
defaultEventId = mainConfig.getString("settings.default-event", "RANDOM");
|
||||
announceBefore = mainConfig.getInt("settings.announce-before-seconds", 30);
|
||||
logEvents = mainConfig.getBoolean("settings.log-events", true);
|
||||
enforceRegionBoundary = mainConfig.getBoolean("protection.enforce-region-boundary", true);
|
||||
noExplosionBlockDamage = mainConfig.getBoolean("protection.no-explosion-block-damage", true);
|
||||
restrictBlockInteraction = mainConfig.getBoolean("protection.restrict-block-interaction", true);
|
||||
prefix = ColorUtil.color(mainConfig.getString("settings.prefix", "&8[&6EventEngine&8]&r "));
|
||||
}
|
||||
|
||||
private void loadSchedule() {
|
||||
schedule.clear();
|
||||
List<Map<?, ?>> entries = mainConfig.getMapList("schedule");
|
||||
for (Map<?, ?> entry : entries) {
|
||||
try {
|
||||
String timeStr = (String) entry.get("time");
|
||||
String eventId = (String) entry.get("event");
|
||||
if (timeStr == null || eventId == null) continue;
|
||||
|
||||
LocalTime time = LocalTime.parse(timeStr);
|
||||
List<DayOfWeek> days = new ArrayList<>();
|
||||
|
||||
Object daysRaw = entry.get("days");
|
||||
if (daysRaw instanceof List<?> dayList) {
|
||||
for (Object d : dayList) {
|
||||
String ds = d.toString().toUpperCase();
|
||||
if (ds.equals("DAILY")) { days.clear(); break; }
|
||||
try { days.add(DayOfWeek.valueOf(ds)); }
|
||||
catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
schedule.add(new ScheduleEntry(days, time, eventId));
|
||||
} catch (DateTimeParseException e) {
|
||||
log.warning("Ungültiger Zeitplan-Eintrag: " + entry);
|
||||
}
|
||||
}
|
||||
log.info("Zeitplan geladen: " + schedule.size() + " Einträge.");
|
||||
}
|
||||
|
||||
private void loadCustomEventsFile() {
|
||||
customEventsFile = new File(plugin.getDataFolder(), "custom_events.yml");
|
||||
if (!customEventsFile.exists()) {
|
||||
try { customEventsFile.createNewFile(); }
|
||||
catch (IOException e) { log.severe("Konnte custom_events.yml nicht erstellen!"); }
|
||||
}
|
||||
customEventsConfig = YamlConfiguration.loadConfiguration(customEventsFile);
|
||||
}
|
||||
|
||||
// ─── Custom Events lesen/schreiben ─────────────────────────────────────
|
||||
|
||||
public Map<String, EventDefinition> loadCustomEvents() {
|
||||
Map<String, EventDefinition> result = new LinkedHashMap<>();
|
||||
ConfigurationSection root = customEventsConfig.getConfigurationSection("events");
|
||||
if (root == null) return result;
|
||||
|
||||
for (String id : root.getKeys(false)) {
|
||||
ConfigurationSection sec = root.getConfigurationSection(id);
|
||||
if (sec != null) {
|
||||
EventDefinition def = EventDefinition.fromConfig(id, sec);
|
||||
result.put(id, def);
|
||||
}
|
||||
}
|
||||
log.info("Custom Events geladen: " + result.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
public void saveCustomEvent(EventDefinition def) {
|
||||
ConfigurationSection root = customEventsConfig.getConfigurationSection("events");
|
||||
if (root == null) root = customEventsConfig.createSection("events");
|
||||
ConfigurationSection sec = root.createSection(def.getId());
|
||||
def.saveToConfig(sec);
|
||||
try {
|
||||
customEventsConfig.save(customEventsFile);
|
||||
} catch (IOException e) {
|
||||
log.severe("Konnte custom_events.yml nicht speichern: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteCustomEvent(String id) {
|
||||
if (customEventsConfig.contains("events." + id)) {
|
||||
customEventsConfig.set("events." + id, null);
|
||||
try { customEventsConfig.save(customEventsFile); }
|
||||
catch (IOException e) { log.severe("Speicherfehler: " + e.getMessage()); }
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Getter ────────────────────────────────────────────────────────────
|
||||
|
||||
public List<ScheduleEntry> getSchedule() { return Collections.unmodifiableList(schedule); }
|
||||
public int getIntervalMinutes() { return intervalMinutes; }
|
||||
public boolean isUseInterval() { return useInterval; }
|
||||
public boolean isRandomOnInterval() { return randomOnInterval; }
|
||||
public String getDefaultEventId() { return defaultEventId; }
|
||||
public int getAnnounceBefore() { return announceBefore; }
|
||||
public boolean isLogEvents() { return logEvents; }
|
||||
public String getPrefix() { return prefix; }
|
||||
public boolean isEnforceRegionBoundary() { return enforceRegionBoundary; }
|
||||
public boolean isNoExplosionBlockDamage() { return noExplosionBlockDamage; }
|
||||
public boolean isRestrictBlockInteraction() { return restrictBlockInteraction; }
|
||||
public FileConfiguration getMainConfig() { return mainConfig; }
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package dev.viper.eventengine.config;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.util.ColorUtil;
|
||||
import dev.viper.eventengine.model.EventCategory;
|
||||
import dev.viper.eventengine.model.EventDefinition;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Liest den "event-overrides" Block aus config.yml und
|
||||
* überschreibt die Defaults eingebauter EventDefinitions.
|
||||
*/
|
||||
public class EventOverrideLoader {
|
||||
|
||||
private final EventEngine plugin;
|
||||
|
||||
public EventOverrideLoader(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void apply(EventDefinition def) {
|
||||
ConfigurationSection overrides = plugin.getConfigManager()
|
||||
.getMainConfig().getConfigurationSection("event-overrides");
|
||||
if (overrides == null) return;
|
||||
|
||||
ConfigurationSection sec = overrides.getConfigurationSection(def.getId());
|
||||
if (sec == null) return;
|
||||
|
||||
if (sec.contains("display-name")) def.setDisplayName(sec.getString("display-name"));
|
||||
if (sec.contains("description")) def.setDescription(sec.getString("description"));
|
||||
if (sec.contains("duration-seconds")) def.setDurationSeconds(sec.getInt("duration-seconds"));
|
||||
if (sec.contains("min-players")) def.setMinPlayers(sec.getInt("min-players"));
|
||||
if (sec.contains("max-players")) def.setMaxPlayers(sec.getInt("max-players"));
|
||||
if (sec.contains("announcement")) def.setAnnouncement(ColorUtil.color(sec.getString("announcement")));
|
||||
if (sec.contains("in-rotation")) def.setInRotation(sec.getBoolean("in-rotation"));
|
||||
if (sec.contains("weight")) def.setWeight(sec.getInt("weight"));
|
||||
if (sec.contains("start-commands")) def.setStartCommands(sec.getStringList("start-commands"));
|
||||
if (sec.contains("end-commands")) def.setEndCommands(sec.getStringList("end-commands"));
|
||||
if (sec.contains("rewards")) def.setRewards(sec.getStringList("rewards"));
|
||||
if (sec.contains("category")) {
|
||||
try { def.setCategory(EventCategory.valueOf(sec.getString("category").toUpperCase())); }
|
||||
catch (Exception ignored) {}
|
||||
}
|
||||
ConfigurationSection settings = sec.getConfigurationSection("settings");
|
||||
if (settings != null) {
|
||||
for (String key : settings.getKeys(false)) {
|
||||
def.setSetting(key, settings.get(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
import org.bukkit.boss.BossBar;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Boss Rush:
|
||||
* - 5 Bosse nacheinander, jeder stärker als der vorherige
|
||||
* - BossBar zeigt HP
|
||||
* - Wer den letzten Schlag landet: Bonus-Punkte
|
||||
*/
|
||||
public class BossRushHandler implements IEventHandler, Listener {
|
||||
|
||||
private static final String[][] BOSSES = {
|
||||
{"§2Mini-Zomboss", "ZOMBIE"},
|
||||
{"§6Skelett-König", "SKELETON"},
|
||||
{"§dHexen-Mutter", "WITCH"},
|
||||
{"§cRiesen-Creeper", "CREEPER"},
|
||||
{"§4§lDER ENDGEGNER", "WITHER_SKELETON"}
|
||||
};
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private int bossIndex = 0;
|
||||
private LivingEntity currentBoss;
|
||||
private BossBar bossBar;
|
||||
|
||||
public BossRushHandler(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
this.bossIndex = 0;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
broadcast("§4⚔ §cBoss Rush! §75 Bosse nacheinander. Wer überlebt?");
|
||||
spawnNextBoss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
if (bossBar != null) { bossBar.removeAll(); bossBar = null; }
|
||||
if (currentBoss != null && !currentBoss.isDead()) currentBoss.remove();
|
||||
this.currentEvent = null;
|
||||
}
|
||||
|
||||
private void spawnNextBoss() {
|
||||
if (bossIndex >= BOSSES.length) {
|
||||
broadcast("§a✔ §eAlle Bosse besiegt! Boss Rush abgeschlossen!");
|
||||
plugin.getEventManager().endEvent("Alle Bosse besiegt");
|
||||
return;
|
||||
}
|
||||
|
||||
String[] bossData = BOSSES[bossIndex];
|
||||
String bossName = bossData[0];
|
||||
EntityType type;
|
||||
try { type = EntityType.valueOf(bossData[1]); }
|
||||
catch (Exception e) { type = EntityType.ZOMBIE; }
|
||||
|
||||
// Spawn bei erstem Online-Teilnehmer
|
||||
Location loc = null;
|
||||
for (UUID uuid : currentEvent.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null) { loc = p.getLocation().add(5, 0, 0); break; }
|
||||
}
|
||||
if (loc == null) return;
|
||||
|
||||
double hp = 40 + (bossIndex * 40);
|
||||
currentBoss = (LivingEntity) loc.getWorld().spawnEntity(loc, type);
|
||||
currentBoss.setCustomName(bossName);
|
||||
currentBoss.setCustomNameVisible(true);
|
||||
if (currentBoss.getAttribute(Attribute.MAX_HEALTH) != null) {
|
||||
currentBoss.getAttribute(Attribute.MAX_HEALTH).setBaseValue(hp);
|
||||
currentBoss.setHealth(hp);
|
||||
}
|
||||
|
||||
// BossBar
|
||||
if (bossBar != null) bossBar.removeAll();
|
||||
bossBar = Bukkit.createBossBar(bossName, BarColor.RED, BarStyle.SEGMENTED_10);
|
||||
for (UUID uuid : currentEvent.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null) bossBar.addPlayer(p);
|
||||
}
|
||||
bossBar.setVisible(true);
|
||||
|
||||
broadcast("§c⚠ §lBoss " + (bossIndex + 1) + "/" + BOSSES.length + ": " + bossName + " §c§l erscheint!");
|
||||
bossIndex++;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBossDeath(EntityDeathEvent e) {
|
||||
if (currentEvent == null || currentBoss == null) return;
|
||||
if (!e.getEntity().getUniqueId().equals(currentBoss.getUniqueId())) return;
|
||||
|
||||
Player killer = e.getEntity().getKiller();
|
||||
if (killer != null && currentEvent.isParticipant(killer)) {
|
||||
int bonus = bossIndex * 10;
|
||||
currentEvent.addScore(killer.getUniqueId(), bonus);
|
||||
broadcast("§a✔ §f" + killer.getName() + " §7hat den Boss bezwungen! §a+" + bonus + " §7Punkte");
|
||||
}
|
||||
|
||||
if (bossBar != null) bossBar.setVisible(false);
|
||||
broadcast("§c§l☠ Boss besiegt! §r§7Nächster Boss in 5 Sekunden...");
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(plugin, this::spawnNextBoss, 100L);
|
||||
}
|
||||
|
||||
private void broadcast(String msg) { Bukkit.broadcastMessage(msg); }
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* PvP Deathmatch:
|
||||
* - Kills = Punkte
|
||||
* - Tod → Respawn nach 3s mit vollen HP
|
||||
* - Am Ende: Spieler mit meisten Kills gewinnt
|
||||
*/
|
||||
public class DeathMatchHandler implements IEventHandler, Listener {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private final Map<UUID, Integer> killCount = new HashMap<>();
|
||||
|
||||
public DeathMatchHandler(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
killCount.clear();
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
broadcast("§c⚔ §ePvP ist aktiv! Kills = Punkte. Viel Erfolg!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
this.currentEvent = null;
|
||||
killCount.clear();
|
||||
|
||||
// Alle Teilnehmer: PvP-Effekte entfernen
|
||||
for (UUID uuid : event.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null) {
|
||||
for (PotionEffect eff : p.getActivePotionEffects())
|
||||
p.removePotionEffect(eff.getType());
|
||||
p.setHealth(Math.min(p.getMaxHealth(), 20));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDeath(PlayerDeathEvent e) {
|
||||
Player victim = e.getEntity();
|
||||
if (currentEvent == null || !currentEvent.isParticipant(victim)) return;
|
||||
|
||||
Player killer = victim.getKiller();
|
||||
if (killer != null && currentEvent.isParticipant(killer)) {
|
||||
// Kill → Punkt
|
||||
currentEvent.addScore(killer.getUniqueId(), 1);
|
||||
killCount.merge(killer.getUniqueId(), 1, Integer::sum);
|
||||
int kills = killCount.getOrDefault(killer.getUniqueId(), 0);
|
||||
killer.sendTitle("§c⚔ Kill!", "§7Kills: §e" + kills, 5, 30, 10);
|
||||
killer.playSound(killer.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1f, 1.5f);
|
||||
}
|
||||
|
||||
// Respawn nach 3 Sekunden
|
||||
Location respawn = victim.getWorld().getSpawnLocation();
|
||||
e.setDeathMessage(null);
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||
if (victim.isOnline()) {
|
||||
victim.spigot().respawn();
|
||||
victim.teleport(respawn);
|
||||
victim.setHealth(Math.min(victim.getMaxHealth(), 20));
|
||||
victim.sendMessage(plugin.prefix() + "§7Du bist respawnt — kämpfe weiter!");
|
||||
}
|
||||
}, 60L); // 3s
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerJoin(ActiveEvent event, Player player) {
|
||||
player.setHealth(Math.min(player.getMaxHealth(), 20));
|
||||
player.setFoodLevel(20);
|
||||
broadcast("§a+ §f" + player.getName() + " §7nimmt am Deathmatch teil!");
|
||||
}
|
||||
|
||||
private void broadcast(String msg) {
|
||||
Bukkit.broadcastMessage(plugin.prefix() + msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Drop Party:
|
||||
* - Items regnen alle 2s über allen Online-Spielern
|
||||
* - Item-Pool: Common/Rare/Epic-Loot
|
||||
* - Loot landet als Entity am Boden
|
||||
*/
|
||||
public class DropPartyHandler implements IEventHandler, Listener {
|
||||
|
||||
// Loot-Tabelle: Material, Menge, Gewichtung
|
||||
private static final Object[][] LOOT = {
|
||||
// Common (viel)
|
||||
{Material.BREAD, 8, 30},
|
||||
{Material.IRON_INGOT, 5, 25},
|
||||
{Material.COAL, 16, 20},
|
||||
{Material.ARROW, 32, 20},
|
||||
{Material.TORCH, 16, 20},
|
||||
// Uncommon
|
||||
{Material.GOLD_INGOT, 5, 10},
|
||||
{Material.EXPERIENCE_BOTTLE, 3, 10},
|
||||
{Material.GOLDEN_APPLE, 2, 8},
|
||||
// Rare
|
||||
{Material.DIAMOND, 3, 4},
|
||||
{Material.EMERALD, 2, 3},
|
||||
{Material.ENCHANTED_GOLDEN_APPLE, 1, 1},
|
||||
{Material.DIAMOND_SWORD, 1, 1},
|
||||
{Material.ELYTRA, 1, 1},
|
||||
};
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private BukkitRunnable dropper;
|
||||
private final Random rng = new Random();
|
||||
|
||||
public DropPartyHandler(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
broadcast("§6🎉 §eDropParty! §7Items regnen vom Himmel! Schnapp dir so viel du kannst!");
|
||||
|
||||
for (Player p : Bukkit.getOnlinePlayers())
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_FIREWORK_ROCKET_LARGE_BLAST, 1f, 1f);
|
||||
|
||||
dropper = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentEvent == null) { cancel(); return; }
|
||||
dropItems();
|
||||
}
|
||||
};
|
||||
dropper.runTaskTimer(plugin, 20L, 40L); // alle 2s
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
if (dropper != null) dropper.cancel();
|
||||
this.currentEvent = null;
|
||||
broadcast("§6🎉 §7Drop Party vorbei! Viel Spaß mit dem Loot!");
|
||||
}
|
||||
|
||||
private void dropItems() {
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
if (!p.isOnline()) continue;
|
||||
// 1-3 Items pro Spieler pro Drop
|
||||
int count = 1 + rng.nextInt(3);
|
||||
for (int i = 0; i < count; i++) {
|
||||
ItemStack item = rollLoot();
|
||||
Location dropLoc = p.getLocation().clone()
|
||||
.add((rng.nextDouble() - 0.5) * 8, 8, (rng.nextDouble() - 0.5) * 8);
|
||||
p.getWorld().dropItemNaturally(dropLoc, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack rollLoot() {
|
||||
int totalWeight = Arrays.stream(LOOT).mapToInt(e -> (int) e[2]).sum();
|
||||
int roll = rng.nextInt(totalWeight);
|
||||
int cumulative = 0;
|
||||
for (Object[] entry : LOOT) {
|
||||
cumulative += (int) entry[2];
|
||||
if (roll < cumulative) {
|
||||
return new ItemStack((Material) entry[0], (int) entry[1]);
|
||||
}
|
||||
}
|
||||
return new ItemStack(Material.BREAD);
|
||||
}
|
||||
|
||||
private void broadcast(String msg) { Bukkit.broadcastMessage(msg); }
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.EventType;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class EventHandlerRegistry {
|
||||
|
||||
private final Map<EventType, IEventHandler> handlers = new EnumMap<>(EventType.class);
|
||||
|
||||
public EventHandlerRegistry(EventEngine plugin) {
|
||||
registerAll(plugin);
|
||||
}
|
||||
|
||||
private void registerAll(EventEngine plugin) {
|
||||
|
||||
// ── KAMPF ──────────────────────────────────────────────────────────
|
||||
register(EventType.PVP_DEATHMATCH, new DeathMatchHandler(plugin));
|
||||
register(EventType.PVP_FREE_FOR_ALL, new DeathMatchHandler(plugin));
|
||||
register(EventType.PVP_LAST_MAN_STANDING, new LastManStandingHandler(plugin));
|
||||
register(EventType.PVP_SUMO, new SumoHandler(plugin));
|
||||
register(EventType.PVP_SPLEEF, new SpleefHandler(plugin));
|
||||
register(EventType.PVP_SNOWBALL_FIGHT, new SnowballFightHandler(plugin));
|
||||
register(EventType.PVP_ONE_VS_ONE, new OneVsOneHandler(plugin));
|
||||
register(EventType.PVP_TEAM_BATTLE, new TeamBattleHandler(plugin));
|
||||
register(EventType.PVP_BOW_ONLY, new BowOnlyHandler(plugin));
|
||||
register(EventType.PVP_SWORD_ONLY, new SwordOnlyHandler(plugin));
|
||||
register(EventType.PVP_FIST_FIGHT, new FistFightHandler(plugin));
|
||||
register(EventType.PVP_KIT_PVP, new KitPvPHandler(plugin));
|
||||
register(EventType.PVP_KING_OF_THE_HILL, new KingOfTheHillHandler(plugin));
|
||||
register(EventType.PVP_HUNGER_GAMES, new HungerGamesHandler(plugin));
|
||||
register(EventType.PVP_CAPTURE_THE_FLAG, new CaptureTheFlagHandler(plugin));
|
||||
register(EventType.PVP_BEDWARS_LITE, new BedWarsLiteHandler(plugin));
|
||||
register(EventType.PVP_SKYWARS_LITE, new SkyWarsLiteHandler(plugin));
|
||||
register(EventType.PVP_UHC, new UHCHandler(plugin));
|
||||
register(EventType.PVP_ELYTRA_PVP, new ElytraPvPHandler(plugin));
|
||||
register(EventType.PVP_ARENA_SURVIVAL, new ArenaSurvivalHandler(plugin));
|
||||
|
||||
// ── ÜBERLEBEN ──────────────────────────────────────────────────────
|
||||
register(EventType.SURVIVAL_MOB_WAVE, new MobWaveHandler(plugin));
|
||||
register(EventType.SURVIVAL_BOSS_RUSH, new BossRushHandler(plugin));
|
||||
register(EventType.SURVIVAL_LAVA_RISING, new LavaRisingHandler(plugin));
|
||||
register(EventType.SURVIVAL_ZOMBIE_SIEGE, new ZombieSiegeHandler(plugin));
|
||||
register(EventType.SURVIVAL_WITHER_STORM, new WitherStormHandler(plugin));
|
||||
register(EventType.SURVIVAL_DRAGON_FIGHT, new DragonFightHandler(plugin));
|
||||
register(EventType.SURVIVAL_HARDCORE_ROUND,new HardcoreRoundHandler(plugin));
|
||||
register(EventType.SURVIVAL_ISLAND, new IslandSurvivalHandler(plugin));
|
||||
register(EventType.SURVIVAL_NETHER_RUN, new NetherRunHandler(plugin));
|
||||
register(EventType.SURVIVAL_ENDURANCE, new EnduranceHandler(plugin));
|
||||
register(EventType.SURVIVAL_RAIDS_PLUS, new RaidsPlusHandler(plugin));
|
||||
register(EventType.SURVIVAL_MONSTER_HUNT, new MonsterHuntHandler(plugin));
|
||||
register(EventType.SURVIVAL_GRAVITY_SHIFT,new GravityShiftHandler(plugin));
|
||||
register(EventType.SURVIVAL_RANDOM_SPAWN, new RandomSpawnHandler(plugin));
|
||||
register(EventType.SURVIVAL_MANHUNT, new ManhuntHandler(plugin));
|
||||
|
||||
// ── BAUEN ──────────────────────────────────────────────────────────
|
||||
register(EventType.BUILD_BATTLE, new BuildBattleHandler(plugin));
|
||||
register(EventType.BUILD_SPEED_BUILD, new SpeedBuildHandler(plugin));
|
||||
register(EventType.BUILD_THEME_CHALLENGE, new ThemeChallengeHandler(plugin));
|
||||
register(EventType.BUILD_PIXEL_ART, new PixelArtHandler(plugin));
|
||||
register(EventType.BUILD_TALLEST_TOWER, new TallestTowerHandler(plugin));
|
||||
register(EventType.BUILD_BRIDGE, new BridgeBuildHandler(plugin));
|
||||
register(EventType.BUILD_REDSTONE, new RedstoneChallengeHandler(plugin));
|
||||
register(EventType.BUILD_UNDERGROUND, new UndergroundBuildHandler(plugin));
|
||||
register(EventType.BUILD_SKYBLOCK_STYLE, new SkyblockStyleHandler(plugin));
|
||||
register(EventType.BUILD_BLINDBUILD, new BlindBuildHandler(plugin));
|
||||
|
||||
// ── RENNEN ─────────────────────────────────────────────────────────
|
||||
register(EventType.RACE_PARKOUR, new ParkourRaceHandler(plugin));
|
||||
register(EventType.RACE_ELYTRA, new ElytraRaceHandler(plugin));
|
||||
register(EventType.RACE_BOAT, new BoatRaceHandler(plugin));
|
||||
register(EventType.RACE_HORSE, new HorseRaceHandler(plugin));
|
||||
register(EventType.RACE_PIG, new PigRaceHandler(plugin));
|
||||
register(EventType.RACE_MINECART, new MinecartRaceHandler(plugin));
|
||||
register(EventType.RACE_SWIMMING, new SwimmingRaceHandler(plugin));
|
||||
register(EventType.RACE_OBSTACLE, new ObstacleRaceHandler(plugin));
|
||||
register(EventType.RACE_MAZE, new MazeHandler(plugin));
|
||||
register(EventType.RACE_ICEBOAT, new IceBoatRaceHandler(plugin));
|
||||
|
||||
// ── SAMMELN ────────────────────────────────────────────────────────
|
||||
register(EventType.COLLECT_SCAVENGER_HUNT,new ScavengerHuntHandler(plugin));
|
||||
register(EventType.COLLECT_MINING_COMP, new MiningCompHandler(plugin));
|
||||
register(EventType.COLLECT_FISHING_COMP, new FishingCompHandler(plugin));
|
||||
register(EventType.COLLECT_FARMING_COMP, new FarmingCompHandler(plugin));
|
||||
register(EventType.COLLECT_MOB_DROPS, new MobDropsHandler(plugin));
|
||||
register(EventType.COLLECT_TREASURE_HUNT, new TreasureHuntHandler(plugin));
|
||||
register(EventType.COLLECT_EASTER_EGG, new EasterEggHandler(plugin));
|
||||
register(EventType.COLLECT_SPEED_MINE, new SpeedMineHandler(plugin));
|
||||
register(EventType.COLLECT_WOODCUTTING, new WoodcuttingHandler(plugin));
|
||||
register(EventType.COLLECT_ENCHANT_RACE, new EnchantRaceHandler(plugin));
|
||||
|
||||
// ── SPASS ──────────────────────────────────────────────────────────
|
||||
register(EventType.FUN_DROP_PARTY, new DropPartyHandler(plugin));
|
||||
register(EventType.FUN_TNT_RAIN, new TntRainHandler(plugin));
|
||||
register(EventType.FUN_ITEM_RAIN, new ItemRainHandler(plugin));
|
||||
register(EventType.FUN_RANDOM_EFFECTS, new RandomEffectsHandler(plugin));
|
||||
register(EventType.FUN_FIREWORK_SHOW, new FireworkShowHandler(plugin));
|
||||
register(EventType.FUN_LIGHTNING_STORM, new LightningStormHandler(plugin));
|
||||
register(EventType.FUN_SPEED_BOOST, new SpeedBoostHandler(plugin));
|
||||
register(EventType.FUN_CHAOS_MODE, new ChaosModeHandler(plugin));
|
||||
register(EventType.FUN_TINY_PLAYERS, new TinyPlayersHandler(plugin));
|
||||
register(EventType.FUN_GIANT_PLAYERS, new GiantPlayersHandler(plugin));
|
||||
register(EventType.FUN_INVISIBLE_PLAYERS, new InvisiblePlayersHandler(plugin));
|
||||
register(EventType.FUN_RANDOM_TELEPORT, new RandomTeleportHandler(plugin));
|
||||
register(EventType.FUN_SWAP_INVENTORIES, new SwapInventoriesHandler(plugin));
|
||||
register(EventType.FUN_REVERSE_GRAVITY, new ReverseGravityHandler(plugin));
|
||||
register(EventType.FUN_BOUNCY_BLOCKS, new BouncyBlocksHandler(plugin));
|
||||
|
||||
// ── QUIZ ───────────────────────────────────────────────────────────
|
||||
register(EventType.QUIZ_MINECRAFT_TRIVIA, new TriviaHandler(plugin));
|
||||
register(EventType.QUIZ_SPEED_QUIZ, new TriviaHandler(plugin));
|
||||
register(EventType.QUIZ_GENERAL_KNOWLEDGE,new GeneralKnowledgeQuizHandler(plugin));
|
||||
register(EventType.QUIZ_CRAFTING_CHALLENGE,new CraftingChallengeHandler(plugin));
|
||||
register(EventType.QUIZ_MOB_QUIZ, new MobQuizHandler(plugin));
|
||||
|
||||
// ── WIRTSCHAFT ─────────────────────────────────────────────────────
|
||||
register(EventType.ECONOMY_LOTTERY, new LotteryHandler(plugin));
|
||||
register(EventType.ECONOMY_AUCTION, new AuctionHandler(plugin));
|
||||
register(EventType.ECONOMY_MARKET_RUSH, new MarketRushHandler(plugin));
|
||||
register(EventType.ECONOMY_TRADE_FRENZY, new TradeFrenzyHandler(plugin));
|
||||
register(EventType.ECONOMY_BETTING, new BettingHandler(plugin));
|
||||
|
||||
// ── TEAM ───────────────────────────────────────────────────────────
|
||||
register(EventType.TEAM_RELAY_RACE, new TeamRelayRaceHandler(plugin));
|
||||
register(EventType.TEAM_BUILD_BATTLE, new TeamBuildBattleHandler(plugin));
|
||||
register(EventType.TEAM_SURVIVAL, new TeamSurvivalHandler(plugin));
|
||||
register(EventType.TEAM_TREASURE_HUNT, new TeamTreasureHuntHandler(plugin));
|
||||
register(EventType.TEAM_QUIZ, new TeamQuizHandler(plugin));
|
||||
register(EventType.TEAM_CAPTURE_POINTS, new CapturePointsHandler(plugin));
|
||||
register(EventType.TEAM_RESOURCE_RACE, new ResourceRaceHandler(plugin));
|
||||
register(EventType.TEAM_HIDE_AND_SEEK, new HideAndSeekHandler(plugin));
|
||||
register(EventType.TEAM_MURDER_MYSTERY, new MurderMysteryHandler(plugin));
|
||||
register(EventType.TEAM_COLOR_WAR, new ColorWarHandler(plugin));
|
||||
}
|
||||
|
||||
public void register(EventType type, IEventHandler handler) {
|
||||
handlers.put(type, handler);
|
||||
}
|
||||
|
||||
public Optional<IEventHandler> get(EventType type) {
|
||||
return Optional.ofNullable(handlers.get(type));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.inventory.meta.FireworkMeta;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Feuerwerk-Show: Feuerwerke steigen über allen Spielern auf
|
||||
*/
|
||||
public class FireworkShowHandler implements IEventHandler, Listener {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private BukkitRunnable show;
|
||||
private final Random rng = new Random();
|
||||
|
||||
private static final Color[] COLORS = {
|
||||
Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW,
|
||||
Color.PURPLE, Color.AQUA, Color.ORANGE, Color.WHITE,
|
||||
Color.FUCHSIA, Color.LIME
|
||||
};
|
||||
|
||||
public FireworkShowHandler(EventEngine plugin) { this.plugin = plugin; }
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
Bukkit.broadcastMessage(plugin.prefix() + "§e✨ §eFeuerwerk-Show! §7Lehnt euch zurück und genießt!");
|
||||
|
||||
show = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentEvent == null) { cancel(); return; }
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
spawnFirework(p.getLocation().add(
|
||||
(rng.nextDouble()-0.5)*10, 5, (rng.nextDouble()-0.5)*10));
|
||||
}
|
||||
}
|
||||
};
|
||||
show.runTaskTimer(plugin, 5L, 15L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
if (show != null) show.cancel();
|
||||
this.currentEvent = null;
|
||||
}
|
||||
|
||||
private void spawnFirework(Location loc) {
|
||||
Firework fw = loc.getWorld().spawn(loc, Firework.class);
|
||||
FireworkMeta meta = fw.getFireworkMeta();
|
||||
meta.setPower(1 + rng.nextInt(2));
|
||||
|
||||
FireworkEffect.Type[] types = FireworkEffect.Type.values();
|
||||
FireworkEffect effect = FireworkEffect.builder()
|
||||
.withColor(COLORS[rng.nextInt(COLORS.length)])
|
||||
.withFade(COLORS[rng.nextInt(COLORS.length)])
|
||||
.with(types[rng.nextInt(types.length)])
|
||||
.trail(rng.nextBoolean())
|
||||
.flicker(rng.nextBoolean())
|
||||
.build();
|
||||
|
||||
meta.addEffect(effect);
|
||||
fw.setFireworkMeta(meta);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// TNT-Regen Handler
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class TntRainHandler implements IEventHandler, Listener {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private BukkitRunnable rain;
|
||||
private final Random rng = new Random();
|
||||
|
||||
TntRainHandler(EventEngine plugin) { this.plugin = plugin; }
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
Bukkit.broadcastMessage(plugin.prefix() + "§c💣 §eTNT-Regen! §7Duck dich! (Spieler haben Blast Protection...)");
|
||||
|
||||
// Spielern Blast Protection geben (Rüstung)
|
||||
for (UUID uuid : event.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null) p.addPotionEffect(new PotionEffect(PotionEffectType.RESISTANCE, 99999, 1, false, false));
|
||||
}
|
||||
|
||||
rain = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentEvent == null) { cancel(); return; }
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
Location loc = p.getLocation().add(
|
||||
(rng.nextDouble() - 0.5) * 20, 15, (rng.nextDouble() - 0.5) * 20);
|
||||
TNTPrimed tnt = p.getWorld().spawn(loc, TNTPrimed.class);
|
||||
tnt.setFuseTicks(40);
|
||||
}
|
||||
}
|
||||
};
|
||||
rain.runTaskTimer(plugin, 20L, 30L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
if (rain != null) rain.cancel();
|
||||
for (UUID uuid : event.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null) p.removePotionEffect(PotionEffectType.RESISTANCE);
|
||||
}
|
||||
this.currentEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Item-Regen Handler
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class ItemRainHandler implements IEventHandler, Listener {
|
||||
|
||||
private static final Material[] ITEMS = {
|
||||
Material.DIAMOND, Material.GOLD_INGOT, Material.IRON_INGOT,
|
||||
Material.EMERALD, Material.COAL, Material.BREAD, Material.ARROW,
|
||||
Material.GOLDEN_APPLE, Material.EXPERIENCE_BOTTLE
|
||||
};
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private BukkitRunnable rain;
|
||||
private final Random rng = new Random();
|
||||
|
||||
ItemRainHandler(EventEngine plugin) { this.plugin = plugin; }
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
Bukkit.broadcastMessage(plugin.prefix() + "§d🌧 §eItem-Regen! §7Items fallen vom Himmel!");
|
||||
|
||||
rain = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentEvent == null) { cancel(); return; }
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
Material mat = ITEMS[rng.nextInt(ITEMS.length)];
|
||||
Location loc = p.getLocation().add(
|
||||
(rng.nextDouble() - 0.5) * 12, 12, (rng.nextDouble() - 0.5) * 12);
|
||||
p.getWorld().dropItemNaturally(loc, new ItemStack(mat, 1 + rng.nextInt(5)));
|
||||
}
|
||||
}
|
||||
};
|
||||
rain.runTaskTimer(plugin, 10L, 15L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
if (rain != null) rain.cancel();
|
||||
this.currentEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Blitz-Sturm Handler
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class LightningStormHandler implements IEventHandler, Listener {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private BukkitRunnable storm;
|
||||
private final Random rng = new Random();
|
||||
|
||||
LightningStormHandler(EventEngine plugin) { this.plugin = plugin; }
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
Bukkit.broadcastMessage(plugin.prefix() + "§e⚡ §eBlitz-Sturm! §7Es blitzt überall!");
|
||||
storm = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentEvent == null) { cancel(); return; }
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
Location loc = p.getLocation().add(
|
||||
(rng.nextDouble() - 0.5) * 16, 0, (rng.nextDouble() - 0.5) * 16);
|
||||
p.getWorld().strikeLightningEffect(loc);
|
||||
}
|
||||
}
|
||||
};
|
||||
storm.runTaskTimer(plugin, 10L, 20L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
if (storm != null) storm.cancel();
|
||||
this.currentEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Geschwindigkeits-Boost Handler
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class SpeedBoostHandler implements IEventHandler, Listener {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
|
||||
SpeedBoostHandler(EventEngine plugin) { this.plugin = plugin; }
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
Bukkit.broadcastMessage(plugin.prefix() + "§a💨 §eSpeed Boost! §7Alle Spieler sind für kurze Zeit superschnell!");
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, event.getDefinition().getDurationSeconds() * 20, 4, false, true));
|
||||
p.addPotionEffect(new PotionEffect(PotionEffectType.JUMP_BOOST, event.getDefinition().getDurationSeconds() * 20, 3, false, true));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
p.removePotionEffect(PotionEffectType.SPEED);
|
||||
p.removePotionEffect(PotionEffectType.JUMP_BOOST);
|
||||
}
|
||||
this.currentEvent = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Optionaler Handler für eingebaute Events mit echter Spiellogik.
|
||||
* Plugins können über EventHandlerRegistry eigene Handler registrieren.
|
||||
*/
|
||||
public interface IEventHandler {
|
||||
|
||||
/** Wird beim Start aufgerufen (nach Ankündigung, Sync Main-Thread) */
|
||||
void onStart(ActiveEvent event);
|
||||
|
||||
/** Wird beim Ende aufgerufen */
|
||||
void onEnd(ActiveEvent event);
|
||||
|
||||
/** Ein Spieler tritt bei */
|
||||
default void onPlayerJoin(ActiveEvent event, Player player) {}
|
||||
|
||||
/** Ein Spieler verlässt das Event */
|
||||
default void onPlayerLeave(ActiveEvent event, Player player) {}
|
||||
|
||||
/** Wird jede Sekunde aufgerufen (Tick) */
|
||||
default void onTick(ActiveEvent event) {}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Last Man Standing:
|
||||
* - Kein Respawn — einmal tot = draußen
|
||||
* - Letzter Überlebender gewinnt
|
||||
*/
|
||||
public class LastManStandingHandler implements IEventHandler, Listener {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private final Set<UUID> alive = new HashSet<>();
|
||||
|
||||
public LastManStandingHandler(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
alive.clear();
|
||||
alive.addAll(event.getParticipants());
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
broadcast("§c☠ §eLast Man Standing! §7Einmal tot = §craus§7.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
this.currentEvent = null;
|
||||
alive.clear();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDeath(PlayerDeathEvent e) {
|
||||
Player victim = e.getEntity();
|
||||
if (currentEvent == null || !currentEvent.isParticipant(victim)) return;
|
||||
|
||||
alive.remove(victim.getUniqueId());
|
||||
currentEvent.removeParticipant(victim);
|
||||
e.setDeathMessage(null);
|
||||
|
||||
int remaining = alive.size();
|
||||
broadcast("§c☠ §f" + victim.getName() + " §7ist ausgeschieden! §8[§e" + remaining + " §7übrig§8]");
|
||||
|
||||
victim.sendMessage(plugin.prefix() + "§cDu bist ausgeschieden! Schau dir das Finale an.");
|
||||
victim.setGameMode(org.bukkit.GameMode.SPECTATOR);
|
||||
|
||||
// Noch 1 übrig → Gewinner
|
||||
if (remaining == 1) {
|
||||
UUID winnerId = alive.iterator().next();
|
||||
Player winner = Bukkit.getPlayer(winnerId);
|
||||
String winName = winner != null ? winner.getName() : "Unbekannt";
|
||||
|
||||
currentEvent.addScore(winnerId, 100);
|
||||
broadcast("§6✦ §e" + winName + " §6ist der letzte Überlebende! §6GEWONNEN!");
|
||||
if (winner != null) {
|
||||
winner.playSound(winner.getLocation(), Sound.UI_TOAST_CHALLENGE_COMPLETE, 1f, 1f);
|
||||
winner.sendTitle("§6GEWONNEN!", "§7Last Man Standing!", 10, 60, 20);
|
||||
}
|
||||
plugin.getEventManager().endEvent(winName + " hat gewonnen");
|
||||
} else if (remaining == 0) {
|
||||
plugin.getEventManager().endEvent("Unentschieden");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerJoin(ActiveEvent event, Player player) {
|
||||
alive.add(player.getUniqueId());
|
||||
}
|
||||
|
||||
private void broadcast(String msg) { Bukkit.broadcastMessage(msg); }
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Steigendes Lava:
|
||||
* - Lava-Level steigt alle 10s um 1 Block
|
||||
* - Spieler müssen nach oben klettern
|
||||
* - Wer in der Lava landet = ausgeschieden (Tod)
|
||||
* - Höchster Überlebender gewinnt (Zeit überleben = Punkte)
|
||||
*/
|
||||
public class LavaRisingHandler implements IEventHandler, Listener {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private int lavaY = 30;
|
||||
private BukkitRunnable ticker;
|
||||
|
||||
public LavaRisingHandler(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
|
||||
// Startlevel aus Spieler-Y
|
||||
lavaY = getLowestPlayerY() - 5;
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
broadcast("§c🔥 §eDie Lava steigt! §7Klettere nach oben und überlebe so lange wie möglich!");
|
||||
|
||||
ticker = new BukkitRunnable() {
|
||||
int tick = 0;
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentEvent == null) { cancel(); return; }
|
||||
tick++;
|
||||
|
||||
// Punkte pro Sekunde für Überlebende
|
||||
for (UUID uuid : currentEvent.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null) currentEvent.addScore(uuid, 1);
|
||||
}
|
||||
|
||||
// Alle 10s: Lava steigt
|
||||
if (tick % 10 == 0) {
|
||||
lavaY++;
|
||||
// Warnung wenn Lava nah
|
||||
for (UUID uuid : currentEvent.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p == null) continue;
|
||||
double dist = p.getLocation().getY() - lavaY;
|
||||
if (dist < 5) {
|
||||
p.sendActionBar("§c🔥 LAVA §f" + (int)dist + " §cBlöcke unter dir!");
|
||||
p.playSound(p.getLocation(), Sound.BLOCK_LAVA_AMBIENT, 1f, 1.5f);
|
||||
}
|
||||
}
|
||||
if (tick % 30 == 0) broadcast("§c🔥 §7Lava-Level: §cY=" + lavaY);
|
||||
}
|
||||
|
||||
// Check: Spieler in/unter Lava
|
||||
for (UUID uuid : currentEvent.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null && p.getLocation().getY() <= lavaY) {
|
||||
p.setFireTicks(100);
|
||||
p.damage(4.0);
|
||||
p.sendActionBar("§c§l🔥 LAVA! Raus da!");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
ticker.runTaskTimer(plugin, 20L, 20L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
if (ticker != null) ticker.cancel();
|
||||
this.currentEvent = null;
|
||||
}
|
||||
|
||||
private int getLowestPlayerY() {
|
||||
int lowest = 64;
|
||||
if (currentEvent == null) return lowest;
|
||||
for (UUID uuid : currentEvent.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null) lowest = Math.min(lowest, p.getLocation().getBlockY());
|
||||
}
|
||||
return lowest;
|
||||
}
|
||||
|
||||
private void broadcast(String msg) { Bukkit.broadcastMessage(msg); }
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class LotteryHandler implements IEventHandler, Listener {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private final List<UUID> pool = new ArrayList<>();
|
||||
|
||||
public LotteryHandler(EventEngine plugin) { this.plugin = plugin; }
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
pool.clear();
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
Bukkit.broadcastMessage(plugin.prefix() + "§6🎟 §eLotterie! §7Nimm teil mit §f/event join §7um ein Los zu erhalten!");
|
||||
Bukkit.broadcastMessage(plugin.prefix() + "§7Am Ende wird ein §6Gewinner §7gezogen. Viel Glück!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
pool.addAll(event.getParticipants());
|
||||
|
||||
if (pool.isEmpty()) {
|
||||
Bukkit.broadcastMessage(plugin.prefix() + "§7Keine Teilnehmer — keine Lotterie.");
|
||||
this.currentEvent = null;
|
||||
return;
|
||||
}
|
||||
|
||||
UUID winnerId = pool.get(new Random().nextInt(pool.size()));
|
||||
Player winner = Bukkit.getPlayer(winnerId);
|
||||
String name = winner != null ? winner.getName() : "Offline-Spieler";
|
||||
|
||||
Bukkit.broadcastMessage("§8§m══════════════════════════════");
|
||||
Bukkit.broadcastMessage("§6 🎟 Lotterie-Ergebnis!");
|
||||
Bukkit.broadcastMessage("§7 Teilnehmer: §f" + new HashSet<>(pool).size());
|
||||
Bukkit.broadcastMessage("§6 🏆 GEWINNER: §e§l" + name + "§r §6🏆");
|
||||
Bukkit.broadcastMessage("§8§m══════════════════════════════");
|
||||
|
||||
if (winner != null) {
|
||||
winner.playSound(winner.getLocation(), Sound.UI_TOAST_CHALLENGE_COMPLETE, 1f, 1f);
|
||||
winner.sendTitle("§6GEWONNEN!", "§7Lotterie!", 10, 60, 20);
|
||||
for (String cmd : event.getDefinition().getRewards())
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("%player%", winner.getName()));
|
||||
}
|
||||
this.currentEvent = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerJoin(ActiveEvent event, Player player) {
|
||||
pool.add(player.getUniqueId());
|
||||
player.sendMessage(plugin.prefix() + "§a🎟 Los erhalten! §7Du bist im Pool. Viel Glück!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,441 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.player.PlayerFishEvent;
|
||||
import org.bukkit.event.player.PlayerHarvestBlockEvent;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
// ══════════════════════════════════════════════════════════
|
||||
// RENNEN — alle 10
|
||||
// ══════════════════════════════════════════════════════════
|
||||
|
||||
/** Basis für alle Renn-Events: Punkte pro Sekunde, wer am Ende mehr hat gewinnt */
|
||||
class BaseRaceHandler implements IEventHandler {
|
||||
protected final EventEngine plugin;
|
||||
protected final String icon;
|
||||
protected final String name;
|
||||
protected BukkitRunnable ticker;
|
||||
|
||||
BaseRaceHandler(EventEngine p, String icon, String name) { this.plugin=p; this.icon=icon; this.name=name; }
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
Bukkit.broadcastMessage(plugin.prefix()+icon+" §e"+name+"! §7Bereitet euch vor — die Strecke ist bereit!");
|
||||
ticker=new BukkitRunnable(){ @Override public void run(){ if(e.getState()==ActiveEvent.State.ENDED){cancel();return;} }};
|
||||
ticker.runTaskTimer(plugin,20L,20L);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){ if(ticker!=null)ticker.cancel(); }
|
||||
}
|
||||
|
||||
class ParkourRaceHandler extends BaseRaceHandler {
|
||||
ParkourRaceHandler(EventEngine p){super(p,"🏃","Parkour Race");}
|
||||
@Override public void onStart(ActiveEvent e){ super.onStart(e); Bukkit.broadcastMessage(plugin.prefix()+"§a🏃 §eParkour Race! §7Lauft durch den Kurs — wer zuerst am Ziel ist, gewinnt!"); }
|
||||
}
|
||||
class ElytraRaceHandler extends BaseRaceHandler {
|
||||
ElytraRaceHandler(EventEngine p){super(p,"🪂","Elytra-Rennen");}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
super.onStart(e);
|
||||
for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p==null)continue;p.getEquipment().setChestplate(new ItemStack(Material.ELYTRA));p.getInventory().addItem(new ItemStack(Material.FIREWORK_ROCKET,64));}
|
||||
Bukkit.broadcastMessage(plugin.prefix()+"§b🪂 §eElytra-Rennen! §7Fliegt mit Elytren zum Ziel!");
|
||||
}
|
||||
}
|
||||
class BoatRaceHandler extends BaseRaceHandler {
|
||||
BoatRaceHandler(EventEngine p){super(p,"⛵","Boot-Rennen");}
|
||||
@Override public void onStart(ActiveEvent e){ super.onStart(e); for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p==null)continue;p.getInventory().addItem(new ItemStack(Material.OAK_BOAT));} Bukkit.broadcastMessage(plugin.prefix()+"§b⛵ §eBoot-Rennen! §7Klettert in euer Boot und rast zum Ziel!"); }
|
||||
}
|
||||
class HorseRaceHandler extends BaseRaceHandler {
|
||||
HorseRaceHandler(EventEngine p){super(p,"🐎","Pferde-Rennen");}
|
||||
@Override public void onStart(ActiveEvent e){ super.onStart(e); Bukkit.broadcastMessage(plugin.prefix()+"§6🐎 §ePferde-Rennen! §7Besteigt eure Pferde — Zügel in die Hand und auf zum Start!"); }
|
||||
}
|
||||
class PigRaceHandler extends BaseRaceHandler {
|
||||
PigRaceHandler(EventEngine p){super(p,"🐷","Schweine-Rennen");}
|
||||
@Override public void onStart(ActiveEvent e){ super.onStart(e); for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p==null)continue;p.getInventory().addItem(new ItemStack(Material.CARROT_ON_A_STICK));} Bukkit.broadcastMessage(plugin.prefix()+"§e🐷 §eSchweine-Rennen! §7Schnappt euch eure Karotten-Angel und reitet eure Schweine!"); }
|
||||
}
|
||||
class MinecartRaceHandler extends BaseRaceHandler {
|
||||
MinecartRaceHandler(EventEngine p){super(p,"🚃","Lore-Rennen");}
|
||||
@Override public void onStart(ActiveEvent e){ super.onStart(e); Bukkit.broadcastMessage(plugin.prefix()+"§7🚃 §eLore-Rennen! §7Setzt euch in eure Lore und rast die Schienen entlang!"); }
|
||||
}
|
||||
class SwimmingRaceHandler extends BaseRaceHandler {
|
||||
SwimmingRaceHandler(EventEngine p){super(p,"🏊","Schwimm-Rennen");}
|
||||
@Override public void onStart(ActiveEvent e){ super.onStart(e); for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p==null)continue;p.addPotionEffect(new PotionEffect(PotionEffectType.DOLPHINS_GRACE,e.getDefinition().getDurationSeconds()*20,0));} Bukkit.broadcastMessage(plugin.prefix()+"§9🏊 §eSchwimm-Rennen! §7Los — durch den Kanal zum Ziel!"); }
|
||||
}
|
||||
class ObstacleRaceHandler extends BaseRaceHandler {
|
||||
ObstacleRaceHandler(EventEngine p){super(p,"🏅","Hindernislauf");}
|
||||
@Override public void onStart(ActiveEvent e){ super.onStart(e); Bukkit.broadcastMessage(plugin.prefix()+"§e🏅 §eHindernislauf! §7Überwindet alle Hindernisse und erreicht das Ziel!"); }
|
||||
}
|
||||
class MazeHandler extends BaseRaceHandler {
|
||||
MazeHandler(EventEngine p){super(p,"🌀","Labyrinth");}
|
||||
@Override public void onStart(ActiveEvent e){ super.onStart(e); Bukkit.broadcastMessage(plugin.prefix()+"§d🌀 §eLabyrinth! §7Findet den Weg durch das Labyrinth — wer zuerst herauskommt gewinnt!"); }
|
||||
}
|
||||
class IceBoatRaceHandler extends BaseRaceHandler {
|
||||
IceBoatRaceHandler(EventEngine p){super(p,"❄","Eisboot-Rennen");}
|
||||
@Override public void onStart(ActiveEvent e){ super.onStart(e); for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p==null)continue;p.getInventory().addItem(new ItemStack(Material.OAK_BOAT));} Bukkit.broadcastMessage(plugin.prefix()+"§b❄ §eEisboot-Rennen! §7Rast auf dem Eis — Boote auf Blaueis sind blitzschnell!"); }
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════
|
||||
// SAMMEL EVENTS — alle 10
|
||||
// ══════════════════════════════════════════════════════════
|
||||
|
||||
class ScavengerHuntHandler implements IEventHandler {
|
||||
private final EventEngine plugin;
|
||||
ScavengerHuntHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){ Bukkit.broadcastMessage(plugin.prefix()+"§6🔍 §eSchatzsuche! §7Findet alle versteckten Items in der Arena. Hinweise folgen im Chat!"); scheduleHints(e); }
|
||||
@Override public void onEnd(ActiveEvent e){}
|
||||
private void scheduleHints(ActiveEvent e){
|
||||
String[] hints={"§7Tipp 1: §fSchau in der Nähe von Bäumen!","§7Tipp 2: §fUnter der Erde könnte etwas versteckt sein...","§7Tipp 3: §fDas Wasser verbirgt Geheimnisse!"};
|
||||
for(int i=0;i<hints.length;i++){final String h=hints[i]; new BukkitRunnable(){@Override public void run(){if(e.getState()!=ActiveEvent.State.ENDED)Bukkit.broadcastMessage(plugin.prefix()+h);}}.runTaskLater(plugin,(i+1)*60L*20L);}
|
||||
}
|
||||
}
|
||||
|
||||
class MiningCompHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
private static final Map<Material,Integer> ORE_SCORES=new EnumMap<>(Material.class);
|
||||
static{ORE_SCORES.put(Material.COAL_ORE,1);ORE_SCORES.put(Material.DEEPSLATE_COAL_ORE,1);ORE_SCORES.put(Material.IRON_ORE,2);ORE_SCORES.put(Material.DEEPSLATE_IRON_ORE,2);ORE_SCORES.put(Material.GOLD_ORE,4);ORE_SCORES.put(Material.DEEPSLATE_GOLD_ORE,4);ORE_SCORES.put(Material.DIAMOND_ORE,10);ORE_SCORES.put(Material.DEEPSLATE_DIAMOND_ORE,10);ORE_SCORES.put(Material.EMERALD_ORE,8);ORE_SCORES.put(Material.ANCIENT_DEBRIS,20);}
|
||||
MiningCompHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){current=e;Bukkit.getPluginManager().registerEvents(this,plugin);Bukkit.broadcastMessage(plugin.prefix()+"§7⛏ §eMining-Wettbewerb! §7Baut so viele Erze wie möglich ab. Diamanten = 10 Punkte!");}
|
||||
@Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);current=null;}
|
||||
@EventHandler public void onBreak(BlockBreakEvent e){if(current==null||!current.isParticipant(e.getPlayer()))return;Integer pts=ORE_SCORES.get(e.getBlock().getType());if(pts!=null){current.addScore(e.getPlayer().getUniqueId(),pts);e.getPlayer().sendActionBar("§7+"+pts+" §7["+e.getBlock().getType().name()+"]");}}
|
||||
}
|
||||
|
||||
class FishingCompHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
FishingCompHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){current=e;Bukkit.getPluginManager().registerEvents(this,plugin);for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p==null)continue;p.getInventory().addItem(new ItemStack(Material.FISHING_ROD));}Bukkit.broadcastMessage(plugin.prefix()+"§9🎣 §eAngel-Wettbewerb! §7Angelt so viele Fische wie möglich. Schatz-Funde geben Bonuspunkte!");}
|
||||
@Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);current=null;}
|
||||
@EventHandler public void onFish(PlayerFishEvent e){
|
||||
if(current==null||!current.isParticipant(e.getPlayer()))return;
|
||||
if(e.getState()!=PlayerFishEvent.State.CAUGHT_FISH&&e.getState()!=PlayerFishEvent.State.CAUGHT_ENTITY)return;
|
||||
int pts=e.getState()==PlayerFishEvent.State.CAUGHT_ENTITY?5:2;
|
||||
current.addScore(e.getPlayer().getUniqueId(),pts);
|
||||
e.getPlayer().sendActionBar("§9+"+pts+" §7Angelpunkte!");
|
||||
}
|
||||
}
|
||||
|
||||
class FarmingCompHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
private static final Map<Material,Integer> CROP_SCORES=new EnumMap<>(Material.class);
|
||||
static{CROP_SCORES.put(Material.WHEAT,1);CROP_SCORES.put(Material.CARROT,1);CROP_SCORES.put(Material.POTATO,1);CROP_SCORES.put(Material.BEETROOT,1);CROP_SCORES.put(Material.MELON,2);CROP_SCORES.put(Material.PUMPKIN,2);CROP_SCORES.put(Material.SWEET_BERRIES,1);CROP_SCORES.put(Material.COCOA_BEANS,1);}
|
||||
FarmingCompHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){current=e;Bukkit.getPluginManager().registerEvents(this,plugin);Bukkit.broadcastMessage(plugin.prefix()+"§a🌾 §eFarm-Wettbewerb! §7Erntet so viele Crops wie möglich!");}
|
||||
@Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);current=null;}
|
||||
@EventHandler public void onHarvest(PlayerHarvestBlockEvent e){if(current==null||!current.isParticipant(e.getPlayer()))return;for(ItemStack item:e.getItemsHarvested()){Integer pts=CROP_SCORES.get(item.getType());if(pts!=null){current.addScore(e.getPlayer().getUniqueId(),pts*item.getAmount());e.getPlayer().sendActionBar("§a+"+pts+" §7pro Ernte");break;}}}
|
||||
}
|
||||
|
||||
class MobDropsHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
private static final Map<org.bukkit.entity.EntityType,Integer> MOB_SCORES=new EnumMap<>(org.bukkit.entity.EntityType.class);
|
||||
static{MOB_SCORES.put(org.bukkit.entity.EntityType.ZOMBIE,1);MOB_SCORES.put(org.bukkit.entity.EntityType.SKELETON,1);MOB_SCORES.put(org.bukkit.entity.EntityType.SPIDER,1);MOB_SCORES.put(org.bukkit.entity.EntityType.CREEPER,2);MOB_SCORES.put(org.bukkit.entity.EntityType.ENDERMAN,5);MOB_SCORES.put(org.bukkit.entity.EntityType.BLAZE,4);MOB_SCORES.put(org.bukkit.entity.EntityType.WITCH,3);MOB_SCORES.put(org.bukkit.entity.EntityType.WITHER_SKELETON,8);}
|
||||
MobDropsHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){current=e;Bukkit.getPluginManager().registerEvents(this,plugin);Bukkit.broadcastMessage(plugin.prefix()+"§c🗡 §eMob-Drops! §7Töte Mobs und sammle ihre Drops. Seltene Mobs = mehr Punkte!");}
|
||||
@Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);current=null;}
|
||||
@EventHandler public void onKill(EntityDeathEvent e){if(current==null)return;Player k=e.getEntity().getKiller();if(k==null||!current.isParticipant(k))return;Integer pts=MOB_SCORES.get(e.getEntityType());if(pts!=null){current.addScore(k.getUniqueId(),pts);k.sendActionBar("§c+"+pts+" §7Punkte");}}
|
||||
}
|
||||
|
||||
class TreasureHuntHandler implements IEventHandler {
|
||||
private final EventEngine plugin;
|
||||
TreasureHuntHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(plugin.prefix()+"§6💎 §eSchatz finden! §7Ein versteckter Schatz liegt irgendwo in der Arena. Findet ihn zuerst und gewinnt alles darin!");scheduleHints(e);}
|
||||
@Override public void onEnd(ActiveEvent e){}
|
||||
private void scheduleHints(ActiveEvent e){new BukkitRunnable(){@Override public void run(){if(e.getState()!=ActiveEvent.State.ENDED)Bukkit.broadcastMessage(plugin.prefix()+"§7💡 §eTipp: §fDer Schatz liegt in der Nähe von Wasser!");}}.runTaskLater(plugin,60*20L);}
|
||||
}
|
||||
|
||||
class EasterEggHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
EasterEggHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){current=e;Bukkit.getPluginManager().registerEvents(this,plugin);Bukkit.broadcastMessage(plugin.prefix()+"§d🥚 §eEier suchen! §7Findet alle versteckten Eier in der Arena. Wer die meisten hat, gewinnt!");}
|
||||
@Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);current=null;}
|
||||
}
|
||||
|
||||
class SpeedMineHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
SpeedMineHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
current=e;Bukkit.getPluginManager().registerEvents(this,plugin);
|
||||
for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p==null)continue;p.addPotionEffect(new PotionEffect(PotionEffectType.HASTE,e.getDefinition().getDurationSeconds()*20,1));}
|
||||
Bukkit.broadcastMessage(plugin.prefix()+"§7⛏ §eSpeed Mining! §7Baut so schnell wie möglich! Alle erhalten Eile II!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p!=null)p.removePotionEffect(PotionEffectType.HASTE);}current=null;}
|
||||
@EventHandler public void onBreak(BlockBreakEvent e){if(current==null||!current.isParticipant(e.getPlayer()))return;current.addScore(e.getPlayer().getUniqueId(),1);}
|
||||
}
|
||||
|
||||
class WoodcuttingHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
private static final Map<Material,Integer> WOOD_SCORES=new EnumMap<>(Material.class);
|
||||
static{WOOD_SCORES.put(Material.OAK_LOG,1);WOOD_SCORES.put(Material.BIRCH_LOG,1);WOOD_SCORES.put(Material.SPRUCE_LOG,1);WOOD_SCORES.put(Material.JUNGLE_LOG,2);WOOD_SCORES.put(Material.ACACIA_LOG,2);WOOD_SCORES.put(Material.DARK_OAK_LOG,3);WOOD_SCORES.put(Material.MANGROVE_LOG,2);WOOD_SCORES.put(Material.CHERRY_LOG,3);}
|
||||
WoodcuttingHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){current=e;Bukkit.getPluginManager().registerEvents(this,plugin);Bukkit.broadcastMessage(plugin.prefix()+"§2🪓 §eHolzfäll-Comp! §7Fällt so viele Bäume wie möglich. Dunkles Holz = mehr Punkte!");}
|
||||
@Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);current=null;}
|
||||
@EventHandler public void onBreak(BlockBreakEvent e){if(current==null||!current.isParticipant(e.getPlayer()))return;Integer pts=WOOD_SCORES.get(e.getBlock().getType());if(pts!=null){current.addScore(e.getPlayer().getUniqueId(),pts);}}
|
||||
}
|
||||
|
||||
class EnchantRaceHandler implements IEventHandler {
|
||||
private final EventEngine plugin;
|
||||
EnchantRaceHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(plugin.prefix()+"§5✨ §eVerzauberungsrennen! §7Sammelt Erfahrung und verzaubert euer Item zuerst auf Stufe 30! Wer zuerst fertig ist, gewinnt!");}
|
||||
@Override public void onEnd(ActiveEvent e){}
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════
|
||||
// BUILD EVENTS — alle 10
|
||||
// ══════════════════════════════════════════════════════════
|
||||
|
||||
class BuildBattleHandler implements IEventHandler {
|
||||
protected final EventEngine p; private final String theme;
|
||||
BuildBattleHandler(EventEngine p){this.p=p;this.theme=null;}
|
||||
BuildBattleHandler(EventEngine p,String theme){this.p=p;this.theme=theme;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
String t=theme!=null?theme:pickTheme();
|
||||
Bukkit.broadcastMessage(p.prefix()+"§a🏗 §eBuild Battle! §7Thema: §6§l"+t);
|
||||
Bukkit.broadcastMessage(p.prefix()+"§7Ihr habt §e"+e.getDefinition().getDurationSeconds()/60+" Minuten §7- Los geht's!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7✦ §eBauzeit vorbei! §7Alle Bauten werden jetzt bewertet.");}
|
||||
private String pickTheme(){String[]themes={"Burg","Unterwasserwelt","Vulkan","Raumstation","Verzauberte Waldlichtung","Drachen-Nest","Piratenschiff","Zukunftsstadt","Dschungeltempel","Eispalast"};return themes[new Random().nextInt(themes.length)];}
|
||||
}
|
||||
class SpeedBuildHandler extends BuildBattleHandler { SpeedBuildHandler(EventEngine p){super(p);} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§e⚡ §eSpeed Build! §7Nur 2 Minuten! Thema kommt gleich..."); super.onStart(e);} }
|
||||
class ThemeChallengeHandler extends BuildBattleHandler { ThemeChallengeHandler(EventEngine p){super(p);} }
|
||||
class PixelArtHandler implements IEventHandler { private final EventEngine p; PixelArtHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§d🎨 §ePixel Art Contest! §7Malt ein Pixel-Art-Bild auf dem flachen Boden. Motiv: §6Creeper-Gesicht");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Pinsel runter! Alle Bilder werden bewertet.");} }
|
||||
class TallestTowerHandler implements IEventHandler, Listener { private final EventEngine plugin; private ActiveEvent current; TallestTowerHandler(EventEngine p){this.plugin=p;} @Override public void onStart(ActiveEvent e){current=e;Bukkit.getPluginManager().registerEvents(this,plugin);Bukkit.broadcastMessage(plugin.prefix()+"§e🗼 §eHöchster Turm! §7Baut so hoch wie möglich! Am Ende wird die Höhe gemessen.");} @Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);if(current==null)return;int best=0;UUID winner=null;for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p==null)continue;int y=p.getLocation().getBlockY();if(y>best){best=y;winner=u;}}if(winner!=null){e.addScore(winner,100);Player wp=Bukkit.getPlayer(winner);Bukkit.broadcastMessage(plugin.prefix()+"§6✦ §7Höchster Punkt: §e"+(wp!=null?wp.getName():"?")+" §7bei Y=§e"+best);}current=null;} }
|
||||
class BridgeBuildHandler implements IEventHandler { private final EventEngine p; BridgeBuildHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7🌉 §eBrücke bauen! §7Baut eine Brücke von Punkt A zu Punkt B. Schnellste und schönste Brücke gewinnt!");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Bauzeit vorbei! §eDie Brücken werden jetzt bewertet.");} }
|
||||
class RedstoneChallengeHandler implements IEventHandler { private final EventEngine p; RedstoneChallengeHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§c⚡ §eRedstone Challenge! §7Aufgabe: §6Baut eine automatisch öffnende Tür mit Druckplatten!");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Zeit abgelaufen! §eSchaltkreise werden geprüft.");} }
|
||||
class UndergroundBuildHandler implements IEventHandler { private final EventEngine p; UndergroundBuildHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§8⛏ §eUnterirdisch bauen! §7Grabt euch ein und baut eure Anlage NUR unterhalb der Erde!");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Bauten werden begutachtet — die kreativste unterirdische Anlage gewinnt!");} }
|
||||
class SkyblockStyleHandler implements IEventHandler { private final EventEngine p; SkyblockStyleHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§e☁ §eSkyblock Style! §7Ihr startet auf eurer Insel — baut sie so weit wie möglich aus! Kreativste Insel am Ende gewinnt.");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Inselentwicklung vorbei — Bewertung beginnt!");} }
|
||||
class BlindBuildHandler implements IEventHandler, Listener { private final EventEngine plugin; private ActiveEvent current; BlindBuildHandler(EventEngine p){this.plugin=p;} @Override public void onStart(ActiveEvent e){current=e;Bukkit.getPluginManager().registerEvents(this,plugin);for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p==null)continue;p.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,e.getDefinition().getDurationSeconds()*20,0));}Bukkit.broadcastMessage(plugin.prefix()+"§8👁 §eBlind bauen! §7Ihr könnt kaum etwas sehen — baut das Thema: §6Haus");} @Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p!=null)p.removePotionEffect(PotionEffectType.BLINDNESS);}Bukkit.broadcastMessage(plugin.prefix()+"§7Blindheit weg! §eSchaut euch gegenseitig eure Werke an 😂");current=null;} }
|
||||
|
||||
// ══════════════════════════════════════════════════════════
|
||||
// QUIZ — 3 fehlende
|
||||
// ══════════════════════════════════════════════════════════
|
||||
|
||||
class GeneralKnowledgeQuizHandler extends TriviaHandler {
|
||||
private static final List<dev.viper.eventengine.events.builtin.TriviaHandler.QuestionEntry> GENERAL_QUESTIONS=List.of(
|
||||
new dev.viper.eventengine.events.builtin.TriviaHandler.QuestionEntry("Was ist die Hauptstadt von Deutschland?","Berlin",10),
|
||||
new dev.viper.eventengine.events.builtin.TriviaHandler.QuestionEntry("Wie viele Kontinente gibt es?","7",10),
|
||||
new dev.viper.eventengine.events.builtin.TriviaHandler.QuestionEntry("Welches ist das größte Land der Welt?","Russland",10),
|
||||
new dev.viper.eventengine.events.builtin.TriviaHandler.QuestionEntry("Wie viele Planeten hat unser Sonnensystem?","8",15),
|
||||
new dev.viper.eventengine.events.builtin.TriviaHandler.QuestionEntry("Was ist H2O?","Wasser",5)
|
||||
);
|
||||
GeneralKnowledgeQuizHandler(EventEngine p){super(p,GENERAL_QUESTIONS);}
|
||||
}
|
||||
|
||||
class CraftingChallengeHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
private static final String[][] CHALLENGES={
|
||||
{"Goldener Apfel","Crafting: 8 Goldbarren + 1 Apfel in der Mitte"},
|
||||
{"Verzauberungstisch","Crafting: Buch, Diamant x2, Obsidian x4"},
|
||||
{"Enderauge","Crafting: Enderpearl + Blaze Powder"},
|
||||
{"TNT","Crafting: 5x Sand + 4x Schwarzpulver (Schachbrett)"}
|
||||
};
|
||||
CraftingChallengeHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
current=e;Bukkit.getPluginManager().registerEvents(this,plugin);
|
||||
String[]challenge=CHALLENGES[new Random().nextInt(CHALLENGES.length)];
|
||||
Bukkit.broadcastMessage(plugin.prefix()+"§6🔨 §eCrafting-Challenge! §7Craftet als Erstes: §e"+challenge[0]);
|
||||
Bukkit.broadcastMessage(plugin.prefix()+"§7Tipp: §f"+challenge[1]);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);current=null;}
|
||||
}
|
||||
|
||||
class MobQuizHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
private final List<String[]> questions=Arrays.asList(
|
||||
new String[]{"Ich lebe im Nether, fliege und schieße Feuerbälle. Wer bin ich?","Ghast"},
|
||||
new String[]{"Ich bin grün, habe keine Arme und explodiere. Wer bin ich?","Creeper"},
|
||||
new String[]{"Ich bin sehr groß, lila und droppe Enderpearls. Wer bin ich?","Enderman"},
|
||||
new String[]{"Ich schwimme, lebe im Meer und bin der seltenste Boss. Wer bin ich?","Elder Guardian"},
|
||||
new String[]{"Ich werfe Tränke und trage immer einen Hut. Wer bin ich?","Witch"}
|
||||
);
|
||||
private int idx=0; private boolean answered=false;
|
||||
MobQuizHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
current=e;idx=0;answered=false;Bukkit.getPluginManager().registerEvents(this,plugin);
|
||||
Bukkit.broadcastMessage(plugin.prefix()+"§2🐾 §eMob-Quiz! §7Erkenne den Mob anhand der Beschreibung!");
|
||||
nextQuestion(e);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);current=null;}
|
||||
private void nextQuestion(ActiveEvent e){if(idx>=questions.size()){plugin.getEventManager().endEvent("Alle Fragen beantwortet");return;}answered=false;String[]q=questions.get(idx);Bukkit.broadcastMessage("§2❓ §f"+q[0]);}
|
||||
@EventHandler public void onChat(org.bukkit.event.player.AsyncPlayerChatEvent e){
|
||||
if(current==null||answered) return;
|
||||
Player p=e.getPlayer();if(!current.isParticipant(p))return;
|
||||
String[]q=questions.get(idx);
|
||||
if(e.getMessage().trim().equalsIgnoreCase(q[1])){answered=true;current.addScore(p.getUniqueId(),10);Bukkit.broadcastMessage("§a✔ §f"+p.getName()+" §7hat es gewusst! §a+10 Punkte");idx++;Bukkit.getScheduler().runTaskLater(plugin,()->nextQuestion(current),40L);}
|
||||
}
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════
|
||||
// ECONOMY — 4 fehlende
|
||||
// ══════════════════════════════════════════════════════════
|
||||
|
||||
class AuctionHandler implements IEventHandler { private final EventEngine p; AuctionHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§6🔨 §eAuktion! §7Ein Item wird gleich versteigert. Biete im Chat mit einem Betrag! Höchstes Gebot gewinnt!");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Auktion beendet! §eDer Gewinner erhält sein Item.");} }
|
||||
class MarketRushHandler implements IEventHandler { private final EventEngine p; MarketRushHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§e💹 §eMarkt-Rush! §7Für die nächsten §c"+e.getDefinition().getDurationSeconds()/60+" Minuten §7werden §6Eisenbarren §7zum 3-fachen Preis eingekauft! Sammelt so viel wie möglich!");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Markt-Rush vorbei! §7Der Sonderpreis ist nicht mehr aktiv.");} }
|
||||
class TradeFrenzyHandler implements IEventHandler { private final EventEngine p; TradeFrenzyHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§a🤝 §eHandels-Frenzy! §7Handelt so viel wie möglich mit anderen Spielern! Jeder abgeschlossene Handel gibt Bonus-Punkte.");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Handels-Zeit vorbei!");} }
|
||||
class BettingHandler implements IEventHandler { private final EventEngine p; BettingHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§6🎲 §eWetten-Event! §7Setzt auf den Gewinner des nächsten Events! Nutzt die Wetten-Befehle um mitzumachen.");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Wetten sind geschlossen — Gewinner wird ausgezahlt!");} }
|
||||
|
||||
// ══════════════════════════════════════════════════════════
|
||||
// TEAM EVENTS — alle 10
|
||||
// ══════════════════════════════════════════════════════════
|
||||
|
||||
class TeamRelayRaceHandler implements IEventHandler { private final EventEngine p; TeamRelayRaceHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§e🏅 §eStaffellauf! §7Teams treten im Staffelrennen an. Erst wenn Spieler A das Ziel erreicht, startet Spieler B!");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Staffellauf beendet — das schnellste Team gewinnt!");} }
|
||||
class TeamBuildBattleHandler implements IEventHandler { private final EventEngine p; TeamBuildBattleHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§a👥 §eTeam Build Battle! §7Baut gemeinsam im Team zum Thema: §6Verlassene Burg!");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Bauzeit vorbei — Teams werden bewertet!");} }
|
||||
class TeamSurvivalHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
TeamSurvivalHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){current=e;Bukkit.getPluginManager().registerEvents(this,plugin);Bukkit.broadcastMessage(plugin.prefix()+"§2👥 §eTeam Survival! §7Überlebt gemeinsam so lange wie möglich gegen Mobs und die Umwelt!");}
|
||||
@Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);current=null;}
|
||||
}
|
||||
class TeamTreasureHuntHandler implements IEventHandler { private final EventEngine p; TeamTreasureHuntHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§6👥 §eTeam Schatzsuche! §7Findet gemeinsam alle versteckten Truhen in der Arena. Das erste Team das alle findet, gewinnt!");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Schatzsuche beendet!");} }
|
||||
class TeamQuizHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
TeamQuizHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){current=e;Bukkit.getPluginManager().registerEvents(this,plugin);Bukkit.broadcastMessage(plugin.prefix()+"§e👥❓ §eTeam-Quiz! §7Teams beantworten Fragen — schnellste richtige Antwort gewinnt die Runde!");nextQuestion();}
|
||||
@Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);current=null;}
|
||||
private final String[][]questions={{"Was ist die härteste Materie?","Diamant"},{"Wie heißt der End-Boss?","Ender Dragon"},{"Was dropped ein Creeper?","Gunpowder"}};
|
||||
private int qi=0;
|
||||
private void nextQuestion(){if(qi>=questions.length){plugin.getEventManager().endEvent("Quiz beendet");return;}Bukkit.broadcastMessage("§e❓ §f"+questions[qi][0]);}
|
||||
@EventHandler public void onChat(org.bukkit.event.player.AsyncPlayerChatEvent e){if(current==null||qi>=questions.length)return;if(!current.isParticipant(e.getPlayer()))return;if(e.getMessage().trim().equalsIgnoreCase(questions[qi][1])){current.addScore(e.getPlayer().getUniqueId(),10);Bukkit.broadcastMessage("§a✔ §f"+e.getPlayer().getName()+"! §a+10");qi++;Bukkit.getScheduler().runTaskLater(plugin,this::nextQuestion,40L);}}
|
||||
}
|
||||
class CapturePointsHandler implements IEventHandler {
|
||||
private final EventEngine plugin; private BukkitRunnable ticker;
|
||||
CapturePointsHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
Bukkit.broadcastMessage(plugin.prefix()+"§e🚩 §ePunkte-Capture! §7Steht auf den markierten Punkten um Punkte zu sammeln. Mehr Spieler auf einem Punkt = schnellere Einnahme!");
|
||||
ticker=new BukkitRunnable(){ @Override public void run(){ if(e.getState()==ActiveEvent.State.ENDED){cancel();return;} /* Punkt-Check hier — benötigt vorbereitete Punkte-Positionen in den Settings */ for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p==null)continue;/* Placeholder: jeder Spieler auf einem Kontrollpunkt bekommt Punkte */} }};
|
||||
ticker.runTaskTimer(plugin,20L,20L);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){ if(ticker!=null)ticker.cancel(); }
|
||||
}
|
||||
class ResourceRaceHandler implements IEventHandler { private final EventEngine p; ResourceRaceHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7👥 §eRessourcen-Rennen! §7Sammelt gemeinsam: §e64x Eisen, 32x Gold, 16x Diamant §7— gebt alles in der Truhe ab!");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Ressourcen-Zeit vorbei — wer hat die Liste zuerst erfüllt?");} }
|
||||
class HideAndSeekHandler implements IEventHandler { private final EventEngine p; HideAndSeekHandler(EventEngine pp){this.p=pp;} @Override public void onStart(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§8👁 §eVerstecken! §7Ein Team versteckt sich — das andere sucht. §c30 Sekunden §7zum Verstecken — lauft!");} @Override public void onEnd(ActiveEvent e){Bukkit.broadcastMessage(p.prefix()+"§7Verstecken beendet! §eDie Sucher haben alle gefunden (oder nicht 😄)");} }
|
||||
class MurderMysteryHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current; private UUID murderer; private UUID detective;
|
||||
MurderMysteryHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
current=e;Bukkit.getPluginManager().registerEvents(this,plugin);
|
||||
List<UUID>parts=new ArrayList<>(e.getParticipants());Collections.shuffle(parts);
|
||||
if(parts.size()<3){Bukkit.broadcastMessage(plugin.prefix()+"§cMindestens 3 Spieler benötigt!");return;}
|
||||
murderer=parts.get(0);detective=parts.get(1);
|
||||
Player mp=Bukkit.getPlayer(murderer);Player dp=Bukkit.getPlayer(detective);
|
||||
if(mp!=null){mp.sendTitle("§c§lDU BIST DER MÖRDER!","§7Töte alle ohne entdeckt zu werden!",10,60,20);mp.getInventory().setItem(0,new ItemStack(Material.IRON_SWORD));}
|
||||
if(dp!=null){dp.sendTitle("§9§lDU BIST DER DETEKTIV!","§7Finde den Mörder und bringe ihn zur Strecke!",10,60,20);dp.getInventory().setItem(0,new ItemStack(Material.BOW));dp.getInventory().addItem(new ItemStack(Material.ARROW,1));}
|
||||
Bukkit.broadcastMessage(plugin.prefix()+"§8🔍 §eMurder Mystery! §7Der Mörder ist unter euch. Detektiv: finde ihn!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);current=null;murderer=null;detective=null;}
|
||||
@EventHandler public void onDeath(org.bukkit.event.entity.PlayerDeathEvent e){
|
||||
if(current==null||!current.isParticipant(e.getEntity()))return;
|
||||
e.setDeathMessage(null);
|
||||
if(e.getEntity().getUniqueId().equals(murderer)){Bukkit.broadcastMessage(plugin.prefix()+"§a✔ §7Der Mörder wurde gefangen! §9Detektiv und Unschuldige §7gewinnen!");if(detective!=null){current.addScore(detective,100);}plugin.getEventManager().endEvent("Mörder gefangen");}
|
||||
else if(e.getEntity().getUniqueId().equals(detective)){Bukkit.broadcastMessage(plugin.prefix()+"§c§lDer Detektiv ist tot! §r§7Der Mörder macht weiter...");e.getEntity().setGameMode(GameMode.SPECTATOR);}
|
||||
else{e.getEntity().setGameMode(GameMode.SPECTATOR);Bukkit.broadcastMessage("§7"+e.getEntity().getName()+" §7wurde ermordet...");}
|
||||
}
|
||||
}
|
||||
class ColorWarHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current; private final Map<UUID,Material> teamColors=new HashMap<>();
|
||||
ColorWarHandler(EventEngine p){this.plugin=p;}
|
||||
private static final Material[]COLORS={Material.RED_WOOL,Material.BLUE_WOOL,Material.GREEN_WOOL,Material.YELLOW_WOOL};
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
current=e;Bukkit.getPluginManager().registerEvents(this,plugin);
|
||||
List<UUID>parts=new ArrayList<>(e.getParticipants());
|
||||
for(int i=0;i<parts.size();i++){Material col=COLORS[i%COLORS.length];teamColors.put(parts.get(i),col);Player p=Bukkit.getPlayer(parts.get(i));if(p!=null){p.getInventory().addItem(new ItemStack(col,64));p.sendMessage(plugin.prefix()+"§7Deine Farbe: §f"+col.name());}}
|
||||
Bukkit.broadcastMessage(plugin.prefix()+"§e🎨 §eFarben-Krieg! §7Bedeckt so viel Fläche wie möglich mit eurer Teamfarbe!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){
|
||||
HandlerList.unregisterAll(this);
|
||||
// Zähle Blöcke pro Farbe in der Region
|
||||
if(e.getDefinition().hasRegion()){
|
||||
org.bukkit.World w=e.getDefinition().getRegion().getWorld();
|
||||
if(w!=null){Map<Material,Integer>counts=new EnumMap<>(Material.class);dev.viper.eventengine.model.EventRegion r=e.getDefinition().getRegion();for(int x=r.getMinX();x<=r.getMaxX();x++)for(int z=r.getMinZ();z<=r.getMaxZ();z++){Material t=w.getBlockAt(x,r.getMinY(),z).getType();if(Arrays.asList(COLORS).contains(t))counts.merge(t,1,Integer::sum);}Bukkit.broadcastMessage(plugin.prefix()+"§e🎨 §7Farben-Ergebnis:");counts.forEach((m,cnt)->Bukkit.broadcastMessage(" §7"+m.name()+": §e"+cnt+" §7Blöcke"));}
|
||||
}
|
||||
current=null;teamColors.clear();
|
||||
}
|
||||
// Damit ist der Import nötig
|
||||
private static final Material[] COLORS_REF = COLORS;
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════
|
||||
// FUN EVENTS — 7 fehlende
|
||||
// ══════════════════════════════════════════════════════════
|
||||
|
||||
class TinyPlayersHandler implements IEventHandler {
|
||||
private final EventEngine p;
|
||||
TinyPlayersHandler(EventEngine pp){this.p=pp;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
for(UUID u:e.getParticipants()){Player pl=Bukkit.getPlayer(u);if(pl==null)continue;pl.addPotionEffect(new PotionEffect(PotionEffectType.SLOWNESS,e.getDefinition().getDurationSeconds()*20,0,false,false));pl.addPotionEffect(new PotionEffect(PotionEffectType.JUMP_BOOST,e.getDefinition().getDurationSeconds()*20,2,false,false));}
|
||||
Bukkit.broadcastMessage(p.prefix()+"§e🐭 §eMini-Spieler! §7Alle sind jetzt winzig klein!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){for(UUID u:e.getParticipants()){Player pl=Bukkit.getPlayer(u);if(pl!=null){pl.removePotionEffect(PotionEffectType.SLOWNESS);pl.removePotionEffect(PotionEffectType.JUMP_BOOST);}}}
|
||||
}
|
||||
class GiantPlayersHandler implements IEventHandler {
|
||||
private final EventEngine p;
|
||||
GiantPlayersHandler(EventEngine pp){this.p=pp;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
for(UUID u:e.getParticipants()){Player pl=Bukkit.getPlayer(u);if(pl==null)continue;pl.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,e.getDefinition().getDurationSeconds()*20,1,false,false));pl.addPotionEffect(new PotionEffect(PotionEffectType.STRENGTH,e.getDefinition().getDurationSeconds()*20,1,false,false));}
|
||||
Bukkit.broadcastMessage(p.prefix()+"§6🦣 §eRiesen-Spieler! §7Alle sind jetzt riesig! Stärke und Geschwindigkeit erhöht!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){for(UUID u:e.getParticipants()){Player pl=Bukkit.getPlayer(u);if(pl!=null){pl.removePotionEffect(PotionEffectType.SPEED);pl.removePotionEffect(PotionEffectType.STRENGTH);}}}
|
||||
}
|
||||
class InvisiblePlayersHandler implements IEventHandler {
|
||||
private final EventEngine p;
|
||||
InvisiblePlayersHandler(EventEngine pp){this.p=pp;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
for(UUID u:e.getParticipants()){Player pl=Bukkit.getPlayer(u);if(pl==null)continue;pl.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY,e.getDefinition().getDurationSeconds()*20,0,false,false));}
|
||||
Bukkit.broadcastMessage(p.prefix()+"§7👻 §eUnsichtbarkeit! §7Alle Spieler sind unsichtbar!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){for(UUID u:e.getParticipants()){Player pl=Bukkit.getPlayer(u);if(pl!=null)pl.removePotionEffect(PotionEffectType.INVISIBILITY);}}
|
||||
}
|
||||
class RandomTeleportHandler implements IEventHandler {
|
||||
private final EventEngine plugin; private BukkitRunnable tpRunner;
|
||||
RandomTeleportHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
Bukkit.broadcastMessage(plugin.prefix()+"§d🌀 §eZufalls-TP! §7Alle 5 Sekunden wird jemand teleportiert!");
|
||||
final Random rng=new Random();
|
||||
tpRunner=new BukkitRunnable(){@Override public void run(){if(e.getState()==ActiveEvent.State.ENDED){cancel();return;} for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p==null||rng.nextInt(3)!=0)continue;Location loc=e.getDefinition().hasRegion()?e.getDefinition().getRegion().randomLocation(rng):p.getLocation().add((rng.nextDouble()-0.5)*30,0,(rng.nextDouble()-0.5)*30);if(loc!=null)p.teleport(loc);p.sendActionBar("§d⚡ ZUFALLS-TP!");}}};
|
||||
tpRunner.runTaskTimer(plugin,20L,100L);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){ if(tpRunner!=null)tpRunner.cancel(); }
|
||||
}
|
||||
class SwapInventoriesHandler implements IEventHandler {
|
||||
private final EventEngine p;
|
||||
SwapInventoriesHandler(EventEngine pp){this.p=pp;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
List<UUID>parts=new ArrayList<>(e.getParticipants());
|
||||
if(parts.size()<2){Bukkit.broadcastMessage(p.prefix()+"§cMindestens 2 Spieler benötigt!");return;}
|
||||
Collections.shuffle(parts);
|
||||
List<ItemStack[]>inventories=new ArrayList<>();
|
||||
for(UUID u:parts){Player pl=Bukkit.getPlayer(u);inventories.add(pl!=null?pl.getInventory().getContents().clone():new ItemStack[41]);}
|
||||
for(int i=0;i<parts.size();i++){Player pl=Bukkit.getPlayer(parts.get(i));if(pl!=null)pl.getInventory().setContents(inventories.get((i+1)%parts.size()));}
|
||||
Bukkit.broadcastMessage(p.prefix()+"§e🔄 §eInventar-Tausch! §7Alle Inventare wurden zufällig getauscht!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){}
|
||||
}
|
||||
class ReverseGravityHandler implements IEventHandler {
|
||||
private final EventEngine plugin; private BukkitRunnable ticker;
|
||||
ReverseGravityHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
Bukkit.broadcastMessage(plugin.prefix()+"§9⬆ §eUmgekehrte Schwerkraft! §7Alle werden hochgezogen!");
|
||||
final Random rng=new Random();
|
||||
ticker=new BukkitRunnable(){@Override public void run(){if(e.getState()==ActiveEvent.State.ENDED){cancel();return;}for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p==null)continue;p.setVelocity(p.getVelocity().setY(0.5+rng.nextDouble()*0.5));}}};
|
||||
ticker.runTaskTimer(plugin,20L,15L);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){ if(ticker!=null)ticker.cancel(); }
|
||||
}
|
||||
class BouncyBlocksHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
BouncyBlocksHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){current=e;Bukkit.getPluginManager().registerEvents(this,plugin);Bukkit.broadcastMessage(plugin.prefix()+"§a🤸 §eHüpfende Blöcke! §7Bestimmte Blöcke katapultieren euch in die Luft wenn ihr draufsteht!");}
|
||||
@Override public void onEnd(ActiveEvent e){HandlerList.unregisterAll(this);current=null;}
|
||||
@EventHandler public void onMove(org.bukkit.event.player.PlayerMoveEvent e){
|
||||
if(current==null||!current.isParticipant(e.getPlayer()))return;
|
||||
Material below=e.getPlayer().getLocation().subtract(0,1,0).getBlock().getType();
|
||||
if(below==Material.SLIME_BLOCK||below==Material.HONEY_BLOCK){e.getPlayer().setVelocity(e.getPlayer().getVelocity().setY(1.5));e.getPlayer().sendActionBar("§a🤸 BOING!");}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Mob-Wellen:
|
||||
* - Alle 30s eine neue Welle mit mehr/stärkeren Mobs
|
||||
* - Kills = Punkte
|
||||
* - Nach 10 Wellen oder Ende: Gewinner mit meisten Kills
|
||||
*/
|
||||
public class MobWaveHandler implements IEventHandler, Listener {
|
||||
|
||||
private static final int MAX_WAVES = 10;
|
||||
private static final int WAVE_INTERVAL_SEC = 30;
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private int currentWave = 0;
|
||||
private BukkitRunnable waveRunner;
|
||||
|
||||
public MobWaveHandler(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
this.currentWave = 0;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
|
||||
broadcast("§c🌊 §eMob-Wellen! §7Überlebe alle " + MAX_WAVES + " Wellen! Kills = Punkte.");
|
||||
|
||||
waveRunner = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentEvent == null) { cancel(); return; }
|
||||
currentWave++;
|
||||
if (currentWave > MAX_WAVES) {
|
||||
cancel();
|
||||
plugin.getEventManager().endEvent("Alle Wellen überstanden!");
|
||||
return;
|
||||
}
|
||||
spawnWave(currentWave);
|
||||
}
|
||||
};
|
||||
waveRunner.runTaskTimer(plugin, 60L, WAVE_INTERVAL_SEC * 20L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
if (waveRunner != null) waveRunner.cancel();
|
||||
this.currentEvent = null;
|
||||
}
|
||||
|
||||
private void spawnWave(int wave) {
|
||||
broadcast("§c🌊 §eWelle §c" + wave + "§e/" + MAX_WAVES + " §7startet!");
|
||||
|
||||
// Spawn-Punkt = erster Teilnehmer oder Welt-Spawn
|
||||
Location spawnLoc = null;
|
||||
for (UUID uuid : currentEvent.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null) { spawnLoc = p.getLocation(); break; }
|
||||
}
|
||||
if (spawnLoc == null) return;
|
||||
|
||||
World world = spawnLoc.getWorld();
|
||||
int mobCount = 3 + (wave * 2);
|
||||
|
||||
for (int i = 0; i < mobCount; i++) {
|
||||
// Zufälliger Offset
|
||||
double offsetX = (Math.random() - 0.5) * 20;
|
||||
double offsetZ = (Math.random() - 0.5) * 20;
|
||||
Location loc = spawnLoc.clone().add(offsetX, 0, offsetZ);
|
||||
|
||||
EntityType type = getMobForWave(wave);
|
||||
try {
|
||||
Entity mob = world.spawnEntity(loc, type);
|
||||
// HP skalieren
|
||||
if (mob instanceof LivingEntity le) {
|
||||
double baseHp = 20 + (wave * 4);
|
||||
if (le.getAttribute(Attribute.MAX_HEALTH) != null) {
|
||||
le.getAttribute(Attribute.MAX_HEALTH).setBaseValue(baseHp);
|
||||
le.setHealth(baseHp);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
// Boss ab Welle 5
|
||||
if (wave == 5) spawnBoss(spawnLoc, "Mini-Boss der Welle 5", EntityType.ELDER_GUARDIAN);
|
||||
if (wave == 10) spawnBoss(spawnLoc, "§c⚠ ENDGEGNER", EntityType.WITHER_SKELETON);
|
||||
}
|
||||
|
||||
private EntityType getMobForWave(int wave) {
|
||||
EntityType[] early = {EntityType.ZOMBIE, EntityType.SKELETON, EntityType.SPIDER};
|
||||
EntityType[] mid = {EntityType.CREEPER, EntityType.WITCH, EntityType.HUSK};
|
||||
EntityType[] late = {EntityType.VINDICATOR, EntityType.RAVAGER, EntityType.PIGLIN_BRUTE};
|
||||
|
||||
if (wave <= 3) return early[(int)(Math.random() * early.length)];
|
||||
if (wave <= 6) return mid[(int)(Math.random() * mid.length)];
|
||||
return late[(int)(Math.random() * late.length)];
|
||||
}
|
||||
|
||||
private void spawnBoss(Location loc, String name, EntityType type) {
|
||||
try {
|
||||
Entity boss = loc.getWorld().spawnEntity(loc, type);
|
||||
if (boss instanceof LivingEntity le) {
|
||||
le.setCustomName("§c§l" + name);
|
||||
le.setCustomNameVisible(true);
|
||||
if (le.getAttribute(Attribute.MAX_HEALTH) != null) {
|
||||
le.getAttribute(Attribute.MAX_HEALTH).setBaseValue(200);
|
||||
le.setHealth(200);
|
||||
}
|
||||
}
|
||||
broadcast("§c⚠ §l" + name + " §c§ltaucht auf!");
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onMobDeath(EntityDeathEvent e) {
|
||||
if (currentEvent == null) return;
|
||||
Player killer = e.getEntity().getKiller();
|
||||
if (killer == null || !currentEvent.isParticipant(killer)) return;
|
||||
|
||||
int points = getMobPoints(e.getEntityType());
|
||||
currentEvent.addScore(killer.getUniqueId(), points);
|
||||
killer.sendActionBar("§c+" + points + " §7Punkte (Welle §e" + currentWave + "§7)");
|
||||
}
|
||||
|
||||
private int getMobPoints(EntityType type) {
|
||||
return switch (type) {
|
||||
case ZOMBIE, SKELETON, SPIDER -> 1;
|
||||
case CREEPER, WITCH, HUSK -> 2;
|
||||
case VINDICATOR, RAVAGER -> 5;
|
||||
case ELDER_GUARDIAN, WITHER_SKELETON, PIGLIN_BRUTE -> 10;
|
||||
default -> 1;
|
||||
};
|
||||
}
|
||||
|
||||
private void broadcast(String msg) { Bukkit.broadcastMessage(msg); }
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Zufalls-Effekte: Alle 15s bekommt jeder Spieler einen zufälligen Potion-Effekt
|
||||
*/
|
||||
class RandomEffectsHandler implements IEventHandler, Listener {
|
||||
|
||||
private static final List<PotionEffectType> EFFECTS = List.of(
|
||||
PotionEffectType.SPEED, PotionEffectType.SLOWNESS, PotionEffectType.JUMP_BOOST,
|
||||
PotionEffectType.STRENGTH, PotionEffectType.WEAKNESS, PotionEffectType.BLINDNESS,
|
||||
PotionEffectType.NIGHT_VISION, PotionEffectType.INVISIBILITY, PotionEffectType.NAUSEA,
|
||||
PotionEffectType.REGENERATION, PotionEffectType.FIRE_RESISTANCE, PotionEffectType.POISON
|
||||
);
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private BukkitRunnable roller;
|
||||
private final Random rng = new Random();
|
||||
|
||||
RandomEffectsHandler(EventEngine plugin) { this.plugin = plugin; }
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
Bukkit.broadcastMessage(plugin.prefix() + "§5🎲 §eZufalls-Effekte! §7Alle 15s ein neuer zufälliger Trank-Effekt!");
|
||||
|
||||
roller = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentEvent == null) { cancel(); return; }
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
PotionEffectType type = EFFECTS.get(rng.nextInt(EFFECTS.size()));
|
||||
int amp = rng.nextInt(3); // 0-2
|
||||
p.addPotionEffect(new PotionEffect(type, 300, amp, false, true));
|
||||
p.sendActionBar("§5🎲 Effekt: §f" + formatEffect(type) + " §7(Stufe " + (amp + 1) + ")");
|
||||
}
|
||||
}
|
||||
};
|
||||
roller.runTaskTimer(plugin, 20L, 300L); // 15s
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
if (roller != null) roller.cancel();
|
||||
for (Player p : Bukkit.getOnlinePlayers())
|
||||
EFFECTS.forEach(p::removePotionEffect);
|
||||
this.currentEvent = null;
|
||||
}
|
||||
|
||||
private String formatEffect(PotionEffectType type) {
|
||||
return type.getName().replace("_", " ").toLowerCase()
|
||||
.substring(0, 1).toUpperCase() + type.getName().replace("_", " ").toLowerCase().substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Chaos-Modus: Verschiedene verrückte Effekte gleichzeitig
|
||||
*/
|
||||
class ChaosModeHandler implements IEventHandler, Listener {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private BukkitRunnable chaos;
|
||||
private final Random rng = new Random();
|
||||
|
||||
ChaosModeHandler(EventEngine plugin) { this.plugin = plugin; }
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
Bukkit.broadcastMessage(plugin.prefix() + "§c§l⚡ CHAOS MODUS! §r§7Alles ist möglich!");
|
||||
|
||||
chaos = new BukkitRunnable() {
|
||||
int tick = 0;
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentEvent == null) { cancel(); return; }
|
||||
tick++;
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
int action = rng.nextInt(6);
|
||||
switch (action) {
|
||||
case 0 -> { // Random Teleport in der Nähe
|
||||
var loc = p.getLocation().add(
|
||||
(rng.nextDouble()-0.5)*30, 0, (rng.nextDouble()-0.5)*30);
|
||||
p.teleport(loc);
|
||||
p.sendActionBar("§c⚡ TELEPORT!");
|
||||
}
|
||||
case 1 -> { // Zufällige Geschwindigkeit
|
||||
p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,
|
||||
100, rng.nextInt(5), false, false));
|
||||
}
|
||||
case 2 -> { // Feuern
|
||||
if (rng.nextBoolean()) p.setFireTicks(40);
|
||||
}
|
||||
case 3 -> { // In die Luft schleudern
|
||||
p.setVelocity(p.getVelocity().setY(1.5 + rng.nextDouble()));
|
||||
p.sendActionBar("§6⬆ YEET!");
|
||||
}
|
||||
case 4 -> { // Unsichtbar machen
|
||||
p.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY,
|
||||
100, 0, false, false));
|
||||
}
|
||||
case 5 -> { /* Nichts */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
chaos.runTaskTimer(plugin, 20L, 40L); // alle 2s
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
if (chaos != null) chaos.cancel();
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
p.setFireTicks(0);
|
||||
p.removePotionEffect(PotionEffectType.SPEED);
|
||||
p.removePotionEffect(PotionEffectType.INVISIBILITY);
|
||||
}
|
||||
this.currentEvent = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,471 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// 1v1 Turnier — genau 2 Spieler, wer zuerst stirbt verliert
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class OneVsOneHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent current;
|
||||
OneVsOneHandler(EventEngine p) { this.plugin = p; }
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
current = e;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
broadcast("§61v1 §e– zwei Spieler, ein Gewinner. Kein Respawn!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e) { HandlerList.unregisterAll(this); current = null; }
|
||||
private void broadcast(String m) { Bukkit.broadcastMessage(m); }
|
||||
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e) {
|
||||
if (current == null || !current.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null);
|
||||
Player loser = e.getEntity();
|
||||
current.removeParticipant(loser);
|
||||
loser.setGameMode(GameMode.SPECTATOR);
|
||||
// Übriggebliebener = Gewinner
|
||||
current.getParticipants().stream().findFirst().ifPresent(uuid -> {
|
||||
current.addScore(uuid, 100);
|
||||
Player w = Bukkit.getPlayer(uuid);
|
||||
if (w != null) { w.sendTitle("§6GEWONNEN!", "§71v1 Champion!", 10,60,20); }
|
||||
});
|
||||
plugin.getEventManager().endEvent(loser.getName() + " wurde besiegt");
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Nur Bogen — Kills mit Bogen = Punkte, Nahkampfschaden = 0
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class BowOnlyHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent current;
|
||||
BowOnlyHandler(EventEngine p) { this.plugin = p; }
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
current = e;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
for (UUID uuid : e.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid); if (p == null) continue;
|
||||
p.getInventory().clear();
|
||||
p.getInventory().setItem(0, enchant(new ItemStack(Material.BOW), Enchantment.INFINITY, 1));
|
||||
p.getInventory().setItem(9, new ItemStack(Material.ARROW, 1));
|
||||
p.setHealth(Math.min(p.getMaxHealth(),20));
|
||||
}
|
||||
broadcast("§9🏹 §eNur Bogen! §7Nahkampf macht keinen Schaden.");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e) { HandlerList.unregisterAll(this); current = null; }
|
||||
private void broadcast(String m) { Bukkit.broadcastMessage(m); }
|
||||
|
||||
@EventHandler public void onDamage(EntityDamageByEntityEvent e) {
|
||||
if (current == null || !(e.getEntity() instanceof Player victim)) return;
|
||||
if (!current.isParticipant(victim)) return;
|
||||
if (e.getCause() != org.bukkit.event.entity.EntityDamageEvent.DamageCause.PROJECTILE)
|
||||
e.setDamage(0);
|
||||
}
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e) {
|
||||
if (current == null || !current.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null);
|
||||
Player killer = e.getEntity().getKiller();
|
||||
if (killer != null && current.isParticipant(killer)) current.addScore(killer.getUniqueId(),1);
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> { if(e.getEntity().isOnline()){ e.getEntity().spigot().respawn(); resetKit(e.getEntity()); }}, 60L);
|
||||
}
|
||||
private void resetKit(Player p) {
|
||||
p.getInventory().clear();
|
||||
p.getInventory().setItem(0, enchant(new ItemStack(Material.BOW), Enchantment.INFINITY, 1));
|
||||
p.getInventory().setItem(9, new ItemStack(Material.ARROW, 1));
|
||||
p.setHealth(Math.min(p.getMaxHealth(),20));
|
||||
}
|
||||
private ItemStack enchant(ItemStack i, Enchantment e, int lvl) {
|
||||
ItemMeta m = i.getItemMeta(); m.addEnchant(e, lvl, true); i.setItemMeta(m); return i;
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Nur Schwert — nur Schwertschaden zählt
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class SwordOnlyHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent current;
|
||||
SwordOnlyHandler(EventEngine p) { this.plugin = p; }
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
current = e;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
for (UUID uuid : e.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid); if (p == null) continue;
|
||||
p.getInventory().clear();
|
||||
p.getInventory().setItem(0, new ItemStack(Material.IRON_SWORD));
|
||||
p.setHealth(Math.min(p.getMaxHealth(),20));
|
||||
}
|
||||
broadcast("§c⚔ §eNur Schwert! §7Bogen-Schaden wird blockiert.");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e) { HandlerList.unregisterAll(this); current = null; }
|
||||
private void broadcast(String m) { Bukkit.broadcastMessage(m); }
|
||||
|
||||
@EventHandler public void onDamage(EntityDamageByEntityEvent e) {
|
||||
if (current == null || !(e.getEntity() instanceof Player victim)) return;
|
||||
if (!current.isParticipant(victim)) return;
|
||||
if (e.getCause() == org.bukkit.event.entity.EntityDamageEvent.DamageCause.PROJECTILE)
|
||||
e.setDamage(0);
|
||||
}
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e) {
|
||||
if (current == null || !current.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null);
|
||||
Player killer = e.getEntity().getKiller();
|
||||
if (killer != null && current.isParticipant(killer)) current.addScore(killer.getUniqueId(),1);
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> { if(e.getEntity().isOnline()){ e.getEntity().spigot().respawn(); e.getEntity().getInventory().setItem(0, new ItemStack(Material.IRON_SWORD)); e.getEntity().setHealth(Math.min(e.getEntity().getMaxHealth(),20)); }}, 60L);
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Faustkampf — kein Item-Schaden
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class FistFightHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent current;
|
||||
FistFightHandler(EventEngine p) { this.plugin = p; }
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
current = e;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
for (UUID uuid : e.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid); if (p == null) continue;
|
||||
p.getInventory().clear();
|
||||
p.setHealth(Math.min(p.getMaxHealth(),20));
|
||||
}
|
||||
broadcast("§e✊ §eFaustkampf! §7Kein Item erlaubt — nur Fäuste!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e) { HandlerList.unregisterAll(this); current = null; }
|
||||
private void broadcast(String m) { Bukkit.broadcastMessage(m); }
|
||||
|
||||
@EventHandler public void onDamage(EntityDamageByEntityEvent e) {
|
||||
if (current == null || !(e.getEntity() instanceof Player victim)) return;
|
||||
if (!current.isParticipant(victim)) return;
|
||||
// Nur Hand-Schaden (ENTITY_ATTACK mit leerem Item)
|
||||
if (e.getDamager() instanceof Player attacker) {
|
||||
if (attacker.getInventory().getItemInMainHand().getType() != Material.AIR
|
||||
&& attacker.getInventory().getItemInMainHand().getType() != Material.AIR)
|
||||
e.setDamage(1.5); // normaler Faust-Schaden
|
||||
}
|
||||
}
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e) {
|
||||
if (current == null || !current.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null);
|
||||
Player killer = e.getEntity().getKiller();
|
||||
if (killer != null && current.isParticipant(killer)) current.addScore(killer.getUniqueId(),1);
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> { if(e.getEntity().isOnline()){ e.getEntity().spigot().respawn(); e.getEntity().getInventory().clear(); e.getEntity().setHealth(Math.min(e.getEntity().getMaxHealth(),20)); }}, 60L);
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Kit PvP — alle Spieler kriegen gleiches Kit
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class KitPvPHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent current;
|
||||
KitPvPHandler(EventEngine p) { this.plugin = p; }
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
current = e;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
for (UUID uuid : e.getParticipants()) giveKit(Bukkit.getPlayer(uuid));
|
||||
broadcast("§6🗡 §eKit PvP! §7Alle erhalten gleiches Kit — nur Skill entscheidet!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e) { HandlerList.unregisterAll(this); current = null; }
|
||||
@Override public void onPlayerJoin(ActiveEvent e, Player p) { giveKit(p); }
|
||||
private void broadcast(String m) { Bukkit.broadcastMessage(m); }
|
||||
|
||||
private void giveKit(Player p) {
|
||||
if (p == null) return;
|
||||
p.getInventory().clear();
|
||||
p.getInventory().setItem(0, new ItemStack(Material.IRON_SWORD));
|
||||
p.getInventory().setItem(1, enchant(new ItemStack(Material.BOW), Enchantment.INFINITY,1));
|
||||
p.getInventory().setItem(2, new ItemStack(Material.GOLDEN_APPLE, 3));
|
||||
p.getInventory().setItem(9, new ItemStack(Material.ARROW,1));
|
||||
p.getEquipment().setHelmet(new ItemStack(Material.IRON_HELMET));
|
||||
p.getEquipment().setChestplate(new ItemStack(Material.IRON_CHESTPLATE));
|
||||
p.getEquipment().setLeggings(new ItemStack(Material.IRON_LEGGINGS));
|
||||
p.getEquipment().setBoots(new ItemStack(Material.IRON_BOOTS));
|
||||
p.setHealth(Math.min(p.getMaxHealth(),20)); p.setFoodLevel(20);
|
||||
}
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e) {
|
||||
if (current == null || !current.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null);
|
||||
Player killer = e.getEntity().getKiller();
|
||||
if (killer != null && current.isParticipant(killer)) current.addScore(killer.getUniqueId(),1);
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> { if(e.getEntity().isOnline()){ e.getEntity().spigot().respawn(); giveKit(e.getEntity()); }},60L);
|
||||
}
|
||||
private ItemStack enchant(ItemStack i, Enchantment e, int lvl) {
|
||||
ItemMeta m = i.getItemMeta(); m.addEnchant(e,lvl,true); i.setItemMeta(m); return i;
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// King of the Hill — Zentrum halten = Punkte pro Sekunde
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class KingOfTheHillHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent current;
|
||||
private BukkitRunnable ticker;
|
||||
KingOfTheHillHandler(EventEngine p) { this.plugin = p; }
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
current = e;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
broadcast("§6👑 §eKing of the Hill! §7Halte die Mitte und sammle Punkte!");
|
||||
|
||||
ticker = new BukkitRunnable() {
|
||||
@Override public void run() {
|
||||
if (current == null) { cancel(); return; }
|
||||
org.bukkit.Location center = current.getDefinition().hasRegion()
|
||||
? current.getDefinition().getRegion().getCenter() : null;
|
||||
if (center == null) return;
|
||||
for (UUID uuid : current.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid); if (p == null) continue;
|
||||
if (p.getLocation().distance(center) <= 5) {
|
||||
current.addScore(uuid, 1);
|
||||
p.sendActionBar("§6👑 §eAuf dem Hügel! §7+" + 1 + " Punkt");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
ticker.runTaskTimer(plugin, 20L, 20L);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e) { HandlerList.unregisterAll(this); if(ticker!=null)ticker.cancel(); current=null; }
|
||||
private void broadcast(String m) { Bukkit.broadcastMessage(m); }
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e) {
|
||||
if (current == null || !current.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null);
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> { if(e.getEntity().isOnline()) e.getEntity().spigot().respawn(); }, 60L);
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Team Battle — 2 Teams, Kills = Teampunkte
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class TeamBattleHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent current;
|
||||
private final Map<UUID, Integer> teamMap = new HashMap<>(); // 0 = rot, 1 = blau
|
||||
TeamBattleHandler(EventEngine p) { this.plugin = p; }
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
current = e; teamMap.clear();
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
List<UUID> participants = new ArrayList<>(e.getParticipants());
|
||||
for (int i = 0; i < participants.size(); i++) teamMap.put(participants.get(i), i % 2);
|
||||
broadcast("§cTeam Rot §7vs §9Team Blau §7– Kills gewinnen!");
|
||||
for (UUID uuid : teamMap.keySet()) {
|
||||
Player p = Bukkit.getPlayer(uuid); if (p == null) continue;
|
||||
p.sendMessage(plugin.prefix() + "Dein Team: " + (teamMap.get(uuid)==0 ? "§cRot":"§9Blau"));
|
||||
}
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e) { HandlerList.unregisterAll(this); current=null; teamMap.clear(); }
|
||||
private void broadcast(String m) { Bukkit.broadcastMessage(m); }
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e) {
|
||||
if (current == null || !current.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null);
|
||||
Player killer = e.getEntity().getKiller();
|
||||
if (killer != null && current.isParticipant(killer)) {
|
||||
// Team des Killers bekommt Punkt
|
||||
Integer killerTeam = teamMap.get(killer.getUniqueId());
|
||||
if (killerTeam != null) {
|
||||
teamMap.forEach((uuid,team) -> { if(team.equals(killerTeam)) current.addScore(uuid,1); });
|
||||
}
|
||||
}
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> { if(e.getEntity().isOnline()){ e.getEntity().spigot().respawn(); e.getEntity().setHealth(Math.min(e.getEntity().getMaxHealth(),20)); }},60L);
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Elytra PvP — Spieler mit Elytra + Bogen, keine Gravity
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class ElytraPvPHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent current;
|
||||
ElytraPvPHandler(EventEngine p) { this.plugin = p; }
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
current = e;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
for (UUID uuid : e.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid); if (p == null) continue;
|
||||
p.getInventory().clear();
|
||||
p.getEquipment().setChestplate(new ItemStack(Material.ELYTRA));
|
||||
ItemStack bow = new ItemStack(Material.BOW);
|
||||
ItemMeta bm = bow.getItemMeta(); bm.addEnchant(Enchantment.INFINITY,1,true); bow.setItemMeta(bm);
|
||||
p.getInventory().setItem(0, bow);
|
||||
p.getInventory().setItem(9, new ItemStack(Material.ARROW,1));
|
||||
p.getInventory().setItem(1, new ItemStack(Material.FIREWORK_ROCKET, 64));
|
||||
p.setHealth(Math.min(p.getMaxHealth(),20));
|
||||
}
|
||||
broadcast("§b🪂 §eElytra PvP! §7Fliege und schieße deine Gegner ab!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e) { HandlerList.unregisterAll(this); current=null; }
|
||||
private void broadcast(String m) { Bukkit.broadcastMessage(m); }
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e) {
|
||||
if (current==null||!current.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null);
|
||||
Player killer = e.getEntity().getKiller();
|
||||
if (killer!=null&¤t.isParticipant(killer)) current.addScore(killer.getUniqueId(),1);
|
||||
Bukkit.getScheduler().runTaskLater(plugin,()->{ if(e.getEntity().isOnline()) e.getEntity().spigot().respawn(); },60L);
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Arena Survival — PvP + Mobs gleichzeitig, beide geben Punkte
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class ArenaSurvivalHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent current;
|
||||
private BukkitRunnable spawner;
|
||||
ArenaSurvivalHandler(EventEngine p) { this.plugin = p; }
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
current = e;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
broadcast("§c⚔🧟 §eArena Survival! §7Besiege Spieler UND Mobs für Punkte!");
|
||||
spawner = new BukkitRunnable() {
|
||||
final org.bukkit.entity.EntityType[] mobs = {
|
||||
org.bukkit.entity.EntityType.ZOMBIE,org.bukkit.entity.EntityType.SKELETON,org.bukkit.entity.EntityType.SPIDER
|
||||
};
|
||||
final Random rng = new Random();
|
||||
@Override public void run() {
|
||||
if (current==null){cancel();return;}
|
||||
for (UUID uuid : current.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid); if(p==null) continue;
|
||||
org.bukkit.Location loc = p.getLocation().add((rng.nextDouble()-0.5)*10,0,(rng.nextDouble()-0.5)*10);
|
||||
p.getWorld().spawnEntity(loc, mobs[rng.nextInt(mobs.length)]);
|
||||
}
|
||||
}
|
||||
};
|
||||
spawner.runTaskTimer(plugin, 100L, 100L);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e) { HandlerList.unregisterAll(this); if(spawner!=null)spawner.cancel(); current=null; }
|
||||
private void broadcast(String m) { Bukkit.broadcastMessage(m); }
|
||||
@EventHandler public void onPlayerDeath(PlayerDeathEvent e) {
|
||||
if (current==null||!current.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null);
|
||||
Player killer=e.getEntity().getKiller();
|
||||
if (killer!=null&¤t.isParticipant(killer)) current.addScore(killer.getUniqueId(),3);
|
||||
Bukkit.getScheduler().runTaskLater(plugin,()->{ if(e.getEntity().isOnline()){ e.getEntity().spigot().respawn(); e.getEntity().setHealth(Math.min(e.getEntity().getMaxHealth(),20)); }},60L);
|
||||
}
|
||||
@EventHandler public void onMobDeath(org.bukkit.event.entity.EntityDeathEvent e) {
|
||||
if (current==null) return;
|
||||
Player killer=e.getEntity().getKiller();
|
||||
if (killer!=null&¤t.isParticipant(killer)) current.addScore(killer.getUniqueId(),1);
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// UHC — kein natürliches Heilen, Goldenäpfel heilen
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class UHCHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent current;
|
||||
private final Set<UUID> alive = new HashSet<>();
|
||||
UHCHandler(EventEngine p) { this.plugin = p; }
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
current = e; alive.clear(); alive.addAll(e.getParticipants());
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
for (UUID uuid : e.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid); if(p==null) continue;
|
||||
p.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 0, 0)); // sicherstellen keine regen
|
||||
}
|
||||
broadcast("§c☠ §eUltra Hardcore! §7Keine natürliche Regeneration. Nur Goldäpfel heilen!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e) { HandlerList.unregisterAll(this); current=null; alive.clear(); }
|
||||
private void broadcast(String m) { Bukkit.broadcastMessage(m); }
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e) {
|
||||
if (current==null||!current.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null); alive.remove(e.getEntity().getUniqueId());
|
||||
if (alive.size()==1) {
|
||||
UUID w=alive.iterator().next(); current.addScore(w,100);
|
||||
Player wp=Bukkit.getPlayer(w); String wn=wp!=null?wp.getName():"?";
|
||||
broadcast("§6✦ §e"+wn+" §6gewinnt Ultra Hardcore!");
|
||||
plugin.getEventManager().endEvent(wn+" hat gewonnen");
|
||||
}
|
||||
}
|
||||
// Natürliche Regeneration durch hunger blockieren
|
||||
@EventHandler public void onRegen(org.bukkit.event.entity.EntityRegainHealthEvent e) {
|
||||
if (current==null||!(e.getEntity() instanceof Player p)) return;
|
||||
if (!current.isParticipant(p)) return;
|
||||
if (e.getRegainReason()==org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.SATIATED||
|
||||
e.getRegainReason()==org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.REGEN)
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Hunger Games — starte ohne Items, sammle Loot, letzter gewinnt
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class HungerGamesHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent current;
|
||||
private final Set<UUID> alive = new HashSet<>();
|
||||
HungerGamesHandler(EventEngine p) { this.plugin = p; }
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
current = e; alive.clear(); alive.addAll(e.getParticipants());
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
for (UUID uuid : e.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid); if(p==null) continue;
|
||||
p.getInventory().clear(); p.setHealth(Math.min(p.getMaxHealth(),20));
|
||||
}
|
||||
broadcast("§2🌲 §eHunger Games! §7Keine Ausrüstung — sammle Loot und überlebe!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e) { HandlerList.unregisterAll(this); current=null; alive.clear(); }
|
||||
private void broadcast(String m) { Bukkit.broadcastMessage(m); }
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e) {
|
||||
if (current==null||!current.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null); alive.remove(e.getEntity().getUniqueId());
|
||||
e.getEntity().setGameMode(GameMode.SPECTATOR);
|
||||
Player killer=e.getEntity().getKiller();
|
||||
if (killer!=null&¤t.isParticipant(killer)) current.addScore(killer.getUniqueId(),5);
|
||||
broadcast("§c☠ §f"+e.getEntity().getName()+" §7scheidet aus! §8[§e"+alive.size()+" §7übrig§8]");
|
||||
if (alive.size()==1) {
|
||||
UUID w=alive.iterator().next(); current.addScore(w,100);
|
||||
Player wp=Bukkit.getPlayer(w); String wn=wp!=null?wp.getName():"?";
|
||||
broadcast("§6✦ §e"+wn+" §6gewinnt die Hunger Games!"); plugin.getEventManager().endEvent(wn+" hat gewonnen");
|
||||
} else if (alive.isEmpty()) plugin.getEventManager().endEvent("Unentschieden");
|
||||
}
|
||||
}
|
||||
|
||||
// Capture the Flag, BedWars Lite, SkyWars Lite: Arena-abhängig, Basislogik
|
||||
class CaptureTheFlagHandler implements IEventHandler {
|
||||
private final EventEngine plugin;
|
||||
CaptureTheFlagHandler(EventEngine p) { this.plugin = p; }
|
||||
@Override public void onStart(ActiveEvent e) { Bukkit.broadcastMessage(plugin.prefix()+"§e🚩 Capture the Flag! §7Stehle die Flagge des Gegners und bringe sie zu deiner Basis!"); }
|
||||
@Override public void onEnd(ActiveEvent e) {}
|
||||
}
|
||||
class BedWarsLiteHandler implements IEventHandler {
|
||||
private final EventEngine plugin;
|
||||
BedWarsLiteHandler(EventEngine p) { this.plugin = p; }
|
||||
@Override public void onStart(ActiveEvent e) { Bukkit.broadcastMessage(plugin.prefix()+"§e🛏 BedWars Lite! §7Schütze dein Bett und zerstöre das der Gegner!"); }
|
||||
@Override public void onEnd(ActiveEvent e) {}
|
||||
}
|
||||
class SkyWarsLiteHandler implements IEventHandler {
|
||||
private final EventEngine plugin;
|
||||
SkyWarsLiteHandler(EventEngine p) { this.plugin = p; }
|
||||
@Override public void onStart(ActiveEvent e) { Bukkit.broadcastMessage(plugin.prefix()+"§e☁ SkyWars Lite! §7Starte auf deiner Insel — sammle Loot und besiege alle anderen!"); }
|
||||
@Override public void onEnd(ActiveEvent e) {}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Snowball;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* Schneeballschlacht:
|
||||
* - Jeder Treffer = 1 Punkt
|
||||
* - Spieler bekommen unendlich Schneebälle
|
||||
* - Kein normaler Schaden
|
||||
*/
|
||||
public class SnowballFightHandler implements IEventHandler, Listener {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
|
||||
public SnowballFightHandler(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
// Schneebälle verteilen
|
||||
for (var uuid : event.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null) {
|
||||
p.getInventory().clear();
|
||||
p.getInventory().setItem(0, new ItemStack(Material.SNOWBALL, 64));
|
||||
p.setHealth(Math.min(p.getMaxHealth(), 20));
|
||||
}
|
||||
}
|
||||
broadcast("§b❄ §eSchneeballschlacht! §7Treffe Gegner für Punkte!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
this.currentEvent = null;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onHit(EntityDamageByEntityEvent e) {
|
||||
if (!(e.getEntity() instanceof Player victim)) return;
|
||||
if (!(e.getDamager() instanceof Snowball snowball)) return;
|
||||
if (!(snowball.getShooter() instanceof Player shooter)) return;
|
||||
if (currentEvent == null) return;
|
||||
if (!currentEvent.isParticipant(shooter) || !currentEvent.isParticipant(victim)) return;
|
||||
if (shooter.equals(victim)) return;
|
||||
|
||||
e.setDamage(0); // Kein Schaden
|
||||
currentEvent.addScore(shooter.getUniqueId(), 1);
|
||||
int score = currentEvent.getScore(shooter.getUniqueId());
|
||||
shooter.sendActionBar("§b❄ Treffer! §7Punkte: §e" + score);
|
||||
shooter.playSound(shooter.getLocation(), Sound.BLOCK_GLASS_BREAK, 0.5f, 1.5f);
|
||||
|
||||
// Nachladen
|
||||
if (!shooter.getInventory().contains(Material.SNOWBALL)) {
|
||||
shooter.getInventory().addItem(new ItemStack(Material.SNOWBALL, 64));
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcast(String msg) { Bukkit.broadcastMessage(msg); }
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Spleef:
|
||||
* - Spieler graben Schnee/Eis unter Gegnern weg
|
||||
* - Fallen = ausgeschieden
|
||||
* - Kein normaler Block-Break außerhalb der Spleef-Arena-Materialien
|
||||
*/
|
||||
public class SpleefHandler implements IEventHandler, Listener {
|
||||
|
||||
private static final Set<Material> SPLEEF_MATERIALS = Set.of(
|
||||
Material.SNOW_BLOCK, Material.ICE, Material.PACKED_ICE,
|
||||
Material.BLUE_ICE, Material.WHITE_CONCRETE
|
||||
);
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private final Set<UUID> alive = new HashSet<>();
|
||||
|
||||
public SpleefHandler(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
alive.clear();
|
||||
alive.addAll(event.getParticipants());
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
|
||||
// Jedem Spieler eine Schneeschaufel geben
|
||||
for (UUID uuid : event.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null) {
|
||||
p.getInventory().addItem(new ItemStack(Material.DIAMOND_SHOVEL));
|
||||
}
|
||||
}
|
||||
broadcast("§a⛏ §eSpleef! §7Grabe Schnee unter deinen Gegnern weg. §7Wer fällt, verliert!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
this.currentEvent = null;
|
||||
alive.clear();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockBreak(BlockBreakEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (currentEvent == null || !currentEvent.isParticipant(p)) return;
|
||||
// Nur Spleef-Materialien erlaubt
|
||||
if (!SPLEEF_MATERIALS.contains(e.getBlock().getType())) {
|
||||
e.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
e.setDropItems(false); // Kein Item-Drop
|
||||
p.playSound(p.getLocation(), Sound.BLOCK_SNOW_BREAK, 1f, 1f);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDamage(EntityDamageEvent e) {
|
||||
if (!(e.getEntity() instanceof Player p)) return;
|
||||
if (currentEvent == null || !currentEvent.isParticipant(p)) return;
|
||||
if (e.getCause() == EntityDamageEvent.DamageCause.FALL ||
|
||||
e.getCause() == EntityDamageEvent.DamageCause.VOID) {
|
||||
e.setCancelled(true);
|
||||
eliminate(p);
|
||||
} else {
|
||||
e.setDamage(0); // Kein PvP-Schaden
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDeath(PlayerDeathEvent e) {
|
||||
if (currentEvent == null || !currentEvent.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null);
|
||||
}
|
||||
|
||||
private void eliminate(Player p) {
|
||||
if (!alive.contains(p.getUniqueId())) return;
|
||||
alive.remove(p.getUniqueId());
|
||||
currentEvent.removeParticipant(p);
|
||||
p.setGameMode(org.bukkit.GameMode.SPECTATOR);
|
||||
broadcast("§c⬇ §f" + p.getName() + " §7ist gefallen! §8[§e" + alive.size() + " §7übrig§8]");
|
||||
checkWinner();
|
||||
}
|
||||
|
||||
private void checkWinner() {
|
||||
if (alive.size() == 1) {
|
||||
UUID winnerId = alive.iterator().next();
|
||||
Player winner = Bukkit.getPlayer(winnerId);
|
||||
String name = winner != null ? winner.getName() : "?";
|
||||
currentEvent.addScore(winnerId, 100);
|
||||
broadcast("§6✦ §e" + name + " §6gewinnt Spleef!");
|
||||
if (winner != null) winner.playSound(winner.getLocation(), Sound.UI_TOAST_CHALLENGE_COMPLETE, 1f, 1f);
|
||||
plugin.getEventManager().endEvent(name + " hat gewonnen");
|
||||
} else if (alive.isEmpty()) {
|
||||
plugin.getEventManager().endEvent("Unentschieden");
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcast(String msg) { Bukkit.broadcastMessage(msg); }
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Sumo:
|
||||
* - Kein normaler Schaden (nur Knockback)
|
||||
* - Fall in Void/Wasser = ausgeschieden
|
||||
* - Spieler erhalten Speed I + kein Schaden-Handling außer Knockback
|
||||
*/
|
||||
public class SumoHandler implements IEventHandler, Listener {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private final Set<UUID> alive = new HashSet<>();
|
||||
private BukkitRunnable voidChecker;
|
||||
|
||||
public SumoHandler(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
alive.clear();
|
||||
alive.addAll(event.getParticipants());
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
|
||||
// Teilnehmer vorbereiten
|
||||
for (UUID uuid : event.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p == null) continue;
|
||||
p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, Integer.MAX_VALUE, 0, false, false));
|
||||
p.setHealth(Math.min(p.getMaxHealth(), 20));
|
||||
}
|
||||
|
||||
// Void-Check alle 5 Ticks
|
||||
voidChecker = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentEvent == null) { cancel(); return; }
|
||||
for (UUID uuid : new HashSet<>(alive)) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null && p.getLocation().getY() < 0) {
|
||||
eliminate(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
voidChecker.runTaskTimer(plugin, 5L, 5L);
|
||||
|
||||
broadcast("§b🌊 §eSumo! §7Stoße deine Gegner in den Void! §7Kein Schaden — nur Knockback.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
if (voidChecker != null) voidChecker.cancel();
|
||||
for (UUID uuid : event.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null) p.removePotionEffect(PotionEffectType.SPEED);
|
||||
}
|
||||
this.currentEvent = null;
|
||||
alive.clear();
|
||||
}
|
||||
|
||||
// Schaden blockieren (außer Knockback bleibt)
|
||||
@EventHandler
|
||||
public void onDamage(EntityDamageEvent e) {
|
||||
if (!(e.getEntity() instanceof Player p)) return;
|
||||
if (currentEvent == null || !currentEvent.isParticipant(p)) return;
|
||||
if (e.getCause() == EntityDamageEvent.DamageCause.VOID) {
|
||||
e.setCancelled(true);
|
||||
eliminate(p);
|
||||
return;
|
||||
}
|
||||
// Kein HP-Verlust, aber Knockback bleibt
|
||||
e.setDamage(0);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDeath(PlayerDeathEvent e) {
|
||||
if (currentEvent == null || !currentEvent.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null);
|
||||
e.getEntity().spigot().respawn();
|
||||
}
|
||||
|
||||
private void eliminate(Player p) {
|
||||
if (!alive.contains(p.getUniqueId())) return;
|
||||
alive.remove(p.getUniqueId());
|
||||
currentEvent.removeParticipant(p);
|
||||
p.setGameMode(org.bukkit.GameMode.SPECTATOR);
|
||||
broadcast("§c💧 §f" + p.getName() + " §7ist ins Wasser gefallen! §8[§e" + alive.size() + " §7übrig§8]");
|
||||
|
||||
if (alive.size() == 1) {
|
||||
UUID winnerId = alive.iterator().next();
|
||||
Player winner = Bukkit.getPlayer(winnerId);
|
||||
String name = winner != null ? winner.getName() : "?";
|
||||
currentEvent.addScore(winnerId, 100);
|
||||
broadcast("§6✦ §e" + name + " §6gewinnt das Sumo-Event!");
|
||||
if (winner != null) winner.playSound(winner.getLocation(), Sound.UI_TOAST_CHALLENGE_COMPLETE, 1f, 1f);
|
||||
plugin.getEventManager().endEvent(name + " hat gewonnen");
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcast(String msg) { Bukkit.broadcastMessage(msg); }
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Zombie Belagerung
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class ZombieSiegeHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
private BukkitRunnable spawner; private int wave = 0;
|
||||
ZombieSiegeHandler(EventEngine p) { this.plugin = p; }
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
current = e;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
broadcast("§2🧟 §eZombie-Belagerung! §7Halte die Stellung — Zombies kommen in Wellen!");
|
||||
spawner = new BukkitRunnable() {
|
||||
@Override public void run() {
|
||||
if (current==null){cancel();return;}
|
||||
wave++;
|
||||
broadcast("§2🧟 §eZombie-Welle §c"+wave+"§e kommt!");
|
||||
Location loc = getSpawnLoc();
|
||||
if (loc==null) return;
|
||||
int count = 5 + wave * 3;
|
||||
Random rng = new Random();
|
||||
for (int i=0;i<count;i++) {
|
||||
Location sl = loc.clone().add((rng.nextDouble()-0.5)*20,0,(rng.nextDouble()-0.5)*20);
|
||||
Zombie z = (Zombie) loc.getWorld().spawnEntity(sl, EntityType.ZOMBIE);
|
||||
if (wave > 3) z.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,99999,1));
|
||||
}
|
||||
}
|
||||
};
|
||||
spawner.runTaskTimer(plugin, 20L, 30*20L);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e) { HandlerList.unregisterAll(this); if(spawner!=null)spawner.cancel(); current=null; }
|
||||
@EventHandler public void onKill(EntityDeathEvent e) {
|
||||
if (current==null||!(e.getEntity() instanceof Zombie)) return;
|
||||
Player killer=e.getEntity().getKiller();
|
||||
if (killer!=null&¤t.isParticipant(killer)) { current.addScore(killer.getUniqueId(),1); killer.sendActionBar("§2+1 §7Zombie Kill"); }
|
||||
}
|
||||
private Location getSpawnLoc() { for (UUID u:current.getParticipants()){Player p=Bukkit.getPlayer(u);if(p!=null)return p.getLocation();} return null; }
|
||||
private void broadcast(String m){Bukkit.broadcastMessage(m);}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Wither Sturm
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class WitherStormHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current; private Wither wither;
|
||||
WitherStormHandler(EventEngine p){this.plugin=p;}
|
||||
|
||||
@Override public void onStart(ActiveEvent e) {
|
||||
current=e; Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
broadcast("§8☠ §lWITHER STURM! §r§7Besiegt den Wither gemeinsam! Wer den letzten Schlag landet gewinnt den Jackpot!");
|
||||
Location loc=getCenter(); if(loc==null)return;
|
||||
wither=(Wither)loc.getWorld().spawnEntity(loc.add(0,5,0), EntityType.WITHER);
|
||||
wither.setCustomName("§8§l☠ DER WITHER ☠");
|
||||
wither.setCustomNameVisible(true);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){ HandlerList.unregisterAll(this); if(wither!=null&&!wither.isDead())wither.remove(); current=null; }
|
||||
@EventHandler public void onWitherDeath(EntityDeathEvent e){
|
||||
if(current==null||!(e.getEntity() instanceof Wither)) return;
|
||||
Player killer=e.getEntity().getKiller();
|
||||
if(killer!=null&¤t.isParticipant(killer)){
|
||||
current.addScore(killer.getUniqueId(),100);
|
||||
broadcast("§6✦ §f"+killer.getName()+" §6hat den Wither besiegt und bekommt 100 Punkte!");
|
||||
}
|
||||
plugin.getEventManager().endEvent("Wither besiegt");
|
||||
}
|
||||
private Location getCenter(){if(current.getDefinition().hasRegion())return current.getDefinition().getRegion().getCenter(); for(UUID u:current.getParticipants()){Player p=Bukkit.getPlayer(u);if(p!=null)return p.getLocation();}return null;}
|
||||
private void broadcast(String m){Bukkit.broadcastMessage(m);}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Drachen Event
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class DragonFightHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
DragonFightHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
current=e; Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
broadcast("§5🐉 §eDrachen-Event! §7Besiegt den Ender-Dragon! Wer den Killing Blow landet gewinnt den Jackpot!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){ HandlerList.unregisterAll(this); current=null; }
|
||||
@EventHandler public void onDragonDeath(EntityDeathEvent e){
|
||||
if(current==null||!(e.getEntity() instanceof EnderDragon)) return;
|
||||
Player killer=e.getEntity().getKiller();
|
||||
if(killer!=null&¤t.isParticipant(killer)){
|
||||
current.addScore(killer.getUniqueId(),200);
|
||||
broadcast("§6✦ §f"+killer.getName()+" §6hat den Drachen getötet! §e+200 Punkte!");
|
||||
}
|
||||
broadcast("§5🐉 §eDer Drache ist gefallen! §7Alle Teilnehmer erhalten eine Belohnung!");
|
||||
plugin.getEventManager().endEvent("Drache besiegt");
|
||||
}
|
||||
private void broadcast(String m){Bukkit.broadcastMessage(m);}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Hardcore Runde — kein Respawn, wer lebt gewinnt
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class HardcoreRoundHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current; private final Set<UUID> alive=new HashSet<>();
|
||||
HardcoreRoundHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
current=e; alive.clear(); alive.addAll(e.getParticipants());
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
broadcast("§c💀 §eHardcore-Runde! §7Kein Respawn — stirb einmal und du bist raus!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){ HandlerList.unregisterAll(this); current=null; alive.clear(); }
|
||||
private void broadcast(String m) { Bukkit.broadcastMessage(m); }
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e){
|
||||
if(current==null||!current.isParticipant(e.getEntity())) return;
|
||||
e.setDeathMessage(null); alive.remove(e.getEntity().getUniqueId());
|
||||
e.getEntity().setGameMode(GameMode.SPECTATOR);
|
||||
broadcast("§c💀 §f"+e.getEntity().getName()+" §7ist ausgeschieden! §8[§e"+alive.size()+" §7übrig§8]");
|
||||
if(alive.size()==1){ UUID w=alive.iterator().next(); current.addScore(w,100); Player wp=Bukkit.getPlayer(w); broadcast("§6✦ "+(wp!=null?wp.getName():"?")+" §6gewinnt die Hardcore-Runde!"); plugin.getEventManager().endEvent("Gewinner ermittelt"); }
|
||||
else if(alive.isEmpty()) plugin.getEventManager().endEvent("Unentschieden");
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Insel Überleben — punkte pro Sekunde
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class IslandSurvivalHandler implements IEventHandler {
|
||||
private final EventEngine plugin; private BukkitRunnable ticker;
|
||||
IslandSurvivalHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
Bukkit.broadcastMessage(plugin.prefix()+"§2🏝 §eInsel-Überleben! §7Überlebt und sammelt Punkte pro Sekunde!");
|
||||
ticker=new BukkitRunnable(){ @Override public void run(){ if(e.getState()==dev.viper.eventengine.model.ActiveEvent.State.ENDED){cancel();return;} for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p!=null)e.addScore(u,1);} }};
|
||||
ticker.runTaskTimer(plugin,20L,20L);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){ if(ticker!=null)ticker.cancel(); }
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Nether Sprint — Punkte für Nether-Items
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class NetherRunHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
private static final Map<Material,Integer> NETHER_SCORES=new EnumMap<>(Material.class);
|
||||
static { NETHER_SCORES.put(Material.BLAZE_ROD,5); NETHER_SCORES.put(Material.NETHER_QUARTZ_ORE,2); NETHER_SCORES.put(Material.MAGMA_CREAM,3); NETHER_SCORES.put(Material.GHAST_TEAR,8); NETHER_SCORES.put(Material.WITHER_SKELETON_SKULL,20); NETHER_SCORES.put(Material.ANCIENT_DEBRIS,15); }
|
||||
NetherRunHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){ current=e; Bukkit.getPluginManager().registerEvents(this,plugin); broadcast("§c🔥 §eNether-Sprint! §7Sammle Nether-Items für Punkte! Wer hat am Ende das meiste?"); }
|
||||
@Override public void onEnd(ActiveEvent e){
|
||||
HandlerList.unregisterAll(this);
|
||||
// Inventar-Scan beim Ende
|
||||
for(UUID uuid:e.getParticipants()){ Player p=Bukkit.getPlayer(uuid); if(p==null)continue; for(ItemStack item:p.getInventory().getContents()){ if(item==null)continue; Integer pts=NETHER_SCORES.get(item.getType()); if(pts!=null) e.addScore(uuid,pts*item.getAmount()); } }
|
||||
current=null;
|
||||
}
|
||||
private void broadcast(String m){Bukkit.broadcastMessage(m);}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Ausdauer Test — Schaden über Zeit, wer überlebt länger = mehr Punkte
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class EnduranceHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current; private BukkitRunnable ticker;
|
||||
EnduranceHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
current=e; Bukkit.getPluginManager().registerEvents(this,plugin);
|
||||
broadcast("§9⏱ §eAusdauer-Test! §7Jede Sekunde wachsen die Gefahren — wer hält am längsten durch?");
|
||||
ticker=new BukkitRunnable(){
|
||||
int tick=0;
|
||||
@Override public void run(){
|
||||
if(current==null){cancel();return;} tick++;
|
||||
for(UUID uuid:current.getParticipants()){
|
||||
Player p=Bukkit.getPlayer(uuid); if(p==null) continue;
|
||||
current.addScore(uuid,1);
|
||||
// Nach 30s: Gift; nach 60s: Hunger; nach 90s: Langsamkeit
|
||||
if(tick>=30) p.addPotionEffect(new PotionEffect(PotionEffectType.POISON,40,0,false,false));
|
||||
if(tick>=60) p.setFoodLevel(Math.max(0,p.getFoodLevel()-1));
|
||||
if(tick>=90) p.addPotionEffect(new PotionEffect(PotionEffectType.SLOWNESS,40,1,false,false));
|
||||
}
|
||||
}
|
||||
};
|
||||
ticker.runTaskTimer(plugin,20L,20L);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){ HandlerList.unregisterAll(this); if(ticker!=null)ticker.cancel(); current=null; }
|
||||
private void broadcast(String m) { Bukkit.broadcastMessage(m); }
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e){ if(current!=null&¤t.isParticipant(e.getEntity())){ e.setDeathMessage(null); current.removeParticipant(e.getEntity()); e.getEntity().setGameMode(GameMode.SPECTATOR); } }
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Raid Plus — verstärkte Raid-Wellen
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class RaidsPlusHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current; private BukkitRunnable spawner;
|
||||
private static final EntityType[] RAID_MOBS={EntityType.PILLAGER,EntityType.VINDICATOR,EntityType.WITCH,EntityType.EVOKER,EntityType.RAVAGER};
|
||||
RaidsPlusHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
current=e; Bukkit.getPluginManager().registerEvents(this,plugin);
|
||||
broadcast("§4🏹 §eRaid+! §7Verstärkte Illager-Angriffe — besiegt alle Wellen!");
|
||||
spawner=new BukkitRunnable(){
|
||||
int wave=0; final Random rng=new Random();
|
||||
@Override public void run(){
|
||||
if(current==null){cancel();return;} wave++;
|
||||
broadcast("§4🏹 §eRaid-Welle §c"+wave+"§e startet!");
|
||||
Location loc=getCenter(); if(loc==null)return;
|
||||
int count=4+wave*2;
|
||||
for(int i=0;i<count;i++){
|
||||
EntityType type=RAID_MOBS[rng.nextInt(Math.min(wave+1,RAID_MOBS.length))];
|
||||
Location sl=loc.clone().add((rng.nextDouble()-0.5)*20,0,(rng.nextDouble()-0.5)*20);
|
||||
try{ LivingEntity mob=(LivingEntity)loc.getWorld().spawnEntity(sl,type); if(mob.getAttribute(Attribute.MAX_HEALTH)!=null){double hp=20+wave*5;mob.getAttribute(Attribute.MAX_HEALTH).setBaseValue(hp);mob.setHealth(hp);} }catch(Exception ignored){}
|
||||
}
|
||||
}
|
||||
};
|
||||
spawner.runTaskTimer(plugin,60L,25*20L);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){ HandlerList.unregisterAll(this); if(spawner!=null)spawner.cancel(); current=null; }
|
||||
@EventHandler public void onKill(EntityDeathEvent e){ if(current==null)return; Player k=e.getEntity().getKiller(); if(k!=null&¤t.isParticipant(k)){ int pts=e.getEntity().getType()==EntityType.RAVAGER?10:e.getEntity().getType()==EntityType.EVOKER?8:3; current.addScore(k.getUniqueId(),pts); k.sendActionBar("§4+"+pts+" §7Raid-Kill"); } }
|
||||
private Location getCenter(){ if(current.getDefinition().hasRegion())return current.getDefinition().getRegion().getCenter(); for(UUID u:current.getParticipants()){Player p=Bukkit.getPlayer(u);if(p!=null)return p.getLocation();} return null; }
|
||||
private void broadcast(String m){Bukkit.broadcastMessage(m);}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Monster Jagd — töte bestimmte Mobs für Punkte
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class MonsterHuntHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current;
|
||||
private static final Map<EntityType,Integer> BOUNTY=new EnumMap<>(EntityType.class);
|
||||
static{ BOUNTY.put(EntityType.ZOMBIE,1);BOUNTY.put(EntityType.SKELETON,1);BOUNTY.put(EntityType.CREEPER,2);BOUNTY.put(EntityType.ENDERMAN,3);BOUNTY.put(EntityType.WITCH,4);BOUNTY.put(EntityType.ELDER_GUARDIAN,10);BOUNTY.put(EntityType.WITHER_SKELETON,6);BOUNTY.put(EntityType.BLAZE,5); }
|
||||
MonsterHuntHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){ current=e; Bukkit.getPluginManager().registerEvents(this,plugin); broadcast("§c🎯 §eMonster-Jagd! §7Töte Mobs für Punkte. Rare Mobs = mehr Punkte!"); }
|
||||
@Override public void onEnd(ActiveEvent e){ HandlerList.unregisterAll(this); current=null; }
|
||||
@EventHandler public void onKill(EntityDeathEvent e){ if(current==null) return; Player k=e.getEntity().getKiller(); if(k==null||!current.isParticipant(k))return; Integer pts=BOUNTY.get(e.getEntityType()); if(pts!=null){ current.addScore(k.getUniqueId(),pts); k.sendActionBar("§c+"+pts+" §7["+e.getEntityType().name()+"]"); } }
|
||||
private void broadcast(String m){Bukkit.broadcastMessage(m);}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Schwerkraft Chaos — Spieler werden hochgeworfen
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class GravityShiftHandler implements IEventHandler {
|
||||
private final EventEngine plugin; private BukkitRunnable ticker;
|
||||
GravityShiftHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
Bukkit.broadcastMessage(plugin.prefix()+"§b🌀 §eSchwerkraft-Chaos! §7Die Schwerkraft verhält sich zufällig!");
|
||||
final Random rng=new Random();
|
||||
ticker=new BukkitRunnable(){ @Override public void run(){ if(e.getState()==dev.viper.eventengine.model.ActiveEvent.State.ENDED){cancel();return;} for(UUID u:e.getParticipants()){Player p=Bukkit.getPlayer(u);if(p==null)continue; if(rng.nextInt(5)==0) p.setVelocity(p.getVelocity().setY(1.5+rng.nextDouble()*2)); e.addScore(u,1); } }};
|
||||
ticker.runTaskTimer(plugin,20L,20L);
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){ if(ticker!=null)ticker.cancel(); }
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Random Spawn — Spieler werden zufällig in Arena gespawnt, kein Respawn
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class RandomSpawnHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current; private final Set<UUID> alive=new HashSet<>();
|
||||
RandomSpawnHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
current=e; alive.clear(); alive.addAll(e.getParticipants());
|
||||
Bukkit.getPluginManager().registerEvents(this,plugin);
|
||||
final Random rng=new Random();
|
||||
for(UUID uuid:e.getParticipants()){ Player p=Bukkit.getPlayer(uuid); if(p==null)continue; Location loc=e.getDefinition().hasRegion()?e.getDefinition().getRegion().randomLocation(rng):p.getWorld().getSpawnLocation(); p.teleport(loc); }
|
||||
broadcast("§d🎲 §eRandom Spawn! §7Alle wurden zufällig verteilt — kein Respawn. Letzter gewinnt!");
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){ HandlerList.unregisterAll(this); current=null; alive.clear(); }
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e){ if(current==null||!current.isParticipant(e.getEntity()))return; e.setDeathMessage(null); alive.remove(e.getEntity().getUniqueId()); e.getEntity().setGameMode(GameMode.SPECTATOR); broadcast("§c☠ §f"+e.getEntity().getName()+" §7scheidet aus! §8[§e"+alive.size()+" §7übrig§8]"); if(alive.size()==1){UUID w=alive.iterator().next();current.addScore(w,100);Player wp=Bukkit.getPlayer(w);broadcast("§6✦ "+(wp!=null?wp.getName():"?")+" §6gewinnt!");plugin.getEventManager().endEvent("Gewinner ermittelt");}else if(alive.isEmpty())plugin.getEventManager().endEvent("Unentschieden"); }
|
||||
private void broadcast(String m){Bukkit.broadcastMessage(m);}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Manhunt — 1 Gejagter, alle anderen Jäger
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
class ManhuntHandler implements IEventHandler, Listener {
|
||||
private final EventEngine plugin; private ActiveEvent current; private UUID target;
|
||||
ManhuntHandler(EventEngine p){this.plugin=p;}
|
||||
@Override public void onStart(ActiveEvent e){
|
||||
current=e; Bukkit.getPluginManager().registerEvents(this,plugin);
|
||||
List<UUID> parts=new ArrayList<>(e.getParticipants());
|
||||
if(parts.isEmpty())return;
|
||||
target=parts.get(new Random().nextInt(parts.size()));
|
||||
Player tp=Bukkit.getPlayer(target);
|
||||
broadcast("§c🎯 §eManhunt! §fGejagter: §c"+(tp!=null?tp.getName():"?")+" §7— alle anderen sind Jäger!");
|
||||
if(tp!=null){ tp.sendTitle("§cDU BIST GEJAGT!","§7Überlebe so lange wie möglich!",10,60,20); tp.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,99999,0,false,false)); }
|
||||
}
|
||||
@Override public void onEnd(ActiveEvent e){ HandlerList.unregisterAll(this); current=null; target=null; }
|
||||
@EventHandler public void onDeath(PlayerDeathEvent e){
|
||||
if(current==null||!current.isParticipant(e.getEntity()))return;
|
||||
e.setDeathMessage(null);
|
||||
if(e.getEntity().getUniqueId().equals(target)){
|
||||
broadcast("§6✦ §7Die Jäger haben gewonnen! §c"+(e.getEntity().getName())+" §7wurde gefangen!");
|
||||
for(UUID u:current.getParticipants()) if(!u.equals(target)) current.addScore(u,50);
|
||||
plugin.getEventManager().endEvent("Gejagter gefangen");
|
||||
} else {
|
||||
broadcast("§7Ein Jäger ist gestorben. §c"+e.getEntity().getName()+" §7scheidet aus.");
|
||||
e.getEntity().setGameMode(GameMode.SPECTATOR);
|
||||
}
|
||||
}
|
||||
// Kompatibilitätsmethode
|
||||
private void addPotion(Player p, PotionEffect effect){ p.addPotionEffect(effect); }
|
||||
private void broadcast(String m){Bukkit.broadcastMessage(m);}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package dev.viper.eventengine.events.builtin;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Minecraft-Trivia:
|
||||
* - Frage wird im Chat gestellt
|
||||
* - Erster der richtig antwortet bekommt Punkte
|
||||
* - 10 Fragen, danach endet das Event
|
||||
*/
|
||||
public class TriviaHandler implements IEventHandler, Listener {
|
||||
|
||||
/** Öffentlich für Subklassen (GeneralKnowledgeQuizHandler etc.) */
|
||||
public static final class QuestionEntry {
|
||||
public final String question, answer; public final int points;
|
||||
public QuestionEntry(String q, String a, int p){this.question=q;this.answer=a;this.points=p;}
|
||||
}
|
||||
|
||||
private static final List<QuestionEntry> QUESTIONS = List.of(
|
||||
new QuestionEntry("Wie viele Blöcke hoch ist eine Karotte wenn sie voll gewachsen ist?", "1", 10),
|
||||
new QuestionEntry("Was braucht man um ein Bett zu craften? (Material)", "Wolle", 10),
|
||||
new QuestionEntry("Wie heißt der End-Boss?", "Ender Dragon", 15),
|
||||
new QuestionEntry("Was dropped ein Blaze?", "Blaze Rod", 10),
|
||||
new QuestionEntry("Aus wie vielen Blöcken besteht ein Chunk?", "16", 15),
|
||||
new QuestionEntry("Welches Erz ist das seltenste in Minecraft?", "Netherit", 20),
|
||||
new QuestionEntry("Was ist die maximale Verzauberungsstufe in Vanilla?", "30", 10),
|
||||
new QuestionEntry("Wie nennt man den grünen feindlichen Mob ohne Arme?", "Creeper", 5),
|
||||
new QuestionEntry("Welches Tier liefert Wolle?", "Schaf", 5),
|
||||
new QuestionEntry("Was dropped ein Ender Dragon?", "Dragon Egg", 20),
|
||||
new QuestionEntry("Wie heißt der Minecraft-Entwickler?", "Notch", 10),
|
||||
new QuestionEntry("Aus welchem Material werden Schienen gecraftet?", "Eisen", 10),
|
||||
new QuestionEntry("Was ist die tiefste Y-Koordinate in 1.18+?", "-64", 15),
|
||||
new QuestionEntry("Wie viele Lebensherzen hat ein Spieler maximal (vanilla)?", "10", 10),
|
||||
new QuestionEntry("Was braucht man um einen Kompass zu craften?", "Redstone", 15)
|
||||
);
|
||||
|
||||
private final EventEngine plugin;
|
||||
private ActiveEvent currentEvent;
|
||||
private QuestionEntry currentQuestion;
|
||||
private boolean answered;
|
||||
private int questionIndex = 0;
|
||||
private final List<QuestionEntry> shuffled = new ArrayList<>();
|
||||
private BukkitRunnable questionRunner;
|
||||
|
||||
public TriviaHandler(EventEngine plugin) { this.plugin = plugin; this.externalQuestions = null; }
|
||||
|
||||
private final List<QuestionEntry> externalQuestions;
|
||||
public TriviaHandler(EventEngine plugin, List<QuestionEntry> questions) { this.plugin = plugin; this.externalQuestions = questions; }
|
||||
|
||||
@Override
|
||||
public void onStart(ActiveEvent event) {
|
||||
this.currentEvent = event;
|
||||
this.questionIndex = 0;
|
||||
this.answered = false;
|
||||
shuffled.clear();
|
||||
shuffled.addAll(externalQuestions != null ? externalQuestions : QUESTIONS);
|
||||
Collections.shuffle(shuffled);
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
broadcast("§e❓ §eMinecraft-Quiz! §7Beantworte Fragen im Chat!");
|
||||
|
||||
questionRunner = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentEvent == null) { cancel(); return; }
|
||||
if (questionIndex >= Math.min(10, shuffled.size())) {
|
||||
cancel();
|
||||
plugin.getEventManager().endEvent("Alle Fragen beantwortet");
|
||||
return;
|
||||
}
|
||||
if (!answered && currentQuestion != null) {
|
||||
broadcast("§c⏰ §7Zu langsam! Die Antwort war: §e" + currentQuestion.answer);
|
||||
}
|
||||
nextQuestion();
|
||||
}
|
||||
};
|
||||
questionRunner.runTaskTimer(plugin, 60L, 200L); // 10s pro Frage
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(ActiveEvent event) {
|
||||
HandlerList.unregisterAll(this);
|
||||
if (questionRunner != null) questionRunner.cancel();
|
||||
this.currentEvent = null;
|
||||
}
|
||||
|
||||
private void nextQuestion() {
|
||||
if (questionIndex >= shuffled.size()) return;
|
||||
currentQuestion = shuffled.get(questionIndex++);
|
||||
answered = false;
|
||||
broadcast("§8§m══════════════════════════════");
|
||||
broadcast("§e❓ Frage " + questionIndex + ": §f" + currentQuestion.question);
|
||||
broadcast("§7Punkte: §e" + currentQuestion.points + " §8| §7Tippe die Antwort im Chat!");
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onChat(AsyncPlayerChatEvent e) {
|
||||
if (currentEvent == null || currentQuestion == null || answered) return;
|
||||
Player p = e.getPlayer();
|
||||
String msg = e.getMessage().trim();
|
||||
|
||||
if (msg.equalsIgnoreCase(currentQuestion.answer)) {
|
||||
answered = true;
|
||||
currentEvent.addScore(p.getUniqueId(), currentQuestion.points);
|
||||
broadcast("§a✔ §f" + p.getName() + " §7hat die Antwort gewusst! §a+" + currentQuestion.points + " §7Punkte");
|
||||
Bukkit.getScheduler().runTask(plugin, () ->
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1f, 1.5f));
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcast(String msg) { Bukkit.broadcastMessage(msg); }
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
package dev.viper.eventengine.events.custom;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.util.ColorUtil;
|
||||
import dev.viper.eventengine.model.EventCategory;
|
||||
import dev.viper.eventengine.model.EventDefinition;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Geführter CLI-Wizard für Admins zum Erstellen von Custom Events.
|
||||
*
|
||||
* Ablauf:
|
||||
* /event create <id> → Startet den Wizard
|
||||
* → Spieler antwortet auf Fragen über Chat
|
||||
*
|
||||
* Wird über EventCreateListener empfangen.
|
||||
*/
|
||||
public class CustomEventBuilder {
|
||||
|
||||
public enum Step {
|
||||
DISPLAY_NAME,
|
||||
DESCRIPTION,
|
||||
CATEGORY,
|
||||
DURATION,
|
||||
MIN_PLAYERS,
|
||||
MAX_PLAYERS,
|
||||
ANNOUNCEMENT,
|
||||
START_COMMANDS,
|
||||
END_COMMANDS,
|
||||
REWARDS,
|
||||
CONFIRM
|
||||
}
|
||||
|
||||
private final EventEngine plugin;
|
||||
private final Player player;
|
||||
private final EventDefinition def;
|
||||
private Step currentStep;
|
||||
|
||||
public CustomEventBuilder(EventEngine plugin, Player player, String id) {
|
||||
this.plugin = plugin;
|
||||
this.player = player;
|
||||
this.def = new EventDefinition(id.toLowerCase());
|
||||
this.currentStep = Step.DISPLAY_NAME;
|
||||
promptCurrentStep();
|
||||
}
|
||||
|
||||
// ─── Eingabe verarbeiten ───────────────────────────────────────────────
|
||||
|
||||
public boolean handleInput(String input) {
|
||||
switch (currentStep) {
|
||||
case DISPLAY_NAME -> {
|
||||
def.setDisplayName(input);
|
||||
advance();
|
||||
}
|
||||
case DESCRIPTION -> {
|
||||
def.setDescription(input);
|
||||
advance();
|
||||
}
|
||||
case CATEGORY -> {
|
||||
try {
|
||||
EventCategory cat = EventCategory.valueOf(input.toUpperCase());
|
||||
def.setCategory(cat);
|
||||
advance();
|
||||
} catch (Exception e) {
|
||||
sendError("Ungültige Kategorie. Wähle: " + getCategoryList());
|
||||
}
|
||||
}
|
||||
case DURATION -> {
|
||||
if (input.equalsIgnoreCase("skip") || input.equals("0")) {
|
||||
def.setDurationSeconds(0);
|
||||
advance();
|
||||
} else {
|
||||
try {
|
||||
int sec = Integer.parseInt(input);
|
||||
if (sec < 0) throw new NumberFormatException();
|
||||
def.setDurationSeconds(sec);
|
||||
advance();
|
||||
} catch (NumberFormatException e) {
|
||||
sendError("Bitte eine Zahl in Sekunden eingeben (0 = unbegrenzt).");
|
||||
}
|
||||
}
|
||||
}
|
||||
case MIN_PLAYERS -> {
|
||||
try {
|
||||
int n = Integer.parseInt(input);
|
||||
if (n < 1) throw new NumberFormatException();
|
||||
def.setMinPlayers(n);
|
||||
advance();
|
||||
} catch (NumberFormatException e) {
|
||||
sendError("Bitte eine Zahl ≥ 1 eingeben.");
|
||||
}
|
||||
}
|
||||
case MAX_PLAYERS -> {
|
||||
try {
|
||||
int n = Integer.parseInt(input);
|
||||
if (n < def.getMinPlayers()) throw new NumberFormatException();
|
||||
def.setMaxPlayers(n);
|
||||
advance();
|
||||
} catch (NumberFormatException e) {
|
||||
sendError("Bitte eine Zahl ≥ " + def.getMinPlayers() + " eingeben.");
|
||||
}
|
||||
}
|
||||
case ANNOUNCEMENT -> {
|
||||
if (input.equalsIgnoreCase("skip")) {
|
||||
// Default beibehalten
|
||||
} else {
|
||||
def.setAnnouncement(ColorUtil.color(input));
|
||||
}
|
||||
advance();
|
||||
}
|
||||
case START_COMMANDS -> {
|
||||
if (!input.equalsIgnoreCase("skip")) {
|
||||
List<String> cmds = parseCommandList(input);
|
||||
def.setStartCommands(cmds);
|
||||
}
|
||||
advance();
|
||||
}
|
||||
case END_COMMANDS -> {
|
||||
if (!input.equalsIgnoreCase("skip")) {
|
||||
List<String> cmds = parseCommandList(input);
|
||||
def.setEndCommands(cmds);
|
||||
}
|
||||
advance();
|
||||
}
|
||||
case REWARDS -> {
|
||||
if (!input.equalsIgnoreCase("skip")) {
|
||||
List<String> rewards = parseCommandList(input);
|
||||
def.setRewards(rewards);
|
||||
}
|
||||
advance();
|
||||
}
|
||||
case CONFIRM -> {
|
||||
if (input.equalsIgnoreCase("ja") || input.equalsIgnoreCase("yes")) {
|
||||
plugin.getEventRegistry().register(def);
|
||||
send("§a✔ Custom Event §e'" + def.getDisplayName() + "' §awurde erstellt und gespeichert!");
|
||||
send("§7ID: §f" + def.getId() + " §8| §7Start: §f/event start " + def.getId());
|
||||
return true; // fertig
|
||||
} else {
|
||||
send("§cAbgebrochen. Das Event wurde nicht gespeichert.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false; // noch nicht fertig
|
||||
}
|
||||
|
||||
// ─── Navigation ────────────────────────────────────────────────────────
|
||||
|
||||
private void advance() {
|
||||
Step[] steps = Step.values();
|
||||
int idx = currentStep.ordinal() + 1;
|
||||
if (idx < steps.length) {
|
||||
currentStep = steps[idx];
|
||||
promptCurrentStep();
|
||||
}
|
||||
}
|
||||
|
||||
private void promptCurrentStep() {
|
||||
String p = plugin.prefix();
|
||||
switch (currentStep) {
|
||||
case DISPLAY_NAME -> send(p + "§e[1/10] §7Anzeigename des Events: §f(z.B. 'Mein Spaß-Event')");
|
||||
case DESCRIPTION -> send(p + "§e[2/10] §7Beschreibung: §f(kurze Info was passiert)");
|
||||
case CATEGORY -> send(p + "§e[3/10] §7Kategorie: §f" + getCategoryList());
|
||||
case DURATION -> send(p + "§e[4/10] §7Dauer in Sekunden: §f(0 oder 'skip' = unbegrenzt)");
|
||||
case MIN_PLAYERS -> send(p + "§e[5/10] §7Mindestspieler: §f(Standard: 1)");
|
||||
case MAX_PLAYERS -> send(p + "§e[6/10] §7Maximale Spieler: §f(Standard: 50)");
|
||||
case ANNOUNCEMENT -> send(p + "§e[7/10] §7Ankündigungstext: §f(oder 'skip' für Standard, &c = Farbe)");
|
||||
case START_COMMANDS -> send(p + "§e[8/10] §7Start-Befehle: §f(kommagetrennt, %player%=Spieler, oder 'skip')");
|
||||
case END_COMMANDS -> send(p + "§e[9/10] §7End-Befehle: §f(kommagetrennt, oder 'skip')");
|
||||
case REWARDS -> send(p + "§e[10/10] §7Belohnungen: §f(Befehle pro Teilnehmer, %player%, oder 'skip')");
|
||||
case CONFIRM -> {
|
||||
sendSummary();
|
||||
send(p + "§eSpeichern? §a[ja] §c[nein]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendSummary() {
|
||||
send("§8§m══════════════════════════════");
|
||||
send("§6 Event Zusammenfassung");
|
||||
send("§7 ID: §f" + def.getId());
|
||||
send("§7 Name: §f" + def.getDisplayName());
|
||||
send("§7 Kategorie: §f" + def.getCategory().getDisplayName());
|
||||
send("§7 Dauer: §f" + (def.getDurationSeconds() == 0 ? "∞" : def.getDurationSeconds() + "s"));
|
||||
send("§7 Spieler: §f" + def.getMinPlayers() + "–" + def.getMaxPlayers());
|
||||
send("§7 Start-Befehle: §f" + def.getStartCommands().size());
|
||||
send("§7 Belohnungen: §f" + def.getRewards().size());
|
||||
send("§8§m══════════════════════════════");
|
||||
}
|
||||
|
||||
// ─── Hilfsmethoden ─────────────────────────────────────────────────────
|
||||
|
||||
private List<String> parseCommandList(String input) {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (String part : input.split(",")) {
|
||||
String trimmed = part.trim();
|
||||
if (!trimmed.isEmpty()) result.add(trimmed);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getCategoryList() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (EventCategory cat : EventCategory.values()) {
|
||||
if (sb.length() > 0) sb.append("§7, ");
|
||||
sb.append("§e").append(cat.name());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void send(String msg) { player.sendMessage(msg); }
|
||||
private void sendError(String msg) { player.sendMessage("§c✗ " + msg); }
|
||||
|
||||
public Step getCurrentStep() { return currentStep; }
|
||||
public EventDefinition getDef() { return def; }
|
||||
public Player getPlayer() { return player; }
|
||||
}
|
||||
225
src/main/java/dev/viper/eventengine/gui/EventGUI.java
Normal file
225
src/main/java/dev/viper/eventengine/gui/EventGUI.java
Normal file
@@ -0,0 +1,225 @@
|
||||
package dev.viper.eventengine.gui;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.EventCategory;
|
||||
import dev.viper.eventengine.model.EventDefinition;
|
||||
import dev.viper.eventengine.manager.EventManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Haupt-GUI für EventEngine:
|
||||
* Seite 1 → Kategorien-Übersicht
|
||||
* Seite 2 → Events der gewählten Kategorie
|
||||
* Klick auf Event → Startet das Event (Admin)
|
||||
*/
|
||||
public class EventGUI implements Listener {
|
||||
|
||||
private static final String MAIN_TITLE = "§8✦ §6EventEngine §8✦ Kategorien";
|
||||
private static final String EVENT_TITLE_PREFIX = "§8✦ §6Events: ";
|
||||
|
||||
private final EventEngine plugin;
|
||||
// Welche Kategorie der Spieler gerade betrachtet
|
||||
private final Map<UUID, EventCategory> categoryView = new HashMap<>();
|
||||
// Welche Seite der Spieler bei Events ist
|
||||
private final Map<UUID, Integer> pagemap = new HashMap<>();
|
||||
|
||||
public EventGUI(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
// ─── Öffnen ────────────────────────────────────────────────────────────
|
||||
|
||||
public void openMain(Player player) {
|
||||
Inventory inv = Bukkit.createInventory(null, 54, MAIN_TITLE);
|
||||
fillBorder(inv, Material.BLACK_STAINED_GLASS_PANE);
|
||||
|
||||
// Kategorien anzeigen
|
||||
EventCategory[] cats = EventCategory.values();
|
||||
int[] slots = {10, 11, 12, 13, 14, 15, 16, 28, 29, 30};
|
||||
for (int i = 0; i < cats.length && i < slots.length; i++) {
|
||||
EventCategory cat = cats[i];
|
||||
long count = plugin.getEventRegistry().getAll().stream()
|
||||
.filter(d -> d.getCategory() == cat).count();
|
||||
ItemStack item = makeItem(cat.getIcon(),
|
||||
"§6" + cat.getDisplayName(),
|
||||
Arrays.asList("§7" + count + " Events", "", "§eKlicken zum Anzeigen"));
|
||||
inv.setItem(slots[i], item);
|
||||
}
|
||||
|
||||
// Status-Info
|
||||
String statusText;
|
||||
if (plugin.getEventManager().isRunning()) {
|
||||
statusText = "§a▶ Läuft: §f" + plugin.getEventManager().getCurrentEvent().getDefinition().getDisplayName();
|
||||
} else {
|
||||
statusText = "§7Kein Event aktiv";
|
||||
}
|
||||
ItemStack status = makeItem(Material.CLOCK, "§eStatus", Arrays.asList(statusText,
|
||||
"§7Gesamt Events: §f" + plugin.getEventRegistry().count()));
|
||||
inv.setItem(4, status);
|
||||
|
||||
// Zufälliges Event starten
|
||||
ItemStack random = makeItem(Material.ENDER_PEARL, "§d✦ Zufälliges Event",
|
||||
Arrays.asList("§7Startet ein zufälliges Event", "§7aus der Rotation.", "", "§eKlicken"));
|
||||
inv.setItem(40, random);
|
||||
|
||||
player.openInventory(inv);
|
||||
}
|
||||
|
||||
public void openCategory(Player player, EventCategory category, int page) {
|
||||
List<EventDefinition> events = plugin.getEventRegistry().getByCategory(category);
|
||||
int perPage = 28;
|
||||
int totalPages = Math.max(1, (int) Math.ceil(events.size() / (double) perPage));
|
||||
page = Math.max(0, Math.min(page, totalPages - 1));
|
||||
|
||||
categoryView.put(player.getUniqueId(), category);
|
||||
pagemap.put(player.getUniqueId(), page);
|
||||
|
||||
String title = EVENT_TITLE_PREFIX + category.getDisplayName() + " §8(" + (page + 1) + "/" + totalPages + ")";
|
||||
Inventory inv = Bukkit.createInventory(null, 54, title);
|
||||
fillBorder(inv, Material.GRAY_STAINED_GLASS_PANE);
|
||||
|
||||
List<EventDefinition> pageEvents = events.stream()
|
||||
.skip((long) page * perPage)
|
||||
.limit(perPage)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
int[] contentSlots = buildContentSlots();
|
||||
for (int i = 0; i < pageEvents.size() && i < contentSlots.length; i++) {
|
||||
EventDefinition def = pageEvents.get(i);
|
||||
List<String> lore = new ArrayList<>();
|
||||
lore.add("§7" + def.getDescription());
|
||||
lore.add("");
|
||||
lore.add("§7Dauer: §f" + EventManager.formatTime(def.getDurationSeconds()));
|
||||
lore.add("§7Spieler: §f" + def.getMinPlayers() + "–" + def.getMaxPlayers());
|
||||
if (def.isCustom()) lore.add("§d✦ Custom Event");
|
||||
lore.add("");
|
||||
lore.add("§aKlicken zum Starten");
|
||||
|
||||
Material icon = def.getCategory().getIcon();
|
||||
if (plugin.getEventManager().isRunning() &&
|
||||
plugin.getEventManager().getCurrentEvent().getDefinition().getId().equals(def.getId())) {
|
||||
icon = Material.LIME_CONCRETE;
|
||||
}
|
||||
inv.setItem(contentSlots[i], makeItem(icon, "§e" + def.getDisplayName(), lore));
|
||||
}
|
||||
|
||||
// Navigation
|
||||
if (page > 0) {
|
||||
inv.setItem(45, makeItem(Material.ARROW, "§7◀ Zurück", List.of("§7Seite " + page)));
|
||||
}
|
||||
inv.setItem(49, makeItem(Material.BARRIER, "§c← Hauptmenü", List.of("§7Zurück zur Kategorien-Übersicht")));
|
||||
if (page < totalPages - 1) {
|
||||
inv.setItem(53, makeItem(Material.ARROW, "§7Weiter ▶", List.of("§7Seite " + (page + 2))));
|
||||
}
|
||||
|
||||
player.openInventory(inv);
|
||||
}
|
||||
|
||||
// ─── Click-Handler ─────────────────────────────────────────────────────
|
||||
|
||||
@EventHandler
|
||||
public void onClick(InventoryClickEvent event) {
|
||||
if (!(event.getWhoClicked() instanceof Player player)) return;
|
||||
String title = event.getView().getTitle();
|
||||
if (!title.startsWith("§8✦ §6EventEngine") && !title.startsWith(EVENT_TITLE_PREFIX)) return;
|
||||
|
||||
event.setCancelled(true);
|
||||
ItemStack clicked = event.getCurrentItem();
|
||||
if (clicked == null || clicked.getType() == Material.AIR) return;
|
||||
if (clicked.getType() == Material.BLACK_STAINED_GLASS_PANE ||
|
||||
clicked.getType() == Material.GRAY_STAINED_GLASS_PANE) return;
|
||||
|
||||
String itemName = ChatColor.stripColor(clicked.getItemMeta() != null ?
|
||||
clicked.getItemMeta().getDisplayName() : "");
|
||||
|
||||
if (title.equals(MAIN_TITLE)) {
|
||||
handleMainClick(player, itemName, clicked);
|
||||
} else {
|
||||
handleCategoryClick(player, title, itemName, clicked, event.getSlot());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMainClick(Player player, String itemName, ItemStack item) {
|
||||
if (itemName.equals("✦ Zufälliges Event")) {
|
||||
plugin.getEventRegistry().getWeightedRandom()
|
||||
.ifPresent(def -> plugin.getEventManager().startEvent(def, player));
|
||||
player.closeInventory();
|
||||
return;
|
||||
}
|
||||
// Kategorien-Match
|
||||
for (EventCategory cat : EventCategory.values()) {
|
||||
if (item.getType() == cat.getIcon()) {
|
||||
openCategory(player, cat, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCategoryClick(Player player, String title, String itemName, ItemStack item, int slot) {
|
||||
if (item.getType() == Material.BARRIER) {
|
||||
openMain(player);
|
||||
return;
|
||||
}
|
||||
if (item.getType() == Material.ARROW) {
|
||||
EventCategory cat = categoryView.get(player.getUniqueId());
|
||||
int page = pagemap.getOrDefault(player.getUniqueId(), 0);
|
||||
if (slot == 45) openCategory(player, cat, page - 1);
|
||||
else openCategory(player, cat, page + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Event-Klick: Name raussuchen
|
||||
String stripped = itemName.trim();
|
||||
plugin.getEventRegistry().getAll().stream()
|
||||
.filter(d -> d.getDisplayName().equals(stripped))
|
||||
.findFirst()
|
||||
.ifPresent(def -> {
|
||||
player.closeInventory();
|
||||
plugin.getEventManager().startEvent(def, player);
|
||||
});
|
||||
}
|
||||
|
||||
// ─── Utility ───────────────────────────────────────────────────────────
|
||||
|
||||
private ItemStack makeItem(Material mat, String name, List<String> lore) {
|
||||
ItemStack item = new ItemStack(mat);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta == null) return item;
|
||||
meta.setDisplayName(name);
|
||||
meta.setLore(lore);
|
||||
item.setItemMeta(meta);
|
||||
return item;
|
||||
}
|
||||
|
||||
private void fillBorder(Inventory inv, Material mat) {
|
||||
ItemStack glass = makeItem(mat, " ", List.of());
|
||||
int size = inv.getSize();
|
||||
for (int i = 0; i < 9; i++) inv.setItem(i, glass);
|
||||
for (int i = size - 9; i < size; i++) inv.setItem(i, glass);
|
||||
for (int i = 9; i < size - 9; i += 9) inv.setItem(i, glass);
|
||||
for (int i = 17; i < size - 9; i += 9) inv.setItem(i, glass);
|
||||
}
|
||||
|
||||
private int[] buildContentSlots() {
|
||||
// Slots 10-16, 19-25, 28-34, 37-43 (ohne Rand)
|
||||
List<Integer> slots = new ArrayList<>();
|
||||
for (int row = 1; row <= 4; row++) {
|
||||
for (int col = 1; col <= 7; col++) {
|
||||
slots.add(row * 9 + col);
|
||||
}
|
||||
}
|
||||
return slots.stream().mapToInt(Integer::intValue).toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package dev.viper.eventengine.listener;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.events.custom.CustomEventBuilder;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Leitet Chat-Nachrichten von Admins im Builder-Modus an CustomEventBuilder weiter.
|
||||
*/
|
||||
public class EventCreateListener implements Listener {
|
||||
|
||||
private final EventEngine plugin;
|
||||
// Laufende Builder-Sessions
|
||||
private final Map<UUID, CustomEventBuilder> sessions = new HashMap<>();
|
||||
|
||||
public EventCreateListener(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void startSession(Player player, String id) {
|
||||
if (sessions.containsKey(player.getUniqueId())) {
|
||||
player.sendMessage(plugin.prefix() + "§cDu hast bereits einen laufenden Builder. Schreibe 'abbrechen' um ihn zu stoppen.");
|
||||
return;
|
||||
}
|
||||
sessions.put(player.getUniqueId(), new CustomEventBuilder(plugin, player, id));
|
||||
}
|
||||
|
||||
public boolean hasSession(Player player) {
|
||||
return sessions.containsKey(player.getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onChat(AsyncPlayerChatEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
CustomEventBuilder builder = sessions.get(player.getUniqueId());
|
||||
if (builder == null) return;
|
||||
|
||||
event.setCancelled(true); // Eingabe nicht im globalen Chat zeigen
|
||||
String input = event.getMessage().trim();
|
||||
|
||||
if (input.equalsIgnoreCase("abbrechen") || input.equalsIgnoreCase("cancel")) {
|
||||
sessions.remove(player.getUniqueId());
|
||||
player.sendMessage(plugin.prefix() + "§cEvent-Builder abgebrochen.");
|
||||
return;
|
||||
}
|
||||
|
||||
// An Builder weitergeben — synchron auf Main-Thread
|
||||
plugin.getServer().getScheduler().runTask(plugin, () -> {
|
||||
boolean done = builder.handleInput(input);
|
||||
if (done) sessions.remove(player.getUniqueId());
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event) {
|
||||
sessions.remove(event.getPlayer().getUniqueId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package dev.viper.eventengine.listener;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import dev.viper.eventengine.model.EventRegion;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
|
||||
/**
|
||||
* Schützt Event-Regionen während laufender Events:
|
||||
*
|
||||
* 1. TNT / Explosionen → kein Block-Schaden innerhalb der Region
|
||||
* 2. Spieler die die Region verlassen → werden zurückteleportiert
|
||||
* 3. Block-Interaktionen außerhalb der Region durch Teilnehmer → geblockt
|
||||
*/
|
||||
public class EventProtectionListener implements Listener {
|
||||
|
||||
private final EventEngine plugin;
|
||||
|
||||
public EventProtectionListener(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
// ─── 1. Explosionen (TNT, Creeper, Ghast, ...) ────────────────────────
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onExplode(EntityExplodeEvent e) {
|
||||
ActiveEvent active = plugin.getEventManager().getCurrentEvent();
|
||||
|
||||
// Immer wenn ein Event läuft: TNT-Blockschaden deaktivieren
|
||||
if (active == null) return;
|
||||
if (!plugin.getConfigManager().isNoExplosionBlockDamage()) return;
|
||||
|
||||
EventRegion region = active.getDefinition().getRegion();
|
||||
|
||||
if (region != null) {
|
||||
// Nur Blöcke INNERHALB der Region schützen — Explosion außerhalb normal
|
||||
e.blockList().removeIf(block -> region.contains(block.getLocation()));
|
||||
} else {
|
||||
// Kein Region definiert → global während Event kein Block-Schaden durch Explosionen
|
||||
e.blockList().clear();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onEntityDamageByExplosion(EntityDamageEvent e) {
|
||||
// Spieler-Schaden durch Explosionen während Events: behalten (nur Block-Schaden deaktiviert)
|
||||
// Nichts tun — Spieler sollen Schaden nehmen können
|
||||
}
|
||||
|
||||
// ─── 2. Spieler-Bewegung: Region-Grenze prüfen ────────────────────────
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onMove(PlayerMoveEvent e) {
|
||||
Player player = e.getPlayer();
|
||||
ActiveEvent active = plugin.getEventManager().getCurrentEvent();
|
||||
if (active == null) return;
|
||||
|
||||
// Nur für Event-Teilnehmer
|
||||
if (!active.isParticipant(player)) return;
|
||||
|
||||
EventRegion region = active.getDefinition().getRegion();
|
||||
if (region == null) return; // keine Region → frei bewegen
|
||||
if (!plugin.getConfigManager().isEnforceRegionBoundary()) return;
|
||||
|
||||
Location to = e.getTo();
|
||||
if (to == null) return;
|
||||
|
||||
// Nur prüfen wenn Spieler Block-Grenze überschreitet (Performance)
|
||||
if (e.getFrom().getBlockX() == to.getBlockX()
|
||||
&& e.getFrom().getBlockY() == to.getBlockY()
|
||||
&& e.getFrom().getBlockZ() == to.getBlockZ()) return;
|
||||
|
||||
if (!region.contains(to)) {
|
||||
// Zurückteleportieren zur letzten gültigen Position
|
||||
e.setCancelled(true);
|
||||
player.sendActionBar("§c⚠ Du kannst die Event-Arena nicht verlassen!");
|
||||
}
|
||||
}
|
||||
|
||||
// ─── 3. Block-Break/Place außerhalb der Region ────────────────────────
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onBlockBreak(BlockBreakEvent e) {
|
||||
Player player = e.getPlayer();
|
||||
ActiveEvent active = plugin.getEventManager().getCurrentEvent();
|
||||
if (active == null) return;
|
||||
if (!active.isParticipant(player)) return;
|
||||
|
||||
EventRegion region = active.getDefinition().getRegion();
|
||||
if (region == null) return;
|
||||
if (!plugin.getConfigManager().isRestrictBlockInteraction()) return;
|
||||
|
||||
if (!region.contains(e.getBlock().getLocation())) {
|
||||
e.setCancelled(true);
|
||||
player.sendActionBar("§c⚠ Du kannst außerhalb der Event-Arena keine Blöcke abbauen!");
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onBlockPlace(BlockPlaceEvent e) {
|
||||
Player player = e.getPlayer();
|
||||
ActiveEvent active = plugin.getEventManager().getCurrentEvent();
|
||||
if (active == null) return;
|
||||
if (!active.isParticipant(player)) return;
|
||||
|
||||
EventRegion region = active.getDefinition().getRegion();
|
||||
if (region == null) return;
|
||||
if (!plugin.getConfigManager().isRestrictBlockInteraction()) return;
|
||||
|
||||
if (!region.contains(e.getBlock().getLocation())) {
|
||||
e.setCancelled(true);
|
||||
player.sendActionBar("§c⚠ Du kannst außerhalb der Event-Arena keine Blöcke setzen!");
|
||||
}
|
||||
}
|
||||
}
|
||||
188
src/main/java/dev/viper/eventengine/manager/EventManager.java
Normal file
188
src/main/java/dev/viper/eventengine/manager/EventManager.java
Normal file
@@ -0,0 +1,188 @@
|
||||
package dev.viper.eventengine.manager;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.events.builtin.EventHandlerRegistry;
|
||||
import dev.viper.eventengine.events.builtin.IEventHandler;
|
||||
import dev.viper.eventengine.model.ActiveEvent;
|
||||
import dev.viper.eventengine.model.EventDefinition;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Steuert den Lebenszyklus von Events:
|
||||
* start → announce → run → end → reward
|
||||
*/
|
||||
public class EventManager {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private final Logger log;
|
||||
private final EventHandlerRegistry handlerRegistry;
|
||||
|
||||
private ActiveEvent currentEvent = null;
|
||||
private final Deque<EventDefinition> queue = new ArrayDeque<>();
|
||||
|
||||
public EventManager(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
this.log = plugin.getLogger();
|
||||
this.handlerRegistry = new EventHandlerRegistry(plugin);
|
||||
}
|
||||
|
||||
public boolean startEvent(EventDefinition def, Player initiator) {
|
||||
if (currentEvent != null && currentEvent.getState() != ActiveEvent.State.ENDED) {
|
||||
if (initiator != null)
|
||||
initiator.sendMessage(plugin.prefix() + "§cEin Event läuft bereits: §e"
|
||||
+ currentEvent.getDefinition().getDisplayName());
|
||||
return false;
|
||||
}
|
||||
|
||||
currentEvent = new ActiveEvent(def);
|
||||
currentEvent.setState(ActiveEvent.State.RUNNING);
|
||||
|
||||
broadcast(def.getAnnouncement());
|
||||
if (def.getDurationSeconds() > 0)
|
||||
broadcast(plugin.prefix() + "§7Dauer: §e" + formatTime(def.getDurationSeconds()));
|
||||
|
||||
if (plugin.getConfigManager().isLogEvents()) {
|
||||
String by = initiator != null ? initiator.getName() : "Zeitplan";
|
||||
log.info("Event gestartet von " + by + ": " + def.getDisplayName());
|
||||
}
|
||||
|
||||
runCommands(def.getStartCommands(), null);
|
||||
handlerRegistry.get(def.getType()).ifPresent(h -> h.onStart(currentEvent));
|
||||
|
||||
if (def.getDurationSeconds() > 0) {
|
||||
final ActiveEvent snap = currentEvent;
|
||||
if (def.getDurationSeconds() > 70)
|
||||
new BukkitRunnable() { @Override public void run() {
|
||||
if (currentEvent == snap && currentEvent.getState() == ActiveEvent.State.RUNNING)
|
||||
broadcast(plugin.prefix() + "§e⏰ Noch §c60 Sekunden §ebis das Event endet!");
|
||||
}}.runTaskLater(plugin, (def.getDurationSeconds() - 60) * 20L);
|
||||
|
||||
if (def.getDurationSeconds() > 15)
|
||||
new BukkitRunnable() { @Override public void run() {
|
||||
if (currentEvent == snap && currentEvent.getState() == ActiveEvent.State.RUNNING)
|
||||
broadcast(plugin.prefix() + "§c⏰ Noch 10 Sekunden!");
|
||||
}}.runTaskLater(plugin, (def.getDurationSeconds() - 10) * 20L);
|
||||
|
||||
int taskId = (int) new BukkitRunnable() { @Override public void run() {
|
||||
if (currentEvent == snap && currentEvent.getState() == ActiveEvent.State.RUNNING)
|
||||
endEvent("Zeit abgelaufen");
|
||||
}}.runTaskLater(plugin, def.getDurationSeconds() * 20L).getTaskId();
|
||||
currentEvent.setTaskId(taskId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean endEvent(String reason) {
|
||||
if (currentEvent == null || currentEvent.getState() == ActiveEvent.State.ENDED) return false;
|
||||
|
||||
EventDefinition def = currentEvent.getDefinition();
|
||||
currentEvent.setState(ActiveEvent.State.ENDED);
|
||||
|
||||
if (currentEvent.getTaskId() != -1)
|
||||
Bukkit.getScheduler().cancelTask(currentEvent.getTaskId());
|
||||
|
||||
handlerRegistry.get(def.getType()).ifPresent(h -> h.onEnd(currentEvent));
|
||||
|
||||
broadcast(plugin.prefix() + "§6✦ §e" + def.getDisplayName()
|
||||
+ " §7ist beendet! §7(" + reason + ")");
|
||||
showLeaderboard();
|
||||
runCommands(def.getEndCommands(), null);
|
||||
distributeRewards(def);
|
||||
|
||||
if (plugin.getConfigManager().isLogEvents())
|
||||
log.info("Event beendet: " + def.getDisplayName() + " [" + reason + "]");
|
||||
|
||||
currentEvent = null;
|
||||
|
||||
if (!queue.isEmpty()) {
|
||||
EventDefinition next = queue.poll();
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> startEvent(next, null), 100L);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean join(Player player) {
|
||||
if (currentEvent == null || currentEvent.getState() == ActiveEvent.State.ENDED) {
|
||||
player.sendMessage(plugin.prefix() + "§cKein Event aktiv."); return false;
|
||||
}
|
||||
if (currentEvent.isParticipant(player)) {
|
||||
player.sendMessage(plugin.prefix() + "§cDu nimmst bereits teil."); return false;
|
||||
}
|
||||
EventDefinition def = currentEvent.getDefinition();
|
||||
if (currentEvent.getParticipantCount() >= def.getMaxPlayers()) {
|
||||
player.sendMessage(plugin.prefix() + "§cDas Event ist voll!"); return false;
|
||||
}
|
||||
currentEvent.addParticipant(player);
|
||||
broadcast(plugin.prefix() + "§a" + player.getName() + " §7nimmt teil! §8("
|
||||
+ currentEvent.getParticipantCount() + "/" + def.getMaxPlayers() + ")");
|
||||
handlerRegistry.get(def.getType()).ifPresent(h -> h.onPlayerJoin(currentEvent, player));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void leave(Player player) {
|
||||
if (currentEvent == null) { player.sendMessage(plugin.prefix() + "§cKein Event aktiv."); return; }
|
||||
if (!currentEvent.isParticipant(player)) { player.sendMessage(plugin.prefix() + "§cDu nimmst nicht teil."); return; }
|
||||
currentEvent.removeParticipant(player);
|
||||
handlerRegistry.get(currentEvent.getDefinition().getType())
|
||||
.ifPresent(h -> h.onPlayerLeave(currentEvent, player));
|
||||
player.sendMessage(plugin.prefix() + "§7Du hast das Event verlassen.");
|
||||
}
|
||||
|
||||
private void showLeaderboard() {
|
||||
if (currentEvent == null) return;
|
||||
List<Map.Entry<UUID, Integer>> lb = currentEvent.getLeaderboard();
|
||||
if (lb.isEmpty()) return;
|
||||
broadcast("§8§m══════════════════════════════");
|
||||
broadcast("§6 🏆 Event Leaderboard §8– §e" + currentEvent.getDefinition().getDisplayName());
|
||||
int rank = 1;
|
||||
for (Map.Entry<UUID, Integer> e : lb) {
|
||||
if (rank > 5) break;
|
||||
Player p = Bukkit.getPlayer(e.getKey());
|
||||
String name = p != null ? p.getName() : "Unbekannt";
|
||||
String medal = switch (rank) { case 1 -> "§6🥇"; case 2 -> "§7🥈"; case 3 -> "§c🥉"; default -> "§7 " + rank + "."; };
|
||||
broadcast(" " + medal + " §f" + name + " §8– §e" + e.getValue() + " Punkte");
|
||||
rank++;
|
||||
}
|
||||
broadcast("§8§m══════════════════════════════");
|
||||
}
|
||||
|
||||
private void distributeRewards(EventDefinition def) {
|
||||
if (def.getRewards().isEmpty() || currentEvent == null) return;
|
||||
for (UUID uuid : currentEvent.getParticipants()) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p == null) continue;
|
||||
for (String cmd : def.getRewards())
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("%player%", p.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
private void runCommands(List<String> cmds, Player player) {
|
||||
for (String cmd : cmds) {
|
||||
String filled = player != null ? cmd.replace("%player%", player.getName()) : cmd;
|
||||
try { Bukkit.dispatchCommand(Bukkit.getConsoleSender(), filled); }
|
||||
catch (Exception ex) { log.warning("Befehl fehlgeschlagen: " + filled); }
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcast(String msg) { Bukkit.broadcastMessage(msg); }
|
||||
|
||||
public static String formatTime(int seconds) {
|
||||
if (seconds <= 0) return "∞";
|
||||
int m = seconds / 60, s = seconds % 60;
|
||||
if (m == 0) return s + "s";
|
||||
if (s == 0) return m + "m";
|
||||
return m + "m " + s + "s";
|
||||
}
|
||||
|
||||
public void enqueue(EventDefinition def) { queue.add(def); }
|
||||
public void clearQueue() { queue.clear(); }
|
||||
public int queueSize() { return queue.size(); }
|
||||
public ActiveEvent getCurrentEvent() { return currentEvent; }
|
||||
public boolean isRunning() { return currentEvent != null && currentEvent.getState() == ActiveEvent.State.RUNNING; }
|
||||
public EventHandlerRegistry getHandlerRegistry() { return handlerRegistry; }
|
||||
}
|
||||
142
src/main/java/dev/viper/eventengine/manager/EventRegistry.java
Normal file
142
src/main/java/dev/viper/eventengine/manager/EventRegistry.java
Normal file
@@ -0,0 +1,142 @@
|
||||
package dev.viper.eventengine.manager;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.util.ColorUtil;
|
||||
import dev.viper.eventengine.config.EventOverrideLoader;
|
||||
import dev.viper.eventengine.model.EventCategory;
|
||||
import dev.viper.eventengine.model.EventDefinition;
|
||||
import dev.viper.eventengine.model.EventType;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Zentrales Registry für alle EventDefinitions.
|
||||
* Enthält alle 100+ eingebauten Events und beliebig viele Custom-Events.
|
||||
*/
|
||||
public class EventRegistry {
|
||||
|
||||
private final EventEngine plugin;
|
||||
// Geordnete Map: id → Definition
|
||||
private final Map<String, EventDefinition> events = new LinkedHashMap<>();
|
||||
|
||||
public EventRegistry(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
// ─── Initialisierung ───────────────────────────────────────────────────
|
||||
|
||||
public void init() {
|
||||
events.clear();
|
||||
registerBuiltins();
|
||||
loadCustom();
|
||||
plugin.getLogger().info("EventRegistry: " + events.size() + " Events registriert.");
|
||||
}
|
||||
|
||||
private void registerBuiltins() {
|
||||
EventOverrideLoader overrideLoader = new EventOverrideLoader(plugin);
|
||||
for (EventType type : EventType.values()) {
|
||||
if (type == EventType.CUSTOM) continue;
|
||||
EventDefinition def = createBuiltin(type);
|
||||
overrideLoader.apply(def); // config.yml overrides anwenden
|
||||
events.put(def.getId(), def);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt eine EventDefinition mit sinnvollen Defaults pro Typ.
|
||||
* Hier können Standardwerte (Dauer, Spielerzahl) pro Event gesetzt werden.
|
||||
*/
|
||||
private EventDefinition createBuiltin(EventType type) {
|
||||
EventDefinition def = new EventDefinition(type);
|
||||
|
||||
// Spezifische Overrides pro Typ
|
||||
switch (type) {
|
||||
case PVP_ONE_VS_ONE -> { def.setMinPlayers(2); def.setMaxPlayers(2); }
|
||||
case PVP_TEAM_BATTLE -> { def.setMinPlayers(4); def.setMaxPlayers(40); }
|
||||
case PVP_UHC -> { def.setDurationSeconds(3600); def.setMinPlayers(4); }
|
||||
case PVP_HUNGER_GAMES -> { def.setDurationSeconds(1800); def.setMinPlayers(8); }
|
||||
case SURVIVAL_BOSS_RUSH -> { def.setDurationSeconds(600); def.setMinPlayers(1); }
|
||||
case SURVIVAL_WITHER_STORM -> { def.setDurationSeconds(900); def.setMinPlayers(2); }
|
||||
case BUILD_BATTLE -> { def.setDurationSeconds(300); def.setMinPlayers(2); }
|
||||
case BUILD_SPEED_BUILD -> { def.setDurationSeconds(120); def.setMinPlayers(1); }
|
||||
case RACE_PARKOUR -> { def.setDurationSeconds(180); def.setMinPlayers(1); }
|
||||
case FUN_DROP_PARTY -> { def.setDurationSeconds(60); def.setMinPlayers(1); def.setMaxPlayers(200); }
|
||||
case FUN_TNT_RAIN -> { def.setDurationSeconds(30); def.setMinPlayers(1); def.setMaxPlayers(200); }
|
||||
case QUIZ_SPEED_QUIZ -> { def.setDurationSeconds(120); def.setMinPlayers(1); }
|
||||
case ECONOMY_LOTTERY -> { def.setDurationSeconds(120); def.setMinPlayers(1); def.setMaxPlayers(200); }
|
||||
default -> { /* Defaults aus Konstruktor */ }
|
||||
}
|
||||
|
||||
// Ankündigungs-Texte
|
||||
def.setAnnouncement("&6✦ &e" + type.getDisplayName() + " &7[" + type.getCategory().getDisplayName() + "&7] &6startet jetzt! &7Viel Erfolg!");
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
private void loadCustom() {
|
||||
Map<String, EventDefinition> custom = plugin.getConfigManager().loadCustomEvents();
|
||||
events.putAll(custom);
|
||||
}
|
||||
|
||||
// ─── API ───────────────────────────────────────────────────────────────
|
||||
|
||||
public Optional<EventDefinition> get(String id) {
|
||||
return Optional.ofNullable(events.get(id.toLowerCase()));
|
||||
}
|
||||
|
||||
public Collection<EventDefinition> getAll() {
|
||||
return Collections.unmodifiableCollection(events.values());
|
||||
}
|
||||
|
||||
public List<EventDefinition> getByCategory(EventCategory category) {
|
||||
return events.values().stream()
|
||||
.filter(d -> d.getCategory() == category)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<EventDefinition> getRotation() {
|
||||
return events.values().stream()
|
||||
.filter(EventDefinition::isInRotation)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Wählt ein zufälliges Event aus der Rotation, gewichtet.
|
||||
*/
|
||||
public Optional<EventDefinition> getWeightedRandom() {
|
||||
List<EventDefinition> rotation = getRotation();
|
||||
if (rotation.isEmpty()) return Optional.empty();
|
||||
|
||||
int totalWeight = rotation.stream().mapToInt(EventDefinition::getWeight).sum();
|
||||
int roll = new Random().nextInt(Math.max(totalWeight, 1));
|
||||
int cumulative = 0;
|
||||
for (EventDefinition def : rotation) {
|
||||
cumulative += def.getWeight();
|
||||
if (roll < cumulative) return Optional.of(def);
|
||||
}
|
||||
return Optional.of(rotation.get(0));
|
||||
}
|
||||
|
||||
public void register(EventDefinition def) {
|
||||
events.put(def.getId().toLowerCase(), def);
|
||||
if (def.isCustom()) {
|
||||
plugin.getConfigManager().saveCustomEvent(def);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean remove(String id) {
|
||||
EventDefinition def = events.remove(id.toLowerCase());
|
||||
if (def != null && def.isCustom()) {
|
||||
plugin.getConfigManager().deleteCustomEvent(id);
|
||||
return true;
|
||||
}
|
||||
return def != null;
|
||||
}
|
||||
|
||||
public boolean exists(String id) {
|
||||
return events.containsKey(id.toLowerCase());
|
||||
}
|
||||
|
||||
public int count() { return events.size(); }
|
||||
}
|
||||
75
src/main/java/dev/viper/eventengine/model/ActiveEvent.java
Normal file
75
src/main/java/dev/viper/eventengine/model/ActiveEvent.java
Normal file
@@ -0,0 +1,75 @@
|
||||
package dev.viper.eventengine.model;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Repräsentiert eine aktuell laufende Event-Instanz.
|
||||
*/
|
||||
public class ActiveEvent {
|
||||
|
||||
public enum State { WAITING, RUNNING, ENDED }
|
||||
|
||||
private final EventDefinition definition;
|
||||
private State state;
|
||||
private final long startTime;
|
||||
private final Set<UUID> participants;
|
||||
private final Map<UUID, Integer> scores;
|
||||
private int taskId = -1;
|
||||
|
||||
public ActiveEvent(EventDefinition definition) {
|
||||
this.definition = definition;
|
||||
this.state = State.WAITING;
|
||||
this.startTime = System.currentTimeMillis();
|
||||
this.participants = new LinkedHashSet<>();
|
||||
this.scores = new HashMap<>();
|
||||
}
|
||||
|
||||
public void addParticipant(Player player) {
|
||||
participants.add(player.getUniqueId());
|
||||
scores.putIfAbsent(player.getUniqueId(), 0);
|
||||
}
|
||||
|
||||
public void removeParticipant(Player player) {
|
||||
participants.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
public boolean isParticipant(Player player) {
|
||||
return participants.contains(player.getUniqueId());
|
||||
}
|
||||
|
||||
public void addScore(UUID uuid, int points) {
|
||||
scores.merge(uuid, points, Integer::sum);
|
||||
}
|
||||
|
||||
public int getScore(UUID uuid) {
|
||||
return scores.getOrDefault(uuid, 0);
|
||||
}
|
||||
|
||||
/** Gibt Spieler sortiert nach Score zurück */
|
||||
public List<Map.Entry<UUID, Integer>> getLeaderboard() {
|
||||
List<Map.Entry<UUID, Integer>> entries = new ArrayList<>(scores.entrySet());
|
||||
entries.sort((a, b) -> b.getValue() - a.getValue());
|
||||
return entries;
|
||||
}
|
||||
|
||||
public long getElapsedSeconds() {
|
||||
return (System.currentTimeMillis() - startTime) / 1000;
|
||||
}
|
||||
|
||||
public long getRemainingSeconds() {
|
||||
if (definition.getDurationSeconds() == 0) return -1;
|
||||
long remaining = definition.getDurationSeconds() - getElapsedSeconds();
|
||||
return Math.max(0, remaining);
|
||||
}
|
||||
|
||||
public EventDefinition getDefinition() { return definition; }
|
||||
public State getState() { return state; }
|
||||
public void setState(State state) { this.state = state; }
|
||||
public Set<UUID> getParticipants() { return Collections.unmodifiableSet(participants); }
|
||||
public Map<UUID, Integer> getScores() { return scores; }
|
||||
public int getTaskId() { return taskId; }
|
||||
public void setTaskId(int taskId) { this.taskId = taskId; }
|
||||
public int getParticipantCount() { return participants.size(); }
|
||||
}
|
||||
27
src/main/java/dev/viper/eventengine/model/EventCategory.java
Normal file
27
src/main/java/dev/viper/eventengine/model/EventCategory.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package dev.viper.eventengine.model;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
public enum EventCategory {
|
||||
COMBAT("⚔ Kampf", Material.DIAMOND_SWORD),
|
||||
SURVIVAL("🌲 Überleben", Material.COOKED_BEEF),
|
||||
BUILDING("🏗 Bauen", Material.BRICKS),
|
||||
RACING("🏁 Rennen", Material.GOLDEN_BOOTS),
|
||||
COLLECTION("📦 Sammeln", Material.CHEST),
|
||||
FUN("🎉 Spaß", Material.FIREWORK_ROCKET),
|
||||
QUIZ("❓ Quiz", Material.BOOK),
|
||||
ECONOMY("💰 Wirtschaft", Material.GOLD_INGOT),
|
||||
TEAM("👥 Team", Material.YELLOW_BANNER),
|
||||
CUSTOM("⭐ Custom", Material.COMMAND_BLOCK);
|
||||
|
||||
private final String displayName;
|
||||
private final Material icon;
|
||||
|
||||
EventCategory(String displayName, Material icon) {
|
||||
this.displayName = displayName;
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public String getDisplayName() { return displayName; }
|
||||
public Material getIcon() { return icon; }
|
||||
}
|
||||
191
src/main/java/dev/viper/eventengine/model/EventDefinition.java
Normal file
191
src/main/java/dev/viper/eventengine/model/EventDefinition.java
Normal file
@@ -0,0 +1,191 @@
|
||||
package dev.viper.eventengine.model;
|
||||
|
||||
import dev.viper.eventengine.util.ColorUtil;
|
||||
import dev.viper.eventengine.model.EventRegion;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Repräsentiert ein einzelnes Event — sowohl eingebaute als auch Custom-Events.
|
||||
* Custom-Events werden in custom_events.yml gespeichert.
|
||||
*/
|
||||
public class EventDefinition {
|
||||
|
||||
private final String id;
|
||||
private String displayName;
|
||||
private String description;
|
||||
private EventType type;
|
||||
private EventCategory category;
|
||||
|
||||
// Zeitlimit in Sekunden (0 = unbegrenzt)
|
||||
private int durationSeconds;
|
||||
// Mindest-/Höchst-Spielerzahl
|
||||
private int minPlayers;
|
||||
private int maxPlayers;
|
||||
// Befehle die beim Start/Ende ausgeführt werden
|
||||
private List<String> startCommands;
|
||||
private List<String> endCommands;
|
||||
// Belohnungen
|
||||
private List<String> rewards;
|
||||
// Ankündigungs-Text
|
||||
private String announcement;
|
||||
// Ob das Event in der Rotation ist
|
||||
private boolean inRotation;
|
||||
// Gewichtung in der Rotation
|
||||
private int weight;
|
||||
// Custom-Einstellungen (Key-Value)
|
||||
private Map<String, Object> customSettings;
|
||||
// Ist es ein benutzerdefiniertes Event?
|
||||
private boolean isCustom;
|
||||
// Optionale Event-Region (null = gesamte Welt)
|
||||
private EventRegion region;
|
||||
|
||||
// ─── Konstruktor für builtin Events ────────────────────────────────────
|
||||
public EventDefinition(EventType type) {
|
||||
this.id = type.name().toLowerCase();
|
||||
this.type = type;
|
||||
this.category = type.getCategory();
|
||||
this.displayName = type.getDisplayName();
|
||||
this.description = "Ein " + type.getDisplayName() + " Event.";
|
||||
this.durationSeconds = 300;
|
||||
this.minPlayers = 2;
|
||||
this.maxPlayers = 50;
|
||||
this.startCommands = new ArrayList<>();
|
||||
this.endCommands = new ArrayList<>();
|
||||
this.rewards = new ArrayList<>();
|
||||
this.announcement = ColorUtil.color("&6✦ &e" + displayName + " &6startet jetzt!");
|
||||
this.inRotation = true;
|
||||
this.weight = 1;
|
||||
this.customSettings = new HashMap<>();
|
||||
this.isCustom = false;
|
||||
}
|
||||
|
||||
// ─── Konstruktor für Custom Events ─────────────────────────────────────
|
||||
public EventDefinition(String id) {
|
||||
this.id = id;
|
||||
this.type = EventType.CUSTOM;
|
||||
this.category = EventCategory.CUSTOM;
|
||||
this.displayName = id;
|
||||
this.description = "Benutzerdefiniertes Event.";
|
||||
this.durationSeconds = 300;
|
||||
this.minPlayers = 1;
|
||||
this.maxPlayers = 50;
|
||||
this.startCommands = new ArrayList<>();
|
||||
this.endCommands = new ArrayList<>();
|
||||
this.rewards = new ArrayList<>();
|
||||
this.announcement = ColorUtil.color("&6✦ &e" + id + " &6startet jetzt!");
|
||||
this.inRotation = true;
|
||||
this.weight = 1;
|
||||
this.customSettings = new HashMap<>();
|
||||
this.isCustom = true;
|
||||
}
|
||||
|
||||
// ─── Laden aus ConfigurationSection ────────────────────────────────────
|
||||
public static EventDefinition fromConfig(String id, ConfigurationSection sec) {
|
||||
EventDefinition def = new EventDefinition(id);
|
||||
def.displayName = sec.getString("display-name", id);
|
||||
def.description = sec.getString("description", "Kein Beschreibungstext.");
|
||||
def.durationSeconds = sec.getInt("duration-seconds", 300);
|
||||
def.minPlayers = sec.getInt("min-players", 1);
|
||||
def.maxPlayers = sec.getInt("max-players", 50);
|
||||
def.startCommands = sec.getStringList("start-commands");
|
||||
def.endCommands = sec.getStringList("end-commands");
|
||||
def.rewards = sec.getStringList("rewards");
|
||||
def.announcement = ColorUtil.color(sec.getString("announcement",
|
||||
"&6✦ &e" + def.displayName + " &6startet jetzt!"));
|
||||
def.inRotation = sec.getBoolean("in-rotation", true);
|
||||
def.weight = sec.getInt("weight", 1);
|
||||
String catStr = sec.getString("category", "CUSTOM");
|
||||
try { def.category = EventCategory.valueOf(catStr); }
|
||||
catch (Exception e) { def.category = EventCategory.CUSTOM; }
|
||||
|
||||
ConfigurationSection cs = sec.getConfigurationSection("settings");
|
||||
if (cs != null) {
|
||||
for (String key : cs.getKeys(false)) {
|
||||
def.customSettings.put(key, cs.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
// Region laden
|
||||
if (sec.contains("region.world")) {
|
||||
try {
|
||||
String w = sec.getString("region.world");
|
||||
int minX = sec.getInt("region.min-x");
|
||||
int minY = sec.getInt("region.min-y");
|
||||
int minZ = sec.getInt("region.min-z");
|
||||
int maxX = sec.getInt("region.max-x");
|
||||
int maxY = sec.getInt("region.max-y");
|
||||
int maxZ = sec.getInt("region.max-z");
|
||||
def.region = new EventRegion(w, minX, minY, minZ, maxX, maxY, maxZ);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
// ─── Speichern in ConfigurationSection ─────────────────────────────────
|
||||
public void saveToConfig(ConfigurationSection sec) {
|
||||
sec.set("display-name", displayName);
|
||||
sec.set("description", description);
|
||||
sec.set("duration-seconds", durationSeconds);
|
||||
sec.set("min-players", minPlayers);
|
||||
sec.set("max-players", maxPlayers);
|
||||
sec.set("start-commands", startCommands);
|
||||
sec.set("end-commands", endCommands);
|
||||
sec.set("rewards", rewards);
|
||||
sec.set("announcement", announcement);
|
||||
sec.set("in-rotation", inRotation);
|
||||
sec.set("weight", weight);
|
||||
sec.set("category", category.name());
|
||||
if (region != null) {
|
||||
sec.set("region.world", region.getWorldName());
|
||||
sec.set("region.min-x", region.getMinX());
|
||||
sec.set("region.min-y", region.getMinY());
|
||||
sec.set("region.min-z", region.getMinZ());
|
||||
sec.set("region.max-x", region.getMaxX());
|
||||
sec.set("region.max-y", region.getMaxY());
|
||||
sec.set("region.max-z", region.getMaxZ());
|
||||
}
|
||||
if (!customSettings.isEmpty()) {
|
||||
for (Map.Entry<String, Object> entry : customSettings.entrySet()) {
|
||||
sec.set("settings." + entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Getter/Setter ──────────────────────────────────────────────────────
|
||||
public String getId() { return id; }
|
||||
public String getDisplayName() { return displayName; }
|
||||
public void setDisplayName(String n) { this.displayName = n; }
|
||||
public String getDescription() { return description; }
|
||||
public void setDescription(String d) { this.description = d; }
|
||||
public EventType getType() { return type; }
|
||||
public EventCategory getCategory() { return category; }
|
||||
public void setCategory(EventCategory c) { this.category = c; }
|
||||
public int getDurationSeconds() { return durationSeconds; }
|
||||
public void setDurationSeconds(int s) { this.durationSeconds = s; }
|
||||
public int getMinPlayers() { return minPlayers; }
|
||||
public void setMinPlayers(int n) { this.minPlayers = n; }
|
||||
public int getMaxPlayers() { return maxPlayers; }
|
||||
public void setMaxPlayers(int n) { this.maxPlayers = n; }
|
||||
public List<String> getStartCommands() { return startCommands; }
|
||||
public void setStartCommands(List<String> l) { this.startCommands = l; }
|
||||
public List<String> getEndCommands() { return endCommands; }
|
||||
public void setEndCommands(List<String> l) { this.endCommands = l; }
|
||||
public List<String> getRewards() { return rewards; }
|
||||
public void setRewards(List<String> l) { this.rewards = l; }
|
||||
public String getAnnouncement() { return announcement; }
|
||||
public void setAnnouncement(String a) { this.announcement = ColorUtil.color(a); }
|
||||
public boolean isInRotation() { return inRotation; }
|
||||
public void setInRotation(boolean b) { this.inRotation = b; }
|
||||
public int getWeight() { return weight; }
|
||||
public void setWeight(int w) { this.weight = w; }
|
||||
public Map<String, Object> getCustomSettings() { return customSettings; }
|
||||
public boolean isCustom() { return isCustom; }
|
||||
public EventRegion getRegion() { return region; }
|
||||
public void setRegion(EventRegion r) { this.region = r; }
|
||||
public boolean hasRegion() { return region != null; }
|
||||
public Object getSetting(String key) { return customSettings.get(key); }
|
||||
public void setSetting(String key, Object val) { customSettings.put(key, val); }
|
||||
}
|
||||
// Wird unten in der Klasse ergänzt — separate Patch-Datei
|
||||
101
src/main/java/dev/viper/eventengine/model/EventRegion.java
Normal file
101
src/main/java/dev/viper/eventengine/model/EventRegion.java
Normal file
@@ -0,0 +1,101 @@
|
||||
package dev.viper.eventengine.model;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
||||
/**
|
||||
* Achsenparalleler Quader in einer Welt.
|
||||
* Wird pro EventDefinition gespeichert.
|
||||
*/
|
||||
public class EventRegion {
|
||||
|
||||
private final String worldName;
|
||||
private final int minX, minY, minZ;
|
||||
private final int maxX, maxY, maxZ;
|
||||
|
||||
public EventRegion(Location pos1, Location pos2) {
|
||||
if (!pos1.getWorld().equals(pos2.getWorld()))
|
||||
throw new IllegalArgumentException("Beide Positionen müssen in der gleichen Welt sein!");
|
||||
this.worldName = pos1.getWorld().getName();
|
||||
this.minX = Math.min(pos1.getBlockX(), pos2.getBlockX());
|
||||
this.minY = Math.min(pos1.getBlockY(), pos2.getBlockY());
|
||||
this.minZ = Math.min(pos1.getBlockZ(), pos2.getBlockZ());
|
||||
this.maxX = Math.max(pos1.getBlockX(), pos2.getBlockX());
|
||||
this.maxY = Math.max(pos1.getBlockY(), pos2.getBlockY());
|
||||
this.maxZ = Math.max(pos1.getBlockZ(), pos2.getBlockZ());
|
||||
}
|
||||
|
||||
/** Konstruktor aus gespeicherten Werten (Config-Load) */
|
||||
public EventRegion(String worldName, int minX, int minY, int minZ,
|
||||
int maxX, int maxY, int maxZ) {
|
||||
this.worldName = worldName;
|
||||
this.minX = minX; this.minY = minY; this.minZ = minZ;
|
||||
this.maxX = maxX; this.maxY = maxY; this.maxZ = maxZ;
|
||||
}
|
||||
|
||||
// ─── Prüfungen ─────────────────────────────────────────────────────────
|
||||
|
||||
public boolean contains(Location loc) {
|
||||
if (loc == null || loc.getWorld() == null) return false;
|
||||
if (!loc.getWorld().getName().equals(worldName)) return false;
|
||||
int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
|
||||
return x >= minX && x <= maxX
|
||||
&& y >= minY && y <= maxY
|
||||
&& z >= minZ && z <= maxZ;
|
||||
}
|
||||
|
||||
/** Erweiterte Prüfung mit horizontalem Puffer (für Boundary-Events) */
|
||||
public boolean containsWithBuffer(Location loc, int buffer) {
|
||||
if (loc == null || loc.getWorld() == null) return false;
|
||||
if (!loc.getWorld().getName().equals(worldName)) return false;
|
||||
int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
|
||||
return x >= minX - buffer && x <= maxX + buffer
|
||||
&& y >= minY - buffer && y <= maxY + buffer
|
||||
&& z >= minZ - buffer && z <= maxZ + buffer;
|
||||
}
|
||||
|
||||
// ─── Hilfsmethoden ─────────────────────────────────────────────────────
|
||||
|
||||
/** Mittelpunkt der Region auf Bodenhöhe (minY) */
|
||||
public Location getCenter() {
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (world == null) return null;
|
||||
return new Location(world,
|
||||
(minX + maxX) / 2.0 + 0.5,
|
||||
minY,
|
||||
(minZ + maxZ) / 2.0 + 0.5);
|
||||
}
|
||||
|
||||
/** Zufällige sichere Position innerhalb der Region */
|
||||
public Location randomLocation(java.util.Random rng) {
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (world == null) return null;
|
||||
int x = minX + rng.nextInt(Math.max(1, maxX - minX));
|
||||
int z = minZ + rng.nextInt(Math.max(1, maxZ - minZ));
|
||||
// Y auf Oberfläche oder minY+1
|
||||
int y = world.getHighestBlockYAt(x, z);
|
||||
y = Math.max(y, minY + 1);
|
||||
return new Location(world, x + 0.5, y, z + 0.5);
|
||||
}
|
||||
|
||||
public World getWorld() { return Bukkit.getWorld(worldName); }
|
||||
public String getWorldName() { return worldName; }
|
||||
public int getMinX() { return minX; }
|
||||
public int getMinY() { return minY; }
|
||||
public int getMinZ() { return minZ; }
|
||||
public int getMaxX() { return maxX; }
|
||||
public int getMaxY() { return maxY; }
|
||||
public int getMaxZ() { return maxZ; }
|
||||
|
||||
/** Größe in Blöcken */
|
||||
public int getSizeX() { return maxX - minX + 1; }
|
||||
public int getSizeY() { return maxY - minY + 1; }
|
||||
public int getSizeZ() { return maxZ - minZ + 1; }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return worldName + " [" + minX + "," + minY + "," + minZ
|
||||
+ "] → [" + maxX + "," + maxY + "," + maxZ + "]";
|
||||
}
|
||||
}
|
||||
156
src/main/java/dev/viper/eventengine/model/EventType.java
Normal file
156
src/main/java/dev/viper/eventengine/model/EventType.java
Normal file
@@ -0,0 +1,156 @@
|
||||
package dev.viper.eventengine.model;
|
||||
|
||||
public enum EventType {
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// COMBAT EVENTS (20)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
PVP_DEATHMATCH("PvP Deathmatch", EventCategory.COMBAT),
|
||||
PVP_TEAM_BATTLE("Team Battle", EventCategory.COMBAT),
|
||||
PVP_FREE_FOR_ALL("Free for All", EventCategory.COMBAT),
|
||||
PVP_LAST_MAN_STANDING("Last Man Standing", EventCategory.COMBAT),
|
||||
PVP_ONE_VS_ONE("1v1 Turnier", EventCategory.COMBAT),
|
||||
PVP_BOW_ONLY("Nur Bogen", EventCategory.COMBAT),
|
||||
PVP_SWORD_ONLY("Nur Schwert", EventCategory.COMBAT),
|
||||
PVP_FIST_FIGHT("Faustkampf", EventCategory.COMBAT),
|
||||
PVP_KIT_PVP("Kit PvP", EventCategory.COMBAT),
|
||||
PVP_CAPTURE_THE_FLAG("Capture the Flag", EventCategory.COMBAT),
|
||||
PVP_KING_OF_THE_HILL("King of the Hill", EventCategory.COMBAT),
|
||||
PVP_HUNGER_GAMES("Hunger Games", EventCategory.COMBAT),
|
||||
PVP_BEDWARS_LITE("BedWars Lite", EventCategory.COMBAT),
|
||||
PVP_SKYWARS_LITE("SkyWars Lite", EventCategory.COMBAT),
|
||||
PVP_UHC("Ultra Hardcore", EventCategory.COMBAT),
|
||||
PVP_SPLEEF("Spleef", EventCategory.COMBAT),
|
||||
PVP_SUMO("Sumo", EventCategory.COMBAT),
|
||||
PVP_SNOWBALL_FIGHT("Schneeballschlacht", EventCategory.COMBAT),
|
||||
PVP_ELYTRA_PVP("Elytra PvP", EventCategory.COMBAT),
|
||||
PVP_ARENA_SURVIVAL("Arena Survival", EventCategory.COMBAT),
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// SURVIVAL EVENTS (15)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
SURVIVAL_MOB_WAVE("Mob-Wellen", EventCategory.SURVIVAL),
|
||||
SURVIVAL_ZOMBIE_SIEGE("Zombie-Belagerung", EventCategory.SURVIVAL),
|
||||
SURVIVAL_BOSS_RUSH("Boss Rush", EventCategory.SURVIVAL),
|
||||
SURVIVAL_WITHER_STORM("Wither Sturm", EventCategory.SURVIVAL),
|
||||
SURVIVAL_DRAGON_FIGHT("Drachen-Event", EventCategory.SURVIVAL),
|
||||
SURVIVAL_HARDCORE_ROUND("Hardcore-Runde", EventCategory.SURVIVAL),
|
||||
SURVIVAL_ISLAND("Insel-Überleben", EventCategory.SURVIVAL),
|
||||
SURVIVAL_NETHER_RUN("Nether-Sprint", EventCategory.SURVIVAL),
|
||||
SURVIVAL_ENDURANCE("Ausdauer-Test", EventCategory.SURVIVAL),
|
||||
SURVIVAL_RAIDS_PLUS("Raid+", EventCategory.SURVIVAL),
|
||||
SURVIVAL_MONSTER_HUNT("Monster-Jagd", EventCategory.SURVIVAL),
|
||||
SURVIVAL_LAVA_RISING("Steigendes Lava", EventCategory.SURVIVAL),
|
||||
SURVIVAL_GRAVITY_SHIFT("Schwerkraft-Chaos", EventCategory.SURVIVAL),
|
||||
SURVIVAL_RANDOM_SPAWN("Random Spawn", EventCategory.SURVIVAL),
|
||||
SURVIVAL_MANHUNT("Manhunt", EventCategory.SURVIVAL),
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// BUILDING EVENTS (10)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
BUILD_BATTLE("Build Battle", EventCategory.BUILDING),
|
||||
BUILD_SPEED_BUILD("Speed Build", EventCategory.BUILDING),
|
||||
BUILD_THEME_CHALLENGE("Themen-Challenge", EventCategory.BUILDING),
|
||||
BUILD_PIXEL_ART("Pixel Art Contest", EventCategory.BUILDING),
|
||||
BUILD_TALLEST_TOWER("Höchster Turm", EventCategory.BUILDING),
|
||||
BUILD_BRIDGE("Brücke bauen", EventCategory.BUILDING),
|
||||
BUILD_REDSTONE("Redstone Challenge", EventCategory.BUILDING),
|
||||
BUILD_UNDERGROUND("Unterirdisch bauen", EventCategory.BUILDING),
|
||||
BUILD_SKYBLOCK_STYLE("Skyblock Style", EventCategory.BUILDING),
|
||||
BUILD_BLINDBUILD("Blind bauen", EventCategory.BUILDING),
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// RACING EVENTS (10)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
RACE_PARKOUR("Parkour Race", EventCategory.RACING),
|
||||
RACE_ELYTRA("Elytra-Rennen", EventCategory.RACING),
|
||||
RACE_BOAT("Boot-Rennen", EventCategory.RACING),
|
||||
RACE_HORSE("Pferde-Rennen", EventCategory.RACING),
|
||||
RACE_PIG("Schweine-Rennen", EventCategory.RACING),
|
||||
RACE_MINECART("Lore-Rennen", EventCategory.RACING),
|
||||
RACE_SWIMMING("Schwimm-Rennen", EventCategory.RACING),
|
||||
RACE_OBSTACLE("Hindernislauf", EventCategory.RACING),
|
||||
RACE_MAZE("Labyrinth", EventCategory.RACING),
|
||||
RACE_ICEBOAT("Eisboot-Rennen", EventCategory.RACING),
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// COLLECTION EVENTS (10)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
COLLECT_SCAVENGER_HUNT("Schatzsuche", EventCategory.COLLECTION),
|
||||
COLLECT_MINING_COMP("Mining-Wettbewerb", EventCategory.COLLECTION),
|
||||
COLLECT_FISHING_COMP("Angel-Wettbewerb", EventCategory.COLLECTION),
|
||||
COLLECT_FARMING_COMP("Farm-Wettbewerb", EventCategory.COLLECTION),
|
||||
COLLECT_MOB_DROPS("Mob-Drops sammeln", EventCategory.COLLECTION),
|
||||
COLLECT_TREASURE_HUNT("Schatz finden", EventCategory.COLLECTION),
|
||||
COLLECT_EASTER_EGG("Eier suchen", EventCategory.COLLECTION),
|
||||
COLLECT_SPEED_MINE("Speed Mining", EventCategory.COLLECTION),
|
||||
COLLECT_WOODCUTTING("Holzfäll-Comp", EventCategory.COLLECTION),
|
||||
COLLECT_ENCHANT_RACE("Verzauberungsrennen", EventCategory.COLLECTION),
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// FUN EVENTS (15)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
FUN_RANDOM_EFFECTS("Zufalls-Effekte", EventCategory.FUN),
|
||||
FUN_TINY_PLAYERS("Mini-Spieler", EventCategory.FUN),
|
||||
FUN_GIANT_PLAYERS("Riesen-Spieler", EventCategory.FUN),
|
||||
FUN_INVISIBLE_PLAYERS("Unsichtbarkeit", EventCategory.FUN),
|
||||
FUN_CHAOS_MODE("Chaos-Modus", EventCategory.FUN),
|
||||
FUN_LIGHTNING_STORM("Blitz-Sturm", EventCategory.FUN),
|
||||
FUN_TNT_RAIN("TNT-Regen", EventCategory.FUN),
|
||||
FUN_ITEM_RAIN("Item-Regen", EventCategory.FUN),
|
||||
FUN_DROP_PARTY("Drop-Party", EventCategory.FUN),
|
||||
FUN_FIREWORK_SHOW("Feuerwerk-Show", EventCategory.FUN),
|
||||
FUN_RANDOM_TELEPORT("Zufalls-TP", EventCategory.FUN),
|
||||
FUN_SWAP_INVENTORIES("Inventar-Tausch", EventCategory.FUN),
|
||||
FUN_REVERSE_GRAVITY("Umgekehrte Schwerkraft", EventCategory.FUN),
|
||||
FUN_SPEED_BOOST("Geschwindigkeits-Boost", EventCategory.FUN),
|
||||
FUN_BOUNCY_BLOCKS("Hüpfende Blöcke", EventCategory.FUN),
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// QUIZ & KNOWLEDGE EVENTS (5)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
QUIZ_MINECRAFT_TRIVIA("Minecraft-Quiz", EventCategory.QUIZ),
|
||||
QUIZ_GENERAL_KNOWLEDGE("Allgemeinwissen-Quiz", EventCategory.QUIZ),
|
||||
QUIZ_SPEED_QUIZ("Speed-Quiz", EventCategory.QUIZ),
|
||||
QUIZ_CRAFTING_CHALLENGE("Crafting-Challenge", EventCategory.QUIZ),
|
||||
QUIZ_MOB_QUIZ("Mob-Quiz", EventCategory.QUIZ),
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// ECONOMY EVENTS (5)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
ECONOMY_AUCTION("Auktion", EventCategory.ECONOMY),
|
||||
ECONOMY_MARKET_RUSH("Markt-Rush", EventCategory.ECONOMY),
|
||||
ECONOMY_LOTTERY("Lotterie", EventCategory.ECONOMY),
|
||||
ECONOMY_TRADE_FRENZY("Handels-Frenzy", EventCategory.ECONOMY),
|
||||
ECONOMY_BETTING("Wetten-Event", EventCategory.ECONOMY),
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// TEAM EVENTS (10)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
TEAM_RELAY_RACE("Staffellauf", EventCategory.TEAM),
|
||||
TEAM_BUILD_BATTLE("Team Build Battle", EventCategory.TEAM),
|
||||
TEAM_SURVIVAL("Team Survival", EventCategory.TEAM),
|
||||
TEAM_TREASURE_HUNT("Team Schatzsuche", EventCategory.TEAM),
|
||||
TEAM_QUIZ("Team-Quiz", EventCategory.TEAM),
|
||||
TEAM_CAPTURE_POINTS("Punkte-Capture", EventCategory.TEAM),
|
||||
TEAM_RESOURCE_RACE("Ressourcen-Rennen", EventCategory.TEAM),
|
||||
TEAM_HIDE_AND_SEEK("Verstecken", EventCategory.TEAM),
|
||||
TEAM_MURDER_MYSTERY("Murder Mystery", EventCategory.TEAM),
|
||||
TEAM_COLOR_WAR("Farben-Krieg", EventCategory.TEAM),
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// CUSTOM (dynamisch erstellt)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
CUSTOM("Eigenes Event", EventCategory.CUSTOM);
|
||||
|
||||
private final String displayName;
|
||||
private final EventCategory category;
|
||||
|
||||
EventType(String displayName, EventCategory category) {
|
||||
this.displayName = displayName;
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public String getDisplayName() { return displayName; }
|
||||
public EventCategory getCategory() { return category; }
|
||||
}
|
||||
56
src/main/java/dev/viper/eventengine/model/ScheduleEntry.java
Normal file
56
src/main/java/dev/viper/eventengine/model/ScheduleEntry.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package dev.viper.eventengine.model;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Repräsentiert einen Zeitplan-Eintrag aus der config.yml.
|
||||
*
|
||||
* Beispiel-Config:
|
||||
* schedule:
|
||||
* - days: [MONDAY, FRIDAY]
|
||||
* time: "18:00"
|
||||
* event: "pvp_deathmatch"
|
||||
* - days: [DAILY]
|
||||
* time: "12:00"
|
||||
* event: "RANDOM"
|
||||
*/
|
||||
public class ScheduleEntry {
|
||||
|
||||
public static final String RANDOM = "RANDOM";
|
||||
|
||||
private final List<DayOfWeek> days; // leer = täglich
|
||||
private final LocalTime time;
|
||||
private final String eventId; // EventDefinition-ID oder "RANDOM"
|
||||
private final boolean everyDay;
|
||||
|
||||
public ScheduleEntry(List<DayOfWeek> days, LocalTime time, String eventId) {
|
||||
this.days = days;
|
||||
this.time = time;
|
||||
this.eventId = eventId;
|
||||
this.everyDay = days == null || days.isEmpty();
|
||||
}
|
||||
|
||||
public boolean matchesNow(DayOfWeek day, LocalTime now) {
|
||||
boolean dayMatch = everyDay || days.contains(day);
|
||||
boolean timeMatch = now.getHour() == time.getHour()
|
||||
&& now.getMinute() == time.getMinute();
|
||||
return dayMatch && timeMatch;
|
||||
}
|
||||
|
||||
public boolean isRandom() {
|
||||
return RANDOM.equalsIgnoreCase(eventId);
|
||||
}
|
||||
|
||||
public List<DayOfWeek> getDays() { return days; }
|
||||
public LocalTime getTime() { return time; }
|
||||
public String getEventId() { return eventId; }
|
||||
public boolean isEveryDay() { return everyDay; }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String dayStr = everyDay ? "Täglich" : days.toString();
|
||||
return dayStr + " um " + time + " → " + eventId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package dev.viper.eventengine.scheduler;
|
||||
|
||||
import dev.viper.eventengine.EventEngine;
|
||||
import dev.viper.eventengine.model.EventDefinition;
|
||||
import dev.viper.eventengine.model.ScheduleEntry;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Läuft jede Minute und prüft, ob ein geplantes Event feuern soll.
|
||||
* Unterstützt:
|
||||
* - Expliziten Zeitplan aus config.yml (schedule: [])
|
||||
* - Intervall-Modus (use-interval: true, interval-minutes: 60)
|
||||
*/
|
||||
public class EventScheduler {
|
||||
|
||||
private final EventEngine plugin;
|
||||
private final Logger log;
|
||||
private BukkitTask minuteTask;
|
||||
private BukkitTask intervalTask;
|
||||
|
||||
// Für Intervall-Modus: Zähler
|
||||
private int minuteCounter = 0;
|
||||
|
||||
public EventScheduler(EventEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
this.log = plugin.getLogger();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
stop();
|
||||
|
||||
// Jede Minute: Zeitplan prüfen
|
||||
minuteTask = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
tickSchedule();
|
||||
}
|
||||
}.runTaskTimer(plugin, 1200L, 1200L); // 1200 Ticks = 60 Sekunden
|
||||
|
||||
log.info("EventScheduler gestartet.");
|
||||
|
||||
// Intervall-Modus als Zusatz
|
||||
if (plugin.getConfigManager().isUseInterval()) {
|
||||
startIntervalMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void startIntervalMode() {
|
||||
int intervalMin = plugin.getConfigManager().getIntervalMinutes();
|
||||
if (intervalMin <= 0) return;
|
||||
|
||||
long ticks = intervalMin * 60L * 20L;
|
||||
intervalTask = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (plugin.getEventManager().isRunning()) return;
|
||||
fireRandomOrDefault();
|
||||
}
|
||||
}.runTaskTimer(plugin, ticks, ticks);
|
||||
|
||||
log.info("Intervall-Modus: alle " + intervalMin + " Minuten.");
|
||||
}
|
||||
|
||||
private void tickSchedule() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
DayOfWeek day = now.getDayOfWeek();
|
||||
LocalTime time = now.toLocalTime();
|
||||
|
||||
List<ScheduleEntry> schedule = plugin.getConfigManager().getSchedule();
|
||||
for (ScheduleEntry entry : schedule) {
|
||||
if (!entry.matchesNow(day, time)) continue;
|
||||
|
||||
if (plugin.getEventManager().isRunning()) {
|
||||
log.info("Zeitplan-Event übersprungen (läuft bereits): " + entry.getEventId());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ankündigung?
|
||||
int announceBefore = plugin.getConfigManager().getAnnounceBefore();
|
||||
if (announceBefore > 0) {
|
||||
scheduleAnnouncement(entry, announceBefore);
|
||||
}
|
||||
|
||||
fireScheduleEntry(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleAnnouncement(ScheduleEntry entry, int secondsBefore) {
|
||||
String name = entry.isRandom() ? "ein zufälliges Event" : entry.getEventId();
|
||||
long ticks = secondsBefore * 20L;
|
||||
// Ankündigung JETZT senden (Event startet in X Sekunden)
|
||||
// (Zeitplan feuert genau zur geplanten Minute)
|
||||
plugin.getServer().broadcastMessage(
|
||||
plugin.prefix() + "§e⏰ In §c" + secondsBefore + " Sekunden §estartet: §6" + name + "§e!");
|
||||
}
|
||||
|
||||
private void fireScheduleEntry(ScheduleEntry entry) {
|
||||
if (entry.isRandom()) {
|
||||
fireRandomOrDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<EventDefinition> defOpt = plugin.getEventRegistry().get(entry.getEventId());
|
||||
if (defOpt.isPresent()) {
|
||||
plugin.getEventManager().startEvent(defOpt.get(), null);
|
||||
} else {
|
||||
log.warning("Zeitplan-Event nicht gefunden: " + entry.getEventId() + " — feuere zufälliges.");
|
||||
fireRandomOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private void fireRandomOrDefault() {
|
||||
if (plugin.getConfigManager().isRandomOnInterval()) {
|
||||
Optional<EventDefinition> random = plugin.getEventRegistry().getWeightedRandom();
|
||||
random.ifPresent(def -> plugin.getEventManager().startEvent(def, null));
|
||||
} else {
|
||||
String defaultId = plugin.getConfigManager().getDefaultEventId();
|
||||
Optional<EventDefinition> def = plugin.getEventRegistry().get(defaultId);
|
||||
def.ifPresent(d -> plugin.getEventManager().startEvent(d, null));
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (minuteTask != null) { minuteTask.cancel(); minuteTask = null; }
|
||||
if (intervalTask != null) { intervalTask.cancel(); intervalTask = null; }
|
||||
}
|
||||
|
||||
public void restart() {
|
||||
stop();
|
||||
start();
|
||||
}
|
||||
}
|
||||
75
src/main/java/dev/viper/eventengine/util/ColorUtil.java
Normal file
75
src/main/java/dev/viper/eventengine/util/ColorUtil.java
Normal file
@@ -0,0 +1,75 @@
|
||||
package dev.viper.eventengine.util;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Wandelt alle Farbformate um:
|
||||
* &c → §c (Standard-Codes)
|
||||
* &#FF5733 → Hex-Farbe (Paper / Spigot 1.16+)
|
||||
* &x&F&F&5&7&3&3 → Bukkit-Hex-Format
|
||||
* §c → bleibt §c (bereits konvertiert)
|
||||
*/
|
||||
public final class ColorUtil {
|
||||
|
||||
// &#RRGGBB oder #RRGGBB
|
||||
private static final Pattern HEX_HASH = Pattern.compile("&#([0-9A-Fa-f]{6})|#([0-9A-Fa-f]{6})");
|
||||
// &x&R&R&G&G&B&B (Bukkit-Hex-Format)
|
||||
private static final Pattern HEX_BUKKIT = Pattern.compile("&x(&[0-9A-Fa-f]){6}");
|
||||
|
||||
private ColorUtil() {}
|
||||
|
||||
/**
|
||||
* Konvertiert einen String mit beliebigen Farbcodes zu einem Minecraft-farbigen String.
|
||||
*/
|
||||
public static String color(String input) {
|
||||
if (input == null) return "";
|
||||
String s = input;
|
||||
|
||||
// 1. &#RRGGBB und #RRGGBB → §x§R§R§G§G§B§B
|
||||
Matcher hexHash = HEX_HASH.matcher(s);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
while (hexHash.find()) {
|
||||
String hex = hexHash.group(1) != null ? hexHash.group(1) : hexHash.group(2);
|
||||
hexHash.appendReplacement(sb, hexToBukkit(hex));
|
||||
}
|
||||
hexHash.appendTail(sb);
|
||||
s = sb.toString();
|
||||
|
||||
// 2. &x&R&R&G&G&B&B → §x§R§R§G§G§B§B (falls jemand es schon im Bukkit-Format angibt)
|
||||
Matcher hexBukkit = HEX_BUKKIT.matcher(s);
|
||||
sb = new StringBuffer();
|
||||
while (hexBukkit.find()) {
|
||||
hexBukkit.appendReplacement(sb, hexBukkit.group().replace('&', '§'));
|
||||
}
|
||||
hexBukkit.appendTail(sb);
|
||||
s = sb.toString();
|
||||
|
||||
// 3. &a–&f, &0–&9, &k–&r → §-Codes
|
||||
s = ChatColor.translateAlternateColorCodes('&', s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entfernt alle Farbcodes aus einem String (für Vergleiche, Logs etc.)
|
||||
*/
|
||||
public static String strip(String input) {
|
||||
if (input == null) return "";
|
||||
return ChatColor.stripColor(color(input));
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert einen 6-stelligen Hex-String (#RRGGBB ohne #) in das
|
||||
* Minecraft §x§R§R§G§G§B§B Format.
|
||||
*/
|
||||
private static String hexToBukkit(String hex) {
|
||||
StringBuilder result = new StringBuilder("§x");
|
||||
for (char c : hex.toCharArray()) {
|
||||
result.append('§').append(c);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user