mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-16 23:11:40 +01:00
Merge branch 'unified-contraptions' of https://github.com/simibubi/Create into 0.2
This commit is contained in:
commit
785d77a59d
63 changed files with 1295 additions and 1592 deletions
|
@ -9,17 +9,17 @@ import com.simibubi.create.foundation.block.RenderUtilityDirectionalBlock;
|
|||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.modules.IModule;
|
||||
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.HarvesterBlock;
|
||||
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.constructs.RadialChassisBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.bearing.MechanicalBearingBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.mounted.CartAssemblerBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.mounted.CartAssemblerBlock.MinecartAnchorBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonHeadBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.piston.PistonPoleBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingBlock;
|
||||
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.CartAssemblerBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerBlock.MinecartAnchorBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonHeadBlock;
|
||||
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.crusher.CrushingWheelBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.crusher.CrushingWheelControllerBlock;
|
||||
|
|
|
@ -2,8 +2,8 @@ package com.simibubi.create;
|
|||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.mounted.ContraptionEntity;
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.mounted.ContraptionEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntityRenderer;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.util.function.Supplier;
|
|||
|
||||
import com.simibubi.create.foundation.packet.NbtPacket;
|
||||
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.motor.ConfigureMotorPacket;
|
||||
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunBeamPacket;
|
||||
|
|
|
@ -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.HarvesterTileEntity;
|
||||
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.constructs.bearing.MechanicalBearingTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.bearing.MechanicalBearingTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonTileEntity;
|
||||
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.MechanicalCrafterTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.components.crusher.CrushingWheelControllerTileEntity;
|
||||
|
|
|
@ -6,7 +6,6 @@ import org.apache.logging.log4j.Logger;
|
|||
import com.simibubi.create.foundation.world.OreGeneration;
|
||||
import com.simibubi.create.modules.ModuleLoadedCondition;
|
||||
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.management.LogisticalNetworkHandler;
|
||||
import com.simibubi.create.modules.logistics.transport.villager.LogisticianHandler;
|
||||
|
@ -42,7 +41,6 @@ public class Create {
|
|||
public static ItemGroup creativeTab = new CreateItemGroup();
|
||||
public static ServerSchematicLoader schematicReceiver;
|
||||
public static FrequencyHandler frequencyHandler;
|
||||
public static MovingConstructHandler constructHandler;
|
||||
public static LogisticalNetworkHandler logisticalNetworkHandler;
|
||||
public static TorquePropagator torquePropagator;
|
||||
public static LogisticianHandler logisticianHandler;
|
||||
|
@ -74,7 +72,6 @@ public class Create {
|
|||
public static void init(final FMLCommonSetupEvent event) {
|
||||
schematicReceiver = new ServerSchematicLoader();
|
||||
frequencyHandler = new FrequencyHandler();
|
||||
constructHandler = new MovingConstructHandler();
|
||||
logisticalNetworkHandler = new LogisticalNetworkHandler();
|
||||
torquePropagator = new TorquePropagator();
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import com.simibubi.create.foundation.block.SpriteShifter.SpriteShiftEntry;
|
|||
import com.simibubi.create.foundation.utility.SuperByteBufferCache;
|
||||
import com.simibubi.create.modules.contraptions.WrenchModel;
|
||||
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.partialWindows.WindowInABlockModel;
|
||||
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunModel;
|
||||
|
|
|
@ -44,7 +44,6 @@ public class Events {
|
|||
public static void onLoadWorld(WorldEvent.Load event) {
|
||||
IWorld world = event.getWorld();
|
||||
Create.frequencyHandler.onLoadWorld(world);
|
||||
Create.constructHandler.onLoadWorld(world);
|
||||
Create.logisticalNetworkHandler.onLoadWorld(world);
|
||||
Create.torquePropagator.onLoadWorld(world);
|
||||
}
|
||||
|
@ -53,7 +52,6 @@ public class Events {
|
|||
public static void onUnloadWorld(WorldEvent.Unload event) {
|
||||
IWorld world = event.getWorld();
|
||||
Create.frequencyHandler.onUnloadWorld(world);
|
||||
Create.constructHandler.onUnloadWorld(world);
|
||||
Create.logisticalNetworkHandler.onUnloadWorld(world);
|
||||
Create.torquePropagator.onUnloadWorld(world);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
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.profiler.IProfiler;
|
||||
|
@ -16,7 +15,6 @@ public class ResourceReloadHandler extends ReloadListener<String> {
|
|||
|
||||
@Override
|
||||
protected void apply(String splashList, IResourceManager resourceManagerIn, IProfiler profilerIn) {
|
||||
MechanicalBearingTileEntityRenderer.invalidateCache();
|
||||
SpriteShifter.reloadUVs();
|
||||
CreateClient.bufferCache.invalidate();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
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.DirectionalBlock;
|
||||
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.VoxelShapes;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static net.minecraft.block.Block.makeCuboidShape;
|
||||
|
||||
public class AllShapes {
|
||||
|
||||
public static final VoxelShaper
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -31,6 +31,7 @@ public class SuperByteBuffer {
|
|||
// Vertex Lighting
|
||||
private boolean shouldLight;
|
||||
private IVertexLighter vertexLighter;
|
||||
private float lightOffsetX, lightOffsetY, lightOffsetZ;
|
||||
private int packedLightCoords;
|
||||
|
||||
// Vertex Coloring
|
||||
|
@ -84,7 +85,8 @@ public class SuperByteBuffer {
|
|||
|
||||
if (shouldLight) {
|
||||
if (vertexLighter != null)
|
||||
putLight(mutable, vertex, vertexLighter.getPackedLight(x2, y2, z2));
|
||||
putLight(mutable, vertex,
|
||||
vertexLighter.getPackedLight(x2 + lightOffsetX, y2 + lightOffsetY, z2 + lightOffsetZ));
|
||||
else
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
}
|
||||
|
@ -153,6 +155,7 @@ public class SuperByteBuffer {
|
|||
|
||||
public SuperByteBuffer light(int packedLightCoords) {
|
||||
shouldLight = true;
|
||||
vertexLighter = null;
|
||||
this.packedLightCoords = packedLightCoords;
|
||||
return this;
|
||||
}
|
||||
|
@ -163,6 +166,13 @@ public class SuperByteBuffer {
|
|||
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) {
|
||||
shouldColor = true;
|
||||
r = ((color >> 16) & 0xFF);
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Random;
|
|||
|
||||
import net.minecraft.nbt.DoubleNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
@ -11,9 +12,15 @@ import net.minecraft.util.math.Vec3i;
|
|||
|
||||
public class VecHelper {
|
||||
|
||||
public static Vec3d rotate(Vec3d vec, float deg, Axis axis) {
|
||||
float angle = (float) (deg / 180f * Math.PI);
|
||||
public static Vec3d rotate(Vec3d vec, double xRot, double yRot, double zRot) {
|
||||
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 cos = MathHelper.cos(angle);
|
||||
double x = vec.x;
|
||||
|
@ -29,6 +36,10 @@ public class VecHelper {
|
|||
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) {
|
||||
return new Vec3d(pos).add(.5f, .5f, .5f);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
package com.simibubi.create.foundation.world;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
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.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public enum OreGeneration {
|
||||
|
||||
TEST_BLOB_1(new BasicOreGenConfig(Blocks.EMERALD_BLOCK, 25, 2, 128)),
|
||||
|
|
|
@ -26,8 +26,8 @@ import net.minecraft.particles.RedstoneParticleData;
|
|||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
|
|
@ -4,10 +4,11 @@ import java.util.List;
|
|||
|
||||
import com.simibubi.create.foundation.block.IRenderUtilityBlock;
|
||||
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.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
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.BlockState;
|
||||
|
@ -85,18 +86,22 @@ public class DrillBlock extends DirectionalKineticBlock
|
|||
}
|
||||
|
||||
@Override
|
||||
public void visitPosition(MovementContext context) {
|
||||
Direction movement = context.getMovementDirection();
|
||||
public boolean isActive(MovementContext context) {
|
||||
return !VecHelper.isVecPointingTowards(context.relativeMotion, context.state.get(FACING).getOpposite());
|
||||
}
|
||||
|
||||
// BlockState block = context.state;
|
||||
// if (movement == block.get(FACING).getOpposite())
|
||||
// return;
|
||||
@Override
|
||||
public Vec3d getActiveAreaOffset(MovementContext context) {
|
||||
return new Vec3d(context.state.get(FACING).getDirectionVec()).scale(.65f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNewPosition(MovementContext context, BlockPos pos) {
|
||||
World world = context.world;
|
||||
BlockPos pos = context.currentGridPos;
|
||||
pos = pos.offset(movement);
|
||||
BlockState stateVisited = world.getBlockState(pos);
|
||||
|
||||
if (world.isRemote)
|
||||
return;
|
||||
if (stateVisited.getCollisionShape(world, pos).isEmpty())
|
||||
return;
|
||||
if (stateVisited.getBlockHardness(world, pos) == -1)
|
||||
|
@ -108,8 +113,7 @@ public class DrillBlock extends DirectionalKineticBlock
|
|||
|
||||
for (ItemStack stack : drops) {
|
||||
ItemEntity itemEntity = new ItemEntity(world, pos.getX() + .5f, pos.getY() + .25f, pos.getZ() + .5f, stack);
|
||||
itemEntity.setMotion(
|
||||
new Vec3d(movement.getDirectionVec()).add(0, 0.5f, 0).scale(world.rand.nextFloat() * .3f));
|
||||
itemEntity.setMotion(context.motion.add(0, 0.5f, 0).scale(world.rand.nextFloat() * .3f));
|
||||
world.addEntity(itemEntity);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,11 @@ import com.simibubi.create.AllBlocks;
|
|||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
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.KineticTileEntity;
|
||||
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.util.Direction.Axis;
|
||||
|
@ -29,7 +30,9 @@ public class DrillTileEntityRenderer extends KineticTileEntityRenderer {
|
|||
BlockState state = context.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);
|
||||
float time = AnimationTickHolder.getRenderTick();
|
||||
float angle = (float) (((time * speed) % 360) / 180 * (float) Math.PI);
|
||||
|
|
|
@ -4,9 +4,10 @@ import java.util.List;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
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.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.BlockState;
|
||||
|
@ -105,18 +106,25 @@ public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBeha
|
|||
}
|
||||
|
||||
@Override
|
||||
public void visitPosition(MovementContext context) {
|
||||
Direction movement = context.getMovementDirection();
|
||||
public boolean isActive(MovementContext context) {
|
||||
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;
|
||||
BlockState block = context.state;
|
||||
BlockPos pos = context.currentGridPos;
|
||||
|
||||
if (movement != block.get(HORIZONTAL_FACING))
|
||||
return;
|
||||
|
||||
BlockState stateVisited = world.getBlockState(pos);
|
||||
boolean notCropButCuttable = false;
|
||||
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
if (stateVisited.getBlock() == Blocks.SUGAR_CANE) {
|
||||
notCropButCuttable = true;
|
||||
pos = pos.up();
|
||||
|
@ -141,8 +149,7 @@ public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBeha
|
|||
seedSubtracted = true;
|
||||
}
|
||||
ItemEntity itemEntity = new ItemEntity(world, pos.getX() + .5f, pos.getY() + .25f, pos.getZ() + .5f, stack);
|
||||
itemEntity.setMotion(
|
||||
new Vec3d(movement.getDirectionVec()).add(0, 0.5f, 0).scale(world.rand.nextFloat() * .3f));
|
||||
itemEntity.setMotion(context.motion.add(0, 0.5f, 0).scale(world.rand.nextFloat() * .3f));
|
||||
world.addEntity(itemEntity);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,8 @@ import com.simibubi.create.AllBlocks;
|
|||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
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.client.renderer.BufferBuilder;
|
||||
|
@ -28,12 +29,9 @@ public class HarvesterTileEntityRenderer extends TileEntityRenderer<HarvesterTil
|
|||
|
||||
public static SuperByteBuffer renderInContraption(MovementContext context) {
|
||||
BlockState state = context.state;
|
||||
Direction facing = context.getMovementDirection();
|
||||
float speed = (float) (facing == state.get(HORIZONTAL_FACING)
|
||||
? context.getAnimationSpeed() * facing.getAxisDirection().getOffset()
|
||||
float speed = (float) (!VecHelper.isVecPointingTowards(context.relativeMotion, state.get(HORIZONTAL_FACING).getOpposite())
|
||||
? context.getAnimationSpeed() * state.get(HORIZONTAL_FACING).getAxisDirection().getOffset()
|
||||
: 0);
|
||||
if (facing.getAxis() == Axis.X)
|
||||
speed = -speed;
|
||||
float time = AnimationTickHolder.getRenderTick();
|
||||
float angle = (float) (((time * speed) % 360) / 180 * (float) Math.PI);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
|
@ -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 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.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 net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.FallingBlock;
|
||||
import net.minecraft.block.PistonBlock;
|
||||
import net.minecraft.block.ShulkerBoxBlock;
|
||||
|
@ -117,13 +125,13 @@ public class Contraption {
|
|||
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<>();
|
||||
Set<BlockPos> visited = new HashSet<>();
|
||||
anchor = pos;
|
||||
|
||||
if (constructCollisionBox == null)
|
||||
constructCollisionBox = new AxisAlignedBB(pos);
|
||||
constructCollisionBox = new AxisAlignedBB(BlockPos.ZERO);
|
||||
|
||||
frontier.add(pos);
|
||||
if (!addToInitialFrontier(world, pos, direction, frontier))
|
||||
|
@ -433,15 +441,29 @@ public class Contraption {
|
|||
return compoundnbt;
|
||||
}
|
||||
|
||||
protected void add(BlockPos pos, BlockInfo block) {
|
||||
BlockInfo blockInfo = new BlockInfo(pos, block.state, block.nbt);
|
||||
blocks.put(pos, blockInfo);
|
||||
public void add(BlockPos pos, BlockInfo block) {
|
||||
BlockPos localPos = pos.subtract(anchor);
|
||||
BlockInfo blockInfo = new BlockInfo(localPos, block.state, block.nbt);
|
||||
blocks.put(localPos, blockInfo);
|
||||
if (block.state.getBlock() instanceof IHaveMovementBehavior)
|
||||
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 -> {
|
||||
CompoundNBT comp = (CompoundNBT) c;
|
||||
BlockInfo info = new BlockInfo(NBTUtil.readBlockPos(comp.getCompound("Pos")),
|
||||
|
@ -453,7 +475,7 @@ public class Contraption {
|
|||
nbt.getList("Actors", 10).forEach(c -> {
|
||||
CompoundNBT comp = (CompoundNBT) c;
|
||||
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));
|
||||
});
|
||||
|
||||
|
@ -469,6 +491,14 @@ public class Contraption {
|
|||
|
||||
public CompoundNBT writeNBT() {
|
||||
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();
|
||||
for (BlockInfo block : this.blocks.values()) {
|
||||
CompoundNBT c = new CompoundNBT();
|
||||
|
@ -520,7 +550,25 @@ public class Contraption {
|
|||
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()) {
|
||||
BlockPos targetPos = block.pos.add(offset);
|
||||
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() {
|
||||
return actors;
|
||||
}
|
||||
|
||||
public BlockPos getAnchor() {
|
||||
return anchor;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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.simibubi.create.foundation.utility.TessellatorHelper;
|
||||
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.entity.EntityRenderer;
|
||||
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) {
|
||||
if (!entity.isAlive())
|
||||
return;
|
||||
if (entity.contraption == null)
|
||||
if (entity.getContraption() == null)
|
||||
return;
|
||||
|
||||
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 anglePitch = (float) (entity.getPitch(partialTicks) / 180 * Math.PI);
|
||||
float angleRoll = (float) (entity.getRoll(partialTicks) / 180 * Math.PI);
|
||||
|
||||
Entity ridingEntity = entity.getRidingEntity();
|
||||
if (ridingEntity != null && ridingEntity instanceof AbstractMinecartEntity) {
|
||||
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 cartY = MathHelper.lerp((double) partialTicks, cart.lastTickPosY, cart.posY);
|
||||
double cartZ = MathHelper.lerp((double) partialTicks, cart.lastTickPosZ, cart.posZ);
|
||||
Vec3d cartPos = cart.getPos(cartX, cartY, cartZ);
|
||||
|
||||
if (cartPos != null) {
|
||||
|
||||
Vec3d cartPosFront = cart.getPosOffset(cartX, cartY, cartZ, (double) 0.3F);
|
||||
Vec3d cartPosBack = cart.getPosOffset(cartX, cartY, cartZ, (double) -0.3F);
|
||||
if (cartPosFront == null)
|
||||
|
@ -74,21 +72,26 @@ public class ContraptionEntityRenderer extends EntityRenderer<ContraptionEntity>
|
|||
}
|
||||
}
|
||||
|
||||
BlockPos anchor = entity.contraption.getAnchor();
|
||||
Vec3d rotationOffset = VecHelper.getCenterOf(anchor);
|
||||
// Vec3d offset = VecHelper.getCenterOf(anchor).scale(-1);
|
||||
|
||||
Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO);
|
||||
TessellatorHelper.prepareFastRender();
|
||||
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.rotate(Axis.X, angleRoll);
|
||||
superByteBuffer.rotate(Axis.Y, angleYaw);
|
||||
superByteBuffer.rotate(Axis.Z, anglePitch);
|
||||
superByteBuffer.translate(rotationOffset.x, rotationOffset.y, rotationOffset.z);
|
||||
superByteBuffer.translate(x, y, z);
|
||||
superByteBuffer.offsetLighting(-x + entity.posX, -y + entity.posY, -z + entity.posZ);
|
||||
|
||||
}, Tessellator.getInstance().getBuffer());
|
||||
TessellatorHelper.draw();
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
GlStateManager.shadeModel(7424);
|
||||
GlStateManager.alphaFunc(516, 0.1F);
|
||||
GlStateManager.matrixMode(5888);
|
||||
RenderHelper.enableStandardItemLighting();
|
||||
|
||||
super.doRender(entity, x, y, z, yaw, partialTicks);
|
||||
}
|
|
@ -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.function.Consumer;
|
||||
|
@ -10,7 +10,7 @@ import com.simibubi.create.CreateClient;
|
|||
import com.simibubi.create.foundation.utility.PlacementSimulationWorld;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
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.renderer.BlockModelRenderer;
|
||||
|
@ -31,7 +31,7 @@ public class ContraptionRenderer {
|
|||
public static void render(World world, Contraption c, Consumer<SuperByteBuffer> transform, BufferBuilder buffer) {
|
||||
SuperByteBuffer contraptionBuffer = CreateClient.bufferCache.get(CONTRAPTION, c, () -> renderContraption(c));
|
||||
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);
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.simibubi.create.modules.contraptions.components.contraptions;
|
||||
|
||||
public interface IControlContraption {
|
||||
|
||||
public void attach(ContraptionEntity contraption);
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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.modules.contraptions.base.DirectionalKineticBlock;
|
|
@ -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.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.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
|
||||
public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity implements IControlContraption {
|
||||
|
||||
protected RotationConstruct movingConstruct;
|
||||
protected ContraptionEntity movedContraption;
|
||||
protected float angle;
|
||||
protected boolean running;
|
||||
protected boolean assembleNextTick;
|
||||
|
@ -30,17 +26,6 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
|
|||
isWindmill = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getRenderBoundingBox() {
|
||||
return INFINITE_EXTENT_AABB;
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public double getMaxRenderDistanceSquared() {
|
||||
return super.getMaxRenderDistanceSquared() * 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAddedStressCapacity() {
|
||||
return isWindmill ? super.getAddedStressCapacity() : 0;
|
||||
|
@ -77,7 +62,9 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
|
|||
public float getGeneratedSpeed() {
|
||||
if (!running || !isWindmill)
|
||||
return 0;
|
||||
int sails = movingConstruct.getSailBlocks();
|
||||
if (movedContraption == null)
|
||||
return 0;
|
||||
int sails = ((BearingContraption) movedContraption.getContraption()).getSailBlocks();
|
||||
return MathHelper.clamp(sails, 0, 128);
|
||||
}
|
||||
|
||||
|
@ -86,9 +73,6 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
|
|||
tag.putBoolean("Running", running);
|
||||
tag.putBoolean("Windmill", isWindmill);
|
||||
tag.putFloat("Angle", angle);
|
||||
if (running && !RotationConstruct.isFrozen())
|
||||
tag.put("Construct", movingConstruct.writeNBT());
|
||||
|
||||
return super.write(tag);
|
||||
}
|
||||
|
||||
|
@ -97,15 +81,10 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
|
|||
running = tag.getBoolean("Running");
|
||||
isWindmill = tag.getBoolean("Windmill");
|
||||
angle = tag.getFloat("Angle");
|
||||
if (running && !RotationConstruct.isFrozen())
|
||||
movingConstruct = RotationConstruct.fromNBT(tag.getCompound("Construct"));
|
||||
|
||||
super.read(tag);
|
||||
}
|
||||
|
||||
public float getInterpolatedAngle(float partialTicks) {
|
||||
if (RotationConstruct.isFrozen())
|
||||
return 0;
|
||||
return MathHelper.lerp(partialTicks, angle, angle + getAngularSpeed());
|
||||
}
|
||||
|
||||
|
@ -123,21 +102,22 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
|
|||
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
||||
|
||||
// Collect Construct
|
||||
movingConstruct = RotationConstruct.getAttachedForRotating(getWorld(), getPos(), direction);
|
||||
if (movingConstruct == null)
|
||||
BearingContraption contraption = BearingContraption.assembleBearingAt(world, pos, direction);
|
||||
if (contraption == null)
|
||||
return;
|
||||
if (isWindmill && movingConstruct.getSailBlocks() == 0)
|
||||
if (isWindmill && contraption.getSailBlocks() == 0)
|
||||
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
|
||||
running = true;
|
||||
angle = 0;
|
||||
sendData();
|
||||
|
||||
for (BlockInfo info : movingConstruct.blocks.values()) {
|
||||
getWorld().setBlockState(info.pos.add(pos), Blocks.AIR.getDefaultState(), 67);
|
||||
}
|
||||
|
||||
updateGeneratedRotation();
|
||||
}
|
||||
|
||||
|
@ -145,24 +125,9 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
|
|||
if (!running)
|
||||
return;
|
||||
|
||||
for (BlockInfo block : movingConstruct.blocks.values()) {
|
||||
BlockPos targetPos = block.pos.add(pos);
|
||||
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"));
|
||||
}
|
||||
}
|
||||
|
||||
movedContraption.disassemble();
|
||||
movedContraption = null;
|
||||
running = false;
|
||||
movingConstruct = null;
|
||||
angle = 0;
|
||||
updateGeneratedRotation();
|
||||
sendData();
|
||||
|
@ -172,14 +137,15 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
|
|||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (running && RotationConstruct.isFrozen())
|
||||
if (running && Contraption.isFrozen())
|
||||
disassembleConstruct();
|
||||
|
||||
if (!world.isRemote && assembleNextTick) {
|
||||
assembleNextTick = false;
|
||||
if (running) {
|
||||
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();
|
||||
}
|
||||
return;
|
||||
|
@ -197,6 +163,26 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
|
|||
float angularSpeed = getAngularSpeed();
|
||||
float newAngle = angle + angularSpeed;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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.simibubi.create.AllBlocks;
|
|
@ -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;
|
||||
|
|
@ -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.foundation.block.RenderUtilityBlock;
|
||||
|
||||
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.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.material.PushReaction;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
|
@ -71,7 +72,7 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
|||
if (!cart.getPassengers().isEmpty())
|
||||
return;
|
||||
|
||||
MountedContraption contraption = MountedContraption.assembleMinecart(world, pos, cart);
|
||||
Contraption contraption = MountedContraption.assembleMinecart(world, pos, cart);
|
||||
ContraptionEntity entity = new ContraptionEntity(world, contraption,
|
||||
ContraptionEntity.yawFromMotion(cart.getMotion()));
|
||||
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) {
|
||||
if (cart.getPassengers().isEmpty())
|
||||
return;
|
||||
Entity entity = cart.getPassengers().get(0);
|
||||
if (!(entity instanceof ContraptionEntity))
|
||||
if (!(cart.getPassengers().get(0) instanceof ContraptionEntity))
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -117,7 +109,8 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
|||
|
||||
@Override
|
||||
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
|
||||
|
@ -125,7 +118,7 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
|||
ISelectionContext context) {
|
||||
if (context.getEntity() instanceof AbstractMinecartEntity)
|
||||
return VoxelShapes.empty();
|
||||
return getShape(state, worldIn, pos, context);
|
||||
return VoxelShapes.fullCube();
|
||||
}
|
||||
|
||||
@Override
|
|
@ -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 org.apache.commons.lang3.tuple.MutablePair;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.Contraption;
|
||||
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.contraptions.Contraption;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
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.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||
|
||||
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())
|
||||
return null;
|
||||
|
||||
|
@ -34,7 +30,7 @@ public class MountedContraption extends Contraption {
|
|||
if (!state.has(RAIL_SHAPE))
|
||||
return null;
|
||||
|
||||
MountedContraption contraption = new MountedContraption();
|
||||
Contraption contraption = new MountedContraption();
|
||||
Vec3d vec = cart.getMotion();
|
||||
if (!contraption.searchMovedStructure(world, pos, Direction.getFacingFromVector(vec.x, vec.y, vec.z)))
|
||||
return null;
|
||||
|
@ -43,21 +39,8 @@ public class MountedContraption extends Contraption {
|
|||
contraption.add(pos, new BlockInfo(pos,
|
||||
AllBlocks.MINECART_ANCHOR.block.getDefaultState().with(BlockStateProperties.HORIZONTAL_AXIS, axis),
|
||||
null));
|
||||
|
||||
for (BlockInfo block : contraption.blocks.values()) {
|
||||
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);
|
||||
}
|
||||
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
|
||||
contraption.initActors(world);
|
||||
|
||||
return contraption;
|
||||
}
|
||||
|
@ -83,8 +66,14 @@ public class MountedContraption extends Contraption {
|
|||
return capture;
|
||||
}
|
||||
|
||||
public BlockPos getAnchor() {
|
||||
return anchor;
|
||||
@Override
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
|
@ -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.CreateConfig;
|
||||
|
@ -33,7 +33,6 @@ import net.minecraftforge.common.Tags;
|
|||
public class MechanicalPistonBlock extends DirectionalAxisKineticBlock {
|
||||
|
||||
public static final EnumProperty<PistonState> STATE = EnumProperty.create("state", PistonState.class);
|
||||
|
||||
protected boolean isSticky;
|
||||
|
||||
public MechanicalPistonBlock(boolean sticky) {
|
|
@ -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.CreateConfig;
|
||||
import com.simibubi.create.foundation.block.IWithoutBlockItem;
|
||||
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
|
||||
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.BlockState;
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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.modules.contraptions.base.IRotate;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
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.client.renderer.BufferBuilder;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
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,
|
||||
int destroyStage, BufferBuilder 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
|
|
@ -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();
|
||||
// }
|
||||
// }
|
||||
|
||||
}*/
|
|
@ -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.PISTON_POLE;
|
||||
|
@ -10,17 +10,19 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.Contraption;
|
||||
import com.simibubi.create.modules.contraptions.components.constructs.piston.MechanicalPistonBlock.PistonState;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.state.properties.PistonType;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||
|
||||
|
@ -39,9 +41,9 @@ public class PistonContraption extends Contraption {
|
|||
construct.orientation = direction;
|
||||
if (!construct.collectExtensions(world, pos, direction))
|
||||
return null;
|
||||
if (!construct.searchMovedStructure(world, pos.offset(direction, construct.initialExtensionProgress + 1),
|
||||
retract ? direction.getOpposite() : direction))
|
||||
if (!construct.searchMovedStructure(world, construct.anchor, retract ? direction.getOpposite() : direction))
|
||||
return null;
|
||||
construct.initActors(world);
|
||||
return construct;
|
||||
}
|
||||
|
||||
|
@ -93,13 +95,18 @@ public class PistonContraption extends Contraption {
|
|||
initialExtensionProgress = extensionsInFront;
|
||||
pistonCollisionBox = new AxisAlignedBB(end.offset(direction, -extensionsInFront));
|
||||
|
||||
anchor = pos.offset(direction, initialExtensionProgress + 1);
|
||||
|
||||
if (extensionLength == 0)
|
||||
return false;
|
||||
|
||||
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));
|
||||
pistonCollisionBox = pistonCollisionBox.union(new AxisAlignedBB(polePos));
|
||||
}
|
||||
|
||||
constructCollisionBox = new AxisAlignedBB(pos.offset(direction, initialExtensionProgress));
|
||||
constructCollisionBox = new AxisAlignedBB(BlockPos.ZERO.offset(direction, -initialExtensionProgress));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -125,14 +132,48 @@ public class PistonContraption extends Contraption {
|
|||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readNBT(CompoundNBT nbt) {
|
||||
super.readNBT(nbt);
|
||||
public void disassemble(IWorld world, BlockPos offset, float yaw, float pitch) {
|
||||
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");
|
||||
initialExtensionProgress = nbt.getInt("InitialLength");
|
||||
orientation = Direction.byIndex(nbt.getInt("Orientation"));
|
||||
if (nbt.contains("BoundsBack"))
|
||||
pistonCollisionBox = readAABB(nbt.getList("BoundsBack", 5));
|
||||
}
|
||||
|
@ -145,7 +186,9 @@ public class PistonContraption extends Contraption {
|
|||
ListNBT bb = writeAABB(pistonCollisionBox);
|
||||
nbt.put("BoundsBack", bb);
|
||||
}
|
||||
nbt.putInt("InitialLength", initialExtensionProgress);
|
||||
nbt.putInt("ExtensionLength", extensionLength);
|
||||
nbt.putInt("Orientation", orientation.getIndex());
|
||||
|
||||
return nbt;
|
||||
}
|
|
@ -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.CreateConfig;
|
||||
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
|
||||
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.Blocks;
|
|
@ -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.IWithTileEntity;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
|
|
|
@ -8,8 +8,8 @@ import com.simibubi.create.AllBlocks;
|
|||
import com.simibubi.create.foundation.block.IRenderUtilityBlock;
|
||||
import com.simibubi.create.foundation.block.IWithTileEntity;
|
||||
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.utility.AllShapes;
|
||||
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.IBeltAttachment;
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.simibubi.create.modules.contraptions.components.saw;
|
|||
import com.simibubi.create.foundation.block.IWithTileEntity;
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
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 net.minecraft.block.Block;
|
||||
|
@ -21,8 +21,8 @@ import net.minecraft.tileentity.TileEntity;
|
|||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
|
|
|
@ -2,8 +2,8 @@ package com.simibubi.create.modules.contraptions.processing;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.IWithTileEntity;
|
||||
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
|
|
@ -4,7 +4,8 @@ import java.util.Random;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
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.BlockState;
|
||||
|
@ -15,6 +16,7 @@ import net.minecraft.state.StateContainer.Builder;
|
|||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.TickPriority;
|
||||
|
@ -100,19 +102,32 @@ public class ContactBlock extends ProperDirectionalBlock implements IHaveMovemen
|
|||
}
|
||||
|
||||
@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;
|
||||
World world = context.world;
|
||||
BlockPos pos = context.currentGridPos;
|
||||
|
||||
Direction direction = block.get(FACING);
|
||||
if (!hasValidContact(world, pos, direction))
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
int ticksToStayActive = (int) Math
|
||||
.ceil(1 / Math.abs(context.motion.length()));
|
||||
world.setBlockState(pos.offset(direction), world.getBlockState(pos.offset(direction)).with(POWERED, true));
|
||||
world.getPendingBlockTicks().scheduleTick(pos.offset(direction), this, ticksToStayActive, TickPriority.NORMAL);
|
||||
BlockState visitedState = world.getBlockState(pos);
|
||||
if (!AllBlocks.CONTACT.typeOf(visitedState))
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import static net.minecraft.block.Block.makeCuboidShape;
|
||||
|
||||
import com.simibubi.create.foundation.utility.VoxelShaper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.shapes.IBooleanFunction;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
|
||||
import static net.minecraft.block.Block.makeCuboidShape;
|
||||
|
||||
public class BeltTunnelShapes {
|
||||
|
||||
private static VoxelShape block = makeCuboidShape(0, -5, 0, 16, 16, 16);
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.gauge;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.foundation.block.RenderUtilityBlock;
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
@ -29,8 +32,6 @@ import net.minecraft.world.IBlockReader;
|
|||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class GaugeBlock extends DirectionalAxisKineticBlock {
|
||||
|
||||
protected Type type;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.modules.logistics.block.inventories;
|
||||
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
|
|
@ -10,9 +10,9 @@ import java.util.Set;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
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.VoxelShaper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.modules.schematics.block;
|
||||
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.material.Material;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.modules.schematics.block;
|
||||
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.simibubi.create.modules.schematics.block;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
|
|
@ -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.Indicator;
|
||||
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.TooltipHelper;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.modules.schematics.packet.ConfigureSchematicannonPacket;
|
||||
import com.simibubi.create.modules.schematics.packet.ConfigureSchematicannonPacket.Option;
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
"block.create.mechanical_crafter": "Mechanical Crafter",
|
||||
"block.create.speed_gauge": "Speedometer",
|
||||
"block.create.stress_gauge": "Stress Gauge",
|
||||
"block.create.cart_assembler": "Cart Assembler",
|
||||
|
||||
"block.create.sticky_mechanical_piston": "Sticky Mechanical Piston",
|
||||
"block.create.mechanical_piston": "Mechanical Piston",
|
||||
|
|
Loading…
Reference in a new issue