From 640db6e34450aad032d8cabfc7f52c837bef272b Mon Sep 17 00:00:00 2001 From: ceze88 Date: Wed, 29 Mar 2023 21:21:00 +0200 Subject: [PATCH] Fix entity stacking, looting --- .../commands/CommandRemoveAll.java | 5 +++- .../listeners/BlockListeners.java | 10 +++++--- .../listeners/DeathListeners.java | 24 +++++++++++++++++++ .../entity/EntityCurrentListener.java | 5 ++-- .../lootables/LootablesManager.java | 4 ++++ .../stackable/entity/EntityStack.java | 14 ++--------- .../stackable/entity/EntityStackManager.java | 4 ++-- .../entity/custom/CustomEntityManager.java | 7 ++++++ .../ultimatestacker/tasks/StackingTask.java | 18 ++++++++------ 9 files changed, 64 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/songoda/ultimatestacker/commands/CommandRemoveAll.java b/src/main/java/com/songoda/ultimatestacker/commands/CommandRemoveAll.java index 840a8eb..ea8cca8 100644 --- a/src/main/java/com/songoda/ultimatestacker/commands/CommandRemoveAll.java +++ b/src/main/java/com/songoda/ultimatestacker/commands/CommandRemoveAll.java @@ -3,6 +3,7 @@ package com.songoda.ultimatestacker.commands; import com.songoda.core.commands.AbstractCommand; import com.songoda.core.utils.TextUtils; import com.songoda.ultimatestacker.UltimateStacker; +import com.songoda.ultimatestacker.stackable.entity.EntityStack; import com.songoda.ultimatestacker.stackable.entity.EntityStackManager; import com.songoda.ultimatestacker.utils.Methods; import org.bukkit.Bukkit; @@ -48,7 +49,9 @@ public class CommandRemoveAll extends AbstractCommand { if (entityO instanceof LivingEntity && (stackManager.isStackedEntity(entityO) || all) && type.equalsIgnoreCase("entities")) { - plugin.getEntityStackManager().getStack((LivingEntity) entityO).destroy(); + EntityStack stack = plugin.getEntityStackManager().getStack((LivingEntity) entityO); + if (stack == null) continue; + stack.destroy(); amountRemoved++; } else if (entityO.getType() == EntityType.DROPPED_ITEM && type.equalsIgnoreCase("items")) { if (!UltimateStacker.hasCustomAmount((Item)entityO) && !all) diff --git a/src/main/java/com/songoda/ultimatestacker/listeners/BlockListeners.java b/src/main/java/com/songoda/ultimatestacker/listeners/BlockListeners.java index 85513c9..f88544b 100644 --- a/src/main/java/com/songoda/ultimatestacker/listeners/BlockListeners.java +++ b/src/main/java/com/songoda/ultimatestacker/listeners/BlockListeners.java @@ -19,6 +19,7 @@ import org.bukkit.block.CreatureSpawner; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; +import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -40,8 +41,9 @@ public class BlockListeners implements Listener { this.plugin = plugin; } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + @EventHandler(priority = EventPriority.HIGHEST) public void onBlockInteract(PlayerInteractEvent event) { + if (event.useInteractedBlock() == Event.Result.DENY) return; Block block = event.getClickedBlock(); Player player = event.getPlayer(); CompatibleHand hand = CompatibleHand.getHand(event); @@ -166,8 +168,9 @@ public class BlockListeners implements Listener { } } - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + @EventHandler(priority = EventPriority.HIGHEST) public void onBlockPlace(BlockPlaceEvent event) { + if (event.isCancelled()) return; Block block = event.getBlock(); Player player = event.getPlayer(); @@ -196,8 +199,9 @@ public class BlockListeners implements Listener { plugin.updateHologram(stack); } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + @EventHandler(priority = EventPriority.HIGHEST) public void onBlockBreak(BlockBreakEvent event) { + if (event.isCancelled()) return; Block block = event.getBlock(); if (block.getType() != CompatibleMaterial.SPAWNER.getMaterial()) return; diff --git a/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java b/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java index 48744ad..4082770 100644 --- a/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java +++ b/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java @@ -7,6 +7,7 @@ import com.songoda.core.lootables.loot.DropUtils; import com.songoda.ultimatestacker.UltimateStacker; import com.songoda.ultimatestacker.settings.Settings; import com.songoda.ultimatestacker.stackable.entity.EntityStack; +import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.GameRule; import org.bukkit.Material; @@ -82,6 +83,10 @@ public class DeathListeners implements Listener { drops.clear(); if (plugin.getCustomEntityManager().getCustomEntity(entity) == null) { + //replace %player% in drop commands with the last player to damage the entity + //Run commands here, or it will be buggy + runCommands(entity, drops); + if (plugin.getEntityStackManager().isStackedEntity(event.getEntity())) { plugin.getEntityStackManager().getStack(event.getEntity()).onDeath(entity, drops, custom, event.getDroppedExp(), event); } else { @@ -92,6 +97,25 @@ public class DeathListeners implements Listener { finalItems.remove(entity.getUniqueId()); } + private void runCommands(LivingEntity entity, List drops) { + String lastDamage = plugin.getEntityStackManager().getLastPlayerDamage(entity); + if (lastDamage != null) { + List commands = new ArrayList<>(); + drops.forEach(drop -> { + if (drop.getCommand() != null) { + String command = drop.getCommand().replace("%player%", lastDamage); + drop.setCommand(null); + commands.add(command); + } + }); + Bukkit.getScheduler().runTask(plugin, () -> { + for (String command : commands) { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); + } + }); + } + } + private boolean shouldDrop(LivingEntity entity, Material material) { if (entity.getEquipment() != null && entity.getEquipment().getArmorContents().length != 0) { if (Settings.DONT_DROP_ARMOR.getBoolean()) diff --git a/src/main/java/com/songoda/ultimatestacker/listeners/entity/EntityCurrentListener.java b/src/main/java/com/songoda/ultimatestacker/listeners/entity/EntityCurrentListener.java index 71bba69..a32b96c 100644 --- a/src/main/java/com/songoda/ultimatestacker/listeners/entity/EntityCurrentListener.java +++ b/src/main/java/com/songoda/ultimatestacker/listeners/entity/EntityCurrentListener.java @@ -1,15 +1,16 @@ package com.songoda.ultimatestacker.listeners.entity; import com.songoda.ultimatestacker.UltimateStacker; +import com.songoda.ultimatestacker.settings.Settings; import com.songoda.ultimatestacker.stackable.entity.EntityStack; import com.songoda.ultimatestacker.stackable.entity.EntityStackManager; import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Slime; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityTransformEvent; import org.bukkit.event.world.EntitiesLoadEvent; @@ -31,11 +32,11 @@ public class EntityCurrentListener implements Listener { && event.getEntity() instanceof LivingEntity && event.getTransformedEntity() instanceof LivingEntity) { if (event.getTransformReason().equals(EntityTransformEvent.TransformReason.SPLIT)) { - stackManager.getStack((LivingEntity) event.getEntity()).removeEntityFromStack(1); event.setCancelled(true); return; } EntityStack stack = stackManager.updateStack((LivingEntity) event.getEntity(), (LivingEntity) event.getTransformedEntity()); + if (stack == null) return; stack.releaseHost(); } } diff --git a/src/main/java/com/songoda/ultimatestacker/lootables/LootablesManager.java b/src/main/java/com/songoda/ultimatestacker/lootables/LootablesManager.java index ea65de0..156b114 100644 --- a/src/main/java/com/songoda/ultimatestacker/lootables/LootablesManager.java +++ b/src/main/java/com/songoda/ultimatestacker/lootables/LootablesManager.java @@ -101,6 +101,10 @@ public class LootablesManager { looting); } + public List getItemStackDrops(LivingEntity entity, int times) { + return getDrops(entity, times).stream().map(Drop::getItemStack).collect(Collectors.toList()); + } + public List getDrops(LivingEntity entity, int times) { return getDrops(entity, times, 3); } diff --git a/src/main/java/com/songoda/ultimatestacker/stackable/entity/EntityStack.java b/src/main/java/com/songoda/ultimatestacker/stackable/entity/EntityStack.java index 998f568..4b6b27f 100644 --- a/src/main/java/com/songoda/ultimatestacker/stackable/entity/EntityStack.java +++ b/src/main/java/com/songoda/ultimatestacker/stackable/entity/EntityStack.java @@ -23,6 +23,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.concurrent.ThreadLocalRandom; @@ -116,22 +117,11 @@ public class EntityStack extends StackedEntity { killed.setCustomName(null); killed.setCustomNameVisible(false); - //replace %player% in drop commands with the last player to damage the entity - String lastDamage = plugin.getEntityStackManager().getLastPlayerDamage(killed); - if (lastDamage != null) { - drops.forEach(drop -> { - if (drop.getCommand() != null) { - drop.setCommand(drop.getCommand().replace("%player%", lastDamage)); - } - }); - } - boolean killWholeStack = Settings.KILL_WHOLE_STACK_ON_DEATH.getBoolean() || plugin.getMobFile().getBoolean("Mobs." + killed.getType().name() + ".Kill Whole Stack"); if (killWholeStack && getAmount() > 1) { handleWholeStackDeath(killed, drops, custom, droppedExp, event); - return; } else if (getAmount() > 1) { List reasons = Settings.INSTANT_KILL.getStringList(); EntityDamageEvent lastDamageCause = killed.getLastDamageCause(); @@ -144,8 +134,8 @@ public class EntityStack extends StackedEntity { return; } } + handleSingleStackDeath(killed, drops, droppedExp, event); } - handleSingleStackDeath(killed, drops, droppedExp, event); } public synchronized LivingEntity takeOneAndSpawnEntity(Location location) { diff --git a/src/main/java/com/songoda/ultimatestacker/stackable/entity/EntityStackManager.java b/src/main/java/com/songoda/ultimatestacker/stackable/entity/EntityStackManager.java index eec6b6b..19192bb 100644 --- a/src/main/java/com/songoda/ultimatestacker/stackable/entity/EntityStackManager.java +++ b/src/main/java/com/songoda/ultimatestacker/stackable/entity/EntityStackManager.java @@ -111,10 +111,10 @@ public class EntityStackManager { * @param newEntity The new entity to transfer the stack to. * @return The new stack. */ - public EntityStack transferStack(LivingEntity oldEntity, LivingEntity newEntity) { + public EntityStack transferStack(LivingEntity oldEntity, LivingEntity newEntity, boolean takeOne) { EntityStack stack = getStack(oldEntity); if (stack == null) return null; - EntityStack newStack = new EntityStack(newEntity, stack.getAmount()); + EntityStack newStack = new EntityStack(newEntity, takeOne ? stack.getAmount()-1 : stack.getAmount()); stack.destroy(); return newStack; } diff --git a/src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/CustomEntityManager.java b/src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/CustomEntityManager.java index 07c01f3..73fc0bd 100644 --- a/src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/CustomEntityManager.java +++ b/src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/CustomEntityManager.java @@ -54,4 +54,11 @@ public class CustomEntityManager { public boolean isCustomEntity(Entity entity) { return getCustomEntity(entity) != null && getCustomEntity(entity).isCustomEntity(entity); } + + public boolean isStackable(Entity entity) { + CustomEntity customEntity = getCustomEntity(entity); + if (customEntity == null) return true; + String key = customEntity.getPluginName().toLowerCase() + "_" + customEntity.getNBTIdentifier(entity).toLowerCase(); + return !Settings.BLACKLISTED_CUSTOM_ENTITIES.getStringList().contains(key); + } } diff --git a/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java b/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java index e665ce7..e400d4a 100644 --- a/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java +++ b/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java @@ -355,16 +355,20 @@ public class StackingTask extends TimerTask { */ private List getFriendlyStacksNearby(LivingEntity entity, double radius, boolean singleChunk) { List entities = new ArrayList<>(); - Set chunks = getNearbyChunks(new SWorld(entity.getWorld()), entity.getLocation(), radius, singleChunk); - for (CachedChunk chunk : chunks) { - Entity[] entityList = chunk.getEntities(); - for (Entity e : entityList) { - if (!processed.contains(e.getUniqueId()) && e.getType() == entity.getType() && e instanceof LivingEntity && e.isValid() && e.getLocation().distance(entity.getLocation()) <= radius) { - entities.add((LivingEntity) e); + try { + Set chunks = getNearbyChunks(new SWorld(entity.getWorld()), entity.getLocation(), radius, singleChunk); + for (CachedChunk chunk : chunks) { + Entity[] entityList = getEntitiesInChunkSync(chunk).get(); + for (Entity e : entityList) { + if (!processed.contains(e.getUniqueId()) && e.getType() == entity.getType() && e instanceof LivingEntity && e.isValid() && e.getLocation().distance(entity.getLocation()) <= radius) { + entities.add((LivingEntity) e); + } } } + entities.removeIf(entity1 -> entity1.equals(entity) || !UltimateStacker.getInstance().getCustomEntityManager().isStackable(entity1)); + } catch (Exception ex) { + ex.printStackTrace(); } - entities.removeIf(entity1 -> entity1.equals(entity)); return entities; }