Merge branch 'unified-contraptions' of https://github.com/simibubi/Create into 0.2

This commit is contained in:
simibubi 2019-12-12 11:58:29 +01:00
commit 785d77a59d
63 changed files with 1295 additions and 1592 deletions

View file

@ -9,17 +9,17 @@ import com.simibubi.create.foundation.block.RenderUtilityDirectionalBlock;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.modules.IModule; import com.simibubi.create.modules.IModule;
import com.simibubi.create.modules.contraptions.components.actors.DrillBlock; import com.simibubi.create.modules.contraptions.components.actors.DrillBlock;
import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock;
import com.simibubi.create.modules.contraptions.components.actors.DrillBlock.DrillHeadBlock; import com.simibubi.create.modules.contraptions.components.actors.DrillBlock.DrillHeadBlock;
import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock;
import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock.HarvesterBladeBlock; import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock.HarvesterBladeBlock;
import com.simibubi.create.modules.contraptions.components.constructs.LinearChassisBlock; import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingBlock;
import com.simibubi.create.modules.contraptions.components.constructs.RadialChassisBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.LinearChassisBlock;
import com.simibubi.create.modules.contraptions.components.constructs.bearing.MechanicalBearingBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.RadialChassisBlock;
import com.simibubi.create.modules.contraptions.components.constructs.mounted.CartAssemblerBlock; import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerBlock;
import com.simibubi.create.modules.contraptions.components.constructs.mounted.CartAssemblerBlock.MinecartAnchorBlock; import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerBlock.MinecartAnchorBlock;
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonBlock; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock;
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonHeadBlock; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonHeadBlock;
import com.simibubi.create.modules.contraptions.components.constructs.piston.PistonPoleBlock; import com.simibubi.create.modules.contraptions.components.contraptions.piston.PistonPoleBlock;
import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCrafterBlock; import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCrafterBlock;
import com.simibubi.create.modules.contraptions.components.crusher.CrushingWheelBlock; import com.simibubi.create.modules.contraptions.components.crusher.CrushingWheelBlock;
import com.simibubi.create.modules.contraptions.components.crusher.CrushingWheelControllerBlock; import com.simibubi.create.modules.contraptions.components.crusher.CrushingWheelControllerBlock;

View file

@ -2,8 +2,8 @@ package com.simibubi.create;
import java.util.function.Function; import java.util.function.Function;
import com.simibubi.create.modules.contraptions.components.constructs.mounted.ContraptionEntity; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
import com.simibubi.create.modules.contraptions.components.constructs.mounted.ContraptionEntityRenderer; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntityRenderer;
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity; import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntityRenderer; import com.simibubi.create.modules.logistics.transport.CardboardBoxEntityRenderer;

View file

@ -6,7 +6,7 @@ import java.util.function.Supplier;
import com.simibubi.create.foundation.packet.NbtPacket; import com.simibubi.create.foundation.packet.NbtPacket;
import com.simibubi.create.foundation.packet.SimplePacketBase; import com.simibubi.create.foundation.packet.SimplePacketBase;
import com.simibubi.create.modules.contraptions.components.constructs.ConfigureChassisPacket; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ConfigureChassisPacket;
import com.simibubi.create.modules.contraptions.components.mixer.ConfigureMixerPacket; import com.simibubi.create.modules.contraptions.components.mixer.ConfigureMixerPacket;
import com.simibubi.create.modules.contraptions.components.motor.ConfigureMotorPacket; import com.simibubi.create.modules.contraptions.components.motor.ConfigureMotorPacket;
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunBeamPacket; import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunBeamPacket;

View file

@ -8,11 +8,11 @@ import com.simibubi.create.modules.contraptions.components.actors.DrillTileEntit
import com.simibubi.create.modules.contraptions.components.actors.DrillTileEntityRenderer; import com.simibubi.create.modules.contraptions.components.actors.DrillTileEntityRenderer;
import com.simibubi.create.modules.contraptions.components.actors.HarvesterTileEntity; import com.simibubi.create.modules.contraptions.components.actors.HarvesterTileEntity;
import com.simibubi.create.modules.contraptions.components.actors.HarvesterTileEntityRenderer; import com.simibubi.create.modules.contraptions.components.actors.HarvesterTileEntityRenderer;
import com.simibubi.create.modules.contraptions.components.constructs.ChassisTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingTileEntity;
import com.simibubi.create.modules.contraptions.components.constructs.bearing.MechanicalBearingTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingTileEntityRenderer;
import com.simibubi.create.modules.contraptions.components.constructs.bearing.MechanicalBearingTileEntityRenderer; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonTileEntity;
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonTileEntityRenderer; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonTileEntityRenderer;
import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCrafterTileEntity; import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCrafterTileEntity;
import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCrafterTileEntityRenderer; import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCrafterTileEntityRenderer;
import com.simibubi.create.modules.contraptions.components.crusher.CrushingWheelControllerTileEntity; import com.simibubi.create.modules.contraptions.components.crusher.CrushingWheelControllerTileEntity;

View file

@ -6,7 +6,6 @@ import org.apache.logging.log4j.Logger;
import com.simibubi.create.foundation.world.OreGeneration; import com.simibubi.create.foundation.world.OreGeneration;
import com.simibubi.create.modules.ModuleLoadedCondition; import com.simibubi.create.modules.ModuleLoadedCondition;
import com.simibubi.create.modules.contraptions.TorquePropagator; import com.simibubi.create.modules.contraptions.TorquePropagator;
import com.simibubi.create.modules.contraptions.components.constructs.piston.MovingConstructHandler;
import com.simibubi.create.modules.logistics.FrequencyHandler; import com.simibubi.create.modules.logistics.FrequencyHandler;
import com.simibubi.create.modules.logistics.management.LogisticalNetworkHandler; import com.simibubi.create.modules.logistics.management.LogisticalNetworkHandler;
import com.simibubi.create.modules.logistics.transport.villager.LogisticianHandler; import com.simibubi.create.modules.logistics.transport.villager.LogisticianHandler;
@ -42,7 +41,6 @@ public class Create {
public static ItemGroup creativeTab = new CreateItemGroup(); public static ItemGroup creativeTab = new CreateItemGroup();
public static ServerSchematicLoader schematicReceiver; public static ServerSchematicLoader schematicReceiver;
public static FrequencyHandler frequencyHandler; public static FrequencyHandler frequencyHandler;
public static MovingConstructHandler constructHandler;
public static LogisticalNetworkHandler logisticalNetworkHandler; public static LogisticalNetworkHandler logisticalNetworkHandler;
public static TorquePropagator torquePropagator; public static TorquePropagator torquePropagator;
public static LogisticianHandler logisticianHandler; public static LogisticianHandler logisticianHandler;
@ -74,7 +72,6 @@ public class Create {
public static void init(final FMLCommonSetupEvent event) { public static void init(final FMLCommonSetupEvent event) {
schematicReceiver = new ServerSchematicLoader(); schematicReceiver = new ServerSchematicLoader();
frequencyHandler = new FrequencyHandler(); frequencyHandler = new FrequencyHandler();
constructHandler = new MovingConstructHandler();
logisticalNetworkHandler = new LogisticalNetworkHandler(); logisticalNetworkHandler = new LogisticalNetworkHandler();
torquePropagator = new TorquePropagator(); torquePropagator = new TorquePropagator();

View file

@ -13,7 +13,7 @@ import com.simibubi.create.foundation.block.SpriteShifter.SpriteShiftEntry;
import com.simibubi.create.foundation.utility.SuperByteBufferCache; import com.simibubi.create.foundation.utility.SuperByteBufferCache;
import com.simibubi.create.modules.contraptions.WrenchModel; import com.simibubi.create.modules.contraptions.WrenchModel;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.components.constructs.ContraptionRenderer; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionRenderer;
import com.simibubi.create.modules.curiosities.deforester.DeforesterModel; import com.simibubi.create.modules.curiosities.deforester.DeforesterModel;
import com.simibubi.create.modules.curiosities.partialWindows.WindowInABlockModel; import com.simibubi.create.modules.curiosities.partialWindows.WindowInABlockModel;
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunModel; import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunModel;

View file

@ -44,7 +44,6 @@ public class Events {
public static void onLoadWorld(WorldEvent.Load event) { public static void onLoadWorld(WorldEvent.Load event) {
IWorld world = event.getWorld(); IWorld world = event.getWorld();
Create.frequencyHandler.onLoadWorld(world); Create.frequencyHandler.onLoadWorld(world);
Create.constructHandler.onLoadWorld(world);
Create.logisticalNetworkHandler.onLoadWorld(world); Create.logisticalNetworkHandler.onLoadWorld(world);
Create.torquePropagator.onLoadWorld(world); Create.torquePropagator.onLoadWorld(world);
} }
@ -53,7 +52,6 @@ public class Events {
public static void onUnloadWorld(WorldEvent.Unload event) { public static void onUnloadWorld(WorldEvent.Unload event) {
IWorld world = event.getWorld(); IWorld world = event.getWorld();
Create.frequencyHandler.onUnloadWorld(world); Create.frequencyHandler.onUnloadWorld(world);
Create.constructHandler.onUnloadWorld(world);
Create.logisticalNetworkHandler.onUnloadWorld(world); Create.logisticalNetworkHandler.onUnloadWorld(world);
Create.torquePropagator.onUnloadWorld(world); Create.torquePropagator.onUnloadWorld(world);
} }

View file

@ -1,7 +1,6 @@
package com.simibubi.create; package com.simibubi.create;
import com.simibubi.create.foundation.block.SpriteShifter; import com.simibubi.create.foundation.block.SpriteShifter;
import com.simibubi.create.modules.contraptions.components.constructs.bearing.MechanicalBearingTileEntityRenderer;
import net.minecraft.client.resources.ReloadListener; import net.minecraft.client.resources.ReloadListener;
import net.minecraft.profiler.IProfiler; import net.minecraft.profiler.IProfiler;
@ -16,7 +15,6 @@ public class ResourceReloadHandler extends ReloadListener<String> {
@Override @Override
protected void apply(String splashList, IResourceManager resourceManagerIn, IProfiler profilerIn) { protected void apply(String splashList, IResourceManager resourceManagerIn, IProfiler profilerIn) {
MechanicalBearingTileEntityRenderer.invalidateCache();
SpriteShifter.reloadUVs(); SpriteShifter.reloadUVs();
CreateClient.bufferCache.invalidate(); CreateClient.bufferCache.invalidate();
} }

View file

@ -1,5 +1,9 @@
package com.simibubi.create.foundation.utility; package com.simibubi.create.foundation.utility;
import static net.minecraft.block.Block.makeCuboidShape;
import java.util.Arrays;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.DirectionalBlock; import net.minecraft.block.DirectionalBlock;
import net.minecraft.block.PistonHeadBlock; import net.minecraft.block.PistonHeadBlock;
@ -9,10 +13,6 @@ import net.minecraft.util.math.shapes.IBooleanFunction;
import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.util.math.shapes.VoxelShapes;
import java.util.Arrays;
import static net.minecraft.block.Block.makeCuboidShape;
public class AllShapes { public class AllShapes {
public static final VoxelShaper public static final VoxelShaper

View file

@ -1,159 +0,0 @@
package com.simibubi.create.foundation.utility;
import java.nio.ByteBuffer;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.MathHelper;
@Deprecated
public abstract class BufferManipulator {
public static final int FORMAT_LENGTH = DefaultVertexFormats.BLOCK.getSize();
protected ByteBuffer original;
protected ByteBuffer mutable;
public BufferManipulator(ByteBuffer original) {
original.rewind();
this.original = original;
this.mutable = GLAllocation.createDirectByteBuffer(original.capacity());
this.mutable.order(original.order());
this.mutable.limit(original.limit());
mutable.put(this.original);
mutable.rewind();
}
protected static int vertexCount(ByteBuffer buffer) {
return buffer.limit() / FORMAT_LENGTH;
}
protected static int getBufferPosition(int vertexIndex) {
return vertexIndex * FORMAT_LENGTH;
}
protected static float getX(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index));
}
protected static float getY(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 4);
}
protected static float getZ(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 8);
}
protected static byte getR(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 12);
}
protected static byte getG(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 13);
}
protected static byte getB(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 14);
}
protected static byte getA(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 15);
}
protected static void putPos(ByteBuffer buffer, int index, float x, float y, float z) {
int pos = getBufferPosition(index);
buffer.putFloat(pos, x);
buffer.putFloat(pos + 4, y);
buffer.putFloat(pos + 8, z);
}
protected static float rotateX(float x, float y, float z, float sin, float cos, Axis axis) {
return axis == Axis.Y ? x * cos + z * sin : axis == Axis.Z ? x * cos - y * sin : x;
}
protected static float rotateY(float x, float y, float z, float sin, float cos, Axis axis) {
return axis == Axis.Y ? y : axis == Axis.Z ? y * cos + x * sin : y * cos - z * sin;
}
protected static float rotateZ(float x, float y, float z, float sin, float cos, Axis axis) {
return axis == Axis.Y ? z * cos - x * sin : axis == Axis.Z ? z : z * cos + y * sin;
}
protected static void putLight(ByteBuffer buffer, int index, int packedLight) {
buffer.putInt(getBufferPosition(index) + 24, packedLight);
}
protected static void putColor(ByteBuffer buffer, int index, byte r, byte g, byte b, byte a) {
int bufferPosition = getBufferPosition(index);
buffer.put(bufferPosition + 12, r);
buffer.put(bufferPosition + 13, g);
buffer.put(bufferPosition + 14, b);
buffer.put(bufferPosition + 15, a);
}
public ByteBuffer getTranslated(float xIn, float yIn, float zIn, int packedLightCoords) {
original.rewind();
mutable.rewind();
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
putPos(mutable, vertex, getX(original, vertex) + xIn, getY(original, vertex) + yIn,
getZ(original, vertex) + zIn);
putLight(mutable, vertex, packedLightCoords);
}
return mutable;
}
public static ByteBuffer remanipulateBuffer(ByteBuffer buffer, float x, float y, float z, float xOrigin,
float yOrigin, float zOrigin, float yaw, float pitch) {
buffer.rewind();
float cosYaw = MathHelper.cos(yaw);
float sinYaw = MathHelper.sin(yaw);
float cosPitch = MathHelper.cos(pitch);
float sinPitch = MathHelper.sin(pitch);
for (int vertex = 0; vertex < vertexCount(buffer); vertex++) {
float xL = getX(buffer, vertex) - xOrigin;
float yL = getY(buffer, vertex) - yOrigin;
float zL = getZ(buffer, vertex) - zOrigin;
float xL2 = rotateX(xL, yL, zL, sinPitch, cosPitch, Axis.X);
float yL2 = rotateY(xL, yL, zL, sinPitch, cosPitch, Axis.X);
float zL2 = rotateZ(xL, yL, zL, sinPitch, cosPitch, Axis.X);
xL = rotateX(xL2, yL2, zL2, sinYaw, cosYaw, Axis.Y);
yL = rotateY(xL2, yL2, zL2, sinYaw, cosYaw, Axis.Y);
zL = rotateZ(xL2, yL2, zL2, sinYaw, cosYaw, Axis.Y);
float xPos = xL + x + xOrigin;
float yPos = yL + y + yOrigin;
float zPos = zL + z + zOrigin;
putPos(buffer, vertex, xPos, yPos, zPos);
}
return buffer;
}
public static ByteBuffer recolorBuffer(ByteBuffer buffer, int color) {
buffer.rewind();
boolean defaultColor = color == -1;
int b = defaultColor ? 128 : color & 0xFF;
int g = defaultColor ? 128 : (color >> 8) & 0xFF;
int r = defaultColor ? 128 : (color >> 16) & 0xFF;
for (int vertex = 0; vertex < vertexCount(buffer); vertex++) {
float lum = 1;
int r2 = (int) (r * lum);
int g2 = (int) (g * lum);
int b2 = (int) (b * lum);
putColor(buffer, vertex, (byte) r2, (byte) g2, (byte) b2, (byte) 255);
}
return buffer;
}
}

View file

