mirror of
https://github.com/XevianLight/Aphelion.git
synced 2026-05-11 01:50:56 +01:00
technically works, but needs visuals on attachments and a lot of organization
This commit is contained in:
@@ -1,9 +1,15 @@
|
|||||||
package net.xevianlight.aphelion.block.custom;
|
package net.xevianlight.aphelion.block.custom;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.kinds.Const;
|
||||||
|
import com.mojang.math.Constants;
|
||||||
import com.mojang.serialization.MapCodec;
|
import com.mojang.serialization.MapCodec;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.ItemInteractionResult;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||||
import net.minecraft.world.level.BlockGetter;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
@@ -15,13 +21,14 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||||||
import net.minecraft.world.level.block.state.StateDefinition;
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||||
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraft.world.phys.shapes.BooleanOp;
|
import net.minecraft.world.phys.shapes.BooleanOp;
|
||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
import net.minecraft.world.phys.shapes.Shapes;
|
import net.minecraft.world.phys.shapes.Shapes;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||||
import net.xevianlight.aphelion.block.custom.base.BasicEntityBlock;
|
import net.xevianlight.aphelion.block.custom.base.BasicEntityBlock;
|
||||||
import net.xevianlight.aphelion.block.entity.custom.OxygenTestBlockEntity;
|
|
||||||
import net.xevianlight.aphelion.block.entity.custom.PipeTestBlockEntity;
|
import net.xevianlight.aphelion.block.entity.custom.PipeTestBlockEntity;
|
||||||
import net.xevianlight.aphelion.core.init.ModBlocks;
|
import net.xevianlight.aphelion.core.init.ModBlocks;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -93,14 +100,24 @@ public class PipeTestBlock extends BasicEntityBlock {
|
|||||||
return Properties.of().noOcclusion();
|
return Properties.of().noOcclusion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasAttachment(@Nullable PipeTestBlockEntity BE, Direction direction) {
|
||||||
|
return (BE != null && BE.hasAttachment(direction));
|
||||||
|
}
|
||||||
|
|
||||||
private BlockState makeConnections(LevelAccessor level, BlockPos pos) {
|
private BlockState makeConnections(LevelAccessor level, BlockPos pos) {
|
||||||
|
BlockEntity BE = level.getBlockEntity(pos);
|
||||||
|
PipeTestBlockEntity PTBE = null;
|
||||||
|
if (BE instanceof PipeTestBlockEntity found) {
|
||||||
|
PTBE = found;
|
||||||
|
}
|
||||||
|
|
||||||
return this.defaultBlockState()
|
return this.defaultBlockState()
|
||||||
.setValue(NORTH, canConnect(level, pos.north(), Direction.SOUTH))
|
.setValue(NORTH, canConnect(level, pos.north(), Direction.SOUTH) || hasAttachment(PTBE, Direction.NORTH))
|
||||||
.setValue(SOUTH, canConnect(level, pos.south(), Direction.NORTH))
|
.setValue(SOUTH, canConnect(level, pos.south(), Direction.NORTH) || hasAttachment(PTBE, Direction.SOUTH))
|
||||||
.setValue(EAST, canConnect(level, pos.east(), Direction.WEST))
|
.setValue(EAST, canConnect(level, pos.east(), Direction.WEST) || hasAttachment(PTBE, Direction.EAST))
|
||||||
.setValue(WEST, canConnect(level, pos.west(), Direction.EAST))
|
.setValue(WEST, canConnect(level, pos.west(), Direction.EAST) || hasAttachment(PTBE, Direction.WEST))
|
||||||
.setValue(UP, canConnect(level, pos.above(), Direction.DOWN))
|
.setValue(UP, canConnect(level, pos.above(), Direction.DOWN) || hasAttachment(PTBE, Direction.UP))
|
||||||
.setValue(DOWN, canConnect(level, pos.below(), Direction.UP));
|
.setValue(DOWN, canConnect(level, pos.below(), Direction.UP) || hasAttachment(PTBE, Direction.DOWN));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If a PipeTestBlock can connect to this position from the given direction.
|
/// If a PipeTestBlock can connect to this position from the given direction.
|
||||||
@@ -130,6 +147,7 @@ public class PipeTestBlock extends BasicEntityBlock {
|
|||||||
// force everything connected to this pipe to reevaluate
|
// force everything connected to this pipe to reevaluate
|
||||||
if (pipe.graph != null) pipe.graph.invalidate();
|
if (pipe.graph != null) pipe.graph.invalidate();
|
||||||
}
|
}
|
||||||
|
super.onRemove(state, level, pos, newState, isMoving);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -137,6 +155,22 @@ public class PipeTestBlock extends BasicEntityBlock {
|
|||||||
builder.add(NORTH, SOUTH, EAST, WEST, UP, DOWN);
|
builder.add(NORTH, SOUTH, EAST, WEST, UP, DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) {
|
||||||
|
|
||||||
|
BlockEntity BE = level.getBlockEntity(pos);
|
||||||
|
if (BE instanceof PipeTestBlockEntity PTBE) {
|
||||||
|
ItemInteractionResult r = PTBE.useItemOn(stack, state, level, pos, player, hand, hitResult, this);
|
||||||
|
|
||||||
|
BlockState newState = makeConnections(level, pos);
|
||||||
|
level.setBlock(pos, newState, 3);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
} else {
|
||||||
|
return super.useItemOn(stack, state, level, pos, player, hand, hitResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Doesn't block sunlight
|
// Doesn't block sunlight
|
||||||
// @Override
|
// @Override
|
||||||
// public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) {
|
// public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) {
|
||||||
|
|||||||
@@ -1,33 +1,41 @@
|
|||||||
package net.xevianlight.aphelion.block.entity.custom;
|
package net.xevianlight.aphelion.block.entity.custom;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayFIFOQueue;
|
|
||||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.ItemInteractionResult;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
|
||||||
import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.neoforged.fml.common.Mod;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import net.neoforged.neoforge.capabilities.BlockCapability;
|
||||||
|
import net.neoforged.neoforge.capabilities.BlockCapabilityCache;
|
||||||
|
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||||
|
import net.neoforged.neoforge.items.IItemHandler;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import net.xevianlight.aphelion.block.custom.PipeTestBlock;
|
import net.xevianlight.aphelion.block.custom.PipeTestBlock;
|
||||||
import net.xevianlight.aphelion.block.custom.base.TickableBlockEntity;
|
import net.xevianlight.aphelion.block.custom.base.TickableBlockEntity;
|
||||||
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
||||||
import net.xevianlight.aphelion.core.init.ModBlocks;
|
import net.xevianlight.aphelion.core.init.ModBlocks;
|
||||||
import net.xevianlight.aphelion.util.FloodFill3D;
|
import net.xevianlight.aphelion.util.FloodFill3D;
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
// TODO: Rearrange this WHOOLE fucking thing into like, 10 different files for the actual pipes
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class PipeTestBlockEntity extends BlockEntity implements TickableBlockEntity {
|
public class PipeTestBlockEntity extends BlockEntity implements TickableBlockEntity {
|
||||||
|
public @Nullable PipeGraph graph = null;
|
||||||
|
public final Map<Direction, @Nullable PipeAttachment> attachments = new HashMap<>();
|
||||||
|
public final Map<Direction, @Nullable PipeOutput> outputs = new HashMap<>();
|
||||||
|
|
||||||
public PipeTestBlockEntity(BlockPos pos, BlockState blockState) {
|
public PipeTestBlockEntity(BlockPos pos, BlockState blockState) {
|
||||||
super(ModBlockEntities.PIPE_TEST_BLOCK_ENTITY.get(), pos, blockState);
|
super(ModBlockEntities.PIPE_TEST_BLOCK_ENTITY.get(), pos, blockState);
|
||||||
}
|
}
|
||||||
@@ -40,6 +48,15 @@ public class PipeTestBlockEntity extends BlockEntity implements TickableBlockEnt
|
|||||||
@Override
|
@Override
|
||||||
public void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos) {
|
public void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos) {
|
||||||
if (this.graph == null) initGraph(level, pos);
|
if (this.graph == null) initGraph(level, pos);
|
||||||
|
// TODO: Call this as little as necessary
|
||||||
|
makeOutputs(level, state, pos);
|
||||||
|
|
||||||
|
for (Direction dir : Direction.values()) {
|
||||||
|
PipeAttachment attachment = attachments.get(dir);
|
||||||
|
if (attachment != null) {
|
||||||
|
attachment.tick(level, state, pos, dir, graph);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -47,12 +64,43 @@ public class PipeTestBlockEntity extends BlockEntity implements TickableBlockEnt
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: move all this somewhere else
|
private void addOutput(Direction dir, PipeOutput output) {
|
||||||
|
outputs.put(dir, output);
|
||||||
|
if (graph != null) graph.outputs.add(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeOutput(Direction dir) {
|
||||||
|
PipeOutput old = outputs.get(dir);
|
||||||
|
if (graph != null) graph.outputs.remove(old);
|
||||||
|
outputs.remove(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canOutputTo(Level level, BlockPos pos, Direction accessSide) {
|
||||||
|
return level.getCapability(Capabilities.ItemHandler.BLOCK, pos, accessSide) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void makeOutputs(ServerLevel level, BlockState state, BlockPos pos) {
|
||||||
|
BlockPos.MutableBlockPos neighbor = new BlockPos.MutableBlockPos();
|
||||||
|
for (Direction dir : Direction.values()) {
|
||||||
|
neighbor.setWithOffset(pos, dir);
|
||||||
|
|
||||||
|
if (canOutputTo(level, neighbor, dir.getOpposite()) && attachments.get(dir) == null && outputs.get(dir) == null) {
|
||||||
|
addOutput(dir, new BasicItemOutput(level, pos, dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(canOutputTo(level, neighbor, dir.getOpposite()) && attachments.get(dir) == null) && outputs.get(dir) != null) {
|
||||||
|
removeOutput(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: move all these classes somewhere else
|
||||||
public interface PipeInput {
|
public interface PipeInput {
|
||||||
void tick(Level level, BlockState state, BlockPos pos, Direction facingDirection);
|
void tick(ServerLevel level, BlockState state, BlockPos pos, Direction facingDirection, PipeGraph graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface PipeOutput {
|
public interface PipeOutput {
|
||||||
|
/// @return Rejected items
|
||||||
ItemStack insertItem(ItemStack stack, boolean simulate);
|
ItemStack insertItem(ItemStack stack, boolean simulate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,27 +119,46 @@ public class PipeTestBlockEntity extends BlockEntity implements TickableBlockEnt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addPipe(PipeTestBlockEntity pipe) {
|
public void addPipe(PipeTestBlockEntity pipe) {
|
||||||
//TODO: add outputs the pipe has already if applicable
|
|
||||||
pipes.add(pipe);
|
pipes.add(pipe);
|
||||||
pipe.graph = this;
|
pipe.graph = this;
|
||||||
|
for (PipeOutput output : pipe.outputs.values()) {
|
||||||
|
if (output != null) this.outputs.add(output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called whenever a pipe is removed from a graph, or when a new graph comes across an old one.
|
/// Called whenever a pipe is removed from a graph, or when a new graph comes across an old one.
|
||||||
public void invalidate() {
|
public void invalidate() {
|
||||||
for (PipeTestBlockEntity pipe : pipes) {
|
for (PipeTestBlockEntity pipe : pipes) {
|
||||||
pipe.graph = null;
|
pipe.graph = null;
|
||||||
|
for (PipeOutput output : pipe.outputs.values()) {
|
||||||
|
if (output != null) this.outputs.remove(output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.isInvalid = true;
|
this.isInvalid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable PipeGraph graph = null;
|
public static abstract class PipeAttachment {
|
||||||
|
PipeAttachment(ServerLevel level, BlockPos pos, Direction facingDirection) {}
|
||||||
|
|
||||||
|
//TODO: put in the right interface for a render function
|
||||||
|
void render() {};
|
||||||
|
|
||||||
|
public void tick(ServerLevel level, BlockState state, BlockPos pos, Direction facingDirection, PipeGraph graph) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasAttachment(Direction direction) {
|
||||||
|
return attachments.get(direction) != null;
|
||||||
|
}
|
||||||
|
|
||||||
// Simplest implementation I can think of
|
// Simplest implementation I can think of
|
||||||
public static void initGraph(Level level, BlockPos pos) {
|
public static void initGraph(Level level, BlockPos pos) {
|
||||||
Aphelion.LOGGER.info("Init graph from {}", pos);
|
Aphelion.LOGGER.info("Init graph from {}", pos);
|
||||||
if (!level.getBlockState(pos).is(ModBlocks.PIPE_TEST_BLOCK.get())) return;
|
if (!level.getBlockState(pos).is(ModBlocks.PIPE_TEST_BLOCK.get())) return;
|
||||||
Set<BlockPos> pipes = FloodFill3D.run(level, pos, 1000, (var v1, var v2, var state, var v4, var v5, var v6) -> state.is(ModBlocks.PIPE_TEST_BLOCK.get()), false);
|
Set<BlockPos> pipes = FloodFill3D.run(
|
||||||
|
level, pos, 1000,
|
||||||
|
(var v1, var v2, var state, var v4, var v5, var v6) -> state.is(ModBlocks.PIPE_TEST_BLOCK.get()),
|
||||||
|
false);
|
||||||
|
|
||||||
Aphelion.LOGGER.info("Got {} pipes", pipes.size());
|
Aphelion.LOGGER.info("Got {} pipes", pipes.size());
|
||||||
PipeGraph graph = new PipeGraph();
|
PipeGraph graph = new PipeGraph();
|
||||||
@@ -107,4 +174,119 @@ public class PipeTestBlockEntity extends BlockEntity implements TickableBlockEnt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAttachment(Direction side, PipeAttachment attachment) {
|
||||||
|
attachments.put(side, attachment);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean trySetAttachment(Direction side, PipeAttachment attachment) {
|
||||||
|
if (hasAttachment(side)) return false;
|
||||||
|
setAttachment(side, attachment);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAttachmentItem(ItemStack stack) {
|
||||||
|
//TODO: add actual attachment items instead of just stone
|
||||||
|
return stack.is(Item.byId(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BasicItemExtractAttachment extends PipeAttachment implements PipeInput {
|
||||||
|
|
||||||
|
BlockCapabilityCache<IItemHandler, @Nullable Direction> capabilityCache;
|
||||||
|
|
||||||
|
BasicItemExtractAttachment(ServerLevel level, BlockPos pos, Direction facingDirection) {
|
||||||
|
super(level, pos, facingDirection);
|
||||||
|
|
||||||
|
capabilityCache = BlockCapabilityCache.create(
|
||||||
|
Capabilities.ItemHandler.BLOCK,
|
||||||
|
level,
|
||||||
|
pos.relative(facingDirection),
|
||||||
|
facingDirection.getOpposite()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(ServerLevel level, BlockState state, BlockPos pos, Direction facingDirection, PipeGraph graph) {
|
||||||
|
// do an extract and distribute
|
||||||
|
IItemHandler container = capabilityCache.getCapability();
|
||||||
|
if (container == null) return;
|
||||||
|
|
||||||
|
final int EXTRACT_PER_TICK = 4;
|
||||||
|
int to_extract = EXTRACT_PER_TICK;
|
||||||
|
|
||||||
|
int extract_slot_id = container.getSlots() - 1;
|
||||||
|
while (extract_slot_id >= 0 && container.getStackInSlot(extract_slot_id).isEmpty()) extract_slot_id--;
|
||||||
|
if (extract_slot_id == -1) return;
|
||||||
|
|
||||||
|
|
||||||
|
// Do a simulated extract, then run through every output side on the graph and do real inserts.
|
||||||
|
// By the end, remove as many items as we successfully inserted with a real extract
|
||||||
|
ItemStack to_distribute = container.extractItem(extract_slot_id, to_extract, true);
|
||||||
|
int extracted_amount = to_distribute.getCount();
|
||||||
|
|
||||||
|
to_distribute = graph.insertItem(to_distribute, false);
|
||||||
|
|
||||||
|
int distributed_amount = extracted_amount;
|
||||||
|
if (!to_distribute.isEmpty()) {
|
||||||
|
distributed_amount = extracted_amount - to_distribute.getCount();
|
||||||
|
}
|
||||||
|
container.extractItem(extract_slot_id, distributed_amount, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BasicItemOutput implements PipeOutput {
|
||||||
|
|
||||||
|
BlockCapabilityCache<IItemHandler, @Nullable Direction> capabilityCache;
|
||||||
|
|
||||||
|
BasicItemOutput(ServerLevel level, BlockPos pos, Direction facingDirection) {
|
||||||
|
capabilityCache = BlockCapabilityCache.create(
|
||||||
|
Capabilities.ItemHandler.BLOCK,
|
||||||
|
level,
|
||||||
|
pos.relative(facingDirection),
|
||||||
|
facingDirection.getOpposite()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack insertItem(ItemStack stack, boolean simulate) {
|
||||||
|
ItemStack toInsert = stack.copy();
|
||||||
|
|
||||||
|
IItemHandler container = capabilityCache.getCapability();
|
||||||
|
if (container == null) return toInsert;
|
||||||
|
|
||||||
|
for (int insertIndex = 0; insertIndex < container.getSlots(); insertIndex++) {
|
||||||
|
if (toInsert.isEmpty()) break;
|
||||||
|
|
||||||
|
toInsert = container.insertItem(insertIndex, toInsert, simulate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return toInsert;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server only
|
||||||
|
public PipeAttachment getAttachmentForItem(ItemStack stack, Direction side) {
|
||||||
|
if (level.isClientSide()) throw new RuntimeException("Cannot get attachment item on client side!");
|
||||||
|
return new BasicItemExtractAttachment((ServerLevel) level, getBlockPos(), side);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called from pipe test block's useItemOn
|
||||||
|
public ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult, PipeTestBlock block) {
|
||||||
|
if (level.isClientSide) return ItemInteractionResult.SUCCESS;
|
||||||
|
Vec3 relativePos = hitResult.getLocation().subtract(pos.getCenter());
|
||||||
|
Direction pipeSide = Direction.getNearest(relativePos);
|
||||||
|
|
||||||
|
if (isAttachmentItem(stack)) {
|
||||||
|
boolean success = trySetAttachment(pipeSide, getAttachmentForItem(stack, pipeSide));
|
||||||
|
|
||||||
|
return success ? ItemInteractionResult.SUCCESS : ItemInteractionResult.FAIL;
|
||||||
|
} else {
|
||||||
|
return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; // goes through with whatever other interaction (placing a block, etc)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user