Prevent unnecessary item copy during drop

This commit is contained in:
Felix Cravic 2020-12-07 23:57:57 +01:00
parent 40787902e3
commit ff4580c41b
3 changed files with 38 additions and 23 deletions

View File

@ -254,14 +254,13 @@ public class PaletteStorage {
8191, 16383, 32767};
private static void setBlockAt(@NotNull PaletteStorage paletteStorage, int x, int y, int z, short blockId) {
if (y < 0 || y >= Chunk.CHUNK_SIZE_Y) {
if (!MathUtils.isBetween(y, 0, Chunk.CHUNK_SIZE_Y)) {
return;
}
final int section = ChunkUtils.getSectionAt(y);
final int valuesPerLong = paletteStorage.valuesPerLong;
final int bitsPerEntry = paletteStorage.bitsPerEntry;
if (paletteStorage.sectionBlocks[section].length == 0) {
if (blockId == 0) {
@ -273,6 +272,7 @@ public class PaletteStorage {
paletteStorage.sectionBlocks[section] = new long[getSize(valuesPerLong)];
}
// Convert world coordinates to chunk coordinates
x = toChunkCoordinate(x);
z = toChunkCoordinate(z);
@ -282,6 +282,8 @@ public class PaletteStorage {
final int sectionIndex = getSectionIndex(x, y, z);
final int index = sectionIndex / valuesPerLong;
final int bitsPerEntry = paletteStorage.bitsPerEntry;
final int bitIndex = (sectionIndex % valuesPerLong) * bitsPerEntry;
final long[] sectionBlock = paletteStorage.sectionBlocks[section];

View File

@ -51,19 +51,6 @@ public class ItemStack implements DataContainer {
private byte amount;
private int damage;
public ItemStack(@NotNull Material material, byte amount, int damage) {
this.identifier = DATA_OWNERSHIP.generateIdentifier();
this.material = material;
this.amount = amount;
this.damage = damage;
this.lore = new ArrayList<>();
this.enchantmentMap = new HashMap<>();
this.attributes = new ArrayList<>();
this.itemMeta = findMeta();
}
private ColoredText displayName;
private boolean unbreakable;
private ArrayList<ColoredText> lore;
@ -83,6 +70,19 @@ public class ItemStack implements DataContainer {
this.stackingRule = defaultStackingRule;
}
public ItemStack(@NotNull Material material, byte amount, int damage) {
this.identifier = DATA_OWNERSHIP.generateIdentifier();
this.material = material;
this.amount = amount;
this.damage = damage;
this.lore = new ArrayList<>();
this.enchantmentMap = new HashMap<>();
this.attributes = new ArrayList<>();
this.itemMeta = findMeta();
}
public ItemStack(@NotNull Material material, byte amount) {
this(material, amount, (short) 0);
}
@ -552,8 +552,10 @@ public class ItemStack implements DataContainer {
/**
* Copies this item stack.
* <p>
* Be aware that the identifier ({@link #getIdentifier()}) will change.
*
* @return a cloned item stack
* @return a cloned item stack with a different identifier
*/
@NotNull
public synchronized ItemStack copy() {

View File

@ -92,19 +92,30 @@ public class PlayerDiggingListener {
}
break;
case DROP_ITEM_STACK:
final ItemStack droppedItemStack = player.getInventory().getItemInMainHand().copy();
final ItemStack droppedItemStack = player.getInventory().getItemInMainHand();
dropItem(player, droppedItemStack, ItemStack.getAirItem());
break;
case DROP_ITEM:
ItemStack handItem = player.getInventory().getItemInMainHand().copy();
ItemStack droppedItemStack2 = handItem.copy();
final StackingRule handStackingRule = handItem.getStackingRule();
final int dropAmount = 1;
droppedItemStack2 = handStackingRule.apply(droppedItemStack2, 1);
ItemStack handItem = player.getInventory().getItemInMainHand();
final StackingRule stackingRule = handItem.getStackingRule();
final int handAmount = stackingRule.getAmount(handItem);
handItem = handStackingRule.apply(handItem, handStackingRule.getAmount(handItem) - 1);
if (handAmount == dropAmount) {
// Drop the whole item without copy
dropItem(player, handItem, ItemStack.getAirItem());
} else {
// Drop a single item, need a copy
ItemStack droppedItemStack2 = handItem.copy();
dropItem(player, droppedItemStack2, handItem);
droppedItemStack2 = stackingRule.apply(droppedItemStack2, dropAmount);
handItem = handItem.copy(); // Force the copy
handItem = stackingRule.apply(handItem, handAmount - dropAmount);
dropItem(player, droppedItemStack2, handItem);
}
break;
case UPDATE_ITEM_STATE:
player.refreshEating(false);