UltimateStacker/UltimateStacker-Plugin/src/main/java/com.craftaro.ultimatestacker/listeners/BlockListeners.java

360 lines
16 KiB
Java
Raw Normal View History

2023-05-25 19:20:03 +02:00
package com.craftaro.ultimatestacker.listeners;
import com.craftaro.core.compatibility.CompatibleHand;
import com.craftaro.core.hooks.ProtectionManager;
2024-01-07 12:16:27 +01:00
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.core.third_party.de.tr7zw.nbtapi.NBTItem;
2023-05-25 19:20:03 +02:00
import com.craftaro.ultimatestacker.UltimateStacker;
import com.craftaro.ultimatestacker.api.UltimateStackerApi;
2023-05-30 11:21:46 +02:00
import com.craftaro.ultimatestacker.api.events.spawner.SpawnerBreakEvent;
import com.craftaro.ultimatestacker.api.events.spawner.SpawnerPlaceEvent;
2023-05-25 19:20:03 +02:00
import com.craftaro.ultimatestacker.api.stack.block.BlockStack;
import com.craftaro.ultimatestacker.api.stack.block.BlockStackManager;
import com.craftaro.ultimatestacker.api.stack.spawner.SpawnerStack;
import com.craftaro.ultimatestacker.settings.Settings;
import com.craftaro.ultimatestacker.stackable.spawner.SpawnerStackImpl;
import com.craftaro.ultimatestacker.utils.Methods;
2018-11-06 04:33:10 +01:00
import org.apache.commons.lang.math.NumberUtils;
import org.bukkit.Bukkit;
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;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
2019-04-11 08:54:59 +02:00
import java.util.List;
2023-06-29 11:18:18 +02:00
import java.util.Optional;
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-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
2023-06-29 11:18:18 +02:00
&& !block.getType().equals(XMaterial.SPAWNER.parseMaterial()) //Don't stack spawners here
) {
2020-08-25 01:01:11 +02:00
2023-06-29 11:18:18 +02:00
Optional<XMaterial> xBlockType = XMaterial.matchXMaterial(block.getType().name());
if (!xBlockType.isPresent()) return;
XMaterial blockType = xBlockType.get();
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
2024-01-07 14:52:51 +01:00
if (clickAction == Action.RIGHT_CLICK_BLOCK && !player.hasPermission("ultimatestacker.block.nostack")) {
2023-04-07 18:58:21 +02:00
if (inHand.getType().equals(Material.AIR)) return;
2023-06-29 11:18:18 +02:00
if(!blockType.equals(XMaterial.matchXMaterial(inHand))) return;
2023-04-07 18:58:21 +02:00
//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());
2023-06-29 11:18:18 +02:00
ItemStack removed = stack.getMaterial().parseItem();
2023-04-07 18:58:21 +02:00
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);
if (Settings.ADD_TO_INVENTORY.getBoolean()) {
2023-06-29 11:18:18 +02:00
player.getInventory().addItem(stack.getMaterial().parseItem());
} else {
2023-06-29 11:18:18 +02:00
player.getWorld().dropItemNaturally(block.getLocation(), stack.getMaterial().parseItem());
}
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);
plugin.getPluginDataManager().save(stack);
2023-04-07 18:58:21 +02:00
return;
} else {
2024-01-07 14:52:51 +01:00
if (isSneaking || player.hasPermission("ultimatestacker.block.nostack")) return;
2023-04-07 18:58:21 +02:00
//Check if player clicked the same type as the clicked block
if (inHand.getType().equals(Material.AIR)) return;
2023-06-29 11:18:18 +02:00
if(!blockType.equals(XMaterial.matchXMaterial(inHand))) return;
2023-04-07 18:58:21 +02:00
if (clickAction != Action.RIGHT_CLICK_BLOCK) return;
//Create new stack
event.setCancelled(true);
if (player.getGameMode() != GameMode.CREATIVE) {
hand.takeItem(player, 1);
}
2023-04-07 18:58:21 +02:00
BlockStack newStack = blockStackManager.createBlock(block);
plugin.getPluginDataManager().save(newStack);
2023-04-07 18:58:21 +02:00
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
2023-06-29 11:18:18 +02:00
if (block.getType() != XMaterial.SPAWNER.parseMaterial()
|| inHand.getType() != XMaterial.SPAWNER.parseMaterial()
2024-01-07 14:52:51 +01: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) {
SpawnerStack stack = UltimateStackerApi.getSpawnerStackManager().getSpawner(block);
2023-09-18 15:34:19 +02:00
if (stack == null) return;
2024-03-23 19:17:44 +01:00
if (player.isSneaking()) {
//Add all to stack from hand
if (Settings.SNEAK_TO_ADD_ALL.getBoolean()) {
//Redo this logic, if we have 10 items in hand and each item is 5 stack size, we need to take into consideration that what happens if we can only add 2 stack total in a stack? We have to remove one extra item and add one spawner with 3 stack back
int amountToAdd = Math.min(maxStackSize - stack.getAmount(), itemAmount * inHand.getAmount()); //Multiply by inHand.getAmount() to get the total amount of items in hand
int remaining = itemAmount * inHand.getAmount() - amountToAdd; //Calculate the remaining amount of items in hand
stack.setAmount(stack.getAmount() + amountToAdd);
plugin.updateHologram(stack);
plugin.getDataManager().save(stack);
if (remaining % itemAmount == 0) { //We don't have to worry about leftovers
if (player.getGameMode() != GameMode.CREATIVE) {
hand.takeItem(player, amountToAdd / itemAmount);
}
} else {
int fullStacks = amountToAdd / itemAmount;
int overflow = remaining % itemAmount;
//remove fullstacks-1 and add back overflow as a new item stack
if (player.getGameMode() != GameMode.CREATIVE) {
if (overflow > 0) {
hand.takeItem(player, fullStacks+1);
ItemStack overflowItem = Methods.getSpawnerItem(blockType, overflow);
if (player.getInventory().firstEmpty() == -1) {
block.getWorld().dropItemNaturally(block.getLocation().add(.5, 0, .5), overflowItem);
} else {
player.getInventory().addItem(overflowItem);
}
} else {
hand.takeItem(player, fullStacks);
}
}
}
}
return;
}
if (player.hasPermission("ultimatestacker.spawner.nostack") && !player.isOp()) {
2024-01-07 14:52:51 +01:00
event.setCancelled(false);
return;
}
2018-11-06 04:33:10 +01:00
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)
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);
2023-09-18 15:34:19 +02:00
plugin.getDataManager().save(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
2023-06-29 11:18:18 +02:00
if (block.getType() != XMaterial.SPAWNER.parseMaterial()
2020-08-25 01:01:11 +02:00
|| !(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());
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
SpawnerStack stack = UltimateStackerApi.getSpawnerStackManager().addSpawner(new SpawnerStackImpl(block.getLocation(), amount));
2023-09-18 15:34:19 +02:00
plugin.getSpawnerStackManager().addSpawner(stack);
plugin.getPluginDataManager().save(stack);
2020-08-25 01:01:11 +02:00
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();
2023-06-29 11:18:18 +02:00
if (block.getType() != XMaterial.SPAWNER.parseMaterial()) return;
2018-11-06 04:33:10 +01:00
2019-08-02 15:59:10 +02:00
if (!plugin.spawnersEnabled()) return;
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
2024-03-20 12:36:33 +01:00
EntityType spawnedEntityType = cs.getSpawnedType();
//Empty spawners return null?? It is annotated as @NotNull
if (spawnedEntityType == null) return;
2018-11-06 04:33:10 +01:00
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
SpawnerStack stack = UltimateStackerApi.getSpawnerStackManager().getSpawner(block);
2024-03-23 19:17:44 +01:00
if (stack == null) return;
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;
}
2024-03-20 12:36:33 +01:00
SpawnerBreakEvent breakEvent = new SpawnerBreakEvent(player, block, spawnedEntityType, amt);
2019-06-05 11:40:36 +02:00
Bukkit.getPluginManager().callEvent(breakEvent);
if (breakEvent.isCancelled())
return;
if (remove) {
event.setCancelled(false);
2020-08-25 01:01:11 +02:00
plugin.removeHologram(stack);
SpawnerStack spawnerStack = UltimateStackerApi.getSpawnerStackManager().removeSpawner(block.getLocation());
plugin.getPluginDataManager().delete(spawnerStack);
2018-11-06 04:33:10 +01:00
} else {
2019-06-05 11:40:36 +02:00
stack.setAmount(stack.getAmount() - 1);
2023-09-18 15:34:19 +02:00
plugin.getDataManager().save(stack);
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
if (player.hasPermission("ultimatestacker.spawner.nosilkdrop") || item.getEnchantments().containsKey(Enchantment.SILK_TOUCH) && player.hasPermission("ultimatestacker.spawner.silktouch")) {
2024-03-20 12:36:33 +01:00
ItemStack spawner = Methods.getSpawnerItem(spawnedEntityType, 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(":")) {
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;
}
}