mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-14 12:10:30 +00:00
Correctly handle double chests on Fabric
Closes #1279. The perils of ignoring the transfer API :(.
This commit is contained in:
parent
3047e3cdf4
commit
7f34aff6bb
@ -66,4 +66,19 @@ class Inventory_Test {
|
||||
helper.assertContainerExactly(BlockPos(3, 2, 2), NonNullList.withSize(27, ItemStack(Items.POLISHED_ANDESITE)))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures inventory methods see a complete double chest
|
||||
*
|
||||
* @see <https://github.com/cc-tweaked/CC-Tweaked/issues/1279>
|
||||
*/
|
||||
@GameTest
|
||||
fun Double_chest_size(helper: GameTestHelper) = helper.sequence {
|
||||
thenOnComputer {
|
||||
getApi<PeripheralAPI>().call(context, ObjectArguments("left", "size")).await()
|
||||
.assertArrayEquals(54, message = "Has 54 slots")
|
||||
getApi<PeripheralAPI>().call(context, ObjectArguments("left", "pushItems", "right", 1)).await()
|
||||
.assertArrayEquals(32, message = "Moved 32 items into a double chest")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
139
projects/common/src/testMod/resources/data/cctest/structures/inventory_test.double_chest_size.snbt
generated
Normal file
139
projects/common/src/testMod/resources/data/cctest/structures/inventory_test.double_chest_size.snbt
generated
Normal file
@ -0,0 +1,139 @@
|
||||
{
|
||||
DataVersion: 3218,
|
||||
size: [5, 5, 5],
|
||||
data: [
|
||||
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 1, 0], state: "minecraft:air"},
|
||||
{pos: [0, 1, 1], state: "minecraft:air"},
|
||||
{pos: [0, 1, 2], state: "minecraft:chest{facing:north,type:left,waterlogged:false}", nbt: {Items: [], id: "minecraft:chest"}},
|
||||
{pos: [0, 1, 3], state: "minecraft:air"},
|
||||
{pos: [0, 1, 4], state: "minecraft:air"},
|
||||
{pos: [1, 1, 0], state: "minecraft:air"},
|
||||
{pos: [1, 1, 1], state: "minecraft:air"},
|
||||
{pos: [1, 1, 2], state: "minecraft:chest{facing:north,type:right,waterlogged:false}", nbt: {Items: [{Count: 64b, Slot: 0b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 1b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 2b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 3b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 4b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 5b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 6b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 7b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 8b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 9b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 10b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 11b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 12b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 13b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 14b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 15b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 16b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 17b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 18b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 19b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 20b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 21b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 22b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 23b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 24b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 25b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 26b, id: "minecraft:polished_andesite"}], id: "minecraft:chest"}},
|
||||
{pos: [1, 1, 3], state: "minecraft:air"},
|
||||
{pos: [1, 1, 4], state: "minecraft:air"},
|
||||
{pos: [2, 1, 0], state: "minecraft:air"},
|
||||
{pos: [2, 1, 1], state: "minecraft:air"},
|
||||
{pos: [2, 1, 2], state: "computercraft:computer_advanced{facing:north,state:on}", nbt: {ComputerId: 1, Label: "inventory_test.double_chest_size", On: 1b, id: "computercraft:computer_advanced"}},
|
||||
{pos: [2, 1, 3], state: "minecraft:air"},
|
||||
{pos: [2, 1, 4], state: "minecraft:air"},
|
||||
{pos: [3, 1, 0], state: "minecraft:air"},
|
||||
{pos: [3, 1, 1], state: "minecraft:air"},
|
||||
{pos: [3, 1, 2], state: "minecraft:chest{facing:north,type:left,waterlogged:false}", nbt: {Items: [], id: "minecraft:chest"}},
|
||||
{pos: [3, 1, 3], state: "minecraft:air"},
|
||||
{pos: [3, 1, 4], state: "minecraft:air"},
|
||||
{pos: [4, 1, 0], state: "minecraft:air"},
|
||||
{pos: [4, 1, 1], state: "minecraft:air"},
|
||||
{pos: [4, 1, 2], state: "minecraft:chest{facing:north,type:right,waterlogged:false}", nbt: {Items: [{Count: 32b, Slot: 0b, id: "minecraft:dirt"}], id: "minecraft:chest"}},
|
||||
{pos: [4, 1, 3], state: "minecraft:air"},
|
||||
{pos: [4, 1, 4], state: "minecraft:air"},
|
||||
{pos: [0, 2, 0], state: "minecraft:air"},
|
||||
{pos: [0, 2, 1], state: "minecraft:air"},
|
||||
{pos: [0, 2, 2], state: "minecraft:air"},
|
||||
{pos: [0, 2, 3], state: "minecraft:air"},
|
||||
{pos: [0, 2, 4], state: "minecraft:air"},
|
||||
{pos: [1, 2, 0], state: "minecraft:air"},
|
||||
{pos: [1, 2, 1], state: "minecraft:air"},
|
||||
{pos: [1, 2, 2], state: "minecraft:air"},
|
||||
{pos: [1, 2, 3], state: "minecraft:air"},
|
||||
{pos: [1, 2, 4], state: "minecraft:air"},
|
||||
{pos: [2, 2, 0], state: "minecraft:air"},
|
||||
{pos: [2, 2, 1], state: "minecraft:air"},
|
||||
{pos: [2, 2, 2], state: "minecraft:air"},
|
||||
{pos: [2, 2, 3], state: "minecraft:air"},
|
||||
{pos: [2, 2, 4], state: "minecraft:air"},
|
||||
{pos: [3, 2, 0], state: "minecraft:air"},
|
||||
{pos: [3, 2, 1], state: "minecraft:air"},
|
||||
{pos: [3, 2, 2], state: "minecraft:air"},
|
||||
{pos: [3, 2, 3], state: "minecraft:air"},
|
||||
{pos: [3, 2, 4], state: "minecraft:air"},
|
||||
{pos: [4, 2, 0], state: "minecraft:air"},
|
||||
{pos: [4, 2, 1], state: "minecraft:air"},
|
||||
{pos: [4, 2, 2], state: "minecraft:air"},
|
||||
{pos: [4, 2, 3], state: "minecraft:air"},
|
||||
{pos: [4, 2, 4], state: "minecraft:air"},
|
||||
{pos: [0, 3, 0], state: "minecraft:air"},
|
||||
{pos: [0, 3, 1], state: "minecraft:air"},
|
||||
{pos: [0, 3, 2], state: "minecraft:air"},
|
||||
{pos: [0, 3, 3], state: "minecraft:air"},
|
||||
{pos: [0, 3, 4], state: "minecraft:air"},
|
||||
{pos: [1, 3, 0], state: "minecraft:air"},
|
||||
{pos: [1, 3, 1], state: "minecraft:air"},
|
||||
{pos: [1, 3, 2], state: "minecraft:air"},
|
||||
{pos: [1, 3, 3], state: "minecraft:air"},
|
||||
{pos: [1, 3, 4], state: "minecraft:air"},
|
||||
{pos: [2, 3, 0], state: "minecraft:air"},
|
||||
{pos: [2, 3, 1], state: "minecraft:air"},
|
||||
{pos: [2, 3, 2], state: "minecraft:air"},
|
||||
{pos: [2, 3, 3], state: "minecraft:air"},
|
||||
{pos: [2, 3, 4], state: "minecraft:air"},
|
||||
{pos: [3, 3, 0], state: "minecraft:air"},
|
||||
{pos: [3, 3, 1], state: "minecraft:air"},
|
||||
{pos: [3, 3, 2], state: "minecraft:air"},
|
||||
{pos: [3, 3, 3], state: "minecraft:air"},
|
||||
{pos: [3, 3, 4], state: "minecraft:air"},
|
||||
{pos: [4, 3, 0], state: "minecraft:air"},
|
||||
{pos: [4, 3, 1], state: "minecraft:air"},
|
||||
{pos: [4, 3, 2], state: "minecraft:air"},
|
||||
{pos: [4, 3, 3], state: "minecraft:air"},
|
||||
{pos: [4, 3, 4], state: "minecraft:air"},
|
||||
{pos: [0, 4, 0], state: "minecraft:air"},
|
||||
{pos: [0, 4, 1], state: "minecraft:air"},
|
||||
{pos: [0, 4, 2], state: "minecraft:air"},
|
||||
{pos: [0, 4, 3], state: "minecraft:air"},
|
||||
{pos: [0, 4, 4], state: "minecraft:air"},
|
||||
{pos: [1, 4, 0], state: "minecraft:air"},
|
||||
{pos: [1, 4, 1], state: "minecraft:air"},
|
||||
{pos: [1, 4, 2], state: "minecraft:air"},
|
||||
{pos: [1, 4, 3], state: "minecraft:air"},
|
||||
{pos: [1, 4, 4], state: "minecraft:air"},
|
||||
{pos: [2, 4, 0], state: "minecraft:air"},
|
||||
{pos: [2, 4, 1], state: "minecraft:air"},
|
||||
{pos: [2, 4, 2], state: "minecraft:air"},
|
||||
{pos: [2, 4, 3], state: "minecraft:air"},
|
||||
{pos: [2, 4, 4], state: "minecraft:air"},
|
||||
{pos: [3, 4, 0], state: "minecraft:air"},
|
||||
{pos: [3, 4, 1], state: "minecraft:air"},
|
||||
{pos: [3, 4, 2], state: "minecraft:air"},
|
||||
{pos: [3, 4, 3], state: "minecraft:air"},
|
||||
{pos: [3, 4, 4], state: "minecraft:air"},
|
||||
{pos: [4, 4, 0], state: "minecraft:air"},
|
||||
{pos: [4, 4, 1], state: "minecraft:air"},
|
||||
{pos: [4, 4, 2], state: "minecraft:air"},
|
||||
{pos: [4, 4, 3], state: "minecraft:air"},
|
||||
{pos: [4, 4, 4], state: "minecraft:air"}
|
||||
],
|
||||
entities: [],
|
||||
palette: [
|
||||
"minecraft:polished_andesite",
|
||||
"minecraft:air",
|
||||
"minecraft:chest{facing:north,type:left,waterlogged:false}",
|
||||
"minecraft:chest{facing:north,type:right,waterlogged:false}",
|
||||
"computercraft:computer_advanced{facing:north,state:on}"
|
||||
]
|
||||
}
|
@ -8,6 +8,7 @@ package dan200.computercraft.shared.peripheral.generic;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.core.asm.NamedMethod;
|
||||
import dan200.computercraft.core.asm.PeripheralMethod;
|
||||
import dan200.computercraft.shared.peripheral.generic.methods.InventoryMethods;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.InventoryStorage;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.ItemStorage;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@ -32,7 +33,10 @@ public class GenericPeripheralProvider {
|
||||
private static final List<Lookup<?>> lookups = List.of(
|
||||
(world, pos, state, blockEntity, context) -> {
|
||||
// Try to avoid using the sided version of InventoryStorage where possible.
|
||||
if (blockEntity instanceof Container container) return InventoryStorage.of(container, null);
|
||||
if (blockEntity instanceof Container container && (container = InventoryMethods.extractContainer(container)) != null) {
|
||||
return InventoryStorage.of(container, null);
|
||||
}
|
||||
|
||||
return ItemStorage.SIDED.find(world, pos, state, blockEntity, context);
|
||||
}
|
||||
);
|
||||
|
@ -21,7 +21,9 @@ import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant;
|
||||
import net.fabricmc.fabric.api.transfer.v1.storage.base.SingleSlotStorage;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.ChestBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
@ -120,6 +122,12 @@ public class InventoryMethods implements GenericPeripheral {
|
||||
return moveItem(from, fromSlot - 1, to, toSlot.orElse(0) - 1, actualLimit);
|
||||
}
|
||||
|
||||
public static @Nullable Container extractContainer(Container container) {
|
||||
return container instanceof ChestBlockEntity chest && chest.getBlockState().getBlock() instanceof ChestBlock chestBlock
|
||||
? ChestBlock.getContainer(chestBlock, chest.getBlockState(), chest.getLevel(), chest.getBlockPos(), true)
|
||||
: container;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static InventoryStorage extractHandler(IPeripheral peripheral) {
|
||||
var object = peripheral.getTarget();
|
||||
@ -128,7 +136,9 @@ public class InventoryMethods implements GenericPeripheral {
|
||||
if (object instanceof BlockEntity blockEntity && blockEntity.isRemoved()) return null;
|
||||
|
||||
if (object instanceof InventoryStorage storage) return storage;
|
||||
if (object instanceof Container container) return InventoryStorage.of(container, null);
|
||||
if (object instanceof Container container && (container = extractContainer(container)) != null) {
|
||||
return InventoryStorage.of(container, null);
|
||||
}
|
||||
|
||||
if (object instanceof BlockEntity blockEntity && direction != null) {
|
||||
var found = ItemStorage.SIDED.find(blockEntity.getLevel(), blockEntity.getBlockPos(), blockEntity.getBlockState(), blockEntity, direction);
|
||||
|
Loading…
Reference in New Issue
Block a user