From b6ae5565bde40acd918ed92ba0f2a99c5dff5f3b Mon Sep 17 00:00:00 2001 From: Boblet Date: Tue, 2 May 2023 16:40:26 +0200 Subject: [PATCH] on a rail --- .../java/com/hbm/blocks/rail/IRailNTM.java | 27 +++++ .../hbm/blocks/rail/RailStandardStraight.java | 105 ++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 src/main/java/com/hbm/blocks/rail/IRailNTM.java create mode 100644 src/main/java/com/hbm/blocks/rail/RailStandardStraight.java diff --git a/src/main/java/com/hbm/blocks/rail/IRailNTM.java b/src/main/java/com/hbm/blocks/rail/IRailNTM.java new file mode 100644 index 000000000..87738ed77 --- /dev/null +++ b/src/main/java/com/hbm/blocks/rail/IRailNTM.java @@ -0,0 +1,27 @@ +package com.hbm.blocks.rail; + +import net.minecraft.util.Vec3; +import net.minecraft.world.World; + +public interface IRailNTM { + + /** Returns a vector pointing to the closest snapping position given the starting position */ + public Vec3 getSnappingPos(World world, int x, int y, int z, double trainX, double trainY, double trainZ); + + /** + * Returns a location on the rail based on the train's current X/Y/Z momentum as well as the intended speed along the rail. + * If the train would leave the rail within that tick, the position is the last valid position on that rail. + * Inherently safer than simply adding the motion to the position and then snapping, since that may lead to derailing. + * The motion has to be calculated from the train's rotation, the scalar doesn't matter since it's only used for determining orientation in a clear way. + * Motion ends up being *-1 if the train is going in reverse, still pointing forwards despite the speed being negative. + * Also features a double[] wrapper with size 1 which holds the speed value that overshoots the rail. + * */ + public Vec3 getTravelLocation(World world, int x, int y, int z, double trainX, double trainY, double trainZ, double motionX, double motionY, double motionZ, double speed, double[] leftover); + + /** Returns that rail'S gauge. Trains will derail if the gauge does not match. */ + public TrackGauge getGauge(World world, int x, int y, int z); + + public static enum TrackGauge { + STANDARD //roughly 1.5m + } +} diff --git a/src/main/java/com/hbm/blocks/rail/RailStandardStraight.java b/src/main/java/com/hbm/blocks/rail/RailStandardStraight.java new file mode 100644 index 000000000..66a188e6a --- /dev/null +++ b/src/main/java/com/hbm/blocks/rail/RailStandardStraight.java @@ -0,0 +1,105 @@ +package com.hbm.blocks.rail; + +import com.hbm.blocks.BlockDummyable; +import com.hbm.lib.Library; + +import net.minecraft.block.material.Material; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.MathHelper; +import net.minecraft.util.Vec3; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +public class RailStandardStraight extends BlockDummyable implements IRailNTM { + + public RailStandardStraight(Material mat) { + super(mat); + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return null; + } + + @Override + public int[] getDimensions() { + return new int[] {0, 0, 2, 2, 0, 0}; + } + + @Override + public int getOffset() { + return 2; + } + + @Override + public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) { + int meta = world.getBlockMetadata(x, y, z); + this.setBlockBounds(0F, 0F, 0F, 1F, 0.125F, 1F); + } + + @Override + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) { + this.setBlockBounds(0F, 0F, 0F, 1F, 0.125F, 1F); + return AxisAlignedBB.getBoundingBox(x + this.minX, y + this.minY, z + this.minZ, x + this.maxX, y + this.maxY, z + this.maxZ); + } + + @Override + public Vec3 getSnappingPos(World world, int x, int y, int z, double trainX, double trainY, double trainZ) { + return snapAndMove(world, x, y, z, trainX, trainY, trainZ, 0, 0, 0, 0, new double[1]); + } + + @Override + public Vec3 getTravelLocation(World world, int x, int y, int z, double trainX, double trainY, double trainZ, double motionX, double motionY, double motionZ, double speed, double[] leftover) { + return snapAndMove(world, x, y, z, trainX, trainY, trainZ, motionX, motionY, motionZ, speed, leftover); + } + + /* Very simple function determining the snapping position and adding the motion value to it, if desired. */ + public Vec3 snapAndMove(World world, int x, int y, int z, double trainX, double trainY, double trainZ, double motionX, double motionY, double motionZ, double speed, double[] leftover) { + int[] pos = this.findCore(world, x, y, z); + if(pos == null) return Vec3.createVectorHelper(trainX, trainY, trainZ); + int cX = pos[0]; + int cY = pos[1]; + int cZ = pos[2]; + int meta = world.getBlockMetadata(cX, cY, cZ) - this.offset; + ForgeDirection dir = ForgeDirection.getOrientation(meta); + + Vec3 vec = Vec3.createVectorHelper(trainX, trainY, trainZ); + + if(speed == 0) { + return vec; + } + + if(dir == Library.POS_X || dir == Library.NEG_X) { + double targetX = trainX; + if(motionX > 0) { + targetX += speed; + } else { + targetX -= speed; + } + vec.xCoord = MathHelper.clamp_double(targetX, x - 2, x + 3); + vec.yCoord = y; + vec.zCoord = z + 0.5; + leftover[0] = Math.abs(targetX - vec.xCoord); + } else { + double targetZ = trainZ; + if(motionZ > 0) { + targetZ += speed; + } else { + targetZ -= speed; + } + vec.xCoord = x + 0.5; + vec.yCoord = y; + vec.zCoord = MathHelper.clamp_double(targetZ, z - 2, z + 3); + leftover[0] = Math.abs(targetZ - vec.zCoord); + } + + return vec; + } + + @Override + public TrackGauge getGauge(World world, int x, int y, int z) { + return TrackGauge.STANDARD; + } +}