Newer
Older
ChallengeSystem / Challenge / src / main / java / de / fanta / challenge / challenges / ManHunt.java
@fanta fanta on 20 Jun 2024 9 KB components :,)
package de.fanta.challenge.challenges;

import de.fanta.challenge.Challenge;
import de.fanta.challenge.events.TimerChangedEvent;
import de.fanta.challenge.schedular.CancellableTask;
import de.fanta.challenge.utils.Config;
import de.fanta.challengeutils.ItemUtils;
import de.fanta.challengeutils.Color;
import net.kyori.adventure.text.Component;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.event.player.PlayerArmorStandManipulateEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.CompassMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;

import java.util.HashMap;

public class ManHunt implements Listener {
    private static final Challenge plugin = Challenge.getPlugin();
    private CancellableTask task;
    private final HashMap<World, Location> locationList = new HashMap<>();
    private static final NamespacedKey hunterItemKey = new NamespacedKey(plugin, "HunterItem");
    private static ItemStack hunterItem;

    @EventHandler
    public void onActivation(TimerChangedEvent event) {
        if (isRunning()) {
            if (event.isRunning()) {
                startUpdateTask();
            } else {
                stopUpdateTask();
            }
        }
    }

    @EventHandler
    public void onDropItem(PlayerDropItemEvent e) {
        if (isRunning()) {
            ItemStack stack = e.getItemDrop().getItemStack();
            ItemMeta meta = stack.getItemMeta();

            if (meta != null && meta.getPersistentDataContainer().has(hunterItemKey)) {
                e.setCancelled(true);
            }
        }
    }

    private boolean isRunning() {
        return Config.getBoolean("manhunt") && plugin.getTimer().isRunning();
    }

    @EventHandler
    public void onSwapItem(PlayerSwapHandItemsEvent e) {
        if (!isRunning()) {
            return;
        }
        Player p = e.getPlayer();
        ItemStack stack = p.getInventory().getItemInMainHand();
        ItemMeta meta = stack.getItemMeta();
        if (meta != null && meta.getPersistentDataContainer().has(hunterItemKey)) {
            e.setCancelled(true);
        }
    }

    @EventHandler
    public void onItemMove(InventoryMoveItemEvent e) {
        if (!isRunning()) {
            return;
        }
        ItemStack stack = e.getItem();
        ItemMeta meta = stack.getItemMeta();
        if (meta != null && meta.getPersistentDataContainer().has(hunterItemKey)) {
            e.setCancelled(true);
        }
    }

    @EventHandler
    public void onInventoryClick(InventoryClickEvent e) {
        if (!isRunning()) {
            return;
        }
        ItemStack stack = e.getCurrentItem();
        ItemStack stackInHand = e.getCursor();
        Player player = (Player) e.getWhoClicked();
        ItemMeta meta = null;
        ItemMeta metaInHand = null;

        if (stack != null) {
            meta = stack.getItemMeta();
        }

        metaInHand = stackInHand.getItemMeta();

        if (e.getClick() == ClickType.NUMBER_KEY) {
            int slot = e.getHotbarButton();
            if (slot >= 0 && slot < 9) {
                if (!e.getWhoClicked().getInventory().equals(e.getInventory())) {
                    ItemStack swap = e.getWhoClicked().getInventory().getItem(slot);
                    if (swap != null) {
                        ItemMeta swapItemMeta = swap.getItemMeta();
                        if (swapItemMeta != null && swapItemMeta.getPersistentDataContainer().has(hunterItemKey)) {
                            e.setCancelled(true);
                        }
                    }
                }
            }
        }

        if (meta != null && meta.getPersistentDataContainer().has(hunterItemKey) || metaInHand != null && metaInHand.getPersistentDataContainer().has(hunterItemKey)) {
            switch (e.getAction()) {
                case NOTHING, PICKUP_ALL, PICKUP_HALF, PICKUP_ONE, PICKUP_SOME, PLACE_ALL, PLACE_ONE, PLACE_SOME, SWAP_WITH_CURSOR, COLLECT_TO_CURSOR, HOTBAR_SWAP -> {
                    if (e.getClickedInventory() != player.getInventory()) {
                        e.setCancelled(true);
                    }
                }
                case MOVE_TO_OTHER_INVENTORY -> {
                    if (!(e.getInventory() instanceof CraftingInventory)) {
                        e.setCancelled(true);
                    }
                }
                default -> e.setCancelled(true);
            }
        }
    }

