diff --git a/src/main/java/de/nexuslobby/modules/gadgets/GadgetModule.java b/src/main/java/de/nexuslobby/modules/gadgets/GadgetModule.java index 924fcad..6130b68 100644 --- a/src/main/java/de/nexuslobby/modules/gadgets/GadgetModule.java +++ b/src/main/java/de/nexuslobby/modules/gadgets/GadgetModule.java @@ -31,6 +31,8 @@ import java.util.Set; import java.util.UUID; public class GadgetModule implements Module, Listener { + // Speichert laufende Disco-Modus Tasks pro Spieler + private final Map discoTasks = new HashMap<>(); private final Map activeBalloons = new HashMap<>(); private final Map activeEffects = new HashMap<>(); @@ -54,6 +56,8 @@ public class GadgetModule implements Module, Listener { private final String FUN_TITLE = "§b§lGadgets §8- §6Lustiges"; private final String HAT_TITLE = "§b§lGadgets §8- §aHüte & Köpfe"; private final String PET_TITLE = "§b§lGadgets §8- §dBegleiter"; + private final String PET2_TITLE = "§b§lGadgets §8- §dBegleiter §7(2)"; + private final String PET3_TITLE = "§b§lGadgets §8- §dBegleiter §7(3)"; @Override public String getName() { return "Gadgets"; } @@ -257,12 +261,70 @@ public class GadgetModule implements Module, Listener { } private void openPetGUI(Player player) { - Inventory gui = Bukkit.createInventory(null, 27, PET_TITLE); + Inventory gui = Bukkit.createInventory(null, 54, PET_TITLE); fillEdges(gui); - gui.setItem(11, createItem(Material.BONE, "§fWolf", "§7Ein treuer Begleiter")); - gui.setItem(13, createItem(Material.CAT_SPAWN_EGG, "§6Katze", "§7Ein verschmuster Freund")); - gui.setItem(15, createItem(Material.PANDA_SPAWN_EGG,"§aPanda", "§7Ein gemütlicher Zeitgenosse")); - gui.setItem(22, createItem(Material.ARROW, "§7Zurück", "§8Zum Hauptmenü")); + // Oben: Baby-Varianten, darunter: Erwachsene + gui.setItem(10, createItem(Material.BONE, "§fBaby-Wolf", "§7Ein kleiner treuer Begleiter")); + gui.setItem(11, createItem(Material.BONE, "§7Baby-Ashen Wolf", "§7Ein kleiner Aschen-Wolf")); + gui.setItem(12, createItem(Material.CAT_SPAWN_EGG, "§6Baby-Katze", "§7Ein kleiner Schmusefreund")); + gui.setItem(13, createItem(Material.PANDA_SPAWN_EGG, "§aBaby-Panda", "§7Ein kleiner Flauschball")); + gui.setItem(14, createItem(Material.FOX_SPAWN_EGG, "§6Baby-Fuchs", "§7Ein kleiner Schlaukopf")); + gui.setItem(15, createItem(Material.FROG_SPAWN_EGG, "§aBaby-Frosch", "§7Ein kleiner Hopsfreund")); + gui.setItem(16, createItem(Material.TURTLE_SPAWN_EGG, "§2Baby-Schildkröte", "§7Ein kleiner Panzenträger")); + gui.setItem(28, createItem(Material.FOX_SPAWN_EGG, "§bBaby-Schneefuchs", "§7Ein kleiner Schnee-Fuchs")); + gui.setItem(29, createItem(Material.RABBIT_SPAWN_EGG, "§fBaby-Kaninchen", "§7Ein kleiner Flitzer")); + gui.setItem(30, createItem(Material.AXOLOTL_SPAWN_EGG,"§dBaby-Axolotl", "§7Ein kleiner Wasserfreund")); + gui.setItem(31, createItem(Material.OCELOT_SPAWN_EGG, "§6Baby-Ozelot", "§7Ein kleiner Schleicher")); + gui.setItem(32, createItem(Material.POLAR_BEAR_SPAWN_EGG, "§fBaby-Eisbär", "§7Ein kleiner Eisbär")); + gui.setItem(33, createItem(Material.BEE_SPAWN_EGG, "§eBaby-Biene", "§7Eine kleine Biene")); + gui.setItem(34, createItem(Material.CHICKEN_SPAWN_EGG,"§fKüken", "§7Ein kleines Huhn")); + // Armadillo Baby entfernt, da auf Seite 2 + + gui.setItem(19, createItem(Material.BONE, "§fWolf", "§7Ein treuer Begleiter")); + gui.setItem(20, createItem(Material.BONE, "§7Ashen Wolf", "§7Ein seltener Aschen-Wolf")); + gui.setItem(21, createItem(Material.CAT_SPAWN_EGG, "§6Katze", "§7Ein verschmuster Freund")); + gui.setItem(22, createItem(Material.PANDA_SPAWN_EGG, "§aPanda", "§7Ein gemütlicher Zeitgenosse")); + gui.setItem(23, createItem(Material.FOX_SPAWN_EGG, "§6Fuchs", "§7Ein schlauer Begleiter")); + gui.setItem(24, createItem(Material.FROG_SPAWN_EGG, "§aFrosch", "§7Ein echter Hopsmeister")); + gui.setItem(25, createItem(Material.TURTLE_SPAWN_EGG, "§2Schildkröte", "§7Gemütlich und gelassen")); + gui.setItem(37, createItem(Material.FOX_SPAWN_EGG, "§bSchneefuchs", "§7Ein Fuchs aus kalten Biomen")); + gui.setItem(38, createItem(Material.RABBIT_SPAWN_EGG, "§fKaninchen", "§7Ein schneller Hopper")); + gui.setItem(39, createItem(Material.AXOLOTL_SPAWN_EGG,"§dAxolotl", "§7Ein seltener Wasserfreund")); + gui.setItem(40, createItem(Material.OCELOT_SPAWN_EGG, "§6Ozelot", "§7Ein wachsamer Begleiter")); + gui.setItem(41, createItem(Material.POLAR_BEAR_SPAWN_EGG, "§fEisbär", "§7Ein starker Eisbär")); + gui.setItem(42, createItem(Material.BEE_SPAWN_EGG, "§eBiene", "§7Eine fleißige Biene")); + gui.setItem(43, createItem(Material.CHICKEN_SPAWN_EGG,"§fHuhn", "§7Ein gackerndes Huhn")); + // Armadillo Erwachsen entfernt, da auf Seite 2 + + gui.setItem(48, createItem(Material.ARROW, "§7Zurück", "§8Zum Hauptmenü")); + gui.setItem(50, createItem(Material.ARROW, "§7Weiter", "§8Seite 2")); + player.openInventory(gui); + } + + private void openPetGUI2(Player player) { + Inventory gui = Bukkit.createInventory(null, 54, PET2_TITLE); + fillEdges(gui); + + // Seite 2: Armadillo (Baby und Erwachsen) + gui.setItem(19, createItem(Material.ARMADILLO_SPAWN_EGG, "§7Baby-Armadillo", "§7Ein kleiner Gürteltier")); + gui.setItem(28, createItem(Material.ARMADILLO_SPAWN_EGG, "§7Armadillo", "§7Ein Gürteltier")); + + gui.setItem(48, createItem(Material.ARROW, "§7Zurück", "§8Seite 1")); + gui.setItem(50, createItem(Material.ARROW, "§7Weiter", "§8Seite 3")); + player.openInventory(gui); + } + + private void openPetGUI3(Player player) { + Inventory gui = Bukkit.createInventory(null, 54, PET3_TITLE); + fillEdges(gui); + + // Seite 3: bisherige Seite 2 Inhalte (Papagei, Allay, Sniffer) + gui.setItem(19, createItem(Material.PARROT_SPAWN_EGG, "§cPapagei", "§7Ein bunter Begleiter")); + gui.setItem(20, createItem(Material.ALLAY_SPAWN_EGG, "§bAllay", "§7Ein magischer Helfer")); + gui.setItem(21, createItem(Material.SNIFFER_SPAWN_EGG,"§aSniffer", "§7Ein uraltes Tier")); + + gui.setItem(48, createItem(Material.ARROW, "§7Zurück", "§8Seite 2")); + gui.setItem(50, createItem(Material.ARROW, "§7Hauptmenü", "§8Zum Hauptmenü")); player.openInventory(gui); } @@ -295,12 +357,20 @@ public class GadgetModule implements Module, Listener { private void openFunGUI(Player player) { Inventory gui = Bukkit.createInventory(null, 27, FUN_TITLE); fillEdges(gui); + // Layout wie im Screenshot: gui.setItem(10, createItem(Material.FISHING_ROD, "§b§lEnterhaken", "§7Zieh dich durch die Luft! §8(3s CD)")); gui.setItem(11, createItem(Material.PACKED_ICE, "§b§lFreeze-Ray", "§7Friere andere ein! §8(10s CD)")); gui.setItem(12, createItem(Material.GOLDEN_HOE, "§6§lPaintball-Gun","§7Male die Lobby bunt aus!")); + gui.setItem(13, createItem(Material.FEATHER, "§f§lMini-Tornado", "§7Wirbele dich herum!")); gui.setItem(14, createItem(Material.FIRE_CHARGE, "§c§lMeteorit", "§7Lass es krachen! §8(15s CD)")); gui.setItem(15, createItem(Material.SHIELD, "§5§lSchutzzone", "§7Halte andere auf Distanz")); gui.setItem(16, createItem(Material.EGG, "§f§lChicken-Rain","§7Gack-Gack! Hühner überall!")); + // Slot 17 und 18 bleiben leer, TNT kommt auf Slot 23 (ganz rechts mittlere Reihe) + gui.setItem(23, createItem(Material.TNT, "§c§lFake-TNT", "§7Täusche andere mit einer harmlosen Explosion!")); + // Zeile 2 + gui.setItem(19, createItem(Material.SLIME_BALL, "§a§lMob-Party", "§7Lustige Mini-Mobs tanzen um dich!")); + gui.setItem(20, createItem(Material.NOTE_BLOCK, "§d§lTanz-Emote", "§7Führe einen Tanz auf!")); + gui.setItem(21, createItem(Material.FIREWORK_ROCKET, "§c§lKonfetti-Kanone", "§7Schieße Konfetti in die Luft!")); gui.setItem(22, createItem(Material.ARROW, "§7Zurück", "§8Zum Hauptmenü")); player.openInventory(gui); } @@ -314,7 +384,21 @@ public class GadgetModule implements Module, Listener { ItemStack item = event.getCurrentItem(); if (item == null || item.getType() == Material.AIR) return; - if (item.getType() == Material.ARROW) { openGUI(player); return; } + if (item.getType() == Material.ARROW) { + String displayName = item.hasItemMeta() && item.getItemMeta().hasDisplayName() + ? item.getItemMeta().getDisplayName() : ""; + if (displayName.equals("§7Weiter")) { + if (title.equals(PET_TITLE)) { openPetGUI2(player); return; } + if (title.equals(PET2_TITLE)) { openPetGUI3(player); return; } + } + if (displayName.equals("§7Zurück")) { + if (title.equals(PET2_TITLE)) { openPetGUI(player); return; } + if (title.equals(PET3_TITLE)) { openPetGUI2(player); return; } + openGUI(player); + return; + } + if (displayName.equals("§7Hauptmenü")) { openGUI(player); return; } + } if (title.equals(MAIN_TITLE)) { if (item.getType() == Material.LEAD) openBalloonGUI(player); @@ -332,11 +416,73 @@ public class GadgetModule implements Module, Listener { player.closeInventory(); } } 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(); + String displayName = item.hasItemMeta() && item.getItemMeta().hasDisplayName() + ? item.getItemMeta().getDisplayName() : ""; + boolean spawned = true; + if (displayName.equals("§fBaby-Wolf")) PetManager.spawnEntityPet(player, "WOLF", true); + else if (displayName.equals("§fWolf")) PetManager.spawnEntityPet(player, "WOLF", false); + else if (displayName.equals("§7Baby-Ashen Wolf")) PetManager.spawnEntityPet(player, "WOLF", true, "ASHEN"); + else if (displayName.equals("§7Ashen Wolf")) PetManager.spawnEntityPet(player, "WOLF", false, "ASHEN"); + else if (displayName.equals("§6Baby-Katze")) PetManager.spawnEntityPet(player, "CAT", true); + else if (displayName.equals("§6Katze")) PetManager.spawnEntityPet(player, "CAT", false); + else if (displayName.equals("§aBaby-Panda")) PetManager.spawnEntityPet(player, "PANDA", true); + else if (displayName.equals("§aPanda")) PetManager.spawnEntityPet(player, "PANDA", false); + else if (displayName.equals("§6Baby-Fuchs")) PetManager.spawnEntityPet(player, "FOX", true); + else if (displayName.equals("§6Fuchs")) PetManager.spawnEntityPet(player, "FOX", false); + else if (displayName.equals("§bBaby-Schneefuchs")) PetManager.spawnEntityPet(player, "FOX", true, "SNOW"); + else if (displayName.equals("§bSchneefuchs")) PetManager.spawnEntityPet(player, "FOX", false, "SNOW"); + else if (displayName.equals("§6Baby-Ozelot")) PetManager.spawnEntityPet(player, "OCELOT", true); + else if (displayName.equals("§6Ozelot")) PetManager.spawnEntityPet(player, "OCELOT", false); + else if (displayName.equals("§aBaby-Frosch")) PetManager.spawnEntityPet(player, "FROG", true); + else if (displayName.equals("§aFrosch")) PetManager.spawnEntityPet(player, "FROG", false); + else if (displayName.equals("§2Baby-Schildkröte")) PetManager.spawnEntityPet(player, "TURTLE", true); + else if (displayName.equals("§2Schildkröte")) PetManager.spawnEntityPet(player, "TURTLE", false); + else if (displayName.equals("§fBaby-Kaninchen")) PetManager.spawnEntityPet(player, "RABBIT", true); + else if (displayName.equals("§fKaninchen")) PetManager.spawnEntityPet(player, "RABBIT", false); + else if (displayName.equals("§dBaby-Axolotl")) PetManager.spawnEntityPet(player, "AXOLOTL", true); + else if (displayName.equals("§dAxolotl")) PetManager.spawnEntityPet(player, "AXOLOTL", false); + + else if (displayName.equals("§fBaby-Eisbär")) PetManager.spawnEntityPet(player, "POLAR_BEAR", true); + else if (displayName.equals("§fEisbär")) PetManager.spawnEntityPet(player, "POLAR_BEAR", false); + else if (displayName.equals("§eBaby-Biene")) PetManager.spawnEntityPet(player, "BEE", true); + else if (displayName.equals("§eBiene")) PetManager.spawnEntityPet(player, "BEE", false); + else if (displayName.equals("§fKüken")) PetManager.spawnEntityPet(player, "CHICKEN", true); + else if (displayName.equals("§fHuhn")) PetManager.spawnEntityPet(player, "CHICKEN", false); + else if (displayName.equals("§7Baby-Armadillo")) PetManager.spawnEntityPet(player, "ARMADILLO", true); + else if (displayName.equals("§7Armadillo")) PetManager.spawnEntityPet(player, "ARMADILLO", false); + else spawned = false; + + if (spawned) { + player.sendMessage("§8[§6Nexus§8] §dDein Pet wurde gerufen!"); + player.closeInventory(); + } + } else if (title.equals(PET2_TITLE)) { + String displayName = item.hasItemMeta() && item.getItemMeta().hasDisplayName() + ? item.getItemMeta().getDisplayName() : ""; + boolean spawned = true; + + if (displayName.equals("§7Baby-Armadillo")) PetManager.spawnEntityPet(player, "ARMADILLO", true); + else if (displayName.equals("§7Armadillo")) PetManager.spawnEntityPet(player, "ARMADILLO", false); + else spawned = false; + + if (spawned) { + player.sendMessage("§8[§6Nexus§8] §dDein Pet wurde gerufen!"); + player.closeInventory(); + } + } else if (title.equals(PET3_TITLE)) { + String displayName = item.hasItemMeta() && item.getItemMeta().hasDisplayName() + ? item.getItemMeta().getDisplayName() : ""; + boolean spawned = true; + + if (displayName.equals("§cPapagei")) PetManager.spawnEntityPet(player, "PARROT", false); + else if (displayName.equals("§bAllay")) PetManager.spawnEntityPet(player, "ALLAY", false); + else if (displayName.equals("§aSniffer")) PetManager.spawnEntityPet(player, "SNIFFER", false); + else spawned = false; + + if (spawned) { + player.sendMessage("§8[§6Nexus§8] §dDein Pet wurde gerufen!"); + player.closeInventory(); + } } else if (title.equals(BALLOON_TITLE)) { if (item.getType().toString().endsWith("_WOOL")) { if (activeBalloons.containsKey(player.getUniqueId())) activeBalloons.get(player.getUniqueId()).remove(); @@ -376,11 +522,130 @@ public class GadgetModule implements Module, Listener { player.sendMessage("§8[§6Nexus§8] §5Schutzzone aktiviert!"); } player.closeInventory(); + } else if (item.getType() == Material.FEATHER) { + // Mini-Tornado: Spieler wird schnell im Kreis gedreht und Partikel erscheinen (weiter oben) + Bukkit.getScheduler().runTaskTimer(NexusLobby.getInstance(), new Runnable() { + int ticks = 0; + @Override + public void run() { + if (ticks >= 20) return; + float yaw = player.getLocation().getYaw() + 36; + // Spieler leicht anheben + org.bukkit.Location loc = player.getLocation().clone(); + loc.setYaw(yaw); + loc.setY(loc.getY() + 0.5); + player.teleport(loc); + // Partikel deutlich höher + player.getWorld().spawnParticle(Particle.CLOUD, loc.clone().add(0,1.5,0), 14, 0.4,0.2,0.4,0.02); + player.setVelocity(player.getVelocity().setY(0.13)); + ticks++; + } + }, 0L, 1L); + player.playSound(player.getLocation(), Sound.ENTITY_PHANTOM_FLAP, 1, 1.2f); + player.sendMessage("§8[§6Nexus§8] §fMini-Tornado: Du wirbelst herum!"); + player.closeInventory(); + } else if (item.getType() == Material.TNT) { + // Fake-TNT: Platziert eine harmlose TNT-Attrappe + org.bukkit.Location tntLoc = player.getLocation().add(0, 0.5, 0); + player.getWorld().spawnParticle(Particle.SMOKE, tntLoc, 16, 0.4, 0.2, 0.4, 0.01); + player.getWorld().playSound(tntLoc, Sound.ENTITY_TNT_PRIMED, 1, 1); + Bukkit.getScheduler().runTaskLater(NexusLobby.getInstance(), () -> { + player.getWorld().spawnParticle(Particle.EXPLOSION, tntLoc, 2, 0.5, 0.2, 0.5, 0.1); + player.getWorld().playSound(tntLoc, Sound.ENTITY_GENERIC_EXPLODE, 1, 1.1f); + }, 30L); + player.sendMessage("§8[§6Nexus§8] §cFake-TNT gezündet! Keine Sorge, alles harmlos."); + player.closeInventory(); + } else if (item.getType() == Material.SLIME_BALL) { + // Mob-Party: Spawnt harmlose Mini-Mobs mit Partikeleffekten + org.bukkit.World world = player.getWorld(); + org.bukkit.Location baseLoc = player.getLocation(); + org.bukkit.entity.EntityType[] types = new org.bukkit.entity.EntityType[] { + org.bukkit.entity.EntityType.ZOMBIE, + org.bukkit.entity.EntityType.SKELETON, + org.bukkit.entity.EntityType.CREEPER, + org.bukkit.entity.EntityType.SLIME + }; + List spawned = new ArrayList<>(); + for (int i = 0; i < types.length; i++) { + org.bukkit.Location mobLoc = baseLoc.clone().add(Math.cos(i * Math.PI/2) * 1.5, 0, Math.sin(i * Math.PI/2) * 1.5); + org.bukkit.entity.Entity ent = world.spawnEntity(mobLoc, types[i]); + if (ent instanceof org.bukkit.entity.LivingEntity mob) { + mob.setCustomName("§aParty-Mob"); + mob.setCustomNameVisible(true); + mob.setAI(false); + mob.setInvulnerable(true); + mob.setCollidable(false); + mob.setSilent(true); + mob.setGlowing(true); + // setBaby() ist nicht für alle EntityTypes verfügbar, daher nur für passende Typen aufrufen + try { + if (mob instanceof org.bukkit.entity.Zombie zombie) { + zombie.setBaby(true); + } else if (mob instanceof org.bukkit.entity.Slime slime) { + slime.setSize(1); + } + } catch (Exception ignored) {} + spawned.add(mob); + } + } + // Partikel und "Tanz" für 4 Sekunden, dann despawnen + Bukkit.getScheduler().runTaskTimer(NexusLobby.getInstance(), new Runnable() { + int ticks = 0; + @Override + public void run() { + if (ticks >= 80) { + spawned.forEach(e -> e.remove()); + return; + } + for (org.bukkit.entity.LivingEntity mob : spawned) { + mob.getWorld().spawnParticle(Particle.NOTE, mob.getLocation().add(0,1,0), 6, 0.3,0.2,0.3,0.01); + mob.teleport(mob.getLocation().add(0, 0.08 * Math.sin(ticks/2.0), 0)); + } + ticks++; + } + }, 0L, 2L); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_CELEBRATE, 1, 1.2f); + player.sendMessage("§8[§6Nexus§8] §aMob-Party gestartet! Die Mobs tanzen um dich."); + player.closeInventory(); + } else if (item.getType() == Material.FIREWORK_ROCKET) { + // Konfetti-Kanone: Bunte Partikel und Knall + for (int i = 0; i < 3; i++) { + Bukkit.getScheduler().runTaskLater(NexusLobby.getInstance(), () -> { + player.getWorld().spawnParticle(Particle.CRIT, player.getLocation().add(0,1,0), 40, 0.8,0.5,0.8,0.15); + player.getWorld().spawnParticle(Particle.NOTE, player.getLocation().add(0,1,0), 20, 0.7,0.3,0.7,0.1); + player.playSound(player.getLocation(), Sound.ENTITY_FIREWORK_ROCKET_BLAST, 1, 1.1f); + }, i * 6L); + } + player.sendMessage("§8[§6Nexus§8] §cKonfetti-Kanone: Buntes Konfetti überall!"); + player.closeInventory(); + } else if (item.getType() == Material.NOTE_BLOCK) { + // Tanz-Emote: Spieler springt, Partikel und Musik + Bukkit.getScheduler().runTaskTimer(NexusLobby.getInstance(), new Runnable() { + int ticks = 0; + @Override + public void run() { + if (ticks >= 40) return; + if (ticks % 8 == 0) { + player.setVelocity(player.getVelocity().setY(0.4)); + player.getWorld().spawnParticle(Particle.NOTE, player.getLocation().add(0,2,0), 8, 0.5,0.2,0.5,0.01); + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BELL, 1, 1.2f); + } + ticks++; + } + }, 0L, 2L); + player.sendMessage("§8[§6Nexus§8] §dTanz-Emote: Du beginnst zu tanzen!"); + player.closeInventory(); } } } private void removeGadgets(Player player) { + // Laufenden Disco-Modus Task abbrechen + UUID uuid = player.getUniqueId(); + Integer discoTask = discoTasks.remove(uuid); + if (discoTask != null) { + Bukkit.getScheduler().cancelTask(discoTask); + } if (activeBalloons.containsKey(player.getUniqueId())) { activeBalloons.get(player.getUniqueId()).remove(); activeBalloons.remove(player.getUniqueId()); diff --git a/src/main/java/de/nexuslobby/modules/gadgets/PetManager.java b/src/main/java/de/nexuslobby/modules/gadgets/PetManager.java index f440105..387597c 100644 --- a/src/main/java/de/nexuslobby/modules/gadgets/PetManager.java +++ b/src/main/java/de/nexuslobby/modules/gadgets/PetManager.java @@ -3,11 +3,18 @@ package de.nexuslobby.modules.gadgets; import de.nexuslobby.NexusLobby; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; +import org.bukkit.entity.Ageable; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Fox; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Tameable; +import org.bukkit.entity.Wolf; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageEvent; @@ -50,6 +57,14 @@ public class PetManager implements Listener { * Spawnt ein echtes Tier-Entity für den Spieler. */ public static void spawnEntityPet(Player player, String type) { + spawnEntityPet(player, type, false); + } + + public static void spawnEntityPet(Player player, String type, boolean baby) { + spawnEntityPet(player, type, baby, null); + } + + public static void spawnEntityPet(Player player, String type, boolean baby, String variantName) { removePet(player); EntityType entityType; @@ -63,15 +78,42 @@ public class PetManager implements Listener { Location loc = player.getLocation(); Entity pet = player.getWorld().spawnEntity(loc, entityType); - pet.setCustomName("§d" + player.getName() + "'s " + capitalize(type.toLowerCase())); + String agePrefix = baby ? "§bBaby " : ""; + String petName = buildPetDisplayName(type, variantName); + pet.setCustomName(agePrefix + petName); pet.setCustomNameVisible(true); pet.setInvulnerable(true); pet.setPersistent(false); + applyNeutralPetTeam(pet); if (pet instanceof LivingEntity) { LivingEntity le = (LivingEntity) pet; le.setRemoveWhenFarAway(false); - + + if (le instanceof Ageable) { + Ageable ageable = (Ageable) le; + if (baby) { + ageable.setBaby(); + } else { + ageable.setAdult(); + } + } + + if (le instanceof Wolf && variantName != null && !variantName.isEmpty()) { + Wolf.Variant variant = resolveWolfVariant(variantName); + if (variant != null) { + ((Wolf) le).setVariant(variant); + } + } + + if (le instanceof Fox && variantName != null && !variantName.isEmpty()) { + try { + ((Fox) le).setFoxType(Fox.Type.valueOf(variantName)); + } catch (IllegalArgumentException ignored) { + // Ignorieren: Unbekannte Variante + } + } + // Verhindert, dass das Pet andere angreift if (le instanceof Tameable) { ((Tameable) le).setTamed(true); @@ -118,13 +160,16 @@ public class PetManager implements Listener { public static void removePet(Player player) { if (activePets.containsKey(player.getUniqueId())) { - activePets.get(player.getUniqueId()).remove(); + Entity pet = activePets.get(player.getUniqueId()); + removeFromPetTeam(pet); + pet.remove(); activePets.remove(player.getUniqueId()); } } public static void clearAll() { for (Entity pet : activePets.values()) { + removeFromPetTeam(pet); pet.remove(); } activePets.clear(); @@ -135,6 +180,49 @@ public class PetManager implements Listener { return str.substring(0, 1).toUpperCase() + str.substring(1); } + private static String buildPetDisplayName(String type, String variantName) { + String baseType = capitalize(type.toLowerCase()); + if (variantName == null || variantName.isEmpty()) return baseType; + String variant = capitalize(variantName.toLowerCase()); + return variant + " " + baseType; + } + + private static Wolf.Variant resolveWolfVariant(String variantName) { + String keyName = variantName.toLowerCase(); + NamespacedKey key = NamespacedKey.minecraft(keyName); + return Registry.WOLF_VARIANT.get(key); + } + + private static Team getOrCreatePetTeam() { + Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard(); + Team team = scoreboard.getTeam("nexus_pets"); + if (team == null) { + team = scoreboard.registerNewTeam("nexus_pets"); + team.setPrefix(""); + team.setSuffix(""); + } + return team; + } + + private static void applyNeutralPetTeam(Entity pet) { + Team team = getOrCreatePetTeam(); + String entry = pet.getUniqueId().toString(); + if (!team.hasEntry(entry)) { + team.addEntry(entry); + } + } + + private static void removeFromPetTeam(Entity pet) { + if (pet == null) return; + Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard(); + Team team = scoreboard.getTeam("nexus_pets"); + if (team == null) return; + String entry = pet.getUniqueId().toString(); + if (team.hasEntry(entry)) { + team.removeEntry(entry); + } + } + // --- Events um die Pets zu schützen --- @EventHandler