mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-01-27 13:28:00 +01:00
Types of points
- Refactor the ArmInteractionPoint system - ArmInteractionPointTypes are now used instead of instances - Point types can now have a priority that determines the primary type at a certain location - Points can now deserialize arbitrary data - Points' cached BlockState is now updated before it is used - Points now store the Level directly - Default types are now registered in AllArmInteractionPointTypes - Add point types for campfires and respawn anchors - Fix arms being able to insert any item into composters - Delete unused flag models and texture - Make all BehaviorType instances final
This commit is contained in:
parent
3d5af741af
commit
d8dd101fdf
24 changed files with 942 additions and 643 deletions
|
@ -89,9 +89,6 @@ public class AllBlockPartials {
|
||||||
ARM_HEAD = block("mechanical_arm/head"), ARM_CLAW_BASE = block("mechanical_arm/claw_base"),
|
ARM_HEAD = block("mechanical_arm/head"), ARM_CLAW_BASE = block("mechanical_arm/claw_base"),
|
||||||
ARM_CLAW_GRIP = block("mechanical_arm/claw_grip"),
|
ARM_CLAW_GRIP = block("mechanical_arm/claw_grip"),
|
||||||
|
|
||||||
FLAG_SHORT_IN = block("mechanical_arm/flag/short_in"), FLAG_SHORT_OUT = block("mechanical_arm/flag/short_out"),
|
|
||||||
FLAG_LONG_IN = block("mechanical_arm/flag/long_in"), FLAG_LONG_OUT = block("mechanical_arm/flag/long_out"),
|
|
||||||
|
|
||||||
MECHANICAL_PUMP_ARROW = block("mechanical_pump/arrow"), MECHANICAL_PUMP_COG = block("mechanical_pump/cog"),
|
MECHANICAL_PUMP_ARROW = block("mechanical_pump/arrow"), MECHANICAL_PUMP_COG = block("mechanical_pump/cog"),
|
||||||
FLUID_PIPE_CASING = block("fluid_pipe/casing"), FLUID_VALVE_POINTER = block("fluid_valve/pointer"),
|
FLUID_PIPE_CASING = block("fluid_pipe/casing"), FLUID_VALVE_POINTER = block("fluid_valve/pointer"),
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import com.simibubi.create.content.contraptions.TorquePropagator;
|
||||||
import com.simibubi.create.content.contraptions.components.flywheel.engine.FurnaceEngineInteractions;
|
import com.simibubi.create.content.contraptions.components.flywheel.engine.FurnaceEngineInteractions;
|
||||||
import com.simibubi.create.content.curiosities.weapons.BuiltinPotatoProjectileTypes;
|
import com.simibubi.create.content.curiosities.weapons.BuiltinPotatoProjectileTypes;
|
||||||
import com.simibubi.create.content.logistics.RedstoneLinkNetworkHandler;
|
import com.simibubi.create.content.logistics.RedstoneLinkNetworkHandler;
|
||||||
|
import com.simibubi.create.content.logistics.block.mechanicalArm.AllArmInteractionPointTypes;
|
||||||
import com.simibubi.create.content.palettes.AllPaletteBlocks;
|
import com.simibubi.create.content.palettes.AllPaletteBlocks;
|
||||||
import com.simibubi.create.content.palettes.PalettesItemGroup;
|
import com.simibubi.create.content.palettes.PalettesItemGroup;
|
||||||
import com.simibubi.create.content.schematics.SchematicProcessor;
|
import com.simibubi.create.content.schematics.SchematicProcessor;
|
||||||
|
@ -94,6 +95,7 @@ public class Create {
|
||||||
AllTileEntities.register();
|
AllTileEntities.register();
|
||||||
AllMovementBehaviours.register();
|
AllMovementBehaviours.register();
|
||||||
AllInteractionBehaviours.register();
|
AllInteractionBehaviours.register();
|
||||||
|
AllArmInteractionPointTypes.register();
|
||||||
AllWorldFeatures.register();
|
AllWorldFeatures.register();
|
||||||
AllEnchantments.register();
|
AllEnchantments.register();
|
||||||
AllConfigs.register(modLoadingContext);
|
AllConfigs.register(modLoadingContext);
|
||||||
|
|
|
@ -30,6 +30,8 @@ import net.minecraftforge.fluids.FluidStack;
|
||||||
|
|
||||||
public class FluidDrainingBehaviour extends FluidManipulationBehaviour {
|
public class FluidDrainingBehaviour extends FluidManipulationBehaviour {
|
||||||
|
|
||||||
|
public static final BehaviourType<FluidDrainingBehaviour> TYPE = new BehaviourType<>();
|
||||||
|
|
||||||
Fluid fluid;
|
Fluid fluid;
|
||||||
|
|
||||||
// Execution
|
// Execution
|
||||||
|
@ -322,8 +324,6 @@ public class FluidDrainingBehaviour extends FluidManipulationBehaviour {
|
||||||
tileEntity.sendData();
|
tileEntity.sendData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BehaviourType<FluidDrainingBehaviour> TYPE = new BehaviourType<>();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
|
|
|
@ -41,6 +41,8 @@ import net.minecraft.world.ticks.LevelTicks;
|
||||||
|
|
||||||
public class FluidFillingBehaviour extends FluidManipulationBehaviour {
|
public class FluidFillingBehaviour extends FluidManipulationBehaviour {
|
||||||
|
|
||||||
|
public static final BehaviourType<FluidFillingBehaviour> TYPE = new BehaviourType<>();
|
||||||
|
|
||||||
PriorityQueue<BlockPosEntry> queue;
|
PriorityQueue<BlockPosEntry> queue;
|
||||||
|
|
||||||
List<BlockPosEntry> infinityCheckFrontier;
|
List<BlockPosEntry> infinityCheckFrontier;
|
||||||
|
@ -298,8 +300,6 @@ public class FluidFillingBehaviour extends FluidManipulationBehaviour {
|
||||||
infinityCheckVisited.clear();
|
infinityCheckVisited.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BehaviourType<FluidFillingBehaviour> TYPE = new BehaviourType<>();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
|
|
|
@ -40,7 +40,7 @@ import net.minecraftforge.items.ItemStackHandler;
|
||||||
|
|
||||||
public class DepotBehaviour extends TileEntityBehaviour {
|
public class DepotBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
public static BehaviourType<DepotBehaviour> TYPE = new BehaviourType<>();
|
public static final BehaviourType<DepotBehaviour> TYPE = new BehaviourType<>();
|
||||||
|
|
||||||
TransportedItemStack heldItem;
|
TransportedItemStack heldItem;
|
||||||
List<TransportedItemStack> incoming;
|
List<TransportedItemStack> incoming;
|
||||||
|
|
|
@ -0,0 +1,689 @@
|
||||||
|
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllBlocks;
|
||||||
|
import com.simibubi.create.Create;
|
||||||
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
|
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterBlock;
|
||||||
|
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterTileEntity;
|
||||||
|
import com.simibubi.create.content.contraptions.components.deployer.DeployerBlock;
|
||||||
|
import com.simibubi.create.content.contraptions.components.saw.SawBlock;
|
||||||
|
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
||||||
|
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock;
|
||||||
|
import com.simibubi.create.content.logistics.block.chute.AbstractChuteBlock;
|
||||||
|
import com.simibubi.create.content.logistics.block.funnel.AbstractFunnelBlock;
|
||||||
|
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock;
|
||||||
|
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock.Shape;
|
||||||
|
import com.simibubi.create.content.logistics.block.funnel.FunnelBlock;
|
||||||
|
import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity;
|
||||||
|
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||||
|
import com.simibubi.create.foundation.item.SmartInventory;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.Containers;
|
||||||
|
import net.minecraft.world.InteractionResultHolder;
|
||||||
|
import net.minecraft.world.WorldlyContainer;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
|
import net.minecraft.world.item.RecordItem;
|
||||||
|
import net.minecraft.world.item.crafting.CampfireCookingRecipe;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.CampfireBlock;
|
||||||
|
import net.minecraft.world.level.block.ComposterBlock;
|
||||||
|
import net.minecraft.world.level.block.JukeboxBlock;
|
||||||
|
import net.minecraft.world.level.block.RespawnAnchorBlock;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.CampfireBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.JukeboxBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||||
|
import net.minecraftforge.items.wrapper.SidedInvWrapper;
|
||||||
|
|
||||||
|
public class AllArmInteractionPointTypes {
|
||||||
|
|
||||||
|
public static final BasinType BASIN = register("basin", BasinType::new);
|
||||||
|
public static final BeltType BELT = register("belt", BeltType::new);
|
||||||
|
public static final BlazeBurnerType BLAZE_BURNER = register("blaze_burner", BlazeBurnerType::new);
|
||||||
|
public static final ChuteType CHUTE = register("chute", ChuteType::new);
|
||||||
|
public static final CrafterType CRAFTER = register("crafter", CrafterType::new);
|
||||||
|
public static final CrushingWheelsType CRUSHING_WHEELS = register("crushing_wheels", CrushingWheelsType::new);
|
||||||
|
public static final DeployerType DEPLOYER = register("deployer", DeployerType::new);
|
||||||
|
public static final DepotType DEPOT = register("depot", DepotType::new);
|
||||||
|
public static final FunnelType FUNNEL = register("funnel", FunnelType::new);
|
||||||
|
public static final MillstoneType MILLSTONE = register("millstone", MillstoneType::new);
|
||||||
|
public static final SawType SAW = register("saw", SawType::new);
|
||||||
|
|
||||||
|
public static final CampfireType CAMPFIRE = register("campfire", CampfireType::new);
|
||||||
|
public static final ComposterType COMPOSTER = register("composter", ComposterType::new);
|
||||||
|
public static final JukeboxType JUKEBOX = register("jukebox", JukeboxType::new);
|
||||||
|
public static final RespawnAnchorType RESPAWN_ANCHOR = register("respawn_anchor", RespawnAnchorType::new);
|
||||||
|
|
||||||
|
private static <T extends ArmInteractionPointType> T register(String id, Function<ResourceLocation, T> factory) {
|
||||||
|
T type = factory.apply(Create.asResource(id));
|
||||||
|
ArmInteractionPointType.register(type);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register() {
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
public static class BasinType extends ArmInteractionPointType {
|
||||||
|
public BasinType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return AllBlocks.BASIN.has(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new ArmInteractionPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BeltType extends ArmInteractionPointType {
|
||||||
|
public BeltType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return AllBlocks.BELT.has(state) && !(level.getBlockState(pos.above())
|
||||||
|
.getBlock() instanceof BeltTunnelBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new BeltPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BlazeBurnerType extends ArmInteractionPointType {
|
||||||
|
public BlazeBurnerType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return AllBlocks.BLAZE_BURNER.has(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new BlazeBurnerPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ChuteType extends ArmInteractionPointType {
|
||||||
|
public ChuteType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return AbstractChuteBlock.isChute(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new TopFaceArmInteractionPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CrafterType extends ArmInteractionPointType {
|
||||||
|
public CrafterType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return AllBlocks.MECHANICAL_CRAFTER.has(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new CrafterPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CrushingWheelsType extends ArmInteractionPointType {
|
||||||
|
public CrushingWheelsType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return AllBlocks.CRUSHING_WHEEL_CONTROLLER.has(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new TopFaceArmInteractionPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DeployerType extends ArmInteractionPointType {
|
||||||
|
public DeployerType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return AllBlocks.DEPLOYER.has(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new DeployerPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DepotType extends ArmInteractionPointType {
|
||||||
|
public DepotType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return AllBlocks.DEPOT.has(state) || AllBlocks.WEIGHTED_EJECTOR.has(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new DepotPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FunnelType extends ArmInteractionPointType {
|
||||||
|
public FunnelType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return state.getBlock() instanceof AbstractFunnelBlock
|
||||||
|
&& !(state.hasProperty(FunnelBlock.EXTRACTING) && state.getValue(FunnelBlock.EXTRACTING))
|
||||||
|
&& !(state.hasProperty(BeltFunnelBlock.SHAPE) && state.getValue(BeltFunnelBlock.SHAPE) == Shape.PUSHING);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new FunnelPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MillstoneType extends ArmInteractionPointType {
|
||||||
|
public MillstoneType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return AllBlocks.MILLSTONE.has(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new ArmInteractionPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SawType extends ArmInteractionPointType {
|
||||||
|
public SawType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return AllBlocks.MECHANICAL_SAW.has(state) && state.getValue(SawBlock.FACING) == Direction.UP
|
||||||
|
&& ((KineticTileEntity) level.getBlockEntity(pos)).getSpeed() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new DepotPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CampfireType extends ArmInteractionPointType {
|
||||||
|
public CampfireType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return state.getBlock() instanceof CampfireBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new CampfirePoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ComposterType extends ArmInteractionPointType {
|
||||||
|
public ComposterType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return state.is(Blocks.COMPOSTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new ComposterPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class JukeboxType extends ArmInteractionPointType {
|
||||||
|
public JukeboxType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return state.is(Blocks.JUKEBOX);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new JukeboxPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RespawnAnchorType extends ArmInteractionPointType {
|
||||||
|
public RespawnAnchorType(ResourceLocation id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return state.is(Blocks.RESPAWN_ANCHOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return new RespawnAnchorPoint(this, level, pos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
public static class DepositOnlyArmInteractionPoint extends ArmInteractionPoint {
|
||||||
|
public DepositOnlyArmInteractionPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||||
|
super(type, level, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cycleMode() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack extract(int slot, int amount, boolean simulate) {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSlotCount() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TopFaceArmInteractionPoint extends ArmInteractionPoint {
|
||||||
|
public TopFaceArmInteractionPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||||
|
super(type, level, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Vec3 getInteractionPositionVector() {
|
||||||
|
return Vec3.atLowerCornerOf(pos).add(.5f, 1, .5f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BeltPoint extends DepotPoint {
|
||||||
|
public BeltPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||||
|
super(type, level, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keepAlive() {
|
||||||
|
super.keepAlive();
|
||||||
|
BeltTileEntity beltTE = BeltHelper.getSegmentTE(level, pos);
|
||||||
|
if (beltTE == null)
|
||||||
|
return;
|
||||||
|
TransportedItemStackHandlerBehaviour transport =
|
||||||
|
beltTE.getBehaviour(TransportedItemStackHandlerBehaviour.TYPE);
|
||||||
|
if (transport == null)
|
||||||
|
return;
|
||||||
|
MutableBoolean found = new MutableBoolean(false);
|
||||||
|
transport.handleProcessingOnAllItems(tis -> {
|
||||||
|
if (found.isTrue())
|
||||||
|
return TransportedResult.doNothing();
|
||||||
|
tis.lockedExternally = true;
|
||||||
|
found.setTrue();
|
||||||
|
return TransportedResult.doNothing();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BlazeBurnerPoint extends DepositOnlyArmInteractionPoint {
|
||||||
|
public BlazeBurnerPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||||
|
super(type, level, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||||
|
ItemStack input = stack.copy();
|
||||||
|
InteractionResultHolder<ItemStack> res = BlazeBurnerBlock.tryInsert(cachedState, level, pos, input, false, false, simulate);
|
||||||
|
ItemStack remainder = res.getObject();
|
||||||
|
if (input.isEmpty()) {
|
||||||
|
return remainder;
|
||||||
|
} else {
|
||||||
|
if (!simulate)
|
||||||
|
Containers.dropItemStack(level, pos.getX(), pos.getY(), pos.getZ(), remainder);
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CrafterPoint extends ArmInteractionPoint {
|
||||||
|
public CrafterPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||||
|
super(type, level, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Direction getInteractionDirection() {
|
||||||
|
return cachedState.getValue(MechanicalCrafterBlock.HORIZONTAL_FACING)
|
||||||
|
.getOpposite();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Vec3 getInteractionPositionVector() {
|
||||||
|
return super.getInteractionPositionVector()
|
||||||
|
.add(Vec3.atLowerCornerOf(getInteractionDirection().getNormal()).scale(.5f));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCachedState() {
|
||||||
|
BlockState oldState = cachedState;
|
||||||
|
super.updateCachedState();
|
||||||
|
if (oldState != cachedState)
|
||||||
|
cachedAngles = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack extract(int slot, int amount, boolean simulate) {
|
||||||
|
BlockEntity te = level.getBlockEntity(pos);
|
||||||
|
if (!(te instanceof MechanicalCrafterTileEntity))
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
MechanicalCrafterTileEntity crafter = (MechanicalCrafterTileEntity) te;
|
||||||
|
SmartInventory inventory = crafter.getInventory();
|
||||||
|
inventory.allowExtraction();
|
||||||
|
ItemStack extract = super.extract(slot, amount, simulate);
|
||||||
|
inventory.forbidExtraction();
|
||||||
|
return extract;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DeployerPoint extends ArmInteractionPoint {
|
||||||
|
public DeployerPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||||
|
super(type, level, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Direction getInteractionDirection() {
|
||||||
|
return cachedState.getValue(DeployerBlock.FACING)
|
||||||
|
.getOpposite();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Vec3 getInteractionPositionVector() {
|
||||||
|
return super.getInteractionPositionVector()
|
||||||
|
.add(Vec3.atLowerCornerOf(getInteractionDirection().getNormal()).scale(.65f));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCachedState() {
|
||||||
|
BlockState oldState = cachedState;
|
||||||
|
super.updateCachedState();
|
||||||
|
if (oldState != cachedState)
|
||||||
|
cachedAngles = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DepotPoint extends ArmInteractionPoint {
|
||||||
|
public DepotPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||||
|
super(type, level, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Vec3 getInteractionPositionVector() {
|
||||||
|
return Vec3.atLowerCornerOf(pos).add(.5f, 14 / 16f, .5f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FunnelPoint extends DepositOnlyArmInteractionPoint {
|
||||||
|
public FunnelPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||||
|
super(type, level, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Vec3 getInteractionPositionVector() {
|
||||||
|
return VecHelper.getCenterOf(pos)
|
||||||
|
.add(Vec3.atLowerCornerOf(FunnelBlock.getFunnelFacing(cachedState)
|
||||||
|
.getNormal()).scale(-.15f));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Direction getInteractionDirection() {
|
||||||
|
return FunnelBlock.getFunnelFacing(cachedState)
|
||||||
|
.getOpposite();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCachedState() {
|
||||||
|
BlockState oldState = cachedState;
|
||||||
|
super.updateCachedState();
|
||||||
|
if (oldState != cachedState)
|
||||||
|
cachedAngles = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||||
|
FilteringBehaviour filtering = TileEntityBehaviour.get(level, pos, FilteringBehaviour.TYPE);
|
||||||
|
InvManipulationBehaviour inserter = TileEntityBehaviour.get(level, pos, InvManipulationBehaviour.TYPE);
|
||||||
|
if (cachedState.getOptionalValue(BlockStateProperties.POWERED).orElse(false))
|
||||||
|
return stack;
|
||||||
|
if (inserter == null)
|
||||||
|
return stack;
|
||||||
|
if (filtering != null && !filtering.test(stack))
|
||||||
|
return stack;
|
||||||
|
if (simulate)
|
||||||
|
inserter.simulate();
|
||||||
|
ItemStack insert = inserter.insert(stack);
|
||||||
|
if (!simulate && insert.getCount() != stack.getCount()) {
|
||||||
|
BlockEntity tileEntity = level.getBlockEntity(pos);
|
||||||
|
if (tileEntity instanceof FunnelTileEntity) {
|
||||||
|
FunnelTileEntity funnelTileEntity = (FunnelTileEntity) tileEntity;
|
||||||
|
funnelTileEntity.onTransfer(stack);
|
||||||
|
if (funnelTileEntity.hasFlap())
|
||||||
|
funnelTileEntity.flap(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return insert;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CampfirePoint extends DepositOnlyArmInteractionPoint {
|
||||||
|
public CampfirePoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||||
|
super(type, level, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||||
|
BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||||
|
if (!(blockEntity instanceof CampfireBlockEntity campfireBE))
|
||||||
|
return stack;
|
||||||
|
Optional<CampfireCookingRecipe> recipe = campfireBE.getCookableRecipe(stack);
|
||||||
|
if (recipe.isEmpty())
|
||||||
|
return stack;
|
||||||
|
if (simulate) {
|
||||||
|
boolean hasSpace = false;
|
||||||
|
for (ItemStack campfireStack : campfireBE.getItems()) {
|
||||||
|
if (campfireStack.isEmpty()) {
|
||||||
|
hasSpace = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasSpace)
|
||||||
|
return stack;
|
||||||
|
ItemStack remainder = stack.copy();
|
||||||
|
remainder.shrink(1);
|
||||||
|
return remainder;
|
||||||
|
}
|
||||||
|
ItemStack remainder = stack.copy();
|
||||||
|
campfireBE.placeFood(remainder, recipe.get().getCookingTime());
|
||||||
|
return remainder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ComposterPoint extends ArmInteractionPoint {
|
||||||
|
public ComposterPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||||
|
super(type, level, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Vec3 getInteractionPositionVector() {
|
||||||
|
return Vec3.atLowerCornerOf(pos).add(.5f, 13 / 16f, .5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCachedState() {
|
||||||
|
BlockState oldState = cachedState;
|
||||||
|
super.updateCachedState();
|
||||||
|
if (oldState != cachedState)
|
||||||
|
cachedHandler.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
protected IItemHandler getHandler() {
|
||||||
|
if (!cachedHandler.isPresent()) {
|
||||||
|
cachedHandler = LazyOptional.of(() -> {
|
||||||
|
ComposterBlock composterBlock = (ComposterBlock) Blocks.COMPOSTER;
|
||||||
|
WorldlyContainer container = composterBlock.getContainer(cachedState, level, pos);
|
||||||
|
SidedInvWrapper insertionHandler = new SidedInvWrapper(container, Direction.UP);
|
||||||
|
SidedInvWrapper extractionHandler = new SidedInvWrapper(container, Direction.DOWN);
|
||||||
|
return new CombinedInvWrapper(insertionHandler, extractionHandler);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return cachedHandler.orElse(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class JukeboxPoint extends TopFaceArmInteractionPoint {
|
||||||
|
public JukeboxPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||||
|
super(type, level, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSlotCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||||
|
Item item = stack.getItem();
|
||||||
|
if (!(item instanceof RecordItem))
|
||||||
|
return stack;
|
||||||
|
if (cachedState.getValue(JukeboxBlock.HAS_RECORD))
|
||||||
|
return stack;
|
||||||
|
BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||||
|
if (!(blockEntity instanceof JukeboxBlockEntity jukeboxBE))
|
||||||
|
return stack;
|
||||||
|
if (!jukeboxBE.getRecord()
|
||||||
|
.isEmpty())
|
||||||
|
return stack;
|
||||||
|
ItemStack remainder = stack.copy();
|
||||||
|
ItemStack toInsert = remainder.split(1);
|
||||||
|
if (!simulate) {
|
||||||
|
jukeboxBE.setRecord(toInsert);
|
||||||
|
level.setBlock(pos, cachedState.setValue(JukeboxBlock.HAS_RECORD, true), 2);
|
||||||
|
level.levelEvent(null, 1010, pos, Item.getId(item));
|
||||||
|
AllTriggers.triggerForNearbyPlayers(AllTriggers.MUSICAL_ARM, level, pos, 10);
|
||||||
|
}
|
||||||
|
return remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack extract(int slot, int amount, boolean simulate) {
|
||||||
|
if (!cachedState.getValue(JukeboxBlock.HAS_RECORD))
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||||
|
if (!(blockEntity instanceof JukeboxBlockEntity jukeboxBE))
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
ItemStack record = jukeboxBE.getRecord();
|
||||||
|
if (record.isEmpty())
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
if (!simulate) {
|
||||||
|
level.levelEvent(1010, pos, 0);
|
||||||
|
jukeboxBE.clearContent();
|
||||||
|
level.setBlock(pos, cachedState.setValue(JukeboxBlock.HAS_RECORD, false), 2);
|
||||||
|
}
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RespawnAnchorPoint extends DepositOnlyArmInteractionPoint {
|
||||||
|
public RespawnAnchorPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||||
|
super(type, level, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Vec3 getInteractionPositionVector() {
|
||||||
|
return Vec3.atLowerCornerOf(pos).add(.5f, 1, .5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||||
|
if (!stack.is(Items.GLOWSTONE))
|
||||||
|
return stack;
|
||||||
|
if (cachedState.getValue(RespawnAnchorBlock.CHARGE) == 4)
|
||||||
|
return stack;
|
||||||
|
if (!simulate)
|
||||||
|
RespawnAnchorBlock.charge(level, pos, cachedState);
|
||||||
|
ItemStack remainder = stack.copy();
|
||||||
|
remainder.shrink(1);
|
||||||
|
return remainder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,7 +11,7 @@ import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public class ArmAngleTarget {
|
public class ArmAngleTarget {
|
||||||
|
|
||||||
static ArmAngleTarget NO_TARGET = new ArmAngleTarget();
|
static final ArmAngleTarget NO_TARGET = new ArmAngleTarget();
|
||||||
|
|
||||||
float baseAngle;
|
float baseAngle;
|
||||||
float lowerArmAngle;
|
float lowerArmAngle;
|
||||||
|
|
|
@ -1,119 +1,66 @@
|
||||||
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.PartialModel;
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import com.simibubi.create.AllBlockPartials;
|
|
||||||
import com.simibubi.create.AllBlocks;
|
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
|
||||||
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterBlock;
|
|
||||||
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterTileEntity;
|
|
||||||
import com.simibubi.create.content.contraptions.components.deployer.DeployerBlock;
|
|
||||||
import com.simibubi.create.content.contraptions.components.saw.SawBlock;
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||||
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
|
||||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock;
|
|
||||||
import com.simibubi.create.content.logistics.block.chute.AbstractChuteBlock;
|
|
||||||
import com.simibubi.create.content.logistics.block.funnel.AbstractFunnelBlock;
|
|
||||||
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock;
|
|
||||||
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock.Shape;
|
|
||||||
import com.simibubi.create.content.logistics.block.funnel.FunnelBlock;
|
|
||||||
import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity;
|
|
||||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
|
||||||
import com.simibubi.create.foundation.item.SmartInventory;
|
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
|
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
|
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour;
|
|
||||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.NbtUtils;
|
import net.minecraft.nbt.NbtUtils;
|
||||||
import net.minecraft.world.Containers;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.InteractionResultHolder;
|
|
||||||
import net.minecraft.world.item.Item;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.RecordItem;
|
|
||||||
import net.minecraft.world.level.BlockGetter;
|
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
|
||||||
import net.minecraft.world.level.block.Blocks;
|
|
||||||
import net.minecraft.world.level.block.ComposterBlock;
|
|
||||||
import net.minecraft.world.level.block.JukeboxBlock;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.JukeboxBlockEntity;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
import net.minecraftforge.items.ItemHandlerHelper;
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
import net.minecraftforge.items.wrapper.InvWrapper;
|
|
||||||
|
|
||||||
public abstract class ArmInteractionPoint {
|
public class ArmInteractionPoint {
|
||||||
public enum Mode {
|
|
||||||
DEPOSIT, TAKE
|
|
||||||
}
|
|
||||||
|
|
||||||
protected BlockPos pos;
|
protected final ArmInteractionPointType type;
|
||||||
protected BlockState state;
|
protected Level level;
|
||||||
protected Mode mode;
|
protected final BlockPos pos;
|
||||||
|
protected Mode mode = Mode.DEPOSIT;
|
||||||
|
|
||||||
protected LazyOptional<IItemHandler> cachedHandler;
|
protected BlockState cachedState;
|
||||||
|
protected LazyOptional<IItemHandler> cachedHandler = LazyOptional.empty();
|
||||||
protected ArmAngleTarget cachedAngles;
|
protected ArmAngleTarget cachedAngles;
|
||||||
|
|
||||||
protected static final HashMap<ArmInteractionPoint, Supplier<ArmInteractionPoint>> POINTS = new HashMap<>();
|
public ArmInteractionPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||||
|
this.type = type;
|
||||||
static {
|
this.level = level;
|
||||||
addPoint(new Saw(), Saw::new);
|
this.pos = pos;
|
||||||
addPoint(new Belt(), Belt::new);
|
this.cachedState = state;
|
||||||
addPoint(new Depot(), Depot::new);
|
|
||||||
addPoint(new Chute(), Chute::new);
|
|
||||||
addPoint(new Basin(), Basin::new);
|
|
||||||
addPoint(new Funnel(), Funnel::new);
|
|
||||||
addPoint(new Jukebox(), Jukebox::new);
|
|
||||||
addPoint(new Crafter(), Crafter::new);
|
|
||||||
addPoint(new Deployer(), Deployer::new);
|
|
||||||
addPoint(new Composter(), Composter::new);
|
|
||||||
addPoint(new Millstone(), Millstone::new);
|
|
||||||
addPoint(new BlazeBurner(), BlazeBurner::new);
|
|
||||||
addPoint(new CrushingWheels(), CrushingWheels::new);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addPoint(ArmInteractionPoint instance, Supplier<ArmInteractionPoint> factory) {
|
public ArmInteractionPointType getType() {
|
||||||
if (POINTS.containsKey(instance))
|
return type;
|
||||||
Create.LOGGER.warn("Point for " + instance.getClass().getSimpleName() + " was overridden");
|
|
||||||
POINTS.put(instance, factory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArmInteractionPoint() {
|
public Level getLevel() {
|
||||||
cachedHandler = LazyOptional.empty();
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
public void setLevel(Level level) {
|
||||||
protected void transformFlag(PoseStack stack) {}
|
this.level = level;
|
||||||
|
|
||||||
protected PartialModel getFlagType() {
|
|
||||||
return mode == Mode.TAKE ? AllBlockPartials.FLAG_LONG_OUT : AllBlockPartials.FLAG_LONG_IN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void cycleMode() {
|
public BlockPos getPos() {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mode getMode() {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cycleMode() {
|
||||||
mode = mode == Mode.DEPOSIT ? Mode.TAKE : Mode.DEPOSIT;
|
mode = mode == Mode.DEPOSIT ? Mode.TAKE : Mode.DEPOSIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,22 +72,7 @@ public abstract class ArmInteractionPoint {
|
||||||
return Direction.DOWN;
|
return Direction.DOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isStillValid(BlockGetter reader) {
|
public ArmAngleTarget getTargetAngles(BlockPos armPos, boolean ceiling) {
|
||||||
return isValid(reader, pos, reader.getBlockState(pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void keepAlive(LevelAccessor world) {}
|
|
||||||
|
|
||||||
protected abstract boolean isValid(BlockGetter reader, BlockPos pos, BlockState state);
|
|
||||||
|
|
||||||
protected static boolean isInteractable(BlockGetter reader, BlockPos pos, BlockState state) {
|
|
||||||
for (ArmInteractionPoint armInteractionPoint : POINTS.keySet())
|
|
||||||
if (armInteractionPoint.isValid(reader, pos, state))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ArmAngleTarget getTargetAngles(BlockPos armPos, boolean ceiling) {
|
|
||||||
if (cachedAngles == null)
|
if (cachedAngles == null)
|
||||||
cachedAngles =
|
cachedAngles =
|
||||||
new ArmAngleTarget(armPos, getInteractionPositionVector(), getInteractionDirection(), ceiling);
|
new ArmAngleTarget(armPos, getInteractionPositionVector(), getInteractionDirection(), ceiling);
|
||||||
|
@ -148,10 +80,21 @@ public abstract class ArmInteractionPoint {
|
||||||
return cachedAngles;
|
return cachedAngles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateCachedState() {
|
||||||
|
cachedState = level.getBlockState(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
updateCachedState();
|
||||||
|
return type.canCreatePoint(level, pos, cachedState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void keepAlive() {}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
protected IItemHandler getHandler(Level world) {
|
protected IItemHandler getHandler() {
|
||||||
if (!cachedHandler.isPresent()) {
|
if (!cachedHandler.isPresent()) {
|
||||||
BlockEntity te = world.getBlockEntity(pos);
|
BlockEntity te = level.getBlockEntity(pos);
|
||||||
if (te == null)
|
if (te == null)
|
||||||
return null;
|
return null;
|
||||||
cachedHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, Direction.UP);
|
cachedHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, Direction.UP);
|
||||||
|
@ -159,393 +102,106 @@ public abstract class ArmInteractionPoint {
|
||||||
return cachedHandler.orElse(null);
|
return cachedHandler.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ItemStack insert(Level world, ItemStack stack, boolean simulate) {
|
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||||
IItemHandler handler = getHandler(world);
|
IItemHandler handler = getHandler();
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
return stack;
|
return stack;
|
||||||
return ItemHandlerHelper.insertItem(handler, stack, simulate);
|
return ItemHandlerHelper.insertItem(handler, stack, simulate);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ItemStack extract(Level world, int slot, int amount, boolean simulate) {
|
public ItemStack extract(int slot, int amount, boolean simulate) {
|
||||||
IItemHandler handler = getHandler(world);
|
IItemHandler handler = getHandler();
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
return handler.extractItem(slot, amount, simulate);
|
return handler.extractItem(slot, amount, simulate);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ItemStack extract(Level world, int slot, boolean simulate) {
|
public ItemStack extract(int slot, boolean simulate) {
|
||||||
return extract(world, slot, 64, simulate);
|
return extract(slot, 64, simulate);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getSlotCount(Level world) {
|
public int getSlotCount() {
|
||||||
IItemHandler handler = getHandler(world);
|
IItemHandler handler = getHandler();
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
return 0;
|
return 0;
|
||||||
return handler.getSlots();
|
return handler.getSlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
protected void serialize(CompoundTag nbt, BlockPos anchor) {
|
||||||
protected static ArmInteractionPoint createAt(BlockGetter world, BlockPos pos) {
|
NBTHelper.writeEnum(nbt, "Mode", mode);
|
||||||
BlockState state = world.getBlockState(pos);
|
|
||||||
ArmInteractionPoint point = null;
|
|
||||||
|
|
||||||
for (ArmInteractionPoint armInteractionPoint : POINTS.keySet())
|
|
||||||
if (armInteractionPoint.isValid(world, pos, state))
|
|
||||||
point = POINTS.get(armInteractionPoint)
|
|
||||||
.get();
|
|
||||||
|
|
||||||
if (point != null) {
|
|
||||||
point.state = state;
|
|
||||||
point.pos = pos;
|
|
||||||
point.mode = Mode.DEPOSIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return point;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CompoundTag serialize(BlockPos anchor) {
|
protected void deserialize(CompoundTag nbt, BlockPos anchor) {
|
||||||
|
mode = NBTHelper.readEnum(nbt, "Mode", Mode.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final CompoundTag serialize(BlockPos anchor) {
|
||||||
CompoundTag nbt = new CompoundTag();
|
CompoundTag nbt = new CompoundTag();
|
||||||
|
nbt.putString("Type", type.getId().toString());
|
||||||
nbt.put("Pos", NbtUtils.writeBlockPos(pos.subtract(anchor)));
|
nbt.put("Pos", NbtUtils.writeBlockPos(pos.subtract(anchor)));
|
||||||
NBTHelper.writeEnum(nbt, "Mode", mode);
|
serialize(nbt, anchor);
|
||||||
return nbt;
|
return nbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ArmInteractionPoint deserialize(BlockGetter world, BlockPos anchor, CompoundTag nbt) {
|
@Nullable
|
||||||
BlockPos pos = NbtUtils.readBlockPos(nbt.getCompound("Pos"));
|
public static ArmInteractionPoint deserialize(CompoundTag nbt, Level level, BlockPos anchor) {
|
||||||
ArmInteractionPoint interactionPoint = createAt(world, pos.offset(anchor));
|
ResourceLocation id = ResourceLocation.tryParse(nbt.getString("Type"));
|
||||||
if (interactionPoint == null)
|
if (id == null)
|
||||||
return null;
|
return null;
|
||||||
interactionPoint.mode = NBTHelper.readEnum(nbt, "Mode", Mode.class);
|
ArmInteractionPointType type = ArmInteractionPointType.get(id);
|
||||||
return interactionPoint;
|
if (type == null)
|
||||||
|
return null;
|
||||||
|
BlockPos pos = NbtUtils.readBlockPos(nbt.getCompound("Pos")).offset(anchor);
|
||||||
|
ArmInteractionPoint point = type.createPoint(level, pos, level.getBlockState(pos));
|
||||||
|
if (point == null)
|
||||||
|
return null;
|
||||||
|
point.deserialize(nbt, anchor);
|
||||||
|
return point;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void transformPos(StructureTransform transform, CompoundTag nbt) {
|
public static void transformPos(CompoundTag nbt, StructureTransform transform) {
|
||||||
BlockPos pos = NbtUtils.readBlockPos(nbt.getCompound("Pos"));
|
BlockPos pos = NbtUtils.readBlockPos(nbt.getCompound("Pos"));
|
||||||
pos = transform.applyWithoutOffset(pos);
|
pos = transform.applyWithoutOffset(pos);
|
||||||
nbt.put("Pos", NbtUtils.writeBlockPos(pos));
|
nbt.put("Pos", NbtUtils.writeBlockPos(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static abstract class TopFaceArmInteractionPoint extends ArmInteractionPoint {
|
public static boolean isInteractable(Level level, BlockPos pos, BlockState state) {
|
||||||
|
return ArmInteractionPointType.getPrimaryType(level, pos, state) != null;
|
||||||
@Override
|
|
||||||
protected Vec3 getInteractionPositionVector() {
|
|
||||||
return Vec3.atLowerCornerOf(pos).add(.5f, 1, .5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Depot extends ArmInteractionPoint {
|
@Nullable
|
||||||
|
public static ArmInteractionPoint create(Level level, BlockPos pos, BlockState state) {
|
||||||
@Override
|
ArmInteractionPointType type = ArmInteractionPointType.getPrimaryType(level, pos, state);
|
||||||
protected Vec3 getInteractionPositionVector() {
|
if (type == null)
|
||||||
return Vec3.atLowerCornerOf(pos).add(.5f, 14 / 16f, .5f);
|
return null;
|
||||||
}
|
return type.createPoint(level, pos, state);
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
|
||||||
return AllBlocks.DEPOT.has(state) || AllBlocks.WEIGHTED_EJECTOR.has(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Saw extends Depot {
|
public enum Mode {
|
||||||
|
DEPOSIT("mechanical_arm.deposit_to", ChatFormatting.GOLD, 0xFFCB74),
|
||||||
|
TAKE("mechanical_arm.extract_from", ChatFormatting.AQUA, 0x4F8A8B);
|
||||||
|
|
||||||
@Override
|
private final String translationKey;
|
||||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
private final ChatFormatting chatColor;
|
||||||
return AllBlocks.MECHANICAL_SAW.has(state) && state.getValue(SawBlock.FACING) == Direction.UP
|
private final int color;
|
||||||
&& ((KineticTileEntity) reader.getBlockEntity(pos)).getSpeed() != 0;
|
|
||||||
|
Mode(String translationKey, ChatFormatting chatColor, int color) {
|
||||||
|
this.translationKey = translationKey;
|
||||||
|
this.chatColor = chatColor;
|
||||||
|
this.color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
public String getTranslationKey() {
|
||||||
|
return translationKey;
|
||||||
public static class Millstone extends ArmInteractionPoint {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
|
||||||
return AllBlocks.MILLSTONE.has(state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
public ChatFormatting getChatColor() {
|
||||||
|
return chatColor;
|
||||||
public static class CrushingWheels extends TopFaceArmInteractionPoint {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
|
||||||
return AllBlocks.CRUSHING_WHEEL_CONTROLLER.has(state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
public int getColor() {
|
||||||
|
return color;
|
||||||
public static class Composter extends TopFaceArmInteractionPoint {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Vec3 getInteractionPositionVector() {
|
|
||||||
return Vec3.atLowerCornerOf(pos).add(.5f, 13 / 16f, .5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
|
||||||
return Blocks.COMPOSTER.equals(state.getBlock());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
protected IItemHandler getHandler(Level world) {
|
|
||||||
return new InvWrapper(
|
|
||||||
((ComposterBlock) Blocks.COMPOSTER).getContainer(world.getBlockState(pos), world, pos));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Deployer extends ArmInteractionPoint {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
|
||||||
return AllBlocks.DEPLOYER.has(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Direction getInteractionDirection() {
|
|
||||||
return state.getValue(DeployerBlock.FACING)
|
|
||||||
.getOpposite();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Vec3 getInteractionPositionVector() {
|
|
||||||
return super.getInteractionPositionVector()
|
|
||||||
.add(Vec3.atLowerCornerOf(getInteractionDirection().getNormal()).scale(.65f));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class BlazeBurner extends ArmInteractionPoint {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
|
||||||
return AllBlocks.BLAZE_BURNER.has(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemStack extract(Level world, int slot, int amount, boolean simulate) {
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemStack insert(Level world, ItemStack stack, boolean simulate) {
|
|
||||||
ItemStack input = stack.copy();
|
|
||||||
InteractionResultHolder<ItemStack> res = BlazeBurnerBlock.tryInsert(state, world, pos, input, false, false, simulate);
|
|
||||||
ItemStack remainder = res.getObject();
|
|
||||||
if (input.isEmpty()) {
|
|
||||||
return remainder;
|
|
||||||
} else {
|
|
||||||
if (!simulate)
|
|
||||||
Containers.dropItemStack(world, pos.getX(), pos.getY(), pos.getZ(), remainder);
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void cycleMode() {}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Crafter extends ArmInteractionPoint {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
|
||||||
return AllBlocks.MECHANICAL_CRAFTER.has(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Direction getInteractionDirection() {
|
|
||||||
return state.getValue(MechanicalCrafterBlock.HORIZONTAL_FACING)
|
|
||||||
.getOpposite();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemStack extract(Level world, int slot, int amount, boolean simulate) {
|
|
||||||
BlockEntity te = world.getBlockEntity(pos);
|
|
||||||
if (!(te instanceof MechanicalCrafterTileEntity))
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
MechanicalCrafterTileEntity crafter = (MechanicalCrafterTileEntity) te;
|
|
||||||
SmartInventory inventory = crafter.getInventory();
|
|
||||||
inventory.allowExtraction();
|
|
||||||
ItemStack extract = super.extract(world, slot, amount, simulate);
|
|
||||||
inventory.forbidExtraction();
|
|
||||||
return extract;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Vec3 getInteractionPositionVector() {
|
|
||||||
return super.getInteractionPositionVector()
|
|
||||||
.add(Vec3.atLowerCornerOf(getInteractionDirection().getNormal()).scale(.5f));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Basin extends ArmInteractionPoint {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
|
||||||
return AllBlocks.BASIN.has(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Jukebox extends TopFaceArmInteractionPoint {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
|
||||||
return state.getBlock() instanceof JukeboxBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getSlotCount(Level world) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemStack insert(Level world, ItemStack stack, boolean simulate) {
|
|
||||||
BlockEntity tileEntity = world.getBlockEntity(pos);
|
|
||||||
if (!(tileEntity instanceof JukeboxBlockEntity))
|
|
||||||
return stack;
|
|
||||||
if (!(state.getBlock() instanceof JukeboxBlock))
|
|
||||||
return stack;
|
|
||||||
JukeboxBlock jukeboxBlock = (JukeboxBlock) state.getBlock();
|
|
||||||
JukeboxBlockEntity jukeboxTE = (JukeboxBlockEntity) tileEntity;
|
|
||||||
if (!jukeboxTE.getRecord()
|
|
||||||
.isEmpty())
|
|
||||||
return stack;
|
|
||||||
if (!(stack.getItem() instanceof RecordItem))
|
|
||||||
return stack;
|
|
||||||
ItemStack remainder = stack.copy();
|
|
||||||
ItemStack toInsert = remainder.split(1);
|
|
||||||
if (!simulate && !world.isClientSide) {
|
|
||||||
jukeboxBlock.setRecord(world, pos, state, toInsert);
|
|
||||||
world.levelEvent(null, 1010, pos, Item.getId(toInsert.getItem()));
|
|
||||||
AllTriggers.triggerForNearbyPlayers(AllTriggers.MUSICAL_ARM, world, pos, 10);
|
|
||||||
}
|
|
||||||
return remainder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemStack extract(Level world, int slot, int amount, boolean simulate) {
|
|
||||||
BlockEntity tileEntity = world.getBlockEntity(pos);
|
|
||||||
if (!(tileEntity instanceof JukeboxBlockEntity))
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
if (!(state.getBlock() instanceof JukeboxBlock))
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
JukeboxBlockEntity jukeboxTE = (JukeboxBlockEntity) tileEntity;
|
|
||||||
ItemStack itemstack = jukeboxTE.getRecord();
|
|
||||||
if (itemstack.isEmpty())
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
if (!simulate && !world.isClientSide) {
|
|
||||||
world.levelEvent(1010, pos, 0);
|
|
||||||
jukeboxTE.clearContent();
|
|
||||||
world.setBlock(pos, state.setValue(JukeboxBlock.HAS_RECORD, false), 2);
|
|
||||||
}
|
|
||||||
return itemstack;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Belt extends Depot {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
|
||||||
return AllBlocks.BELT.has(state) && !(reader.getBlockState(pos.above())
|
|
||||||
.getBlock() instanceof BeltTunnelBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void keepAlive(LevelAccessor world) {
|
|
||||||
super.keepAlive(world);
|
|
||||||
BeltTileEntity beltTE = BeltHelper.getSegmentTE(world, pos);
|
|
||||||
if (beltTE == null)
|
|
||||||
return;
|
|
||||||
TransportedItemStackHandlerBehaviour transport =
|
|
||||||
beltTE.getBehaviour(TransportedItemStackHandlerBehaviour.TYPE);
|
|
||||||
if (transport == null)
|
|
||||||
return;
|
|
||||||
MutableBoolean found = new MutableBoolean(false);
|
|
||||||
transport.handleProcessingOnAllItems(tis -> {
|
|
||||||
if (found.isTrue())
|
|
||||||
return TransportedResult.doNothing();
|
|
||||||
tis.lockedExternally = true;
|
|
||||||
found.setTrue();
|
|
||||||
return TransportedResult.doNothing();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Chute extends TopFaceArmInteractionPoint {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
|
||||||
return AbstractChuteBlock.isChute(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Funnel extends ArmInteractionPoint {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Vec3 getInteractionPositionVector() {
|
|
||||||
return VecHelper.getCenterOf(pos)
|
|
||||||
.add(Vec3.atLowerCornerOf(FunnelBlock.getFunnelFacing(state)
|
|
||||||
.getNormal()).scale(-.15f));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getSlotCount(Level world) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemStack extract(Level world, int slot, int amount, boolean simulate) {
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Direction getInteractionDirection() {
|
|
||||||
return FunnelBlock.getFunnelFacing(state)
|
|
||||||
.getOpposite();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemStack insert(Level world, ItemStack stack, boolean simulate) {
|
|
||||||
FilteringBehaviour filtering = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE);
|
|
||||||
InvManipulationBehaviour inserter = TileEntityBehaviour.get(world, pos, InvManipulationBehaviour.TYPE);
|
|
||||||
BlockState state = world.getBlockState(pos);
|
|
||||||
if (state.getOptionalValue(BlockStateProperties.POWERED).orElse(false))
|
|
||||||
return stack;
|
|
||||||
if (inserter == null)
|
|
||||||
return stack;
|
|
||||||
if (filtering != null && !filtering.test(stack))
|
|
||||||
return stack;
|
|
||||||
if (simulate)
|
|
||||||
inserter.simulate();
|
|
||||||
ItemStack insert = inserter.insert(stack);
|
|
||||||
if (!simulate && insert.getCount() != stack.getCount()) {
|
|
||||||
BlockEntity tileEntity = world.getBlockEntity(pos);
|
|
||||||
if (tileEntity instanceof FunnelTileEntity) {
|
|
||||||
FunnelTileEntity funnelTileEntity = (FunnelTileEntity) tileEntity;
|
|
||||||
funnelTileEntity.onTransfer(stack);
|
|
||||||
if (funnelTileEntity.hasFlap())
|
|
||||||
funnelTileEntity.flap(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return insert;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
|
||||||
return state.getBlock() instanceof AbstractFunnelBlock
|
|
||||||
&& !(state.hasProperty(FunnelBlock.EXTRACTING) && state.getValue(FunnelBlock.EXTRACTING))
|
|
||||||
&& !(state.hasProperty(BeltFunnelBlock.SHAPE) && state.getValue(BeltFunnelBlock.SHAPE) == Shape.PUSHING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void cycleMode() {}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.player.LocalPlayer;
|
import net.minecraft.client.player.LocalPlayer;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import net.minecraft.network.chat.MutableComponent;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
@ -52,9 +52,10 @@ public class ArmInteractionPointHandler {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ArmInteractionPoint selected = getSelected(pos);
|
ArmInteractionPoint selected = getSelected(pos);
|
||||||
|
BlockState state = world.getBlockState(pos);
|
||||||
|
|
||||||
if (selected == null) {
|
if (selected == null) {
|
||||||
ArmInteractionPoint point = ArmInteractionPoint.createAt(world, pos);
|
ArmInteractionPoint point = ArmInteractionPoint.create(world, pos, state);
|
||||||
if (point == null)
|
if (point == null)
|
||||||
return;
|
return;
|
||||||
selected = point;
|
selected = point;
|
||||||
|
@ -63,10 +64,9 @@ public class ArmInteractionPointHandler {
|
||||||
|
|
||||||
selected.cycleMode();
|
selected.cycleMode();
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
String key = selected.mode == Mode.DEPOSIT ? "mechanical_arm.deposit_to" : "mechanical_arm.extract_from";
|
String key = selected.getMode().getTranslationKey();
|
||||||
ChatFormatting colour = selected.mode == Mode.DEPOSIT ? ChatFormatting.GOLD : ChatFormatting.AQUA;
|
ChatFormatting colour = selected.getMode().getChatColor();
|
||||||
TranslatableComponent translatedBlock = new TranslatableComponent(selected.state.getBlock()
|
MutableComponent translatedBlock = state.getBlock().getName();
|
||||||
.getDescriptionId());
|
|
||||||
player.displayClientMessage((Lang.translate(key, translatedBlock.withStyle(ChatFormatting.WHITE, colour)).withStyle(colour)),
|
player.displayClientMessage((Lang.translate(key, translatedBlock.withStyle(ChatFormatting.WHITE, colour)).withStyle(colour)),
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ public class ArmInteractionPointHandler {
|
||||||
int removed = 0;
|
int removed = 0;
|
||||||
for (Iterator<ArmInteractionPoint> iterator = currentSelection.iterator(); iterator.hasNext();) {
|
for (Iterator<ArmInteractionPoint> iterator = currentSelection.iterator(); iterator.hasNext();) {
|
||||||
ArmInteractionPoint point = iterator.next();
|
ArmInteractionPoint point = iterator.next();
|
||||||
if (point.pos.closerThan(pos, ArmTileEntity.getRange()))
|
if (point.getPos().closerThan(pos, ArmTileEntity.getRange()))
|
||||||
continue;
|
continue;
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
removed++;
|
removed++;
|
||||||
|
@ -109,7 +109,7 @@ public class ArmInteractionPointHandler {
|
||||||
int inputs = 0;
|
int inputs = 0;
|
||||||
int outputs = 0;
|
int outputs = 0;
|
||||||
for (ArmInteractionPoint armInteractionPoint : currentSelection) {
|
for (ArmInteractionPoint armInteractionPoint : currentSelection) {
|
||||||
if (armInteractionPoint.mode == Mode.DEPOSIT)
|
if (armInteractionPoint.getMode() == Mode.DEPOSIT)
|
||||||
outputs++;
|
outputs++;
|
||||||
else
|
else
|
||||||
inputs++;
|
inputs++;
|
||||||
|
@ -179,22 +179,22 @@ public class ArmInteractionPointHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void drawOutlines(Collection<ArmInteractionPoint> selection) {
|
private static void drawOutlines(Collection<ArmInteractionPoint> selection) {
|
||||||
Level world = Minecraft.getInstance().level;
|
|
||||||
for (Iterator<ArmInteractionPoint> iterator = selection.iterator(); iterator.hasNext();) {
|
for (Iterator<ArmInteractionPoint> iterator = selection.iterator(); iterator.hasNext();) {
|
||||||
ArmInteractionPoint point = iterator.next();
|
ArmInteractionPoint point = iterator.next();
|
||||||
BlockPos pos = point.pos;
|
|
||||||
BlockState state = world.getBlockState(pos);
|
|
||||||
|
|
||||||
if (!point.isValid(world, pos, state)) {
|
if (!point.isValid()) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelShape shape = state.getShape(world, pos);
|
Level level = point.getLevel();
|
||||||
|
BlockPos pos = point.getPos();
|
||||||
|
BlockState state = level.getBlockState(pos);
|
||||||
|
VoxelShape shape = state.getShape(level, pos);
|
||||||
if (shape.isEmpty())
|
if (shape.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int color = point.mode == Mode.DEPOSIT ? 0xffcb74 : 0x4f8a8b;
|
int color = point.getMode().getColor();
|
||||||
CreateClient.OUTLINER.showAABB(point, shape.bounds()
|
CreateClient.OUTLINER.showAABB(point, shape.bounds()
|
||||||
.move(pos))
|
.move(pos))
|
||||||
.colored(color)
|
.colored(color)
|
||||||
|
@ -214,10 +214,9 @@ public class ArmInteractionPointHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ArmInteractionPoint getSelected(BlockPos pos) {
|
private static ArmInteractionPoint getSelected(BlockPos pos) {
|
||||||
for (ArmInteractionPoint point : currentSelection) {
|
for (ArmInteractionPoint point : currentSelection)
|
||||||
if (point.pos.equals(pos))
|
if (point.getPos().equals(pos))
|
||||||
return point;
|
return point;
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
|
public abstract class ArmInteractionPointType {
|
||||||
|
|
||||||
|
private static final Map<ResourceLocation, ArmInteractionPointType> TYPES = new HashMap<>();
|
||||||
|
private static final List<ArmInteractionPointType> SORTED_TYPES = new ArrayList<>();
|
||||||
|
|
||||||
|
protected final ResourceLocation id;
|
||||||
|
|
||||||
|
public ArmInteractionPointType(ResourceLocation id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register(ArmInteractionPointType type) {
|
||||||
|
ResourceLocation id = type.getId();
|
||||||
|
if (TYPES.containsKey(id))
|
||||||
|
throw new IllegalArgumentException("Tried to override ArmInteractionPointType registration for id '" + id + "'. This is not supported!");
|
||||||
|
TYPES.put(id, type);
|
||||||
|
SORTED_TYPES.add(type);
|
||||||
|
SORTED_TYPES.sort((t1, t2) -> t2.getPriority() - t1.getPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static ArmInteractionPointType get(ResourceLocation id) {
|
||||||
|
return TYPES.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void forEach(Consumer<ArmInteractionPointType> action) {
|
||||||
|
SORTED_TYPES.forEach(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static ArmInteractionPointType getPrimaryType(Level level, BlockPos pos, BlockState state) {
|
||||||
|
for (ArmInteractionPointType type : SORTED_TYPES)
|
||||||
|
if (type.canCreatePoint(level, pos, state))
|
||||||
|
return type;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final ResourceLocation getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean canCreatePoint(Level level, BlockPos pos, BlockState state);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public abstract ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state);
|
||||||
|
|
||||||
|
public int getPriority() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,7 +9,6 @@ import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Jukebox;
|
|
||||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode;
|
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode;
|
||||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
|
@ -35,6 +34,7 @@ import net.minecraft.sounds.SoundEvents;
|
||||||
import net.minecraft.sounds.SoundSource;
|
import net.minecraft.sounds.SoundSource;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.JukeboxBlock;
|
import net.minecraft.world.level.block.JukeboxBlock;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
@ -116,7 +116,7 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
||||||
if (phase == Phase.MOVE_TO_INPUT) {
|
if (phase == Phase.MOVE_TO_INPUT) {
|
||||||
ArmInteractionPoint point = getTargetedInteractionPoint();
|
ArmInteractionPoint point = getTargetedInteractionPoint();
|
||||||
if (point != null)
|
if (point != null)
|
||||||
point.keepAlive(level);
|
point.keepAlive();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -164,9 +164,9 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
||||||
|
|
||||||
private boolean checkForMusicAmong(List<ArmInteractionPoint> list) {
|
private boolean checkForMusicAmong(List<ArmInteractionPoint> list) {
|
||||||
for (ArmInteractionPoint armInteractionPoint : list) {
|
for (ArmInteractionPoint armInteractionPoint : list) {
|
||||||
if (!(armInteractionPoint instanceof Jukebox))
|
if (!(armInteractionPoint instanceof AllArmInteractionPointTypes.JukeboxPoint))
|
||||||
continue;
|
continue;
|
||||||
BlockState state = level.getBlockState(armInteractionPoint.pos);
|
BlockState state = level.getBlockState(armInteractionPoint.getPos());
|
||||||
if (state.getOptionalValue(JukeboxBlock.HAS_RECORD).orElse(false))
|
if (state.getOptionalValue(JukeboxBlock.HAS_RECORD).orElse(false))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -236,9 +236,9 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
||||||
|
|
||||||
InteractionPoints: for (int i = startIndex; i < scanRange; i++) {
|
InteractionPoints: for (int i = startIndex; i < scanRange; i++) {
|
||||||
ArmInteractionPoint armInteractionPoint = inputs.get(i);
|
ArmInteractionPoint armInteractionPoint = inputs.get(i);
|
||||||
if (!armInteractionPoint.isStillValid(level))
|
if (!armInteractionPoint.isValid())
|
||||||
continue;
|
continue;
|
||||||
for (int j = 0; j < armInteractionPoint.getSlotCount(level); j++) {
|
for (int j = 0; j < armInteractionPoint.getSlotCount(); j++) {
|
||||||
if (getDistributableAmount(armInteractionPoint, j) == 0)
|
if (getDistributableAmount(armInteractionPoint, j) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -274,10 +274,10 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
||||||
|
|
||||||
for (int i = startIndex; i < scanRange; i++) {
|
for (int i = startIndex; i < scanRange; i++) {
|
||||||
ArmInteractionPoint armInteractionPoint = outputs.get(i);
|
ArmInteractionPoint armInteractionPoint = outputs.get(i);
|
||||||
if (!armInteractionPoint.isStillValid(level))
|
if (!armInteractionPoint.isValid())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ItemStack remainder = armInteractionPoint.insert(level, held, true);
|
ItemStack remainder = armInteractionPoint.insert(held, true);
|
||||||
if (remainder.equals(heldItem, false))
|
if (remainder.equals(heldItem, false))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getDistributableAmount(ArmInteractionPoint armInteractionPoint, int i) {
|
protected int getDistributableAmount(ArmInteractionPoint armInteractionPoint, int i) {
|
||||||
ItemStack stack = armInteractionPoint.extract(level, i, true);
|
ItemStack stack = armInteractionPoint.extract(i, true);
|
||||||
ItemStack remainder = simulateInsertion(stack);
|
ItemStack remainder = simulateInsertion(stack);
|
||||||
if (stack.sameItem(remainder)) {
|
if (stack.sameItem(remainder)) {
|
||||||
return stack.getCount() - remainder.getCount();
|
return stack.getCount() - remainder.getCount();
|
||||||
|
@ -320,11 +320,21 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ItemStack simulateInsertion(ItemStack stack) {
|
||||||
|
for (ArmInteractionPoint armInteractionPoint : outputs) {
|
||||||
|
if (armInteractionPoint.isValid())
|
||||||
|
stack = armInteractionPoint.insert(stack, true);
|
||||||
|
if (stack.isEmpty())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
protected void depositItem() {
|
protected void depositItem() {
|
||||||
ArmInteractionPoint armInteractionPoint = getTargetedInteractionPoint();
|
ArmInteractionPoint armInteractionPoint = getTargetedInteractionPoint();
|
||||||
if (armInteractionPoint != null) {
|
if (armInteractionPoint != null && armInteractionPoint.isValid()) {
|
||||||
ItemStack toInsert = heldItem.copy();
|
ItemStack toInsert = heldItem.copy();
|
||||||
ItemStack remainder = armInteractionPoint.insert(level, toInsert, false);
|
ItemStack remainder = armInteractionPoint.insert(toInsert, false);
|
||||||
heldItem = remainder;
|
heldItem = remainder;
|
||||||
}
|
}
|
||||||
phase = heldItem.isEmpty() ? Phase.SEARCH_INPUTS : Phase.SEARCH_OUTPUTS;
|
phase = heldItem.isEmpty() ? Phase.SEARCH_INPUTS : Phase.SEARCH_OUTPUTS;
|
||||||
|
@ -339,14 +349,14 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
||||||
|
|
||||||
protected void collectItem() {
|
protected void collectItem() {
|
||||||
ArmInteractionPoint armInteractionPoint = getTargetedInteractionPoint();
|
ArmInteractionPoint armInteractionPoint = getTargetedInteractionPoint();
|
||||||
if (armInteractionPoint != null)
|
if (armInteractionPoint != null && armInteractionPoint.isValid())
|
||||||
for (int i = 0; i < armInteractionPoint.getSlotCount(level); i++) {
|
for (int i = 0; i < armInteractionPoint.getSlotCount(); i++) {
|
||||||
int amountExtracted = getDistributableAmount(armInteractionPoint, i);
|
int amountExtracted = getDistributableAmount(armInteractionPoint, i);
|
||||||
if (amountExtracted == 0)
|
if (amountExtracted == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ItemStack prevHeld = heldItem;
|
ItemStack prevHeld = heldItem;
|
||||||
heldItem = armInteractionPoint.extract(level, i, amountExtracted, false);
|
heldItem = armInteractionPoint.extract(i, amountExtracted, false);
|
||||||
phase = Phase.SEARCH_OUTPUTS;
|
phase = Phase.SEARCH_OUTPUTS;
|
||||||
chasedPointProgress = 0;
|
chasedPointProgress = 0;
|
||||||
chasedPointIndex = -1;
|
chasedPointIndex = -1;
|
||||||
|
@ -366,15 +376,6 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
||||||
setChanged();
|
setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemStack simulateInsertion(ItemStack stack) {
|
|
||||||
for (ArmInteractionPoint armInteractionPoint : outputs) {
|
|
||||||
stack = armInteractionPoint.insert(level, stack, true);
|
|
||||||
if (stack.isEmpty())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void redstoneUpdate() {
|
public void redstoneUpdate() {
|
||||||
if (level.isClientSide)
|
if (level.isClientSide)
|
||||||
return;
|
return;
|
||||||
|
@ -392,8 +393,8 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
||||||
if (interactionPointTag == null)
|
if (interactionPointTag == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (Tag inbt : interactionPointTag) {
|
for (Tag tag : interactionPointTag) {
|
||||||
ArmInteractionPoint.transformPos(transform, (CompoundTag) inbt);
|
ArmInteractionPoint.transformPos((CompoundTag) tag, transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyUpdate();
|
notifyUpdate();
|
||||||
|
@ -408,15 +409,15 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
||||||
outputs.clear();
|
outputs.clear();
|
||||||
|
|
||||||
boolean hasBlazeBurner = false;
|
boolean hasBlazeBurner = false;
|
||||||
for (Tag inbt : interactionPointTag) {
|
for (Tag tag : interactionPointTag) {
|
||||||
ArmInteractionPoint point = ArmInteractionPoint.deserialize(level, worldPosition, (CompoundTag) inbt);
|
ArmInteractionPoint point = ArmInteractionPoint.deserialize((CompoundTag) tag, level, worldPosition);
|
||||||
if (point == null)
|
if (point == null)
|
||||||
continue;
|
continue;
|
||||||
if (point.mode == Mode.DEPOSIT)
|
if (point.getMode() == Mode.DEPOSIT)
|
||||||
outputs.add(point);
|
outputs.add(point);
|
||||||
if (point.mode == Mode.TAKE)
|
else if (point.getMode() == Mode.TAKE)
|
||||||
inputs.add(point);
|
inputs.add(point);
|
||||||
hasBlazeBurner |= point instanceof ArmInteractionPoint.BlazeBurner;
|
hasBlazeBurner |= point instanceof AllArmInteractionPointTypes.BlazeBurnerPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!level.isClientSide) {
|
if (!level.isClientSide) {
|
||||||
|
@ -496,6 +497,10 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
||||||
previousPoint == null ? ArmAngleTarget.NO_TARGET : previousPoint.getTargetAngles(worldPosition, ceiling);
|
previousPoint == null ? ArmAngleTarget.NO_TARGET : previousPoint.getTargetAngles(worldPosition, ceiling);
|
||||||
if (previousPoint != null)
|
if (previousPoint != null)
|
||||||
previousBaseAngle = previousPoint.getTargetAngles(worldPosition, ceiling).baseAngle;
|
previousBaseAngle = previousPoint.getTargetAngles(worldPosition, ceiling).baseAngle;
|
||||||
|
|
||||||
|
ArmInteractionPoint targetedPoint = getTargetedInteractionPoint();
|
||||||
|
if (targetedPoint != null)
|
||||||
|
targetedPoint.updateCachedState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,6 +523,16 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLevel(Level level) {
|
||||||
|
super.setLevel(level);
|
||||||
|
for (ArmInteractionPoint input : inputs) {
|
||||||
|
input.setLevel(level);
|
||||||
|
}
|
||||||
|
for (ArmInteractionPoint output : outputs) {
|
||||||
|
output.setLevel(level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class SelectionModeValueBox extends CenteredSideValueBoxTransform {
|
private class SelectionModeValueBox extends CenteredSideValueBoxTransform {
|
||||||
|
|
||||||
public SelectionModeValueBox() {
|
public SelectionModeValueBox() {
|
||||||
|
|
|
@ -77,6 +77,13 @@ public interface ItemAttribute {
|
||||||
return attributeType;
|
return attributeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ItemAttribute fromNBT(CompoundTag nbt) {
|
||||||
|
for (ItemAttribute itemAttribute : types)
|
||||||
|
if (itemAttribute.canRead(nbt))
|
||||||
|
return itemAttribute.readNBT(nbt.getCompound(itemAttribute.getNBTKey()));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
default boolean appliesTo(ItemStack stack, Level world) {
|
default boolean appliesTo(ItemStack stack, Level world) {
|
||||||
return appliesTo(stack);
|
return appliesTo(stack);
|
||||||
}
|
}
|
||||||
|
@ -87,29 +94,20 @@ public interface ItemAttribute {
|
||||||
return listAttributesOf(stack);
|
return listAttributesOf(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ItemAttribute> listAttributesOf(ItemStack stack);
|
List<ItemAttribute> listAttributesOf(ItemStack stack);
|
||||||
|
|
||||||
public String getTranslationKey();
|
String getTranslationKey();
|
||||||
|
|
||||||
void writeNBT(CompoundTag nbt);
|
void writeNBT(CompoundTag nbt);
|
||||||
|
|
||||||
ItemAttribute readNBT(CompoundTag nbt);
|
ItemAttribute readNBT(CompoundTag nbt);
|
||||||
|
|
||||||
public default void serializeNBT(CompoundTag nbt) {
|
default void serializeNBT(CompoundTag nbt) {
|
||||||
CompoundTag compound = new CompoundTag();
|
CompoundTag compound = new CompoundTag();
|
||||||
writeNBT(compound);
|
writeNBT(compound);
|
||||||
nbt.put(getNBTKey(), compound);
|
nbt.put(getNBTKey(), compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ItemAttribute fromNBT(CompoundTag nbt) {
|
|
||||||
for (ItemAttribute itemAttribute : types) {
|
|
||||||
if (!itemAttribute.canRead(nbt))
|
|
||||||
continue;
|
|
||||||
return itemAttribute.readNBT(nbt.getCompound(itemAttribute.getNBTKey()));
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
default Object[] getTranslationParameters() {
|
default Object[] getTranslationParameters() {
|
||||||
return new String[0];
|
return new String[0];
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,8 @@ import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public class TransportedItemStackHandlerBehaviour extends TileEntityBehaviour {
|
public class TransportedItemStackHandlerBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
public static BehaviourType<TransportedItemStackHandlerBehaviour> TYPE = new BehaviourType<>();
|
public static final BehaviourType<TransportedItemStackHandlerBehaviour> TYPE = new BehaviourType<>();
|
||||||
|
|
||||||
private ProcessingCallback processingCallback;
|
private ProcessingCallback processingCallback;
|
||||||
private PositionGetter positionGetter;
|
private PositionGetter positionGetter;
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
public class FilteringBehaviour extends TileEntityBehaviour {
|
public class FilteringBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
public static BehaviourType<FilteringBehaviour> TYPE = new BehaviourType<>();
|
public static final BehaviourType<FilteringBehaviour> TYPE = new BehaviourType<>();
|
||||||
|
|
||||||
ValueBoxTransform slotPositioning;
|
ValueBoxTransform slotPositioning;
|
||||||
boolean showCount;
|
boolean showCount;
|
||||||
|
|
|
@ -22,9 +22,9 @@ import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||||
|
|
||||||
public class SmartFluidTankBehaviour extends TileEntityBehaviour {
|
public class SmartFluidTankBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
public static BehaviourType<SmartFluidTankBehaviour>
|
public static final BehaviourType<SmartFluidTankBehaviour>
|
||||||
|
|
||||||
TYPE = new BehaviourType<>(), INPUT = new BehaviourType<>("Input"), OUTPUT = new BehaviourType<>("Output");
|
TYPE = new BehaviourType<>(), INPUT = new BehaviourType<>("Input"), oOUTPUT = new BehaviourType<>("Output");
|
||||||
|
|
||||||
private static final int SYNC_RATE = 8;
|
private static final int SYNC_RATE = 8;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
|
||||||
|
|
||||||
public class TankManipulationBehaviour extends CapManipulationBehaviourBase<IFluidHandler, TankManipulationBehaviour> {
|
public class TankManipulationBehaviour extends CapManipulationBehaviourBase<IFluidHandler, TankManipulationBehaviour> {
|
||||||
|
|
||||||
public static BehaviourType<TankManipulationBehaviour> OBSERVE = new BehaviourType<>();
|
public static final BehaviourType<TankManipulationBehaviour> OBSERVE = new BehaviourType<>();
|
||||||
private BehaviourType<TankManipulationBehaviour> behaviourType;
|
private BehaviourType<TankManipulationBehaviour> behaviourType;
|
||||||
|
|
||||||
public TankManipulationBehaviour(SmartTileEntity te, InterfaceProvider target) {
|
public TankManipulationBehaviour(SmartTileEntity te, InterfaceProvider target) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public class LinkBehaviour extends TileEntityBehaviour implements IRedstoneLinkable {
|
public class LinkBehaviour extends TileEntityBehaviour implements IRedstoneLinkable {
|
||||||
|
|
||||||
public static BehaviourType<LinkBehaviour> TYPE = new BehaviourType<>();
|
public static final BehaviourType<LinkBehaviour> TYPE = new BehaviourType<>();
|
||||||
|
|
||||||
enum Mode {
|
enum Mode {
|
||||||
TRANSMIT, RECEIVE
|
TRANSMIT, RECEIVE
|
||||||
|
|
|
@ -18,7 +18,7 @@ import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public class ScrollValueBehaviour extends TileEntityBehaviour {
|
public class ScrollValueBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
public static BehaviourType<ScrollValueBehaviour> TYPE = new BehaviourType<>();
|
public static final BehaviourType<ScrollValueBehaviour> TYPE = new BehaviourType<>();
|
||||||
|
|
||||||
ValueBoxTransform slotPositioning;
|
ValueBoxTransform slotPositioning;
|
||||||
Vec3 textShift;
|
Vec3 textShift;
|
||||||
|
|
|
@ -10,7 +10,7 @@ import net.minecraft.nbt.CompoundTag;
|
||||||
|
|
||||||
public class DeferralBehaviour extends TileEntityBehaviour {
|
public class DeferralBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
public static BehaviourType<DeferralBehaviour> TYPE = new BehaviourType<>();
|
public static final BehaviourType<DeferralBehaviour> TYPE = new BehaviourType<>();
|
||||||
|
|
||||||
private boolean needsUpdate;
|
private boolean needsUpdate;
|
||||||
private Supplier<Boolean> callback;
|
private Supplier<Boolean> callback;
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
{
|
|
||||||
"credit": "Made with Blockbench",
|
|
||||||
"parent": "block/block",
|
|
||||||
"textures": {
|
|
||||||
"4": "create:block/marker_flag"
|
|
||||||
},
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"from": [0, 0, 0],
|
|
||||||
"to": [1, 16, 1],
|
|
||||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -3, 10]},
|
|
||||||
"faces": {
|
|
||||||
"north": {"uv": [1, 0, 2, 16], "texture": "#4"},
|
|
||||||
"east": {"uv": [0, 0, 1, 16], "texture": "#4"},
|
|
||||||
"south": {"uv": [1, 0, 2, 16], "texture": "#4"},
|
|
||||||
"west": {"uv": [0, 0, 1, 16], "texture": "#4"},
|
|
||||||
"up": {"uv": [0, 0, 1, 1], "texture": "#4"},
|
|
||||||
"down": {"uv": [0, 0, 1, 1], "texture": "#4"}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": [0.4, 7.5, 1],
|
|
||||||
"to": [0.4, 15.5, 9],
|
|
||||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -3, 10]},
|
|
||||||
"faces": {
|
|
||||||
"east": {"uv": [16, 0, 8, 8], "texture": "#4", "tintindex": 0},
|
|
||||||
"west": {"uv": [8, 0, 16, 8], "texture": "#4", "tintindex": 0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
{
|
|
||||||
"credit": "Made with Blockbench",
|
|
||||||
"parent": "block/block",
|
|
||||||
"textures": {
|
|
||||||
"4": "create:block/marker_flag"
|
|
||||||
},
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"from": [0, 0, 0],
|
|
||||||
"to": [1, 16, 1],
|
|
||||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -3, 10]},
|
|
||||||
"faces": {
|
|
||||||
"north": {"uv": [1, 0, 2, 16], "texture": "#4"},
|
|
||||||
"east": {"uv": [0, 0, 1, 16], "texture": "#4"},
|
|
||||||
"south": {"uv": [1, 0, 2, 16], "texture": "#4"},
|
|
||||||
"west": {"uv": [0, 0, 1, 16], "texture": "#4"},
|
|
||||||
"up": {"uv": [0, 0, 1, 1], "texture": "#4"},
|
|
||||||
"down": {"uv": [0, 0, 1, 1], "texture": "#4"}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": [0.4, 7.5, 1],
|
|
||||||
"to": [0.4, 15.5, 9],
|
|
||||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -3, 10]},
|
|
||||||
"faces": {
|
|
||||||
"east": {"uv": [16, 8, 8, 16], "texture": "#4", "tintindex": 0},
|
|
||||||
"west": {"uv": [8, 8, 16, 16], "texture": "#4", "tintindex": 0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
{
|
|
||||||
"credit": "Made with Blockbench",
|
|
||||||
"parent": "block/block",
|
|
||||||
"textures": {
|
|
||||||
"4": "create:block/marker_flag"
|
|
||||||
},
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"from": [0, 0, 0],
|
|
||||||
"to": [1, 8, 1],
|
|
||||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -3, 10]},
|
|
||||||
"faces": {
|
|
||||||
"north": {"uv": [1, 8, 2, 16], "texture": "#4"},
|
|
||||||
"east": {"uv": [0, 0, 1, 8], "texture": "#4"},
|
|
||||||
"south": {"uv": [1, 0, 2, 8], "texture": "#4"},
|
|
||||||
"west": {"uv": [0, 0, 1, 8], "texture": "#4"},
|
|
||||||
"up": {"uv": [0, 0, 1, 1], "texture": "#4"},
|
|
||||||
"down": {"uv": [0, 0, 1, 1], "texture": "#4"}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": [0.4, -0.5, 1],
|
|
||||||
"to": [0.4, 7.5, 9],
|
|
||||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -3, 10]},
|
|
||||||
"faces": {
|
|
||||||
"east": {"uv": [16, 0, 8, 8], "texture": "#4", "tintindex": 0},
|
|
||||||
"west": {"uv": [8, 0, 16, 8], "texture": "#4", "tintindex": 0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
{
|
|
||||||
"credit": "Made with Blockbench",
|
|
||||||
"parent": "block/block",
|
|
||||||
"textures": {
|
|
||||||
"4": "create:block/marker_flag"
|
|
||||||
},
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"from": [0, 0, 0],
|
|
||||||
"to": [1, 8, 1],
|
|
||||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -3, 10]},
|
|
||||||
"faces": {
|
|
||||||
"north": {"uv": [1, 8, 2, 16], "texture": "#4"},
|
|
||||||
"east": {"uv": [0, 0, 1, 8], "texture": "#4"},
|
|
||||||
"south": {"uv": [1, 0, 2, 8], "texture": "#4"},
|
|
||||||
"west": {"uv": [0, 0, 1, 8], "texture": "#4"},
|
|
||||||
"up": {"uv": [0, 0, 1, 1], "texture": "#4"},
|
|
||||||
"down": {"uv": [0, 0, 1, 1], "texture": "#4"}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": [0.4, -0.5, 1],
|
|
||||||
"to": [0.4, 7.5, 9],
|
|
||||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -3, 10]},
|
|
||||||
"faces": {
|
|
||||||
"east": {"uv": [16, 8, 8, 16], "texture": "#4", "tintindex": 0},
|
|
||||||
"west": {"uv": [8, 8, 16, 16], "texture": "#4", "tintindex": 0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 196 B |
Loading…
Reference in a new issue