More Contraption Bug-Fixes

- Fixed containers dropping items when moved while also holding on to them
- Fixed filters dropping when a filterable tile entity gets moved
- Fixed actors rotating in the central axis of a bearing contraption not activating as no new positions are visited
- Shulker boxes can now be moved in a contraption
- Fixed general tile entities not rendering on moving contraptions
- Chests and Flexcrates can now be used as portable storage in a moving contraption
- Fixed mechanical pistons not moving on the first activation
- Fixed occasional crash when moving deployers
- Made some more blocks piston-safe
- Double flexcrates now split when at least one half gets picked up by a contraption
This commit is contained in:
simibubi 2020-03-08 18:25:56 +01:00
parent bea5d783ce
commit 71c65615bc
30 changed files with 373 additions and 40 deletions

View file

@ -5,6 +5,8 @@ public class CClient extends ConfigBase {
public ConfigGroup client = group(0, "client",
"Client-only settings - If you're looking for general settings, look inside your worlds serverconfig folder!");
public ConfigBool tooltips = b(true, "enableTooltips", "Show item descriptions on Shift and controls on Ctrl.");
public ConfigBool explainRenderErrors =
b(false, "explainRenderErrors", "Log a stack-trace when rendering issues happen within a moving contraption.");
public ConfigFloat fanParticleDensity = f(.5f, 0, 1, "fanParticleDensity");
public ConfigBool rainbowDebug =
b(true, "enableRainbowDebug", "Show colourful debug information while the F3-Menu is open.");

View file

@ -59,6 +59,10 @@ public abstract class TileEntityBehaviour {
}
public void destroy() {
}
public boolean isPaused() {
return paused;
}
@ -89,6 +93,13 @@ public abstract class TileEntityBehaviour {
return get(reader.getTileEntity(pos), type);
}
public static <T extends TileEntityBehaviour> void destroy(IEnviromentBlockReader reader, BlockPos pos,
IBehaviourType<T> type) {
T behaviour = get(reader.getTileEntity(pos), type);
if (behaviour != null)
behaviour.destroy();
}
public static <T extends TileEntityBehaviour> T get(TileEntity te, IBehaviourType<T> type) {
if (te == null)
return null;

View file

@ -126,14 +126,14 @@ public class FilteringBehaviour extends TileEntityBehaviour {
}
@Override
public void remove() {
public void destroy() {
if (filter.getItem() instanceof FilterItem) {
Vec3d pos = VecHelper.getCenterOf(getPos());
World world = getWorld();
world.addEntity(new ItemEntity(world, pos.x, pos.y, pos.z, filter.copy()));
}
super.remove();
super.destroy();
}
public ItemStack getFilter() {

View file

@ -76,4 +76,22 @@ public class VecHelper {
return new Vec3d(x, y, z).scale(1 / 16f);
}
public static int getCoordinate(Vec3i pos, Axis axis) {
return axis.getCoordinate(pos.getX(), pos.getY(), pos.getZ());
}
public static float getCoordinate(Vec3d vec, Axis axis) {
return (float) axis.getCoordinate(vec.x, vec.y, vec.z);
}
public static boolean onSameAxis(BlockPos pos1, BlockPos pos2, Axis axis) {
if (pos1.equals(pos2))
return true;
for (Axis otherAxis : Axis.values())
if (axis != otherAxis)
if (getCoordinate(pos1, otherAxis) != getCoordinate(pos2, otherAxis))
return false;
return true;
}
}

View file

@ -66,7 +66,7 @@ public abstract class DirectionalKineticBlock extends KineticBlock {
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
Direction preferred = getPreferredFacing(context);
if (preferred == null) {
if (preferred == null || context.isPlacerSneaking()) {
Direction nearestLookingDirection = context.getNearestLookingDirection();
return getDefaultState().with(FACING,
context.isPlacerSneaking() ? nearestLookingDirection : nearestLookingDirection.getOpposite());

View file

@ -83,6 +83,11 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
private void validateKinetics() {
if (hasSource()) {
if (!hasNetwork()) {
removeSource();
return;
}
if (!world.isBlockPresent(source))
return;

View file

@ -1,11 +1,11 @@
package com.simibubi.create.modules.contraptions.components.contraptions;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ShulkerBoxBlock;
import net.minecraft.block.material.PushReaction;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
@ -18,8 +18,6 @@ public class BlockMovementTraits {
BlockState blockState = world.getBlockState(pos);
if (blockState.getBlock() instanceof AbstractChassisBlock)
return true;
if (blockState.getBlock() instanceof ShulkerBoxBlock)
return false;
if (blockState.getBlockHardness(world, pos) == -1)
return false;
if (blockState.getBlock() == Blocks.OBSIDIAN)
@ -32,6 +30,8 @@ public class BlockMovementTraits {
return state.get(BlockStateProperties.FACING) == facing;
if (AllBlocks.SAW.typeOf(state))
return state.get(BlockStateProperties.FACING) == facing;
if (AllBlocks.PORTABLE_STORAGE_INTERFACE.typeOf(state))
return state.get(PortableStorageInterfaceBlock.FACING) == facing;
if (AllBlocks.HARVESTER.typeOf(state))
return state.get(BlockStateProperties.HORIZONTAL_FACING) == facing;
return false;

View file

@ -20,18 +20,23 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.config.AllConfigs;
import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.WrappedWorld;
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.ChassisTileEntity;
import com.simibubi.create.modules.contraptions.components.saw.SawBlock;
import com.simibubi.create.modules.contraptions.redstone.ContactBlock;
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ChestBlock;
import net.minecraft.block.SlimeBlock;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.state.properties.ChestType;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction;
@ -52,6 +57,7 @@ public abstract class Contraption {
public Map<BlockPos, MountedStorage> storage;
public List<MutablePair<BlockInfo, MovementContext>> actors;
public CombinedInvWrapper inventory;
public List<TileEntity> customRenderTEs;
public AxisAlignedBB bounds;
public boolean stalled;
@ -67,6 +73,7 @@ public abstract class Contraption {
storage = new HashMap<>();
actors = new ArrayList<>();
renderOrder = new ArrayList<>();
customRenderTEs = new ArrayList<>();
}
public Set<BlockPos> getColliders(World world, Direction movementDirection) {
@ -141,6 +148,8 @@ public abstract class Contraption {
return false;
if (isChassis(state) && !moveChassis(world, pos, forcedDirection, frontier, visited))
return false;
if (AllBlocks.FLEXCRATE.typeOf(state))
FlexcrateBlock.splitCrate(world, pos);
if (state.getBlock() instanceof SlimeBlock)
for (Direction offset : Direction.values()) {
@ -182,6 +191,12 @@ public abstract class Contraption {
BlockState blockstate = world.getBlockState(pos);
if (AllBlocks.SAW.typeOf(blockstate))
blockstate = blockstate.with(SawBlock.RUNNING, true);
if (blockstate.getBlock() instanceof ChestBlock)
blockstate = blockstate.with(ChestBlock.TYPE, ChestType.SINGLE);
if (AllBlocks.FLEXCRATE.typeOf(blockstate))
blockstate = blockstate.with(FlexcrateBlock.DOUBLE, false);
if (AllBlocks.CONTACT.typeOf(blockstate))
blockstate = blockstate.with(ContactBlock.POWERED, true);
CompoundNBT compoundnbt = getTileEntityNBT(world, pos);
TileEntity tileentity = world.getTileEntity(pos);
return Pair.of(new BlockInfo(pos, blockstate, compoundnbt), tileentity);
@ -225,6 +240,7 @@ public abstract class Contraption {
public void readNBT(World world, CompoundNBT nbt) {
blocks.clear();
renderOrder.clear();
customRenderTEs.clear();
nbt.getList("Blocks", 10).forEach(c -> {
CompoundNBT comp = (CompoundNBT) c;
@ -233,11 +249,31 @@ public abstract class Contraption {
comp.contains("Data") ? comp.getCompound("Data") : null);
blocks.put(info.pos, info);
if (world.isRemote) {
BlockRenderLayer renderLayer = info.state.getBlock().getRenderLayer();
Block block = info.state.getBlock();
BlockRenderLayer renderLayer = block.getRenderLayer();
if (renderLayer == BlockRenderLayer.TRANSLUCENT)
renderOrder.add(info.pos);
else
renderOrder.add(0, info.pos);
if (info.nbt == null || block instanceof IPortableBlock)
return;
info.nbt.putInt("x", info.pos.getX());
info.nbt.putInt("y", info.pos.getY());
info.nbt.putInt("z", info.pos.getZ());
TileEntity te = TileEntity.create(info.nbt);
te.setWorld(new WrappedWorld(world) {
@Override
public BlockState getBlockState(BlockPos pos) {
if (isOutsideBuildHeight(pos) || !pos.equals(te.getPos()))
return Blocks.AIR.getDefaultState();
return info.state;
}
});
te.getBlockState();
customRenderTEs.add(te);
}
});
@ -331,6 +367,7 @@ public abstract class Contraption {
BlockPos add = block.pos.add(anchor).add(offset);
if (customRemoval.test(add, block.state))
continue;
world.getWorld().removeTileEntity(add);
world.setBlockState(add, Blocks.AIR.getDefaultState(), 67);
}
}

View file

@ -8,6 +8,7 @@ import org.apache.commons.lang3.tuple.MutablePair;
import com.simibubi.create.AllEntities;
import com.simibubi.create.AllPackets;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.BearingContraption;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
@ -23,6 +24,7 @@ import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
@ -146,12 +148,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
if (getMotion().length() > 1 / 4098f)
move(getMotion().x, getMotion().y, getMotion().z);
tickActors(new Vec3d(posX - prevPosX, posY - prevPosY, posZ - prevPosZ));
prevYaw = yaw;
prevPitch = pitch;
prevRoll = roll;
tickActors(new Vec3d(posX - prevPosX, posY - prevPosY, posZ - prevPosZ));
super.tick();
}
@ -189,6 +191,23 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
newPosVisited = !new BlockPos(previousPosition).equals(gridPosition)
|| context.relativeMotion.length() > 0 && context.firstMovement;
}
if (getContraption() instanceof BearingContraption) {
BearingContraption bc = (BearingContraption) getContraption();
Direction facing = bc.getFacing();
if (VecHelper.onSameAxis(blockInfo.pos, BlockPos.ZERO, facing.getAxis())) {
context.motion = new Vec3d(facing.getDirectionVec()).scale(
facing.getAxis().getCoordinate(roll - prevRoll, yaw - prevYaw, pitch - prevPitch));
context.relativeMotion = context.motion;
int timer = context.data.getInt("StationaryTimer");
if (timer > 0) {
context.data.putInt("StationaryTimer", timer - 1);
} else {
context.data.putInt("StationaryTimer", 20);
newPosVisited = true;
}
}
}
}
context.rotation = rotationVec;

View file

@ -43,9 +43,13 @@ public class ContraptionEntityRenderer extends EntityRenderer<ContraptionEntity>
float zNudge = (((float) (randomBits >> 24 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
GlStateManager.translatef(xNudge, yNudge, zNudge);
float angleYaw = (float) (entity.getYaw(partialTicks) / 180 * Math.PI);
float anglePitch = (float) (entity.getPitch(partialTicks) / 180 * Math.PI);
float angleRoll = (float) (entity.getRoll(partialTicks) / 180 * Math.PI);
float degYaw = entity.getYaw(partialTicks);
float degPitch = entity.getPitch(partialTicks);
float degRoll = entity.getRoll(partialTicks);
float angleYaw = (float) (degYaw / 180 * Math.PI);
float anglePitch = (float) (degPitch / 180 * Math.PI);
float angleRoll = (float) (degRoll / 180 * Math.PI);
Entity ridingEntity = entity.getRidingEntity();
if (ridingEntity != null && ridingEntity instanceof AbstractMinecartEntity) {
@ -88,6 +92,19 @@ public class ContraptionEntityRenderer extends EntityRenderer<ContraptionEntity>
}, Tessellator.getInstance().getBuffer());
TessellatorHelper.draw();
if (!entity.getContraption().customRenderTEs.isEmpty()) {
GlStateManager.pushMatrix();
GlStateManager.translated(x, y, z);
GlStateManager.translated(rotationOffset.x, rotationOffset.y, rotationOffset.z);
GlStateManager.rotated(degPitch, 0, 0, 1);
GlStateManager.rotated(degYaw, 0, 1, 0);
GlStateManager.rotated(degRoll, 1, 0, 0);
GlStateManager.translated(-rotationOffset.x, -rotationOffset.y, -rotationOffset.z);
ContraptionRenderer.renderTEsWithGL(entity.world, entity.getContraption(), entity.getPositionVec(),
new Vec3d(degRoll, degYaw, degPitch));
GlStateManager.popMatrix();
}
GlStateManager.disableCull();
GlStateManager.popMatrix();
GlStateManager.shadeModel(7424);

View file

@ -1,24 +1,38 @@
package com.simibubi.create.modules.contraptions.components.contraptions;
import java.util.Iterator;
import java.util.Random;
import java.util.function.Consumer;
import org.apache.commons.lang3.tuple.Pair;
import org.lwjgl.opengl.GL11;
import com.mojang.blaze3d.platform.GLX;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.Create;
import com.simibubi.create.CreateClient;
import com.simibubi.create.config.AllConfigs;
import com.simibubi.create.foundation.utility.PlacementSimulationWorld;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.SuperByteBufferCache.Compartment;
import com.simibubi.create.foundation.utility.WrappedWorld;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelRenderer;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.crash.ReportedException;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.MutableBlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.LightType;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
@ -28,6 +42,7 @@ public class ContraptionRenderer {
public static final Compartment<Contraption> CONTRAPTION = new Compartment<>();
protected static PlacementSimulationWorld renderWorld;
protected static LightingWorld lightingWorld;
public static void render(World world, Contraption c, Consumer<SuperByteBuffer> transform, BufferBuilder buffer) {
SuperByteBuffer contraptionBuffer = CreateClient.bufferCache.get(CONTRAPTION, c, () -> renderContraption(c));
@ -36,6 +51,57 @@ public class ContraptionRenderer {
renderActors(world, c, transform, buffer);
}
public static void renderTEsWithGL(World world, Contraption c, Vec3d position, Vec3d rotation) {
TileEntityRendererDispatcher dispatcher = TileEntityRendererDispatcher.instance;
float pt = Minecraft.getInstance().getRenderPartialTicks();
World prevDispatcherWorld = dispatcher.world;
if (lightingWorld == null)
lightingWorld = new LightingWorld(world);
lightingWorld.setWorld(world);
lightingWorld.setTransform(position, rotation);
dispatcher.setWorld(lightingWorld);
for (Iterator<TileEntity> iterator = c.customRenderTEs.iterator(); iterator.hasNext();) {
TileEntity tileEntity = iterator.next();
if (dispatcher.getRenderer(tileEntity) == null) {
iterator.remove();
continue;
}
try {
BlockPos pos = tileEntity.getPos();
if (!tileEntity.hasFastRenderer()) {
RenderHelper.enableStandardItemLighting();
int i = lightingWorld.getCombinedLight(pos, 0);
int j = i % 65536;
int k = i / 65536;
GLX.glMultiTexCoord2f(GLX.GL_TEXTURE1, (float) j, (float) k);
GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
}
World prevTileWorld = tileEntity.getWorld();
tileEntity.setWorld(lightingWorld);
dispatcher.render(tileEntity, pos.getX(), pos.getY(), pos.getZ(), pt, -1, true);
tileEntity.setWorld(prevTileWorld);
} catch (ReportedException e) {
if (AllConfigs.CLIENT.explainRenderErrors.get()) {
Create.logger.error("TileEntity " + tileEntity.getType().getRegistryName().toString()
+ " didn't want to render while moved.\n", e);
} else {
Create.logger.error("TileEntity " + tileEntity.getType().getRegistryName().toString()
+ " didn't want to render while moved.\n");
}
iterator.remove();
continue;
}
}
dispatcher.setWorld(prevDispatcherWorld);
}
private static SuperByteBuffer renderContraption(Contraption c) {
if (renderWorld == null || renderWorld.getWorld() != Minecraft.getInstance().world)
renderWorld = new PlacementSimulationWorld(Minecraft.getInstance().world);
@ -51,8 +117,13 @@ public class ContraptionRenderer {
renderWorld.setBlockState(info.pos, info.state);
for (BlockPos pos : c.renderOrder) {
BlockInfo info = c.blocks.get(pos);
IBakedModel originalModel = dispatcher.getModelForState(info.state);
blockRenderer.renderModel(renderWorld, originalModel, info.state, info.pos, builder, true, random, 42,
BlockState state = info.state;
if (state.getRenderType() == BlockRenderType.ENTITYBLOCK_ANIMATED)
continue;
IBakedModel originalModel = dispatcher.getModelForState(state);
blockRenderer.renderModel(renderWorld, originalModel, state, info.pos, builder, true, random, 42,
EmptyModelData.INSTANCE);
}
@ -102,4 +173,36 @@ public class ContraptionRenderer {
return ((int) sky) << 20 | ((int) block) << 4;
}
private static class LightingWorld extends WrappedWorld {
private Vec3d offset;
private Vec3d rotation;
public LightingWorld(World world) {
super(world);
}
void setWorld(World world) {
this.world = world;
}
void setTransform(Vec3d offset, Vec3d rotation) {
this.offset = offset;
this.rotation = rotation;
}
@Override
public int getCombinedLight(BlockPos pos, int minLight) {
return super.getCombinedLight(transformPos(pos), minLight);
}
private BlockPos transformPos(BlockPos pos) {
Vec3d vec = VecHelper.getCenterOf(pos);
vec = VecHelper.rotate(vec, rotation.x, rotation.y, rotation.z);
vec = vec.add(offset).subtract(VecHelper.getCenterOf(BlockPos.ZERO));
return new BlockPos(vec);
}
}
}

View file

@ -1,7 +1,12 @@
package com.simibubi.create.modules.contraptions.components.contraptions;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock;
import net.minecraft.block.ChestBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.properties.ChestType;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraftforge.items.CapabilityItemHandler;
@ -23,20 +28,47 @@ public class MountedStorage {
}
public void empty() {
if (te != null) {
IItemHandler teHandler =
te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(dummyHandler);
if (teHandler != dummyHandler && teHandler instanceof IItemHandlerModifiable) {
working = false;
if (te == null)
return;
// Split double chests
if (te.getType() == TileEntityType.CHEST || te.getType() == TileEntityType.TRAPPED_CHEST) {
if (te.getBlockState().get(ChestBlock.TYPE) != ChestType.SINGLE)
te.getWorld().setBlockState(te.getPos(), te.getBlockState().with(ChestBlock.TYPE, ChestType.SINGLE));
te.updateContainingBlockInfo();
}
// Split double flexcrates
if (te.getType() == AllTileEntities.FLEXCRATE.type) {
if (te.getBlockState().get(FlexcrateBlock.DOUBLE))
te.getWorld().setBlockState(te.getPos(), te.getBlockState().with(FlexcrateBlock.DOUBLE, false));
te.updateContainingBlockInfo();
}
IItemHandler teHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(dummyHandler);
if (teHandler == dummyHandler)
return;
// te uses ItemStackHandler
if (teHandler instanceof ItemStackHandler) {
handler = (ItemStackHandler) teHandler;
working = true;
return;
}
// serialization not accessible -> fill into a serializable handler
if (teHandler instanceof IItemHandlerModifiable) {
IItemHandlerModifiable inv = (IItemHandlerModifiable) teHandler;
handler = new ItemStackHandler(teHandler.getSlots());
for (int slot = 0; slot < handler.getSlots(); slot++) {
handler.setStackInSlot(slot, inv.getStackInSlot(slot));
inv.setStackInSlot(slot, ItemStack.EMPTY);
}
}
working = true;
return;
}
working = te != null && handler != dummyHandler;
}
public MountedStorage(CompoundNBT nbt) {
@ -71,8 +103,12 @@ public class MountedStorage {
if (te == null)
return false;
TileEntityType<?> type = te.getType();
if (type == AllTileEntities.FLEXCRATE.type)
return true;
if (type == TileEntityType.BARREL)
return true;
if (type == TileEntityType.CHEST || type == TileEntityType.TRAPPED_CHEST)
return true;
return false;
}

View file

@ -63,4 +63,8 @@ public class BearingContraption extends Contraption {
return sailBlocks;
}
public Direction getFacing() {
return facing;
}
}

View file

@ -35,13 +35,6 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
forceMove = true;
}
// @Override
// public void initialize() {
// super.initialize();
// if (!world.isRemote)
//
// }
@Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);

View file

@ -48,8 +48,8 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
return;
// Check if not at limit already
float resultingOffset = contraption.initialExtensionProgress + Math.signum(getMovementSpeed()) * .5f;
extensionLength = contraption.extensionLength;
float resultingOffset = contraption.initialExtensionProgress + Math.signum(getMovementSpeed()) * .5f;
if (resultingOffset <= 0 || resultingOffset >= extensionLength) {
return;
}

View file

@ -1,6 +1,8 @@
package com.simibubi.create.modules.contraptions.components.deployer;
import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.block.IWithTileEntity;
import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
@ -74,6 +76,7 @@ public class DeployerBlock extends DirectionalAxisKineticBlock
}
});
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
worldIn.removeTileEntity(pos);
}
}

View file

@ -168,7 +168,7 @@ public class DeployerTileEntityRenderer extends SafeTileEntityRenderer<DeployerT
SuperByteBuffer hand = renderAndTransform(world, handPose, blockState, pos, false);
double factor;
if (context.contraption.stalled) {
if (context.contraption.stalled || context.position == null) {
factor = MathHelper.sin(AnimationTickHolder.getRenderTick() * .5f) * .25f + .25f;
} else {
Vec3d center = VecHelper.getCenterOf(new BlockPos(context.position));

View file

@ -7,6 +7,7 @@ import com.simibubi.create.AllBlockPartials;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.HorizontalBlock;
import net.minecraft.block.material.PushReaction;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.tileentity.TileEntity;
@ -34,6 +35,11 @@ public abstract class EngineBlock extends HorizontalBlock {
return true;
}
@Override
public PushReaction getPushReaction(BlockState state) {
return PushReaction.BLOCK;
}
@Override
public abstract TileEntity createTileEntity(BlockState state, IBlockReader world);

View file

@ -1,5 +1,7 @@
package com.simibubi.create.modules.contraptions.components.saw;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.block.IWithTileEntity;
import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
@ -132,7 +134,7 @@ public class SawBlock extends DirectionalAxisKineticBlock implements IWithTileEn
te.inventory.getStackInSlot(slot));
}
});
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
worldIn.removeTileEntity(pos);
}
}

View file

@ -59,7 +59,10 @@ public class WaterWheelBlock extends HorizontalKineticBlock {
@Override
public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn,
BlockPos currentPos, BlockPos facingPos) {
updateFlowAt(stateIn, worldIn.getWorld(), currentPos, facing);
World world = worldIn.getWorld();
if (world == null)
return stateIn;
updateFlowAt(stateIn, world, currentPos, facing);
updateWheelSpeed(worldIn, currentPos);
return stateIn;
}

View file

@ -7,6 +7,7 @@ import com.simibubi.create.foundation.utility.AllShapes;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.material.PushReaction;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
@ -40,6 +41,11 @@ public class BasinBlock extends Block implements IWithTileEntity<BasinTileEntity
return new BasinTileEntity();
}
@Override
public PushReaction getPushReaction(BlockState state) {
return PushReaction.BLOCK;
}
@Override
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
BlockRayTraceResult hit) {

View file

@ -4,6 +4,7 @@ import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.material.PushReaction;
import net.minecraft.item.ItemGroup;
@ -29,6 +30,11 @@ public class ShaftBlock extends RotatedPillarKineticBlock {
return PushReaction.NORMAL;
}
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.ENTITYBLOCK_ANIMATED;
}
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return new ShaftTileEntity();

View file

@ -30,6 +30,7 @@ public abstract class BeltAttachableLogisticalBlock extends AttachedLogisticalBl
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
onAttachmentRemoved(worldIn, pos, state);
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
worldIn.removeTileEntity(pos);
}
}

View file

@ -23,6 +23,7 @@ import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.HorizontalBlock;
import net.minecraft.block.material.PushReaction;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.BlockItemUseContext;
@ -62,6 +63,11 @@ public class BeltObserverBlock extends HorizontalBlock
return new BeltObserverTileEntity();
}
@Override
public PushReaction getPushReaction(BlockState state) {
return PushReaction.BLOCK;
}
@Override
public boolean hasTileEntity(BlockState state) {
return true;
@ -168,6 +174,7 @@ public class BeltObserverBlock extends HorizontalBlock
if (newState.getBlock() != this || newState.with(POWERED, false) != state.with(POWERED, false))
onAttachmentRemoved(worldIn, pos, state);
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
worldIn.removeTileEntity(pos);
}
}

View file

@ -5,6 +5,8 @@ import java.util.Collections;
import java.util.List;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.block.IWithTileEntity;
import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
@ -140,6 +142,7 @@ public class FunnelBlock extends AttachedLogisticalBlock implements IBeltAttachm
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
onAttachmentRemoved(worldIn, pos, state);
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
worldIn.removeTileEntity(pos);
}
}

View file

@ -131,9 +131,24 @@ public class FlexcrateBlock extends ProperDirectionalBlock {
return new FlexcrateTileEntity();
}
public static void splitCrate(World world, BlockPos pos) {
BlockState state = world.getBlockState(pos);
if (!AllBlocks.FLEXCRATE.typeOf(state))
return;
if (!state.get(DOUBLE))
return;
TileEntity te = world.getTileEntity(pos);
if (!(te instanceof FlexcrateTileEntity))
return;
FlexcrateTileEntity crateTe = (FlexcrateTileEntity) te;
crateTe.onSplit();
world.setBlockState(pos, state.with(DOUBLE, false));
world.setBlockState(crateTe.getOtherCrate().getPos(), state.with(DOUBLE, false));
}
@Override
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (worldIn.getTileEntity(pos) == null)
if (!(worldIn.getTileEntity(pos) instanceof FlexcrateTileEntity))
return;
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {

View file

@ -104,6 +104,30 @@ public class FlexcrateTileEntity extends SyncedTileEntity implements INamedConta
return getBlockState().get(FlexcrateBlock.FACING);
}
public void onSplit() {
FlexcrateTileEntity other = getOtherCrate();
if (other == null)
return;
if (other == getMainCrate()) {
other.onSplit();
return;
}
other.allowedAmount = Math.max(1, allowedAmount - 1024);
for (int slot = 0; slot < other.inventory.getSlots(); slot++)
other.inventory.setStackInSlot(slot, ItemStack.EMPTY);
for (int slot = 16; slot < inventory.getSlots(); slot++) {
other.inventory.setStackInSlot(slot - 16, inventory.getStackInSlot(slot));
inventory.setStackInSlot(slot, ItemStack.EMPTY);
}
allowedAmount = Math.min(1024, allowedAmount);
invHandler.invalidate();
invHandler = LazyOptional.of(() -> inventory);
other.invHandler.invalidate();
other.invHandler = LazyOptional.of(() -> other.inventory);
}
public void onDestroyed() {
FlexcrateTileEntity other = getOtherCrate();
if (other == null) {

View file

@ -6,6 +6,7 @@ import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.HorizontalBlock;
import net.minecraft.block.material.PushReaction;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.InventoryHelper;
@ -38,6 +39,11 @@ public class SchematicTableBlock extends HorizontalBlock {
return false;
}
@Override
public PushReaction getPushReaction(BlockState state) {
return PushReaction.BLOCK;
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
return this.getDefaultState().with(HORIZONTAL_FACING, context.getPlacementHorizontalFacing().getOpposite());

View file

@ -6,6 +6,7 @@ import com.simibubi.create.foundation.utility.AllShapes;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.material.PushReaction;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.InventoryHelper;
@ -42,6 +43,11 @@ public class SchematicannonBlock extends Block {
return false;
}
@Override
public PushReaction getPushReaction(BlockState state) {
return PushReaction.BLOCK;
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
return AllShapes.SCHEMATICANNON_SHAPE;