Pushing the Pusher
- Ore features no longer spawn in the "void" or "hell" biome - Fixed Minecart contraptions killing their own mount using saws/drills - Pistons, Bearings and Pulleys can now be moved unless they are moving something themselves - Fixed cart assemblers blocking in the powered rail kickstart logic - Piston poles can now be moved - Crushing wheels no longer spawn missing texture particles when sprinting on the central block - Deployers' hand items can now be directly inserted/extracted using hoppers, extractors, funnels, etc - Fixed Deployers not dropping held items when destroyed - Millstones now empty their input inventory when clicked on while their output buffer is empty - Millstones no longer accept items they cannot process - Fixed hoppers not being able to pull items from belts in certain cases - Fixed adjustable crates corrupting chunks
This commit is contained in:
parent
e2742f6fb2
commit
72ddc1251a
19 changed files with 312 additions and 31 deletions
|
@ -34,7 +34,7 @@ public abstract class SyncedTileEntity extends TileEntity {
|
||||||
public void causeBlockUpdate() {
|
public void causeBlockUpdate() {
|
||||||
world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 1);
|
world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SUpdateTileEntityPacket getUpdatePacket() {
|
public SUpdateTileEntityPacket getUpdatePacket() {
|
||||||
return new SUpdateTileEntityPacket(getPos(), 1, writeToClient(new CompoundNBT()));
|
return new SUpdateTileEntityPacket(getPos(), 1, writeToClient(new CompoundNBT()));
|
||||||
|
|
|
@ -12,6 +12,7 @@ import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.biome.Biomes;
|
||||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec;
|
import net.minecraftforge.common.ForgeConfigSpec;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
@ -33,11 +34,12 @@ public enum AllWorldFeatures {
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increment this number if all worldgen entries should be overwritten in this update.
|
* Increment this number if all worldgen entries should be overwritten in this
|
||||||
* Worlds from the previous version will overwrite potentially changed values with the new defaults.
|
* update. Worlds from the previous version will overwrite potentially changed
|
||||||
|
* values with the new defaults.
|
||||||
*/
|
*/
|
||||||
public static final int forcedUpdateVersion = 1;
|
public static final int forcedUpdateVersion = 1;
|
||||||
|
|
||||||
public IFeature feature;
|
public IFeature feature;
|
||||||
private Map<Biome, ConfiguredFeature<?>> featureInstances;
|
private Map<Biome, ConfiguredFeature<?>> featureInstances;
|
||||||
|
|
||||||
|
@ -51,9 +53,13 @@ public enum AllWorldFeatures {
|
||||||
for (AllWorldFeatures entry : AllWorldFeatures.values()) {
|
for (AllWorldFeatures entry : AllWorldFeatures.values()) {
|
||||||
for (Biome biome : ForgeRegistries.BIOMES) {
|
for (Biome biome : ForgeRegistries.BIOMES) {
|
||||||
|
|
||||||
|
if (biome == Biomes.THE_VOID)
|
||||||
|
continue;
|
||||||
|
if (biome == Biomes.NETHER)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (entry.featureInstances.containsKey(biome))
|
if (entry.featureInstances.containsKey(biome))
|
||||||
biome.getFeatures(entry.feature.getGenerationStage()).remove(entry.featureInstances.remove(biome));
|
biome.getFeatures(entry.feature.getGenerationStage()).remove(entry.featureInstances.remove(biome));
|
||||||
|
|
||||||
Optional<ConfiguredFeature<?>> createFeature = entry.feature.createFeature(biome);
|
Optional<ConfiguredFeature<?>> createFeature = entry.feature.createFeature(biome);
|
||||||
if (!createFeature.isPresent())
|
if (!createFeature.isPresent())
|
||||||
continue;
|
continue;
|
||||||
|
@ -62,7 +68,7 @@ public enum AllWorldFeatures {
|
||||||
biome.addFeature(entry.feature.getGenerationStage(), createFeature.get());
|
biome.addFeature(entry.feature.getGenerationStage(), createFeature.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Debug contained ore features
|
// // Debug contained ore features
|
||||||
// for (Biome biome : ForgeRegistries.BIOMES) {
|
// for (Biome biome : ForgeRegistries.BIOMES) {
|
||||||
// Debug.markTemporary();
|
// Debug.markTemporary();
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package com.simibubi.create.modules.contraptions.components.actors;
|
package com.simibubi.create.modules.contraptions.components.actors;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.BlockHelper;
|
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour;
|
import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
|
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.nbt.NBTUtil;
|
import net.minecraft.nbt.NBTUtil;
|
||||||
import net.minecraft.util.DamageSource;
|
import net.minecraft.util.DamageSource;
|
||||||
|
@ -37,8 +39,17 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour {
|
||||||
if (damageSource == null)
|
if (damageSource == null)
|
||||||
return;
|
return;
|
||||||
for (Entity entity : world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos))) {
|
for (Entity entity : world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos))) {
|
||||||
|
|
||||||
if (entity instanceof ItemEntity)
|
if (entity instanceof ItemEntity)
|
||||||
return;
|
return;
|
||||||
|
if (entity instanceof ContraptionEntity)
|
||||||
|
return;
|
||||||
|
if (entity instanceof AbstractMinecartEntity)
|
||||||
|
for (Entity passenger : entity.getRecursivePassengers())
|
||||||
|
if (passenger instanceof ContraptionEntity
|
||||||
|
&& ((ContraptionEntity) passenger).getContraption() == context.contraption)
|
||||||
|
return;
|
||||||
|
|
||||||
float damage = (float) MathHelper.clamp(Math.abs(context.relativeMotion.length() * 10) + 1, 5, 20);
|
float damage = (float) MathHelper.clamp(Math.abs(context.relativeMotion.length() * 10) + 1, 5, 20);
|
||||||
entity.attackEntityFrom(damageSource, damage);
|
entity.attackEntityFrom(damageSource, damage);
|
||||||
entity.setMotion(entity.getMotion().add(context.relativeMotion.scale(3)));
|
entity.setMotion(entity.getMotion().add(context.relativeMotion.scale(3)));
|
||||||
|
|
|
@ -3,7 +3,15 @@ package com.simibubi.create.modules.contraptions.components.contraptions;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock;
|
import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock;
|
import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingTileEntity;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity;
|
||||||
import com.simibubi.create.modules.logistics.block.AttachedLogisticalBlock;
|
import com.simibubi.create.modules.logistics.block.AttachedLogisticalBlock;
|
||||||
import com.simibubi.create.modules.logistics.block.RedstoneLinkBlock;
|
import com.simibubi.create.modules.logistics.block.RedstoneLinkBlock;
|
||||||
import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock;
|
import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock;
|
||||||
|
@ -28,6 +36,7 @@ import net.minecraft.block.WallTorchBlock;
|
||||||
import net.minecraft.block.material.PushReaction;
|
import net.minecraft.block.material.PushReaction;
|
||||||
import net.minecraft.state.properties.AttachFace;
|
import net.minecraft.state.properties.AttachFace;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
@ -56,6 +65,26 @@ public class BlockMovementTraits {
|
||||||
return false;
|
return false;
|
||||||
if (block == Blocks.OBSIDIAN)
|
if (block == Blocks.OBSIDIAN)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Move controllers only when they aren't moving
|
||||||
|
if (block instanceof MechanicalPistonBlock && blockState.get(MechanicalPistonBlock.STATE) != PistonState.MOVING)
|
||||||
|
return true;
|
||||||
|
if (block instanceof MechanicalBearingBlock) {
|
||||||
|
TileEntity te = world.getTileEntity(pos);
|
||||||
|
if (te instanceof MechanicalBearingTileEntity)
|
||||||
|
return !((MechanicalBearingTileEntity) te).isRunning();
|
||||||
|
}
|
||||||
|
if (block instanceof ClockworkBearingBlock) {
|
||||||
|
TileEntity te = world.getTileEntity(pos);
|
||||||
|
if (te instanceof ClockworkBearingTileEntity)
|
||||||
|
return !((ClockworkBearingTileEntity) te).isRunning();
|
||||||
|
}
|
||||||
|
if (block instanceof PulleyBlock) {
|
||||||
|
TileEntity te = world.getTileEntity(pos);
|
||||||
|
if (te instanceof PulleyTileEntity)
|
||||||
|
return !((PulleyTileEntity) te).running && ((PulleyTileEntity) te).offset == 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (AllBlocks.BELT.typeOf(blockState))
|
if (AllBlocks.BELT.typeOf(blockState))
|
||||||
return true;
|
return true;
|
||||||
if (block instanceof ExtractorBlock)
|
if (block instanceof ExtractorBlock)
|
||||||
|
@ -113,7 +142,7 @@ public class BlockMovementTraits {
|
||||||
return direction == Direction.DOWN;
|
return direction == Direction.DOWN;
|
||||||
if (block instanceof DoorBlock)
|
if (block instanceof DoorBlock)
|
||||||
return direction == Direction.DOWN;
|
return direction == Direction.DOWN;
|
||||||
if (block instanceof AttachedLogisticalBlock && !(block instanceof TransposerBlock))
|
if (block instanceof AttachedLogisticalBlock && !(block instanceof TransposerBlock))
|
||||||
return direction == AttachedLogisticalBlock.getBlockFacing(state);
|
return direction == AttachedLogisticalBlock.getBlockFacing(state);
|
||||||
if (block instanceof RedstoneLinkBlock)
|
if (block instanceof RedstoneLinkBlock)
|
||||||
return direction.getOpposite() == state.get(RedstoneLinkBlock.FACING);
|
return direction.getOpposite() == state.get(RedstoneLinkBlock.FACING);
|
||||||
|
@ -161,14 +190,4 @@ public class BlockMovementTraits {
|
||||||
return isBrittle(state);
|
return isBrittle(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean movementIgnored(BlockState state) {
|
|
||||||
if (AllBlocks.MECHANICAL_PISTON.typeOf(state))
|
|
||||||
return true;
|
|
||||||
if (AllBlocks.STICKY_MECHANICAL_PISTON.typeOf(state))
|
|
||||||
return true;
|
|
||||||
if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,10 @@ import com.simibubi.create.foundation.utility.WrappedWorld;
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
|
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.PistonPoleBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonHeadBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.saw.SawBlock;
|
import com.simibubi.create.modules.contraptions.components.saw.SawBlock;
|
||||||
import com.simibubi.create.modules.contraptions.redstone.ContactBlock;
|
import com.simibubi.create.modules.contraptions.redstone.ContactBlock;
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||||
|
@ -160,6 +164,49 @@ public abstract class Contraption {
|
||||||
if (prevPos != null && !visited.contains(prevPos))
|
if (prevPos != null && !visited.contains(prevPos))
|
||||||
frontier.add(prevPos);
|
frontier.add(prevPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state.getBlock() instanceof MechanicalPistonBlock) {
|
||||||
|
int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get();
|
||||||
|
Direction direction = state.get(MechanicalPistonBlock.FACING);
|
||||||
|
if (state.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) {
|
||||||
|
BlockPos searchPos = pos;
|
||||||
|
while (limit-- >= 0) {
|
||||||
|
searchPos = searchPos.offset(direction);
|
||||||
|
BlockState blockState = world.getBlockState(searchPos);
|
||||||
|
if (AllBlocks.PISTON_POLE.typeOf(blockState)) {
|
||||||
|
if (blockState.get(PistonPoleBlock.FACING).getAxis() != direction.getAxis())
|
||||||
|
break;
|
||||||
|
if (!visited.contains(searchPos))
|
||||||
|
frontier.add(searchPos);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (blockState.getBlock() instanceof MechanicalPistonHeadBlock)
|
||||||
|
if (!visited.contains(searchPos))
|
||||||
|
frontier.add(searchPos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (limit <= -1)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockPos searchPos = pos;
|
||||||
|
while (limit-- >= 0) {
|
||||||
|
searchPos = searchPos.offset(direction.getOpposite());
|
||||||
|
BlockState blockState = world.getBlockState(searchPos);
|
||||||
|
if (AllBlocks.PISTON_POLE.typeOf(blockState)) {
|
||||||
|
if (blockState.get(PistonPoleBlock.FACING).getAxis() != direction.getAxis())
|
||||||
|
break;
|
||||||
|
if (!visited.contains(searchPos))
|
||||||
|
frontier.add(searchPos);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (limit <= -1)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (state.getBlock() instanceof DoorBlock) {
|
if (state.getBlock() instanceof DoorBlock) {
|
||||||
BlockPos otherPartPos = pos.up(state.get(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? 1 : -1);
|
BlockPos otherPartPos = pos.up(state.get(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? 1 : -1);
|
||||||
if (!visited.contains(otherPartPos))
|
if (!visited.contains(otherPartPos))
|
||||||
|
@ -170,7 +217,7 @@ public abstract class Contraption {
|
||||||
for (Direction offset : Direction.values()) {
|
for (Direction offset : Direction.values()) {
|
||||||
BlockPos offsetPos = pos.offset(offset);
|
BlockPos offsetPos = pos.offset(offset);
|
||||||
BlockState blockState = world.getBlockState(offsetPos);
|
BlockState blockState = world.getBlockState(offsetPos);
|
||||||
if (BlockMovementTraits.movementIgnored(blockState))
|
if (isAnchoringBlockAt(offsetPos))
|
||||||
continue;
|
continue;
|
||||||
if (!BlockMovementTraits.movementAllowed(world, offsetPos)) {
|
if (!BlockMovementTraits.movementAllowed(world, offsetPos)) {
|
||||||
if (offset == forcedDirection && isSlimeBlock)
|
if (offset == forcedDirection && isSlimeBlock)
|
||||||
|
@ -188,6 +235,10 @@ public abstract class Contraption {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isAnchoringBlockAt(BlockPos pos) {
|
||||||
|
return pos.equals(anchor);
|
||||||
|
}
|
||||||
|
|
||||||
protected static boolean isChassis(BlockState state) {
|
protected static boolean isChassis(BlockState state) {
|
||||||
return state.getBlock() instanceof AbstractChassisBlock;
|
return state.getBlock() instanceof AbstractChassisBlock;
|
||||||
}
|
}
|
||||||
|
|
|
@ -299,4 +299,8 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
||||||
return this.minuteHand == contraption;
|
return this.minuteHand == contraption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isRunning() {
|
||||||
|
return running;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,5 +298,9 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
||||||
public boolean isAttachedTo(ContraptionEntity contraption) {
|
public boolean isAttachedTo(ContraptionEntity contraption) {
|
||||||
return movedContraption == contraption;
|
return movedContraption == contraption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isRunning() {
|
||||||
|
return running;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,6 +129,11 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
||||||
public PushReaction getPushReaction(BlockState state) {
|
public PushReaction getPushReaction(BlockState state) {
|
||||||
return PushReaction.BLOCK;
|
return PushReaction.BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNormalCube(BlockState state, IBlockReader worldIn, BlockPos pos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static class MinecartAnchorBlock extends RenderUtilityBlock {
|
public static class MinecartAnchorBlock extends RenderUtilityBlock {
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import com.simibubi.create.modules.contraptions.components.contraptions.piston.M
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.material.PushReaction;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.state.EnumProperty;
|
import net.minecraft.state.EnumProperty;
|
||||||
|
@ -37,6 +38,11 @@ public class MechanicalPistonHeadBlock extends ProperDirectionalBlock implements
|
||||||
super.fillStateContainer(builder);
|
super.fillStateContainer(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PushReaction getPushReaction(BlockState state) {
|
||||||
|
return PushReaction.NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getPickBlock(BlockState state, RayTraceResult target, IBlockReader world, BlockPos pos,
|
public ItemStack getPickBlock(BlockState state, RayTraceResult target, IBlockReader world, BlockPos pos,
|
||||||
PlayerEntity player) {
|
PlayerEntity player) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.simibubi.create.modules.contraptions.components.contraptions.piston.M
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.material.PushReaction;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.BlockItemUseContext;
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
@ -25,6 +26,11 @@ public class PistonPoleBlock extends ProperDirectionalBlock {
|
||||||
super(Properties.from(Blocks.PISTON_HEAD));
|
super(Properties.from(Blocks.PISTON_HEAD));
|
||||||
setDefaultState(getDefaultState().with(FACING, Direction.UP));
|
setDefaultState(getDefaultState().with(FACING, Direction.UP));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PushReaction getPushReaction(BlockState state) {
|
||||||
|
return PushReaction.NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) {
|
public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) {
|
||||||
|
|
|
@ -30,6 +30,11 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
||||||
return super.getRenderBoundingBox().expand(0, -offset, 0);
|
return super.getRenderBoundingBox().expand(0, -offset, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getMaxRenderDistanceSquared() {
|
||||||
|
return super.getMaxRenderDistanceSquared() + offset * offset;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assemble() {
|
protected void assemble() {
|
||||||
if (speed == 0)
|
if (speed == 0)
|
||||||
|
@ -151,7 +156,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getExtensionRange() {
|
protected int getExtensionRange() {
|
||||||
return Math.min(AllConfigs.SERVER.kinetics.maxRopeLength.get(), pos.getY() - 1);
|
return Math.max(0, Math.min(AllConfigs.SERVER.kinetics.maxRopeLength.get(), pos.getY() - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -53,6 +53,11 @@ public class CrushingWheelControllerBlock extends Block
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addRunningEffects(BlockState state, World world, BlockPos pos, Entity entity) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||||
return new CrushingWheelControllerTileEntity();
|
return new CrushingWheelControllerTileEntity();
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.deployer;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||||
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
|
public class DeployerItemHandler implements IItemHandlerModifiable {
|
||||||
|
|
||||||
|
private DeployerTileEntity te;
|
||||||
|
private DeployerFakePlayer player;
|
||||||
|
|
||||||
|
public DeployerItemHandler(DeployerTileEntity te) {
|
||||||
|
this.te = te;
|
||||||
|
this.player = te.player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSlots() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getStackInSlot(int slot) {
|
||||||
|
return getHeld();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getHeld() {
|
||||||
|
if (player == null)
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
return player.getHeldItemMainhand();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(ItemStack stack) {
|
||||||
|
if (player == null)
|
||||||
|
return;
|
||||||
|
if (te.getWorld().isRemote)
|
||||||
|
return;
|
||||||
|
player.setHeldItem(Hand.MAIN_HAND, stack);
|
||||||
|
te.markDirty();
|
||||||
|
te.sendData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
|
||||||
|
ItemStack held = getHeld();
|
||||||
|
if (!isItemValid(slot, stack))
|
||||||
|
return stack;
|
||||||
|
if (held.isEmpty()) {
|
||||||
|
if (!simulate)
|
||||||
|
set(stack);
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
if (!ItemHandlerHelper.canItemStacksStack(held, stack))
|
||||||
|
return stack;
|
||||||
|
|
||||||
|
int space = held.getMaxStackSize() - held.getCount();
|
||||||
|
ItemStack split = stack.copy().split(space);
|
||||||
|
|
||||||
|
if (space == 0)
|
||||||
|
return stack;
|
||||||
|
if (!simulate) {
|
||||||
|
held = held.copy();
|
||||||
|
held.setCount(held.getCount() + split.getCount());
|
||||||
|
set(held);
|
||||||
|
}
|
||||||
|
|
||||||
|
return split;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||||
|
ItemStack held = getHeld();
|
||||||
|
if (amount == 0 || held.isEmpty())
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
if (simulate)
|
||||||
|
return held.copy().split(amount);
|
||||||
|
|
||||||
|
ItemStack toReturn = held.split(amount);
|
||||||
|
te.markDirty();
|
||||||
|
te.sendData();
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSlotLimit(int slot) {
|
||||||
|
return Math.min(getHeld().getMaxStackSize(), 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isItemValid(int slot, ItemStack stack) {
|
||||||
|
FilteringBehaviour filteringBehaviour = TileEntityBehaviour.get(te, FilteringBehaviour.TYPE);
|
||||||
|
return filteringBehaviour == null || filteringBehaviour.test(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setStackInSlot(int slot, ItemStack stack) {
|
||||||
|
set(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -41,8 +41,12 @@ import net.minecraft.util.math.RayTraceContext.BlockMode;
|
||||||
import net.minecraft.util.math.RayTraceContext.FluidMode;
|
import net.minecraft.util.math.RayTraceContext.FluidMode;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.server.ServerWorld;
|
import net.minecraft.world.server.ServerWorld;
|
||||||
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
import net.minecraftforge.common.util.Constants.NBT;
|
import net.minecraftforge.common.util.Constants.NBT;
|
||||||
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||||
import net.minecraftforge.items.ItemHandlerHelper;
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
public class DeployerTileEntity extends KineticTileEntity {
|
public class DeployerTileEntity extends KineticTileEntity {
|
||||||
|
@ -61,6 +65,7 @@ public class DeployerTileEntity extends KineticTileEntity {
|
||||||
protected boolean boop = false;
|
protected boolean boop = false;
|
||||||
protected List<ItemStack> overflowItems = new ArrayList<>();
|
protected List<ItemStack> overflowItems = new ArrayList<>();
|
||||||
private ListNBT deferredInventoryList;
|
private ListNBT deferredInventoryList;
|
||||||
|
private LazyOptional<IItemHandlerModifiable> invHandler;
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
WAITING, EXPANDING, RETRACTING, DUMPING;
|
WAITING, EXPANDING, RETRACTING, DUMPING;
|
||||||
|
@ -98,7 +103,10 @@ public class DeployerTileEntity extends KineticTileEntity {
|
||||||
heldItem = player.getHeldItemMainhand();
|
heldItem = player.getHeldItemMainhand();
|
||||||
sendData();
|
sendData();
|
||||||
}
|
}
|
||||||
|
Vec3d initialPos = VecHelper.getCenterOf(pos.offset(getBlockState().get(FACING)));
|
||||||
|
player.setPosition(initialPos.x, initialPos.y, initialPos.z);
|
||||||
}
|
}
|
||||||
|
invHandler = LazyOptional.of(this::createHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onExtract(ItemStack stack) {
|
protected void onExtract(ItemStack stack) {
|
||||||
|
@ -372,6 +380,10 @@ public class DeployerTileEntity extends KineticTileEntity {
|
||||||
super.readClientUpdate(tag);
|
super.readClientUpdate(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IItemHandlerModifiable createHandler() {
|
||||||
|
return new DeployerItemHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasFastRenderer() {
|
public boolean hasFastRenderer() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -387,15 +399,24 @@ public class DeployerTileEntity extends KineticTileEntity {
|
||||||
return super.getRenderBoundingBox().grow(3);
|
return super.getRenderBoundingBox().grow(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
super.remove();
|
||||||
|
invHandler.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
public void changeMode() {
|
public void changeMode() {
|
||||||
eject();
|
|
||||||
mode = mode == Mode.PUNCH ? Mode.USE : Mode.PUNCH;
|
mode = mode == Mode.PUNCH ? Mode.USE : Mode.PUNCH;
|
||||||
markDirty();
|
markDirty();
|
||||||
sendData();
|
sendData();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void eject() {
|
@Override
|
||||||
|
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
||||||
|
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && invHandler != null) {
|
||||||
|
return invHandler.cast();
|
||||||
|
}
|
||||||
|
return super.getCapability(cap, side);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,11 +64,24 @@ public class MillstoneBlock extends KineticBlock implements ITE<MillstoneTileEnt
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
withTileEntityDo(worldIn, pos, millstone -> {
|
withTileEntityDo(worldIn, pos, millstone -> {
|
||||||
|
boolean emptyOutput = true;
|
||||||
IItemHandlerModifiable inv = millstone.outputInv;
|
IItemHandlerModifiable inv = millstone.outputInv;
|
||||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||||
player.inventory.placeItemBackInInventory(worldIn, inv.getStackInSlot(slot));
|
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
||||||
|
if (!stackInSlot.isEmpty())
|
||||||
|
emptyOutput = false;
|
||||||
|
player.inventory.placeItemBackInInventory(worldIn, stackInSlot);
|
||||||
inv.setStackInSlot(slot, ItemStack.EMPTY);
|
inv.setStackInSlot(slot, ItemStack.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (emptyOutput) {
|
||||||
|
inv = millstone.inputInv;
|
||||||
|
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||||
|
player.inventory.placeItemBackInInventory(worldIn, inv.getStackInSlot(slot));
|
||||||
|
inv.setStackInSlot(slot, ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
millstone.markDirty();
|
millstone.markDirty();
|
||||||
millstone.sendData();
|
millstone.sendData();
|
||||||
});
|
});
|
||||||
|
|
|
@ -142,6 +142,16 @@ public class MillstoneTileEntity extends KineticTileEntity {
|
||||||
return super.getCapability(cap, side);
|
return super.getCapability(cap, side);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean canProcess(ItemStack stack) {
|
||||||
|
ItemStackHandler tester = new ItemStackHandler(1);
|
||||||
|
tester.setStackInSlot(0, stack);
|
||||||
|
RecipeWrapper inventoryIn = new RecipeWrapper(tester);
|
||||||
|
|
||||||
|
if (lastRecipe != null && lastRecipe.matches(inventoryIn, world))
|
||||||
|
return true;
|
||||||
|
return world.getRecipeManager().getRecipe(AllRecipes.MILLING.getType(), inventoryIn, world).isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
private class MillstoneInventoryHandler extends CombinedInvWrapper {
|
private class MillstoneInventoryHandler extends CombinedInvWrapper {
|
||||||
|
|
||||||
public MillstoneInventoryHandler() {
|
public MillstoneInventoryHandler() {
|
||||||
|
@ -152,13 +162,15 @@ public class MillstoneTileEntity extends KineticTileEntity {
|
||||||
public boolean isItemValid(int slot, ItemStack stack) {
|
public boolean isItemValid(int slot, ItemStack stack) {
|
||||||
if (outputInv == getHandlerFromIndex(getIndexForSlot(slot)))
|
if (outputInv == getHandlerFromIndex(getIndexForSlot(slot)))
|
||||||
return false;
|
return false;
|
||||||
return super.isItemValid(slot, stack);
|
return canProcess(stack) && super.isItemValid(slot, stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
|
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
|
||||||
if (outputInv == getHandlerFromIndex(getIndexForSlot(slot)))
|
if (outputInv == getHandlerFromIndex(getIndexForSlot(slot)))
|
||||||
return stack;
|
return stack;
|
||||||
|
if (!isItemValid(slot, stack))
|
||||||
|
return stack;
|
||||||
return super.insertItem(slot, stack, simulate);
|
return super.insertItem(slot, stack, simulate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -379,7 +379,7 @@ public class BeltInventory {
|
||||||
float max = offset + .5f + (SEGMENT_WINDOW / 2);
|
float max = offset + .5f + (SEGMENT_WINDOW / 2);
|
||||||
for (TransportedItemStack stack : getItems()) {
|
for (TransportedItemStack stack : getItems()) {
|
||||||
if (stack.beltPosition > max)
|
if (stack.beltPosition > max)
|
||||||
break;
|
continue;
|
||||||
if (stack.beltPosition > min)
|
if (stack.beltPosition > min)
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,15 @@ import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
|
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
|
||||||
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.behaviour.linked.LinkBehaviour;
|
import com.simibubi.create.foundation.behaviour.linked.LinkBehaviour;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
@ -97,9 +98,13 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
|
||||||
return;
|
return;
|
||||||
if (world.isRemote)
|
if (world.isRemote)
|
||||||
return;
|
return;
|
||||||
if (receivedSignal != getBlockState().get(POWERED)) {
|
BlockState blockState = getBlockState();
|
||||||
world.setBlockState(pos, getBlockState().cycle(POWERED));
|
if (!AllBlocks.REDSTONE_BRIDGE.typeOf(blockState))
|
||||||
Direction attachedFace = getBlockState().get(BlockStateProperties.FACING).getOpposite();
|
return;
|
||||||
|
|
||||||
|
if (receivedSignal != blockState.get(POWERED)) {
|
||||||
|
world.setBlockState(pos, blockState.cycle(POWERED));
|
||||||
|
Direction attachedFace = blockState.get(RedstoneLinkBlock.FACING).getOpposite();
|
||||||
BlockPos attachedPos = pos.offset(attachedFace);
|
BlockPos attachedPos = pos.offset(attachedFace);
|
||||||
world.notifyNeighbors(attachedPos, world.getBlockState(attachedPos).getBlock());
|
world.notifyNeighbors(attachedPos, world.getBlockState(attachedPos).getBlock());
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -86,11 +86,15 @@ public class FlexcrateTileEntity extends SyncedTileEntity implements INamedConta
|
||||||
}
|
}
|
||||||
|
|
||||||
public FlexcrateTileEntity getMainCrate() {
|
public FlexcrateTileEntity getMainCrate() {
|
||||||
if (isDoubleCrate() && getFacing().getAxisDirection() == AxisDirection.NEGATIVE)
|
if (isSecondaryCrate())
|
||||||
return getOtherCrate();
|
return getOtherCrate();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSecondaryCrate() {
|
||||||
|
return isDoubleCrate() && getFacing().getAxisDirection() == AxisDirection.NEGATIVE;
|
||||||
|
}
|
||||||
|
|
||||||
public FlexcrateTileEntity getOtherCrate() {
|
public FlexcrateTileEntity getOtherCrate() {
|
||||||
if (!AllBlocks.FLEXCRATE.typeOf(getBlockState()))
|
if (!AllBlocks.FLEXCRATE.typeOf(getBlockState()))
|
||||||
return null;
|
return null;
|
||||||
|
@ -158,7 +162,7 @@ public class FlexcrateTileEntity extends SyncedTileEntity implements INamedConta
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundNBT write(CompoundNBT compound) {
|
public CompoundNBT write(CompoundNBT compound) {
|
||||||
if (getMainCrate() == this) {
|
if (!isSecondaryCrate()) {
|
||||||
compound.putBoolean("Main", true);
|
compound.putBoolean("Main", true);
|
||||||
compound.putInt("AllowedAmount", allowedAmount);
|
compound.putInt("AllowedAmount", allowedAmount);
|
||||||
compound.put("Inventory", inventory.serializeNBT());
|
compound.put("Inventory", inventory.serializeNBT());
|
||||||
|
|
Loading…
Reference in a new issue