From 41d0c94eed2eb2b8b05fd8d858bd13bddd4d9f68 Mon Sep 17 00:00:00 2001 From: Teriuihi Date: Mon, 31 Mar 2025 22:03:42 +0200 Subject: [PATCH] Add April Fools event listener for themed interactions Introduced a new event listener, `AprilFoolsEvent`, to handle April Fools Day interactions with players. This includes good and bad actions that trigger messages, potion effects, and other behaviors based on player activities. Registered the new event listener in `PlayerUtils`. --- .../com/alttd/playerutils/PlayerUtils.java | 1 + .../event_listeners/AprilFoolsEvent.java | 226 ++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 src/main/java/com/alttd/playerutils/event_listeners/AprilFoolsEvent.java diff --git a/src/main/java/com/alttd/playerutils/PlayerUtils.java b/src/main/java/com/alttd/playerutils/PlayerUtils.java index 7ffbfe7..06f4869 100644 --- a/src/main/java/com/alttd/playerutils/PlayerUtils.java +++ b/src/main/java/com/alttd/playerutils/PlayerUtils.java @@ -42,6 +42,7 @@ public final class PlayerUtils extends JavaPlugin { pluginManager.registerEvents(new TeleportEvent(), this); pluginManager.registerEvents(new GoatHornEvent(logger), this); pluginManager.registerEvents(new LimitArmorStands(this, logger), this); + pluginManager.registerEvents(new AprilFoolsEvent(), this); RotateBlockEvent rotateBlockEvent = new RotateBlockEvent(logger); pluginManager.registerEvents(rotateBlockEvent, this); diff --git a/src/main/java/com/alttd/playerutils/event_listeners/AprilFoolsEvent.java b/src/main/java/com/alttd/playerutils/event_listeners/AprilFoolsEvent.java new file mode 100644 index 0000000..55cbd5b --- /dev/null +++ b/src/main/java/com/alttd/playerutils/event_listeners/AprilFoolsEvent.java @@ -0,0 +1,226 @@ +package com.alttd.playerutils.event_listeners; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.Material; +import org.bukkit.Tag; +import org.bukkit.block.Block; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Monster; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityBreedEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.player.PlayerBucketEntityEvent; +import org.bukkit.event.player.PlayerFishEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.NotNull; + +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + +public class AprilFoolsEvent implements Listener { + + MiniMessage miniMessage = MiniMessage.miniMessage(); + + List happyMessages = List.of( + miniMessage.deserialize("You have a sudden urge of calmness and peace"), + miniMessage.deserialize("Mother nature is pleased and graces us with her beauty!"), + miniMessage.deserialize("The gentle breeze feels like a soothing hug from nature.") + ); + + List angryMessages = List.of( + miniMessage.deserialize("Something seems off..."), + miniMessage.deserialize("Mother nature is angry and furious with you!"), + miniMessage.deserialize("The wind picks up, carrying the anger of the earth.") + ); + + private final List badEffects = List.of(PotionEffectType.BLINDNESS, PotionEffectType.NAUSEA, + PotionEffectType.LEVITATION, PotionEffectType.DARKNESS, PotionEffectType.MINING_FATIGUE, PotionEffectType.SLOWNESS); + + private final List goodEffects = List.of(PotionEffectType.ABSORPTION, PotionEffectType.GLOWING, + PotionEffectType.HEALTH_BOOST, PotionEffectType.HERO_OF_THE_VILLAGE, PotionEffectType.LUCK, PotionEffectType.REGENERATION, + PotionEffectType.REGENERATION, PotionEffectType.RESISTANCE, PotionEffectType.SATURATION, PotionEffectType.STRENGTH); + + private final List badBlocks = List.of(Material.SHORT_GRASS, Material.TALL_GRASS, Material.SEAGRASS, + Material.TALL_SEAGRASS, Material.LILY_PAD, Material.KELP, Material.KELP_PLANT, Material.BEEHIVE, + Material.BAMBOO, Material.MOSS_BLOCK, Material.CACTUS, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF); + + private final List goodBlocks = List.of(Material.CACTUS, Material.AZALEA, Material.FLOWERING_AZALEA); + + private final HashMap goodActions = new HashMap<>(); + + private final HashMap badActions = new HashMap<>(); + + private boolean isFlower(Material material) { + return Tag.FLOWERS.isTagged(material); + } + + private boolean isLog(Material material) { + return Tag.LOGS.isTagged(material); + } + + private boolean isLeaves(Material material) { + return Tag.LEAVES.isTagged(material); + } + + private boolean isBadBlock(Material material) { + return badBlocks.contains(material) || isFlower(material) || isLog(material) || isLeaves(material); + } + + private boolean isGoodBlock(@NotNull Material material) { + return goodBlocks.contains(material) || isFlower(material); + } + + private boolean isNotAprilFools() { + LocalDate currentDate = LocalDate.now(ZoneOffset.UTC); + return currentDate.getMonthValue() != 4 || currentDate.getDayOfMonth() != 1; + } + + /** + * Determines whether the provided count exceeds a randomly generated limit. + * The limit is generated as a random integer between 100 and 300, inclusive. + * + * @param count the value to be compared against the generated random limit + * @return true if the count is greater than the random limit; false otherwise + */ + private boolean underLimit(int count) { + int randomValue = 100 + (int) (Math.random() * 201); + return count <= randomValue; + } + + private Component getRandomMessage(@NotNull List messages) { + return messages.get((int) (Math.random() * messages.size())); + } + + private PotionEffectType getRandomEffect(@NotNull List potionEffectTypes) { + return potionEffectTypes.get((int) (Math.random() * potionEffectTypes.size())); + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent event) { + if (isNotAprilFools()) { + return; + } + if (!isGoodBlock(event.getBlock().getType())) { + return; + } + runGoodAction(event.getPlayer()); + } + + @EventHandler + public void onGrassBlockBoneMealed(PlayerInteractEvent event) { + if (isNotAprilFools()) { + return; + } + + if (!event.getAction().isRightClick()) { + return; + } + + ItemStack itemInHand = event.getPlayer().getInventory().getItemInMainHand(); + if (itemInHand.getType() != Material.BONE_MEAL) { + return; + } + + Block clickedBlock = event.getClickedBlock(); + if (clickedBlock == null || clickedBlock.getType() != Material.GRASS_BLOCK) { + return; + } + + if (event.getHand() != EquipmentSlot.HAND) { + return; + } + runGoodAction(event.getPlayer()); + } + + @EventHandler + public void onAnimalBred(EntityBreedEvent event) { + if (isNotAprilFools()) { + return; + } + if (!(event.getBreeder() instanceof Player player)) { + return; + } + + runGoodAction(player); + } + + private void runGoodAction(@NotNull Player player) { + goodActions.merge(player.getUniqueId(), 1, Integer::sum); + if (underLimit(goodActions.get(player.getUniqueId()))) { + return; + } + player.sendMessage(getRandomMessage(happyMessages)); + player.addPotionEffect(getRandomEffect(goodEffects).createEffect(60 * 20, 1)); + goodActions.put(player.getUniqueId(), 0); + } + + @EventHandler + public void onBlockBreak(BlockBreakEvent event) { + if (isNotAprilFools()) { + return; + } + if (!isBadBlock(event.getBlock().getType())) { + return; + } + Player player = event.getPlayer(); + runBadAction(player); + } + + @EventHandler + public void onAnimalKilled(EntityDeathEvent event) { + if (isNotAprilFools()) { + return; + } + LivingEntity entity = event.getEntity(); + if (entity.getKiller() == null) { + return; + } + + if (entity instanceof Monster) { + return; + } + + Player player = entity.getKiller(); + runBadAction(player); + } + + @EventHandler + public void onFishCollected(PlayerBucketEntityEvent event) { + if (isNotAprilFools()) { + return; + } + Player player = event.getPlayer(); + runBadAction(player); + } + + @EventHandler + public void onPlayerFish(PlayerFishEvent event) { + if (isNotAprilFools()) { + return; + } + Player player = event.getPlayer(); + runBadAction(player); + } + + private void runBadAction(@NotNull Player player) { + badActions.merge(player.getUniqueId(), 1, Integer::sum); + if (underLimit(badActions.get(player.getUniqueId()))) { + return; + } + player.sendMessage(getRandomMessage(angryMessages)); + player.addPotionEffect(getRandomEffect(badEffects).createEffect(10 * 20, 1)); + badActions.put(player.getUniqueId(), 0); + } + +}