Upload folder via GUI - src

This commit is contained in:
Git Manager GUI
2026-04-08 02:42:04 +02:00
parent 4e18de17fc
commit 87f80d30c5
16 changed files with 1160 additions and 22 deletions

View File

@@ -18,8 +18,10 @@ public class EventEngine extends JavaPlugin {
private ConfigManager configManager; private ConfigManager configManager;
private EventRegistry eventRegistry; private EventRegistry eventRegistry;
private EventManager eventManager; private EventManager eventManager;
private dev.viper.eventengine.manager.ScoreboardManager scoreboardManager;
private EventScheduler eventScheduler; private EventScheduler eventScheduler;
private EventGUI eventGUI; private EventGUI eventGUI;
private dev.viper.eventengine.gui.ItemRainGUI itemRainGUI;
private EventCreateListener eventCreateListener; private EventCreateListener eventCreateListener;
private RegionSetupManager regionSetupManager; private RegionSetupManager regionSetupManager;
@@ -35,6 +37,9 @@ public class EventEngine extends JavaPlugin {
eventRegistry = new EventRegistry(this); eventRegistry = new EventRegistry(this);
eventRegistry.init(); eventRegistry.init();
// Scoreboard-Manager
scoreboardManager = new dev.viper.eventengine.manager.ScoreboardManager(this);
// Event-Manager (Lifecycle) // Event-Manager (Lifecycle)
eventManager = new EventManager(this); eventManager = new EventManager(this);
@@ -46,6 +51,10 @@ public class EventEngine extends JavaPlugin {
eventGUI = new EventGUI(this); eventGUI = new EventGUI(this);
getServer().getPluginManager().registerEvents(eventGUI, this); getServer().getPluginManager().registerEvents(eventGUI, this);
// Item-Regen GUI
itemRainGUI = new dev.viper.eventengine.gui.ItemRainGUI(this);
getServer().getPluginManager().registerEvents(itemRainGUI, this);
// Create-Listener (Custom Event Builder) // Create-Listener (Custom Event Builder)
eventCreateListener = new EventCreateListener(this); eventCreateListener = new EventCreateListener(this);
getServer().getPluginManager().registerEvents(eventCreateListener, this); getServer().getPluginManager().registerEvents(eventCreateListener, this);
@@ -53,6 +62,9 @@ public class EventEngine extends JavaPlugin {
// Region-Schutz Listener // Region-Schutz Listener
getServer().getPluginManager().registerEvents(new EventProtectionListener(this), this); getServer().getPluginManager().registerEvents(new EventProtectionListener(this), this);
// Race-Goal Listener
getServer().getPluginManager().registerEvents(new dev.viper.eventengine.listener.RaceGoalListener(this), this);
// Region-Setup Manager // Region-Setup Manager
regionSetupManager = new RegionSetupManager(this); regionSetupManager = new RegionSetupManager(this);
@@ -79,8 +91,10 @@ public class EventEngine extends JavaPlugin {
public ConfigManager getConfigManager() { return configManager; } public ConfigManager getConfigManager() { return configManager; }
public EventRegistry getEventRegistry() { return eventRegistry; } public EventRegistry getEventRegistry() { return eventRegistry; }
public EventManager getEventManager() { return eventManager; } public EventManager getEventManager() { return eventManager; }
public dev.viper.eventengine.manager.ScoreboardManager getScoreboardManager() { return scoreboardManager; }
public EventScheduler getEventScheduler() { return eventScheduler; } public EventScheduler getEventScheduler() { return eventScheduler; }
public EventGUI getEventGUI() { return eventGUI; } public EventGUI getEventGUI() { return eventGUI; }
public dev.viper.eventengine.gui.ItemRainGUI getItemRainGUI() { return itemRainGUI; }
public EventCreateListener getEventCreateListener() { return eventCreateListener; } public EventCreateListener getEventCreateListener() { return eventCreateListener; }
public RegionSetupManager getRegionSetupManager() { return regionSetupManager; } public RegionSetupManager getRegionSetupManager() { return regionSetupManager; }

View File

@@ -44,6 +44,13 @@ public class EventCommand implements CommandExecutor, TabCompleter {
requirePlayer(sender, () -> plugin.getEventGUI().openMain((Player) sender)); requirePlayer(sender, () -> plugin.getEventGUI().openMain((Player) sender));
} }
// ─── ITEM-REGEN GUI ──────────────────────────────────────────
case "itemrain" -> {
requirePerm(sender, () -> {
requirePlayer(sender, () -> plugin.getItemRainGUI().open((Player) sender));
});
}
// ─── START ───────────────────────────────────────────────────── // ─── START ─────────────────────────────────────────────────────
case "start" -> { case "start" -> {
requirePerm(sender, () -> { requirePerm(sender, () -> {
@@ -89,6 +96,9 @@ public class EventCommand implements CommandExecutor, TabCompleter {
sender.sendMessage("§7 Custom: §f" + def.isCustom()); sender.sendMessage("§7 Custom: §f" + def.isCustom());
sender.sendMessage("§7 Start-Befehle: §f" + def.getStartCommands().size()); sender.sendMessage("§7 Start-Befehle: §f" + def.getStartCommands().size());
sender.sendMessage("§7 Belohnungen: §f" + def.getRewards().size()); sender.sendMessage("§7 Belohnungen: §f" + def.getRewards().size());
sender.sendMessage("§7 Winner-Belohnungen: §f" + def.getWinnerRewards().size());
sender.sendMessage("§7 Startbereich: §f" + (def.hasStartRegion() ? "gesetzt" : "-"));
sender.sendMessage("§7 Zielbereich: §f" + (def.hasGoalRegion() ? "gesetzt" : "-"));
sender.sendMessage("§8§m══════════════════════════════"); sender.sendMessage("§8§m══════════════════════════════");
}, () -> sender.sendMessage(p + "§cEvent nicht gefunden.")); }, () -> sender.sendMessage(p + "§cEvent nicht gefunden."));
} else { } else {
@@ -231,6 +241,43 @@ public class EventCommand implements CommandExecutor, TabCompleter {
}); });
} }
// ─── RACE START/GOAL ───────────────────────────────────────
case "race" -> {
requirePerm(sender, () -> {
requirePlayer(sender, () -> {
if (args.length < 4) {
sender.sendMessage(p + "§cUsage: /event race <start|goal> <pos1|pos2|clear|info> <id>");
return;
}
String target = args[1].toLowerCase();
String sub = args[2].toLowerCase();
String id = args[3].toLowerCase();
RegionSetupManager rsm = plugin.getRegionSetupManager();
if (target.equals("start")) {
switch (sub) {
case "pos1" -> rsm.handleStartPos1((Player) sender, id);
case "pos2" -> rsm.handleStartPos2((Player) sender, id);
case "clear" -> rsm.handleStartClear((Player) sender, id);
case "info" -> rsm.handleStartInfo((Player) sender, id);
default -> sender.sendMessage(p + "§cUnbekannte Sub-Option. pos1 | pos2 | clear | info");
}
return;
}
if (target.equals("goal")) {
switch (sub) {
case "pos1" -> rsm.handleGoalPos1((Player) sender, id);
case "pos2" -> rsm.handleGoalPos2((Player) sender, id);
case "clear" -> rsm.handleGoalClear((Player) sender, id);
case "info" -> rsm.handleGoalInfo((Player) sender, id);
default -> sender.sendMessage(p + "§cUnbekannte Sub-Option. pos1 | pos2 | clear | info");
}
return;
}
sender.sendMessage(p + "§cUnbekannte Option. start | goal");
});
});
}
default -> sendHelp(sender); default -> sendHelp(sender);
} }
@@ -243,7 +290,7 @@ public class EventCommand implements CommandExecutor, TabCompleter {
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) { public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if (args.length == 1) { if (args.length == 1) {
return filter(args[0], "gui", "start", "stop", "join", "leave", "info", "list", return filter(args[0], "gui", "start", "stop", "join", "leave", "info", "list",
"schedule", "create", "delete", "score", "rotation", "region", "reload"); "schedule", "create", "delete", "score", "rotation", "region", "race", "itemrain", "reload");
} }
if (args.length == 2) { if (args.length == 2) {
return switch (args[0].toLowerCase()) { return switch (args[0].toLowerCase()) {
@@ -257,15 +304,25 @@ public class EventCommand implements CommandExecutor, TabCompleter {
case "rotation" -> filter(args[1], "add", "remove"); case "rotation" -> filter(args[1], "add", "remove");
case "score" -> null; // Spielernamen case "score" -> null; // Spielernamen
case "region" -> filter(args[1], "pos1", "pos2", "clear", "info"); case "region" -> filter(args[1], "pos1", "pos2", "clear", "info");
case "race" -> filter(args[1], "start", "goal");
default -> null; default -> null;
}; };
} }
if (args.length == 3 && args[0].equalsIgnoreCase("race")) {
return filter(args[2], "pos1", "pos2", "clear", "info");
}
if (args.length == 3 && args[0].equalsIgnoreCase("rotation")) { if (args.length == 3 && args[0].equalsIgnoreCase("rotation")) {
return plugin.getEventRegistry().getAll().stream() return plugin.getEventRegistry().getAll().stream()
.map(EventDefinition::getId) .map(EventDefinition::getId)
.filter(id -> id.startsWith(args[2].toLowerCase())) .filter(id -> id.startsWith(args[2].toLowerCase()))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
if (args.length == 4 && args[0].equalsIgnoreCase("race")) {
return plugin.getEventRegistry().getAll().stream()
.map(EventDefinition::getId)
.filter(id -> id.startsWith(args[3].toLowerCase()))
.collect(Collectors.toList());
}
return null; return null;
} }
@@ -287,6 +344,8 @@ public class EventCommand implements CommandExecutor, TabCompleter {
sender.sendMessage("§e /event rotation <add|remove> <id> §7- Rotation steuern"); sender.sendMessage("§e /event rotation <add|remove> <id> §7- Rotation steuern");
sender.sendMessage("§e /event reload §7- Config neu laden"); 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("§e /event region <pos1|pos2|clear|info> <id> §7- Event-Arena setzen");
sender.sendMessage("§e /event race <start|goal> <pos1|pos2|clear|info> <id> §7- Start/Ziel setzen");
sender.sendMessage("§e /event itemrain §7- Item-Regen GUI");
sender.sendMessage("§8§m══════════════════════════════"); sender.sendMessage("§8§m══════════════════════════════");
} }

View File

@@ -23,6 +23,8 @@ public class RegionSetupManager {
private final EventEngine plugin; private final EventEngine plugin;
// Temporäre Pos1-Speicher pro Spieler: UUID → [eventId, Location] // Temporäre Pos1-Speicher pro Spieler: UUID → [eventId, Location]
private final Map<UUID, Object[]> pos1Selection = new HashMap<>(); private final Map<UUID, Object[]> pos1Selection = new HashMap<>();
private final Map<UUID, Object[]> startPos1Selection = new HashMap<>();
private final Map<UUID, Object[]> goalPos1Selection = new HashMap<>();
public RegionSetupManager(EventEngine plugin) { public RegionSetupManager(EventEngine plugin) {
this.plugin = plugin; this.plugin = plugin;
@@ -78,6 +80,120 @@ public class RegionSetupManager {
player.sendMessage(plugin.prefix() + "§7Region für §e" + def.getDisplayName() + " §7entfernt (gesamte Welt)."); player.sendMessage(plugin.prefix() + "§7Region für §e" + def.getDisplayName() + " §7entfernt (gesamte Welt).");
} }
public void handleStartPos1(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; }
startPos1Selection.put(player.getUniqueId(), new Object[]{eventId, player.getLocation().clone()});
player.sendMessage(plugin.prefix() + "§aStart-Pos1 gesetzt: §f" + formatLoc(player));
player.sendMessage(plugin.prefix() + "§7Jetzt: §f/event race start pos2 " + eventId);
}
public void handleStartPos2(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 = startPos1Selection.get(player.getUniqueId());
if (sel == null || !sel[0].equals(eventId)) {
player.sendMessage(plugin.prefix() + "§cZuerst Start-Pos1 setzen: §f/event race start 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.setStartRegion(region);
if (def.isCustom()) plugin.getConfigManager().saveCustomEvent(def);
startPos1Selection.remove(player.getUniqueId());
player.sendMessage(plugin.prefix() + "§a✔ Startbereich gesetzt für §e" + def.getDisplayName() + "§a:");
sendRegionInfo(player, region);
}
public void handleStartClear(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.setStartRegion(null);
if (def.isCustom()) plugin.getConfigManager().saveCustomEvent(def);
player.sendMessage(plugin.prefix() + "§7Startbereich für §e" + def.getDisplayName() + " §7entfernt.");
}
public void handleStartInfo(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.hasStartRegion()) {
player.sendMessage(plugin.prefix() + "§e" + def.getDisplayName() + " §7hat keinen Startbereich.");
return;
}
player.sendMessage("§8§m══════════════════════════════");
player.sendMessage("§6 Startbereich: §e" + def.getDisplayName());
sendRegionInfo(player, def.getStartRegion());
player.sendMessage("§8§m══════════════════════════════");
}
public void handleGoalPos1(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; }
goalPos1Selection.put(player.getUniqueId(), new Object[]{eventId, player.getLocation().clone()});
player.sendMessage(plugin.prefix() + "§aZiel-Pos1 gesetzt: §f" + formatLoc(player));
player.sendMessage(plugin.prefix() + "§7Jetzt: §f/event race goal pos2 " + eventId);
}
public void handleGoalPos2(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 = goalPos1Selection.get(player.getUniqueId());
if (sel == null || !sel[0].equals(eventId)) {
player.sendMessage(plugin.prefix() + "§cZuerst Ziel-Pos1 setzen: §f/event race goal 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.setGoalRegion(region);
if (def.isCustom()) plugin.getConfigManager().saveCustomEvent(def);
goalPos1Selection.remove(player.getUniqueId());
player.sendMessage(plugin.prefix() + "§a✔ Zielbereich gesetzt für §e" + def.getDisplayName() + "§a:");
sendRegionInfo(player, region);
}
public void handleGoalClear(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.setGoalRegion(null);
if (def.isCustom()) plugin.getConfigManager().saveCustomEvent(def);
player.sendMessage(plugin.prefix() + "§7Zielbereich für §e" + def.getDisplayName() + " §7entfernt.");
}
public void handleGoalInfo(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.hasGoalRegion()) {
player.sendMessage(plugin.prefix() + "§e" + def.getDisplayName() + " §7hat keinen Zielbereich.");
return;
}
player.sendMessage("§8§m══════════════════════════════");
player.sendMessage("§6 Zielbereich: §e" + def.getDisplayName());
sendRegionInfo(player, def.getGoalRegion());
player.sendMessage("§8§m══════════════════════════════");
}
public void handleInfo(Player player, String eventId) { public void handleInfo(Player player, String eventId) {
EventDefinition def = plugin.getEventRegistry().get(eventId).orElse(null); EventDefinition def = plugin.getEventRegistry().get(eventId).orElse(null);
if (def == null) { player.sendMessage(plugin.prefix() + "§cEvent nicht gefunden: §f" + eventId); return; } if (def == null) { player.sendMessage(plugin.prefix() + "§cEvent nicht gefunden: §f" + eventId); return; }
@@ -101,4 +217,11 @@ public class RegionSetupManager {
+ p.getLocation().getBlockY() + ", " + p.getLocation().getBlockY() + ", "
+ p.getLocation().getBlockZ(); + p.getLocation().getBlockZ();
} }
private void sendRegionInfo(Player player, EventRegion region) {
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());
}
} }

View File

@@ -4,6 +4,7 @@ import dev.viper.eventengine.EventEngine;
import dev.viper.eventengine.model.EventDefinition; import dev.viper.eventengine.model.EventDefinition;
import dev.viper.eventengine.model.ScheduleEntry; import dev.viper.eventengine.model.ScheduleEntry;
import dev.viper.eventengine.util.ColorUtil; import dev.viper.eventengine.util.ColorUtil;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
@@ -18,6 +19,18 @@ import java.util.logging.Logger;
public class ConfigManager { public class ConfigManager {
private static final List<Material> DEFAULT_ITEM_RAIN_ITEMS = List.of(
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 final EventEngine plugin;
private final Logger log; private final Logger log;
@@ -44,6 +57,7 @@ public class ConfigManager {
private boolean enforceRegionBoundary; private boolean enforceRegionBoundary;
private boolean noExplosionBlockDamage; private boolean noExplosionBlockDamage;
private boolean restrictBlockInteraction; private boolean restrictBlockInteraction;
private List<Material> itemRainItems;
public ConfigManager(EventEngine plugin) { public ConfigManager(EventEngine plugin) {
this.plugin = plugin; this.plugin = plugin;
@@ -73,6 +87,16 @@ public class ConfigManager {
noExplosionBlockDamage = mainConfig.getBoolean("protection.no-explosion-block-damage", true); noExplosionBlockDamage = mainConfig.getBoolean("protection.no-explosion-block-damage", true);
restrictBlockInteraction = mainConfig.getBoolean("protection.restrict-block-interaction", true); restrictBlockInteraction = mainConfig.getBoolean("protection.restrict-block-interaction", true);
prefix = ColorUtil.color(mainConfig.getString("settings.prefix", "&8[&6EventEngine&8]&r ")); prefix = ColorUtil.color(mainConfig.getString("settings.prefix", "&8[&6EventEngine&8]&r "));
List<String> rawItems = mainConfig.getStringList("item-rain.items");
itemRainItems = new ArrayList<>();
for (String name : rawItems) {
try {
Material mat = Material.valueOf(name.toUpperCase());
if (mat.isItem()) itemRainItems.add(mat);
} catch (Exception ignored) {}
}
if (itemRainItems.isEmpty()) itemRainItems.addAll(DEFAULT_ITEM_RAIN_ITEMS);
} }
private void loadSchedule() { private void loadSchedule() {
@@ -166,4 +190,17 @@ public class ConfigManager {
public boolean isNoExplosionBlockDamage() { return noExplosionBlockDamage; } public boolean isNoExplosionBlockDamage() { return noExplosionBlockDamage; }
public boolean isRestrictBlockInteraction() { return restrictBlockInteraction; } public boolean isRestrictBlockInteraction() { return restrictBlockInteraction; }
public FileConfiguration getMainConfig() { return mainConfig; } public FileConfiguration getMainConfig() { return mainConfig; }
public List<Material> getItemRainItems() { return Collections.unmodifiableList(itemRainItems); }
public void setItemRainItems(List<Material> items) {
itemRainItems = new ArrayList<>(items);
if (itemRainItems.isEmpty()) itemRainItems.addAll(DEFAULT_ITEM_RAIN_ITEMS);
List<String> raw = itemRainItems.stream().map(Material::name).toList();
mainConfig.set("item-rain.items", raw);
plugin.saveConfig();
}
public void resetItemRainItems() {
setItemRainItems(DEFAULT_ITEM_RAIN_ITEMS);
}
} }

View File

@@ -39,10 +39,35 @@ public class EventOverrideLoader {
if (sec.contains("start-commands")) def.setStartCommands(sec.getStringList("start-commands")); 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("end-commands")) def.setEndCommands(sec.getStringList("end-commands"));
if (sec.contains("rewards")) def.setRewards(sec.getStringList("rewards")); if (sec.contains("rewards")) def.setRewards(sec.getStringList("rewards"));
if (sec.contains("winner-rewards")) def.setWinnerRewards(sec.getStringList("winner-rewards"));
if (sec.contains("category")) { if (sec.contains("category")) {
try { def.setCategory(EventCategory.valueOf(sec.getString("category").toUpperCase())); } try { def.setCategory(EventCategory.valueOf(sec.getString("category").toUpperCase())); }
catch (Exception ignored) {} catch (Exception ignored) {}
} }
if (sec.contains("start-region.world")) {
try {
String w = sec.getString("start-region.world");
int minX = sec.getInt("start-region.min-x");
int minY = sec.getInt("start-region.min-y");
int minZ = sec.getInt("start-region.min-z");
int maxX = sec.getInt("start-region.max-x");
int maxY = sec.getInt("start-region.max-y");
int maxZ = sec.getInt("start-region.max-z");
def.setStartRegion(new dev.viper.eventengine.model.EventRegion(w, minX, minY, minZ, maxX, maxY, maxZ));
} catch (Exception ignored) {}
}
if (sec.contains("goal-region.world")) {
try {
String w = sec.getString("goal-region.world");
int minX = sec.getInt("goal-region.min-x");
int minY = sec.getInt("goal-region.min-y");
int minZ = sec.getInt("goal-region.min-z");
int maxX = sec.getInt("goal-region.max-x");
int maxY = sec.getInt("goal-region.max-y");
int maxZ = sec.getInt("goal-region.max-z");
def.setGoalRegion(new dev.viper.eventengine.model.EventRegion(w, minX, minY, minZ, maxX, maxY, maxZ));
} catch (Exception ignored) {}
}
ConfigurationSection settings = sec.getConfigurationSection("settings"); ConfigurationSection settings = sec.getConfigurationSection("settings");
if (settings != null) { if (settings != null) {
for (String key : settings.getKeys(false)) { for (String key : settings.getKeys(false)) {

View File

@@ -12,6 +12,7 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.UUID; import java.util.UUID;
@@ -24,6 +25,7 @@ class TntRainHandler implements IEventHandler, Listener {
private ActiveEvent currentEvent; private ActiveEvent currentEvent;
private BukkitRunnable rain; private BukkitRunnable rain;
private final Random rng = new Random(); private final Random rng = new Random();
private final java.util.Set<java.util.UUID> spawnedTnt = new java.util.HashSet<>();
TntRainHandler(EventEngine plugin) { this.plugin = plugin; } TntRainHandler(EventEngine plugin) { this.plugin = plugin; }
@@ -47,6 +49,7 @@ class TntRainHandler implements IEventHandler, Listener {
(rng.nextDouble() - 0.5) * 20, 15, (rng.nextDouble() - 0.5) * 20); (rng.nextDouble() - 0.5) * 20, 15, (rng.nextDouble() - 0.5) * 20);
TNTPrimed tnt = p.getWorld().spawn(loc, TNTPrimed.class); TNTPrimed tnt = p.getWorld().spawn(loc, TNTPrimed.class);
tnt.setFuseTicks(40); tnt.setFuseTicks(40);
spawnedTnt.add(tnt.getUniqueId());
} }
} }
}; };
@@ -57,12 +60,25 @@ class TntRainHandler implements IEventHandler, Listener {
public void onEnd(ActiveEvent event) { public void onEnd(ActiveEvent event) {
HandlerList.unregisterAll(this); HandlerList.unregisterAll(this);
if (rain != null) rain.cancel(); if (rain != null) rain.cancel();
clearSpawnedTnt();
for (UUID uuid : event.getParticipants()) { for (UUID uuid : event.getParticipants()) {
Player p = Bukkit.getPlayer(uuid); Player p = Bukkit.getPlayer(uuid);
if (p != null) p.removePotionEffect(PotionEffectType.RESISTANCE); if (p != null) p.removePotionEffect(PotionEffectType.RESISTANCE);
} }
this.currentEvent = null; this.currentEvent = null;
} }
private void clearSpawnedTnt() {
if (spawnedTnt.isEmpty()) return;
for (World world : Bukkit.getWorlds()) {
for (TNTPrimed tnt : world.getEntitiesByClass(TNTPrimed.class)) {
if (spawnedTnt.remove(tnt.getUniqueId())) {
tnt.remove();
}
}
}
spawnedTnt.clear();
}
} }
// ═══════════════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════════════
@@ -70,16 +86,13 @@ class TntRainHandler implements IEventHandler, Listener {
// ═══════════════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════════════
class ItemRainHandler implements IEventHandler, Listener { 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 final EventEngine plugin;
private ActiveEvent currentEvent; private ActiveEvent currentEvent;
private BukkitRunnable rain; private BukkitRunnable rain;
private final Random rng = new Random(); private final Random rng = new Random();
private BukkitRunnable afkCheck;
private final java.util.Map<java.util.UUID, Long> lastMove = new java.util.HashMap<>();
private final java.util.Map<java.util.UUID, Long> warnedAt = new java.util.HashMap<>();
ItemRainHandler(EventEngine plugin) { this.plugin = plugin; } ItemRainHandler(EventEngine plugin) { this.plugin = plugin; }
@@ -87,13 +100,21 @@ class ItemRainHandler implements IEventHandler, Listener {
public void onStart(ActiveEvent event) { public void onStart(ActiveEvent event) {
this.currentEvent = event; this.currentEvent = event;
Bukkit.broadcastMessage(plugin.prefix() + "§d🌧 §eItem-Regen! §7Items fallen vom Himmel!"); Bukkit.broadcastMessage(plugin.prefix() + "§d🌧 §eItem-Regen! §7Items fallen vom Himmel!");
Bukkit.getPluginManager().registerEvents(this, plugin);
long now = System.currentTimeMillis();
for (UUID uuid : event.getParticipants()) {
lastMove.put(uuid, now);
warnedAt.remove(uuid);
}
rain = new BukkitRunnable() { rain = new BukkitRunnable() {
@Override @Override
public void run() { public void run() {
if (currentEvent == null) { cancel(); return; } if (currentEvent == null) { cancel(); return; }
for (Player p : Bukkit.getOnlinePlayers()) { for (Player p : Bukkit.getOnlinePlayers()) {
Material mat = ITEMS[rng.nextInt(ITEMS.length)]; List<Material> items = plugin.getConfigManager().getItemRainItems();
Material mat = items.get(rng.nextInt(items.size()));
Location loc = p.getLocation().add( Location loc = p.getLocation().add(
(rng.nextDouble() - 0.5) * 12, 12, (rng.nextDouble() - 0.5) * 12); (rng.nextDouble() - 0.5) * 12, 12, (rng.nextDouble() - 0.5) * 12);
p.getWorld().dropItemNaturally(loc, new ItemStack(mat, 1 + rng.nextInt(5))); p.getWorld().dropItemNaturally(loc, new ItemStack(mat, 1 + rng.nextInt(5)));
@@ -101,14 +122,67 @@ class ItemRainHandler implements IEventHandler, Listener {
} }
}; };
rain.runTaskTimer(plugin, 10L, 15L); rain.runTaskTimer(plugin, 10L, 15L);
afkCheck = new BukkitRunnable() {
@Override
public void run() {
if (currentEvent == null) { cancel(); return; }
long now = System.currentTimeMillis();
for (UUID uuid : new java.util.ArrayList<>(currentEvent.getParticipants())) {
Player p = Bukkit.getPlayer(uuid);
if (p == null) continue;
long last = lastMove.getOrDefault(uuid, now);
if (now - last < 60_000L) continue;
Long warned = warnedAt.get(uuid);
if (warned == null) {
warnedAt.put(uuid, now);
p.sendMessage(plugin.prefix() + "§eDu bist seit 1 Minute AFK. Bewege dich, sonst wirst du entfernt!");
continue;
}
if (now - warned >= 10_000L) {
warnedAt.remove(uuid);
plugin.getEventManager().leave(p);
p.sendMessage(plugin.prefix() + "§cAFK: Du wurdest aus dem Event entfernt.");
}
}
}
};
afkCheck.runTaskTimer(plugin, 20L, 20L);
} }
@Override @Override
public void onEnd(ActiveEvent event) { public void onEnd(ActiveEvent event) {
HandlerList.unregisterAll(this); HandlerList.unregisterAll(this);
if (rain != null) rain.cancel(); if (rain != null) rain.cancel();
if (afkCheck != null) afkCheck.cancel();
lastMove.clear();
warnedAt.clear();
this.currentEvent = null; this.currentEvent = null;
} }
@Override
public void onPlayerJoin(ActiveEvent event, Player player) {
lastMove.put(player.getUniqueId(), System.currentTimeMillis());
warnedAt.remove(player.getUniqueId());
}
@Override
public void onPlayerLeave(ActiveEvent event, Player player) {
lastMove.remove(player.getUniqueId());
warnedAt.remove(player.getUniqueId());
}
@org.bukkit.event.EventHandler(ignoreCancelled = true)
public void onMove(org.bukkit.event.player.PlayerMoveEvent e) {
if (currentEvent == null || !currentEvent.isParticipant(e.getPlayer())) return;
if (e.getFrom().getBlockX() == e.getTo().getBlockX()
&& e.getFrom().getBlockY() == e.getTo().getBlockY()
&& e.getFrom().getBlockZ() == e.getTo().getBlockZ()) return;
lastMove.put(e.getPlayer().getUniqueId(), System.currentTimeMillis());
warnedAt.remove(e.getPlayer().getUniqueId());
}
} }
// ═══════════════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════════════

View File

@@ -12,6 +12,7 @@ import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.event.player.PlayerHarvestBlockEvent; import org.bukkit.event.player.PlayerHarvestBlockEvent;
import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
@@ -28,15 +29,38 @@ class BaseRaceHandler implements IEventHandler {
protected final String icon; protected final String icon;
protected final String name; protected final String name;
protected BukkitRunnable ticker; protected BukkitRunnable ticker;
private final java.util.Random rng = new java.util.Random();
BaseRaceHandler(EventEngine p, String icon, String name) { this.plugin=p; this.icon=icon; this.name=name; } BaseRaceHandler(EventEngine p, String icon, String name) { this.plugin=p; this.icon=icon; this.name=name; }
@Override public void onStart(ActiveEvent e) { @Override public void onStart(ActiveEvent e) {
Bukkit.broadcastMessage(plugin.prefix()+icon+" §e"+name+"! §7Bereitet euch vor — die Strecke ist bereit!"); Bukkit.broadcastMessage(plugin.prefix()+icon+" §e"+name+"! §7Bereitet euch vor — die Strecke ist bereit!");
teleportToStart(e);
warnIfMissingGoal(e);
ticker=new BukkitRunnable(){ @Override public void run(){ if(e.getState()==ActiveEvent.State.ENDED){cancel();return;} }}; ticker=new BukkitRunnable(){ @Override public void run(){ if(e.getState()==ActiveEvent.State.ENDED){cancel();return;} }};
ticker.runTaskTimer(plugin,20L,20L); ticker.runTaskTimer(plugin,20L,20L);
} }
@Override public void onEnd(ActiveEvent e){ if(ticker!=null)ticker.cancel(); } @Override public void onEnd(ActiveEvent e){ if(ticker!=null)ticker.cancel(); }
protected void teleportToStart(ActiveEvent e) {
var start = e.getDefinition().getStartRegion();
if (start == null) {
Bukkit.broadcastMessage(plugin.prefix() + "§e⚠ Kein Startbereich gesetzt. /event race start pos1/pos2 " + e.getDefinition().getId());
return;
}
for (UUID u : e.getParticipants()) {
Player p = Bukkit.getPlayer(u);
if (p == null) continue;
org.bukkit.Location loc = start.randomPoint(rng);
if (loc != null) p.teleport(loc);
}
}
protected void warnIfMissingGoal(ActiveEvent e) {
if (!e.getDefinition().hasGoalRegion()) {
Bukkit.broadcastMessage(plugin.prefix() + "§e⚠ Kein Zielbereich gesetzt. /event race goal pos1/pos2 " + e.getDefinition().getId());
}
}
} }
class ParkourRaceHandler extends BaseRaceHandler { class ParkourRaceHandler extends BaseRaceHandler {
@@ -367,30 +391,154 @@ class ColorWarHandler implements IEventHandler, Listener {
class TinyPlayersHandler implements IEventHandler { class TinyPlayersHandler implements IEventHandler {
private final EventEngine p; private final EventEngine p;
private final Map<UUID, Double> prevScale = new HashMap<>();
TinyPlayersHandler(EventEngine pp){this.p=pp;} TinyPlayersHandler(EventEngine pp){this.p=pp;}
@Override public void onStart(ActiveEvent e){ @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));} List<Player> players = new ArrayList<>();
if (e.getParticipants().isEmpty()) {
players.addAll(Bukkit.getOnlinePlayers());
} else {
for(UUID u:e.getParticipants()){Player pl=Bukkit.getPlayer(u);if(pl!=null)players.add(pl);}
}
for (Player pl : players) {
applyScale(pl, 0.6);
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!"); 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);}}} @Override public void onEnd(ActiveEvent e){
if (e.getParticipants().isEmpty()) {
for (Player pl : Bukkit.getOnlinePlayers()) {
restoreScale(pl);
pl.removePotionEffect(PotionEffectType.SLOWNESS);
pl.removePotionEffect(PotionEffectType.JUMP_BOOST);
}
} else {
for(UUID u:e.getParticipants()){
Player pl=Bukkit.getPlayer(u);
if(pl!=null){
restoreScale(pl);
pl.removePotionEffect(PotionEffectType.SLOWNESS);
pl.removePotionEffect(PotionEffectType.JUMP_BOOST);
}
}
}
prevScale.clear();
}
private void applyScale(Player pl, double scale) {
org.bukkit.attribute.Attribute attrType = getScaleAttribute();
if (attrType == null) return;
org.bukkit.attribute.AttributeInstance attr = pl.getAttribute(attrType);
if (attr == null) return;
prevScale.putIfAbsent(pl.getUniqueId(), attr.getBaseValue());
attr.setBaseValue(scale);
}
private void restoreScale(Player pl) {
org.bukkit.attribute.Attribute attrType = getScaleAttribute();
if (attrType == null) return;
org.bukkit.attribute.AttributeInstance attr = pl.getAttribute(attrType);
if (attr == null) return;
Double prev = prevScale.remove(pl.getUniqueId());
if (prev != null) attr.setBaseValue(prev);
}
private org.bukkit.attribute.Attribute getScaleAttribute() {
try {
return org.bukkit.attribute.Attribute.valueOf("GENERIC_SCALE");
} catch (IllegalArgumentException ex) {
return null;
}
}
} }
class GiantPlayersHandler implements IEventHandler { class GiantPlayersHandler implements IEventHandler {
private final EventEngine p; private final EventEngine p;
private final Map<UUID, Double> prevScale = new HashMap<>();
GiantPlayersHandler(EventEngine pp){this.p=pp;} GiantPlayersHandler(EventEngine pp){this.p=pp;}
@Override public void onStart(ActiveEvent e){ @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));} List<Player> players = new ArrayList<>();
if (e.getParticipants().isEmpty()) {
players.addAll(Bukkit.getOnlinePlayers());
} else {
for(UUID u:e.getParticipants()){Player pl=Bukkit.getPlayer(u);if(pl!=null)players.add(pl);}
}
for(Player pl:players){
applyScale(pl, 1.6);
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!"); 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);}}} @Override public void onEnd(ActiveEvent e){
if (e.getParticipants().isEmpty()) {
for (Player pl : Bukkit.getOnlinePlayers()) {
restoreScale(pl);
pl.removePotionEffect(PotionEffectType.SPEED);
pl.removePotionEffect(PotionEffectType.STRENGTH);
}
} else {
for(UUID u:e.getParticipants()){
Player pl=Bukkit.getPlayer(u);
if(pl!=null){
restoreScale(pl);
pl.removePotionEffect(PotionEffectType.SPEED);
pl.removePotionEffect(PotionEffectType.STRENGTH);
}
}
}
prevScale.clear();
}
private void applyScale(Player pl, double scale) {
org.bukkit.attribute.Attribute attrType = getScaleAttribute();
if (attrType == null) return;
org.bukkit.attribute.AttributeInstance attr = pl.getAttribute(attrType);
if (attr == null) return;
prevScale.putIfAbsent(pl.getUniqueId(), attr.getBaseValue());
attr.setBaseValue(scale);
}
private void restoreScale(Player pl) {
org.bukkit.attribute.Attribute attrType = getScaleAttribute();
if (attrType == null) return;
org.bukkit.attribute.AttributeInstance attr = pl.getAttribute(attrType);
if (attr == null) return;
Double prev = prevScale.remove(pl.getUniqueId());
if (prev != null) attr.setBaseValue(prev);
}
private org.bukkit.attribute.Attribute getScaleAttribute() {
try {
return org.bukkit.attribute.Attribute.valueOf("GENERIC_SCALE");
} catch (IllegalArgumentException ex) {
return null;
}
}
} }
class InvisiblePlayersHandler implements IEventHandler { class InvisiblePlayersHandler implements IEventHandler {
private final EventEngine p; private final EventEngine p;
InvisiblePlayersHandler(EventEngine pp){this.p=pp;} InvisiblePlayersHandler(EventEngine pp){this.p=pp;}
@Override public void onStart(ActiveEvent e){ @Override public void onStart(ActiveEvent e){
if (e.getParticipants().isEmpty()) {
for (Player pl : Bukkit.getOnlinePlayers()) {
pl.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY,e.getDefinition().getDurationSeconds()*20,0,false,false));
}
} else {
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));} 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!"); 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);}} @Override public void onEnd(ActiveEvent e){
if (e.getParticipants().isEmpty()) {
for (Player pl : Bukkit.getOnlinePlayers()) {
pl.removePotionEffect(PotionEffectType.INVISIBILITY);
}
} else {
for(UUID u:e.getParticipants()){Player pl=Bukkit.getPlayer(u);if(pl!=null)pl.removePotionEffect(PotionEffectType.INVISIBILITY);}
}
}
} }
class RandomTeleportHandler implements IEventHandler { class RandomTeleportHandler implements IEventHandler {
private final EventEngine plugin; private BukkitRunnable tpRunner; private final EventEngine plugin; private BukkitRunnable tpRunner;
@@ -398,7 +546,25 @@ class RandomTeleportHandler implements IEventHandler {
@Override public void onStart(ActiveEvent e){ @Override public void onStart(ActiveEvent e){
Bukkit.broadcastMessage(plugin.prefix()+"§d🌀 §eZufalls-TP! §7Alle 5 Sekunden wird jemand teleportiert!"); Bukkit.broadcastMessage(plugin.prefix()+"§d🌀 §eZufalls-TP! §7Alle 5 Sekunden wird jemand teleportiert!");
final Random rng=new Random(); 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=new BukkitRunnable(){@Override public void run(){
if(e.getState()==ActiveEvent.State.ENDED){cancel();return;}
if (e.getParticipants().isEmpty()) {
for (Player p : Bukkit.getOnlinePlayers()) {
if (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!");
}
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); tpRunner.runTaskTimer(plugin,20L,100L);
} }
@Override public void onEnd(ActiveEvent e){ if(tpRunner!=null)tpRunner.cancel(); } @Override public void onEnd(ActiveEvent e){ if(tpRunner!=null)tpRunner.cancel(); }
@@ -407,12 +573,20 @@ class SwapInventoriesHandler implements IEventHandler {
private final EventEngine p; private final EventEngine p;
SwapInventoriesHandler(EventEngine pp){this.p=pp;} SwapInventoriesHandler(EventEngine pp){this.p=pp;}
@Override public void onStart(ActiveEvent e){ @Override public void onStart(ActiveEvent e){
List<UUID>parts=new ArrayList<>(e.getParticipants()); List<Player> players = new ArrayList<>();
if(parts.size()<2){Bukkit.broadcastMessage(p.prefix()+"§cMindestens 2 Spieler benötigt!");return;} if (e.getParticipants().isEmpty()) {
Collections.shuffle(parts); players.addAll(Bukkit.getOnlinePlayers());
} else {
for (UUID u : e.getParticipants()) {
Player pl = Bukkit.getPlayer(u);
if (pl != null) players.add(pl);
}
}
if(players.size()<2){Bukkit.broadcastMessage(p.prefix()+"§cMindestens 2 Spieler benötigt!");return;}
Collections.shuffle(players);
List<ItemStack[]>inventories=new ArrayList<>(); 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(Player pl:players){inventories.add(pl.getInventory().getContents().clone());}
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()));} for(int i=0;i<players.size();i++){players.get(i).getInventory().setContents(inventories.get((i+1)%players.size()));}
Bukkit.broadcastMessage(p.prefix()+"§e🔄 §eInventar-Tausch! §7Alle Inventare wurden zufällig getauscht!"); Bukkit.broadcastMessage(p.prefix()+"§e🔄 §eInventar-Tausch! §7Alle Inventare wurden zufällig getauscht!");
} }
@Override public void onEnd(ActiveEvent e){} @Override public void onEnd(ActiveEvent e){}
@@ -423,7 +597,20 @@ class ReverseGravityHandler implements IEventHandler {
@Override public void onStart(ActiveEvent e){ @Override public void onStart(ActiveEvent e){
Bukkit.broadcastMessage(plugin.prefix()+"§9⬆ §eUmgekehrte Schwerkraft! §7Alle werden hochgezogen!"); Bukkit.broadcastMessage(plugin.prefix()+"§9⬆ §eUmgekehrte Schwerkraft! §7Alle werden hochgezogen!");
final Random rng=new Random(); 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=new BukkitRunnable(){@Override public void run(){
if(e.getState()==ActiveEvent.State.ENDED){cancel();return;}
if (e.getParticipants().isEmpty()) {
for (Player p : Bukkit.getOnlinePlayers()) {
p.setVelocity(p.getVelocity().setY(0.5 + rng.nextDouble() * 0.5));
}
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); ticker.runTaskTimer(plugin,20L,15L);
} }
@Override public void onEnd(ActiveEvent e){ if(ticker!=null)ticker.cancel(); } @Override public void onEnd(ActiveEvent e){ if(ticker!=null)ticker.cancel(); }

View File

@@ -0,0 +1,277 @@
package dev.viper.eventengine.gui;
import dev.viper.eventengine.EventEngine;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
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.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.Map;
import java.util.HashMap;
import java.util.Comparator;
public class ItemRainGUI implements Listener {
private static final String TITLE = "§8✦ §6Item-Regen §8✦ Items";
private final EventEngine plugin;
private final Map<UUID, Integer> pageMap = new HashMap<>();
private final Map<UUID, String> filterMap = new HashMap<>();
private final Map<UUID, SortMode> sortMap = new HashMap<>();
private final Set<UUID> awaitingSearch = new HashSet<>();
public ItemRainGUI(EventEngine plugin) {
this.plugin = plugin;
}
public void open(Player player) {
open(player, 0);
}
public void open(Player player, int page) {
Inventory inv = Bukkit.createInventory(null, 54, TITLE);
fillBorder(inv, Material.GRAY_STAINED_GLASS_PANE);
List<Material> items = applyFilterAndSort(player, plugin.getConfigManager().getItemRainItems());
int[] slots = buildContentSlots();
int perPage = slots.length;
int totalPages = Math.max(1, (int) Math.ceil(items.size() / (double) perPage));
page = Math.max(0, Math.min(page, totalPages - 1));
pageMap.put(player.getUniqueId(), page);
int start = page * perPage;
int end = Math.min(items.size(), start + perPage);
for (int i = start; i < end; i++) {
Material mat = items.get(i);
List<String> lore = List.of("§7Klicken zum Entfernen");
inv.setItem(slots[i - start], makeItem(mat, "§e" + mat.name(), lore));
}
if (page > 0) inv.setItem(45, makeItem(Material.ARROW, "§7◀ Zurueck", List.of("§7Seite " + page)));
if (page < totalPages - 1) inv.setItem(53, makeItem(Material.ARROW, "§7Weiter ▶", List.of("§7Seite " + (page + 2))));
inv.setItem(46, makeItem(Material.NAME_TAG, "§bSuche", List.of(
"§7Filter: §f" + currentFilter(player),
"§7Klicken um im Chat zu suchen"
)));
inv.setItem(47, makeItem(Material.HOPPER, "§eSortierung", List.of(
"§7" + sortLabel(player),
"§7Klicken um zu wechseln"
)));
inv.setItem(48, makeItem(Material.REDSTONE_BLOCK, "§cReset", List.of("§7Standard-Items wiederherstellen")));
inv.setItem(49, makeItem(Material.BARRIER, "§cSchliessen", List.of("§7GUI schliessen")));
inv.setItem(50, makeItem(Material.CHEST, "§aAus Inventar", List.of(
"§7Fuegt alle Items aus",
"§7deinem Inventar hinzu"
)));
inv.setItem(52, makeItem(Material.BOOK, "§aHinzufuegen", List.of(
"§7Lege ein Item auf den Cursor",
"§7und klicke auf einen freien Slot."
)));
player.openInventory(inv);
}
@EventHandler
public void onClick(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player player)) return;
if (!event.getView().getTitle().equals(TITLE)) return;
event.setCancelled(true);
ItemStack clicked = event.getCurrentItem();
ItemStack cursor = event.getCursor();
if (clicked != null && clicked.getType() == Material.BARRIER
&& clicked.getItemMeta() != null
&& clicked.getItemMeta().getDisplayName().contains("Schliessen")) {
player.closeInventory();
return;
}
List<Material> items = new ArrayList<>(plugin.getConfigManager().getItemRainItems());
Set<Material> itemSet = new HashSet<>(items);
if (clicked != null && clicked.getType() == Material.ARROW) {
int page = pageMap.getOrDefault(player.getUniqueId(), 0);
if (clicked.getItemMeta() != null && clicked.getItemMeta().getDisplayName().contains("Zurueck")) {
open(player, page - 1);
} else {
open(player, page + 1);
}
return;
}
if (clicked != null && clicked.getType() == Material.NAME_TAG) {
awaitingSearch.add(player.getUniqueId());
player.closeInventory();
player.sendMessage(plugin.prefix() + "§7Suche: Tippe einen Begriff im Chat (leer = Filter loeschen)." );
return;
}
if (clicked != null && clicked.getType() == Material.HOPPER) {
cycleSort(player);
open(player, 0);
return;
}
if (clicked != null && clicked.getType() == Material.CHEST) {
addAllFromInventory(player, items, itemSet);
plugin.getConfigManager().setItemRainItems(items);
open(player, 0);
return;
}
if (clicked != null && clicked.getType() == Material.REDSTONE_BLOCK
&& clicked.getItemMeta() != null
&& clicked.getItemMeta().getDisplayName().contains("Reset")) {
plugin.getConfigManager().resetItemRainItems();
open(player, 0);
return;
}
if (clicked != null && clicked.getType() != Material.AIR
&& clicked.getType() != Material.GRAY_STAINED_GLASS_PANE
&& clicked.getType() != Material.BOOK
&& clicked.getType() != Material.NAME_TAG
&& clicked.getType() != Material.HOPPER
&& clicked.getType() != Material.CHEST
&& clicked.getType() != Material.BARRIER
&& clicked.getType() != Material.REDSTONE_BLOCK) {
Material mat = clicked.getType();
items.remove(mat);
plugin.getConfigManager().setItemRainItems(items);
open(player, 0);
return;
}
if (cursor != null && cursor.getType() != Material.AIR) {
Material mat = cursor.getType();
if (!mat.isItem()) return;
if (!itemSet.contains(mat)) {
items.add(mat);
plugin.getConfigManager().setItemRainItems(items);
open(player, 0);
}
}
}
@EventHandler
public void onChat(AsyncPlayerChatEvent event) {
Player player = event.getPlayer();
if (!awaitingSearch.remove(player.getUniqueId())) return;
event.setCancelled(true);
String msg = event.getMessage().trim();
if (msg.isEmpty()) filterMap.remove(player.getUniqueId());
else filterMap.put(player.getUniqueId(), msg.toLowerCase());
Bukkit.getScheduler().runTask(plugin, () -> open(player, 0));
}
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() {
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();
}
private List<Material> applyFilterAndSort(Player player, List<Material> items) {
String filter = currentFilter(player);
List<Material> filtered = new ArrayList<>();
for (Material mat : items) {
if (filter.isEmpty() || mat.name().toLowerCase().contains(filter)) {
filtered.add(mat);
}
}
SortMode mode = sortMap.getOrDefault(player.getUniqueId(), SortMode.DEFAULT);
if (mode == SortMode.AZ) {
filtered.sort(Comparator.comparing(Material::name));
} else if (mode == SortMode.ZA) {
filtered.sort(Comparator.comparing(Material::name).reversed());
} else if (mode == SortMode.RARE) {
filtered.sort(Comparator.comparingInt(Material::getMaxStackSize));
} else if (mode == SortMode.COMMON) {
filtered.sort(Comparator.comparingInt(Material::getMaxStackSize).reversed());
}
return filtered;
}
private String currentFilter(Player player) {
return filterMap.getOrDefault(player.getUniqueId(), "");
}
private String sortLabel(Player player) {
SortMode mode = sortMap.getOrDefault(player.getUniqueId(), SortMode.DEFAULT);
return switch (mode) {
case DEFAULT -> "Sortierung: Standard";
case AZ -> "Sortierung: A-Z";
case ZA -> "Sortierung: Z-A";
case RARE -> "Sortierung: Selten (Stack)";
case COMMON -> "Sortierung: Haeufig (Stack)";
};
}
private void cycleSort(Player player) {
SortMode mode = sortMap.getOrDefault(player.getUniqueId(), SortMode.DEFAULT);
SortMode next = switch (mode) {
case DEFAULT -> SortMode.AZ;
case AZ -> SortMode.ZA;
case ZA -> SortMode.RARE;
case RARE -> SortMode.COMMON;
case COMMON -> SortMode.DEFAULT;
};
sortMap.put(player.getUniqueId(), next);
}
private void addAllFromInventory(Player player, List<Material> items, Set<Material> itemSet) {
for (ItemStack stack : player.getInventory().getContents()) {
if (stack == null || stack.getType() == Material.AIR) continue;
Material mat = stack.getType();
if (!mat.isItem()) continue;
if (itemSet.add(mat)) items.add(mat);
}
}
private enum SortMode {
DEFAULT,
AZ,
ZA,
RARE,
COMMON
}
}

View File

@@ -0,0 +1,55 @@
package dev.viper.eventengine.listener;
import dev.viper.eventengine.EventEngine;
import dev.viper.eventengine.model.ActiveEvent;
import dev.viper.eventengine.model.EventCategory;
import dev.viper.eventengine.model.EventDefinition;
import dev.viper.eventengine.model.EventRegion;
import dev.viper.eventengine.model.EventType;
import org.bukkit.Location;
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.PlayerMoveEvent;
public class RaceGoalListener implements Listener {
private final EventEngine plugin;
public RaceGoalListener(EventEngine plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onMove(PlayerMoveEvent e) {
ActiveEvent active = plugin.getEventManager().getCurrentEvent();
if (active == null || active.getState() != ActiveEvent.State.RUNNING) return;
Player player = e.getPlayer();
if (!active.isParticipant(player)) return;
EventDefinition def = active.getDefinition();
if (!isRaceEvent(def)) return;
EventRegion goal = def.getGoalRegion();
if (goal == null) return;
Location to = e.getTo();
if (to == null) return;
if (e.getFrom().getBlockX() == to.getBlockX()
&& e.getFrom().getBlockY() == to.getBlockY()
&& e.getFrom().getBlockZ() == to.getBlockZ()) return;
if (!goal.contains(to)) return;
if (active.hasWinner()) return;
plugin.getEventManager().endEventWithWinner(player, "Ziel erreicht");
}
private boolean isRaceEvent(EventDefinition def) {
if (def.getCategory() == EventCategory.RACING) return true;
return def.getType() == EventType.TEAM_RELAY_RACE;
}
}

View File

@@ -53,6 +53,7 @@ public class EventManager {
runCommands(def.getStartCommands(), null); runCommands(def.getStartCommands(), null);
handlerRegistry.get(def.getType()).ifPresent(h -> h.onStart(currentEvent)); handlerRegistry.get(def.getType()).ifPresent(h -> h.onStart(currentEvent));
plugin.getScoreboardManager().start(currentEvent);
if (def.getDurationSeconds() > 0) { if (def.getDurationSeconds() > 0) {
final ActiveEvent snap = currentEvent; final ActiveEvent snap = currentEvent;
@@ -87,6 +88,7 @@ public class EventManager {
Bukkit.getScheduler().cancelTask(currentEvent.getTaskId()); Bukkit.getScheduler().cancelTask(currentEvent.getTaskId());
handlerRegistry.get(def.getType()).ifPresent(h -> h.onEnd(currentEvent)); handlerRegistry.get(def.getType()).ifPresent(h -> h.onEnd(currentEvent));
plugin.getScoreboardManager().stop();
broadcast(plugin.prefix() + "§6✦ §e" + def.getDisplayName() broadcast(plugin.prefix() + "§6✦ §e" + def.getDisplayName()
+ " §7ist beendet! §7(" + reason + ")"); + " §7ist beendet! §7(" + reason + ")");
@@ -106,6 +108,16 @@ public class EventManager {
return true; return true;
} }
public boolean endEventWithWinner(Player winner, String reason) {
if (currentEvent == null || currentEvent.getState() == ActiveEvent.State.ENDED) return false;
if (winner != null) {
currentEvent.setWinner(winner.getUniqueId());
broadcast(plugin.prefix() + "§6🏁 " + winner.getName() + " §ehat das Ziel erreicht und gewinnt!");
distributeWinnerRewards(currentEvent.getDefinition(), winner);
}
return endEvent(reason);
}
public boolean join(Player player) { public boolean join(Player player) {
if (currentEvent == null || currentEvent.getState() == ActiveEvent.State.ENDED) { if (currentEvent == null || currentEvent.getState() == ActiveEvent.State.ENDED) {
player.sendMessage(plugin.prefix() + "§cKein Event aktiv."); return false; player.sendMessage(plugin.prefix() + "§cKein Event aktiv."); return false;
@@ -121,6 +133,7 @@ public class EventManager {
broadcast(plugin.prefix() + "§a" + player.getName() + " §7nimmt teil! §8(" broadcast(plugin.prefix() + "§a" + player.getName() + " §7nimmt teil! §8("
+ currentEvent.getParticipantCount() + "/" + def.getMaxPlayers() + ")"); + currentEvent.getParticipantCount() + "/" + def.getMaxPlayers() + ")");
handlerRegistry.get(def.getType()).ifPresent(h -> h.onPlayerJoin(currentEvent, player)); handlerRegistry.get(def.getType()).ifPresent(h -> h.onPlayerJoin(currentEvent, player));
plugin.getScoreboardManager().onJoin(player, currentEvent);
return true; return true;
} }
@@ -130,6 +143,7 @@ public class EventManager {
currentEvent.removeParticipant(player); currentEvent.removeParticipant(player);
handlerRegistry.get(currentEvent.getDefinition().getType()) handlerRegistry.get(currentEvent.getDefinition().getType())
.ifPresent(h -> h.onPlayerLeave(currentEvent, player)); .ifPresent(h -> h.onPlayerLeave(currentEvent, player));
plugin.getScoreboardManager().onLeave(player);
player.sendMessage(plugin.prefix() + "§7Du hast das Event verlassen."); player.sendMessage(plugin.prefix() + "§7Du hast das Event verlassen.");
} }
@@ -161,6 +175,11 @@ public class EventManager {
} }
} }
private void distributeWinnerRewards(EventDefinition def, Player winner) {
if (def.getWinnerRewards().isEmpty() || winner == null) return;
runCommands(def.getWinnerRewards(), winner);
}
private void runCommands(List<String> cmds, Player player) { private void runCommands(List<String> cmds, Player player) {
for (String cmd : cmds) { for (String cmd : cmds) {
String filled = player != null ? cmd.replace("%player%", player.getName()) : cmd; String filled = player != null ? cmd.replace("%player%", player.getName()) : cmd;

View File

@@ -0,0 +1,174 @@
package dev.viper.eventengine.manager;
import dev.viper.eventengine.EventEngine;
import dev.viper.eventengine.model.ActiveEvent;
import dev.viper.eventengine.model.EventDefinition;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Criteria;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
public class ScoreboardManager {
private static final String OBJECTIVE_NAME = "eventengine";
private final EventEngine plugin;
private BukkitRunnable ticker;
private ActiveEvent current;
private final Map<UUID, Scoreboard> boards = new HashMap<>();
private final Map<UUID, Scoreboard> previous = new HashMap<>();
public ScoreboardManager(EventEngine plugin) {
this.plugin = plugin;
}
public void start(ActiveEvent event) {
stop();
this.current = event;
ticker = new BukkitRunnable() {
@Override public void run() {
if (current == null || current.getState() != ActiveEvent.State.RUNNING) return;
for (UUID uuid : current.getParticipants()) {
Player p = Bukkit.getPlayer(uuid);
if (p == null) continue;
updateFor(p, current);
}
}
};
ticker.runTaskTimer(plugin, 0L, 20L);
}
public void stop() {
if (ticker != null) {
ticker.cancel();
ticker = null;
}
if (current != null) {
for (UUID uuid : current.getParticipants()) {
Player p = Bukkit.getPlayer(uuid);
if (p != null) clearFor(p);
}
}
current = null;
}
public void onJoin(Player player, ActiveEvent event) {
updateFor(player, event);
}
public void onLeave(Player player) {
clearFor(player);
}
private void updateFor(Player player, ActiveEvent event) {
org.bukkit.scoreboard.ScoreboardManager sm = Bukkit.getScoreboardManager();
if (sm == null) return;
Scoreboard sb = boards.get(player.getUniqueId());
if (sb == null) {
if (!previous.containsKey(player.getUniqueId())) {
previous.put(player.getUniqueId(), player.getScoreboard());
}
sb = sm.getNewScoreboard();
boards.put(player.getUniqueId(), sb);
player.setScoreboard(sb);
}
Objective obj = sb.getObjective(OBJECTIVE_NAME);
if (obj == null) {
obj = sb.registerNewObjective(OBJECTIVE_NAME, Criteria.DUMMY, titleFor(event.getDefinition()));
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
} else {
obj.setDisplayName(titleFor(event.getDefinition()));
}
for (String entry : new HashSet<>(sb.getEntries())) {
sb.resetScores(entry);
}
List<String> lines = buildLines(player, event);
int score = lines.size();
for (String line : lines) {
obj.getScore(line).setScore(score--);
}
}
private void clearFor(Player player) {
Scoreboard prev = previous.remove(player.getUniqueId());
if (prev != null) {
player.setScoreboard(prev);
} else {
org.bukkit.scoreboard.ScoreboardManager sm = Bukkit.getScoreboardManager();
if (sm != null) player.setScoreboard(sm.getMainScoreboard());
}
boards.remove(player.getUniqueId());
}
private List<String> buildLines(Player player, ActiveEvent event) {
EventDefinition def = event.getDefinition();
List<String> lines = new ArrayList<>();
lines.add("§7Event:");
lines.add("§f" + trim(def.getDisplayName(), 28));
lines.add("§7Kategorie: §f" + trim(def.getCategory().getDisplayName(), 16));
lines.add("§7Zeit: §f" + EventManager.formatTime((int) event.getRemainingSeconds()));
lines.add("§7Teilnehmer: §f" + event.getParticipantCount() + "/" + def.getMaxPlayers());
lines.add("§7Deine Punkte: §f" + event.getScore(player.getUniqueId()));
lines.add("§8----------------");
lines.add("§7Top 3:");
List<java.util.Map.Entry<UUID, Integer>> lb = event.getLeaderboard();
for (int i = 0; i < 3; i++) {
if (i >= lb.size()) {
lines.add("§8-" + (i + 1) + ". §f---");
continue;
}
UUID uuid = lb.get(i).getKey();
int pts = lb.get(i).getValue();
Player p = Bukkit.getPlayer(uuid);
String name = p != null ? p.getName() : "Unbekannt";
lines.add("§e" + (i + 1) + ". §f" + trim(name, 12) + " §7(" + pts + ")");
}
lines.add("§8");
return ensureUnique(lines);
}
private String titleFor(EventDefinition def) {
return trim("§6✦ §e" + def.getDisplayName(), 32);
}
private List<String> ensureUnique(List<String> lines) {
List<String> result = new ArrayList<>(lines.size());
Set<String> used = new HashSet<>();
int colorIndex = 0;
for (String line : lines) {
String unique = line;
while (used.contains(unique)) {
unique = line + "§" + Integer.toHexString(colorIndex % 16);
colorIndex++;
}
used.add(unique);
result.add(unique);
}
return result;
}
private String trim(String text, int maxLen) {
if (text == null) return "";
if (text.length() <= maxLen) return text;
return text.substring(0, Math.max(0, maxLen - 3)) + "...";
}
}

View File

@@ -17,6 +17,7 @@ public class ActiveEvent {
private final Set<UUID> participants; private final Set<UUID> participants;
private final Map<UUID, Integer> scores; private final Map<UUID, Integer> scores;
private int taskId = -1; private int taskId = -1;
private UUID winner;
public ActiveEvent(EventDefinition definition) { public ActiveEvent(EventDefinition definition) {
this.definition = definition; this.definition = definition;
@@ -24,6 +25,7 @@ public class ActiveEvent {
this.startTime = System.currentTimeMillis(); this.startTime = System.currentTimeMillis();
this.participants = new LinkedHashSet<>(); this.participants = new LinkedHashSet<>();
this.scores = new HashMap<>(); this.scores = new HashMap<>();
this.winner = null;
} }
public void addParticipant(Player player) { public void addParticipant(Player player) {
@@ -72,4 +74,7 @@ public class ActiveEvent {
public int getTaskId() { return taskId; } public int getTaskId() { return taskId; }
public void setTaskId(int taskId) { this.taskId = taskId; } public void setTaskId(int taskId) { this.taskId = taskId; }
public int getParticipantCount() { return participants.size(); } public int getParticipantCount() { return participants.size(); }
public UUID getWinner() { return winner; }
public void setWinner(UUID winner) { this.winner = winner; }
public boolean hasWinner() { return winner != null; }
} }

View File

@@ -34,12 +34,17 @@ public class EventDefinition {
private boolean inRotation; private boolean inRotation;
// Gewichtung in der Rotation // Gewichtung in der Rotation
private int weight; private int weight;
// Optionaler Start-/Zielbereich (Rennen)
private EventRegion startRegion;
private EventRegion goalRegion;
// Custom-Einstellungen (Key-Value) // Custom-Einstellungen (Key-Value)
private Map<String, Object> customSettings; private Map<String, Object> customSettings;
// Ist es ein benutzerdefiniertes Event? // Ist es ein benutzerdefiniertes Event?
private boolean isCustom; private boolean isCustom;
// Optionale Event-Region (null = gesamte Welt) // Optionale Event-Region (null = gesamte Welt)
private EventRegion region; private EventRegion region;
// Winner-Belohnungen (nur Sieger)
private List<String> winnerRewards;
// ─── Konstruktor für builtin Events ──────────────────────────────────── // ─── Konstruktor für builtin Events ────────────────────────────────────
public EventDefinition(EventType type) { public EventDefinition(EventType type) {
@@ -57,8 +62,11 @@ public class EventDefinition {
this.announcement = ColorUtil.color("&6✦ &e" + displayName + " &6startet jetzt!"); this.announcement = ColorUtil.color("&6✦ &e" + displayName + " &6startet jetzt!");
this.inRotation = true; this.inRotation = true;
this.weight = 1; this.weight = 1;
this.startRegion = null;
this.goalRegion = null;
this.customSettings = new HashMap<>(); this.customSettings = new HashMap<>();
this.isCustom = false; this.isCustom = false;
this.winnerRewards = new ArrayList<>();
} }
// ─── Konstruktor für Custom Events ───────────────────────────────────── // ─── Konstruktor für Custom Events ─────────────────────────────────────
@@ -77,8 +85,11 @@ public class EventDefinition {
this.announcement = ColorUtil.color("&6✦ &e" + id + " &6startet jetzt!"); this.announcement = ColorUtil.color("&6✦ &e" + id + " &6startet jetzt!");
this.inRotation = true; this.inRotation = true;
this.weight = 1; this.weight = 1;
this.startRegion = null;
this.goalRegion = null;
this.customSettings = new HashMap<>(); this.customSettings = new HashMap<>();
this.isCustom = true; this.isCustom = true;
this.winnerRewards = new ArrayList<>();
} }
// ─── Laden aus ConfigurationSection ──────────────────────────────────── // ─── Laden aus ConfigurationSection ────────────────────────────────────
@@ -96,6 +107,7 @@ public class EventDefinition {
"&6✦ &e" + def.displayName + " &6startet jetzt!")); "&6✦ &e" + def.displayName + " &6startet jetzt!"));
def.inRotation = sec.getBoolean("in-rotation", true); def.inRotation = sec.getBoolean("in-rotation", true);
def.weight = sec.getInt("weight", 1); def.weight = sec.getInt("weight", 1);
def.winnerRewards = sec.getStringList("winner-rewards");
String catStr = sec.getString("category", "CUSTOM"); String catStr = sec.getString("category", "CUSTOM");
try { def.category = EventCategory.valueOf(catStr); } try { def.category = EventCategory.valueOf(catStr); }
catch (Exception e) { def.category = EventCategory.CUSTOM; } catch (Exception e) { def.category = EventCategory.CUSTOM; }
@@ -120,6 +132,32 @@ public class EventDefinition {
def.region = new EventRegion(w, minX, minY, minZ, maxX, maxY, maxZ); def.region = new EventRegion(w, minX, minY, minZ, maxX, maxY, maxZ);
} catch (Exception ignored) {} } catch (Exception ignored) {}
} }
// Start-/Zielregion laden
if (sec.contains("start-region.world")) {
try {
String w = sec.getString("start-region.world");
int minX = sec.getInt("start-region.min-x");
int minY = sec.getInt("start-region.min-y");
int minZ = sec.getInt("start-region.min-z");
int maxX = sec.getInt("start-region.max-x");
int maxY = sec.getInt("start-region.max-y");
int maxZ = sec.getInt("start-region.max-z");
def.startRegion = new EventRegion(w, minX, minY, minZ, maxX, maxY, maxZ);
} catch (Exception ignored) {}
}
if (sec.contains("goal-region.world")) {
try {
String w = sec.getString("goal-region.world");
int minX = sec.getInt("goal-region.min-x");
int minY = sec.getInt("goal-region.min-y");
int minZ = sec.getInt("goal-region.min-z");
int maxX = sec.getInt("goal-region.max-x");
int maxY = sec.getInt("goal-region.max-y");
int maxZ = sec.getInt("goal-region.max-z");
def.goalRegion = new EventRegion(w, minX, minY, minZ, maxX, maxY, maxZ);
} catch (Exception ignored) {}
}
return def; return def;
} }
@@ -136,6 +174,7 @@ public class EventDefinition {
sec.set("announcement", announcement); sec.set("announcement", announcement);
sec.set("in-rotation", inRotation); sec.set("in-rotation", inRotation);
sec.set("weight", weight); sec.set("weight", weight);
sec.set("winner-rewards", winnerRewards);
sec.set("category", category.name()); sec.set("category", category.name());
if (region != null) { if (region != null) {
sec.set("region.world", region.getWorldName()); sec.set("region.world", region.getWorldName());
@@ -146,6 +185,24 @@ public class EventDefinition {
sec.set("region.max-y", region.getMaxY()); sec.set("region.max-y", region.getMaxY());
sec.set("region.max-z", region.getMaxZ()); sec.set("region.max-z", region.getMaxZ());
} }
if (startRegion != null) {
sec.set("start-region.world", startRegion.getWorldName());
sec.set("start-region.min-x", startRegion.getMinX());
sec.set("start-region.min-y", startRegion.getMinY());
sec.set("start-region.min-z", startRegion.getMinZ());
sec.set("start-region.max-x", startRegion.getMaxX());
sec.set("start-region.max-y", startRegion.getMaxY());
sec.set("start-region.max-z", startRegion.getMaxZ());
}
if (goalRegion != null) {
sec.set("goal-region.world", goalRegion.getWorldName());
sec.set("goal-region.min-x", goalRegion.getMinX());
sec.set("goal-region.min-y", goalRegion.getMinY());
sec.set("goal-region.min-z", goalRegion.getMinZ());
sec.set("goal-region.max-x", goalRegion.getMaxX());
sec.set("goal-region.max-y", goalRegion.getMaxY());
sec.set("goal-region.max-z", goalRegion.getMaxZ());
}
if (!customSettings.isEmpty()) { if (!customSettings.isEmpty()) {
for (Map.Entry<String, Object> entry : customSettings.entrySet()) { for (Map.Entry<String, Object> entry : customSettings.entrySet()) {
sec.set("settings." + entry.getKey(), entry.getValue()); sec.set("settings." + entry.getKey(), entry.getValue());
@@ -174,6 +231,8 @@ public class EventDefinition {
public void setEndCommands(List<String> l) { this.endCommands = l; } public void setEndCommands(List<String> l) { this.endCommands = l; }
public List<String> getRewards() { return rewards; } public List<String> getRewards() { return rewards; }
public void setRewards(List<String> l) { this.rewards = l; } public void setRewards(List<String> l) { this.rewards = l; }
public List<String> getWinnerRewards() { return winnerRewards; }
public void setWinnerRewards(List<String> l) { this.winnerRewards = l; }
public String getAnnouncement() { return announcement; } public String getAnnouncement() { return announcement; }
public void setAnnouncement(String a) { this.announcement = ColorUtil.color(a); } public void setAnnouncement(String a) { this.announcement = ColorUtil.color(a); }
public boolean isInRotation() { return inRotation; } public boolean isInRotation() { return inRotation; }
@@ -185,6 +244,12 @@ public class EventDefinition {
public EventRegion getRegion() { return region; } public EventRegion getRegion() { return region; }
public void setRegion(EventRegion r) { this.region = r; } public void setRegion(EventRegion r) { this.region = r; }
public boolean hasRegion() { return region != null; } public boolean hasRegion() { return region != null; }
public EventRegion getStartRegion() { return startRegion; }
public void setStartRegion(EventRegion r) { this.startRegion = r; }
public boolean hasStartRegion() { return startRegion != null; }
public EventRegion getGoalRegion() { return goalRegion; }
public void setGoalRegion(EventRegion r) { this.goalRegion = r; }
public boolean hasGoalRegion() { return goalRegion != null; }
public Object getSetting(String key) { return customSettings.get(key); } public Object getSetting(String key) { return customSettings.get(key); }
public void setSetting(String key, Object val) { customSettings.put(key, val); } public void setSetting(String key, Object val) { customSettings.put(key, val); }
} }

View File

@@ -79,6 +79,16 @@ public class EventRegion {
return new Location(world, x + 0.5, y, z + 0.5); return new Location(world, x + 0.5, y, z + 0.5);
} }
/** Zufälliger Punkt direkt innerhalb der Region (ohne Geländeprüfung) */
public Location randomPoint(java.util.Random rng) {
World world = Bukkit.getWorld(worldName);
if (world == null) return null;
int x = minX + rng.nextInt(Math.max(1, maxX - minX + 1));
int y = minY + rng.nextInt(Math.max(1, maxY - minY + 1));
int z = minZ + rng.nextInt(Math.max(1, maxZ - minZ + 1));
return new Location(world, x + 0.5, y + 0.1, z + 0.5);
}
public World getWorld() { return Bukkit.getWorld(worldName); } public World getWorld() { return Bukkit.getWorld(worldName); }
public String getWorldName() { return worldName; } public String getWorldName() { return worldName; }
public int getMinX() { return minX; } public int getMinX() { return minX; }

View File

@@ -104,7 +104,7 @@ public enum EventType {
FUN_SWAP_INVENTORIES("Inventar-Tausch", EventCategory.FUN), FUN_SWAP_INVENTORIES("Inventar-Tausch", EventCategory.FUN),
FUN_REVERSE_GRAVITY("Umgekehrte Schwerkraft", EventCategory.FUN), FUN_REVERSE_GRAVITY("Umgekehrte Schwerkraft", EventCategory.FUN),
FUN_SPEED_BOOST("Geschwindigkeits-Boost", EventCategory.FUN), FUN_SPEED_BOOST("Geschwindigkeits-Boost", EventCategory.FUN),
FUN_BOUNCY_BLOCKS("Hüpfende Blöcke", EventCategory.FUN), FUN_BOUNCY_BLOCKS("Jump-Funn", EventCategory.FUN),
// ═══════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════
// QUIZ & KNOWLEDGE EVENTS (5) // QUIZ & KNOWLEDGE EVENTS (5)

View File

@@ -119,3 +119,17 @@ protection:
no-explosion-block-damage: true no-explosion-block-damage: true
# Teilnehmer können nur innerhalb der Region Blöcke abbauen/setzen # Teilnehmer können nur innerhalb der Region Blöcke abbauen/setzen
restrict-block-interaction: true restrict-block-interaction: true
# ── Item-Regen ──────────────────────────────────────────────────
item-rain:
# Items, die vom Himmel fallen (Material-Namen)
items:
- DIAMOND
- GOLD_INGOT
- IRON_INGOT
- EMERALD
- COAL
- BREAD
- ARROW
- GOLDEN_APPLE
- EXPERIENCE_BOTTLE