@ -31,6 +31,7 @@ public class SuperByteBuffer {
// Vertex Lighting // Vertex Lighting
private boolean shouldLight; private boolean shouldLight;
private IVertexLighter vertexLighter; private IVertexLighter vertexLighter;
private float lightOffsetX, lightOffsetY, lightOffsetZ;
private int packedLightCoords; private int packedLightCoords;
// Vertex Coloring // Vertex Coloring
@ -84,7 +85,8 @@ public class SuperByteBuffer {
if (shouldLight) { if (shouldLight) {
if (vertexLighter != null) if (vertexLighter != null)
putLight(mutable, vertex, vertexLighter.getPackedLight(x2, y2, z2)); putLight(mutable, vertex,
vertexLighter.getPackedLight(x2 + lightOffsetX, y2 + lightOffsetY, z2 + lightOffsetZ));
else else
putLight(mutable, vertex, packedLightCoords); putLight(mutable, vertex, packedLightCoords);
} }
@ -153,6 +155,7 @@ public class SuperByteBuffer {
public SuperByteBuffer light(int packedLightCoords) { public SuperByteBuffer light(int packedLightCoords) {
shouldLight = true; shouldLight = true;
vertexLighter = null;
this.packedLightCoords = packedLightCoords; this.packedLightCoords = packedLightCoords;
return this; return this;
} }
@ -163,6 +166,13 @@ public class SuperByteBuffer {
return this; return this;
} }
public SuperByteBuffer offsetLighting(double x, double y, double z) {
lightOffsetX = (float) x;
lightOffsetY = (float) y;
lightOffsetZ = (float) z;
return this;
}
public SuperByteBuffer color(int color) { public SuperByteBuffer color(int color) {
shouldColor = true; shouldColor = true;
r = ((color >> 16) & 0xFF); r = ((color >> 16) & 0xFF);

View file

@ -4,6 +4,7 @@ import java.util.Random;
import net.minecraft.nbt.DoubleNBT; import net.minecraft.nbt.DoubleNBT;
import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.ListNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -11,9 +12,15 @@ import net.minecraft.util.math.Vec3i;
public class VecHelper { public class VecHelper {
public static Vec3d rotate(Vec3d vec, float deg, Axis axis) { public static Vec3d rotate(Vec3d vec, double xRot, double yRot, double zRot) {
float angle = (float) (deg / 180f * Math.PI); return rotate(rotate(rotate(vec, xRot, Axis.X), yRot, Axis.Y), zRot, Axis.Z);
}
public static Vec3d rotate(Vec3d vec, double deg, Axis axis) {
if (deg == 0)
return vec;
float angle = (float) (deg / 180f * Math.PI);
double sin = MathHelper.sin(angle); double sin = MathHelper.sin(angle);
double cos = MathHelper.cos(angle); double cos = MathHelper.cos(angle);
double x = vec.x; double x = vec.x;
@ -29,6 +36,10 @@ public class VecHelper {
return vec; return vec;
} }
public static boolean isVecPointingTowards(Vec3d vec, Direction direction) {
return new Vec3d(direction.getDirectionVec()).distanceTo(vec.normalize()) < .75;
}
public static Vec3d getCenterOf(Vec3i pos) { public static Vec3d getCenterOf(Vec3i pos) {
return new Vec3d(pos).add(.5f, .5f, .5f); return new Vec3d(pos).add(.5f, .5f, .5f);
} }

View file

@ -1,6 +1,11 @@
package com.simibubi.create.foundation.world; package com.simibubi.create.foundation.world;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
@ -12,10 +17,6 @@ import net.minecraft.world.gen.placement.CountRangeConfig;
import net.minecraft.world.gen.placement.Placement; import net.minecraft.world.gen.placement.Placement;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public enum OreGeneration { public enum OreGeneration {
TEST_BLOB_1(new BasicOreGenConfig(Blocks.EMERALD_BLOCK, 25, 2, 128)), TEST_BLOB_1(new BasicOreGenConfig(Blocks.EMERALD_BLOCK, 25, 2, 128)),

View file

@ -26,8 +26,8 @@ import net.minecraft.particles.RedstoneParticleData;
import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;

View file

@ -4,10 +4,11 @@ import java.util.List;
import com.simibubi.create.foundation.block.IRenderUtilityBlock; import com.simibubi.create.foundation.block.IRenderUtilityBlock;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.IWithTileEntity;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock; import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior; import com.simibubi.create.modules.contraptions.components.contraptions.IHaveMovementBehavior;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -85,18 +86,22 @@ public class DrillBlock extends DirectionalKineticBlock
} }
@Override @Override
public void visitPosition(MovementContext context) { public boolean isActive(MovementContext context) {
Direction movement = context.getMovementDirection(); return !VecHelper.isVecPointingTowards(context.relativeMotion, context.state.get(FACING).getOpposite());
}
// BlockState block = context.state; @Override
// if (movement == block.get(FACING).getOpposite()) public Vec3d getActiveAreaOffset(MovementContext context) {
// return; return new Vec3d(context.state.get(FACING).getDirectionVec()).scale(.65f);
}
@Override
public void visitNewPosition(MovementContext context, BlockPos pos) {
World world = context.world; World world = context.world;
BlockPos pos = context.currentGridPos;
pos = pos.offset(movement);
BlockState stateVisited = world.getBlockState(pos); BlockState stateVisited = world.getBlockState(pos);
if (world.isRemote)
return;
if (stateVisited.getCollisionShape(world, pos).isEmpty()) if (stateVisited.getCollisionShape(world, pos).isEmpty())
return; return;
if (stateVisited.getBlockHardness(world, pos) == -1) if (stateVisited.getBlockHardness(world, pos) == -1)
@ -108,8 +113,7 @@ public class DrillBlock extends DirectionalKineticBlock
for (ItemStack stack : drops) { for (ItemStack stack : drops) {
ItemEntity itemEntity = new ItemEntity(world, pos.getX() + .5f, pos.getY() + .25f, pos.getZ() + .5f, stack); ItemEntity itemEntity = new ItemEntity(world, pos.getX() + .5f, pos.getY() + .25f, pos.getZ() + .5f, stack);
itemEntity.setMotion( itemEntity.setMotion(context.motion.add(0, 0.5f, 0).scale(world.rand.nextFloat() * .3f));
new Vec3d(movement.getDirectionVec()).add(0, 0.5f, 0).scale(world.rand.nextFloat() * .3f));
world.addEntity(itemEntity); world.addEntity(itemEntity);
} }
} }

View file

@ -6,10 +6,11 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.SuperByteBuffer; import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.base.IRotate; import com.simibubi.create.modules.contraptions.base.IRotate;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior.MovementContext; import com.simibubi.create.modules.contraptions.components.contraptions.IHaveMovementBehavior.MovementContext;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
@ -29,7 +30,9 @@ public class DrillTileEntityRenderer extends KineticTileEntityRenderer {
BlockState state = context.state; BlockState state = context.state;
SuperByteBuffer buffer = CreateClient.bufferCache.renderBlockState(KINETIC_TILE, getRenderedBlockState(state)); SuperByteBuffer buffer = CreateClient.bufferCache.renderBlockState(KINETIC_TILE, getRenderedBlockState(state));
float speed = (float) (context.getMovementDirection() == state.get(FACING) ? context.getAnimationSpeed() : 0); float speed = (float) (!VecHelper.isVecPointingTowards(context.relativeMotion, state.get(FACING).getOpposite())
? context.getAnimationSpeed()
: 0);
Axis axis = ((IRotate) state.getBlock()).getRotationAxis(state); Axis axis = ((IRotate) state.getBlock()).getRotationAxis(state);
float time = AnimationTickHolder.getRenderTick(); float time = AnimationTickHolder.getRenderTick();
float angle = (float) (((time * speed) % 360) / 180 * (float) Math.PI); float angle = (float) (((time * speed) % 360) / 180 * (float) Math.PI);

View file

@ -4,9 +4,10 @@ import java.util.List;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IRenderUtilityBlock; import com.simibubi.create.foundation.block.IRenderUtilityBlock;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.components.contraptions.IHaveMovementBehavior;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -105,18 +106,25 @@ public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBeha
} }
@Override @Override
public void visitPosition(MovementContext context) { public boolean isActive(MovementContext context) {
Direction movement = context.getMovementDirection(); return !VecHelper.isVecPointingTowards(context.relativeMotion,
context.state.get(HORIZONTAL_FACING).getOpposite());
}
@Override
public Vec3d getActiveAreaOffset(MovementContext context) {
return new Vec3d(context.state.get(HORIZONTAL_FACING).getDirectionVec()).scale(.5);
}
@Override
public void visitNewPosition(MovementContext context, BlockPos pos) {
World world = context.world; World world = context.world;
BlockState block = context.state;
BlockPos pos = context.currentGridPos;
if (movement != block.get(HORIZONTAL_FACING))
return;
BlockState stateVisited = world.getBlockState(pos); BlockState stateVisited = world.getBlockState(pos);
boolean notCropButCuttable = false; boolean notCropButCuttable = false;
if (world.isRemote)
return;
if (stateVisited.getBlock() == Blocks.SUGAR_CANE) { if (stateVisited.getBlock() == Blocks.SUGAR_CANE) {
notCropButCuttable = true; notCropButCuttable = true;
pos = pos.up(); pos = pos.up();
@ -141,8 +149,7 @@ public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBeha
seedSubtracted = true; seedSubtracted = true;
} }
ItemEntity itemEntity = new ItemEntity(world, pos.getX() + .5f, pos.getY() + .25f, pos.getZ() + .5f, stack); ItemEntity itemEntity = new ItemEntity(world, pos.getX() + .5f, pos.getY() + .25f, pos.getZ() + .5f, stack);
itemEntity.setMotion( itemEntity.setMotion(context.motion.add(0, 0.5f, 0).scale(world.rand.nextFloat() * .3f));
new Vec3d(movement.getDirectionVec()).add(0, 0.5f, 0).scale(world.rand.nextFloat() * .3f));
world.addEntity(itemEntity); world.addEntity(itemEntity);
} }
} }

View file

@ -7,7 +7,8 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.SuperByteBuffer; import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior.MovementContext; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.components.contraptions.IHaveMovementBehavior.MovementContext;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
@ -28,12 +29,9 @@ public class HarvesterTileEntityRenderer extends TileEntityRenderer<HarvesterTil
public static SuperByteBuffer renderInContraption(MovementContext context) { public static SuperByteBuffer renderInContraption(MovementContext context) {
BlockState state = context.state; BlockState state = context.state;
Direction facing = context.getMovementDirection(); float speed = (float) (!VecHelper.isVecPointingTowards(context.relativeMotion, state.get(HORIZONTAL_FACING).getOpposite())
float speed = (float) (facing == state.get(HORIZONTAL_FACING) ? context.getAnimationSpeed() * state.get(HORIZONTAL_FACING).getAxisDirection().getOffset()
? context.getAnimationSpeed() * facing.getAxisDirection().getOffset()
: 0); : 0);
if (facing.getAxis() == Axis.X)
speed = -speed;
float time = AnimationTickHolder.getRenderTick(); float time = AnimationTickHolder.getRenderTick();
float angle = (float) (((time * speed) % 360) / 180 * (float) Math.PI); float angle = (float) (((time * speed) % 360) / 180 * (float) Math.PI);

View file

@ -1,83 +0,0 @@
package com.simibubi.create.modules.contraptions.components.constructs;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonTileEntity;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.Constants.NBT;
public interface IHaveMovementBehavior {
public enum MoverType {
PISTON, BEARING, MINECART;
}
default void visitPosition(MovementContext context) {
}
default void tick(MechanicalPistonTileEntity piston) {
}
default boolean hasSpecialRenderer() {
return false;
}
public class MovementContext {
public BlockPos currentGridPos;
public Vec3d motion;
public float movementSpeedModifier = 1;
public MoverType moverType;
public World world;
public BlockState state;
public MovementContext(BlockState state, MoverType moverType) {
this.state = state;
this.moverType = moverType;
}
public Direction getMovementDirection() {
return Direction.getFacingFromVector(motion.x, motion.y, motion.z);
}
public float getAnimationSpeed() {
int modifier = moverType == MoverType.MINECART ? 1000 : 200;
return ((int) (motion.length() * modifier)) / 100 * 100;
}
public static MovementContext readNBT(CompoundNBT nbt) {
MovementContext context = new MovementContext(NBTUtil.readBlockState(nbt.getCompound("State")),
MoverType.valueOf(nbt.getString("MoverType")));
context.motion = VecHelper.readNBT(nbt.getList("Motion", NBT.TAG_DOUBLE));
context.movementSpeedModifier = nbt.getFloat("SpeedModifier");
context.currentGridPos = NBTUtil.readBlockPos(nbt.getCompound("GridPos"));
return context;
}
public CompoundNBT writeToNBT(CompoundNBT nbt) {
nbt.put("State", NBTUtil.writeBlockState(state));
nbt.putString("MoverType", moverType.name());
nbt.put("Motion", VecHelper.writeNBT(motion));
nbt.putFloat("SpeedModifier", movementSpeedModifier);
nbt.put("GridPos", NBTUtil.writeBlockPos(currentGridPos));
return nbt;
}
}
@OnlyIn(value = Dist.CLIENT)
default SuperByteBuffer renderInContraption(MovementContext context) {
return null;
}
}

View file

@ -1,108 +0,0 @@
package com.simibubi.create.modules.contraptions.components.constructs.bearing;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import org.lwjgl.opengl.GL11;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.utility.PlacementSimulationWorld;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
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.model.IBakedModel;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
import net.minecraftforge.client.model.data.EmptyModelData;
public class MechanicalBearingTileEntityRenderer extends KineticTileEntityRenderer {
protected static Cache<RotationConstruct, RotationConstructVertexBuffer> cachedConstructs;
protected static PlacementSimulationWorld renderWorld;
@Override
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
int destroyStage, BufferBuilder buffer) {
super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
MechanicalBearingTileEntity bearingTe = (MechanicalBearingTileEntity) te;
final Direction facing = te.getBlockState().get(BlockStateProperties.FACING);
BlockState capState = AllBlocks.MECHANICAL_BEARING_TOP.get().getDefaultState().with(BlockStateProperties.FACING,
facing);
SuperByteBuffer superBuffer = CreateClient.bufferCache.renderBlockState(KINETIC_TILE, capState);
float interpolatedAngle = bearingTe.getInterpolatedAngle(partialTicks);
kineticRotationTransform(superBuffer, bearingTe, facing.getAxis(), interpolatedAngle, getWorld());
superBuffer.translate(x, y, z).renderInto(buffer);
if (!bearingTe.running)
return;
cacheConstructIfMissing(bearingTe.movingConstruct);
renderConstructFromCache(bearingTe.movingConstruct, bearingTe, x, y, z, partialTicks, buffer);
}
protected void cacheConstructIfMissing(RotationConstruct c) {
if (cachedConstructs == null)
cachedConstructs = CacheBuilder.newBuilder().expireAfterAccess(1, TimeUnit.SECONDS).build();
if (cachedConstructs.getIfPresent(c) != null)
return;
if (renderWorld == null || renderWorld.getWorld() != Minecraft.getInstance().world)
renderWorld = new PlacementSimulationWorld(Minecraft.getInstance().world);
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
Random random = new Random();
BufferBuilder builder = new BufferBuilder(0);
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
builder.setTranslation(0, 0, 0);
for (BlockInfo info : c.blocks.values()) {
renderWorld.setBlockState(info.pos, info.state);
}
for (BlockInfo info : c.blocks.values()) {
IBakedModel originalModel = dispatcher.getModelForState(info.state);
blockRenderer.renderModel(renderWorld, originalModel, info.state, info.pos, builder, true, random, 42,
EmptyModelData.INSTANCE);
}
builder.finishDrawing();
renderWorld.clear();
cachedConstructs.put(c, new RotationConstructVertexBuffer(builder.getByteBuffer()));
}
protected void renderConstructFromCache(RotationConstruct c, MechanicalBearingTileEntity te, double x, double y,
double z, float partialTicks, BufferBuilder buffer) {
float zfightBonus = 1 / 128f;
Direction direction = te.getBlockState().get(BlockStateProperties.FACING);
Vec3i vec = direction.getDirectionVec();
buffer.putBulkData(cachedConstructs.getIfPresent(c).getTransformed(te, (float) (x) + vec.getX() * zfightBonus,
(float) (y) + vec.getY() * zfightBonus, (float) (z) + vec.getZ() * zfightBonus,
te.getInterpolatedAngle(partialTicks), direction.getAxis()));
}
@Override
protected BlockState getRenderedBlockState(KineticTileEntity te) {
return AllBlocks.SHAFT_HALF.get().getDefaultState().with(BlockStateProperties.FACING,
te.getBlockState().get(BlockStateProperties.FACING).getOpposite());
}
public static void invalidateCache() {
if (cachedConstructs != null)
cachedConstructs.invalidateAll();
}
}

View file

@ -1,212 +0,0 @@
package com.simibubi.create.modules.contraptions.components.constructs.bearing;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.simibubi.create.AllBlockTags;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.CreateConfig;
import com.simibubi.create.modules.contraptions.components.constructs.ChassisTileEntity;
import com.simibubi.create.modules.contraptions.components.constructs.RadialChassisBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.PistonBlock;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
public class RotationConstruct {
protected Map<BlockPos, BlockInfo> blocks;
protected int sailBlocks;
public RotationConstruct() {
blocks = new HashMap<>();
sailBlocks = 0;
}
public static RotationConstruct getAttachedForRotating(World world, BlockPos pos, Direction direction) {
RotationConstruct construct = new RotationConstruct();
if (!construct.collectAttached(world, pos, direction))
return null;
return construct;
}
public int getSailBlocks() {
return sailBlocks;
}
protected boolean collectAttached(World world, BlockPos pos, Direction direction) {
if (isFrozen())
return false;
// Find chassis
List<BlockInfo> chassis = collectChassis(world, pos, direction);
if (chassis == null)
return false;
// Get single block
if (chassis.isEmpty()) {
BlockPos blockPos = pos.offset(direction);
BlockState state = world.getBlockState(pos.offset(direction));
if (state.getMaterial().isReplaceable() || state.isAir(world, blockPos))
return true;
if (state.getCollisionShape(world, blockPos).isEmpty())
return true;
if (!canRotate(world, blockPos, direction))
return false;
blocks.put(blockPos, new BlockInfo(blockPos.subtract(pos), state, null));
// Get attached blocks by chassis
} else {
List<BlockInfo> attachedBlocksByChassis = getAttachedBlocksByChassis(world, direction, chassis);
if (attachedBlocksByChassis == null)
return false;
attachedBlocksByChassis.forEach(info -> {
if (isSailBlock(info.state))
sailBlocks++;
blocks.put(info.pos, new BlockInfo(info.pos.subtract(pos), info.state, info.nbt));
});
}
return true;
}
private List<BlockInfo> getAttachedBlocksByChassis(World world, Direction direction, List<BlockInfo> chassis) {
List<BlockInfo> blocks = new ArrayList<>();
RadialChassisBlock def = (RadialChassisBlock) AllBlocks.ROTATION_CHASSIS.block;
for (BlockInfo chassisBlock : chassis) {
blocks.add(chassisBlock);
BlockState state = chassisBlock.state;
BlockPos currentPos = chassisBlock.pos;
TileEntity tileEntity = world.getTileEntity(currentPos);
if (!(tileEntity instanceof ChassisTileEntity))
return null;
int chassisRange = ((ChassisTileEntity) tileEntity).getRange();
Set<BlockPos> visited = new HashSet<>();
for (Direction facing : Direction.values()) {
if (facing.getAxis() == direction.getAxis())
continue;
if (!state.get(def.getGlueableSide(state, facing)))
continue;
BlockPos startPos = currentPos.offset(facing);
List<BlockPos> frontier = new LinkedList<>();
frontier.add(startPos);
CompoundNBT nbt = new CompoundNBT();
nbt.putInt("Range", chassisRange);
while (!frontier.isEmpty()) {
BlockPos searchPos = frontier.remove(0);
BlockState searchedState = world.getBlockState(searchPos);
if (visited.contains(searchPos))
continue;
if (!searchPos.withinDistance(currentPos, chassisRange + .5f))
continue;
if (searchedState.getMaterial().isReplaceable() || state.isAir(world, searchPos))
continue;
if (searchedState.getCollisionShape(world, searchPos).isEmpty())
continue;
if (!canRotate(world, searchPos, direction))
return null;
visited.add(searchPos);
blocks.add(new BlockInfo(searchPos, searchedState,
AllBlocks.ROTATION_CHASSIS.typeOf(searchedState) ? nbt : null));
for (Direction offset : Direction.values()) {
if (offset.getAxis() == direction.getAxis())
continue;
if (searchPos.equals(currentPos) && offset != facing)
continue;
frontier.add(searchPos.offset(offset));
}
}
}
}
return blocks;
}
private List<BlockInfo> collectChassis(World world, BlockPos pos, Direction direction) {
List<BlockInfo> chassis = new ArrayList<>();
for (int distance = 1; distance <= CreateConfig.parameters.maxChassisForRotation.get(); distance++) {
BlockPos currentPos = pos.offset(direction, distance);
if (!world.isBlockPresent(currentPos))
return chassis;
BlockState state = world.getBlockState(currentPos);
if (!AllBlocks.ROTATION_CHASSIS.typeOf(state))
return chassis;
if (direction.getAxis() != state.get(BlockStateProperties.AXIS))
return chassis;
chassis.add(new BlockInfo(currentPos, state, null));
}
return chassis;
}
private static boolean isSailBlock(BlockState state) {
return AllBlockTags.WINDMILL_SAILS.matches(state);
}
public CompoundNBT writeNBT() {
CompoundNBT nbt = new CompoundNBT();
ListNBT blocks = new ListNBT();
for (BlockInfo block : this.blocks.values()) {
CompoundNBT c = new CompoundNBT();
c.put("Block", NBTUtil.writeBlockState(block.state));
c.put("Pos", NBTUtil.writeBlockPos(block.pos));
if (block.nbt != null)
c.put("Data", block.nbt);
blocks.add(c);
}
nbt.put("Blocks", blocks);
return nbt;
}
public static RotationConstruct fromNBT(CompoundNBT nbt) {
RotationConstruct construct = new RotationConstruct();
nbt.getList("Blocks", 10).forEach(c -> {
CompoundNBT comp = (CompoundNBT) c;
BlockInfo info = new BlockInfo(NBTUtil.readBlockPos(comp.getCompound("Pos")),
NBTUtil.readBlockState(comp.getCompound("Block")),
comp.contains("Data") ? comp.getCompound("Data") : null);
construct.blocks.put(info.pos, info);
});
return construct;
}
private static boolean canRotate(World world, BlockPos pos, Direction direction) {
return PistonBlock.canPush(world.getBlockState(pos), world, pos, direction, true, direction)
|| AllBlocks.ROTATION_CHASSIS.typeOf(world.getBlockState(pos));
}
public static boolean isFrozen() {
return CreateConfig.parameters.freezeRotationConstructs.get();
}
}

View file

@ -1,42 +0,0 @@
package com.simibubi.create.modules.contraptions.components.constructs.bearing;
import java.nio.ByteBuffer;
import com.simibubi.create.foundation.utility.BufferManipulator;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
public class RotationConstructVertexBuffer extends BufferManipulator {
public RotationConstructVertexBuffer(ByteBuffer original) {
super(original);
}
public ByteBuffer getTransformed(TileEntity te, float x, float y, float z, float angle, Axis axis) {
original.rewind();
mutable.rewind();
float cos = MathHelper.cos(angle);
float sin = MathHelper.sin(angle);
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
float xL = getX(original, vertex) -.5f;
float yL = getY(original, vertex) -.5f;
float zL = getZ(original, vertex) -.5f;
float xL2 = rotateX(xL, yL, zL, sin, cos, axis) + .5f;
float yL2 = rotateY(xL, yL, zL, sin, cos, axis) + .5f;
float zL2 = rotateZ(xL, yL, zL, sin, cos, axis) + .5f;
putPos(mutable, vertex, xL2 + x, yL2 + y, zL2 + z);
BlockPos pos = new BlockPos(te.getPos().getX() + xL2, te.getPos().getY() + yL2, te.getPos().getZ() + zL2);
putLight(mutable, vertex, te.getWorld().getCombinedLight(pos, 0));
}
return mutable;
}
}

View file

@ -1,202 +0,0 @@
package com.simibubi.create.modules.contraptions.components.constructs.mounted;
import com.simibubi.create.AllEntities;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior.MovementContext;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.IPacket;
import net.minecraft.network.PacketBuffer;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.util.DamageSource;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
import net.minecraftforge.fml.network.FMLPlayMessages.SpawnEntity;
import net.minecraftforge.fml.network.NetworkHooks;
public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnData {
protected MountedContraption contraption;
protected float initialAngle;
enum MovementType {
TRANSLATION, ROTATION, MOUNTED;
}
// Not synchronizing any of these
public float targetYaw;
public float targetPitch;
public float contraptionYaw;
public float contraptionPitch;
public ContraptionEntity(EntityType<?> entityTypeIn, World worldIn) {
super(entityTypeIn, worldIn);
}
protected ContraptionEntity(World world) {
this(AllEntities.CONTRAPTION.type, world);
}
public ContraptionEntity(World world, MountedContraption contraption, float initialAngle) {
this(world);
this.contraption = contraption;
this.initialAngle = initialAngle;
this.prevRotationYaw = initialAngle;
this.contraptionYaw = initialAngle;
this.targetYaw = initialAngle;
}
@Override
protected void registerData() {
}
@Override
public void tick() {
super.tick();
Entity e = getRidingEntity();
if (e == null)
remove();
else {
Vec3d movementVector = e.getMotion();
Vec3d motion = movementVector.normalize();
if (motion.length() > 0) {
targetYaw = yawFromMotion(motion);
targetPitch = (float) ((Math.atan(motion.y) * 73.0D) / Math.PI * 180);
if (targetYaw < 0)
targetYaw += 360;
if (contraptionYaw < 0)
contraptionYaw += 360;
}
float speed = 0.2f;
prevRotationYaw = contraptionYaw;
contraptionYaw = angleLerp(speed, contraptionYaw, targetYaw);
prevRotationPitch = contraptionPitch;
contraptionPitch = angleLerp(speed, contraptionPitch, targetPitch);
tickActors(movementVector);
}
}
public void tickActors(Vec3d movementVector) {
contraption.getActors().forEach(pair -> {
MovementContext context = pair.right;
float deg = -contraptionYaw + initialAngle;
context.motion = VecHelper.rotate(movementVector, deg, Axis.Y);
if (context.world == null)
context.world = world;
Vec3d offset = new Vec3d(pair.left.pos.subtract(contraption.getAnchor()));
world.addParticle(ParticleTypes.BUBBLE, offset.x, offset.y, offset.z, 0, 0, 0);
offset = VecHelper.rotate(offset, deg, Axis.Y);
world.addParticle(ParticleTypes.CRIT, offset.x, offset.y, offset.z, 0, 0, 0);
offset = offset.add(new Vec3d(getPosition()).add(0.5, 0, 0.5));
world.addParticle(ParticleTypes.NOTE, offset.x, offset.y, offset.z, 0, 10, 0);
if (world.isRemote)
return;
BlockPos gridPos = new BlockPos(offset);
if (context.currentGridPos.equals(gridPos))
return;
context.currentGridPos = gridPos;
IHaveMovementBehavior actor = (IHaveMovementBehavior) pair.left.state.getBlock();
actor.visitPosition(context);
});
}
public static float yawFromMotion(Vec3d motion) {
return (float) ((Math.PI / 2 - Math.atan2(motion.z, motion.x)) / Math.PI * 180);
}
public float getYaw(float partialTicks) {
float yaw = contraptionYaw;
return (partialTicks == 1.0F ? yaw : angleLerp(partialTicks, this.prevRotationYaw, yaw)) - initialAngle;
}
public float getPitch(float partialTicks) {
float pitch = contraptionPitch;
return partialTicks == 1.0F ? pitch : angleLerp(partialTicks, this.prevRotationPitch, pitch);
}
private float angleLerp(float pct, float current, float target) {
current = current % 360;
target = target % 360;
float shortest_angle = ((((target - current) % 360) + 540) % 360) - 180;
return current + shortest_angle * pct;
}
public boolean hitByEntity(Entity entityIn) {
return entityIn instanceof PlayerEntity
? this.attackEntityFrom(DamageSource.causePlayerDamage((PlayerEntity) entityIn), 0.0F)
: false;
}
public boolean attackEntityFrom(DamageSource source, float amount) {
if (this.isInvulnerableTo(source)) {
return false;
} else {
if (this.isAlive() && !this.world.isRemote) {
this.remove();
this.markVelocityChanged();
}
return true;
}
}
public static EntityType.Builder<?> build(EntityType.Builder<?> builder) {
@SuppressWarnings("unchecked")
EntityType.Builder<ContraptionEntity> entityBuilder = (EntityType.Builder<ContraptionEntity>) builder;
return entityBuilder.setCustomClientFactory(ContraptionEntity::spawn).size(1, 1);
}
public static ContraptionEntity spawn(SpawnEntity spawnEntity, World world) {
return new ContraptionEntity(world);
}
@Override
protected void readAdditional(CompoundNBT compound) {
contraption = new MountedContraption();
contraption.readNBT(compound.getCompound("Contraption"));
initialAngle = compound.getFloat("InitialAngle");
prevRotationYaw = initialAngle;
contraptionYaw = initialAngle;
targetYaw = initialAngle;
}
@Override
protected void writeAdditional(CompoundNBT compound) {
compound.put("Contraption", contraption.writeNBT());
compound.putFloat("InitialAngle", initialAngle);
}
@Override
public IPacket<?> createSpawnPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
public void writeSpawnData(PacketBuffer buffer) {
CompoundNBT compound = new CompoundNBT();
writeAdditional(compound);
buffer.writeCompoundTag(compound);
}
@Override
public void readSpawnData(PacketBuffer additionalData) {
readAdditional(additionalData.readCompoundTag());
}
}

View file

@ -1,347 +0,0 @@
package com.simibubi.create.modules.contraptions.components.constructs.piston;
import static com.simibubi.create.CreateConfig.parameters;
import static com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonBlock.STATE;
import java.util.Arrays;
import java.util.Iterator;
import org.apache.commons.lang3.tuple.MutablePair;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.Create;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior.MovementContext;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior.MoverType;
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonBlock.PistonState;
import net.minecraft.block.Blocks;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class MechanicalPistonTileEntity extends KineticTileEntity {
protected PistonContraption movedContraption;
protected float offset;
protected boolean running;
protected boolean assembleNextTick;
protected boolean hadCollisionWithOtherPiston;
public MechanicalPistonTileEntity() {
super(AllTileEntities.MECHANICAL_PISTON.type);
}
@Override
public void onSpeedChanged() {
super.onSpeedChanged();
assembleNextTick = true;
}
@Override
public void remove() {
this.removed = true;
if (!world.isRemote)
disassembleConstruct();
super.remove();
}
@Override
public AxisAlignedBB getRenderBoundingBox() {
return INFINITE_EXTENT_AABB;
}
@Override
@OnlyIn(Dist.CLIENT)
public double getMaxRenderDistanceSquared() {
return super.getMaxRenderDistanceSquared() * 16;
}
@Override
public CompoundNBT write(CompoundNBT tag) {
tag.putBoolean("Running", running);
tag.putFloat("Offset", offset);
if (running && !PistonContraption.isFrozen())
tag.put("Construct", movedContraption.writeNBT());
return super.write(tag);
}
@Override
public void read(CompoundNBT tag) {
running = tag.getBoolean("Running");
offset = tag.getFloat("Offset");
if (running && !PistonContraption.isFrozen()) {
movedContraption = new PistonContraption();
movedContraption.readNBT(tag.getCompound("Construct"));
for (MutablePair<BlockInfo, MovementContext> pair : movedContraption.getActors()) {
MovementContext context = new MovementContext(pair.left.state, MoverType.PISTON);
context.world = world;
Direction direction = getBlockState().get(BlockStateProperties.FACING);
context.motion = new Vec3d(direction.getDirectionVec()).scale(getMovementSpeed()).normalize();
context.currentGridPos = pair.left.pos.offset(direction, getModulatedOffset(offset));
pair.setRight(context);
}
}
super.read(tag);
}
protected void onBlockVisited(float newOffset) {
if (PistonContraption.isFrozen())
return;
Direction direction = getBlockState().get(BlockStateProperties.FACING);
for (MutablePair<BlockInfo, MovementContext> pair : movedContraption.getActors()) {
BlockInfo block = pair.left;
MovementContext context = pair.right;
BlockPos newPos = block.pos.offset(direction, getModulatedOffset(newOffset));
context.currentGridPos = newPos;
IHaveMovementBehavior actor = (IHaveMovementBehavior) block.state.getBlock();
actor.visitPosition(context);
}
}
public void assembleConstruct() {
Direction direction = getBlockState().get(BlockStateProperties.FACING);
// Collect Construct
movedContraption = PistonContraption.movePistonAt(world, pos, direction, getMovementSpeed() < 0);
if (movedContraption == null)
return;
// Check if not at limit already
float resultingOffset = movedContraption.initialExtensionProgress + getMovementSpeed();
if (resultingOffset <= 0 || resultingOffset >= movedContraption.extensionLength) {
movedContraption = null;
return;
}
if (hasBlockCollisions(resultingOffset + .5f)) {
movedContraption = null;
return;
}
// Run
running = true;
offset = movedContraption.initialExtensionProgress;
if (!world.isRemote)
Create.constructHandler.add(this);
sendData();
getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66);
for (BlockInfo block : movedContraption.blocks.values()) {
BlockPos startPos = block.pos.offset(direction, movedContraption.initialExtensionProgress);
if (startPos.equals(pos))
continue;
getWorld().setBlockState(startPos, Blocks.AIR.getDefaultState(), 67);
}
for (MutablePair<BlockInfo, MovementContext> pair : movedContraption.getActors()) {
MovementContext context = new MovementContext(pair.left.state, MoverType.PISTON);
context.world = world;
context.motion = new Vec3d(direction.getDirectionVec()).scale(getMovementSpeed()).normalize();
context.currentGridPos = pair.left.pos.offset(direction, getModulatedOffset(offset));
pair.setRight(context);
}
onBlockVisited(offset);
}
public void disassembleConstruct() {
if (!running)
return;
Direction direction = getBlockState().get(BlockStateProperties.FACING);
if (!removed)
getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.EXTENDED), 3);
movedContraption.disassemble(world, BlockPos.ZERO.offset(direction, getModulatedOffset(offset)),
(targetPos, state) -> {
if (targetPos.equals(pos)) {
if (!AllBlocks.PISTON_POLE.typeOf(state) && !removed)
world.setBlockState(pos, getBlockState().with(STATE, PistonState.RETRACTED), 3);
return true;
}
return false;
});
running = false;
if (!world.isRemote)
Create.constructHandler.remove(this);
movedContraption = null;
sendData();
if (removed)
AllBlocks.MECHANICAL_PISTON.get().onBlockHarvested(world, pos, getBlockState(), null);
}
@Override
public void tick() {
super.tick();
if (isRemoved())
return;
if (!world.isRemote && assembleNextTick) {
assembleNextTick = false;
if (running) {
if (getSpeed() == 0)
disassembleConstruct();
else {
for (MutablePair<BlockInfo, MovementContext> pair : movedContraption.getActors())
pair.right.motion = new Vec3d(
getBlockState().get(BlockStateProperties.FACING).getDirectionVec())
.scale(getMovementSpeed());
sendData();
}
return;
}
assembleConstruct();
return;
}
if (!running)
return;
float movementSpeed = getMovementSpeed();
Direction movementDirection = getBlockState().get(BlockStateProperties.FACING);
float newOffset = offset + movementSpeed;
MovingConstructHandler.moveEntities(this, movementSpeed, movementDirection, newOffset);
if (world.isRemote) {
offset = newOffset;
return;
}
if (getModulatedOffset(newOffset) != getModulatedOffset(offset)) {
onBlockVisited(newOffset);
}
float movement = .5f + (movementSpeed < 0 ? -1f : 0);
if (getModulatedOffset(newOffset + movement) != getModulatedOffset(offset + movement)) {
if (hasBlockCollisions(newOffset + movement)) {
disassembleConstruct();
if (hadCollisionWithOtherPiston)
hadCollisionWithOtherPiston = false;
else if (movementSpeed > 0)
assembleNextTick = true;
return;
}
}
offset = newOffset;
if (offset <= 0 || offset >= movedContraption.extensionLength) {
disassembleConstruct();
return;
}
}
private boolean hasBlockCollisions(float newOffset) {
if (PistonContraption.isFrozen())
return true;
Direction movementDirection = getBlockState().get(BlockStateProperties.FACING);
BlockPos relativePos = BlockPos.ZERO.offset(movementDirection, getModulatedOffset(newOffset));
// Other moving Pistons
int maxPossibleRange = parameters.maxPistonPoles.get() + parameters.maxChassisRange.get()
+ parameters.maxChassisForTranslation.get();
Iterator<MechanicalPistonTileEntity> iterator = Create.constructHandler.getOtherMovingPistonsInWorld(this)
.iterator();
pistonLoop: while (iterator.hasNext()) {
MechanicalPistonTileEntity otherPiston = iterator.next();
if (otherPiston == this)
continue;
if (!otherPiston.running || otherPiston.movedContraption == null) {
iterator.remove();
continue;
}
if (otherPiston.pos.manhattanDistance(pos) > maxPossibleRange * 2)
continue;
Direction otherMovementDirection = otherPiston.getBlockState().get(BlockStateProperties.FACING);
BlockPos otherRelativePos = BlockPos.ZERO.offset(otherMovementDirection,
getModulatedOffset(otherPiston.offset));
for (AxisAlignedBB tBB : Arrays.asList(movedContraption.constructCollisionBox,
movedContraption.pistonCollisionBox)) {
for (AxisAlignedBB oBB : Arrays.asList(otherPiston.movedContraption.constructCollisionBox,
otherPiston.movedContraption.pistonCollisionBox)) {
if (tBB == null || oBB == null)
continue;
boolean frontalCollision = otherMovementDirection == movementDirection.getOpposite();
BlockPos thisColliderOffset = relativePos.offset(movementDirection,
frontalCollision ? (getMovementSpeed() > 0 ? 1 : -1) : 0);
AxisAlignedBB thisBB = tBB.offset(thisColliderOffset);
AxisAlignedBB otherBB = oBB.offset(otherRelativePos);
if (thisBB.intersects(otherBB)) {
boolean actuallyColliding = false;
for (BlockPos colliderPos : movedContraption.getColliders(world, movementDirection)) {
colliderPos = colliderPos.add(thisColliderOffset).subtract(otherRelativePos);
if (!otherPiston.movedContraption.blocks.containsKey(colliderPos))
continue;
actuallyColliding = true;
}
if (!actuallyColliding)
continue pistonLoop;
hadCollisionWithOtherPiston = true;
return true;
}
}
}
}
if (!running)
return false;
// Other Blocks in world
for (BlockPos pos : movedContraption.getColliders(world,
getMovementSpeed() > 0 ? movementDirection : movementDirection.getOpposite())) {
BlockPos colliderPos = pos.add(relativePos);
if (!world.isBlockPresent(colliderPos))
return true;
if (!world.getBlockState(colliderPos).getMaterial().isReplaceable()
&& !world.getBlockState(colliderPos).getCollisionShape(world, colliderPos).isEmpty())
return true;
}
return false;
}
private int getModulatedOffset(float offset) {
return MathHelper.clamp((int) (offset + .5f), 0, movedContraption.extensionLength);
}
public float getMovementSpeed() {
Direction pistonDirection = getBlockState().get(BlockStateProperties.FACING);
int movementModifier = pistonDirection.getAxisDirection().getOffset()
* (pistonDirection.getAxis() == Axis.Z ? -1 : 1);
return getSpeed() * -movementModifier / 1024f;
}
public Vec3d getConstructOffset(float partialTicks) {
float interpolatedOffset = MathHelper.clamp(offset + (partialTicks - .5f) * getMovementSpeed(), 0,
movedContraption.extensionLength);
return new Vec3d(getBlockState().get(BlockStateProperties.FACING).getDirectionVec()).scale(interpolatedOffset);
}
}

