From 465cbd17fccb8f3ee851473ab48c0a3bcd89db96 Mon Sep 17 00:00:00 2001 From: akastijn Date: Sun, 5 Apr 2026 17:36:32 +0200 Subject: [PATCH] Remove `SpawnListener` and adjust egg drop mechanics for difficulty-based spawning. --- src/main/java/com/alttd/easter/Easter.java | 10 ---- .../java/com/alttd/easter/config/Config.java | 26 ++++----- .../com/alttd/easter/config/Messages.java | 2 +- .../java/com/alttd/easter/egg/EggType.java | 39 +++++++------ .../com/alttd/easter/glow/GlowManager.java | 3 +- .../alttd/easter/gui/TurnInGuiManager.java | 34 +++++++++--- .../alttd/easter/listeners/DeathListener.java | 31 +++++++---- .../alttd/easter/listeners/SpawnListener.java | 55 ------------------- .../java/com/alttd/easter/util/ItemUtils.java | 4 +- 9 files changed, 83 insertions(+), 121 deletions(-) delete mode 100644 src/main/java/com/alttd/easter/listeners/SpawnListener.java diff --git a/src/main/java/com/alttd/easter/Easter.java b/src/main/java/com/alttd/easter/Easter.java index 1d81f28..39f5a25 100644 --- a/src/main/java/com/alttd/easter/Easter.java +++ b/src/main/java/com/alttd/easter/Easter.java @@ -4,10 +4,8 @@ import com.alttd.easter.commands.Command; import com.alttd.easter.config.Config; import com.alttd.easter.config.Messages; import com.alttd.easter.data.DataManager; -import com.alttd.easter.glow.GlowManager; import com.alttd.easter.gui.TurnInGuiManager; import com.alttd.easter.listeners.DeathListener; -import com.alttd.easter.listeners.SpawnListener; import com.alttd.easter.npc.RabbitNpcManager; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; @@ -16,19 +14,16 @@ public final class Easter extends JavaPlugin { private DataManager dataManager; private RabbitNpcManager rabbitNpcManager; - private GlowManager glowManager; private TurnInGuiManager turnInGuiManager; @Override public void onEnable() { reloadConfigs(); this.dataManager = new DataManager(this); - this.glowManager = new GlowManager(this); this.turnInGuiManager = new TurnInGuiManager(dataManager); this.rabbitNpcManager = new RabbitNpcManager(this, turnInGuiManager, dataManager); registerCommands(); registerEvents(); - registerSchedulers(); } @Override @@ -44,7 +39,6 @@ public final class Easter extends JavaPlugin { private void registerEvents() { PluginManager pluginManager = getServer().getPluginManager(); - pluginManager.registerEvents(new SpawnListener(glowManager), this); pluginManager.registerEvents(new DeathListener(), this); pluginManager.registerEvents(rabbitNpcManager, this); pluginManager.registerEvents(turnInGuiManager, this); @@ -57,8 +51,4 @@ public final class Easter extends JavaPlugin { rabbitNpcManager.reload(); } } - - private void registerSchedulers() { - // No schedulers required currently - } } diff --git a/src/main/java/com/alttd/easter/config/Config.java b/src/main/java/com/alttd/easter/config/Config.java index 7f3561d..8c82e24 100644 --- a/src/main/java/com/alttd/easter/config/Config.java +++ b/src/main/java/com/alttd/easter/config/Config.java @@ -31,11 +31,19 @@ public class Config extends AbstractConfig { public static class EGGS { private static final String prefix = "eggs."; - public static double SPAWN_CHANCE = 0.02; // ~2 per night per player + public static double EASY_CHANCE = 0.05; + public static double NORMAL_CHANCE = 0.10; + public static double HARD_CHANCE = 0.25; @SuppressWarnings("unused") private static void load() { - SPAWN_CHANCE = config.getDouble(prefix, "spawn-chance", SPAWN_CHANCE); + EASY_CHANCE = config.getDouble(prefix, "easy-chance", EASY_CHANCE); + NORMAL_CHANCE = config.getDouble(prefix, "normal-chance", NORMAL_CHANCE); + HARD_CHANCE = config.getDouble(prefix, "hard-chance", HARD_CHANCE); + // ensure paths exist in config file with their current values + config.yaml.addDefault(prefix + "easy-chance", EASY_CHANCE); + config.yaml.addDefault(prefix + "normal-chance", NORMAL_CHANCE); + config.yaml.addDefault(prefix + "hard-chance", HARD_CHANCE); } } @@ -123,19 +131,5 @@ public class Config extends AbstractConfig { } config.set(prefix, "next-index", NEXT_INDEX); } - - public static ItemStack getNextPrize() { - if (LIST.isEmpty()) { - log.warn("[Easter] No prizes configured. Staff should configure prizes using /easter setprize."); - return null; - } - if (NEXT_INDEX < 0 || NEXT_INDEX >= LIST.size()) { - NEXT_INDEX = 0; - } - ItemStack prize = LIST.get(NEXT_INDEX).clone(); - NEXT_INDEX = (NEXT_INDEX + 1) % LIST.size(); - config.set(prefix, "next-index", NEXT_INDEX); - return prize; - } } } diff --git a/src/main/java/com/alttd/easter/config/Messages.java b/src/main/java/com/alttd/easter/config/Messages.java index a738554..6c61628 100644 --- a/src/main/java/com/alttd/easter/config/Messages.java +++ b/src/main/java/com/alttd/easter/config/Messages.java @@ -70,7 +70,7 @@ public class Messages extends AbstractConfig { public static String NO_EGGS = "Please come back when you've found some eggs!"; public static String THANK_YOU = "Thank you for finding my eggs ! Keep looking for more!"; public static String ONE_EGG = "Thank you for finding my eggs ! I have received the from you. Please keep looking for more!"; - public static String MULTI_EGGS = "Thank you for finding my eggs ! I have received the , , and from you. Please keep looking for more!"; + public static String MULTI_EGGS = "Thank you for finding my eggs ! I have received from you. Please keep looking for more!"; public static String REWARD = "Thank you! You've turned in 4 unique eggs and earned a prize!"; public static String DUPLICATE_EGGS = "Those are duplicates I already have. Bring me new colors!"; public static String GUI_TITLE = "Turn in Eggs"; diff --git a/src/main/java/com/alttd/easter/egg/EggType.java b/src/main/java/com/alttd/easter/egg/EggType.java index bdce9fe..3bce3f3 100644 --- a/src/main/java/com/alttd/easter/egg/EggType.java +++ b/src/main/java/com/alttd/easter/egg/EggType.java @@ -6,22 +6,24 @@ import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.EntityType; public enum EggType { - BROWN_HUSK(Material.BROWN_GLAZED_TERRACOTTA, EntityType.HUSK, Enchantment.FIRE_PROTECTION, 2), - RED_SPIDER(Material.RED_GLAZED_TERRACOTTA, EntityType.SPIDER, Enchantment.BANE_OF_ARTHROPODS, 2), - ORANGE_BLAZE(Material.ORANGE_GLAZED_TERRACOTTA, EntityType.BLAZE, Enchantment.FIRE_ASPECT, 2), - YELLOW_PIGLIN(Material.YELLOW_GLAZED_TERRACOTTA, EntityType.PIGLIN, Enchantment.FORTUNE, 2), - LIME_CREEPER(Material.LIME_GLAZED_TERRACOTTA, EntityType.CREEPER, Enchantment.BLAST_PROTECTION, 2), - GREEN_ZOMBIE(Material.GREEN_GLAZED_TERRACOTTA, EntityType.ZOMBIE, Enchantment.FEATHER_FALLING, 2), - LIGHT_BLUE_STRAY(Material.LIGHT_BLUE_GLAZED_TERRACOTTA, EntityType.STRAY, Enchantment.FROST_WALKER, 2), - CYAN_GUARDIAN(Material.CYAN_GLAZED_TERRACOTTA, EntityType.GUARDIAN, Enchantment.THORNS, 2), - BLUE_WARDEN(Material.BLUE_GLAZED_TERRACOTTA, EntityType.WARDEN, Enchantment.SWIFT_SNEAK, 2), - PURPLE_ENDER_DRAGON(Material.PURPLE_GLAZED_TERRACOTTA, EntityType.ENDER_DRAGON, Enchantment.POWER, 2), - MAGENTA_ENDERMAN(Material.MAGENTA_GLAZED_TERRACOTTA, EntityType.ENDERMAN, Enchantment.INFINITY, 2), - PINK_HOGLIN(Material.PINK_GLAZED_TERRACOTTA, EntityType.HOGLIN, Enchantment.PIERCING, 2), - WHITE_SKELETON(Material.WHITE_GLAZED_TERRACOTTA, EntityType.SKELETON, Enchantment.MULTISHOT, 2), - LIGHT_GRAY_SILVERFISH(Material.LIGHT_GRAY_GLAZED_TERRACOTTA, EntityType.SILVERFISH, Enchantment.EFFICIENCY, 2), - GRAY_WITHER(Material.GRAY_GLAZED_TERRACOTTA, EntityType.WITHER, Enchantment.SMITE, 2), - BLACK_WITHER_SKELETON(Material.BLACK_GLAZED_TERRACOTTA, EntityType.WITHER_SKELETON, Enchantment.LOOTING, 2); + BROWN_HUSK(Material.BROWN_GLAZED_TERRACOTTA, EntityType.HUSK, Enchantment.FIRE_PROTECTION, 2, Difficulty.EASY), + RED_SPIDER(Material.RED_GLAZED_TERRACOTTA, EntityType.SPIDER, Enchantment.BANE_OF_ARTHROPODS, 2, Difficulty.EASY), + ORANGE_BLAZE(Material.ORANGE_GLAZED_TERRACOTTA, EntityType.BLAZE, Enchantment.FIRE_ASPECT, 2, Difficulty.NORMAL), + YELLOW_PIGLIN(Material.YELLOW_GLAZED_TERRACOTTA, EntityType.PIGLIN, Enchantment.FORTUNE, 2, Difficulty.NORMAL), + LIME_CREEPER(Material.LIME_GLAZED_TERRACOTTA, EntityType.CREEPER, Enchantment.BLAST_PROTECTION, 2, Difficulty.NORMAL), + GREEN_ZOMBIE(Material.GREEN_GLAZED_TERRACOTTA, EntityType.ZOMBIE, Enchantment.FEATHER_FALLING, 2, Difficulty.EASY), + LIGHT_BLUE_STRAY(Material.LIGHT_BLUE_GLAZED_TERRACOTTA, EntityType.STRAY, Enchantment.FROST_WALKER, 2, Difficulty.NORMAL), + CYAN_GUARDIAN(Material.CYAN_GLAZED_TERRACOTTA, EntityType.GUARDIAN, Enchantment.THORNS, 2, Difficulty.HARD), + BLUE_WARDEN(Material.BLUE_GLAZED_TERRACOTTA, EntityType.WARDEN, Enchantment.SWIFT_SNEAK, 2, Difficulty.HARD), + PURPLE_ENDER_DRAGON(Material.PURPLE_GLAZED_TERRACOTTA, EntityType.ENDER_DRAGON, Enchantment.POWER, 2, Difficulty.HARD), + MAGENTA_ENDERMAN(Material.MAGENTA_GLAZED_TERRACOTTA, EntityType.ENDERMAN, Enchantment.INFINITY, 2, Difficulty.NORMAL), + PINK_HOGLIN(Material.PINK_GLAZED_TERRACOTTA, EntityType.HOGLIN, Enchantment.PIERCING, 2, Difficulty.NORMAL), + WHITE_SKELETON(Material.WHITE_GLAZED_TERRACOTTA, EntityType.SKELETON, Enchantment.MULTISHOT, 2, Difficulty.EASY), + LIGHT_GRAY_SILVERFISH(Material.LIGHT_GRAY_GLAZED_TERRACOTTA, EntityType.SILVERFISH, Enchantment.EFFICIENCY, 2, Difficulty.EASY), + GRAY_WITHER(Material.GRAY_GLAZED_TERRACOTTA, EntityType.WITHER, Enchantment.SMITE, 2, Difficulty.HARD), + BLACK_WITHER_SKELETON(Material.BLACK_GLAZED_TERRACOTTA, EntityType.WITHER_SKELETON, Enchantment.LOOTING, 2, Difficulty.HARD); + + public enum Difficulty { EASY, NORMAL, HARD } @Getter private final Material material; @@ -30,12 +32,15 @@ public enum EggType { private final Enchantment enchantment; @Getter private final int enchantLevel; + @Getter + private final Difficulty difficulty; - EggType(Material material, EntityType entityType, Enchantment enchantment, int enchantLevel) { + EggType(Material material, EntityType entityType, Enchantment enchantment, int enchantLevel, Difficulty difficulty) { this.material = material; this.entityType = entityType; this.enchantment = enchantment; this.enchantLevel = enchantLevel; + this.difficulty = difficulty; } public static EggType fromEntityType(EntityType entityType) { diff --git a/src/main/java/com/alttd/easter/glow/GlowManager.java b/src/main/java/com/alttd/easter/glow/GlowManager.java index ce12daa..0b8f470 100644 --- a/src/main/java/com/alttd/easter/glow/GlowManager.java +++ b/src/main/java/com/alttd/easter/glow/GlowManager.java @@ -4,6 +4,7 @@ import com.alttd.easter.egg.EggType; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; import org.bukkit.entity.Entity; +import org.bukkit.plugin.Plugin; import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; @@ -11,7 +12,7 @@ public class GlowManager { private final Scoreboard scoreboard; - public GlowManager(org.bukkit.plugin.Plugin plugin) { + public GlowManager(Plugin plugin) { this.scoreboard = Bukkit.getScoreboardManager().getMainScoreboard(); } diff --git a/src/main/java/com/alttd/easter/gui/TurnInGuiManager.java b/src/main/java/com/alttd/easter/gui/TurnInGuiManager.java index 8c5bc1b..8a25885 100644 --- a/src/main/java/com/alttd/easter/gui/TurnInGuiManager.java +++ b/src/main/java/com/alttd/easter/gui/TurnInGuiManager.java @@ -7,6 +7,7 @@ import com.alttd.easter.egg.EggType; import com.alttd.easter.util.ItemUtils; import lombok.extern.slf4j.Slf4j; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.JoinConfiguration; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.Bukkit; @@ -105,21 +106,36 @@ public class TurnInGuiManager implements Listener { int newlyAdded = dataManager.addEggs(player.getUniqueId(), submitted); dataManager.save(); // Dialog formatting for submission summary - List colors = submitted.stream().map(ItemUtils::colorName).toList(); - if (colors.size() == 1) { + List eggComponents = new ArrayList<>(); + for (EggType type : submitted) { + eggComponents.add(Component.text(ItemUtils.colorName(type))); + } + if (eggComponents.size() == 1) { player.sendRichMessage(Messages.RABBIT.ONE_EGG, Placeholder.parsed("player", player.getName()), - Placeholder.parsed("egg1", colors.getFirst()) + Placeholder.component("egg1", eggComponents.getFirst()) ); } else { - String c1 = !colors.isEmpty() ? colors.get(0) : ""; - String c2 = colors.size() > 1 ? colors.get(1) : ""; - String c3 = colors.size() > 2 ? colors.get(2) : ""; + Component eggsJoined; + if (eggComponents.size() == 2) { + eggsJoined = Component.join( + JoinConfiguration.builder() + .lastSeparator(Component.text(" and ")) + .build(), + eggComponents + ); + } else { + eggsJoined = Component.join( + JoinConfiguration.builder() + .separator(Component.text(", ")) + .lastSeparator(Component.text(", and ")) + .build(), + eggComponents + ); + } player.sendRichMessage(Messages.RABBIT.MULTI_EGGS, Placeholder.parsed("player", player.getName()), - Placeholder.parsed("egg1", c1), - Placeholder.parsed("egg2", c2), - Placeholder.parsed("egg3", c3) + Placeholder.component("eggs", eggsJoined) ); } int newTotal = prevTotal + newlyAdded; diff --git a/src/main/java/com/alttd/easter/listeners/DeathListener.java b/src/main/java/com/alttd/easter/listeners/DeathListener.java index e5900cc..78817e3 100644 --- a/src/main/java/com/alttd/easter/listeners/DeathListener.java +++ b/src/main/java/com/alttd/easter/listeners/DeathListener.java @@ -1,30 +1,41 @@ package com.alttd.easter.listeners; +import com.alttd.easter.config.Config; import com.alttd.easter.egg.EggType; import com.alttd.easter.util.ItemUtils; -import com.alttd.easter.util.Keys; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Mob; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.persistence.PersistentDataType; + +import java.util.concurrent.ThreadLocalRandom; public class DeathListener implements Listener { @EventHandler public void onDeath(EntityDeathEvent event) { LivingEntity entity = event.getEntity(); - String eggName = entity.getPersistentDataContainer().get(Keys.EGG_ENTITY, PersistentDataType.STRING); - if (eggName == null) { + // Only consider AI-capable mobs + if (!(entity instanceof Mob mob) || !mob.isAware()) { return; } - EggType type; - try { - type = EggType.valueOf(eggName); - } catch (IllegalArgumentException ex) { + EggType eggType = EggType.fromEntityType(entity.getType()); + if (eggType == null) { return; } - // Ensure the egg drops - event.getDrops().add(ItemUtils.createEggItem(type)); + double chance; + switch (eggType.getDifficulty()) { + case EASY -> chance = Config.EGGS.EASY_CHANCE; + case NORMAL -> chance = Config.EGGS.NORMAL_CHANCE; + case HARD -> chance = Config.EGGS.HARD_CHANCE; + default -> chance = 0.0; + } + if (chance <= 0) { + return; + } + if (ThreadLocalRandom.current().nextDouble() < chance) { + event.getDrops().add(ItemUtils.createEggItem(eggType)); + } } } diff --git a/src/main/java/com/alttd/easter/listeners/SpawnListener.java b/src/main/java/com/alttd/easter/listeners/SpawnListener.java deleted file mode 100644 index 057844b..0000000 --- a/src/main/java/com/alttd/easter/listeners/SpawnListener.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.alttd.easter.listeners; - -import com.alttd.easter.config.Config; -import com.alttd.easter.egg.EggType; -import com.alttd.easter.glow.GlowManager; -import com.alttd.easter.util.ItemUtils; -import com.alttd.easter.util.Keys; -import org.bukkit.entity.Creature; -import org.bukkit.entity.EntityType; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.inventory.EntityEquipment; -import org.bukkit.inventory.ItemStack; -import org.bukkit.persistence.PersistentDataType; - -import java.util.concurrent.ThreadLocalRandom; - -@SuppressWarnings("ClassCanBeRecord") -public class SpawnListener implements Listener { - - private final GlowManager glowManager; - - public SpawnListener(GlowManager glowManager) { - this.glowManager = glowManager; - } - - @EventHandler - public void onNaturalSpawn(CreatureSpawnEvent event) { - if (event.getSpawnReason() != CreatureSpawnEvent.SpawnReason.NATURAL) { - return; - } - if (!(event.getEntity() instanceof Creature creature)) { - return; - } - EntityType type = event.getEntityType(); - EggType eggType = EggType.fromEntityType(type); - if (eggType == null) { - return; - } - double chance = Config.EGGS.SPAWN_CHANCE; - if (ThreadLocalRandom.current().nextDouble() >= chance) { - return; - } - - ItemStack eggItem = ItemUtils.createEggItem(eggType); - EntityEquipment equipment = creature.getEquipment(); - equipment.setHelmet(eggItem); - equipment.setHelmetDropChance(1.0f); - // tag entity so we know it's an egg carrier - creature.getPersistentDataContainer().set(Keys.EGG_ENTITY, PersistentDataType.STRING, eggType.name()); - creature.setGlowing(true); - glowManager.applyGlow(creature, eggType); - } -} diff --git a/src/main/java/com/alttd/easter/util/ItemUtils.java b/src/main/java/com/alttd/easter/util/ItemUtils.java index de8657a..34b2390 100644 --- a/src/main/java/com/alttd/easter/util/ItemUtils.java +++ b/src/main/java/com/alttd/easter/util/ItemUtils.java @@ -28,8 +28,8 @@ public final class ItemUtils { case MAGENTA_ENDERMAN -> "Magenta"; case PINK_HOGLIN -> "Pink"; case WHITE_SKELETON -> "White"; - case LIGHT_GRAY_SILVERFISH -> "Light Grey"; - case GRAY_WITHER -> "Grey"; + case LIGHT_GRAY_SILVERFISH -> "Light Gray"; + case GRAY_WITHER -> "Gray"; case BLACK_WITHER_SKELETON -> "Black"; }; }