    @EventHandler
    public void onItemDrag(InventoryDragEvent e) {
        if (!isRunning()) {
            return;
        }
        ItemStack stack = e.getCursor();
        ItemMeta stackMeta = null;
        ItemStack oldStack = e.getOldCursor();
        ItemMeta oldStackMeta = null;
        if (stack != null) {
            if (stack.getItemMeta() != null) {
                stackMeta = stack.getItemMeta();
            }
        }

        if (oldStack.getItemMeta() != null) {
            oldStackMeta = oldStack.getItemMeta();
        }

        if (stackMeta != null && stackMeta.getPersistentDataContainer().has(hunterItemKey) || oldStackMeta != null && oldStackMeta.getPersistentDataContainer().has(hunterItemKey)) {
            if (!(e.getInventory() instanceof CraftingInventory)) {
                e.setCancelled(true);
            }
        }
    }

    @EventHandler(priority = EventPriority.LOWEST)
    public void onPlayerInteractEntity(PlayerArmorStandManipulateEvent e) {
        if (!isRunning()) {
            return;
        }
        Player p = e.getPlayer();
        ItemStack stack = p.getInventory().getItemInMainHand();
        ItemMeta meta = stack.getItemMeta();
        if (meta != null && meta.getPersistentDataContainer().has(hunterItemKey)) {
            e.setCancelled(true);
        }
    }

    @EventHandler
    public void onPlayerDeath(PlayerDeathEvent e) {
        if (!isRunning()) {
            return;
        }
        ItemStack[] inv = e.getEntity().getInventory().getContents();
        for (ItemStack stack : inv) {
            if (stack != null) {
                ItemMeta meta = stack.getItemMeta();
                if (meta != null && meta.getPersistentDataContainer().has(hunterItemKey)) {
                    e.getItemsToKeep().add(stack);
                    e.getDrops().remove(stack);
                }
            }
        }
    }

    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent e) {
        if (!Config.getBoolean("manhunt")) {
            return;
        }
        Player player = e.getPlayer();
        int count = 0;

        for (ItemStack stack : player.getInventory().getContents()) {
            if (stack != null && stack.getItemMeta() instanceof CompassMeta compassMeta && compassMeta.getPersistentDataContainer().has(hunterItemKey)) {
                count++;
            }
        }

        if (count == 0) {
            player.getInventory().setItem(8, hunterItem);
        }
    }
    public void startUpdateTask() {
        task = plugin.getScheduler().runGlobalAtFixedRate(this::tick, 1L, 1L);
    }

    public void stopUpdateTask() {
        task.cancel();
        task = null;
    }

    private void tick() {
        Player editor = plugin.getCurrentEditor();
        if (editor == null) {
            return;
        }
        locationList.put(editor.getWorld(), editor.getLocation());
        for (Player player : plugin.getVanish().getPlayerListWithoutVanishPlayers()) {
            if (locationList.get(player.getWorld()) != null) {
                for (ItemStack stack : player.getInventory().getContents()) {
                    if (stack != null && stack.getItemMeta() instanceof CompassMeta compassMeta && compassMeta.getPersistentDataContainer().has(hunterItemKey)) {
                        compassMeta.setLodestone(locationList.get(player.getWorld()));
                        compassMeta.setLodestoneTracked(false);
                        stack.setItemMeta(compassMeta);
                    }
                }
            }
        }
    }

    public static ItemStack createHunterItem() {
        ItemStack stack = ItemUtils.createGuiItem(Material.COMPASS, Component.text("Hunter Kompass", Color.GREEN), Component.text("Zeigt die Richtung zum gejagten Spieler", Color.GREEN));
        CompassMeta meta = (CompassMeta) stack.getItemMeta();
        meta.addEnchant(Enchantment.VANISHING_CURSE, 1, true);
        meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
        meta.getPersistentDataContainer().set(hunterItemKey, PersistentDataType.STRING, "HunterItem");
        stack.setItemMeta(meta);

        return stack;
    }

    public static void start() {
        hunterItem = createHunterItem();
        for (Player pp : plugin.getVanish().getPlayerListWithoutVanishPlayers()) {
            if (plugin.getCurrentEditor() != null && plugin.getCurrentEditor() != pp) {
                pp.getInventory().setItem(8, hunterItem);
            }
        }
    }

    public static void stop() {
        for (Player pp : plugin.getVanish().getPlayerListWithoutVanishPlayers()) {
            for (ItemStack stack : pp.getInventory().getContents()) {
                if (stack != null && stack.getItemMeta() instanceof CompassMeta compassMeta && compassMeta.getPersistentDataContainer().has(hunterItemKey)) {
                    stack.setAmount(0);
                }
            }
        }
    }
}