1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-09-02 18:37:55 +00:00

Merge pull request #10 from Toad-Dev/fabric-merith

Bugfixes
This commit is contained in:
Merith
2021-05-16 13:00:47 -07:00
committed by GitHub
9 changed files with 150 additions and 235 deletions

View File

@@ -31,17 +31,3 @@ jobs:
with: with:
name: cc-restiched name: cc-restiched
path: build/libs path: build/libs
- name: Upload Coverage
run: bash <(curl -s https://codecov.io/bash)
continue-on-error: true
- name: Lint Lua code
run: |
test -d bin || mkdir bin
test -f bin/illuaminate || wget -q -Obin/illuaminate https://squiddev.cc/illuaminate/linux-x86-64/illuaminate
chmod +x bin/illuaminate
bin/illuaminate lint
- name: Check whitespace
run: python3 tools/check-lines.py

View File

@@ -43,8 +43,8 @@ If you need help getting started with CC: Tweaked, want to show off your latest
Main Known issue Main Known issue
* Mods that add blocks that can be used as peripherals for CC:T On forge, dont work with CC:R. * Mods that add blocks that can be used as peripherals for CC:T On forge, dont work with CC:R.
* This is because of the differences between forge and fabric, and that mod devs, to my knowledge have not agreed upon a standard method in which to implement cross compatibility between mods, * This is because of the differences between forge and fabric, and that mod devs, to my knowledge have not agreed upon a standard method in which to implement cross compatibility between mods,
* Storage Peripherals throw a java "StackOverflowError" when using `pushItems()`, * [Fixed (d10f297c): please report if bug persists]</br> ~~Storage Peripherals throw a java "StackOverflowError" when using `pushItems()`,~~
* Work around, you are probably using `pushItems(chest, 1)` or simular. please use `pushItems(chest, 1, nil, 1)`. * ~~Work around, you are probably using `pushItems(chest, 1)` or similar. please use `pushItems(chest, 1, nil, 1)`.~~
## Known Working mods that add Peripherals ## Known Working mods that add Peripherals
* Please let me know of other mods that work with this one * Please let me know of other mods that work with this one

View File

@@ -14,8 +14,8 @@ import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormatElement; import net.minecraft.client.render.VertexFormatElement;
import net.minecraft.client.render.VertexFormats; import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.render.model.BakedQuad; import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.util.math.Vector4f;
import net.minecraft.util.math.Matrix4f; import net.minecraft.util.math.Matrix4f;
import net.minecraft.util.math.Quaternion;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
@@ -50,41 +50,31 @@ public final class ModelTransformer {
} }
private static BakedQuad doTransformQuad(VertexFormat format, BakedQuad quad, Matrix4f transform) { private static BakedQuad doTransformQuad(VertexFormat format, BakedQuad quad, Matrix4f transform) {
int[] vertexData = quad.getVertexData() int[] vertexData = quad.getVertexData().clone();
.clone();
int offset = 0;
BakedQuad copy = new BakedQuad(vertexData, -1, quad.getFace(), ((BakedQuadAccess)quad).getSprite(), true); BakedQuad copy = new BakedQuad(vertexData, -1, quad.getFace(), ((BakedQuadAccess)quad).getSprite(), true);
for (int i = 0; i < format.getElements()
.size(); ++i) // For each vertex element int offsetBytes = 0;
{ for (int v = 0; v < 4; ++v) {
VertexFormatElement element = format.getElements() for (VertexFormatElement element : format.getElements()) // For each vertex element
.get(i);
if (element.getType() == VertexFormatElement.Type.POSITION && element.getFormat() == VertexFormatElement.Format.FLOAT && element.getSize() == 3) // When we find a position
// element
{ {
for (int j = 0; j < 4; ++j) // For each corner of the quad int start = offsetBytes / Integer.BYTES;
if (element.getType() == VertexFormatElement.Type.POSITION && element.getFormat() == VertexFormatElement.Format.FLOAT) // When we find a position element
{ {
int start = offset + j * format.getVertexSize(); Vector4f pos = new Vector4f(Float.intBitsToFloat(vertexData[start]),
if ((start % 4) == 0) { Float.intBitsToFloat(vertexData[start+1]),
start = start / 4; Float.intBitsToFloat(vertexData[start+2]),
1);
// Extract the position // Transform the position
Quaternion pos = new Quaternion(Float.intBitsToFloat(vertexData[start]), pos.transform(transform);
Float.intBitsToFloat(vertexData[start + 1]),
Float.intBitsToFloat(vertexData[start + 2]),
1);
// Transform the position // Insert the position
transform.multiply(pos); vertexData[start] = Float.floatToRawIntBits(pos.getX());
vertexData[start+1] = Float.floatToRawIntBits(pos.getY());
// Insert the position vertexData[start+2] = Float.floatToRawIntBits(pos.getZ());
vertexData[start] = Float.floatToRawIntBits(pos.getX());
vertexData[start + 1] = Float.floatToRawIntBits(pos.getY());
vertexData[start + 2] = Float.floatToRawIntBits(pos.getZ());
}
} }
offsetBytes += element.getSize();
} }
offset += element.getSize();
} }
return copy; return copy;
} }

