mirror of
https://github.com/Minestom/Minestom.git
synced 2024-11-15 07:05:52 +01:00
Make StackingRule an interface, support per item max size, fix double click stacking
This commit is contained in:
parent
f432308197
commit
2773a2d46c
@ -32,7 +32,8 @@ public interface TransactionType {
|
||||
}
|
||||
if (stackingRule.canBeStacked(itemStack, inventoryItem)) {
|
||||
final int itemAmount = stackingRule.getAmount(inventoryItem);
|
||||
if (itemAmount == stackingRule.getMaxSize())
|
||||
final int maxSize = stackingRule.getMaxSize(inventoryItem);
|
||||
if (itemAmount == maxSize)
|
||||
continue;
|
||||
|
||||
if (!slotPredicate.test(i, inventoryItem)) {
|
||||
@ -44,8 +45,8 @@ public interface TransactionType {
|
||||
final int totalAmount = itemStackAmount + itemAmount;
|
||||
if (!stackingRule.canApply(itemStack, totalAmount)) {
|
||||
// Slot cannot accept the whole item, reduce amount to 'itemStack'
|
||||
itemChangesMap.put(i, stackingRule.apply(inventoryItem, stackingRule.getMaxSize()));
|
||||
itemStack = stackingRule.apply(itemStack, totalAmount - stackingRule.getMaxSize());
|
||||
itemChangesMap.put(i, stackingRule.apply(inventoryItem, maxSize));
|
||||
itemStack = stackingRule.apply(itemStack, totalAmount - maxSize);
|
||||
} else {
|
||||
// Slot can accept the whole item
|
||||
itemChangesMap.put(i, stackingRule.apply(inventoryItem, totalAmount));
|
||||
@ -97,10 +98,12 @@ public interface TransactionType {
|
||||
final int itemAmount = stackingRule.getAmount(inventoryItem);
|
||||
final int itemStackAmount = stackingRule.getAmount(itemStack);
|
||||
if (itemStackAmount < itemAmount) {
|
||||
System.out.println(1);
|
||||
itemChangesMap.put(i, stackingRule.apply(inventoryItem, itemAmount - itemStackAmount));
|
||||
itemStack = stackingRule.apply(itemStack, 0);
|
||||
break;
|
||||
}
|
||||
System.out.println(2);
|
||||
itemChangesMap.put(i, stackingRule.apply(inventoryItem, 0));
|
||||
itemStack = stackingRule.apply(itemStack, itemStackAmount - itemAmount);
|
||||
if (stackingRule.getAmount(itemStack) == 0) {
|
||||
|
@ -57,10 +57,11 @@ public class InventoryClickProcessor {
|
||||
|
||||
if (cursorRule.canBeStacked(cursor, clicked)) {
|
||||
final int totalAmount = cursorRule.getAmount(cursor) + clickedRule.getAmount(clicked);
|
||||
final int maxSize = cursorRule.getMaxSize(cursor);
|
||||
|
||||
if (!clickedRule.canApply(clicked, totalAmount)) {
|
||||
resultCursor = cursorRule.apply(cursor, totalAmount - cursorRule.getMaxSize());
|
||||
resultClicked = clickedRule.apply(clicked, clickedRule.getMaxSize());
|
||||
resultCursor = cursorRule.apply(cursor, totalAmount - maxSize);
|
||||
resultClicked = clickedRule.apply(clicked, maxSize);
|
||||
} else {
|
||||
resultCursor = cursorRule.apply(cursor, 0);
|
||||
resultClicked = clickedRule.apply(clicked, totalAmount);
|
||||
@ -256,7 +257,7 @@ public class InventoryClickProcessor {
|
||||
break;
|
||||
StackingRule slotItemRule = slotItem.getStackingRule();
|
||||
|
||||
final int maxSize = stackingRule.getMaxSize();
|
||||
final int maxSize = stackingRule.getMaxSize(cursor);
|
||||
if (stackingRule.canBeStacked(cursor, slotItem)) {
|
||||
final int amount = slotItemRule.getAmount(slotItem);
|
||||
if (stackingRule.canApply(slotItem, amount + slotSize)) {
|
||||
@ -351,7 +352,13 @@ public class InventoryClickProcessor {
|
||||
|
||||
final StackingRule cursorRule = cursor.getStackingRule();
|
||||
final int amount = cursorRule.getAmount(cursor);
|
||||
final int remainingAmount = cursorRule.getMaxSize() - amount;
|
||||
final int maxSize = cursorRule.getMaxSize(cursor);
|
||||
final int remainingAmount = maxSize - amount;
|
||||
|
||||
if (remainingAmount == 0) {
|
||||
// Item is already full
|
||||
return clickResult;
|
||||
}
|
||||
|
||||
ItemStack remain = cursorRule.apply(cursor, remainingAmount);
|
||||
|
||||
@ -386,9 +393,15 @@ public class InventoryClickProcessor {
|
||||
remain = func.apply(playerInventory, remain);
|
||||
}
|
||||
|
||||
final int tookAmount = remainingAmount - cursorRule.getAmount(remain);
|
||||
ItemStack resultCursor;
|
||||
if (remain.isAir()) {
|
||||
// Item has been filled
|
||||
resultCursor = cursorRule.apply(cursor, maxSize);
|
||||
} else {
|
||||
final int tookAmount = remainingAmount - cursorRule.getAmount(remain);
|
||||
resultCursor = cursorRule.apply(cursor, amount + tookAmount);
|
||||
}
|
||||
|
||||
ItemStack resultCursor = cursorRule.apply(cursor, amount + tookAmount);
|
||||
clickResult.setCursor(resultCursor);
|
||||
return clickResult;
|
||||
}
|
||||
|
@ -41,8 +41,7 @@ public final class ItemStack implements HoverEventSource<HoverEvent.ShowItem> {
|
||||
this.material = material;
|
||||
this.amount = amount;
|
||||
this.meta = meta;
|
||||
this.stackingRule = Objects.requireNonNullElseGet(stackingRule,
|
||||
() -> new VanillaStackingRule(64));
|
||||
this.stackingRule = Objects.requireNonNullElseGet(stackingRule, VanillaStackingRule::new);
|
||||
}
|
||||
|
||||
@Contract(value = "_ -> new", pure = true)
|
||||
|
@ -109,10 +109,9 @@ public class ItemStackBuilder {
|
||||
|
||||
@Contract(value = "-> new", pure = true)
|
||||
public @NotNull ItemStack build() {
|
||||
if (amount <= 0)
|
||||
return ItemStack.AIR;
|
||||
|
||||
return new ItemStack(material, amount, metaBuilder.build(), stackingRule);
|
||||
if (amount > 0)
|
||||
return new ItemStack(material, amount, metaBuilder.build(), stackingRule);
|
||||
return ItemStack.AIR;
|
||||
}
|
||||
|
||||
private static final class DefaultMeta extends ItemMetaBuilder {
|
||||
|
@ -10,13 +10,7 @@ import java.util.function.IntUnaryOperator;
|
||||
* This can be used to mimic the vanilla one (using the displayed item quantity)
|
||||
* or a complete new one which can be stored in lore, name, etc...
|
||||
*/
|
||||
public abstract class StackingRule {
|
||||
|
||||
private final int maxSize;
|
||||
|
||||
public StackingRule(int maxSize) {
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
public interface StackingRule {
|
||||
|
||||
/**
|
||||
* Used to know if two {@link ItemStack} can be stacked together.
|
||||
@ -26,16 +20,16 @@ public abstract class StackingRule {
|
||||
* @return true if both {@link ItemStack} can be stacked together
|
||||
* (without taking their amount in consideration)
|
||||
*/
|
||||
public abstract boolean canBeStacked(@NotNull ItemStack item1, @NotNull ItemStack item2);
|
||||
boolean canBeStacked(@NotNull ItemStack item1, @NotNull ItemStack item2);
|
||||
|
||||
/**
|
||||
* Used to know if an {@link ItemStack} can have the size {@code newAmount} applied.
|
||||
*
|
||||
* @param item the {@link ItemStack} to check
|
||||
* @param newAmount the desired new amount
|
||||
* @param amount the desired new amount
|
||||
* @return true if {@code item} can have its stack size set to newAmount
|
||||
*/
|
||||
public abstract boolean canApply(@NotNull ItemStack item, int newAmount);
|
||||
boolean canApply(@NotNull ItemStack item, int amount);
|
||||
|
||||
/**
|
||||
* Changes the size of the {@link ItemStack} to {@code newAmount}.
|
||||
@ -46,10 +40,10 @@ public abstract class StackingRule {
|
||||
* @return a new {@link ItemStack item} with the specified amount
|
||||
*/
|
||||
@Contract("_, _ -> new")
|
||||
public abstract @NotNull ItemStack apply(@NotNull ItemStack item, int newAmount);
|
||||
@NotNull ItemStack apply(@NotNull ItemStack item, int newAmount);
|
||||
|
||||
@Contract("_, _ -> new")
|
||||
public @NotNull ItemStack apply(@NotNull ItemStack item, @NotNull IntUnaryOperator amountOperator) {
|
||||
default @NotNull ItemStack apply(@NotNull ItemStack item, @NotNull IntUnaryOperator amountOperator) {
|
||||
return apply(item, amountOperator.applyAsInt(getAmount(item)));
|
||||
}
|
||||
|
||||
@ -60,14 +54,13 @@ public abstract class StackingRule {
|
||||
* @param itemStack the {@link ItemStack} to check the size
|
||||
* @return the correct size of {@link ItemStack}
|
||||
*/
|
||||
public abstract int getAmount(@NotNull ItemStack itemStack);
|
||||
int getAmount(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Gets the max size of a stack.
|
||||
*
|
||||
* @param itemStack the item to get the max size from
|
||||
* @return the max size of a stack
|
||||
*/
|
||||
public int getMaxSize() {
|
||||
return maxSize;
|
||||
}
|
||||
int getMaxSize(@NotNull ItemStack itemStack);
|
||||
}
|
||||
|
@ -5,11 +5,7 @@ import net.minestom.server.item.StackingRule;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class VanillaStackingRule extends StackingRule {
|
||||
|
||||
public VanillaStackingRule(int maxSize) {
|
||||
super(maxSize);
|
||||
}
|
||||
public class VanillaStackingRule implements StackingRule {
|
||||
|
||||
@Override
|
||||
public boolean canBeStacked(@NotNull ItemStack item1, @NotNull ItemStack item2) {
|
||||
@ -18,20 +14,23 @@ public class VanillaStackingRule extends StackingRule {
|
||||
|
||||
@Override
|
||||
public boolean canApply(@NotNull ItemStack item, int newAmount) {
|
||||
return MathUtils.isBetween(newAmount, 0, getMaxSize());
|
||||
return MathUtils.isBetween(newAmount, 0, getMaxSize(item));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ItemStack apply(@NotNull ItemStack item, int newAmount) {
|
||||
if (newAmount <= 0)
|
||||
return ItemStack.AIR;
|
||||
|
||||
return item.withAmount(newAmount);
|
||||
public @NotNull ItemStack apply(@NotNull ItemStack item, int amount) {
|
||||
if (amount > 0)
|
||||
return item.withAmount(amount);
|
||||
return ItemStack.AIR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount(@NotNull ItemStack itemStack) {
|
||||
return itemStack.getAmount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxSize(@NotNull ItemStack itemStack) {
|
||||
return itemStack.getMaterial().getMaxDefaultStackSize();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user