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:
parent
bea5d783ce
commit
71c65615bc
30 changed files with 373 additions and 40 deletions
|
@ -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.");
|
||||
|
|
|
@ -57,6 +57,10 @@ public abstract class TileEntityBehaviour {
|
|||
|
||||
public void remove() {
|
||||
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
public boolean isPaused() {
|
||||
|
@ -88,6 +92,13 @@ public abstract class TileEntityBehaviour {
|
|||
IBehaviourType<T> type) {
|
||||
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)
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -75,5 +75,23 @@ public class VecHelper {
|
|||
public static Vec3d voxelSpace(double x, double y, double z) {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -21,22 +26,49 @@ public class MountedStorage {
|
|||
this.te = te;
|
||||
handler = dummyHandler;
|
||||
}
|
||||
|
||||
|
||||
public void empty() {
|
||||
if (te != null) {
|
||||
IItemHandler teHandler =
|
||||
te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(dummyHandler);
|
||||
if (teHandler != dummyHandler && 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 = 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,5 +62,9 @@ public class BearingContraption extends Contraption {
|
|||
public int getSailBlocks() {
|
||||
return sailBlocks;
|
||||
}
|
||||
|
||||
public Direction getFacing() {
|
||||
return facing;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -73,7 +75,8 @@ public class DeployerBlock extends DirectionalAxisKineticBlock
|
|||
te.player = null;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
|
||||
worldIn.removeTileEntity(pos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
@ -33,6 +34,11 @@ public abstract class EngineBlock extends HorizontalBlock {
|
|||
public boolean hasTileEntity(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPushReaction(BlockState state) {
|
||||
return PushReaction.BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract TileEntity createTileEntity(BlockState state, IBlockReader world);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -41,7 +41,7 @@ public class StockswitchBlock extends HorizontalBlock {
|
|||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||
updateObservedInventory(state, worldIn, pos);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onNeighborChange(BlockState state, IWorldReader world, BlockPos pos, BlockPos neighbor) {
|
||||
if (world.isRemote())
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -61,6 +62,11 @@ public class BeltObserverBlock extends HorizontalBlock
|
|||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new BeltObserverTileEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPushReaction(BlockState state) {
|
||||
return PushReaction.BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
@ -37,6 +38,11 @@ public class SchematicTableBlock extends HorizontalBlock {
|
|||
public boolean isSolid(BlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPushReaction(BlockState state) {
|
||||
return PushReaction.BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
|
|
|
@ -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;
|
||||
|
@ -41,6 +42,11 @@ public class SchematicannonBlock extends Block {
|
|||
public boolean isSolid(BlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPushReaction(BlockState state) {
|
||||
return PushReaction.BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
|
|
Loading…
Reference in a new issue