made IPipeConnectable a capability

This commit is contained in:
Ell 2020-10-17 14:29:37 +02:00
parent 5cda7beca7
commit 4ff3ac6851
12 changed files with 131 additions and 107 deletions

View file

@ -90,6 +90,8 @@ public final class Registry {
@CapabilityInject(PipeNetwork.class)
public static Capability<PipeNetwork> pipeNetworkCapability;
@CapabilityInject(IPipeConnectable.class)
public static Capability<IPipeConnectable> pipeConnectableCapability;
public static Item wrenchItem;
public static Item pipeFrameItem;
@ -203,18 +205,8 @@ public final class Registry {
}
public static void setup(FMLCommonSetupEvent event) {
CapabilityManager.INSTANCE.register(PipeNetwork.class, new Capability.IStorage<PipeNetwork>() {
@Nullable
@Override
public INBT writeNBT(Capability<PipeNetwork> capability, PipeNetwork instance, Direction side) {
return null;
}
@Override
public void readNBT(Capability<PipeNetwork> capability, PipeNetwork instance, Direction side, INBT nbt) {
}
}, () -> null);
registerCap(PipeNetwork.class);
registerCap(IPipeConnectable.class);
PacketHandler.setup();
}
@ -236,4 +228,19 @@ public final class Registry {
ScreenManager.registerFactory(craftingModuleContainer, CraftingModuleGui::new);
}
}
private static <T> void registerCap(Class<T> capClass) {
CapabilityManager.INSTANCE.register(capClass, new Capability.IStorage<T>() {
@Nullable
@Override
public INBT writeNBT(Capability<T> capability, T instance, Direction side) {
return null;
}
@Override
public void readNBT(Capability<T> capability, T instance, Direction side, INBT nbt) {
}
}, () -> null);
}
}

View file

