add shulker extraction and fix storing techreborn storage (#3111)

* add shulker extraction and fix storing techreborn storage

Only accept when nbt is null.
Adds shulker-extracting support

* fix when storeItemStack was empty

* fix inputting stack at first

* Use MC pair

---------

Co-authored-by: modmuss50 <modmuss50@gmail.com>
This commit is contained in:
AngelBottomless 2023-03-18 21:35:56 +09:00 committed by GitHub
parent 9841d3332d
commit 8b527dbead
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 116 additions and 5 deletions

View file

@ -30,11 +30,15 @@ import net.fabricmc.fabric.api.transfer.v1.item.PlayerInventoryStorage;
import net.fabricmc.fabric.api.transfer.v1.storage.base.SingleSlotStorage;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventories;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Pair;
import net.minecraft.util.collection.DefaultedList;
import org.jetbrains.annotations.Nullable;
import reborncore.common.powerSystem.RcEnergyItem;
import reborncore.common.recipes.IRecipeInput;
import team.reborn.energy.api.EnergyStorage;
@ -78,6 +82,95 @@ public class ItemUtils {
return false;
}
public static boolean canExtractAnyFromShulker(ItemStack shulkerStack, ItemStack targetStack) {
//bundle method
List<ItemStack> stacks = getBlockEntityStacks(shulkerStack);
if (stacks == null) return false;
for (ItemStack stack : stacks) {
if (isItemEqual(targetStack, stack, true)) {
return true;
}
}
return false;
}
public static int canExtractFromCachedShulker(List<ItemStack> stacks, ItemStack targetStack) {
//bundle method
if (stacks == null) return 0;
int defaultValue = 0;
for (ItemStack stack : stacks) {
if (isItemEqual(targetStack, stack, true)) {
defaultValue += stack.getCount();
}
}
return defaultValue;
}
public static boolean isStackListEmpty(List<ItemStack> stacks) {
for (ItemStack stack : stacks) {
if (!stack.isEmpty()) {
return false;
}
}
return true;
}
public static int extractableFromCachedShulker(List<ItemStack> stacks, ItemStack targetStack, int maxAmount) {
int extracted = 0;
for (ItemStack stack : stacks) {
if (stack.isEmpty()) continue;
if (isItemEqual(targetStack, stack, true)) {
int count = stack.getCount();
int toExtract = Math.min(maxAmount, count);
stack.decrement(toExtract);
maxAmount -= toExtract;
extracted += toExtract;
}
if (maxAmount == 0) break;
if (maxAmount < 0) throw new AssertionError("Extracted more than required amount!");
}
return extracted;
}
public static Pair<Integer, ItemStack> extractFromShulker(ItemStack shulkerStack, DefaultedList<ItemStack> entityStack, ItemStack targetStack, int capacity) {
ItemStack newStack = shulkerStack.copy();
if (entityStack == null) {
entityStack = getBlockEntityStacks(newStack);
}
if (entityStack == null) {
return new Pair<>(0, shulkerStack);
}
int extracted = extractableFromCachedShulker(entityStack, targetStack, capacity);
if (extracted == 0) {
return new Pair<>(0, shulkerStack);
}
NbtCompound blockEntityTag = newStack.getSubNbt("BlockEntityTag");
if (blockEntityTag == null) throw new IllegalStateException("BlockEntityTag is removed during operation!");
if (isStackListEmpty(entityStack)) {
if (blockEntityTag.contains("Items")) blockEntityTag.remove("Items");
if (blockEntityTag.getKeys().size() == 0) {
//remove empty nbt
blockEntityTag = null;
newStack.removeSubNbt("BlockEntityTag");
}
return new Pair<>(extracted, newStack);
}
Inventories.writeNbt(blockEntityTag, entityStack);
return new Pair<>(extracted, newStack);
}
public static @Nullable DefaultedList<ItemStack> getBlockEntityStacks(ItemStack targetStack) {
int maxSize = 128; // theorical max is 255
NbtCompound compound = targetStack.getSubNbt("BlockEntityTag");
if (compound == null) {
return null;
}
DefaultedList<ItemStack> returnStacks = DefaultedList.ofSize(maxSize, ItemStack.EMPTY);
if (compound.contains("Items")) {
Inventories.readNbt(compound, returnStacks);
}
return returnStacks;
}
public static boolean isEqualIgnoreEnergy(ItemStack stack1, ItemStack stack2) {
if (stack1 == stack2) {
return true;