View file

@ -1,184 +0,0 @@
package com.simibubi.create.modules.contraptions.components.constructs.piston;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import com.simibubi.create.Create;
import com.simibubi.create.modules.contraptions.components.constructs.Contraption;
import net.minecraft.block.material.PushReaction;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.MoverType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.ReuseableStream;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber
public class MovingConstructHandler {
static List<AxisAlignedBB> renderedBBs = new LinkedList<>();
static Map<IWorld, List<MechanicalPistonTileEntity>> movingPistons = new HashMap<>();
public void onLoadWorld(IWorld world) {
movingPistons.put(world, new ArrayList<>());
Create.logger.debug("Prepared Construct List for " + world.getDimension().getType().getRegistryName());
}
public void onUnloadWorld(IWorld world) {
movingPistons.remove(world);
Create.logger.debug("Removed Construct List for " + world.getDimension().getType().getRegistryName());
}
public static void moveEntities(MechanicalPistonTileEntity te, float movementSpeed, Direction movementDirection,
float newOffset) {
if (PistonContraption.isFrozen())
return;
World world = te.getWorld();
Vec3d movementVec = new Vec3d(te.getBlockState().get(BlockStateProperties.FACING).getDirectionVec());
Contraption construct = te.movedContraption;
// if (world.isRemote) {
// renderedBBs.clear();
// if (construct.pistonCollisionBox != null)
// renderedBBs.add(construct.pistonCollisionBox.offset(te.getConstructOffset(0)));
// if (construct.constructCollisionBox != null)
// renderedBBs.add(construct.constructCollisionBox.offset(te.getConstructOffset(0)));
//
// }
if (construct.getCollisionBoxFront() != null) {
AxisAlignedBB constructBB = construct.getCollisionBoxFront().offset(te.getConstructOffset(0)).grow(.5f);
for (Entity entity : world.getEntitiesWithinAABB((EntityType<?>) null, constructBB,
e -> e.getPushReaction() == PushReaction.NORMAL)) {
AxisAlignedBB entityScanBB = entity.getBoundingBox().offset(movementVec.scale(-1 * newOffset))
.grow(.5f);
BlockPos min = new BlockPos(entityScanBB.minX, entityScanBB.minY, entityScanBB.minZ);
BlockPos max = new BlockPos(entityScanBB.maxX, entityScanBB.maxY, entityScanBB.maxZ);
Stream<VoxelShape> hits = BlockPos.getAllInBox(min, max).filter(construct.blocks::containsKey)
.map(pos -> {
Vec3d vec = new Vec3d(pos).add(te.getConstructOffset(te.getMovementSpeed() > 0 ? 1 : 0));
return construct.blocks.get(pos).state.getShape(world, new BlockPos(vec)).withOffset(vec.x,
vec.y, vec.z);
});
ReuseableStream<VoxelShape> potentialHits = new ReuseableStream<>(hits);
AxisAlignedBB entityBB = entity.getBoundingBox();
Vec3d motion = entity.getMotion();
Vec3d movement = new Vec3d(movementDirection.getDirectionVec()).scale(-movementSpeed).add(motion);
Vec3d allowedMovement = Entity.getAllowedMovement(movement, entityBB, world,
ISelectionContext.forEntity(entity), potentialHits);
for (Object shape : potentialHits.createStream().toArray()) {
VoxelShape voxelShape = (VoxelShape) shape;
if (!entityBB.intersects(voxelShape.getBoundingBox()))
continue;
Direction bestSide = Direction.DOWN;
double bestOffset = 100;
double finalOffset = 0;
for (Direction face : Direction.values()) {
Axis axis = face.getAxis();
double d = axis == Axis.X ? entityBB.getXSize()
: axis == Axis.Y ? entityBB.getYSize() : entityBB.getZSize();
d = d + 1.5f;
Vec3d nudge = new Vec3d(face.getDirectionVec()).scale(d);
AxisAlignedBB nudgedBB = entityBB.offset(nudge.getX(), nudge.getY(), nudge.getZ());
double nudgeDistance = face.getAxisDirection() == AxisDirection.POSITIVE ? -d : d;
double offset = voxelShape.getAllowedOffset(face.getAxis(), nudgedBB, nudgeDistance);
double abs = Math.abs(nudgeDistance - offset);
if (abs < Math.abs(bestOffset) && abs != 0) {
bestOffset = abs;
finalOffset = abs;
bestSide = face;
}
}
if (bestOffset != 0) {
entity.move(MoverType.SELF, new Vec3d(bestSide.getDirectionVec()).scale(finalOffset));
switch (bestSide.getAxis()) {
case X:
entity.setMotion(0, motion.y, motion.z);
break;
case Y:
entity.setMotion(motion.x, bestSide == Direction.UP ? movementSpeed + 1 / 8f : 0, motion.z);
entity.fall(entity.fallDistance, 1);
entity.fallDistance = 0;
entity.onGround = true;
break;
case Z:
entity.setMotion(motion.x, motion.y, 0);
break;
}
break;
}
}
if (!allowedMovement.equals(movement)) {
if (allowedMovement.y != movement.y) {
entity.fall(entity.fallDistance, 1);
entity.fallDistance = 0;
entity.onGround = true;
}
if (entity instanceof PlayerEntity && !world.isRemote)
return;
entity.setMotion(allowedMovement.subtract(movement.subtract(motion)));
entity.velocityChanged = true;
}
}
}
}
public void add(MechanicalPistonTileEntity mechanicalPistonTileEntity) {
movingPistons.get(mechanicalPistonTileEntity.getWorld()).add(mechanicalPistonTileEntity);
}
public void remove(MechanicalPistonTileEntity mechanicalPistonTileEntity) {
movingPistons.get(mechanicalPistonTileEntity.getWorld()).remove(mechanicalPistonTileEntity);
}
public List<MechanicalPistonTileEntity> getOtherMovingPistonsInWorld(
MechanicalPistonTileEntity mechanicalPistonTileEntity) {
return movingPistons.get(mechanicalPistonTileEntity.getWorld());
}
// @SubscribeEvent
// @OnlyIn(value = Dist.CLIENT)
// public static void onRenderWorld(RenderWorldLastEvent event) {
// for (AxisAlignedBB bb : renderedBBs) {
// TessellatorHelper.prepareForDrawing();
// GlStateManager.disableTexture();
// GlStateManager.lineWidth(3);
// int color = ColorHelper.rainbowColor(renderedBBs.indexOf(bb) * 170);
// WorldRenderer.drawSelectionBoundingBox(bb.grow(1 / 256f), (color >> 16 & 0xFF) / 256f,
// (color >> 8 & 0xFF) / 256f, (color & 0xFF) / 256f, 1);
// GlStateManager.lineWidth(1);
// GlStateManager.enableTexture();
// TessellatorHelper.cleanUpAfterDrawing();
// }
// }
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.components.constructs; package com.simibubi.create.modules.contraptions.components.contraptions;
import static com.simibubi.create.CreateConfig.parameters; import static com.simibubi.create.CreateConfig.parameters;
import static net.minecraft.state.properties.BlockStateProperties.AXIS; import static net.minecraft.state.properties.BlockStateProperties.AXIS;
@ -18,10 +18,18 @@ import org.apache.commons.lang3.tuple.MutablePair;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.CreateConfig; import com.simibubi.create.CreateConfig;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior.MovementContext; import com.simibubi.create.modules.contraptions.components.contraptions.IHaveMovementBehavior.MovementContext;
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.BearingContraption;
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.LinearChassisBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.RadialChassisBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.mounted.MountedContraption;
import com.simibubi.create.modules.contraptions.components.contraptions.piston.PistonContraption;
import com.simibubi.create.modules.contraptions.components.saw.SawBlock; import com.simibubi.create.modules.contraptions.components.saw.SawBlock;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.FallingBlock; import net.minecraft.block.FallingBlock;
import net.minecraft.block.PistonBlock; import net.minecraft.block.PistonBlock;
import net.minecraft.block.ShulkerBoxBlock; import net.minecraft.block.ShulkerBoxBlock;
@ -117,13 +125,13 @@ public class Contraption {
return cachedColliders; return cachedColliders;
} }
protected boolean searchMovedStructure(World world, BlockPos pos, Direction direction) { public boolean searchMovedStructure(World world, BlockPos pos, Direction direction) {
List<BlockPos> frontier = new ArrayList<>(); List<BlockPos> frontier = new ArrayList<>();
Set<BlockPos> visited = new HashSet<>(); Set<BlockPos> visited = new HashSet<>();
anchor = pos; anchor = pos;
if (constructCollisionBox == null) if (constructCollisionBox == null)
constructCollisionBox = new AxisAlignedBB(pos); constructCollisionBox = new AxisAlignedBB(BlockPos.ZERO);
frontier.add(pos); frontier.add(pos);
if (!addToInitialFrontier(world, pos, direction, frontier)) if (!addToInitialFrontier(world, pos, direction, frontier))
@ -433,15 +441,29 @@ public class Contraption {
return compoundnbt; return compoundnbt;
} }
protected void add(BlockPos pos, BlockInfo block) { public void add(BlockPos pos, BlockInfo block) {
BlockInfo blockInfo = new BlockInfo(pos, block.state, block.nbt); BlockPos localPos = pos.subtract(anchor);
blocks.put(pos, blockInfo); BlockInfo blockInfo = new BlockInfo(localPos, block.state, block.nbt);
blocks.put(localPos, blockInfo);
if (block.state.getBlock() instanceof IHaveMovementBehavior) if (block.state.getBlock() instanceof IHaveMovementBehavior)
getActors().add(MutablePair.of(blockInfo, null)); getActors().add(MutablePair.of(blockInfo, null));
constructCollisionBox = constructCollisionBox.union(new AxisAlignedBB(pos)); constructCollisionBox = constructCollisionBox.union(new AxisAlignedBB(localPos));
} }
public void readNBT(CompoundNBT nbt) { public static Contraption fromNBT(World world, CompoundNBT nbt) {
String type = nbt.getString("Type");
Contraption contraption = new Contraption();
if (type.equals("Piston"))
contraption = new PistonContraption();
if (type.equals("Mounted"))
contraption = new MountedContraption();
if (type.equals("Bearing"))
contraption = new BearingContraption();
contraption.readNBT(world, nbt);
return contraption;
}
public void readNBT(World world, CompoundNBT nbt) {
nbt.getList("Blocks", 10).forEach(c -> { nbt.getList("Blocks", 10).forEach(c -> {
CompoundNBT comp = (CompoundNBT) c; CompoundNBT comp = (CompoundNBT) c;
BlockInfo info = new BlockInfo(NBTUtil.readBlockPos(comp.getCompound("Pos")), BlockInfo info = new BlockInfo(NBTUtil.readBlockPos(comp.getCompound("Pos")),
@ -453,7 +475,7 @@ public class Contraption {
nbt.getList("Actors", 10).forEach(c -> { nbt.getList("Actors", 10).forEach(c -> {
CompoundNBT comp = (CompoundNBT) c; CompoundNBT comp = (CompoundNBT) c;
BlockInfo info = blocks.get(NBTUtil.readBlockPos(comp.getCompound("Pos"))); BlockInfo info = blocks.get(NBTUtil.readBlockPos(comp.getCompound("Pos")));
MovementContext context = MovementContext.readNBT(comp); MovementContext context = MovementContext.readNBT(world, comp);
getActors().add(MutablePair.of(info, context)); getActors().add(MutablePair.of(info, context));
}); });
@ -469,6 +491,14 @@ public class Contraption {
public CompoundNBT writeNBT() { public CompoundNBT writeNBT() {
CompoundNBT nbt = new CompoundNBT(); CompoundNBT nbt = new CompoundNBT();
if (this instanceof PistonContraption)
nbt.putString("Type", "Piston");
if (this instanceof MountedContraption)
nbt.putString("Type", "Mounted");
if (this instanceof BearingContraption)
nbt.putString("Type", "Bearing");
ListNBT blocks = new ListNBT(); ListNBT blocks = new ListNBT();
for (BlockInfo block : this.blocks.values()) { for (BlockInfo block : this.blocks.values()) {
CompoundNBT c = new CompoundNBT(); CompoundNBT c = new CompoundNBT();
@ -520,7 +550,25 @@ public class Contraption {
return CreateConfig.parameters.freezePistonConstructs.get(); return CreateConfig.parameters.freezePistonConstructs.get();
} }
public void disassemble(IWorld world, BlockPos offset, BiPredicate<BlockPos, BlockState> customPlacement) { public void disassemble(IWorld world, BlockPos offset, float yaw, float pitch) {
disassemble(world, offset, yaw, pitch, (pos, state) -> false);
}
public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
removeBlocksFromWorld(world, offset, (pos, state) -> false);
}
public void removeBlocksFromWorld(IWorld world, BlockPos offset, BiPredicate<BlockPos, BlockState> customRemoval) {
for (BlockInfo block : blocks.values()) {
BlockPos add = block.pos.add(anchor).add(offset);
if (customRemoval.test(add, block.state))
continue;
world.setBlockState(add, Blocks.AIR.getDefaultState(), 67);
}
}
public void disassemble(IWorld world, BlockPos offset, float yaw, float pitch,
BiPredicate<BlockPos, BlockState> customPlacement) {
for (BlockInfo block : blocks.values()) { for (BlockInfo block : blocks.values()) {
BlockPos targetPos = block.pos.add(offset); BlockPos targetPos = block.pos.add(offset);
BlockState state = block.state; BlockState state = block.state;
@ -546,8 +594,21 @@ public class Contraption {
} }
} }
public void initActors(World world) {
for (MutablePair<BlockInfo, MovementContext> pair : actors) {
BlockState blockState = pair.left.state;
MovementContext context = new MovementContext(world, blockState);
((IHaveMovementBehavior) blockState.getBlock()).startMoving(context);
pair.setRight(context);
}
}
public List<MutablePair<BlockInfo, MovementContext>> getActors() { public List<MutablePair<BlockInfo, MovementContext>> getActors() {
return actors; return actors;
} }
public BlockPos getAnchor() {
return anchor;
}
} }

View file

@ -0,0 +1,306 @@
package com.simibubi.create.modules.contraptions.components.contraptions;
import org.apache.commons.lang3.tuple.MutablePair;
import com.simibubi.create.AllEntities;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.components.contraptions.IHaveMovementBehavior.MovementContext;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.network.IPacket;
import net.minecraft.network.PacketBuffer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
import net.minecraftforge.fml.network.NetworkHooks;
public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnData {
protected Contraption contraption;
protected float initialAngle;
protected BlockPos controllerPos;
protected IControlContraption controllerTE;
public float movementSpeedModifier;
public float prevYaw;
public float prevPitch;
public float prevRoll;
public float yaw;
public float pitch;
public float roll;
// Mounted Contraptions
public float targetYaw;
public float targetPitch;
public ContraptionEntity(EntityType<?> entityTypeIn, World worldIn) {
super(entityTypeIn, worldIn);
}
protected ContraptionEntity(World world) {
this(AllEntities.CONTRAPTION.type, world);
}
public ContraptionEntity(World world, Contraption contraption, float initialAngle) {
this(world);
this.contraption = contraption;
this.initialAngle = initialAngle;
this.prevYaw = initialAngle;
this.yaw = initialAngle;
this.targetYaw = initialAngle;
movementSpeedModifier = 1;
}
public <T extends TileEntity & IControlContraption> ContraptionEntity controlledBy(T controller) {
this.controllerPos = controller.getPos();
this.controllerTE = controller;
return this;
}
@Override
public void tick() {
attachToController();
Entity e = getRidingEntity();
if (e != null) {
Vec3d movementVector = e.getMotion();
Vec3d motion = movementVector.normalize();
if (motion.length() > 0) {
targetYaw = yawFromMotion(motion);
targetPitch = (float) ((Math.atan(motion.y) * 73.0D) / Math.PI * 180);
if (targetYaw < 0)
targetYaw += 360;
if (yaw < 0)
yaw += 360;
}
if (Math.abs(getShortestAngleDiff(yaw, targetYaw)) >= 175) {
initialAngle += 180;
yaw += 180;
prevYaw = yaw;
} else {
float speed = 0.2f;
prevYaw = yaw;
yaw = angleLerp(speed, yaw, targetYaw);
prevPitch = pitch;
pitch = angleLerp(speed, pitch, targetPitch);
}
tickActors(movementVector);
super.tick();
return;
}
prevYaw = yaw;
prevPitch = pitch;
prevRoll = roll;
tickActors(new Vec3d(posX - prevPosX, posY - prevPosY, posZ - prevPosZ));
super.tick();
}
public void tickActors(Vec3d movementVector) {
movementSpeedModifier = 1;
float anglePitch = getPitch(1);
float angleYaw = getYaw(1);
float angleRoll = getRoll(1);
Vec3d rotationVec = new Vec3d(angleRoll, angleYaw, anglePitch);
Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO);
for (MutablePair<BlockInfo, MovementContext> pair : contraption.actors) {
MovementContext context = pair.right;
BlockInfo blockInfo = pair.left;
IHaveMovementBehavior actor = (IHaveMovementBehavior) blockInfo.state.getBlock();
Vec3d actorPosition = new Vec3d(blockInfo.pos);
actorPosition = actorPosition.add(actor.getActiveAreaOffset(context));
actorPosition = VecHelper.rotate(actorPosition, angleRoll, angleYaw, anglePitch);
actorPosition = actorPosition.add(rotationOffset).add(posX, posY, posZ);
Vec3d previousPosition = context.position;
BlockPos gridPosition = new BlockPos(actorPosition);
boolean newPosVisited = true;
if (previousPosition != null) {
context.motion = actorPosition.subtract(previousPosition);
Vec3d relativeMotion = context.motion;
relativeMotion = VecHelper.rotate(relativeMotion, -angleRoll, -angleYaw, -anglePitch);
context.relativeMotion = relativeMotion;
newPosVisited = !new BlockPos(previousPosition).equals(gridPosition);
}
context.rotation = rotationVec;
context.position = actorPosition;
if (actor.isActive(context)) {
if (newPosVisited)
actor.visitNewPosition(context, gridPosition);
actor.tick(context);
}
if (movementSpeedModifier > context.movementSpeedModifier)
movementSpeedModifier = context.movementSpeedModifier;
}
}
public void moveTo(double x, double y, double z) {
move(x - posX, y - posY, z - posZ);
}
public void move(double x, double y, double z) {
// Collision and stuff
setPosition(posX + x, posY + y, posZ + z);
}
public void rotateTo(double roll, double yaw, double pitch) {
rotate(getShortestAngleDiff(this.roll, roll), getShortestAngleDiff(this.yaw, yaw),
getShortestAngleDiff(this.pitch, pitch));
}
public void rotate(double roll, double yaw, double pitch) {
// Collision and stuff
this.yaw += yaw;
this.pitch += pitch;
this.roll += roll;
}
@Override
public void setPosition(double x, double y, double z) {
Entity e = getRidingEntity();
if (e != null && e instanceof AbstractMinecartEntity) {
x -= .5;
z -= .5;
}
this.posX = x;
this.posY = y;
this.posZ = z;
if (this.isAddedToWorld() && !this.world.isRemote && world instanceof ServerWorld)
((ServerWorld) this.world).chunkCheck(this); // Forge - Process chunk registration after moving.
if (contraption != null) {
AxisAlignedBB cbox = contraption.getCollisionBoxFront();
if (cbox != null)
this.setBoundingBox(cbox.offset(x, y, z));
}
}
@Override
public void stopRiding() {
super.stopRiding();
if (!world.isRemote)
disassemble();
}
public static float yawFromMotion(Vec3d motion) {
return (float) ((3 * Math.PI / 2 + Math.atan2(motion.z, motion.x)) / Math.PI * 180);
}
public float getYaw(float partialTicks) {
return (getRidingEntity() == null ? 1 : -1)
* (partialTicks == 1.0F ? yaw : angleLerp(partialTicks, prevYaw, yaw)) + initialAngle;
}
public float getPitch(float partialTicks) {
return partialTicks == 1.0F ? pitch : angleLerp(partialTicks, prevPitch, pitch);
}
public float getRoll(float partialTicks) {
return partialTicks == 1.0F ? roll : angleLerp(partialTicks, prevRoll, roll);
}
private float angleLerp(float pct, float current, float target) {
return current + getShortestAngleDiff(current, target) * pct;
}
private float getShortestAngleDiff(double current, double target) {
current = current % 360;
target = target % 360;
return (float) (((((target - current) % 360) + 540) % 360) - 180);
}
public static EntityType.Builder<?> build(EntityType.Builder<?> builder) {
@SuppressWarnings("unchecked")
EntityType.Builder<ContraptionEntity> entityBuilder = (EntityType.Builder<ContraptionEntity>) builder;
return entityBuilder.size(1, 1);
}
@Override
protected void registerData() {
}
@Override
protected void readAdditional(CompoundNBT compound) {
contraption = Contraption.fromNBT(world, compound.getCompound("Contraption"));
initialAngle = compound.getFloat("InitialAngle");
if (compound.contains("Controller"))
controllerPos = NBTUtil.readBlockPos(compound.getCompound("Controller"));
prevYaw = initialAngle;
yaw = initialAngle;
targetYaw = initialAngle;
}
public void attachToController() {
if (controllerPos != null && controllerTE == null) {
if (!world.isBlockPresent(controllerPos))
return;
TileEntity te = world.getTileEntity(controllerPos);
if (te == null || !(te instanceof IControlContraption))
remove();
IControlContraption controllerTE = (IControlContraption) te;
this.controllerTE = controllerTE;
controllerTE.attach(this);
}
}
@Override
protected void writeAdditional(CompoundNBT compound) {
compound.put("Contraption", getContraption().writeNBT());
compound.putFloat("InitialAngle", initialAngle);
if (controllerPos != null)
compound.put("Controller", NBTUtil.writeBlockPos(controllerPos));
}
@Override
public IPacket<?> createSpawnPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
public void writeSpawnData(PacketBuffer buffer) {
CompoundNBT compound = new CompoundNBT();
writeAdditional(compound);
buffer.writeCompoundTag(compound);
}
@Override
public void readSpawnData(PacketBuffer additionalData) {
readAdditional(additionalData.readCompoundTag());
}
public void disassemble() {
if (getContraption() != null)
getContraption().disassemble(world, new BlockPos(getPositionVec().add(.5, .5, .5)), yaw, pitch);
remove();
}
public Contraption getContraption() {
return contraption;
}
}

View file

@ -1,10 +1,10 @@
package com.simibubi.create.modules.contraptions.components.constructs.mounted; package com.simibubi.create.modules.contraptions.components.contraptions;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.foundation.utility.TessellatorHelper; import com.simibubi.create.foundation.utility.TessellatorHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.components.constructs.ContraptionRenderer;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererManager; import net.minecraft.client.renderer.entity.EntityRendererManager;
@ -32,33 +32,31 @@ public class ContraptionEntityRenderer extends EntityRenderer<ContraptionEntity>
public void doRender(ContraptionEntity entity, double x, double y, double z, float yaw, float partialTicks) { public void doRender(ContraptionEntity entity, double x, double y, double z, float yaw, float partialTicks) {
if (!entity.isAlive()) if (!entity.isAlive())
return; return;
if (entity.contraption == null) if (entity.getContraption() == null)
return; return;
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translated(0, .5, 0); long randomBits = (long) entity.getEntityId() * 493286711L;
randomBits = randomBits * randomBits * 4392167121L + randomBits * 98761L;
float xNudge = (((float) (randomBits >> 16 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
float yNudge = (((float) (randomBits >> 20 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
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 angleYaw = (float) (entity.getYaw(partialTicks) / 180 * Math.PI);
float anglePitch = (float) (entity.getPitch(partialTicks) / 180 * Math.PI); float anglePitch = (float) (entity.getPitch(partialTicks) / 180 * Math.PI);
float angleRoll = (float) (entity.getRoll(partialTicks) / 180 * Math.PI);
Entity ridingEntity = entity.getRidingEntity(); Entity ridingEntity = entity.getRidingEntity();
if (ridingEntity != null && ridingEntity instanceof AbstractMinecartEntity) { if (ridingEntity != null && ridingEntity instanceof AbstractMinecartEntity) {
AbstractMinecartEntity cart = (AbstractMinecartEntity) ridingEntity; AbstractMinecartEntity cart = (AbstractMinecartEntity) ridingEntity;
long i = (long) entity.getEntityId() * 493286711L;
i = i * i * 4392167121L + i * 98761L;
float f = (((float) (i >> 16 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
float f1 = (((float) (i >> 20 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
float f2 = (((float) (i >> 24 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
GlStateManager.translatef(f, f1, f2);
double cartX = MathHelper.lerp((double) partialTicks, cart.lastTickPosX, cart.posX); double cartX = MathHelper.lerp((double) partialTicks, cart.lastTickPosX, cart.posX);
double cartY = MathHelper.lerp((double) partialTicks, cart.lastTickPosY, cart.posY); double cartY = MathHelper.lerp((double) partialTicks, cart.lastTickPosY, cart.posY);
double cartZ = MathHelper.lerp((double) partialTicks, cart.lastTickPosZ, cart.posZ); double cartZ = MathHelper.lerp((double) partialTicks, cart.lastTickPosZ, cart.posZ);
Vec3d cartPos = cart.getPos(cartX, cartY, cartZ); Vec3d cartPos = cart.getPos(cartX, cartY, cartZ);
if (cartPos != null) { if (cartPos != null) {
Vec3d cartPosFront = cart.getPosOffset(cartX, cartY, cartZ, (double) 0.3F); Vec3d cartPosFront = cart.getPosOffset(cartX, cartY, cartZ, (double) 0.3F);
Vec3d cartPosBack = cart.getPosOffset(cartX, cartY, cartZ, (double) -0.3F); Vec3d cartPosBack = cart.getPosOffset(cartX, cartY, cartZ, (double) -0.3F);
if (cartPosFront == null) if (cartPosFront == null)
@ -74,21 +72,26 @@ public class ContraptionEntityRenderer extends EntityRenderer<ContraptionEntity>
} }
} }
BlockPos anchor = entity.contraption.getAnchor(); Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO);
Vec3d rotationOffset = VecHelper.getCenterOf(anchor);
// Vec3d offset = VecHelper.getCenterOf(anchor).scale(-1);
TessellatorHelper.prepareFastRender(); TessellatorHelper.prepareFastRender();
TessellatorHelper.begin(DefaultVertexFormats.BLOCK); TessellatorHelper.begin(DefaultVertexFormats.BLOCK);
ContraptionRenderer.render(entity.world, entity.contraption, superByteBuffer -> { ContraptionRenderer.render(entity.world, entity.getContraption(), superByteBuffer -> {
superByteBuffer.translate(-rotationOffset.x, -rotationOffset.y, -rotationOffset.z); superByteBuffer.translate(-rotationOffset.x, -rotationOffset.y, -rotationOffset.z);
superByteBuffer.rotate(Axis.X, angleRoll);
superByteBuffer.rotate(Axis.Y, angleYaw); superByteBuffer.rotate(Axis.Y, angleYaw);
superByteBuffer.rotate(Axis.Z, anglePitch); superByteBuffer.rotate(Axis.Z, anglePitch);
superByteBuffer.translate(rotationOffset.x, rotationOffset.y, rotationOffset.z);
superByteBuffer.translate(x, y, z); superByteBuffer.translate(x, y, z);
superByteBuffer.offsetLighting(-x + entity.posX, -y + entity.posY, -z + entity.posZ);
}, Tessellator.getInstance().getBuffer()); }, Tessellator.getInstance().getBuffer());
TessellatorHelper.draw(); TessellatorHelper.draw();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
GlStateManager.shadeModel(7424);
GlStateManager.alphaFunc(516, 0.1F);
GlStateManager.matrixMode(5888);
RenderHelper.enableStandardItemLighting();
super.doRender(entity, x, y, z, yaw, partialTicks); super.doRender(entity, x, y, z, yaw, partialTicks);
} }

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.components.constructs; package com.simibubi.create.modules.contraptions.components.contraptions;
import java.util.Random; import java.util.Random;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -10,7 +10,7 @@ import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.utility.PlacementSimulationWorld; import com.simibubi.create.foundation.utility.PlacementSimulationWorld;
import com.simibubi.create.foundation.utility.SuperByteBuffer; import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.SuperByteBufferCache.Compartment; import com.simibubi.create.foundation.utility.SuperByteBufferCache.Compartment;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior.MovementContext; import com.simibubi.create.modules.contraptions.components.contraptions.IHaveMovementBehavior.MovementContext;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelRenderer; import net.minecraft.client.renderer.BlockModelRenderer;
@ -31,7 +31,7 @@ public class ContraptionRenderer {
public static void render(World world, Contraption c, Consumer<SuperByteBuffer> transform, BufferBuilder buffer) { public static void render(World world, Contraption c, Consumer<SuperByteBuffer> transform, BufferBuilder buffer) {
SuperByteBuffer contraptionBuffer = CreateClient.bufferCache.get(CONTRAPTION, c, () -> renderContraption(c)); SuperByteBuffer contraptionBuffer = CreateClient.bufferCache.get(CONTRAPTION, c, () -> renderContraption(c));
transform.accept(contraptionBuffer); transform.accept(contraptionBuffer);
buffer.putBulkData(contraptionBuffer.build()); contraptionBuffer.light((lx, ly, lz) -> world.getCombinedLight(new BlockPos(lx, ly, lz), 0)).renderInto(buffer);
renderActors(world, c, transform, buffer); renderActors(world, c, transform, buffer);
} }

View file

@ -0,0 +1,7 @@
package com.simibubi.create.modules.contraptions.components.contraptions;
public interface IControlContraption {
public void attach(ContraptionEntity contraption);
}

View file

@ -0,0 +1,99 @@
package com.simibubi.create.modules.contraptions.components.contraptions;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.Constants.NBT;
public interface IHaveMovementBehavior {
public class MovementContext {
public Vec3d position;
public Vec3d motion;
public Vec3d relativeMotion;
public Vec3d rotation;
public World world;
public BlockState state;
public float movementSpeedModifier;
public CompoundNBT data;
public MovementContext(World world, BlockState state) {
this.world = world;
this.state = state;
motion = Vec3d.ZERO;
relativeMotion = Vec3d.ZERO;
rotation = Vec3d.ZERO;
position = null;
data = new CompoundNBT();
movementSpeedModifier = 1;
}
public float getAnimationSpeed() {
int modifier = 1000;
double length = -motion.length();
if (Math.abs(length) < 1 / 512f)
return 0;
return (((int) (length * modifier + 100 * Math.signum(length))) / 100) * 100;
}
public static MovementContext readNBT(World world, CompoundNBT nbt) {
BlockState state = NBTUtil.readBlockState(nbt.getCompound("State"));
MovementContext context = new MovementContext(world, state);
context.motion = VecHelper.readNBT(nbt.getList("Motion", NBT.TAG_DOUBLE));
context.relativeMotion = VecHelper.readNBT(nbt.getList("RelativeMotion", NBT.TAG_DOUBLE));
context.rotation = VecHelper.readNBT(nbt.getList("Rotation", NBT.TAG_DOUBLE));
if (nbt.contains("Position"))
context.position = VecHelper.readNBT(nbt.getList("Position", NBT.TAG_DOUBLE));
context.movementSpeedModifier = nbt.getFloat("SpeedModifier");
context.data = nbt.getCompound("Data");
return context;
}
public CompoundNBT writeToNBT(CompoundNBT nbt) {
nbt.put("State", NBTUtil.writeBlockState(state));
nbt.put("Motion", VecHelper.writeNBT(motion));
nbt.put("RelativeMotion", VecHelper.writeNBT(relativeMotion));
nbt.put("Rotation", VecHelper.writeNBT(rotation));
if (position != null)
nbt.put("Position", VecHelper.writeNBT(position));
nbt.putFloat("SpeedModifier", movementSpeedModifier);
nbt.put("Data", data);
return nbt;
}
}
default boolean isActive(MovementContext context) {
return true;
}
default void tick(MovementContext context) {
}
default void startMoving(MovementContext context) {
}
default void visitNewPosition(MovementContext context, BlockPos pos) {
}
default Vec3d getActiveAreaOffset(MovementContext context) {
return Vec3d.ZERO;
}
@OnlyIn(value = Dist.CLIENT)
default SuperByteBuffer renderInContraption(MovementContext context) {
return null;
}
}

View file

@ -0,0 +1,54 @@
package com.simibubi.create.modules.contraptions.components.contraptions.bearing;
import com.simibubi.create.AllBlockTags;
import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
public class BearingContraption extends Contraption {
protected int sailBlocks;
protected Direction facing;
public static BearingContraption assembleBearingAt(World world, BlockPos pos, Direction direction) {
if (isFrozen())
return null;
BearingContraption construct = new BearingContraption();
construct.facing = direction;
if (!construct.searchMovedStructure(world, pos.offset(direction), direction))
return null;
construct.initActors(world);
return construct;
}
@Override
public void add(BlockPos pos, BlockInfo block) {
if (AllBlockTags.WINDMILL_SAILS.matches(block.state))
sailBlocks++;
super.add(pos, block);
}
@Override
public CompoundNBT writeNBT() {
CompoundNBT tag = super.writeNBT();
tag.putInt("Sails", sailBlocks);
tag.putInt("facing", facing.getIndex());
return tag;
}
@Override
public void readNBT(World world, CompoundNBT tag) {
sailBlocks = tag.getInt("Sails");
facing = Direction.byIndex(tag.getInt("Facing"));
super.readNBT(world, tag);
}
public int getSailBlocks() {
return sailBlocks;
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.components.constructs.bearing; package com.simibubi.create.modules.contraptions.components.contraptions.bearing;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.IWithTileEntity;
import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock; import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock;

View file

@ -1,25 +1,21 @@
package com.simibubi.create.modules.contraptions.components.constructs.bearing; package com.simibubi.create.modules.contraptions.components.contraptions.bearing;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity; import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity;
import com.simibubi.create.modules.contraptions.components.constructs.ChassisTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.IControlContraption;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
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.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraft.util.math.Vec3d;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity { public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity implements IControlContraption {
protected RotationConstruct movingConstruct; protected ContraptionEntity movedContraption;
protected float angle; protected float angle;
protected boolean running; protected boolean running;
protected boolean assembleNextTick; protected boolean assembleNextTick;
@ -30,17 +26,6 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
isWindmill = false; isWindmill = false;
} }
@Override
public AxisAlignedBB getRenderBoundingBox() {
return INFINITE_EXTENT_AABB;
}
@Override
@OnlyIn(Dist.CLIENT)
public double getMaxRenderDistanceSquared() {
return super.getMaxRenderDistanceSquared() * 16;
}
@Override @Override
public float getAddedStressCapacity() { public float getAddedStressCapacity() {
return isWindmill ? super.getAddedStressCapacity() : 0; return isWindmill ? super.getAddedStressCapacity() : 0;
@ -77,7 +62,9 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
public float getGeneratedSpeed() { public float getGeneratedSpeed() {
if (!running || !isWindmill) if (!running || !isWindmill)
return 0; return 0;
int sails = movingConstruct.getSailBlocks(); if (movedContraption == null)
return 0;
int sails = ((BearingContraption) movedContraption.getContraption()).getSailBlocks();
return MathHelper.clamp(sails, 0, 128); return MathHelper.clamp(sails, 0, 128);
} }
@ -86,9 +73,6 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
tag.putBoolean("Running", running); tag.putBoolean("Running", running);
tag.putBoolean("Windmill", isWindmill); tag.putBoolean("Windmill", isWindmill);
tag.putFloat("Angle", angle); tag.putFloat("Angle", angle);
if (running && !RotationConstruct.isFrozen())
tag.put("Construct", movingConstruct.writeNBT());
return super.write(tag); return super.write(tag);
} }
@ -97,15 +81,10 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
running = tag.getBoolean("Running"); running = tag.getBoolean("Running");
isWindmill = tag.getBoolean("Windmill"); isWindmill = tag.getBoolean("Windmill");
angle = tag.getFloat("Angle"); angle = tag.getFloat("Angle");
if (running && !RotationConstruct.isFrozen())
movingConstruct = RotationConstruct.fromNBT(tag.getCompound("Construct"));
super.read(tag); super.read(tag);
} }
public float getInterpolatedAngle(float partialTicks) { public float getInterpolatedAngle(float partialTicks) {
if (RotationConstruct.isFrozen())
return 0;
return MathHelper.lerp(partialTicks, angle, angle + getAngularSpeed()); return MathHelper.lerp(partialTicks, angle, angle + getAngularSpeed());
} }
@ -123,21 +102,22 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
Direction direction = getBlockState().get(BlockStateProperties.FACING); Direction direction = getBlockState().get(BlockStateProperties.FACING);
// Collect Construct // Collect Construct
movingConstruct = RotationConstruct.getAttachedForRotating(getWorld(), getPos(), direction); BearingContraption contraption = BearingContraption.assembleBearingAt(world, pos, direction);
if (movingConstruct == null) if (contraption == null)
return; return;
if (isWindmill && movingConstruct.getSailBlocks() == 0) if (isWindmill && contraption.getSailBlocks() == 0)
return; return;
movedContraption = new ContraptionEntity(world, contraption, 0).controlledBy(this);
BlockPos anchor = pos.offset(direction);
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ());
world.addEntity(movedContraption);
// Run // Run
running = true; running = true;
angle = 0; angle = 0;
sendData(); sendData();
for (BlockInfo info : movingConstruct.blocks.values()) {
getWorld().setBlockState(info.pos.add(pos), Blocks.AIR.getDefaultState(), 67);
}
updateGeneratedRotation(); updateGeneratedRotation();
} }
@ -145,24 +125,9 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
if (!running) if (!running)
return; return;
for (BlockInfo block : movingConstruct.blocks.values()) { movedContraption.disassemble();
BlockPos targetPos = block.pos.add(pos); movedContraption = null;
BlockState state = block.state;
for (Direction face : Direction.values())
state = state.updatePostPlacement(face, world.getBlockState(targetPos.offset(face)), world, targetPos,
targetPos.offset(face));
world.destroyBlock(targetPos, world.getBlockState(targetPos).getCollisionShape(world, targetPos).isEmpty());
getWorld().setBlockState(targetPos, state, 3);
TileEntity tileEntity = world.getTileEntity(targetPos);
if (tileEntity != null && block.nbt != null) {
((ChassisTileEntity) tileEntity).setRange(block.nbt.getInt("Range"));
}
}
running = false; running = false;
movingConstruct = null;
angle = 0; angle = 0;
updateGeneratedRotation(); updateGeneratedRotation();
sendData(); sendData();
@ -172,14 +137,15 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
public void tick() { public void tick() {
super.tick(); super.tick();
if (running && RotationConstruct.isFrozen()) if (running && Contraption.isFrozen())
disassembleConstruct(); disassembleConstruct();
if (!world.isRemote && assembleNextTick) { if (!world.isRemote && assembleNextTick) {
assembleNextTick = false; assembleNextTick = false;
if (running) { if (running) {
boolean canDisassemble = Math.abs(angle) < Math.PI / 4f || Math.abs(angle) > 7 * Math.PI / 4f; boolean canDisassemble = Math.abs(angle) < Math.PI / 4f || Math.abs(angle) > 7 * Math.PI / 4f;
if (speed == 0 && (canDisassemble || movingConstruct == null || movingConstruct.blocks.isEmpty())) { if (speed == 0 && (canDisassemble || movedContraption == null
|| movedContraption.getContraption().blocks.isEmpty())) {
disassembleConstruct(); disassembleConstruct();
} }
return; return;
@ -197,6 +163,26 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
float angularSpeed = getAngularSpeed(); float angularSpeed = getAngularSpeed();
float newAngle = angle + angularSpeed; float newAngle = angle + angularSpeed;
angle = (float) (newAngle % (2 * Math.PI)); angle = (float) (newAngle % (2 * Math.PI));
applyRotation();
}
private void applyRotation() {
if (movedContraption != null) {
Direction direction = getBlockState().get(BlockStateProperties.FACING);
Vec3d vec = new Vec3d(1, 1, 1).scale(angle * 180 / Math.PI).mul(new Vec3d(direction.getDirectionVec()));
movedContraption.rotateTo(vec.x, vec.y, -vec.z);
}
}
@Override
public void attach(ContraptionEntity contraption) {
if (contraption.getContraption() instanceof BearingContraption) {
this.movedContraption = contraption;
BlockPos anchor = pos.offset(getBlockState().get(BlockStateProperties.FACING));
movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ());
if (!world.isRemote)
sendData();
}
} }
} }

View file

@ -0,0 +1,38 @@
package com.simibubi.create.modules.contraptions.components.contraptions.bearing;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
public class MechanicalBearingTileEntityRenderer extends KineticTileEntityRenderer {
@Override
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
int destroyStage, BufferBuilder buffer) {
super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
MechanicalBearingTileEntity bearingTe = (MechanicalBearingTileEntity) te;
final Direction facing = te.getBlockState().get(BlockStateProperties.FACING);
BlockState capState = AllBlocks.MECHANICAL_BEARING_TOP.get().getDefaultState().with(BlockStateProperties.FACING,
facing);
SuperByteBuffer superBuffer = CreateClient.bufferCache.renderBlockState(KINETIC_TILE, capState);
float interpolatedAngle = bearingTe.getInterpolatedAngle(partialTicks);
kineticRotationTransform(superBuffer, bearingTe, facing.getAxis(), interpolatedAngle, getWorld());
superBuffer.translate(x, y, z).renderInto(buffer);
}
@Override
protected BlockState getRenderedBlockState(KineticTileEntity te) {
return AllBlocks.SHAFT_HALF.get().getDefaultState().with(BlockStateProperties.FACING,
te.getBlockState().get(BlockStateProperties.FACING).getOpposite());
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.components.constructs; package com.simibubi.create.modules.contraptions.components.contraptions.chassis;
import java.util.List; import java.util.List;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.components.constructs; package com.simibubi.create.modules.contraptions.components.contraptions.chassis;
import static com.simibubi.create.CreateConfig.parameters; import static com.simibubi.create.CreateConfig.parameters;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.components.constructs; package com.simibubi.create.modules.contraptions.components.contraptions.chassis;
import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket; import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.components.constructs; package com.simibubi.create.modules.contraptions.components.contraptions.chassis;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.components.constructs; package com.simibubi.create.modules.contraptions.components.contraptions.chassis;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;

View file

@ -1,15 +1,16 @@
package com.simibubi.create.modules.contraptions.components.constructs.mounted; package com.simibubi.create.modules.contraptions.components.contraptions.mounted;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.RenderUtilityBlock; import com.simibubi.create.foundation.block.RenderUtilityBlock;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
import net.minecraft.block.AbstractRailBlock; import net.minecraft.block.AbstractRailBlock;
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.block.material.PushReaction;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.minecart.AbstractMinecartEntity; import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.BooleanProperty; import net.minecraft.state.BooleanProperty;
@ -71,7 +72,7 @@ public class CartAssemblerBlock extends AbstractRailBlock {
if (!cart.getPassengers().isEmpty()) if (!cart.getPassengers().isEmpty())
return; return;
MountedContraption contraption = MountedContraption.assembleMinecart(world, pos, cart); Contraption contraption = MountedContraption.assembleMinecart(world, pos, cart);
ContraptionEntity entity = new ContraptionEntity(world, contraption, ContraptionEntity entity = new ContraptionEntity(world, contraption,
ContraptionEntity.yawFromMotion(cart.getMotion())); ContraptionEntity.yawFromMotion(cart.getMotion()));
entity.setPosition(pos.getX(), pos.getY(), pos.getZ()); entity.setPosition(pos.getX(), pos.getY(), pos.getZ());
@ -82,17 +83,8 @@ public class CartAssemblerBlock extends AbstractRailBlock {
protected void disassemble(World world, BlockPos pos, AbstractMinecartEntity cart) { protected void disassemble(World world, BlockPos pos, AbstractMinecartEntity cart) {
if (cart.getPassengers().isEmpty()) if (cart.getPassengers().isEmpty())
return; return;
Entity entity = cart.getPassengers().get(0); if (!(cart.getPassengers().get(0) instanceof ContraptionEntity))
if (!(entity instanceof ContraptionEntity))
return; return;
MountedContraption contraption = ((ContraptionEntity) entity).contraption;
if (contraption == null)
return;
contraption.disassemble(world, pos.subtract(contraption.getAnchor()), (targetPos, state) -> {
return targetPos.equals(pos);
});
cart.removePassengers(); cart.removePassengers();
} }
@ -117,7 +109,8 @@ public class CartAssemblerBlock extends AbstractRailBlock {
@Override @Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
return AllShapes.CART_ASSEMBLER.get(state.get(RAIL_SHAPE) == RailShape.NORTH_SOUTH ? Direction.Axis.Z : Direction.Axis.X); return AllShapes.CART_ASSEMBLER
.get(state.get(RAIL_SHAPE) == RailShape.NORTH_SOUTH ? Direction.Axis.Z : Direction.Axis.X);
} }
@Override @Override
@ -125,7 +118,7 @@ public class CartAssemblerBlock extends AbstractRailBlock {
ISelectionContext context) { ISelectionContext context) {
if (context.getEntity() instanceof AbstractMinecartEntity) if (context.getEntity() instanceof AbstractMinecartEntity)
return VoxelShapes.empty(); return VoxelShapes.empty();
return getShape(state, worldIn, pos, context); return VoxelShapes.fullCube();
} }
@Override @Override

View file

@ -1,18 +1,13 @@
package com.simibubi.create.modules.contraptions.components.constructs.mounted; package com.simibubi.create.modules.contraptions.components.contraptions.mounted;
import static com.simibubi.create.modules.contraptions.components.constructs.mounted.CartAssemblerBlock.RAIL_SHAPE; import static com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerBlock.RAIL_SHAPE;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.tuple.MutablePair;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.contraptions.components.constructs.Contraption; import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior.MovementContext;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior.MoverType;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.item.minecart.AbstractMinecartEntity; import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.state.properties.RailShape; import net.minecraft.state.properties.RailShape;
@ -21,12 +16,13 @@ import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IWorld;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraft.world.gen.feature.template.Template.BlockInfo;
public class MountedContraption extends Contraption { public class MountedContraption extends Contraption {
public static MountedContraption assembleMinecart(World world, BlockPos pos, AbstractMinecartEntity cart) { public static Contraption assembleMinecart(World world, BlockPos pos, AbstractMinecartEntity cart) {
if (isFrozen()) if (isFrozen())
return null; return null;
@ -34,7 +30,7 @@ public class MountedContraption extends Contraption {
if (!state.has(RAIL_SHAPE)) if (!state.has(RAIL_SHAPE))
return null; return null;
MountedContraption contraption = new MountedContraption(); Contraption contraption = new MountedContraption();
Vec3d vec = cart.getMotion(); Vec3d vec = cart.getMotion();
if (!contraption.searchMovedStructure(world, pos, Direction.getFacingFromVector(vec.x, vec.y, vec.z))) if (!contraption.searchMovedStructure(world, pos, Direction.getFacingFromVector(vec.x, vec.y, vec.z)))
return null; return null;
@ -43,21 +39,8 @@ public class MountedContraption extends Contraption {
contraption.add(pos, new BlockInfo(pos, contraption.add(pos, new BlockInfo(pos,
AllBlocks.MINECART_ANCHOR.block.getDefaultState().with(BlockStateProperties.HORIZONTAL_AXIS, axis), AllBlocks.MINECART_ANCHOR.block.getDefaultState().with(BlockStateProperties.HORIZONTAL_AXIS, axis),
null)); null));
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
for (BlockInfo block : contraption.blocks.values()) { contraption.initActors(world);
BlockPos startPos = pos;
if (startPos.equals(block.pos))
continue;
world.setBlockState(block.pos, Blocks.AIR.getDefaultState(), 67);
}
for (MutablePair<BlockInfo, MovementContext> pair : contraption.getActors()) {
MovementContext context = new MovementContext(pair.left.state, MoverType.MINECART);
context.world = world;
context.motion = vec;
context.currentGridPos = pair.left.pos;
pair.setRight(context);
}
return contraption; return contraption;
} }
@ -83,8 +66,14 @@ public class MountedContraption extends Contraption {
return capture; return capture;
} }
public BlockPos getAnchor() { @Override
return anchor; public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
super.removeBlocksFromWorld(world, offset, (pos, state) -> pos.equals(anchor));
}
@Override
public void disassemble(IWorld world, BlockPos offset, float yaw, float pitch) {
super.disassemble(world, offset, yaw, pitch, (pos, state) -> AllBlocks.MINECART_ANCHOR.typeOf(state));
} }
} }

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.components.constructs.piston; package com.simibubi.create.modules.contraptions.components.contraptions.piston;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.CreateConfig; import com.simibubi.create.CreateConfig;
@ -33,7 +33,6 @@ import net.minecraftforge.common.Tags;
public class MechanicalPistonBlock extends DirectionalAxisKineticBlock { public class MechanicalPistonBlock extends DirectionalAxisKineticBlock {
public static final EnumProperty<PistonState> STATE = EnumProperty.create("state", PistonState.class); public static final EnumProperty<PistonState> STATE = EnumProperty.create("state", PistonState.class);
protected boolean isSticky; protected boolean isSticky;
public MechanicalPistonBlock(boolean sticky) { public MechanicalPistonBlock(boolean sticky) {

View file

@ -1,11 +1,11 @@
package com.simibubi.create.modules.contraptions.components.constructs.piston; package com.simibubi.create.modules.contraptions.components.contraptions.piston;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.CreateConfig; import com.simibubi.create.CreateConfig;
import com.simibubi.create.foundation.block.IWithoutBlockItem; import com.simibubi.create.foundation.block.IWithoutBlockItem;
import com.simibubi.create.foundation.block.ProperDirectionalBlock; import com.simibubi.create.foundation.block.ProperDirectionalBlock;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonBlock.PistonState; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;

View file

@ -0,0 +1,257 @@
package com.simibubi.create.modules.contraptions.components.contraptions.piston;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.IControlContraption;
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
public class MechanicalPistonTileEntity extends KineticTileEntity implements IControlContraption {
protected float offset;
protected boolean running;
protected boolean assembleNextTick;
protected boolean hadCollisionWithOtherPiston;
protected ContraptionEntity movedContraption;
protected int extensionLength;
public MechanicalPistonTileEntity() {
super(AllTileEntities.MECHANICAL_PISTON.type);
}
@Override
public void onSpeedChanged() {
super.onSpeedChanged();
assembleNextTick = true;
}
@Override
public void remove() {
this.removed = true;
if (!world.isRemote)
disassembleConstruct();
super.remove();
}
@Override
public CompoundNBT write(CompoundNBT tag) {
tag.putBoolean("Running", running);
tag.putFloat("Offset", offset);
tag.putInt("ExtensionLength", extensionLength);
return super.write(tag);
}
@Override
public void read(CompoundNBT tag) {
running = tag.getBoolean("Running");
offset = tag.getFloat("Offset");
extensionLength = tag.getInt("ExtensionLength");
super.read(tag);
}
public void assembleConstruct() {
Direction direction = getBlockState().get(BlockStateProperties.FACING);
// Collect Construct
PistonContraption contraption = PistonContraption.movePistonAt(world, pos, direction, getMovementSpeed() < 0);
if (contraption == null)
return;
// Check if not at limit already
float resultingOffset = contraption.initialExtensionProgress + Math.signum(getMovementSpeed()) * .5f;
extensionLength = contraption.extensionLength;
if (resultingOffset <= 0 || resultingOffset >= extensionLength) {
return;
}
// Run
running = true;
offset = contraption.initialExtensionProgress;
sendData();
BlockPos startPos = BlockPos.ZERO.offset(direction, contraption.initialExtensionProgress);
contraption.removeBlocksFromWorld(world, startPos);
movedContraption = new ContraptionEntity(getWorld(), contraption, 0).controlledBy(this);
moveContraption();
world.addEntity(movedContraption);
}
public void disassembleConstruct() {
if (!running)
return;
if (!removed)
getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.EXTENDED), 3);
movedContraption.disassemble();
running = false;
movedContraption = null;
sendData();
if (removed)
AllBlocks.MECHANICAL_PISTON.get().onBlockHarvested(world, pos, getBlockState(), null);
}
@Override
public void tick() {
super.tick();
if (!world.isRemote && assembleNextTick) {
assembleNextTick = false;
if (running) {
if (getSpeed() == 0)
disassembleConstruct();
else
sendData();
return;
}
assembleConstruct();
return;
}
if (!running)
return;
float movementSpeed = getMovementSpeed();
float newOffset = offset + movementSpeed;
if (movedContraption == null)
return;
if (!world.isRemote && getModulatedOffset(newOffset) != getModulatedOffset(offset)) {
offset = newOffset;
sendData();
}
offset = newOffset;
moveContraption();
if (offset <= 0 || offset >= extensionLength) {
offset = offset <= 0 ? 0 : extensionLength;
if (!world.isRemote)
disassembleConstruct();
return;
}
}
public void moveContraption() {
if (movedContraption != null) {
Vec3d constructOffset = getConstructOffset(0.5f);
Vec3d vec = constructOffset.add(new Vec3d(movedContraption.getContraption().getAnchor()));
movedContraption.setPosition(vec.x, vec.y, vec.z);
}
}
// private boolean hasBlockCollisions(float newOffset) {
// if (PistonContraption.isFrozen())
// return true;
//
// Direction movementDirection = getBlockState().get(BlockStateProperties.FACING);
// BlockPos relativePos = BlockPos.ZERO.offset(movementDirection, getModulatedOffset(newOffset));
//
// // Other moving Pistons
// int maxPossibleRange = parameters.maxPistonPoles.get() + parameters.maxChassisRange.get()
// + parameters.maxChassisForTranslation.get();
// Iterator<MechanicalPistonTileEntity> iterator = Create.constructHandler.getOtherMovingPistonsInWorld(this)
// .iterator();
// pistonLoop: while (iterator.hasNext()) {
// MechanicalPistonTileEntity otherPiston = iterator.next();
//
// if (otherPiston == this)
// continue;
// if (!otherPiston.running || otherPiston.movedContraption == null) {
// iterator.remove();
// continue;
// }
// if (otherPiston.pos.manhattanDistance(pos) > maxPossibleRange * 2)
// continue;
//
// Direction otherMovementDirection = otherPiston.getBlockState().get(BlockStateProperties.FACING);
// BlockPos otherRelativePos = BlockPos.ZERO.offset(otherMovementDirection,
// getModulatedOffset(otherPiston.offset));
//
// for (AxisAlignedBB tBB : Arrays.asList(movedContraption.constructCollisionBox,
// movedContraption.pistonCollisionBox)) {
// for (AxisAlignedBB oBB : Arrays.asList(otherPiston.movedContraption.constructCollisionBox,
// otherPiston.movedContraption.pistonCollisionBox)) {
// if (tBB == null || oBB == null)
// continue;
//
// boolean frontalCollision = otherMovementDirection == movementDirection.getOpposite();
// BlockPos thisColliderOffset = relativePos.offset(movementDirection,
// frontalCollision ? (getMovementSpeed() > 0 ? 1 : -1) : 0);
// AxisAlignedBB thisBB = tBB.offset(thisColliderOffset);
// AxisAlignedBB otherBB = oBB.offset(otherRelativePos);
//
// if (thisBB.intersects(otherBB)) {
// boolean actuallyColliding = false;
// for (BlockPos colliderPos : movedContraption.getColliders(world, movementDirection)) {
// colliderPos = colliderPos.add(thisColliderOffset).subtract(otherRelativePos);
// if (!otherPiston.movedContraption.blocks.containsKey(colliderPos))
// continue;
// actuallyColliding = true;
// }
// if (!actuallyColliding)
// continue pistonLoop;
// hadCollisionWithOtherPiston = true;
// return true;
// }
//
// }
// }
//
// }
//
// if (!running)
// return false;
//
// // Other Blocks in world
// for (BlockPos pos : movedContraption.getColliders(world,
// getMovementSpeed() > 0 ? movementDirection : movementDirection.getOpposite())) {
// BlockPos colliderPos = pos.add(relativePos);
//
// if (!world.isBlockPresent(colliderPos))
// return true;
// if (!world.getBlockState(colliderPos).getMaterial().isReplaceable()
// && !world.getBlockState(colliderPos).getCollisionShape(world, colliderPos).isEmpty())
// return true;
// }
//
// return false;
// }
private int getModulatedOffset(float offset) {
return MathHelper.clamp((int) (offset + .5f), 0, extensionLength);
}
public float getMovementSpeed() {
Direction pistonDirection = getBlockState().get(BlockStateProperties.FACING);
int movementModifier = pistonDirection.getAxisDirection().getOffset()
* (pistonDirection.getAxis() == Axis.Z ? -1 : 1);
return getSpeed() * -movementModifier / 1024f;
}
public Vec3d getConstructOffset(float partialTicks) {
float interpolatedOffset = MathHelper.clamp(offset + (partialTicks - .5f) * getMovementSpeed(), 0,
extensionLength);
return new Vec3d(getBlockState().get(BlockStateProperties.FACING).getDirectionVec()).scale(interpolatedOffset);
}
@Override
public void attach(ContraptionEntity contraption) {
if (contraption.getContraption() instanceof PistonContraption) {
this.movedContraption = contraption;
if (!world.isRemote)
sendData();
}
}
}

View file

@ -1,15 +1,13 @@
package com.simibubi.create.modules.contraptions.components.constructs.piston; package com.simibubi.create.modules.contraptions.components.contraptions.piston;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.contraptions.base.IRotate; import com.simibubi.create.modules.contraptions.base.IRotate;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.components.constructs.ContraptionRenderer;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.math.Vec3d;
public class MechanicalPistonTileEntityRenderer extends KineticTileEntityRenderer { public class MechanicalPistonTileEntityRenderer extends KineticTileEntityRenderer {
@ -17,14 +15,6 @@ public class MechanicalPistonTileEntityRenderer extends KineticTileEntityRendere
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks, public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
int destroyStage, BufferBuilder buffer) { int destroyStage, BufferBuilder buffer) {
super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer); super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
MechanicalPistonTileEntity pistonTe = (MechanicalPistonTileEntity) te;
if (!pistonTe.running)
return;
Vec3d offset = pistonTe.getConstructOffset(partialTicks).subtract(new Vec3d(pistonTe.getPos()));
ContraptionRenderer.render(getWorld(), pistonTe.movedContraption, (superBuffer) -> {
superBuffer.translate(x + offset.x, y + offset.y, z + offset.z);
}, buffer);
} }
@Override @Override

View file

@ -0,0 +1,167 @@
/*package com.simibubi.create.modules.contraptions.receivers.constructs.piston;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.simibubi.create.Create;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.IWorld;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber
public class MovingConstructHandler {
static List<AxisAlignedBB> renderedBBs = new LinkedList<>();
static Map<IWorld, List<MechanicalPistonTileEntity>> movingPistons = new HashMap<>();
public void onLoadWorld(IWorld world) {
movingPistons.put(world, new ArrayList<>());
Create.logger.debug("Prepared Construct List for " + world.getDimension().getType().getRegistryName());
}
public void onUnloadWorld(IWorld world) {
movingPistons.remove(world);
Create.logger.debug("Removed Construct List for " + world.getDimension().getType().getRegistryName());
}
// public static void moveEntities(MechanicalPistonTileEntity te, float movementSpeed, Direction movementDirection,
// float newOffset) {
// if (PistonContraption.isFrozen())
// return;
//
// World world = te.getWorld();
// Vec3d movementVec = new Vec3d(te.getBlockState().get(BlockStateProperties.FACING).getDirectionVec());
// Contraption construct = te.movedContraption;
//
//// if (world.isRemote) {
//// renderedBBs.clear();
//// if (construct.pistonCollisionBox != null)
//// renderedBBs.add(construct.pistonCollisionBox.offset(te.getConstructOffset(0)));
//// if (construct.constructCollisionBox != null)
//// renderedBBs.add(construct.constructCollisionBox.offset(te.getConstructOffset(0)));
////
//// }
//
// if (construct.getCollisionBoxFront() != null) {
// AxisAlignedBB constructBB = construct.getCollisionBoxFront().offset(te.getConstructOffset(0)).grow(.5f);
//
// for (Entity entity : world.getEntitiesWithinAABB((EntityType<?>) null, constructBB,
// e -> e.getPushReaction() == PushReaction.NORMAL)) {
//
// AxisAlignedBB entityScanBB = entity.getBoundingBox().offset(movementVec.scale(-1 * newOffset))
// .grow(.5f);
// BlockPos min = new BlockPos(entityScanBB.minX, entityScanBB.minY, entityScanBB.minZ);
// BlockPos max = new BlockPos(entityScanBB.maxX, entityScanBB.maxY, entityScanBB.maxZ);
//
// Stream<VoxelShape> hits = BlockPos.getAllInBox(min, max).filter(construct.blocks::containsKey)
// .map(pos -> {
// Vec3d vec = new Vec3d(pos).add(te.getConstructOffset(te.getMovementSpeed() > 0 ? 1 : 0));
// return construct.blocks.get(pos).state.getShape(world, new BlockPos(vec)).withOffset(vec.x,
// vec.y, vec.z);
// });
// ReuseableStream<VoxelShape> potentialHits = new ReuseableStream<>(hits);
//
// AxisAlignedBB entityBB = entity.getBoundingBox();
// Vec3d motion = entity.getMotion();
// Vec3d movement = new Vec3d(movementDirection.getDirectionVec()).scale(-movementSpeed).add(motion);
// Vec3d allowedMovement = Entity.getAllowedMovement(movement, entityBB, world,
// ISelectionContext.forEntity(entity), potentialHits);
//
// for (Object shape : potentialHits.createStream().toArray()) {
// VoxelShape voxelShape = (VoxelShape) shape;
// if (!entityBB.intersects(voxelShape.getBoundingBox()))
// continue;
//
// Direction bestSide = Direction.DOWN;
// double bestOffset = 100;
// double finalOffset = 0;
//
// for (Direction face : Direction.values()) {
// Axis axis = face.getAxis();
// double d = axis == Axis.X ? entityBB.getXSize()
// : axis == Axis.Y ? entityBB.getYSize() : entityBB.getZSize();
// d = d + 1.5f;
//
// Vec3d nudge = new Vec3d(face.getDirectionVec()).scale(d);
// AxisAlignedBB nudgedBB = entityBB.offset(nudge.getX(), nudge.getY(), nudge.getZ());
// double nudgeDistance = face.getAxisDirection() == AxisDirection.POSITIVE ? -d : d;
// double offset = voxelShape.getAllowedOffset(face.getAxis(), nudgedBB, nudgeDistance);
// double abs = Math.abs(nudgeDistance - offset);
// if (abs < Math.abs(bestOffset) && abs != 0) {
// bestOffset = abs;
// finalOffset = abs;
// bestSide = face;
// }
// }
//
// if (bestOffset != 0) {
// entity.move(MoverType.SELF, new Vec3d(bestSide.getDirectionVec()).scale(finalOffset));
// switch (bestSide.getAxis()) {
// case X:
// entity.setMotion(0, motion.y, motion.z);
// break;
// case Y:
// entity.setMotion(motion.x, bestSide == Direction.UP ? movementSpeed + 1 / 8f : 0, motion.z);
// entity.fall(entity.fallDistance, 1);
// entity.fallDistance = 0;
// entity.onGround = true;
// break;
// case Z:
// entity.setMotion(motion.x, motion.y, 0);
// break;
// }
//
// break;
// }
// }
//
// if (!allowedMovement.equals(movement)) {
// if (allowedMovement.y != movement.y) {
// entity.fall(entity.fallDistance, 1);
// entity.fallDistance = 0;
// entity.onGround = true;
// }
// if (entity instanceof PlayerEntity && !world.isRemote)
// return;
// entity.setMotion(allowedMovement.subtract(movement.subtract(motion)));
// entity.velocityChanged = true;
// }
//
// }
// }
// }
public void add(MechanicalPistonTileEntity mechanicalPistonTileEntity) {
movingPistons.get(mechanicalPistonTileEntity.getWorld()).add(mechanicalPistonTileEntity);
}
public void remove(MechanicalPistonTileEntity mechanicalPistonTileEntity) {
movingPistons.get(mechanicalPistonTileEntity.getWorld()).remove(mechanicalPistonTileEntity);
}
public List<MechanicalPistonTileEntity> getOtherMovingPistonsInWorld(
MechanicalPistonTileEntity mechanicalPistonTileEntity) {
return movingPistons.get(mechanicalPistonTileEntity.getWorld());
}
// @SubscribeEvent
// @OnlyIn(value = Dist.CLIENT)
// public static void onRenderWorld(RenderWorldLastEvent event) {
// for (AxisAlignedBB bb : renderedBBs) {
// TessellatorHelper.prepareForDrawing();
// GlStateManager.disableTexture();
// GlStateManager.lineWidth(3);
// int color = ColorHelper.rainbowColor(renderedBBs.indexOf(bb) * 170);
// WorldRenderer.drawSelectionBoundingBox(bb.grow(1 / 256f), (color >> 16 & 0xFF) / 256f,
// (color >> 8 & 0xFF) / 256f, (color & 0xFF) / 256f, 1);
// GlStateManager.lineWidth(1);
// GlStateManager.enableTexture();
// TessellatorHelper.cleanUpAfterDrawing();
// }
// }
}*/

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.components.constructs.piston; package com.simibubi.create.modules.contraptions.components.contraptions.piston;
import static com.simibubi.create.AllBlocks.MECHANICAL_PISTON_HEAD; import static com.simibubi.create.AllBlocks.MECHANICAL_PISTON_HEAD;
import static com.simibubi.create.AllBlocks.PISTON_POLE; import static com.simibubi.create.AllBlocks.PISTON_POLE;
@ -10,17 +10,19 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.contraptions.components.constructs.Contraption; import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonBlock.PistonState; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.ListNBT;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.state.properties.PistonType; import net.minecraft.state.properties.PistonType;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraft.world.gen.feature.template.Template.BlockInfo;
@ -39,9 +41,9 @@ public class PistonContraption extends Contraption {
construct.orientation = direction; construct.orientation = direction;
if (!construct.collectExtensions(world, pos, direction)) if (!construct.collectExtensions(world, pos, direction))
return null; return null;
if (!construct.searchMovedStructure(world, pos.offset(direction, construct.initialExtensionProgress + 1), if (!construct.searchMovedStructure(world, construct.anchor, retract ? direction.getOpposite() : direction))
retract ? direction.getOpposite() : direction))
return null; return null;
construct.initActors(world);
return construct; return construct;
} }
@ -93,13 +95,18 @@ public class PistonContraption extends Contraption {
initialExtensionProgress = extensionsInFront; initialExtensionProgress = extensionsInFront;
pistonCollisionBox = new AxisAlignedBB(end.offset(direction, -extensionsInFront)); pistonCollisionBox = new AxisAlignedBB(end.offset(direction, -extensionsInFront));
anchor = pos.offset(direction, initialExtensionProgress + 1);
if (extensionLength == 0)
return false;
for (BlockInfo pole : poles) { for (BlockInfo pole : poles) {
BlockPos polePos = pole.pos.offset(direction, -extensionsInFront); BlockPos polePos = pole.pos.offset(direction, -extensionsInFront).subtract(anchor);
blocks.put(polePos, new BlockInfo(polePos, pole.state, null)); blocks.put(polePos, new BlockInfo(polePos, pole.state, null));
pistonCollisionBox = pistonCollisionBox.union(new AxisAlignedBB(polePos)); pistonCollisionBox = pistonCollisionBox.union(new AxisAlignedBB(polePos));
} }
constructCollisionBox = new AxisAlignedBB(pos.offset(direction, initialExtensionProgress)); constructCollisionBox = new AxisAlignedBB(BlockPos.ZERO.offset(direction, -initialExtensionProgress));
return true; return true;
} }
@ -125,14 +132,48 @@ public class PistonContraption extends Contraption {
return true; return true;
} }
protected void add(BlockPos pos, BlockInfo block) { public void add(BlockPos pos, BlockInfo block) {
// super.add(pos, block);
super.add(pos.offset(orientation, -initialExtensionProgress), block); super.add(pos.offset(orientation, -initialExtensionProgress), block);
} }
@Override @Override
public void readNBT(CompoundNBT nbt) { public void disassemble(IWorld world, BlockPos offset, float yaw, float pitch) {
super.readNBT(nbt); super.disassemble(world, offset, yaw, pitch, (pos, state) -> {
BlockPos pistonPos = anchor.offset(orientation, -initialExtensionProgress - 1);
BlockState pistonState = world.getBlockState(pistonPos);
TileEntity te = world.getTileEntity(pistonPos);
if (pos.equals(pistonPos)) {
if (te == null || te.isRemoved())
return true;
if (!AllBlocks.PISTON_POLE.typeOf(state) && pistonState.getBlock() instanceof MechanicalPistonBlock)
world.setBlockState(pistonPos, pistonState.with(MechanicalPistonBlock.STATE, PistonState.RETRACTED),
3);
return true;
}
return false;
});
}
@Override
public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
super.removeBlocksFromWorld(world, offset, (pos, state) -> {
BlockPos pistonPos = anchor.offset(orientation, -initialExtensionProgress - 1);
BlockState blockState = world.getBlockState(pos);
if (pos.equals(pistonPos) && blockState.getBlock() instanceof MechanicalPistonBlock) {
world.setBlockState(pos, blockState.with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66);
return true;
}
return false;
});
}
@Override
public void readNBT(World world, CompoundNBT nbt) {
super.readNBT(world, nbt);
extensionLength = nbt.getInt("ExtensionLength"); extensionLength = nbt.getInt("ExtensionLength");
initialExtensionProgress = nbt.getInt("InitialLength");
orientation = Direction.byIndex(nbt.getInt("Orientation"));
if (nbt.contains("BoundsBack")) if (nbt.contains("BoundsBack"))
pistonCollisionBox = readAABB(nbt.getList("BoundsBack", 5)); pistonCollisionBox = readAABB(nbt.getList("BoundsBack", 5));
} }
@ -145,7 +186,9 @@ public class PistonContraption extends Contraption {
ListNBT bb = writeAABB(pistonCollisionBox); ListNBT bb = writeAABB(pistonCollisionBox);
nbt.put("BoundsBack", bb); nbt.put("BoundsBack", bb);
} }
nbt.putInt("InitialLength", initialExtensionProgress);
nbt.putInt("ExtensionLength", extensionLength); nbt.putInt("ExtensionLength", extensionLength);
nbt.putInt("Orientation", orientation.getIndex());
return nbt; return nbt;
} }

View file

@ -1,10 +1,10 @@
package com.simibubi.create.modules.contraptions.components.constructs.piston; package com.simibubi.create.modules.contraptions.components.contraptions.piston;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.CreateConfig; import com.simibubi.create.CreateConfig;
import com.simibubi.create.foundation.block.ProperDirectionalBlock; import com.simibubi.create.foundation.block.ProperDirectionalBlock;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonBlock.PistonState; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;

View file

@ -2,8 +2,8 @@ package com.simibubi.create.modules.contraptions.components.motor;
import com.simibubi.create.foundation.block.IBlockWithScrollableValue; import com.simibubi.create.foundation.block.IBlockWithScrollableValue;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.IWithTileEntity;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock; import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;

View file

@ -8,8 +8,8 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IRenderUtilityBlock; import com.simibubi.create.foundation.block.IRenderUtilityBlock;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.IWithTileEntity;
import com.simibubi.create.foundation.block.SyncedTileEntity; import com.simibubi.create.foundation.block.SyncedTileEntity;
import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock; import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState; import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment; import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment;

View file

@ -3,7 +3,7 @@ package com.simibubi.create.modules.contraptions.components.saw;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.IWithTileEntity;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior; import com.simibubi.create.modules.contraptions.components.contraptions.IHaveMovementBehavior;
import com.simibubi.create.modules.logistics.block.IBlockWithFilter; import com.simibubi.create.modules.logistics.block.IBlockWithFilter;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -21,8 +21,8 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.DamageSource; import net.minecraft.util.DamageSource;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Hand;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.BlockRayTraceResult;

View file

@ -2,8 +2,8 @@ package com.simibubi.create.modules.contraptions.processing;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.IWithTileEntity;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
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;

View file

@ -4,7 +4,8 @@ import java.util.Random;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.ProperDirectionalBlock; import com.simibubi.create.foundation.block.ProperDirectionalBlock;
import com.simibubi.create.modules.contraptions.components.constructs.IHaveMovementBehavior; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.components.contraptions.IHaveMovementBehavior;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -15,6 +16,7 @@ import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties; 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;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.TickPriority; import net.minecraft.world.TickPriority;
@ -100,19 +102,32 @@ public class ContactBlock extends ProperDirectionalBlock implements IHaveMovemen
} }
@Override @Override
public void visitPosition(MovementContext context) { public Vec3d getActiveAreaOffset(MovementContext context) {
return new Vec3d(context.state.get(FACING).getDirectionVec()).scale(.65f);
}
@Override
public void visitNewPosition(MovementContext context, BlockPos pos) {
BlockState block = context.state; BlockState block = context.state;
World world = context.world; World world = context.world;
BlockPos pos = context.currentGridPos;
Direction direction = block.get(FACING); if (world.isRemote)
if (!hasValidContact(world, pos, direction))
return; return;
int ticksToStayActive = (int) Math BlockState visitedState = world.getBlockState(pos);
.ceil(1 / Math.abs(context.motion.length())); if (!AllBlocks.CONTACT.typeOf(visitedState))
world.setBlockState(pos.offset(direction), world.getBlockState(pos.offset(direction)).with(POWERED, true)); return;
world.getPendingBlockTicks().scheduleTick(pos.offset(direction), this, ticksToStayActive, TickPriority.NORMAL);
Vec3d contact = new Vec3d(block.get(FACING).getDirectionVec());
contact = VecHelper.rotate(contact, context.rotation.x, context.rotation.y, context.rotation.z);
Direction direction = Direction.getFacingFromVector(contact.x, contact.y, contact.z);
if (!hasValidContact(world, pos.offset(direction.getOpposite()), direction))
return;
int ticksToStayActive = 4;
world.setBlockState(pos, visitedState.with(POWERED, true));
world.getPendingBlockTicks().scheduleTick(pos, this, ticksToStayActive, TickPriority.NORMAL);
return; return;
} }

View file

@ -1,14 +1,15 @@
package com.simibubi.create.modules.contraptions.relays.belt; package com.simibubi.create.modules.contraptions.relays.belt;
import static net.minecraft.block.Block.makeCuboidShape;
import com.simibubi.create.foundation.utility.VoxelShaper; import com.simibubi.create.foundation.utility.VoxelShaper;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.shapes.IBooleanFunction; import net.minecraft.util.math.shapes.IBooleanFunction;
import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.util.math.shapes.VoxelShapes;
import static net.minecraft.block.Block.makeCuboidShape;
public class BeltTunnelShapes { public class BeltTunnelShapes {
private static VoxelShape block = makeCuboidShape(0, -5, 0, 16, 16, 16); private static VoxelShape block = makeCuboidShape(0, -5, 0, 16, 16, 16);

View file

@ -1,11 +1,14 @@
package com.simibubi.create.modules.contraptions.relays.gauge; package com.simibubi.create.modules.contraptions.relays.gauge;
import java.util.Random;
import com.simibubi.create.foundation.block.RenderUtilityBlock; import com.simibubi.create.foundation.block.RenderUtilityBlock;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
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;
@ -29,8 +32,6 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
import java.util.Random;
public class GaugeBlock extends DirectionalAxisKineticBlock { public class GaugeBlock extends DirectionalAxisKineticBlock {
protected Type type; protected Type type;

View file

@ -1,6 +1,7 @@
package com.simibubi.create.modules.logistics.block.inventories; package com.simibubi.create.modules.logistics.block.inventories;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
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;

View file

@ -10,9 +10,9 @@ import java.util.Set;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.IWithTileEntity;
import com.simibubi.create.foundation.utility.VoxelShaper;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.foundation.utility.VoxelShaper;
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;

View file

@ -1,6 +1,7 @@
package com.simibubi.create.modules.schematics.block; package com.simibubi.create.modules.schematics.block;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;

View file

@ -1,6 +1,7 @@
package com.simibubi.create.modules.schematics.block; package com.simibubi.create.modules.schematics.block;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
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;

View file

@ -1,8 +1,8 @@
package com.simibubi.create.modules.schematics.block; package com.simibubi.create.modules.schematics.block;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
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;

View file

@ -16,8 +16,8 @@ import com.simibubi.create.foundation.gui.AbstractSimiContainerScreen;
import com.simibubi.create.foundation.gui.widgets.IconButton; import com.simibubi.create.foundation.gui.widgets.IconButton;
import com.simibubi.create.foundation.gui.widgets.Indicator; import com.simibubi.create.foundation.gui.widgets.Indicator;
import com.simibubi.create.foundation.gui.widgets.Indicator.State; import com.simibubi.create.foundation.gui.widgets.Indicator.State;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.item.ItemDescription.Palette; import com.simibubi.create.foundation.item.ItemDescription.Palette;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.modules.schematics.packet.ConfigureSchematicannonPacket; import com.simibubi.create.modules.schematics.packet.ConfigureSchematicannonPacket;
import com.simibubi.create.modules.schematics.packet.ConfigureSchematicannonPacket.Option; import com.simibubi.create.modules.schematics.packet.ConfigureSchematicannonPacket.Option;

View file

@ -73,6 +73,7 @@
"block.create.mechanical_crafter": "Mechanical Crafter", "block.create.mechanical_crafter": "Mechanical Crafter",
"block.create.speed_gauge": "Speedometer", "block.create.speed_gauge": "Speedometer",
"block.create.stress_gauge": "Stress Gauge", "block.create.stress_gauge": "Stress Gauge",
"block.create.cart_assembler": "Cart Assembler",
"block.create.sticky_mechanical_piston": "Sticky Mechanical Piston", "block.create.sticky_mechanical_piston": "Sticky Mechanical Piston",
"block.create.mechanical_piston": "Mechanical Piston", "block.create.mechanical_piston": "Mechanical Piston",