@ -212,7 +212,7 @@ public class PipeItem implements INBTSerializable<CompoundNBT> {
Direction dir = Utility.getDirectionFromOffset(this.destInventory, this.getDestPipe());
IPipeConnectable connectable = currPipe.getPipeConnectable(dir);
if (connectable != null)
return connectable.insertItem(currPipe.getWorld(), currPipe.getPos(), dir, this.stack, false);
return connectable.insertItem(currPipe.getPos(), dir, this.stack, false);
IItemHandler handler = currPipe.getItemHandler(dir);
if (handler != null)
return ItemHandlerHelper.insertItemStacked(handler, this.stack, false);

View file

@ -1,22 +1,18 @@
package de.ellpeck.prettypipes.pipe;
import de.ellpeck.prettypipes.network.PipeItem;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
public interface IPipeConnectable {
ConnectionType getConnectionType(World world, BlockPos pipePos, Direction direction);
ConnectionType getConnectionType(BlockPos pipePos, Direction direction);
default ItemStack insertItem(World world, BlockPos pipePos, Direction direction, ItemStack stack, boolean simulate) {
default ItemStack insertItem(BlockPos pipePos, Direction direction, ItemStack stack, boolean simulate) {
return stack;
}
default boolean allowsModules(World world, BlockPos pipePos, Direction direction) {
default boolean allowsModules(BlockPos pipePos, Direction direction) {
return false;
}
}

View file

@ -1,6 +1,7 @@
package de.ellpeck.prettypipes.pipe;
import com.google.common.collect.ImmutableMap;
import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.network.PipeItem;
@ -41,7 +42,7 @@ import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
public class PipeBlock extends ContainerBlock implements IPipeConnectable {
public class PipeBlock extends ContainerBlock {
public static final Map<Direction, EnumProperty<ConnectionType>> DIRECTIONS = new HashMap<>();
private static final Map<Pair<BlockState, BlockState>, VoxelShape> SHAPE_CACHE = new HashMap<>();
@ -180,16 +181,16 @@ public class PipeBlock extends ContainerBlock implements IPipeConnectable {
BlockPos offset = pos.offset(direction);
if (!world.isBlockLoaded(offset))
return ConnectionType.DISCONNECTED;
BlockState offState = world.getBlockState(offset);
Block block = offState.getBlock();
if (block instanceof IPipeConnectable)
return ((IPipeConnectable) block).getConnectionType(world, pos, direction);
TileEntity tile = world.getTileEntity(offset);
if (tile != null) {
IPipeConnectable connectable = tile.getCapability(Registry.pipeConnectableCapability, direction.getOpposite()).orElse(null);
if (connectable != null)
return connectable.getConnectionType(pos, direction);
IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, direction.getOpposite()).orElse(null);
if (handler != null)
return ConnectionType.CONNECTED;
}
BlockState offState = world.getBlockState(offset);
if (hasLegsTo(world, offState, offset, direction)) {
if (DIRECTIONS.values().stream().noneMatch(d -> state.get(d) == ConnectionType.LEGS))
return ConnectionType.LEGS;
@ -273,12 +274,4 @@ public class PipeBlock extends ContainerBlock implements IPipeConnectable {
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.MODEL;
}
@Override
public ConnectionType getConnectionType(World world, BlockPos pipePos, Direction direction) {
BlockState state = world.getBlockState(pipePos.offset(direction));
if (state.get(DIRECTIONS.get(direction.getOpposite())) == ConnectionType.BLOCKED)
return ConnectionType.BLOCKED;
return ConnectionType.CONNECTED;
}
}

View file

@ -35,9 +35,12 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
@ -53,7 +56,7 @@ import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class PipeTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity {
public class PipeTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity, IPipeConnectable {
public final ItemStackHandler modules = new ItemStackHandler(3) {
@Override
@ -316,9 +319,9 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
}
public IPipeConnectable getPipeConnectable(Direction dir) {
BlockState state = this.world.getBlockState(this.pos.offset(dir));
if (state.getBlock() instanceof IPipeConnectable)
return (IPipeConnectable) state.getBlock();
TileEntity tile = this.world.getTileEntity(this.pos.offset(dir));
if (tile != null)
return tile.getCapability(Registry.pipeConnectableCapability, dir.getOpposite()).orElse(null);
return null;
}
@ -331,7 +334,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
if (this.isConnectedInventory(dir))
return true;
IPipeConnectable connectable = this.getPipeConnectable(dir);
if (connectable != null && connectable.allowsModules(this.world, this.pos, dir))
if (connectable != null && connectable.allowsModules(this.pos, dir))
return true;
}
return false;
@ -378,4 +381,19 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
// our render bounding box should always be the full block in case we're covered
return new AxisAlignedBB(this.pos);
}
@Override
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
if (cap == Registry.pipeConnectableCapability)
return LazyOptional.of(() -> (T) this);
return LazyOptional.empty();
}
@Override
public ConnectionType getConnectionType(BlockPos pipePos, Direction direction) {
BlockState state = this.world.getBlockState(pipePos.offset(direction));
if (state.get(PipeBlock.DIRECTIONS.get(direction.getOpposite())) == ConnectionType.BLOCKED)
return ConnectionType.BLOCKED;
return ConnectionType.CONNECTED;
}
}

View file

@ -84,7 +84,7 @@ public class CraftingModuleItem extends ModuleItem {
ItemEqualityType[] equalityTypes = ItemFilter.getEqualityTypes(tile);
Pair<BlockPos, ItemStack> dest = tile.getAvailableDestination(request.stack, true, true);
if (dest != null) {
ItemStack requestRemain = network.requestExistingItem(request.location, tile.getPos(), dest.getLeft(), request, dest.getRight(),equalityTypes);
ItemStack requestRemain = network.requestExistingItem(request.location, tile.getPos(), dest.getLeft(), request, dest.getRight(), equalityTypes);
network.resolveNetworkLock(request);
tile.craftIngredientRequests.remove();
@ -115,7 +115,7 @@ public class CraftingModuleItem extends ModuleItem {
IPipeConnectable connectable = destPipe.getPipeConnectable(dir);
if (connectable == null)
continue;
ItemStack connectableRemain = connectable.insertItem(tile.getWorld(), destPipe.getPos(), dir, remain, true);
ItemStack connectableRemain = connectable.insertItem(destPipe.getPos(), dir, remain, true);
if (connectableRemain.getCount() != remain.getCount()) {
ItemStack inserted = remain.copy();
inserted.shrink(connectableRemain.getCount());

View file

@ -27,7 +27,7 @@ import net.minecraftforge.fml.network.NetworkHooks;
import javax.annotation.Nullable;
import java.util.List;
public class PressurizerBlock extends ContainerBlock implements IPipeConnectable {
public class PressurizerBlock extends ContainerBlock {
public PressurizerBlock() {
super(Properties.create(Material.ROCK).hardnessAndResistance(3).sound(SoundType.STONE));
}
@ -42,11 +42,6 @@ public class PressurizerBlock extends ContainerBlock implements IPipeConnectable
return ActionResultType.SUCCESS;
}
@Override
public ConnectionType getConnectionType(World world, BlockPos pipePos, Direction direction) {
return ConnectionType.CONNECTED;
}
@Override
public TileEntity createNewTileEntity(IBlockReader worldIn) {
return new PressurizerTileEntity();

View file

@ -4,6 +4,8 @@ import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.network.PipeNetwork;
import de.ellpeck.prettypipes.pipe.ConnectionType;
import de.ellpeck.prettypipes.pipe.IPipeConnectable;
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.terminal.containers.ItemTerminalContainer;
import net.minecraft.block.BlockState;
@ -22,6 +24,7 @@ import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
@ -30,7 +33,7 @@ import net.minecraftforge.energy.IEnergyStorage;
import javax.annotation.Nullable;
public class PressurizerTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity {
public class PressurizerTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity, IPipeConnectable {
private final ModifiableEnergyStorage storage = new ModifiableEnergyStorage(64000, 512, 0);
private int lastEnergy;
@ -98,6 +101,8 @@ public class PressurizerTileEntity extends TileEntity implements INamedContainer
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
if (cap == CapabilityEnergy.ENERGY) {
return LazyOptional.of(() -> (T) this.storage);
} else if (cap == Registry.pipeConnectableCapability) {
return LazyOptional.of(() -> (T) this);
} else {
return LazyOptional.empty();
}
@ -127,6 +132,11 @@ public class PressurizerTileEntity extends TileEntity implements INamedContainer
}
}
@Override
public ConnectionType getConnectionType(BlockPos pipePos, Direction direction) {
return ConnectionType.CONNECTED;
}
private static class ModifiableEnergyStorage extends EnergyStorage {
public ModifiableEnergyStorage(int capacity, int maxReceive, int maxExtract) {

View file

@ -1,16 +1,7 @@
package de.ellpeck.prettypipes.terminal;
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.misc.ItemEqualityType;
import de.ellpeck.prettypipes.network.PipeItem;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
import javax.annotation.Nullable;
@ -22,34 +13,4 @@ public class CraftingTerminalBlock extends ItemTerminalBlock {
return new CraftingTerminalTileEntity();
}
@Override
public ItemStack insertItem(World world, BlockPos pipePos, Direction direction, ItemStack remain, boolean simulate) {
BlockPos pos = pipePos.offset(direction);
CraftingTerminalTileEntity tile = Utility.getTileEntity(CraftingTerminalTileEntity.class, world, pos);
if (tile != null) {
remain = remain.copy();
int lowestSlot = -1;
do {
for (int i = 0; i < tile.craftItems.getSlots(); i++) {
ItemStack stack = tile.getRequestedCraftItem(i);
int count = tile.isGhostItem(i) ? 0 : stack.getCount();
if (!ItemHandlerHelper.canItemStacksStackRelaxed(stack, remain))
continue;
if (lowestSlot < 0 || !tile.isGhostItem(lowestSlot) && count < tile.getRequestedCraftItem(lowestSlot).getCount())
lowestSlot = i;
}
if (lowestSlot >= 0) {
ItemStack copy = remain.copy();
copy.setCount(1);
remain.shrink(1 - tile.craftItems.insertItem(lowestSlot, copy, simulate).getCount());
if (remain.isEmpty())
return ItemStack.EMPTY;
}
}
while (lowestSlot >= 0);
return ItemHandlerHelper.insertItemStacked(tile.items, remain, simulate);
}
return remain;
}
}

View file

@ -4,6 +4,7 @@ import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.misc.EquatableItemStack;
import de.ellpeck.prettypipes.misc.ItemEqualityType;
import de.ellpeck.prettypipes.network.NetworkItem;
@ -21,6 +22,7 @@ import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.Style;
@ -153,6 +155,36 @@ public class CraftingTerminalTileEntity extends ItemTerminalTileEntity {
return new CraftingTerminalContainer(Registry.craftingTerminalContainer, window, player, this.pos);
}
@Override
public ItemStack insertItem(BlockPos pipePos, Direction direction, ItemStack remain, boolean simulate) {
BlockPos pos = pipePos.offset(direction);
CraftingTerminalTileEntity tile = Utility.getTileEntity(CraftingTerminalTileEntity.class, this.world, pos);
if (tile != null) {
remain = remain.copy();
int lowestSlot = -1;
do {
for (int i = 0; i < tile.craftItems.getSlots(); i++) {
ItemStack stack = tile.getRequestedCraftItem(i);
int count = tile.isGhostItem(i) ? 0 : stack.getCount();
if (!ItemHandlerHelper.canItemStacksStackRelaxed(stack, remain))
continue;
if (lowestSlot < 0 || !tile.isGhostItem(lowestSlot) && count < tile.getRequestedCraftItem(lowestSlot).getCount())
lowestSlot = i;
}
if (lowestSlot >= 0) {
ItemStack copy = remain.copy();
copy.setCount(1);
remain.shrink(1 - tile.craftItems.insertItem(lowestSlot, copy, simulate).getCount());
if (remain.isEmpty())
return ItemStack.EMPTY;
}
}
while (lowestSlot >= 0);
return ItemHandlerHelper.insertItemStacked(tile.items, remain, simulate);
}
return remain;
}
public static int getAvailableCrafts(PipeTileEntity tile, int slots, Function<Integer, ItemStack> inputFunction, Predicate<Integer> isGhost, Function<EquatableItemStack, Collection<NetworkLocation>> locationsFunction, Consumer<ItemStack> unavailableConsumer, ItemEqualityType... equalityTypes) {
PipeNetwork network = PipeNetwork.get(tile.getWorld());
// the highest amount we can craft with the items we have

View file

@ -30,7 +30,7 @@ import net.minecraftforge.items.ItemHandlerHelper;
import javax.annotation.Nullable;
import java.util.List;
public class ItemTerminalBlock extends ContainerBlock implements IPipeConnectable {
public class ItemTerminalBlock extends ContainerBlock {
public ItemTerminalBlock() {
super(Properties.create(Material.ROCK).hardnessAndResistance(3).sound(SoundType.STONE));
}
@ -63,25 +63,6 @@ public class ItemTerminalBlock extends ContainerBlock implements IPipeConnectabl
return new ItemTerminalTileEntity();
}
@Override
public ConnectionType getConnectionType(World world, BlockPos pipePos, Direction direction) {
return ConnectionType.CONNECTED;
}
@Override
public ItemStack insertItem(World world, BlockPos pipePos, Direction direction, ItemStack stack, boolean simulate) {
BlockPos pos = pipePos.offset(direction);
ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, world, pos);
if (tile != null)
return ItemHandlerHelper.insertItemStacked(tile.items, stack, simulate);
return stack;
}
@Override
public boolean allowsModules(World world, BlockPos pipePos, Direction direction) {
return true;
}
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.MODEL;

View file

@ -9,6 +9,8 @@ import de.ellpeck.prettypipes.misc.ItemOrder;
import de.ellpeck.prettypipes.network.*;
import de.ellpeck.prettypipes.packets.PacketHandler;
import de.ellpeck.prettypipes.packets.PacketNetworkItems;
import de.ellpeck.prettypipes.pipe.ConnectionType;
import de.ellpeck.prettypipes.pipe.IPipeConnectable;
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.terminal.containers.ItemTerminalContainer;
import net.minecraft.block.BlockState;
@ -30,9 +32,12 @@ import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler;
import org.apache.commons.lang3.mutable.MutableInt;
import org.apache.commons.lang3.tuple.Pair;
@ -45,7 +50,7 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
public class ItemTerminalTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity {
public class ItemTerminalTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity, IPipeConnectable {
public final ItemStackHandler items = new ItemStackHandler(12) {
@Override
@ -209,6 +214,32 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
return new ItemTerminalContainer(Registry.itemTerminalContainer, window, player, this.pos);
}
@Override
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
if (cap == Registry.pipeConnectableCapability)
return LazyOptional.of(() -> (T) this);
return LazyOptional.empty();
}
@Override
public ConnectionType getConnectionType(BlockPos pipePos, Direction direction) {
return ConnectionType.CONNECTED;
}
@Override
public ItemStack insertItem(BlockPos pipePos, Direction direction, ItemStack stack, boolean simulate) {
BlockPos pos = pipePos.offset(direction);
ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, world, pos);
if (tile != null)
return ItemHandlerHelper.insertItemStacked(tile.items, stack, simulate);
return stack;
}
@Override
public boolean allowsModules(BlockPos pipePos, Direction direction) {
return true;
}
public static Pair<List<NetworkLock>, ItemStack> requestItemLater(World world, BlockPos destPipe, Collection<NetworkLocation> locations, Consumer<ItemStack> unavailableConsumer, ItemStack stack, ItemEqualityType... equalityTypes) {
List<NetworkLock> requests = new ArrayList<>();
ItemStack remain = stack.copy();