From 42451e708b495f264e51d8e75748181713bc8f6f Mon Sep 17 00:00:00 2001 From: ceze88 Date: Fri, 7 Apr 2023 18:58:21 +0200 Subject: [PATCH] Rewrite block stacking --- .../ultimatestacker/UltimateStacker.java | 1 + .../ultimatestacker/database/DataManager.java | 20 +++ .../listeners/BlockListeners.java | 129 +++++++++++------- .../stackable/block/BlockStack.java | 2 +- .../stackable/block/BlockStackManager.java | 10 +- 5 files changed, 105 insertions(+), 57 deletions(-) diff --git a/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java b/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java index c5e5bf3..a92b12e 100644 --- a/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java +++ b/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java @@ -111,6 +111,7 @@ public class UltimateStacker extends SongodaPlugin { this.stackingTask.stop(); this.stackingTask = null; this.dataManager.bulkUpdateSpawners(this.spawnerStackManager.getStacks()); + this.dataManager.bulkUpdateBlocks(this.blockStackManager.getStacks()); HologramManager.removeAllHolograms(); Async.shutdown(); } diff --git a/src/main/java/com/songoda/ultimatestacker/database/DataManager.java b/src/main/java/com/songoda/ultimatestacker/database/DataManager.java index 10f2a7f..c258595 100644 --- a/src/main/java/com/songoda/ultimatestacker/database/DataManager.java +++ b/src/main/java/com/songoda/ultimatestacker/database/DataManager.java @@ -216,6 +216,11 @@ public class DataManager extends DataManagerAbstract { BlockStack blockStack = new BlockStack(material, location, amount); blockStack.setId(blockId); + if (amount == 0) { + //remove from database + this.deleteBlock(blockStack); + continue; + } blocks.put(location, blockStack); this.sync(() -> callback.accept(blocks)); @@ -225,4 +230,19 @@ public class DataManager extends DataManagerAbstract { } }); } + + public void bulkUpdateBlocks(Collection stacks) { + try (Connection connection = this.databaseConnector.getConnection()) { + String updateSpawner = "UPDATE " + this.getTablePrefix() + "blocks SET amount = ? WHERE id = ?"; + PreparedStatement statement = connection.prepareStatement(updateSpawner); + for (BlockStack spawnerStack : stacks) { + statement.setInt(1, spawnerStack.getAmount()); + statement.setInt(2, spawnerStack.getId()); + statement.addBatch(); + } + statement.executeBatch(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } } diff --git a/src/main/java/com/songoda/ultimatestacker/listeners/BlockListeners.java b/src/main/java/com/songoda/ultimatestacker/listeners/BlockListeners.java index b23a18b..5489978 100644 --- a/src/main/java/com/songoda/ultimatestacker/listeners/BlockListeners.java +++ b/src/main/java/com/songoda/ultimatestacker/listeners/BlockListeners.java @@ -13,9 +13,11 @@ import com.songoda.ultimatestacker.stackable.block.BlockStack; import com.songoda.ultimatestacker.stackable.block.BlockStackManager; import com.songoda.ultimatestacker.stackable.spawner.SpawnerStack; import com.songoda.ultimatestacker.utils.Methods; +import io.lumine.mythic.bukkit.utils.menu.ClickAction; import org.apache.commons.lang.math.NumberUtils; import org.bukkit.Bukkit; import org.bukkit.GameMode; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.CreatureSpawner; import org.bukkit.enchantments.Enchantment; @@ -59,72 +61,93 @@ public class BlockListeners implements Listener { CompatibleHand hand = CompatibleHand.getHand(event); ItemStack inHand = hand.getItem(player); + boolean isSneaking = player.isSneaking(); + Action clickAction = event.getAction(); + int inHandAmount = inHand.getAmount(); - - if (Settings.STACK_BLOCKS.getBoolean()) { - BlockStackManager blockStackManager = plugin.getBlockStackManager(); - - boolean isStacked = blockStackManager.isBlock(block.getLocation()); + //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 + ) { CompatibleMaterial blockType = CompatibleMaterial.getMaterial(block); if (blockType == null) return; - if (isStacked || Settings.STACKABLE_BLOCKS.getStringList().contains(blockType.name())) { - BlockStack stack = blockStackManager.getBlock(block, blockType); - if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { - if (!isStacked) plugin.getDataManager().createBlock(stack); - if (stack.getMaterial() == CompatibleMaterial.getMaterial(inHand)) { - int amountToAdd = player.isSneaking() || Settings.ALWAYS_ADD_ALL.getBoolean() ? inHand.getAmount()-1 : 1; - if (!isStacked) amountToAdd++; - stack.add(amountToAdd); - event.setCancelled(true); - if (player.getGameMode() != GameMode.CREATIVE) - hand.takeItem(player, amountToAdd); - plugin.updateHologram(stack); - } - plugin.getDataManager().updateBlock(stack); - } else if (event.getAction() == Action.LEFT_CLICK_BLOCK && stack.getAmount() != 0) { - event.setCancelled(true); - int amountToRemove = player.isSneaking() - ? Math.min(Settings.MAX_REMOVEABLE.getInt(), stack.getAmount()) - 1 : 1; + BlockStackManager blockStackManager = plugin.getBlockStackManager(); + boolean isStacked = blockStackManager.isBlock(block.getLocation()); + BlockStack stack = blockStackManager.getBlock(block.getLocation()); - ItemStack removed = stack.getMaterial().getItem(); - removed.setAmount(amountToRemove); - stack.take(amountToRemove); - int maxStack = removed.getMaxStackSize(); - - while (amountToRemove > 0) { - int subtract = Math.min(amountToRemove, maxStack); - amountToRemove -= subtract; - ItemStack newItem = removed.clone(); - newItem.setAmount(subtract); - if (Settings.ADD_TO_INVENTORY.getBoolean()) { - Map result = player.getInventory().addItem(newItem); - if (result.get(0) != null) { - amountToRemove += result.get(0).getAmount(); - break; - } - } else { - block.getWorld().dropItemNaturally(block.getLocation().clone().add(.5, 1, .5), newItem); - } - } - stack.add(amountToRemove); - if (stack.getAmount() < 2) { - stack.destroy(); - ItemStack item = stack.getMaterial().getItem(); - if (Settings.ADD_TO_INVENTORY.getBoolean()) { - player.getInventory().addItem(item); - } else { - block.getWorld().dropItemNaturally(block.getLocation().clone().add(.5, 1, .5), item); + //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 { - plugin.updateHologram(stack); - plugin.getDataManager().updateBlock(stack); + //Add one held item to stack + stack.add(1); + if (player.getGameMode() != GameMode.CREATIVE) { + hand.takeItem(player, 1); + } } } + + //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); + if (Settings.ADD_TO_INVENTORY.getBoolean()) { + player.getInventory().addItem(removed); + } else { + player.getWorld().dropItemNaturally(block.getLocation(), removed); + } + } else { + //Remove one item from stack + stack.take(1); + if (Settings.ADD_TO_INVENTORY.getBoolean()) { + player.getInventory().addItem(stack.getMaterial().getItem()); + } else { + player.getWorld().dropItemNaturally(block.getLocation(), stack.getMaterial().getItem()); + } + } + if (stack.getAmount() == 0) { + //Remove stack + stack.destroy(); + return; + } + } + //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); } + return; } + //Stacking spawners if (block.getType() != CompatibleMaterial.SPAWNER.getMaterial() || inHand.getType() != CompatibleMaterial.SPAWNER.getMaterial() || event.getAction() == Action.LEFT_CLICK_BLOCK) return; diff --git a/src/main/java/com/songoda/ultimatestacker/stackable/block/BlockStack.java b/src/main/java/com/songoda/ultimatestacker/stackable/block/BlockStack.java index 94b4d44..cc59b69 100644 --- a/src/main/java/com/songoda/ultimatestacker/stackable/block/BlockStack.java +++ b/src/main/java/com/songoda/ultimatestacker/stackable/block/BlockStack.java @@ -22,7 +22,7 @@ public class BlockStack implements Stackable, Hologramable { // The id that identifies this stack in the database. private int id; - private int amount = 0; + private int amount = 1; private final CompatibleMaterial material; private final Location location; diff --git a/src/main/java/com/songoda/ultimatestacker/stackable/block/BlockStackManager.java b/src/main/java/com/songoda/ultimatestacker/stackable/block/BlockStackManager.java index b53dfe7..136bb63 100644 --- a/src/main/java/com/songoda/ultimatestacker/stackable/block/BlockStackManager.java +++ b/src/main/java/com/songoda/ultimatestacker/stackable/block/BlockStackManager.java @@ -26,12 +26,16 @@ public class BlockStackManager { return registeredBlocks.remove(roundLocation(location)); } - public BlockStack getBlock(Location location, CompatibleMaterial material) { + public BlockStack getBlock(Location location) { + return this.registeredBlocks.get(location); + } + + public BlockStack createBlock(Location location, CompatibleMaterial material) { return this.registeredBlocks.computeIfAbsent(location, b -> new BlockStack(material, location)); } - public BlockStack getBlock(Block block, CompatibleMaterial material) { - return this.getBlock(block.getLocation(), material); + public BlockStack createBlock(Block block) { + return this.createBlock(block.getLocation(), CompatibleMaterial.getMaterial(block)); } public boolean isBlock(Location location) {