diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index 61cef8a9a..43dee6e5d 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -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; diff --git a/src/main/java/com/simibubi/create/AllEntities.java b/src/main/java/com/simibubi/create/AllEntities.java index e9545c2b7..5fe9394ee 100644 --- a/src/main/java/com/simibubi/create/AllEntities.java +++ b/src/main/java/com/simibubi/create/AllEntities.java @@ -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; diff --git a/src/main/java/com/simibubi/create/AllPackets.java b/src/main/java/com/simibubi/create/AllPackets.java index 64a86967d..d3046b799 100644 --- a/src/main/java/com/simibubi/create/AllPackets.java +++ b/src/main/java/com/simibubi/create/AllPackets.java @@ -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; diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 431b801b1..b6b7af3a7 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -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; diff --git a/src/main/java/com/simibubi/create/Create.java b/src/main/java/com/simibubi/create/Create.java index afe5223bf..058f77956 100644 --- a/src/main/java/com/simibubi/create/Create.java +++ b/src/main/java/com/simibubi/create/Create.java @@ -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(); diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index 145a76c81..274ef05a5 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -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; diff --git a/src/main/java/com/simibubi/create/Events.java b/src/main/java/com/simibubi/create/Events.java index e18411124..d3cbd8410 100644 --- a/src/main/java/com/simibubi/create/Events.java +++ b/src/main/java/com/simibubi/create/Events.java @@ -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); } diff --git a/src/main/java/com/simibubi/create/ResourceReloadHandler.java b/src/main/java/com/simibubi/create/ResourceReloadHandler.java index d863bfd73..2823618d3 100644 --- a/src/main/java/com/simibubi/create/ResourceReloadHandler.java +++ b/src/main/java/com/simibubi/create/ResourceReloadHandler.java @@ -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 { @Override protected void apply(String splashList, IResourceManager resourceManagerIn, IProfiler profilerIn) { - MechanicalBearingTileEntityRenderer.invalidateCache(); SpriteShifter.reloadUVs(); CreateClient.bufferCache.invalidate(); } diff --git a/src/main/java/com/simibubi/create/foundation/utility/AllShapes.java b/src/main/java/com/simibubi/create/foundation/utility/AllShapes.java index 410dc4472..7966f7f61 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/AllShapes.java +++ b/src/main/java/com/simibubi/create/foundation/utility/AllShapes.java @@ -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 diff --git a/src/main/java/com/simibubi/create/foundation/utility/BufferManipulator.java b/src/main/java/com/simibubi/create/foundation/utility/BufferManipulator.java deleted file mode 100644 index 6845c514b..000000000 --- a/src/main/java/com/simibubi/create/foundation/utility/BufferManipulator.java +++ /dev/null @@ -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; - } - -} diff --git a/src/main/java/com/simibubi/create/foundation/utility/SuperByteBuffer.java b/src/main/java/com/simibubi/create/foundation/utility/SuperByteBuffer.java index 53f8a22b1..e2538a7cb 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/SuperByteBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/SuperByteBuffer.java @@ -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); diff --git a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java index 104150150..02ae74fc2 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java @@ -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); } diff --git a/src/main/java/com/simibubi/create/foundation/world/OreGeneration.java b/src/main/java/com/simibubi/create/foundation/world/OreGeneration.java index 645174f14..8cefa7072 100644 --- a/src/main/java/com/simibubi/create/foundation/world/OreGeneration.java +++ b/src/main/java/com/simibubi/create/foundation/world/OreGeneration.java @@ -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)), diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java index 702f17d8c..edd1bb7ed 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillBlock.java index e060fbe75..27cbc4ea3 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillBlock.java @@ -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(); - -// BlockState block = context.state; -// if (movement == block.get(FACING).getOpposite()) -// return; + public boolean isActive(MovementContext context) { + return !VecHelper.isVecPointingTowards(context.relativeMotion, context.state.get(FACING).getOpposite()); + } + @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); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillTileEntityRenderer.java index a6354024d..514f728f2 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillTileEntityRenderer.java @@ -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); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterBlock.java index 1b0337f24..8194ccdc3 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterBlock.java @@ -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); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterTileEntityRenderer.java index 1e3846ca2..29d28e0b2 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterTileEntityRenderer.java @@ -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 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(); - } - -} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/bearing/RotationConstruct.java b/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/bearing/RotationConstruct.java deleted file mode 100644 index af46277f2..000000000 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/bearing/RotationConstruct.java +++ /dev/null @@ -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 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 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 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 getAttachedBlocksByChassis(World world, Direction direction, List chassis) { - List 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 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 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 collectChassis(World world, BlockPos pos, Direction direction) { - List 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(); - } - -} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/bearing/RotationConstructVertexBuffer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/bearing/RotationConstructVertexBuffer.java deleted file mode 100644 index 43cb48ea0..000000000 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/bearing/RotationConstructVertexBuffer.java +++ /dev/null @@ -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; - } - -} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/mounted/ContraptionEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/mounted/ContraptionEntity.java deleted file mode 100644 index 6e60c3629..000000000 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/mounted/ContraptionEntity.java +++ /dev/null @@ -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 entityBuilder = (EntityType.Builder) 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()); - } - -} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MechanicalPistonTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MechanicalPistonTileEntity.java deleted file mode 100644 index 6fa2f5f29..000000000 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MechanicalPistonTileEntity.java +++ /dev/null @@ -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 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 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 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 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 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); - } - -} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MovingConstructHandler.java b/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MovingConstructHandler.java deleted file mode 100644 index 19b55e135..000000000 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MovingConstructHandler.java +++ /dev/null @@ -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 renderedBBs = new LinkedList<>(); - static Map> 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 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 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 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(); -// } -// } - -} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/Contraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java similarity index 84% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/Contraption.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java index 58967cc12..db16a3cee 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/Contraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java @@ -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 frontier = new ArrayList<>(); Set 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 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 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 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 pair : actors) { + BlockState blockState = pair.left.state; + MovementContext context = new MovementContext(world, blockState); + ((IHaveMovementBehavior) blockState.getBlock()).startMoving(context); + pair.setRight(context); + } + } + public List> getActors() { return actors; } + public BlockPos getAnchor() { + return anchor; + } + } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java new file mode 100644 index 000000000..8943778a0 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java @@ -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 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 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 entityBuilder = (EntityType.Builder) 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; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/mounted/ContraptionEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntityRenderer.java similarity index 70% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/mounted/ContraptionEntityRenderer.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntityRenderer.java index 1d0cb0b7c..22affc745 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/mounted/ContraptionEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntityRenderer.java @@ -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 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 } } - 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); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/ContraptionRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionRenderer.java similarity index 91% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/ContraptionRenderer.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionRenderer.java index 369f9c6fd..af06551dc 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/ContraptionRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionRenderer.java @@ -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 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); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/IControlContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/IControlContraption.java new file mode 100644 index 000000000..178e5e6fd --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/IControlContraption.java @@ -0,0 +1,7 @@ +package com.simibubi.create.modules.contraptions.components.contraptions; + +public interface IControlContraption { + + public void attach(ContraptionEntity contraption); + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/IHaveMovementBehavior.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/IHaveMovementBehavior.java new file mode 100644 index 000000000..2cede4d3b --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/IHaveMovementBehavior.java @@ -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; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java new file mode 100644 index 000000000..99dd82d92 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java @@ -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; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/bearing/MechanicalBearingBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingBlock.java similarity index 94% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/bearing/MechanicalBearingBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingBlock.java index 0358ee7d0..5687166d2 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/bearing/MechanicalBearingBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/bearing/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java similarity index 58% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/bearing/MechanicalBearingTileEntity.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java index f14d367af..d4cc4dc14 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/bearing/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java @@ -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(); + } } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntityRenderer.java new file mode 100644 index 000000000..52cf87338 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntityRenderer.java @@ -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()); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/AbstractChassisBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/AbstractChassisBlock.java similarity index 98% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/AbstractChassisBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/AbstractChassisBlock.java index 4ff4e54a6..dc727477b 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/AbstractChassisBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/AbstractChassisBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/ChassisTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java similarity index 94% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/ChassisTileEntity.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java index fd138aea3..fcd28bf15 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/ChassisTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/ConfigureChassisPacket.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ConfigureChassisPacket.java similarity index 90% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/ConfigureChassisPacket.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ConfigureChassisPacket.java index 1f2f33688..6d917a7e5 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/ConfigureChassisPacket.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ConfigureChassisPacket.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/LinearChassisBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/LinearChassisBlock.java similarity index 97% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/LinearChassisBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/LinearChassisBlock.java index a50e56ca5..1ea0d1af6 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/LinearChassisBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/LinearChassisBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/RadialChassisBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/RadialChassisBlock.java similarity index 96% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/RadialChassisBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/RadialChassisBlock.java index 59d54a571..ad901312a 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/RadialChassisBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/RadialChassisBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/mounted/CartAssemblerBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java similarity index 86% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/mounted/CartAssemblerBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java index 5c2de9ea3..1b15ea76e 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/mounted/CartAssemblerBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java @@ -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 diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/mounted/MountedContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java similarity index 62% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/mounted/MountedContraption.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java index c2e2eda6e..64d5a58eb 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/mounted/MountedContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java @@ -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 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)); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MechanicalPistonBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonBlock.java similarity index 98% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MechanicalPistonBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonBlock.java index b55f76930..d58f02b30 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MechanicalPistonBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonBlock.java @@ -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 STATE = EnumProperty.create("state", PistonState.class); - protected boolean isSticky; public MechanicalPistonBlock(boolean sticky) { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MechanicalPistonHeadBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonHeadBlock.java similarity index 93% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MechanicalPistonHeadBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonHeadBlock.java index 9f00bd5db..3bcb070c5 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MechanicalPistonHeadBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonHeadBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java new file mode 100644 index 000000000..273e87e35 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java @@ -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 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(); + } + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MechanicalPistonTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntityRenderer.java similarity index 62% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MechanicalPistonTileEntityRenderer.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntityRenderer.java index 7ea7d2700..9442cfb7d 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/MechanicalPistonTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntityRenderer.java @@ -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 diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MovingConstructHandler.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MovingConstructHandler.java new file mode 100644 index 000000000..66d2f4c74 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MovingConstructHandler.java @@ -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 renderedBBs = new LinkedList<>(); + static Map> 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 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 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 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(); +// } +// } + +}*/ diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/PistonContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java similarity index 68% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/PistonContraption.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java index 8a1d31b14..c867d471e 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java @@ -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; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/PistonPoleBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonPoleBlock.java similarity index 93% rename from src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/PistonPoleBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonPoleBlock.java index 3d484fab2..08d35aa31 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/constructs/piston/PistonPoleBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonPoleBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorBlock.java index 1e4af704c..adb577821 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/press/MechanicalPressBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/press/MechanicalPressBlock.java index 29dae94ee..82ffacefc 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/press/MechanicalPressBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/press/MechanicalPressBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawBlock.java index fa55ab0a6..3f41608be 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/processing/BasinBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/processing/BasinBlock.java index 01c75400a..1d6834425 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/processing/BasinBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/processing/BasinBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/redstone/ContactBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/redstone/ContactBlock.java index cc3ca1aaf..520213a60 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/redstone/ContactBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/redstone/ContactBlock.java @@ -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; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTunnelShapes.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTunnelShapes.java index 3e41e278e..29e2cf319 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTunnelShapes.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTunnelShapes.java @@ -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); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/GaugeBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/GaugeBlock.java index c878cb573..9f4ed10af 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/GaugeBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/GaugeBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/inventories/FlexcrateBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/inventories/FlexcrateBlock.java index 70429e440..b496f3e71 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/inventories/FlexcrateBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/inventories/FlexcrateBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalCasingBlock.java b/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalCasingBlock.java index f6a855bbf..b5d381ed6 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalCasingBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalCasingBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/schematics/block/CreativeCrateBlock.java b/src/main/java/com/simibubi/create/modules/schematics/block/CreativeCrateBlock.java index fe226272d..b80c3307a 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/block/CreativeCrateBlock.java +++ b/src/main/java/com/simibubi/create/modules/schematics/block/CreativeCrateBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicTableBlock.java b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicTableBlock.java index cf00f3da4..5fca5265e 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicTableBlock.java +++ b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicTableBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonBlock.java b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonBlock.java index 4eda575f7..6dfc81c17 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonBlock.java +++ b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonBlock.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonScreen.java b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonScreen.java index 8236b6f8f..82904fb68 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonScreen.java +++ b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonScreen.java @@ -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; diff --git a/src/main/resources/assets/create/lang/en_us.json b/src/main/resources/assets/create/lang/en_us.json index 96550a500..9bf9d1c55 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -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",