diff --git a/src/main/java/com/alttd/playerutils/event_listeners/VillagerWorkstationEvent.java b/src/main/java/com/alttd/playerutils/event_listeners/VillagerWorkstationEvent.java new file mode 100644 index 0000000..42d571d --- /dev/null +++ b/src/main/java/com/alttd/playerutils/event_listeners/VillagerWorkstationEvent.java @@ -0,0 +1,84 @@ +package com.alttd.playerutils.event_listeners; + +import com.alttd.playerutils.config.Config; +import com.alttd.playerutils.config.Messages; +import lombok.extern.slf4j.Slf4j; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Villager; +import org.bukkit.entity.memory.MemoryKey; +import org.bukkit.event.Listener; +import org.bukkit.plugin.java.JavaPlugin; + +@Slf4j +public class VillagerWorkstationEvent implements Listener { + + public VillagerWorkstationEvent(JavaPlugin plugin) { + Bukkit.getScheduler().runTaskTimer(plugin, this::checkPlayersLookingAtVillagers, + 0L, Config.VILLAGER_WORKSTATION.CHECK_INTERVAL_TICKS); + } + + private void checkPlayersLookingAtVillagers() { + for (Player player : Bukkit.getOnlinePlayers()) { + if (!player.getInventory().getItemInMainHand().getType().equals(Material.AIR)) { + continue; + } + Entity target = player.getTargetEntity(Config.VILLAGER_WORKSTATION.RANGE); + if (!(target instanceof Villager villager)) { + continue; + } + showWorkstation(player, villager); + } + } + + private void showWorkstation(Player player, Villager villager) { + String professionName = formatName(villager.getProfession().name()); + Location jobSite = villager.getMemory(MemoryKey.JOB_SITE); + + if (jobSite == null) { + player.sendActionBar(MiniMessage.miniMessage().deserialize( + Messages.VILLAGER_WORKSTATION.NO_WORKSTATION + .replace("", professionName))); + return; + } + + // Read the actual block type at the linked location so it reflects reality + String blockName = formatName(jobSite.getBlock().getType().name()); + player.sendActionBar(MiniMessage.miniMessage().deserialize( + Messages.VILLAGER_WORKSTATION.WORKSTATION + .replace("", professionName) + .replace("", blockName))); + + spawnWorkstationParticles(player, jobSite.getBlock().getLocation()); + } + + private void spawnWorkstationParticles(Player player, Location blockLoc) { + World world = blockLoc.getWorld(); + if (world == null) { + return; + } + + double cx = blockLoc.getX() + 0.5; + double cy = blockLoc.getY() + 1.1; + double cz = blockLoc.getZ() + 0.5; + int count = Config.VILLAGER_WORKSTATION.PARTICLE_RING_COUNT; + + for (int i = 0; i < count; i++) { + double angle = (2 * Math.PI * i) / count; + double x = cx + 0.5 * Math.cos(angle); + double z = cz + 0.5 * Math.sin(angle); + player.spawnParticle(Particle.VILLAGER_HAPPY, x, cy, z, 1, 0, 0, 0, 0); + } + } + + private static String formatName(String enumName) { + String lower = enumName.replace("_", " ").toLowerCase(); + return Character.toUpperCase(lower.charAt(0)) + lower.substring(1); + } +}