View File

@@ -78,9 +78,10 @@ public class TurtleSmartItemModel implements BakedModel {
Identifier overlay = turtle.getOverlay(stack); Identifier overlay = turtle.getOverlay(stack);
boolean christmas = HolidayUtil.getCurrentHoliday() == Holiday.CHRISTMAS; boolean christmas = HolidayUtil.getCurrentHoliday() == Holiday.CHRISTMAS;
String label = turtle.getLabel(stack); String label = turtle.getLabel(stack);
boolean flip = label != null && (label.equals("Dinnerbone") || label.equals("Grumm")); // TODO make upside down turtle items render properly (currently inivisible)
// TODO Make TurtleTool render for turtle items again. //boolean flip = label != null && (label.equals("Dinnerbone") || label.equals("Grumm"));
TurtleModelCombination combo = new TurtleModelCombination(colour != -1, !(leftUpgrade instanceof TurtleTool) ? leftUpgrade : null, !(rightUpgrade instanceof TurtleTool) ? rightUpgrade : null, overlay, christmas, flip); boolean flip = false;
TurtleModelCombination combo = new TurtleModelCombination(colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip);
BakedModel model = TurtleSmartItemModel.this.m_cachedModels.get(combo); BakedModel model = TurtleSmartItemModel.this.m_cachedModels.get(combo);
if (model == null) { if (model == null) {

View File

@@ -28,7 +28,6 @@ public class GenericPeripheralProvider
ArrayList<SaturatedMethod> saturated = new ArrayList<>( 0 ); ArrayList<SaturatedMethod> saturated = new ArrayList<>( 0 );
// This seems to add inventory methods, how???
List<NamedMethod<PeripheralMethod>> tileMethods = PeripheralMethod.GENERATOR.getMethods( tile.getClass() ); List<NamedMethod<PeripheralMethod>> tileMethods = PeripheralMethod.GENERATOR.getMethods( tile.getClass() );
if( !tileMethods.isEmpty() ) addSaturated( saturated, tile, tileMethods ); if( !tileMethods.isEmpty() ) addSaturated( saturated, tile, tileMethods );

View File

@@ -13,6 +13,8 @@ import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.asm.GenericSource; import dan200.computercraft.core.asm.GenericSource;
import dan200.computercraft.shared.peripheral.generic.data.ItemData; import dan200.computercraft.shared.peripheral.generic.data.ItemData;
import dan200.computercraft.shared.util.InventoryUtil;
import dan200.computercraft.shared.util.ItemStorage;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.ChestBlock; import net.minecraft.block.ChestBlock;
@@ -60,10 +62,7 @@ public class InventoryMethods implements GenericSource
@LuaFunction( mainThread = true ) @LuaFunction( mainThread = true )
public static int size( Inventory inventory ) public static int size( Inventory inventory )
{ {
// Get appropriate inventory for source peripheral return extractHandler(inventory).size();
inventory = extractHandler(inventory);
return inventory.size();
} }
/** /**
@@ -73,9 +72,13 @@ public class InventoryMethods implements GenericSource
* @return The name of this inventory, or {@code nil} if not present. * @return The name of this inventory, or {@code nil} if not present.
*/ */
@LuaFunction( mainThread = true ) @LuaFunction( mainThread = true )
public static String name( Nameable inventory ) public static String name( Inventory inventory )
{ {
return inventory.hasCustomName() ? inventory.getName().asString() : null; if ( inventory instanceof Nameable ) {
Nameable i = (Nameable)inventory;
return i.hasCustomName() ? i.getName().asString() : null;
}
return null;
} }
/** /**
@@ -95,14 +98,13 @@ public class InventoryMethods implements GenericSource
@LuaFunction( mainThread = true ) @LuaFunction( mainThread = true )
public static Map<Integer, Map<String, ?>> list( Inventory inventory ) public static Map<Integer, Map<String, ?>> list( Inventory inventory )
{ {
// Get appropriate inventory for source peripheral ItemStorage itemStorage = extractHandler(inventory);
inventory = extractHandler(inventory);
Map<Integer, Map<String, ?>> result = new HashMap<>(); Map<Integer, Map<String, ?>> result = new HashMap<>();
int size = inventory.size(); int size = itemStorage.size();
for( int i = 0; i < size; i++ ) for( int i = 0; i < size; i++ )
{ {
ItemStack stack = inventory.getStack( i ); ItemStack stack = itemStorage.getStack( i );
if( !stack.isEmpty() ) result.put( i + 1, ItemData.fillBasic( new HashMap<>( 4 ), stack ) ); if( !stack.isEmpty() ) result.put( i + 1, ItemData.fillBasic( new HashMap<>( 4 ), stack ) );
} }
@@ -122,12 +124,11 @@ public class InventoryMethods implements GenericSource
@LuaFunction( mainThread = true ) @LuaFunction( mainThread = true )
public static Map<String, ?> getItemDetail( Inventory inventory, int slot ) throws LuaException public static Map<String, ?> getItemDetail( Inventory inventory, int slot ) throws LuaException
{ {
// Get appropriate inventory ItemStorage itemStorage = extractHandler(inventory);
inventory = extractHandler(inventory);
assertBetween( slot, 1, inventory.size(), "Slot out of range (%s)" ); assertBetween( slot, 1, itemStorage.size(), "Slot out of range (%s)" );
ItemStack stack = inventory.getStack( slot - 1 ); ItemStack stack = itemStorage.getStack( slot - 1 );
return stack.isEmpty() ? null : ItemData.fill( new HashMap<>(), stack ); return stack.isEmpty() ? null : ItemData.fill( new HashMap<>(), stack );
} }
@@ -162,23 +163,22 @@ public class InventoryMethods implements GenericSource
String toName, int fromSlot, Optional<Integer> limit, Optional<Integer> toSlot String toName, int fromSlot, Optional<Integer> limit, Optional<Integer> toSlot
) throws LuaException ) throws LuaException
{ {
// Get appropriate inventory for source peripheral ItemStorage fromStorage = extractHandler( from );
from = extractHandler(from);
// Find location to transfer to // Find location to transfer to
IPeripheral location = computer.getAvailablePeripheral( toName ); IPeripheral location = computer.getAvailablePeripheral( toName );
if( location == null ) throw new LuaException( "Target '" + toName + "' does not exist" ); if( location == null ) throw new LuaException( "Target '" + toName + "' does not exist" );
Inventory to = extractHandler( location.getTarget() ); ItemStorage toStorage = extractHandler( location.getTarget() );
if( to == null ) throw new LuaException( "Target '" + toName + "' is not an inventory" ); if( toStorage == null ) throw new LuaException( "Target '" + toName + "' is not an inventory" );
// Validate slots // Validate slots
int actualLimit = limit.orElse( Integer.MAX_VALUE ); int actualLimit = limit.orElse( Integer.MAX_VALUE );
assertBetween( fromSlot, 1, from.size(), "From slot out of range (%s)" ); assertBetween( fromSlot, 1, fromStorage.size(), "From slot out of range (%s)" );
if( toSlot.isPresent() ) assertBetween( toSlot.get(), 1, to.size(), "To slot out of range (%s)" ); if( toSlot.isPresent() ) assertBetween( toSlot.get(), 1, toStorage.size(), "To slot out of range (%s)" );
if( actualLimit <= 0 ) return 0; if( actualLimit <= 0 ) return 0;
return moveItem( from, fromSlot - 1, to, toSlot.orElse( 0 ) - 1, actualLimit ); return moveItem( fromStorage, fromSlot - 1, toStorage, toSlot.orElse( 0 ) - 1, actualLimit );
} }
/** /**
@@ -213,55 +213,36 @@ public class InventoryMethods implements GenericSource
) throws LuaException ) throws LuaException
{ {
// Get appropriate inventory for source peripheral // Get appropriate inventory for source peripheral
to = extractHandler(to); ItemStorage toStorage = extractHandler( to );
// Find location to transfer to // Find location to transfer to
IPeripheral location = computer.getAvailablePeripheral( fromName ); IPeripheral location = computer.getAvailablePeripheral( fromName );
if( location == null ) throw new LuaException( "Source '" + fromName + "' does not exist" ); if( location == null ) throw new LuaException( "Source '" + fromName + "' does not exist" );
Inventory from = extractHandler( location.getTarget() ); ItemStorage fromStorage = extractHandler( location.getTarget() );
if( from == null ) throw new LuaException( "Source '" + fromName + "' is not an inventory" ); if( fromStorage == null ) throw new LuaException( "Source '" + fromName + "' is not an inventory" );
// Validate slots // Validate slots
int actualLimit = limit.orElse( Integer.MAX_VALUE ); int actualLimit = limit.orElse( Integer.MAX_VALUE );
assertBetween( fromSlot, 1, from.size(), "From slot out of range (%s)" ); assertBetween( fromSlot, 1, fromStorage.size(), "From slot out of range (%s)" );
if( toSlot.isPresent() ) assertBetween( toSlot.get(), 1, to.size(), "To slot out of range (%s)" ); if( toSlot.isPresent() ) assertBetween( toSlot.get(), 1, toStorage.size(), "To slot out of range (%s)" );
if( actualLimit <= 0 ) return 0; if( actualLimit <= 0 ) return 0;
return moveItem( from, fromSlot - 1, to, toSlot.orElse( 0 ) - 1, actualLimit ); return moveItem( fromStorage, fromSlot - 1, toStorage, toSlot.orElse( 0 ) - 1, actualLimit );
} }
/**
* Extracts the most appropriate inventory from the object
* e.g., the correct inventory for a double chest or a sided inventory.
*
* @param object The handler to move from.
* @return The appropriate Inventory.
*/
@Nullable @Nullable
private static Inventory extractHandler( @Nullable Object object ) private static ItemStorage extractHandler( @Nullable Object object )
{ {
Inventory inventory = null; if ( object instanceof BlockEntity ) {
Inventory inventory = InventoryUtil.getInventory((BlockEntity) object);
if (object instanceof BlockEntity ) { if ( inventory != null ) {
BlockEntity blockEntity = (BlockEntity) object; return ItemStorage.wrap(inventory);
World world = blockEntity.getWorld();
BlockPos blockPos = blockEntity.getPos();
BlockState blockState = world.getBlockState(blockPos);
Block block = blockState.getBlock();
if (block instanceof InventoryProvider) {
inventory = ((InventoryProvider)block).getInventory(blockState, world, blockPos);
} else if (blockEntity instanceof Inventory) {
inventory = (Inventory)blockEntity;
if (inventory instanceof ChestBlockEntity && block instanceof ChestBlock) {
inventory = ChestBlock.getInventory((ChestBlock) block, blockState, world, blockPos, true);
}
} }
} }
return inventory; return null;
} }
/** /**
@@ -274,109 +255,36 @@ public class InventoryMethods implements GenericSource
* @param limit The max number to move. {@link Integer#MAX_VALUE} for no limit. * @param limit The max number to move. {@link Integer#MAX_VALUE} for no limit.
* @return The number of items moved. * @return The number of items moved.
*/ */
private static int moveItem( Inventory from, int fromSlot, Inventory to, int toSlot, final int limit ) private static int moveItem( ItemStorage from, int fromSlot, ItemStorage to, int toSlot, final int limit )
{ {
// Moving nothing is easy
/* ORIGINAL FORGE CODE if (limit == 0) {
// See how much we can get out of this slot
// ItemStack extracted = from.extractItem( fromSlot, limit, true );
if( extracted.isEmpty() ) return 0;
// Limit the amount to extract
int extractCount = Math.min( extracted.getCount(), limit );
extracted.setCount( extractCount );
// ItemStack remainder = toSlot < 0 ? bItemHandlerHelper.insertItem( to, extracted, false ) : to.insertItem( toSlot, extracted, false );
int inserted = remainder.isEmpty() ? extractCount : extractCount - remainder.getCount();
if( inserted <= 0 ) return 0;
// Remove the item from the original inventory. Technically this could fail, but there's little we can do
// about that.
from.extractItem( fromSlot, inserted, false );
*/
// Vanilla minecraft inventory manipulation code
Boolean recurse = false;
ItemStack source = from.getStack( fromSlot );
int count = 0;
// If target slot was selected, only push items to that slot.
if (toSlot >= 0) {
int space = amountStackCanAddFrom(to.getStack(toSlot), source, to);
if (space == 0) return 0;
count = space;
}
// If target slot not selected, push items where they will fit, possibly
// across slots (by recurring on this method).
else if (toSlot < 0) {
recurse = true;
int[] result = getFirstValidSlotAndSpace(source, to);
toSlot = result[0];
if(toSlot < 0) return 0;
count = result[1];
}
// Respect slot restrictions
if (!to.isValid(toSlot, source)) { return 0; }
// Compare count available in target ItemStack to limit specified.
count = Math.min(count, limit);
if (count == 0) return 0;
// Mutate destination and source ItemStack
ItemStack destination = to.getStack(toSlot);
if (destination.isEmpty()) {
ItemStack newStack = source.copy();
newStack.setCount(count);
to.setStack(toSlot, newStack);
} else {
destination.increment(count);
}
source.decrement(count);
if (source.isEmpty()) from.setStack(fromSlot, ItemStack.EMPTY);
to.markDirty();
from.markDirty();
// Recurse if no explicit destination slot and more items exist in source slot
// and limit hasn't been reached. Else, return items moved.
if (recurse && !source.isEmpty()) return count + moveItem(from, fromSlot, to, -1, limit - count);
return count;
}
// Maybe there is a nicer existing way to do this in the minecraft codebase. I couldn't find it.
private static int[] getFirstValidSlotAndSpace(ItemStack fromStack, Inventory inventory) {
for (int i = 0; i < inventory.size(); i++) {
ItemStack stack = inventory.getStack(i);
int space = amountStackCanAddFrom(stack, fromStack, inventory);
if (space > 0) {
return new int[]{i, space};
}
}
return new int[]{-1, 0};
}
private static int amountStackCanAddFrom(ItemStack existingStack, ItemStack fromStack, Inventory inventory) {
if (fromStack.isEmpty()) {
return 0; return 0;
} }
else if (existingStack.isEmpty()) {
return Math.min(Math.min(existingStack.getMaxCount(),
inventory.getMaxCountPerStack()),
fromStack.getCount());
}
else if (InventoryMethods.areItemsEqual(existingStack, fromStack) &&
existingStack.isStackable() &&
existingStack.getCount() < existingStack.getMaxCount() &&
existingStack.getCount() < inventory.getMaxCountPerStack()) {
int stackSpace = existingStack.getMaxCount() - existingStack.getCount();
int invSpace = inventory.getMaxCountPerStack() - existingStack.getCount();
return Math.min(Math.min(stackSpace, invSpace), fromStack.getCount());
}
return 0;
}
private static boolean areItemsEqual(ItemStack stack1, ItemStack stack2) { // Get stack to move
return stack1.getItem() == stack2.getItem() && ItemStack.areTagsEqual(stack1, stack2); ItemStack stack = InventoryUtil.takeItems(limit, from, fromSlot, 1, fromSlot);
if (stack.isEmpty()) {
return 0;
}
int stackCount = stack.getCount();
// Move items in
ItemStack remainder;
if (toSlot < 0) {
remainder = InventoryUtil.storeItems(stack, to);
} else {
remainder = InventoryUtil.storeItems(stack, to, toSlot, 1, toSlot);
}
// Calculate items moved
int count = stackCount - remainder.getCount();
if (!remainder.isEmpty()) {
// Put the remainder back
InventoryUtil.storeItems(remainder, from, fromSlot, 1, fromSlot);
}
return count;
} }
} }

