Change PlayerInventoryStorage#drop to use PlayerEntity#dropItem (#2098)

* change `PlayerInventoryStorage#drop` to use `PlayerEntity#dropItem`

* at -> from

* remainder
This commit is contained in:
deirn 2022-04-10 22:27:07 +07:00 committed by GitHub
parent 81ea5b3c83
commit 82a21997c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 22 deletions

View file

@ -20,6 +20,7 @@ import org.jetbrains.annotations.ApiStatus;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.util.Hand;
@ -110,15 +111,47 @@ public interface PlayerInventoryStorage extends InventoryStorage {
long offer(ItemVariant variant, long maxAmount, TransactionContext transaction);
/**
* Drop items in the world at the player's location.
* Throw items in the world from the player's location.
*
* <p>Note: This function has full transaction support, and will not actually drop the items until the outermost transaction is committed.
*
* @param variant The variant to drop.
* @param amount How many of the variant to drop.
* @param throwRandomly If true, the variant will be thrown in a random direction from the entity regardless of which direction the entity is facing.
* @param retainOwnership If true, set the {@code Thrower} NBT data to the player's UUID.
* @param transaction The transaction this operation is part of.
* @see PlayerEntity#dropItem(ItemStack, boolean, boolean)
*/
void drop(ItemVariant variant, long amount, boolean throwRandomly, boolean retainOwnership, TransactionContext transaction);
/**
* Throw items in the world from the player's location.
*
* <p>Note: This function has full transaction support, and will not actually drop the items until the outermost transaction is committed.
*
* @param variant The variant to drop.
* @param amount How many of the variant to drop.
* @param retainOwnership If true, set the {@code Thrower} NBT data to the player's UUID.
* @param transaction The transaction this operation is part of.
* @see PlayerEntity#dropItem(ItemStack, boolean, boolean)
*/
default void drop(ItemVariant variant, long amount, boolean retainOwnership, TransactionContext transaction) {
drop(variant, amount, false, retainOwnership, transaction);
}
/**
* Throw items in the world from the player's location.
*
* <p>Note: This function has full transaction support, and will not actually drop the items until the outermost transaction is committed.
*
* @param variant The variant to drop.
* @param amount How many of the variant to drop.
* @param transaction The transaction this operation is part of.
* @see PlayerEntity#dropItem(ItemStack, boolean, boolean)
*/
void drop(ItemVariant variant, long amount, TransactionContext transaction);
default void drop(ItemVariant variant, long amount, TransactionContext transaction) {
drop(variant, amount, false, transaction);
}
/**
* Return a wrapper around the current slot of the passed hand.

View file

@ -71,13 +71,13 @@ class PlayerInventoryStorageImpl extends InventoryStorageImpl implements PlayerI
}
@Override
public void drop(ItemVariant resource, long amount, TransactionContext tx) {
StoragePreconditions.notBlankNotNegative(resource, amount);
public void drop(ItemVariant variant, long amount, boolean throwRandomly, boolean retainOwnership, TransactionContext transaction) {
StoragePreconditions.notBlankNotNegative(variant, amount);
// Drop in the world on the server side (will be synced by the game with the client).
// Dropping items is server-side only because it involves randomness.
if (amount > 0 && !playerInventory.player.world.isClient()) {
droppedStacks.addDrop(resource, amount, tx);
droppedStacks.addDrop(variant, amount, throwRandomly, retainOwnership, transaction);
}
}
@ -97,18 +97,16 @@ class PlayerInventoryStorageImpl extends InventoryStorageImpl implements PlayerI
}
private class DroppedStacks extends SnapshotParticipant<Integer> {
final List<ItemVariant> droppedKeys = new ArrayList<>();
final List<Long> droppedCounts = new ArrayList<>();
final List<Entry> entries = new ArrayList<>();
void addDrop(ItemVariant key, long count, TransactionContext transaction) {
void addDrop(ItemVariant key, long amount, boolean throwRandomly, boolean retainOwnership, TransactionContext transaction) {
updateSnapshots(transaction);
droppedKeys.add(key);
droppedCounts.add(count);
entries.add(new Entry(key, amount, throwRandomly, retainOwnership));
}
@Override
protected Integer createSnapshot() {
return droppedKeys.size();
return entries.size();
}
@Override
@ -116,27 +114,28 @@ class PlayerInventoryStorageImpl extends InventoryStorageImpl implements PlayerI
// effectively cancel dropping the stacks
int previousSize = snapshot;
while (droppedKeys.size() > previousSize) {
droppedKeys.remove(droppedKeys.size() - 1);
droppedCounts.remove(droppedCounts.size() - 1);
while (entries.size() > previousSize) {
entries.remove(entries.size() - 1);
}
}
@Override
protected void onFinalCommit() {
// actually drop the stacks
for (int i = 0; i < droppedKeys.size(); ++i) {
ItemVariant key = droppedKeys.get(i);
for (Entry entry : entries) {
long remainder = entry.amount;
while (droppedCounts.get(i) > 0) {
int dropped = (int) Math.min(key.getItem().getMaxCount(), droppedCounts.get(i));
playerInventory.player.dropStack(key.toStack(dropped));
droppedCounts.set(i, droppedCounts.get(i) - dropped);
while (remainder > 0) {
int dropped = (int) Math.min(entry.key.getItem().getMaxCount(), remainder);
playerInventory.player.dropItem(entry.key.toStack(dropped), entry.throwRandomly, entry.retainOwnership);
remainder -= dropped;
}
}
droppedKeys.clear();
droppedCounts.clear();
entries.clear();
}
private record Entry(ItemVariant key, long amount, boolean throwRandomly, boolean retainOwnership) {
}
}
}