From 61cf44a40792eebed2a798de5ab1881273ca5698 Mon Sep 17 00:00:00 2001 From: hyperdefined Date: Tue, 1 Mar 2022 23:21:09 -0500 Subject: [PATCH] handle finding who opens a newly spawned chest better --- .../java/lol/hyper/toolstats/ToolStats.java | 5 +- .../hyper/toolstats/events/GenerateLoot.java | 32 ++++++++-- .../toolstats/events/PlayerInteract.java | 60 +++++++++++++++++++ 3 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 src/main/java/lol/hyper/toolstats/events/PlayerInteract.java diff --git a/src/main/java/lol/hyper/toolstats/ToolStats.java b/src/main/java/lol/hyper/toolstats/ToolStats.java index 98cb202..b688ee9 100644 --- a/src/main/java/lol/hyper/toolstats/ToolStats.java +++ b/src/main/java/lol/hyper/toolstats/ToolStats.java @@ -32,8 +32,6 @@ import org.bukkit.plugin.java.JavaPlugin; import java.io.File; import java.io.IOException; -import java.util.HashSet; -import java.util.Set; import java.util.logging.Logger; public final class ToolStats extends JavaPlugin { @@ -65,6 +63,7 @@ public final class ToolStats extends JavaPlugin { public PickupItem pickupItem; public EntityDamage mobKill; public PlayerFish playerFish; + public PlayerInteract playerInteract; public SheepShear sheepShear; public VillagerTrade villagerTrade; public CommandToolStats commandToolStats; @@ -89,6 +88,7 @@ public final class ToolStats extends JavaPlugin { pickupItem = new PickupItem(this); mobKill = new EntityDamage(this); playerFish = new PlayerFish(this); + playerInteract = new PlayerInteract(this); sheepShear = new SheepShear(this); villagerTrade = new VillagerTrade(this); commandToolStats = new CommandToolStats(this); @@ -101,6 +101,7 @@ public final class ToolStats extends JavaPlugin { Bukkit.getServer().getPluginManager().registerEvents(pickupItem, this); Bukkit.getServer().getPluginManager().registerEvents(mobKill, this); Bukkit.getServer().getPluginManager().registerEvents(playerFish, this); + Bukkit.getServer().getPluginManager().registerEvents(playerInteract, this); Bukkit.getServer().getPluginManager().registerEvents(sheepShear, this); Bukkit.getServer().getPluginManager().registerEvents(villagerTrade, this); diff --git a/src/main/java/lol/hyper/toolstats/events/GenerateLoot.java b/src/main/java/lol/hyper/toolstats/events/GenerateLoot.java index 55b2a6f..e15ca28 100644 --- a/src/main/java/lol/hyper/toolstats/events/GenerateLoot.java +++ b/src/main/java/lol/hyper/toolstats/events/GenerateLoot.java @@ -20,7 +20,9 @@ package lol.hyper.toolstats.events; import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.UUIDDataType; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -56,13 +58,31 @@ public class GenerateLoot implements Listener { if (inventoryHolder == null) { return; } - Inventory chest = inventoryHolder.getInventory(); + Location lootLocation = event.getLootContext().getLocation(); + Inventory chestInv = inventoryHolder.getInventory(); + Block openedChest = null; + // look at the current list of opened chest and get the distance + // between the lootcontext location and chest location + // if the distance is less than 1, it's the same chest + for (Block chest : toolStats.playerInteract.openedChests.keySet()) { + Location chestLocation = chest.getLocation(); + double distance = lootLocation.distance(chestLocation); + if (distance <= 1.0) { + openedChest = chest; + } + } + // ignore if the chest is not in the same location + if (openedChest == null) { + return; + } + // run task later since if it runs on the same tick it breaks idk + Block finalOpenedChest = openedChest; Bukkit.getScheduler().runTaskLater(toolStats, () -> { - Player player = (Player) chest.getViewers().get(0); - // do a classic for loot so we keep track of chest index of item - for (int i = 0; i < chest.getContents().length; i++) { - ItemStack itemStack = chest.getItem(i); + Player player = toolStats.playerInteract.openedChests.get(finalOpenedChest); + // do a classic for loop, so we keep track of chest index of item + for (int i = 0; i < chestInv.getContents().length; i++) { + ItemStack itemStack = chestInv.getItem(i); // ignore air if (itemStack == null || itemStack.getType() == Material.AIR) { continue; @@ -70,7 +90,7 @@ public class GenerateLoot implements Listener { String name = itemStack.getType().toString().toLowerCase(Locale.ROOT); for (String x : validItems) { if (name.contains(x)) { - chest.setItem(i, addLore(itemStack, player)); + chestInv.setItem(i, addLore(itemStack, player)); } } } diff --git a/src/main/java/lol/hyper/toolstats/events/PlayerInteract.java b/src/main/java/lol/hyper/toolstats/events/PlayerInteract.java new file mode 100644 index 0000000..2ff9317 --- /dev/null +++ b/src/main/java/lol/hyper/toolstats/events/PlayerInteract.java @@ -0,0 +1,60 @@ +/* + * This file is part of ToolStats. + * + * ToolStats is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ToolStats is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ToolStats. If not, see . + */ + +package lol.hyper.toolstats.events; + +import lol.hyper.toolstats.ToolStats; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; + +import java.util.HashMap; + +public class PlayerInteract implements Listener { + + private final ToolStats toolStats; + + public HashMap openedChests = new HashMap<>(); + + public PlayerInteract(ToolStats toolStats) { + this.toolStats = toolStats; + } + + @EventHandler + public void onInteract(PlayerInteractEvent event) { + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + + Block block = event.getClickedBlock(); + if (block == null) { + return; + } + // store when a player opens a chest + // this is used to detect who opens a newly spawned chest + // since that is not really tracked on the lootevent + if (block.getType() != Material.AIR && block.getType() == Material.CHEST) { + openedChests.put(block, event.getPlayer()); + Bukkit.getScheduler().runTaskLater(toolStats, () -> openedChests.remove(block), 20); + } + } +}