View File

@@ -22,6 +22,7 @@ import dan200.computercraft.shared.util.DirectionUtil;
import dan200.computercraft.shared.util.DropConsumer; import dan200.computercraft.shared.util.DropConsumer;
import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.InventoryUtil;
import dan200.computercraft.shared.util.WorldUtil; import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.item.*;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@@ -29,16 +30,6 @@ import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.block.entity.SignBlockEntity;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.BoatItem;
import net.minecraft.item.BucketItem;
import net.minecraft.item.GlassBottleItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.item.LilyPadItem;
import net.minecraft.item.SignItem;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
@@ -224,27 +215,18 @@ public class TurtlePlaceCommand implements ITurtleCommand {
// Place on the entity // Place on the entity
boolean placed = false; boolean placed = false;
ActionResult cancelResult = hitEntity.interactAt(turtlePlayer, hitPos, Hand.MAIN_HAND); ActionResult cancelResult = hitEntity.interactAt(turtlePlayer, hitPos, Hand.MAIN_HAND);
if (cancelResult == null) {
cancelResult = hitEntity.interactAt(turtlePlayer, hitPos, Hand.MAIN_HAND);
}
if (cancelResult != null && cancelResult.isAccepted()) { if (cancelResult != null && cancelResult.isAccepted()) {
placed = true; placed = true;
} else if (hitEntity instanceof LivingEntity) { }
// See EntityPlayer.interactOn else {
cancelResult = stackCopy.useOnEntity(turtlePlayer, (LivingEntity) hitEntity, Hand.MAIN_HAND); cancelResult = hitEntity.interact(turtlePlayer, Hand.MAIN_HAND);
if (cancelResult != null && cancelResult.isAccepted()) { if (cancelResult != null && cancelResult.isAccepted()) {
placed = true; placed = true;
} else if (cancelResult == null) { }
if (hitEntity.interact(turtlePlayer, Hand.MAIN_HAND) == ActionResult.CONSUME) { else if (hitEntity instanceof LivingEntity) {
placed = true; placed = stackCopy.useOnEntity(turtlePlayer, (LivingEntity) hitEntity, Hand.MAIN_HAND).isAccepted();
} else { if (placed) turtlePlayer.loadInventory(stackCopy);
placed = stackCopy.useOnEntity(turtlePlayer, (LivingEntity) hitEntity, Hand.MAIN_HAND)
.isAccepted();
if (placed) {
turtlePlayer.loadInventory(stackCopy);
}
}
} }
} }
@@ -304,11 +286,9 @@ public class TurtlePlaceCommand implements ITurtleCommand {
BlockEntity existingTile = turtle.getWorld() BlockEntity existingTile = turtle.getWorld()
.getBlockEntity(position); .getBlockEntity(position);
if (placementContext.canPlace()) { if (stackCopy.useOnBlock(context).isAccepted()) {
if (stackCopy.useOnBlock(context) == ActionResult.SUCCESS) { placed = true;
placed = true; turtlePlayer.loadInventory(stackCopy);
turtlePlayer.loadInventory(stackCopy);
}
} }
if (!placed && (item instanceof BucketItem || item instanceof BoatItem || item instanceof LilyPadItem || item instanceof GlassBottleItem)) { if (!placed && (item instanceof BucketItem || item instanceof BoatItem || item instanceof LilyPadItem || item instanceof GlassBottleItem)) {

View File

@@ -8,6 +8,11 @@ package dan200.computercraft.shared.util;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ChestBlock;
import net.minecraft.block.InventoryProvider;
import net.minecraft.block.entity.ChestBlockEntity;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
@@ -33,9 +38,20 @@ public final class InventoryUtil {
// Look for tile with inventory // Look for tile with inventory
int y = pos.getY(); int y = pos.getY();
if (y >= 0 && y < world.getHeight()) { if (y >= 0 && y < world.getHeight()) {
BlockEntity tileEntity = world.getBlockEntity(pos); // Check if block is InventoryProvider
if (tileEntity instanceof Inventory) { BlockState blockState = world.getBlockState(pos);
return (Inventory) tileEntity; Block block = blockState.getBlock();
if (block instanceof InventoryProvider) {
return ((InventoryProvider)block).getInventory(blockState, world, pos);
}
// Check if block is BlockEntity w/ Inventory
if (block.hasBlockEntity()) {
BlockEntity tileEntity = world.getBlockEntity(pos);
Inventory inventory = getInventory(tileEntity);
if (inventory != null) {
return inventory;
}
} }
} }
@@ -55,6 +71,23 @@ public final class InventoryUtil {
return null; return null;
} }
public static Inventory getInventory(BlockEntity tileEntity) {
World world = tileEntity.getWorld();
BlockPos pos = tileEntity.getPos();
BlockState blockState = world.getBlockState(pos);
Block block = blockState.getBlock();
if (tileEntity instanceof Inventory) {
Inventory inventory = (Inventory)tileEntity;
if (inventory instanceof ChestBlockEntity && block instanceof ChestBlock) {
return ChestBlock.getInventory((ChestBlock) block, blockState, world, pos, true);
}
return inventory;
}
return null;
}
@Nonnull @Nonnull
public static ItemStack storeItems(@Nonnull ItemStack itemstack, ItemStorage inventory, int begin) { public static ItemStack storeItems(@Nonnull ItemStack itemstack, ItemStorage inventory, int begin) {
return storeItems(itemstack, inventory, 0, inventory.size(), begin); return storeItems(itemstack, inventory, 0, inventory.size(), begin);

View File

@@ -35,6 +35,9 @@ public interface ItemStorage {
int size(); int size();
@Nonnull
ItemStack getStack(int slot);
@Nonnull @Nonnull
ItemStack take(int slot, int limit, @Nonnull ItemStack filter, boolean simulate); ItemStack take(int slot, int limit, @Nonnull ItemStack filter, boolean simulate);
@@ -57,6 +60,12 @@ public interface ItemStorage {
return this.inventory.size(); return this.inventory.size();
} }
@Override
@Nonnull
public ItemStack getStack(int slot) {
return this.inventory.getStack(slot);
}
@Override @Override
@Nonnull @Nonnull
public ItemStack take(int slot, int limit, @Nonnull ItemStack filter, boolean simulate) { public ItemStack take(int slot, int limit, @Nonnull ItemStack filter, boolean simulate) {
@@ -203,6 +212,15 @@ public interface ItemStorage {
return this.size; return this.size;
} }
@Override
@Nonnull
public ItemStack getStack(int slot) {
if (slot < this.start || slot >= this.start + this.size) {
return ItemStack.EMPTY;
}
return this.parent.getStack(slot - this.start );
}
@Nonnull @Nonnull
@Override @Override
public ItemStack take(int slot, int limit, @Nonnull ItemStack filter, boolean simulate) { public ItemStack take(int slot, int limit, @Nonnull ItemStack filter, boolean simulate) {