2019-05-23 22:15:04 +02:00
|
|
|
package com.songoda.ultimatestacker.listeners;
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2020-08-25 01:01:11 +02:00
|
|
|
import com.songoda.core.compatibility.CompatibleHand;
|
2019-09-09 18:08:04 +02:00
|
|
|
import com.songoda.core.compatibility.CompatibleMaterial;
|
2023-04-01 15:55:37 +02:00
|
|
|
import com.songoda.core.hooks.ProtectionManager;
|
|
|
|
import com.songoda.core.hooks.protection.BentoBoxProtection;
|
2022-03-18 21:38:26 +01:00
|
|
|
import com.songoda.core.third_party.de.tr7zw.nbtapi.NBTItem;
|
2018-11-06 04:33:10 +01:00
|
|
|
import com.songoda.ultimatestacker.UltimateStacker;
|
2019-06-05 11:40:36 +02:00
|
|
|
import com.songoda.ultimatestacker.events.SpawnerBreakEvent;
|
|
|
|
import com.songoda.ultimatestacker.events.SpawnerPlaceEvent;
|
2019-09-07 23:55:16 +02:00
|
|
|
import com.songoda.ultimatestacker.settings.Settings;
|
2020-08-25 01:01:11 +02:00
|
|
|
import com.songoda.ultimatestacker.stackable.block.BlockStack;
|
|
|
|
import com.songoda.ultimatestacker.stackable.block.BlockStackManager;
|
|
|
|
import com.songoda.ultimatestacker.stackable.spawner.SpawnerStack;
|
2018-11-06 04:33:10 +01:00
|
|
|
import com.songoda.ultimatestacker.utils.Methods;
|
2023-04-07 18:58:21 +02:00
|
|
|
import io.lumine.mythic.bukkit.utils.menu.ClickAction;
|
2018-11-06 04:33:10 +01:00
|
|
|
import org.apache.commons.lang.math.NumberUtils;
|
|
|
|
import org.bukkit.Bukkit;
|
2023-04-07 22:03:04 +02:00
|
|
|
import org.bukkit.Chunk;
|
2020-08-25 01:01:11 +02:00
|
|
|
import org.bukkit.GameMode;
|
2023-04-07 18:58:21 +02:00
|
|
|
import org.bukkit.Material;
|
2018-11-06 04:33:10 +01:00
|
|
|
import org.bukkit.block.Block;
|
|
|
|
import org.bukkit.block.CreatureSpawner;
|
|
|
|
import org.bukkit.enchantments.Enchantment;
|
|
|
|
import org.bukkit.entity.EntityType;
|
|
|
|
import org.bukkit.entity.Player;
|
2023-03-29 21:21:00 +02:00
|
|
|
import org.bukkit.event.Event;
|
2018-11-06 04:33:10 +01:00
|
|
|
import org.bukkit.event.EventHandler;
|
|
|
|
import org.bukkit.event.EventPriority;
|
|
|
|
import org.bukkit.event.Listener;
|
|
|
|
import org.bukkit.event.block.Action;
|
|
|
|
import org.bukkit.event.block.BlockBreakEvent;
|
|
|
|
import org.bukkit.event.block.BlockPlaceEvent;
|
|
|
|
import org.bukkit.event.player.PlayerInteractEvent;
|
2023-04-07 22:03:04 +02:00
|
|
|
import org.bukkit.event.world.ChunkLoadEvent;
|
2018-11-06 04:33:10 +01:00
|
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import org.bukkit.inventory.meta.BlockStateMeta;
|
|
|
|
|
2019-04-11 08:54:59 +02:00
|
|
|
import java.util.List;
|
2020-08-25 01:01:11 +02:00
|
|
|
import java.util.Map;
|
2019-04-11 08:54:59 +02:00
|
|
|
|
2018-11-06 04:33:10 +01:00
|
|
|
public class BlockListeners implements Listener {
|
|
|
|
|
2019-08-02 15:59:10 +02:00
|
|
|
private final UltimateStacker plugin;
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2019-08-02 15:59:10 +02:00
|
|
|
public BlockListeners(UltimateStacker plugin) {
|
|
|
|
this.plugin = plugin;
|
2018-11-06 04:33:10 +01:00
|
|
|
}
|
|
|
|
|
2023-04-07 22:03:04 +02:00
|
|
|
@EventHandler
|
|
|
|
public void onChunkLoad(ChunkLoadEvent event) {
|
|
|
|
if (!Settings.STACK_BLOCKS.getBoolean()) return;
|
|
|
|
Chunk chunk = event.getChunk();
|
|
|
|
BlockStackManager blockStackManager = plugin.getBlockStackManager();
|
|
|
|
blockStackManager.getStacks().stream().filter(stack -> stack.getLocation().getChunk().equals(chunk)).forEach(plugin::updateHologram);
|
|
|
|
}
|
|
|
|
|
2023-03-29 21:21:00 +02:00
|
|
|
@EventHandler(priority = EventPriority.HIGHEST)
|
2020-08-25 01:01:11 +02:00
|
|
|
public void onBlockInteract(PlayerInteractEvent event) {
|
2023-03-29 21:21:00 +02:00
|
|
|
if (event.useInteractedBlock() == Event.Result.DENY) return;
|
2018-11-06 04:33:10 +01:00
|
|
|
Block block = event.getClickedBlock();
|
|
|
|
Player player = event.getPlayer();
|
2023-04-01 15:55:37 +02:00
|
|
|
|
|
|
|
if (block == null) return;
|
|
|
|
|
|
|
|
if (!ProtectionManager.canInteract(player, block.getLocation()) || !ProtectionManager.canBreak(player, block.getLocation())) {
|
|
|
|
if (!player.isOp()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-09 20:35:24 +02:00
|
|
|
CompatibleHand hand = CompatibleHand.getHand(event);
|
|
|
|
ItemStack inHand = hand.getItem(player);
|
2023-04-07 18:58:21 +02:00
|
|
|
boolean isSneaking = player.isSneaking();
|
|
|
|
Action clickAction = event.getAction();
|
|
|
|
int inHandAmount = inHand.getAmount();
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2023-04-07 18:58:21 +02:00
|
|
|
//Stacking blocks
|
|
|
|
if (Settings.STACK_BLOCKS.getBoolean()
|
|
|
|
&& Settings.STACKABLE_BLOCKS.getStringList().contains(block.getType().name()) //Is block stackable
|
|
|
|
&& !block.getType().equals(CompatibleMaterial.SPAWNER.getMaterial()) //Don't stack spawners here
|
|
|
|
) {
|
2020-08-25 01:01:11 +02:00
|
|
|
|
|
|
|
CompatibleMaterial blockType = CompatibleMaterial.getMaterial(block);
|
2020-11-30 21:28:04 +01:00
|
|
|
if (blockType == null) return;
|
2020-08-25 01:01:11 +02:00
|
|
|
|
2023-04-07 18:58:21 +02:00
|
|
|
BlockStackManager blockStackManager = plugin.getBlockStackManager();
|
|
|
|
boolean isStacked = blockStackManager.isBlock(block.getLocation());
|
|
|
|
BlockStack stack = blockStackManager.getBlock(block.getLocation());
|
|
|
|
|
|
|
|
//Modify stack
|
|
|
|
if (isStacked) {
|
|
|
|
event.setCancelled(true);
|
|
|
|
//Add to stack
|
|
|
|
if (clickAction == Action.RIGHT_CLICK_BLOCK) {
|
|
|
|
if (inHand.getType().equals(Material.AIR)) return;
|
|
|
|
if(!blockType.equals(CompatibleMaterial.getMaterial(inHand))) return;
|
|
|
|
//Add all held items to stack
|
|
|
|
if (Settings.ALWAYS_ADD_ALL.getBoolean() || isSneaking) {
|
|
|
|
stack.add(inHandAmount);
|
|
|
|
if (player.getGameMode() != GameMode.CREATIVE) {
|
|
|
|
hand.takeItem(player, inHandAmount);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
//Add one held item to stack
|
|
|
|
stack.add(1);
|
|
|
|
if (player.getGameMode() != GameMode.CREATIVE) {
|
|
|
|
hand.takeItem(player, 1);
|
|
|
|
}
|
2020-08-25 01:01:11 +02:00
|
|
|
}
|
2023-04-07 18:58:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//Remove from stack
|
|
|
|
if (clickAction == Action.LEFT_CLICK_BLOCK) {
|
|
|
|
if (isSneaking) {
|
|
|
|
//Remove all items from stack
|
|
|
|
int amountToRemove = Math.min(Settings.MAX_REMOVEABLE.getInt(), stack.getAmount());
|
|
|
|
ItemStack removed = stack.getMaterial().getItem();
|
|
|
|
removed.setAmount(amountToRemove);
|
|
|
|
stack.take(amountToRemove);
|
2020-08-25 01:01:11 +02:00
|
|
|
if (Settings.ADD_TO_INVENTORY.getBoolean()) {
|
2023-04-07 18:58:21 +02:00
|
|
|
player.getInventory().addItem(removed);
|
2020-08-25 01:01:11 +02:00
|
|
|
} else {
|
2023-04-07 18:58:21 +02:00
|
|
|
player.getWorld().dropItemNaturally(block.getLocation(), removed);
|
2020-08-25 01:01:11 +02:00
|
|
|
}
|
2023-04-07 18:58:21 +02:00
|
|
|
} else {
|
|
|
|
//Remove one item from stack
|
|
|
|
stack.take(1);
|
2023-04-05 11:57:17 +02:00
|
|
|
if (Settings.ADD_TO_INVENTORY.getBoolean()) {
|
2023-04-07 18:58:21 +02:00
|
|
|
player.getInventory().addItem(stack.getMaterial().getItem());
|
2023-04-05 11:57:17 +02:00
|
|
|
} else {
|
2023-04-07 18:58:21 +02:00
|
|
|
player.getWorld().dropItemNaturally(block.getLocation(), stack.getMaterial().getItem());
|
2023-04-05 11:57:17 +02:00
|
|
|
}
|
2023-04-07 18:58:21 +02:00
|
|
|
}
|
|
|
|
if (stack.getAmount() == 0) {
|
|
|
|
//Remove stack
|
|
|
|
stack.destroy();
|
|
|
|
return;
|
2020-08-25 01:01:11 +02:00
|
|
|
}
|
|
|
|
}
|
2023-04-07 18:58:21 +02:00
|
|
|
//update hologram
|
|
|
|
plugin.updateHologram(stack);
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
if (isSneaking) return;
|
|
|
|
//Check if player clicked the same type as the clicked block
|
|
|
|
if (inHand.getType().equals(Material.AIR)) return;
|
|
|
|
if(!blockType.equals(CompatibleMaterial.getMaterial(inHand))) return;
|
|
|
|
if (clickAction != Action.RIGHT_CLICK_BLOCK) return;
|
|
|
|
//Create new stack
|
|
|
|
event.setCancelled(true);
|
|
|
|
hand.takeItem(player, 1);
|
|
|
|
BlockStack newStack = blockStackManager.createBlock(block);
|
|
|
|
plugin.getDataManager().createBlock(newStack);
|
|
|
|
plugin.updateHologram(newStack);
|
2020-08-25 01:01:11 +02:00
|
|
|
}
|
2023-04-07 18:58:21 +02:00
|
|
|
return;
|
2020-08-25 01:01:11 +02:00
|
|
|
}
|
|
|
|
|
2023-04-07 18:58:21 +02:00
|
|
|
//Stacking spawners
|
2020-08-25 01:01:11 +02:00
|
|
|
if (block.getType() != CompatibleMaterial.SPAWNER.getMaterial()
|
2020-09-09 20:35:24 +02:00
|
|
|
|| inHand.getType() != CompatibleMaterial.SPAWNER.getMaterial()
|
2019-05-24 01:21:59 +02:00
|
|
|
|| event.getAction() == Action.LEFT_CLICK_BLOCK) return;
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2019-09-07 23:55:16 +02:00
|
|
|
List<String> disabledWorlds = Settings.DISABLED_WORLDS.getStringList();
|
2020-08-25 01:01:11 +02:00
|
|
|
if (disabledWorlds.stream().anyMatch(worldStr -> event.getPlayer().getWorld().getName().equalsIgnoreCase(worldStr)))
|
|
|
|
return;
|
2019-04-11 08:54:59 +02:00
|
|
|
|
2019-08-02 15:59:10 +02:00
|
|
|
if (!plugin.spawnersEnabled()) return;
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2020-09-09 20:35:24 +02:00
|
|
|
BlockStateMeta bsm = (BlockStateMeta) inHand.getItemMeta();
|
2018-11-06 04:33:10 +01:00
|
|
|
CreatureSpawner cs = (CreatureSpawner) bsm.getBlockState();
|
|
|
|
|
|
|
|
EntityType itemType = cs.getSpawnedType();
|
|
|
|
|
2020-09-09 20:35:24 +02:00
|
|
|
int itemAmount = getSpawnerAmount(inHand);
|
2019-09-03 22:38:00 +02:00
|
|
|
int specific = plugin.getSpawnerFile().getInt("Spawners." + cs.getSpawnedType().name() + ".Max Stack Size");
|
2019-09-07 23:55:16 +02:00
|
|
|
int maxStackSize = specific == -1 ? Settings.MAX_STACK_SPAWNERS.getInt() : specific;
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2018-11-06 06:09:40 +01:00
|
|
|
cs = (CreatureSpawner) block.getState();
|
2018-11-06 04:33:10 +01:00
|
|
|
|
|
|
|
EntityType blockType = cs.getSpawnedType();
|
|
|
|
|
|
|
|
event.setCancelled(true);
|
|
|
|
|
|
|
|
if (itemType == blockType) {
|
2019-08-02 15:59:10 +02:00
|
|
|
SpawnerStack stack = plugin.getSpawnerStackManager().getSpawner(block);
|
2018-11-06 04:33:10 +01:00
|
|
|
if (player.isSneaking()) return;
|
|
|
|
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
|
|
|
if (stack.getAmount() == maxStackSize) return;
|
|
|
|
|
2019-06-05 11:40:36 +02:00
|
|
|
ItemStack overflowItem = null;
|
2018-11-06 04:33:10 +01:00
|
|
|
if ((stack.getAmount() + itemAmount) > maxStackSize) {
|
2019-06-05 11:40:36 +02:00
|
|
|
overflowItem = Methods.getSpawnerItem(blockType, (stack.getAmount() + itemAmount) - maxStackSize);
|
|
|
|
itemAmount = maxStackSize - stack.getAmount();
|
|
|
|
}
|
|
|
|
|
|
|
|
SpawnerPlaceEvent placeEvent = new SpawnerPlaceEvent(player, block, blockType, itemAmount);
|
|
|
|
Bukkit.getPluginManager().callEvent(placeEvent);
|
|
|
|
if (placeEvent.isCancelled()) {
|
|
|
|
event.setCancelled(true);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (overflowItem != null) {
|
2018-11-06 04:33:10 +01:00
|
|
|
if (player.getInventory().firstEmpty() == -1)
|
2019-10-05 17:56:30 +02:00
|
|
|
block.getWorld().dropItemNaturally(block.getLocation().add(.5, 0, .5), overflowItem);
|
2018-11-06 04:33:10 +01:00
|
|
|
else
|
2019-06-05 11:40:36 +02:00
|
|
|
player.getInventory().addItem(overflowItem);
|
2018-11-06 04:33:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
stack.setAmount(stack.getAmount() + itemAmount);
|
2019-09-03 22:38:00 +02:00
|
|
|
plugin.updateHologram(stack);
|
2021-05-21 22:52:33 +02:00
|
|
|
if (player.getGameMode() != GameMode.CREATIVE)
|
|
|
|
hand.takeItem(player);
|
2018-11-06 04:33:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-29 21:21:00 +02:00
|
|
|
@EventHandler(priority = EventPriority.HIGHEST)
|
2020-08-25 01:01:11 +02:00
|
|
|
public void onBlockPlace(BlockPlaceEvent event) {
|
2023-03-29 21:21:00 +02:00
|
|
|
if (event.isCancelled()) return;
|
2018-11-06 04:33:10 +01:00
|
|
|
Block block = event.getBlock();
|
2019-06-05 11:40:36 +02:00
|
|
|
Player player = event.getPlayer();
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2020-08-25 01:01:11 +02:00
|
|
|
if (block.getType() != CompatibleMaterial.SPAWNER.getMaterial()
|
|
|
|
|| !(block.getState() instanceof CreatureSpawner) // Needed for a DataPack
|
|
|
|
|| !plugin.spawnersEnabled())
|
|
|
|
return;
|
2019-06-05 11:40:36 +02:00
|
|
|
|
2020-08-25 01:01:11 +02:00
|
|
|
CreatureSpawner cs = (CreatureSpawner) block.getState();
|
|
|
|
CreatureSpawner cs2 = (CreatureSpawner) ((BlockStateMeta) event.getItemInHand().getItemMeta()).getBlockState();
|
|
|
|
int amount = getSpawnerAmount(event.getItemInHand());
|
2019-01-15 07:53:01 +01:00
|
|
|
|
2020-08-25 01:01:11 +02:00
|
|
|
SpawnerPlaceEvent placeEvent = new SpawnerPlaceEvent(player, block, cs2.getSpawnedType(), amount);
|
|
|
|
Bukkit.getPluginManager().callEvent(placeEvent);
|
|
|
|
if (placeEvent.isCancelled()) {
|
|
|
|
event.setCancelled(true);
|
|
|
|
return;
|
2019-01-01 00:41:02 +01:00
|
|
|
}
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2020-08-25 01:01:11 +02:00
|
|
|
SpawnerStack stack = plugin.getSpawnerStackManager().addSpawner(new SpawnerStack(block.getLocation(), amount));
|
|
|
|
plugin.getDataManager().createSpawner(stack);
|
|
|
|
|
|
|
|
cs.setSpawnedType(cs2.getSpawnedType());
|
|
|
|
cs.update();
|
|
|
|
|
|
|
|
plugin.updateHologram(stack);
|
2018-11-06 04:33:10 +01:00
|
|
|
}
|
|
|
|
|
2023-03-29 21:21:00 +02:00
|
|
|
@EventHandler(priority = EventPriority.HIGHEST)
|
2018-11-06 04:33:10 +01:00
|
|
|
public void onBlockBreak(BlockBreakEvent event) {
|
2023-03-29 21:21:00 +02:00
|
|
|
if (event.isCancelled()) return;
|
2018-11-06 04:33:10 +01:00
|
|
|
Block block = event.getBlock();
|
2019-09-09 18:08:04 +02:00
|
|
|
if (block.getType() != CompatibleMaterial.SPAWNER.getMaterial()) return;
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2019-08-02 15:59:10 +02:00
|
|
|
if (!plugin.spawnersEnabled()) return;
|
2019-02-17 22:55:42 +01:00
|
|
|
event.setExpToDrop(0);
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2018-11-06 06:09:40 +01:00
|
|
|
CreatureSpawner cs = (CreatureSpawner) block.getState();
|
2018-11-06 04:33:10 +01:00
|
|
|
|
|
|
|
EntityType blockType = cs.getSpawnedType();
|
|
|
|
|
|
|
|
Player player = event.getPlayer();
|
2018-11-06 05:41:58 +01:00
|
|
|
ItemStack item = player.getInventory().getItemInHand();
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2019-08-02 15:59:10 +02:00
|
|
|
SpawnerStack stack = plugin.getSpawnerStackManager().getSpawner(block);
|
2018-11-06 04:33:10 +01:00
|
|
|
|
|
|
|
event.setCancelled(true);
|
|
|
|
|
|
|
|
int amt = 1;
|
2019-06-05 11:40:36 +02:00
|
|
|
boolean remove = false;
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2019-09-07 23:55:16 +02:00
|
|
|
if (player.isSneaking() && Settings.SNEAK_FOR_STACK.getBoolean()) {
|
2018-11-06 04:33:10 +01:00
|
|
|
amt = stack.getAmount();
|
2019-06-05 11:40:36 +02:00
|
|
|
remove = true;
|
|
|
|
} else if (stack.getAmount() <= 1) {
|
|
|
|
remove = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
SpawnerBreakEvent breakEvent = new SpawnerBreakEvent(player, block, blockType, amt);
|
|
|
|
Bukkit.getPluginManager().callEvent(breakEvent);
|
|
|
|
if (breakEvent.isCancelled())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (remove) {
|
|
|
|
event.setCancelled(false);
|
2020-08-25 01:01:11 +02:00
|
|
|
plugin.removeHologram(stack);
|
2019-08-02 15:59:10 +02:00
|
|
|
SpawnerStack spawnerStack = plugin.getSpawnerStackManager().removeSpawner(block.getLocation());
|
|
|
|
plugin.getDataManager().deleteSpawner(spawnerStack);
|
2018-11-06 04:33:10 +01:00
|
|
|
} else {
|
2019-06-05 11:40:36 +02:00
|
|
|
stack.setAmount(stack.getAmount() - 1);
|
2019-09-03 22:38:00 +02:00
|
|
|
plugin.updateHologram(stack);
|
2018-11-06 04:33:10 +01:00
|
|
|
}
|
2019-06-05 11:40:36 +02:00
|
|
|
|
2019-10-05 17:56:30 +02:00
|
|
|
if (player.hasPermission("ultimatestacker.spawner.nosilkdrop") || item.getEnchantments().containsKey(Enchantment.SILK_TOUCH) && player.hasPermission("ultimatestacker.spawner.silktouch")) {
|
|
|
|
ItemStack spawner = Methods.getSpawnerItem(blockType, amt);
|
|
|
|
if (player.getInventory().firstEmpty() == -1 || !Settings.SPAWNERS_TO_INVENTORY.getBoolean())
|
|
|
|
block.getWorld().dropItemNaturally(block.getLocation().add(.5, 0, .5), spawner);
|
|
|
|
else
|
|
|
|
player.getInventory().addItem(spawner);
|
|
|
|
}
|
|
|
|
|
2018-11-06 04:33:10 +01:00
|
|
|
}
|
|
|
|
|
2018-11-06 05:53:27 +01:00
|
|
|
private int getSpawnerAmount(ItemStack item) {
|
2022-03-18 21:38:26 +01:00
|
|
|
NBTItem nbtItem = new NBTItem(item);
|
|
|
|
if (nbtItem.hasKey("spawner_stack_size"))
|
|
|
|
return nbtItem.getInteger("spawner_stack_size");
|
|
|
|
|
2018-11-06 04:33:10 +01:00
|
|
|
if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName()) return 1;
|
|
|
|
if (item.getItemMeta().getDisplayName().contains(":")) {
|
2019-06-27 20:34:33 +02:00
|
|
|
int amt = NumberUtils.toInt(item.getItemMeta().getDisplayName().replace("\u00A7", "").replace(";", "").split(":")[0], 1);
|
2018-11-06 05:53:27 +01:00
|
|
|
return amt == 0 ? 1 : amt;
|
2018-11-06 04:33:10 +01:00
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|