Rewrite block stacking

This commit is contained in:
ceze88 2023-04-07 18:58:21 +02:00
parent f51cc19c44
commit 42451e708b
5 changed files with 105 additions and 57 deletions

View File

@ -111,6 +111,7 @@ public class UltimateStacker extends SongodaPlugin {
this.stackingTask.stop(); this.stackingTask.stop();
this.stackingTask = null; this.stackingTask = null;
this.dataManager.bulkUpdateSpawners(this.spawnerStackManager.getStacks()); this.dataManager.bulkUpdateSpawners(this.spawnerStackManager.getStacks());
this.dataManager.bulkUpdateBlocks(this.blockStackManager.getStacks());
HologramManager.removeAllHolograms(); HologramManager.removeAllHolograms();
Async.shutdown(); Async.shutdown();
} }

View File

@ -216,6 +216,11 @@ public class DataManager extends DataManagerAbstract {
BlockStack blockStack = new BlockStack(material, location, amount); BlockStack blockStack = new BlockStack(material, location, amount);
blockStack.setId(blockId); blockStack.setId(blockId);
if (amount == 0) {
//remove from database
this.deleteBlock(blockStack);
continue;
}
blocks.put(location, blockStack); blocks.put(location, blockStack);
this.sync(() -> callback.accept(blocks)); this.sync(() -> callback.accept(blocks));
@ -225,4 +230,19 @@ public class DataManager extends DataManagerAbstract {
} }
}); });
} }
public void bulkUpdateBlocks(Collection<BlockStack> 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();
}
}
} }

View File

@ -13,9 +13,11 @@ import com.songoda.ultimatestacker.stackable.block.BlockStack;
import com.songoda.ultimatestacker.stackable.block.BlockStackManager; import com.songoda.ultimatestacker.stackable.block.BlockStackManager;
import com.songoda.ultimatestacker.stackable.spawner.SpawnerStack; import com.songoda.ultimatestacker.stackable.spawner.SpawnerStack;
import com.songoda.ultimatestacker.utils.Methods; import com.songoda.ultimatestacker.utils.Methods;
import io.lumine.mythic.bukkit.utils.menu.ClickAction;
import org.apache.commons.lang.math.NumberUtils; import org.apache.commons.lang.math.NumberUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.CreatureSpawner; import org.bukkit.block.CreatureSpawner;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
@ -59,72 +61,93 @@ public class BlockListeners implements Listener {
CompatibleHand hand = CompatibleHand.getHand(event); CompatibleHand hand = CompatibleHand.getHand(event);
ItemStack inHand = hand.getItem(player); ItemStack inHand = hand.getItem(player);
boolean isSneaking = player.isSneaking();
Action clickAction = event.getAction();
int inHandAmount = inHand.getAmount();
//Stacking blocks
if (Settings.STACK_BLOCKS.getBoolean()) { if (Settings.STACK_BLOCKS.getBoolean()
BlockStackManager blockStackManager = plugin.getBlockStackManager(); && Settings.STACKABLE_BLOCKS.getStringList().contains(block.getType().name()) //Is block stackable
&& !block.getType().equals(CompatibleMaterial.SPAWNER.getMaterial()) //Don't stack spawners here
boolean isStacked = blockStackManager.isBlock(block.getLocation()); ) {
CompatibleMaterial blockType = CompatibleMaterial.getMaterial(block); CompatibleMaterial blockType = CompatibleMaterial.getMaterial(block);
if (blockType == null) return; if (blockType == null) return;
if (isStacked || Settings.STACKABLE_BLOCKS.getStringList().contains(blockType.name())) { BlockStackManager blockStackManager = plugin.getBlockStackManager();
BlockStack stack = blockStackManager.getBlock(block, blockType); boolean isStacked = blockStackManager.isBlock(block.getLocation());
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { BlockStack stack = blockStackManager.getBlock(block.getLocation());
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;
ItemStack removed = stack.getMaterial().getItem(); //Modify stack
removed.setAmount(amountToRemove); if (isStacked) {
stack.take(amountToRemove); event.setCancelled(true);
int maxStack = removed.getMaxStackSize(); //Add to stack
if (clickAction == Action.RIGHT_CLICK_BLOCK) {
while (amountToRemove > 0) { if (inHand.getType().equals(Material.AIR)) return;
int subtract = Math.min(amountToRemove, maxStack); if(!blockType.equals(CompatibleMaterial.getMaterial(inHand))) return;
amountToRemove -= subtract; //Add all held items to stack
ItemStack newItem = removed.clone(); if (Settings.ALWAYS_ADD_ALL.getBoolean() || isSneaking) {
newItem.setAmount(subtract); stack.add(inHandAmount);
if (Settings.ADD_TO_INVENTORY.getBoolean()) { if (player.getGameMode() != GameMode.CREATIVE) {
Map<Integer, ItemStack> result = player.getInventory().addItem(newItem); hand.takeItem(player, inHandAmount);
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);
} }
} else { } else {
plugin.updateHologram(stack); //Add one held item to stack
plugin.getDataManager().updateBlock(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() if (block.getType() != CompatibleMaterial.SPAWNER.getMaterial()
|| inHand.getType() != CompatibleMaterial.SPAWNER.getMaterial() || inHand.getType() != CompatibleMaterial.SPAWNER.getMaterial()
|| event.getAction() == Action.LEFT_CLICK_BLOCK) return; || event.getAction() == Action.LEFT_CLICK_BLOCK) return;

View File

@ -22,7 +22,7 @@ public class BlockStack implements Stackable, Hologramable {
// The id that identifies this stack in the database. // The id that identifies this stack in the database.
private int id; private int id;
private int amount = 0; private int amount = 1;
private final CompatibleMaterial material; private final CompatibleMaterial material;
private final Location location; private final Location location;

View File

@ -26,12 +26,16 @@ public class BlockStackManager {
return registeredBlocks.remove(roundLocation(location)); 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)); return this.registeredBlocks.computeIfAbsent(location, b -> new BlockStack(material, location));
} }
public BlockStack getBlock(Block block, CompatibleMaterial material) { public BlockStack createBlock(Block block) {
return this.getBlock(block.getLocation(), material); return this.createBlock(block.getLocation(), CompatibleMaterial.getMaterial(block));
} }
public boolean isBlock(Location location) { public boolean isBlock(Location location) {