Update from Git Manager GUI
This commit is contained in:
@@ -22,7 +22,8 @@ import de.nexuslobby.modules.intro.IntroModule;
|
||||
import de.nexuslobby.modules.border.BorderModule;
|
||||
import de.nexuslobby.modules.parkour.ParkourManager;
|
||||
import de.nexuslobby.modules.parkour.ParkourListener;
|
||||
import de.nexuslobby.modules.player.PlayerInspectModule; // NEU
|
||||
import de.nexuslobby.modules.player.PlayerInspectModule;
|
||||
import de.nexuslobby.modules.ball.SoccerModule; // NEU
|
||||
import de.nexuslobby.utils.*;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
@@ -67,6 +68,7 @@ public class NexusLobby extends JavaPlugin implements Listener {
|
||||
private IntroModule introModule;
|
||||
private BorderModule borderModule;
|
||||
private ParkourManager parkourManager;
|
||||
private SoccerModule soccerModule; // NEU
|
||||
|
||||
private ConversationManager conversationManager;
|
||||
|
||||
@@ -94,6 +96,10 @@ public class NexusLobby extends JavaPlugin implements Listener {
|
||||
return parkourManager;
|
||||
}
|
||||
|
||||
public SoccerModule getSoccerModule() { // NEU
|
||||
return soccerModule;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
@@ -233,7 +239,11 @@ public class NexusLobby extends JavaPlugin implements Listener {
|
||||
moduleManager.registerModule(tablistModule);
|
||||
|
||||
// Player Inspect Modul registrieren
|
||||
moduleManager.registerModule(new PlayerInspectModule()); // NEU
|
||||
moduleManager.registerModule(new PlayerInspectModule());
|
||||
|
||||
// Soccer Modul registrieren
|
||||
this.soccerModule = new SoccerModule(); // NEU
|
||||
moduleManager.registerModule(this.soccerModule); // NEU
|
||||
|
||||
this.portalManager = new PortalManager(this);
|
||||
moduleManager.registerModule(portalManager);
|
||||
|
||||
@@ -32,7 +32,7 @@ public class LobbyTabCompleter implements TabCompleter {
|
||||
if (cmdName.equals("nexuslobby") || cmdName.equals("nexus")) {
|
||||
if (args.length == 1) {
|
||||
if (sender.hasPermission("nexuslobby.admin")) {
|
||||
suggestions.addAll(Arrays.asList("reload", "setspawn", "silentjoin", "parkour"));
|
||||
suggestions.addAll(Arrays.asList("reload", "setspawn", "silentjoin", "parkour", "ball")); // NEU: ball
|
||||
}
|
||||
suggestions.add("sb");
|
||||
} else if (args.length == 2) {
|
||||
@@ -45,6 +45,10 @@ public class LobbyTabCompleter implements TabCompleter {
|
||||
suggestions.addAll(Arrays.asList("on", "off"));
|
||||
} else if (args[0].equalsIgnoreCase("parkour")) {
|
||||
suggestions.addAll(Arrays.asList("setstart", "setfinish", "setcheckpoint", "reset", "clear", "removeall"));
|
||||
} else if (args[0].equalsIgnoreCase("ball")) { // NEU: Ball Subcommands
|
||||
if (sender.hasPermission("nexuslobby.admin")) {
|
||||
suggestions.addAll(Arrays.asList("setspawn", "reload"));
|
||||
}
|
||||
}
|
||||
} else if (args.length == 3) {
|
||||
if (args[0].equalsIgnoreCase("parkour") && args[1].equalsIgnoreCase("setcheckpoint")) {
|
||||
@@ -118,7 +122,6 @@ public class LobbyTabCompleter implements TabCompleter {
|
||||
} else if (args[0].equalsIgnoreCase("name")) {
|
||||
suggestions.addAll(Arrays.asList("<Anzeigename>", "none"));
|
||||
} else if (args[0].equalsIgnoreCase("conv")) {
|
||||
// ERWEITERT: select3 und select4 hinzugefügt
|
||||
suggestions.addAll(Arrays.asList("select1", "select2", "select3", "select4", "link", "unlink", "start"));
|
||||
} else if (args[0].equalsIgnoreCase("remove")) {
|
||||
suggestions.addAll(Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "all"));
|
||||
|
||||
@@ -110,6 +110,13 @@ public class NexusLobbyCommand implements CommandExecutor {
|
||||
handleScoreboard(player, args);
|
||||
break;
|
||||
|
||||
case "ball": // NEU: Weiterleitung an das SoccerModule
|
||||
if (NexusLobby.getInstance().getSoccerModule() != null) {
|
||||
return NexusLobby.getInstance().getSoccerModule().onCommand(sender, command, label, args);
|
||||
}
|
||||
player.sendMessage("§cDas Fußball-Modul ist nicht geladen.");
|
||||
break;
|
||||
|
||||
case "parkour":
|
||||
if (args.length < 2) {
|
||||
player.sendMessage("§8[§6Nexus§8] §7Nutze: §e/nexus parkour <setstart|setfinish|setcheckpoint|reset|clear|removeall>");
|
||||
@@ -225,6 +232,7 @@ public class NexusLobbyCommand implements CommandExecutor {
|
||||
player.sendMessage("§f/spawn §7- Zum Spawn");
|
||||
player.sendMessage("§f/setstart §8| §f/setcheckpoint §8| §f/setfinish");
|
||||
player.sendMessage("§f/nexus parkour removeall §7- Strecke löschen");
|
||||
player.sendMessage("§f/nexus ball setspawn §7- Fußball Spawn setzen"); // NEU
|
||||
player.sendMessage("§f/nexus setspawn §7- Spawn setzen");
|
||||
player.sendMessage("§f/nexus sb <on|off> §7- Scoreboard");
|
||||
player.sendMessage("§f/nexus reload §7- Config laden");
|
||||
|
||||
312
src/main/java/de/nexuslobby/modules/ball/SoccerModule.java
Normal file
312
src/main/java/de/nexuslobby/modules/ball/SoccerModule.java
Normal file
@@ -0,0 +1,312 @@
|
||||
package de.nexuslobby.modules.ball;
|
||||
|
||||
import de.nexuslobby.NexusLobby;
|
||||
import de.nexuslobby.api.Module;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.profile.PlayerProfile;
|
||||
import org.bukkit.profile.PlayerTextures;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.UUID;
|
||||
import java.util.Objects;
|
||||
|
||||
public class SoccerModule implements Module, Listener, CommandExecutor {
|
||||
|
||||
private ArmorStand ball;
|
||||
private Location spawnLocation;
|
||||
private long lastMoveTime;
|
||||
private final String TEXTURE_URL = "http://textures.minecraft.net/texture/451f8cfcfb85d77945dc6a3618414093e70436b46d2577b28c727f1329b7265e";
|
||||
private final String BALL_TAG = "nexusball_entity"; // Eindeutiges Tag zur Identifizierung
|
||||
private final String BALL_NAME = "§x§N§e§x§u§s§B§a§l§l"; // Zusätzliche Erkennung
|
||||
|
||||
@Override
|
||||
public String getName() { return "Soccer"; }
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
Bukkit.getPluginManager().registerEvents(this, NexusLobby.getInstance());
|
||||
if (NexusLobby.getInstance().getCommand("nexuslobby") != null) {
|
||||
Objects.requireNonNull(NexusLobby.getInstance().getCommand("nexuslobby")).setExecutor(this);
|
||||
}
|
||||
|
||||
loadConfigLocation();
|
||||
|
||||
// AGGRESSIVES MEHRFACHES CLEANUP-SYSTEM
|
||||
// 1. Sofort beim Enable
|
||||
removeAllOldBallsGlobal();
|
||||
|
||||
// 2. Nach 0.5 Sekunden
|
||||
Bukkit.getScheduler().runTaskLater(NexusLobby.getInstance(), this::removeAllOldBallsGlobal, 10L);
|
||||
|
||||
// 3. Nach 1 Sekunde
|
||||
Bukkit.getScheduler().runTaskLater(NexusLobby.getInstance(), this::removeAllOldBallsGlobal, 20L);
|
||||
|
||||
// 4. Nach 2 Sekunden - cleanup und dann spawnen
|
||||
Bukkit.getScheduler().runTaskLater(NexusLobby.getInstance(), () -> {
|
||||
removeAllOldBallsGlobal();
|
||||
spawnBall();
|
||||
}, 40L);
|
||||
|
||||
// 5. Nach 3 Sekunden - finales Cleanup für hartnäckige Duplikate
|
||||
Bukkit.getScheduler().runTaskLater(NexusLobby.getInstance(), this::removeAllOldBallsGlobal, 60L);
|
||||
|
||||
// 6. Nach 5 Sekunden - letzter Check
|
||||
Bukkit.getScheduler().runTaskLater(NexusLobby.getInstance(), this::removeAllOldBallsGlobal, 100L);
|
||||
|
||||
// Haupt-Physik & Anti-Klon Tick
|
||||
Bukkit.getScheduler().runTaskTimer(NexusLobby.getInstance(), () -> {
|
||||
|
||||
// ANTI-KLON-SYSTEM: Prüfe die Umgebung des Spawns auf illegale Kopien
|
||||
if (spawnLocation != null && spawnLocation.getWorld() != null) {
|
||||
for (Entity entity : spawnLocation.getWorld().getNearbyEntities(spawnLocation, 50, 50, 50)) {
|
||||
if (entity instanceof ArmorStand stand) {
|
||||
// Wenn der ArmorStand unser Tag hat, aber nicht unsere aktive Instanz ist -> Löschen
|
||||
if (stand.getScoreboardTags().contains(BALL_TAG)) {
|
||||
if (ball == null || !stand.getUniqueId().equals(ball.getUniqueId())) {
|
||||
stand.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ball == null || !ball.isValid()) return;
|
||||
|
||||
Vector vel = ball.getVelocity();
|
||||
double speed = vel.length();
|
||||
|
||||
handleWallBounce(vel);
|
||||
handleParticles(speed);
|
||||
|
||||
// Dribbel-Logik
|
||||
for (Entity nearby : ball.getNearbyEntities(0.7, 0.5, 0.7)) {
|
||||
if (nearby instanceof Player p) {
|
||||
Vector direction = ball.getLocation().toVector().subtract(p.getLocation().toVector());
|
||||
if (direction.lengthSquared() > 0) {
|
||||
direction.normalize();
|
||||
direction.setY(0.12);
|
||||
ball.setVelocity(direction.multiply(0.35));
|
||||
}
|
||||
lastMoveTime = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
// Automatischer Respawn bei Inaktivität oder Void
|
||||
long delay = NexusLobby.getInstance().getConfig().getLong("ball.respawn_delay", 60) * 1000;
|
||||
if (System.currentTimeMillis() - lastMoveTime > delay || ball.getLocation().getY() < -5) {
|
||||
respawnBall();
|
||||
}
|
||||
}, 1L, 1L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scannt ALLE Welten nach Entities mit dem BALL_TAG und entfernt sie.
|
||||
* Nutzt mehrere Erkennungsmethoden für maximale Sicherheit.
|
||||
*/
|
||||
private void removeAllOldBallsGlobal() {
|
||||
int removed = 0;
|
||||
// Alle Welten durchsuchen
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
for (Entity entity : world.getEntities()) {
|
||||
if (entity instanceof ArmorStand stand) {
|
||||
boolean shouldRemove = false;
|
||||
|
||||
// Methode 1: Tag-basiert
|
||||
if (stand.getScoreboardTags().contains(BALL_TAG)) {
|
||||
shouldRemove = true;
|
||||
}
|
||||
|
||||
// Methode 2: Name-basiert (falls Tags verloren gehen)
|
||||
if (stand.getCustomName() != null && stand.getCustomName().equals(BALL_NAME)) {
|
||||
shouldRemove = true;
|
||||
}
|
||||
|
||||
// Methode 3: Kopf-Textur-basiert (prüfe ob es ein Soccer-Ball Kopf ist)
|
||||
if (stand.getEquipment() != null && stand.getEquipment().getHelmet() != null) {
|
||||
ItemStack helmet = stand.getEquipment().getHelmet();
|
||||
if (helmet.getType() == Material.PLAYER_HEAD && helmet.hasItemMeta()) {
|
||||
SkullMeta meta = (SkullMeta) helmet.getItemMeta();
|
||||
if (meta.hasOwner() && meta.getOwnerProfile() != null) {
|
||||
PlayerProfile profile = meta.getOwnerProfile();
|
||||
if (profile.getName() != null && profile.getName().equals("SoccerBall")) {
|
||||
shouldRemove = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Methode 4: Position-basiert - Entferne alle unsichtbaren, kleinen ArmorStands in der Nähe des Spawns
|
||||
if (spawnLocation != null && spawnLocation.getWorld() != null &&
|
||||
stand.getWorld().equals(spawnLocation.getWorld()) &&
|
||||
stand.isSmall() && stand.isInvisible() && !stand.hasBasePlate()) {
|
||||
|
||||
double distance = stand.getLocation().distance(spawnLocation);
|
||||
// Wenn innerhalb von 5 Blöcken vom Spawn und hat einen Kopf
|
||||
if (distance < 5.0 && stand.getEquipment() != null &&
|
||||
stand.getEquipment().getHelmet() != null &&
|
||||
stand.getEquipment().getHelmet().getType() == Material.PLAYER_HEAD) {
|
||||
shouldRemove = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Nur entfernen wenn es NICHT unsere aktuelle Ball-Instanz ist
|
||||
if (shouldRemove && (ball == null || !stand.getUniqueId().equals(ball.getUniqueId()))) {
|
||||
stand.remove();
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removed > 0) {
|
||||
Bukkit.getLogger().info("[NexusLobby] " + removed + " alte Ball-Entities entfernt.");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleWallBounce(Vector vel) {
|
||||
if (vel.lengthSquared() < 0.001) return;
|
||||
Location loc = ball.getLocation();
|
||||
Block nextX = loc.clone().add(vel.getX() * 1.3, 0.5, 0).getBlock();
|
||||
Block nextZ = loc.clone().add(0, 0.5, vel.getZ() * 1.3).getBlock();
|
||||
|
||||
boolean bounced = false;
|
||||
if (nextX.getType().isSolid()) { vel.setX(-vel.getX() * 0.75); bounced = true; }
|
||||
if (nextZ.getType().isSolid()) { vel.setZ(-vel.getZ() * 0.75); bounced = true; }
|
||||
|
||||
if (bounced) {
|
||||
ball.setVelocity(vel);
|
||||
ball.getWorld().playSound(ball.getLocation(), Sound.BLOCK_WOOD_BREAK, 0.6f, 1.3f);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleParticles(double speed) {
|
||||
if (speed < 0.05) return;
|
||||
Location loc = ball.getLocation().add(0, 0.2, 0);
|
||||
World world = loc.getWorld();
|
||||
if (world == null) return;
|
||||
|
||||
if (speed > 0.85) world.spawnParticle(Particle.SONIC_BOOM, loc, 1, 0, 0, 0, 0);
|
||||
else if (speed > 0.45) world.spawnParticle(Particle.CRIT, loc, 3, 0.1, 0.1, 0.1, 0.08);
|
||||
else world.spawnParticle(Particle.SMOKE, loc, 1, 0.05, 0, 0.05, 0.02);
|
||||
}
|
||||
|
||||
private void spawnBall() {
|
||||
if (spawnLocation == null || (ball != null && ball.isValid())) return;
|
||||
|
||||
// Ball direkt auf dem Boden spawnen (keine Y-Offset Erhöhung)
|
||||
Location spawnLoc = spawnLocation.clone();
|
||||
ball = (ArmorStand) spawnLoc.getWorld().spawnEntity(spawnLoc, EntityType.ARMOR_STAND);
|
||||
|
||||
ball.setInvisible(true);
|
||||
ball.setGravity(true);
|
||||
ball.setBasePlate(false);
|
||||
ball.setSmall(true);
|
||||
ball.setInvulnerable(false);
|
||||
ball.setArms(false);
|
||||
ball.setCustomNameVisible(false);
|
||||
|
||||
// Setze Custom Name für zusätzliche Erkennung (unsichtbar für Spieler)
|
||||
ball.setCustomName(BALL_NAME);
|
||||
|
||||
// Deaktiviert das Speichern in der Welt-Datei
|
||||
ball.setPersistent(false);
|
||||
// Markiert den Ball für das Cleanup-System
|
||||
ball.addScoreboardTag(BALL_TAG);
|
||||
|
||||
ItemStack ballHead = getSoccerHead();
|
||||
if (ball.getEquipment() != null) ball.getEquipment().setHelmet(ballHead);
|
||||
lastMoveTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private ItemStack getSoccerHead() {
|
||||
ItemStack head = new ItemStack(Material.PLAYER_HEAD);
|
||||
SkullMeta meta = (SkullMeta) head.getItemMeta();
|
||||
if (meta == null) return head;
|
||||
|
||||
PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), "SoccerBall");
|
||||
try {
|
||||
profile.getTextures().setSkin(new URL(TEXTURE_URL));
|
||||
} catch (MalformedURLException ignored) {}
|
||||
meta.setOwnerProfile(profile);
|
||||
|
||||
head.setItemMeta(meta);
|
||||
return head;
|
||||
}
|
||||
|
||||
public void respawnBall() {
|
||||
if (ball != null) {
|
||||
ball.remove();
|
||||
ball = null;
|
||||
}
|
||||
removeAllOldBallsGlobal();
|
||||
spawnBall();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBallPunch(EntityDamageByEntityEvent event) {
|
||||
if (event.getEntity().equals(ball)) {
|
||||
event.setCancelled(true);
|
||||
if (event.getDamager() instanceof Player p) {
|
||||
Vector shootDir = p.getLocation().getDirection();
|
||||
if (shootDir.lengthSquared() > 0) {
|
||||
shootDir.normalize().multiply(1.35).setY(0.38);
|
||||
ball.setVelocity(shootDir);
|
||||
}
|
||||
ball.getWorld().playSound(ball.getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 0.6f, 1.5f);
|
||||
lastMoveTime = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBallInteract(PlayerInteractAtEntityEvent event) {
|
||||
if (event.getRightClicked().equals(ball)) event.setCancelled(true);
|
||||
}
|
||||
|
||||
private void loadConfigLocation() {
|
||||
FileConfiguration config = NexusLobby.getInstance().getConfig();
|
||||
if (config.contains("ball.spawn")) spawnLocation = config.getLocation("ball.spawn");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!(sender instanceof Player p) || !p.hasPermission("nexuslobby.admin")) return true;
|
||||
|
||||
if (args.length >= 2 && args[0].equalsIgnoreCase("ball")) {
|
||||
if (args[1].equalsIgnoreCase("setspawn")) {
|
||||
spawnLocation = p.getLocation();
|
||||
NexusLobby.getInstance().getConfig().set("ball.spawn", spawnLocation);
|
||||
NexusLobby.getInstance().saveConfig();
|
||||
respawnBall();
|
||||
p.sendMessage("§8[§6Nexus§8] §aBall-Spawn gesetzt. Cleanup ist aktiv!");
|
||||
return true;
|
||||
} else if (args[1].equalsIgnoreCase("respawn")) {
|
||||
respawnBall();
|
||||
p.sendMessage("§8[§6Nexus§8] §eBall manuell respawnt.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (ball != null) ball.remove();
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package de.nexuslobby.modules.gadgets;
|
||||
import de.nexuslobby.NexusLobby;
|
||||
import de.nexuslobby.api.Module;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
@@ -15,6 +16,7 @@ import org.bukkit.event.player.PlayerFishEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
@@ -59,7 +61,6 @@ public class GadgetModule implements Module, Listener {
|
||||
}, 1L, 1L);
|
||||
}
|
||||
|
||||
// Event für die Benutzung der aktiven Gadgets
|
||||
@EventHandler
|
||||
public void onInteract(PlayerInteractEvent event) {
|
||||
ItemStack item = event.getItem();
|
||||
@@ -80,7 +81,6 @@ public class GadgetModule implements Module, Listener {
|
||||
}
|
||||
}
|
||||
|
||||
// Verhindert Bewegung für eingefrorene Spieler (Stasis)
|
||||
@EventHandler
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
if (FreezeRay.frozenPlayers.contains(event.getPlayer().getUniqueId())) {
|
||||
@@ -95,19 +95,11 @@ public class GadgetModule implements Module, Listener {
|
||||
if (hat == null || hat.getType() == Material.AIR) return;
|
||||
|
||||
switch (hat.getType()) {
|
||||
case CAMPFIRE:
|
||||
p.getWorld().spawnParticle(Particle.CAMPFIRE_COSY_SMOKE, p.getLocation().add(0, 2.2, 0), 1, 0.05, 0.05, 0.05, 0.02);
|
||||
break;
|
||||
case SPAWNER:
|
||||
p.getWorld().spawnParticle(Particle.FLAME, p.getLocation().add(0, 2.1, 0), 1, 0.12, 0.12, 0.12, 0.02);
|
||||
break;
|
||||
case SEA_LANTERN:
|
||||
case BEACON:
|
||||
p.getWorld().spawnParticle(Particle.END_ROD, p.getLocation().add(0, 2.1, 0), 1, 0.1, 0.1, 0.1, 0.03);
|
||||
break;
|
||||
case ENCHANTING_TABLE:
|
||||
p.getWorld().spawnParticle(Particle.ENCHANT, p.getLocation().add(0, 2.3, 0), 1, 0.2, 0.2, 0.2, 0.5);
|
||||
break;
|
||||
case CAMPFIRE -> p.getWorld().spawnParticle(Particle.CAMPFIRE_COSY_SMOKE, p.getLocation().add(0, 2.2, 0), 1, 0.05, 0.05, 0.05, 0.02);
|
||||
case SPAWNER -> p.getWorld().spawnParticle(Particle.FLAME, p.getLocation().add(0, 2.1, 0), 1, 0.12, 0.12, 0.12, 0.02);
|
||||
case SEA_LANTERN, BEACON -> p.getWorld().spawnParticle(Particle.END_ROD, p.getLocation().add(0, 2.1, 0), 1, 0.1, 0.1, 0.1, 0.03);
|
||||
case ENCHANTING_TABLE -> p.getWorld().spawnParticle(Particle.ENCHANT, p.getLocation().add(0, 2.3, 0), 1, 0.2, 0.2, 0.2, 0.5);
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +128,6 @@ public class GadgetModule implements Module, Listener {
|
||||
gui.setItem(14, createItem(Material.GLASS, "§fAstronaut", "§7Bereit für den Mond?"));
|
||||
gui.setItem(15, createItem(Material.DRAGON_HEAD, "§5Enderdrache", "§7Der König der Lüfte"));
|
||||
gui.setItem(16, createItem(Material.CAKE, "§dKuchen-Kopf", "§7Jeder mag Kuchen!"));
|
||||
|
||||
gui.setItem(19, createItem(Material.SLIME_BLOCK, "§aGlibber-Block", "§7Ziemlich klebrig..."));
|
||||
gui.setItem(20, createItem(Material.MELON, "§aMelonen-Helm", "§7Frisch und saftig"));
|
||||
gui.setItem(21, createItem(Material.HAY_BLOCK, "§eStrohhut", "§7Sommer auf dem Land"));
|
||||
@@ -144,7 +135,6 @@ public class GadgetModule implements Module, Listener {
|
||||
gui.setItem(23, createItem(Material.CRAFTING_TABLE, "§6Werkbank", "§7Immer am Basteln"));
|
||||
gui.setItem(24, createItem(Material.BOOKSHELF, "§fBücherregal", "§7Ein wahrer Schlaukopf"));
|
||||
gui.setItem(25, createItem(Material.HONEY_BLOCK, "§6Honig-Hut", "§7Süß und klebrig"));
|
||||
|
||||
gui.setItem(28, createItem(Material.GOLD_BLOCK, "§6Gold-Bonze", "§7Zeig was du hast"));
|
||||
gui.setItem(29, createItem(Material.DIAMOND_ORE, "§bDiamant-Erz", "§7Bau mich bloß nicht ab!"));
|
||||
gui.setItem(30, createItem(Material.BEACON, "§fLeuchtfeuer", "§7§oEffekt: Glitzern"));
|
||||
@@ -224,37 +214,32 @@ public class GadgetModule implements Module, Listener {
|
||||
else if (item.getType() == Material.NETHER_STAR) openParticleGUI(player);
|
||||
else if (item.getType() == Material.FIREWORK_ROCKET) openFunGUI(player);
|
||||
else if (item.getType() == Material.BARRIER) { removeGadgets(player); player.closeInventory(); }
|
||||
}
|
||||
else if (title.equals(HAT_TITLE)) {
|
||||
} else if (title.equals(HAT_TITLE)) {
|
||||
if (item.getType() != Material.GRAY_STAINED_GLASS_PANE) {
|
||||
HatManager.setHat(player, item.getType(), item.getItemMeta().getDisplayName());
|
||||
player.playSound(player.getLocation(), Sound.ITEM_ARMOR_EQUIP_GENERIC, 1, 1);
|
||||
player.closeInventory();
|
||||
}
|
||||
}
|
||||
else if (title.equals(PET_TITLE)) {
|
||||
} else if (title.equals(PET_TITLE)) {
|
||||
if (item.getType() == Material.BONE) PetManager.spawnEntityPet(player, "WOLF");
|
||||
else if (item.getType() == Material.CAT_SPAWN_EGG) PetManager.spawnEntityPet(player, "CAT");
|
||||
else if (item.getType() == Material.PANDA_SPAWN_EGG) PetManager.spawnEntityPet(player, "PANDA");
|
||||
player.sendMessage("§8[§6Nexus§8] §dDein Pet wurde gerufen!");
|
||||
player.closeInventory();
|
||||
}
|
||||
else if (title.equals(BALLOON_TITLE)) {
|
||||
} else if (title.equals(BALLOON_TITLE)) {
|
||||
if (item.getType().toString().endsWith("_WOOL")) {
|
||||
if (activeBalloons.containsKey(player.getUniqueId())) activeBalloons.get(player.getUniqueId()).remove();
|
||||
activeBalloons.put(player.getUniqueId(), new Balloon(player, item.getType()));
|
||||
player.sendMessage("§8[§6Nexus§8] §aBallon aktiviert!");
|
||||
player.closeInventory();
|
||||
}
|
||||
}
|
||||
else if (title.equals(PARTICLE_TITLE)) {
|
||||
} else if (title.equals(PARTICLE_TITLE)) {
|
||||
if (item.getType() == Material.POPPY) activeEffects.put(player.getUniqueId(), new ParticleEffect("hearts"));
|
||||
else if (item.getType() == Material.BLAZE_POWDER) activeEffects.put(player.getUniqueId(), new ParticleEffect("flames"));
|
||||
else if (item.getType() == Material.WATER_BUCKET) activeEffects.put(player.getUniqueId(), new ParticleEffect("cloud"));
|
||||
player.sendMessage("§8[§6Nexus§8] §aPartikel aktiviert!");
|
||||
player.closeInventory();
|
||||
}
|
||||
else if (title.equals(FUN_TITLE)) {
|
||||
} else if (title.equals(FUN_TITLE)) {
|
||||
if (item.getType() == Material.EGG) {
|
||||
ChickenRain.start(player);
|
||||
player.sendMessage("§8[§6Nexus§8] §fHühnerregen gestartet!");
|
||||
@@ -288,7 +273,7 @@ public class GadgetModule implements Module, Listener {
|
||||
public void onFish(PlayerFishEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
ItemStack item = player.getInventory().getItemInMainHand();
|
||||
if (item != null && item.getType() == Material.FISHING_ROD && item.hasItemMeta() && item.getItemMeta().getDisplayName().equals("§b§lEnterhaken")) {
|
||||
if (item.getType() == Material.FISHING_ROD && item.hasItemMeta() && item.getItemMeta().getDisplayName().equals("§b§lEnterhaken")) {
|
||||
if (event.getState() == PlayerFishEvent.State.IN_GROUND || event.getState() == PlayerFishEvent.State.REEL_IN || event.getState() == PlayerFishEvent.State.CAUGHT_ENTITY) {
|
||||
if (event.getHook() != null) {
|
||||
GrapplingHook.pullPlayer(player, event.getHook().getLocation());
|
||||
@@ -314,6 +299,7 @@ public class GadgetModule implements Module, Listener {
|
||||
}
|
||||
|
||||
private void fillEdges(Inventory inv) {
|
||||
// Bedrock braucht einen Space, um den Namen korrekt anzuzeigen
|
||||
ItemStack glass = createItem(Material.GRAY_STAINED_GLASS_PANE, " ", null);
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
if (i < 9 || i >= inv.getSize() - 9 || i % 9 == 0 || (i + 1) % 9 == 0) inv.setItem(i, glass);
|
||||
@@ -325,11 +311,19 @@ public class GadgetModule implements Module, Listener {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(name);
|
||||
if (lore != null) {
|
||||
|
||||
// WICHTIG FÜR BEDROCK: Saubere ArrayList für Lore
|
||||
List<String> l = new ArrayList<>();
|
||||
l.add(lore);
|
||||
if (lore != null && !lore.isEmpty()) {
|
||||
l.add(ChatColor.translateAlternateColorCodes('&', lore));
|
||||
meta.setLore(l);
|
||||
}
|
||||
|
||||
// VERSTECKT ATTRIBUTE: Verhindert "+Armor" etc., was bei Bedrock die Lore überdeckt
|
||||
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
|
||||
meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
|
||||
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
return item;
|
||||
|
||||
@@ -6,12 +6,12 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.GameRule;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.ClickType; // DIESER IMPORT HAT GEFEHLT
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -54,8 +54,30 @@ public class LobbySettingsModule implements Module, Listener {
|
||||
Set<String> keys = settingsConfig.getConfigurationSection("gamerules").getKeys(false);
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
for (String key : keys) {
|
||||
String value = String.valueOf(settingsConfig.get("gamerules." + key));
|
||||
world.setGameRuleValue(key, value);
|
||||
Object value = settingsConfig.get("gamerules." + key);
|
||||
updateGameRule(world, key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hilfsmethode zur sicheren Anwendung von GameRules in 1.21
|
||||
private void updateGameRule(World world, String ruleName, Object value) {
|
||||
GameRule<?> rule = GameRule.getByName(ruleName);
|
||||
if (rule == null) return;
|
||||
|
||||
if (value instanceof Boolean && rule.getType() == Boolean.class) {
|
||||
world.setGameRule((GameRule<Boolean>) rule, (Boolean) value);
|
||||
} else if (value instanceof Integer && rule.getType() == Integer.class) {
|
||||
world.setGameRule((GameRule<Integer>) rule, (Integer) value);
|
||||
} else {
|
||||
// Falls der Wert aus der Config als String kommt, versuchen wir ihn zu parsen
|
||||
String strValue = String.valueOf(value);
|
||||
if (rule.getType() == Boolean.class) {
|
||||
world.setGameRule((GameRule<Boolean>) rule, Boolean.parseBoolean(strValue));
|
||||
} else if (rule.getType() == Integer.class) {
|
||||
try {
|
||||
world.setGameRule((GameRule<Integer>) rule, Integer.parseInt(strValue));
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,7 +176,7 @@ public class LobbySettingsModule implements Module, Listener {
|
||||
settingsConfig.set(path, newValue);
|
||||
saveSettings();
|
||||
if (path.startsWith("gamerules.")) {
|
||||
for (World w : Bukkit.getWorlds()) w.setGameRuleValue(key, String.valueOf(newValue));
|
||||
for (World w : Bukkit.getWorlds()) updateGameRule(w, key, newValue);
|
||||
}
|
||||
} else if (value instanceof Integer) {
|
||||
int newVal = (Integer) value + (event.getClick().isLeftClick() ? 1 : -1);
|
||||
@@ -162,7 +184,7 @@ public class LobbySettingsModule implements Module, Listener {
|
||||
settingsConfig.set(path, newVal);
|
||||
saveSettings();
|
||||
if (path.startsWith("gamerules.")) {
|
||||
for (World w : Bukkit.getWorlds()) w.setGameRuleValue(key, String.valueOf(newVal));
|
||||
for (World w : Bukkit.getWorlds()) updateGameRule(w, key, newVal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +193,6 @@ public class LobbySettingsModule implements Module, Listener {
|
||||
}
|
||||
|
||||
private void refreshCategory(Player p, String category) {
|
||||
// Die refresh-Logik wurde vereinfacht, um Fehler zu vermeiden
|
||||
if (category.equals("Lobby-Schutz")) openCategory(p, "Lobby-Schutz", "allowPvp", "allowBlockBreaking", "allowBlockPlacing", "allowBlockInteracting", "allowItemDropping", "allowItemPickup", "allowExplosions");
|
||||
else if (category.equals("Chat")) openCategory(p, "Chat", "announceAdvancements", "commandBlockOutput", "logAdminCommands", "sendCommandFeedback", "showDeathMessages", "reducedDebugInfo");
|
||||
else if (category.equals("Drops")) openCategory(p, "Drops", "keepInventory", "doEntityDrops", "doMobLoot", "doTileDrops", "mobExplosionDropDecay", "blockExplosionDropDecay", "tntExplosionDropDecay");
|
||||
|
||||
@@ -160,3 +160,19 @@ hider:
|
||||
all: "&aAlle Spieler: &7Sichtbar"
|
||||
# Anzeigename des Items und Nachricht, wenn alle versteckt sind
|
||||
none: "&cKeine Spieler: &7Versteckt"
|
||||
|
||||
# -----------------------------------------------------
|
||||
# BALL / SOCCER EINSTELLUNGEN
|
||||
# -----------------------------------------------------
|
||||
ball:
|
||||
enabled: true
|
||||
# Der Spawnpunkt wird automatisch über /nexus ball setspawn hier gespeichert
|
||||
spawn:
|
||||
world: "world"
|
||||
x: 10.5
|
||||
y: 65.0
|
||||
z: 10.5
|
||||
yaw: 0.0
|
||||
pitch: 0.0
|
||||
# Zeit in Sekunden, bis der Ball bei Inaktivität respawnt
|
||||
respawn_delay: 60
|
||||
164
src/main/resources/conversations.yml
Normal file
164
src/main/resources/conversations.yml
Normal file
@@ -0,0 +1,164 @@
|
||||
# =============================================================
|
||||
# NexusLobby - Lebendige Dialoge v2
|
||||
# =============================================================
|
||||
|
||||
conversations:
|
||||
parkour_begruessung:
|
||||
morgens:
|
||||
dialogue:
|
||||
- '&6&lTrainer &8» &fGuten Morgen! Zeit für Frühsport! *streckt sich*'
|
||||
- '&6&lTrainer &8» &fWillkommen bei &e&lNexusLobby&f!'
|
||||
- '&6&lTrainer &8» &eKlick mich an&f, um den Parkour zu starten!'
|
||||
mittags:
|
||||
dialogue:
|
||||
- '&6&lTrainer &8» &fDie Sonne brennt, der Parkour wartet!'
|
||||
- '&6&lTrainer &8» &fHast du das Zeug zum &aParkour-Meister&f?'
|
||||
- '&6&lTrainer &8» &eKlick mich an&f, wenn du dich traust!'
|
||||
abends:
|
||||
dialogue:
|
||||
- '&6&lTrainer &8» &fNoch eine Runde vor dem Schlafengehen?'
|
||||
- '&6&lTrainer &8» &fZeig bei &e&lNexusLobby&f, was du noch drauf hast!'
|
||||
- '&6&lTrainer &8» &eKlick mich an&f, für deinen neuen Rekord!'
|
||||
|
||||
owner_besuch:
|
||||
morgens:
|
||||
dialogue:
|
||||
- '&dTimmy: &fMami, ist der Owner schon wach? &e*hüpft*'
|
||||
- '&5Sarah: &7Bestimmt! Er schließt den Server auf.'
|
||||
- '&dTimmy: &fIch zeig ihm meinen Teddy mit Krone! &a*stolz*'
|
||||
- '&5Sarah: &7Leise sein, falls er noch arbeitet. *psst*'
|
||||
mittags:
|
||||
dialogue:
|
||||
- '&dTimmy: &fDa ist das Büro! Ich seh die Fenster! &e*rennt*'
|
||||
- '&5Sarah: &cStopp! &7Nicht so stürmisch, Timmy.'
|
||||
- '&dTimmy: &fAber Teddy will den Schreibtisch sehen!'
|
||||
- '&5Sarah: &7Komm an meine Hand. Wir klopfen ganz brav.'
|
||||
abends:
|
||||
dialogue:
|
||||
- '&dTimmy: &fGuck! Im Büro brennt noch Licht! &b*zeigt*'
|
||||
- '&5Sarah: &7Er arbeitet sicher noch an Updates.'
|
||||
- '&dTimmy: &fIst er ein Roboter? Er schläft nie! &7*staunt*'
|
||||
- '&5Sarah: &7Nein, er braucht nur viel Zaubertrank. *lacht*'
|
||||
|
||||
fussball_match:
|
||||
morgens:
|
||||
dialogue:
|
||||
- '&eLeon: &fFinn! Aufwachen! Kick den Ball! &e*kickt*'
|
||||
- '&6Finn: &8*gähnt* &7Mein Fuß schläft noch, Leon...'
|
||||
- '&eLeon: &fKeine Ausreden! Pass an! &6*kickt hart*'
|
||||
- '&6Finn: &fHuch! &7*stoppt unsicher* &fBin ja schon wach!'
|
||||
mittags:
|
||||
dialogue:
|
||||
- '&eLeon: &fPass auf! Jetzt kommt mein Spezialschuss!'
|
||||
- '&6Finn: &fDen hab ich! &e*macht Hechtsprung* &fJaaaa!'
|
||||
- '&eLeon: &7Wie hast du den denn erwischt? &c*schmollt*'
|
||||
- '&6Finn: &fIch kenne deine Tricks, Leon! *grinst*'
|
||||
abends:
|
||||
dialogue:
|
||||
- '&eLeon: &7Ich seh den Ball kaum noch. &8*kneift Augen*'
|
||||
- '&6Finn: &fEgal! Nächstes Tor gewinnt die Krone!'
|
||||
- '&eLeon: &fHe! Das war Foul! Du hast geschubst! &c*meckert*'
|
||||
- '&6Finn: &7Körpereinsatz! Fang mich doch! &a*rennt weg*'
|
||||
|
||||
baum_drama:
|
||||
morgens:
|
||||
dialogue:
|
||||
- '&aLotte: &fDie Aussicht ist göttlich! &d*atmet tief*'
|
||||
- '&bSchmidt: &7Lotte, komm runter! Es ist 7 Uhr morgens!'
|
||||
- '&aLotte: &fIch beobachte Vögel. Ich bin jetzt einer!'
|
||||
- '&bSchmidt: &7Du brauchst Kaffee, keinen Baum. &8*seufzt*'
|
||||
mittags:
|
||||
dialogue:
|
||||
- '&aLotte: &fIch kann fliegen! Seht mich an! &7*balanciert*'
|
||||
- '&bSchmidt: &cLotte, komm sofort vom Baum runter!'
|
||||
- '&aLotte: &fIch bin ein stolzer Adler! &e*breitet Arme aus*'
|
||||
- '&bSchmidt: &7Du bist eine Frau auf einer Birke! Abstieg!'
|
||||
abends:
|
||||
dialogue:
|
||||
- '&aLotte: &fVon hier sieht man das Feuerwerk besser!'
|
||||
- '&bSchmidt: &7Es wird kalt. Und da oben sind Spinnen!'
|
||||
- '&aLotte: &fSpinnen? &7*schaut hektisch* &fWo?!'
|
||||
- '&bSchmidt: &7Komm zur Leiter. Ich rette dich. &e*grinst*'
|
||||
|
||||
familien_spaziergang:
|
||||
morgens:
|
||||
dialogue:
|
||||
- '&9Tom: &7Schaut mal diesen Sonnenaufgang an. &6*genießt*'
|
||||
- '&5Eva: &7Lass dir Zeit. Die Welt wacht gerade erst auf.'
|
||||
- '&dJasmin: &fPapa, die Blumen gehen auf! &e*bleibt stehen*'
|
||||
- '&9Tom: &7Wollen wir zum Bäcker? Frische Brötchen!'
|
||||
mittags:
|
||||
dialogue:
|
||||
- '&9Tom: &7Klar, Jasmin. Wünsch dir was ganz Besonderes!'
|
||||
- '&5Eva: &7Nicht reinfallen! Das Wasser ist tief. &6*lacht*'
|
||||
- '&dJasmin: &fDarf ich eine Münze werfen? Bitte! &d*hüpft*'
|
||||
- '&9Tom: &7Ich wünsche mir... &7*kneift Augen zu* &f...Eis!'
|
||||
abends:
|
||||
dialogue:
|
||||
- '&9Tom: &7Der ganze Spawn leuchtet jetzt schön. &b*guckt*'
|
||||
- '&5Eva: &7Es wird so herrlich ruhig hier, oder? &d*lächelt*'
|
||||
- '&dJasmin: &fPapa, darf ich auf deine Schultern? &7*gähnt*'
|
||||
- '&9Tom: &7Hopp! &e*hebt sie hoch* &7Na, wie ist die Sicht?'
|
||||
|
||||
frauen_plausch:
|
||||
morgens:
|
||||
dialogue:
|
||||
- '&9Marie: &7Guten Morgen! Du siehst verschlafen aus.'
|
||||
- '&fPia: &7Die Party gestern war zu lang. Kaffee... &8*gähnt*'
|
||||
- '&9Marie: &7Der Bäcker hat frische Zimtschnecken! Komm!'
|
||||
- '&fPia: &fSorg dafür, dass ich nicht umkippe. &7*lacht*'
|
||||
mittags:
|
||||
dialogue:
|
||||
- '&9Marie: &7Hast du den neuen Shop gesehen? Tolle Erze!'
|
||||
- '&fPia: &fEcht jetzt? &7Ich dachte, die Mine ist zu.'
|
||||
- '&9Marie: &7Die haben einen neuen Tunnel! Riesige Smaragde!'
|
||||
- '&fPia: &fWahnsinn. Ich muss mein Inventar leeren!'
|
||||
abends:
|
||||
dialogue:
|
||||
- '&9Marie: &7Hast du die Lichter am Hafen gesehen? &b*staunt*'
|
||||
- '&fPia: &7Leider verpasst... ich musste Truhen sortieren.'
|
||||
- '&9Marie: &7Du arbeitest zu viel, Pia. Genieß den Abend!'
|
||||
- '&fPia: &7Stimmt. Morgen machen wir blau, okay?'
|
||||
|
||||
wettrennen_jungs:
|
||||
morgens:
|
||||
dialogue:
|
||||
- '&bNico: &fErster am Portal! Lauf schneller, Lukas!'
|
||||
- '&fLukas: &c*keucht* &fWarte! Meine Schuhe sind offen!'
|
||||
- '&bNico: &fKeine Ausreden! Die Sonne lacht! &a*rennt*'
|
||||
- '&fLukas: &fNa warte, ich krieg dich noch! &7*sprintet*'
|
||||
mittags:
|
||||
dialogue:
|
||||
- '&bNico: &fKomm schon, du lahme Ente! &a*rast davon*'
|
||||
- '&fLukas: &c*außer Atem* &7Ich... hab heute schon gefarmt!'
|
||||
- '&bNico: &fErster! Gewonnen! &7*tanzt* &fHer mit dem Apfel!'
|
||||
- '&fLukas: &fMorgen gewinnen meine Speed-Stiefel! &c*schwitzt*'
|
||||
abends:
|
||||
dialogue:
|
||||
- '&bNico: &fLetztes Rennen! Verlierer poliert Rüstungen!'
|
||||
- '&fLukas: &fDiesmal nicht, Nico! &e*nimmt Anlauf*'
|
||||
- '&bNico: &fOh, jetzt wird es ernst? &7Fertig... LOS!'
|
||||
- '&fLukas: &fJaaa! Ich bin vorne! Wer ist jetzt lahm?! &a*lacht*'
|
||||
|
||||
mutter_kind_spiel:
|
||||
morgens:
|
||||
dialogue:
|
||||
- '&dMia: &fMami, schau! Meine Puppen warten schon. &d*zeigt*'
|
||||
- '&5Sandra: &7Warten sie auf den Empfang, Mia?'
|
||||
- '&dMia: &fJa, sie wollen zum Owner! &e*rückt Puppe recht*'
|
||||
- '&5Sandra: &7Dann müssen sie brav Schlange stehen. &7*lächelt*'
|
||||
mittags:
|
||||
dialogue:
|
||||
- '&dMia: &fGuck! Ein riesiges Hotel aus Klötzen! &e*stapelt*'
|
||||
- '&5Sandra: &7Oha, wird das ein Dino-Hotel?'
|
||||
- '&dMia: &fJa! Der Dino frisst nur Kekse! &e*füttert ihn*'
|
||||
- '&5Sandra: &7Bau fleißig weiter, kleine Architektin.'
|
||||
abends:
|
||||
dialogue:
|
||||
- '&dMia: &fMami, Dino ist müde. &7*gähnt laut*'
|
||||
- '&5Sandra: &7Pack ihn gut in seine Decke ein, Mia.'
|
||||
- '&dMia: &fMuss ich meine Klötze einpacken? &c*traurig*'
|
||||
- '&5Sandra: &7Ja, aber morgen bauen wir ein Schloss!'
|
||||
|
||||
links:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: NexusLobby
|
||||
main: de.nexuslobby.NexusLobby
|
||||
version: "1.0.8"
|
||||
version: "1.1.0"
|
||||
api-version: "1.21"
|
||||
author: M_Viper
|
||||
description: Modular Lobby Plugin with an invisible Particle-Parkour system.
|
||||
|
||||
Reference in New Issue
Block a user