From 0f6379e1fcb6b661564de4279830d4d9ac3c10bf Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Fri, 20 Feb 2026 21:23:35 +0800 Subject: [PATCH 01/16] ref: modernize buildscript and mapping --- build.gradle | 10 +++++----- gradle/wrapper/gradle-wrapper.properties | 2 +- src/main/java/trackapi/compat/MinecraftRail.java | 4 ++-- src/main/java/trackapi/lib/ITrack.java | 7 ++----- src/main/java/trackapi/lib/ITrackBlock.java | 7 ++----- src/main/java/trackapi/lib/Util.java | 4 ++-- 6 files changed, 14 insertions(+), 20 deletions(-) diff --git a/build.gradle b/build.gradle index 1db0c5c..897f9e9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,9 +1,9 @@ -import cam72cam.universalmodcore.Util; +import cam72cam.universalmodcore.Util buildscript { repositories { - jcenter() - maven { url = "http://files.minecraftforge.net/maven" } + mavenCentral() + maven { url = "http://maven.minecraftforge.net/" } maven { url = "https://teamopenindustry.cc/maven" } } dependencies { @@ -30,7 +30,7 @@ compileJava { } minecraft { - version = "1.12.2-14.23.0.2529" + version = "1.12.2-14.23.5.2847" runDir = "run" // the mappings can be changed at any time, and must be in the following format. @@ -38,7 +38,7 @@ minecraft { // stable_# stables are built at the discretion of the MCP team. // Use non-default mappings at your own risk. they may not always work. // simply re-run your setup task after changing the mappings to update your workspace. - mappings = "snapshot_20171003" + mappings = "stable_39" // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e18cba7..92ae1fb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-bin.zip diff --git a/src/main/java/trackapi/compat/MinecraftRail.java b/src/main/java/trackapi/compat/MinecraftRail.java index f691143..8fdebf8 100644 --- a/src/main/java/trackapi/compat/MinecraftRail.java +++ b/src/main/java/trackapi/compat/MinecraftRail.java @@ -67,7 +67,7 @@ public Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { Vec3d trackCenter = centers.get(direction); Vec3d posRelativeToCenter = currentPosition.subtractReverse(new Vec3d(pos).add(trackCenter)); - double distanceToCenter = posRelativeToCenter.lengthVector(); + double distanceToCenter = posRelativeToCenter.length(); // Determine if trackMovement should be positive or negative as relative to block center boolean trackPosMotionInverted = posRelativeToCenter.distanceTo(trackMovement) < posRelativeToCenter.scale(-1).distanceTo(trackMovement); @@ -78,7 +78,7 @@ public Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { //Correct new pos to track alignment newPosition = newPosition.add(trackMovement.scale(trackPosMotionInverted ? -distanceToCenter : distanceToCenter)); // Move new pos along track alignment - newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motion.lengthVector() : motion.lengthVector())); + newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motion.length() : motion.length())); return newPosition; } diff --git a/src/main/java/trackapi/lib/ITrack.java b/src/main/java/trackapi/lib/ITrack.java index ca2362f..8baff44 100644 --- a/src/main/java/trackapi/lib/ITrack.java +++ b/src/main/java/trackapi/lib/ITrack.java @@ -10,16 +10,13 @@ public interface ITrack { * @see Gauges#STANDARD * @see Gauges#MINECRAFT */ - public double getTrackGauge(); + double getTrackGauge(); /** * Used by rolling stock to look up their next position. * * @param currentPosition - Current entity or bogey position - * @param rotationYaw - Current entity rotation in degrees - * @param bogieYaw - Current bogey rotation in degrees (set to rotationYaw if unused) - * @param distance - Distanced traveled in meters * @return The new position of the entity or bogey */ - public Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion); + Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion); } diff --git a/src/main/java/trackapi/lib/ITrackBlock.java b/src/main/java/trackapi/lib/ITrackBlock.java index c478671..b1b4e88 100644 --- a/src/main/java/trackapi/lib/ITrackBlock.java +++ b/src/main/java/trackapi/lib/ITrackBlock.java @@ -16,16 +16,13 @@ public interface ITrackBlock { * @see Gauges#STANDARD * @see Gauges#MINECRAFT */ - public double getTrackGauge(World world, BlockPos pos); + double getTrackGauge(World world, BlockPos pos); /** * Used by rolling stock to look up their next position. * * @param currentPosition - Current entity or bogey position - * @param rotationYaw - Current entity rotation in degrees - * @param bogieYaw - Current bogey rotation in degrees (set to rotationYaw if unused) - * @param distance - Distanced traveled in meters * @return The new position of the entity or bogey */ - public Vec3d getNextPosition(World world, BlockPos pos, Vec3d currentPosition, Vec3d motion); + Vec3d getNextPosition(World world, BlockPos pos, Vec3d currentPosition, Vec3d motion); } diff --git a/src/main/java/trackapi/lib/Util.java b/src/main/java/trackapi/lib/Util.java index 63f2d4a..40a8410 100644 --- a/src/main/java/trackapi/lib/Util.java +++ b/src/main/java/trackapi/lib/Util.java @@ -46,11 +46,11 @@ public static ITrack getTileEntity(World world, Vec3d pos, boolean acceptMinecra return track; } // Allow a bit of vertical fuzziness - track = getInternalTileEntity(world, pos.addVector(0, 0.4, 0), acceptMinecraftRails); + track = getInternalTileEntity(world, pos.add(0, 0.4, 0), acceptMinecraftRails); if (track != null) { return track; } - track = getInternalTileEntity(world, pos.addVector(0, -0.4, 0), acceptMinecraftRails); + track = getInternalTileEntity(world, pos.add(0, -0.4, 0), acceptMinecraftRails); if (track != null) { return track; } From acaad8729f361f2161b8dbacb2d128f1760773be Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Sun, 22 Feb 2026 12:48:58 +0800 Subject: [PATCH 02/16] feat: add PathingContext for packed data --- .../java/trackapi/lib/PathingContext.java | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/main/java/trackapi/lib/PathingContext.java diff --git a/src/main/java/trackapi/lib/PathingContext.java b/src/main/java/trackapi/lib/PathingContext.java new file mode 100644 index 0000000..a6c207c --- /dev/null +++ b/src/main/java/trackapi/lib/PathingContext.java @@ -0,0 +1,98 @@ +package trackapi.lib; + +import net.minecraft.util.math.Vec3d; + +import java.util.IdentityHashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Helper class for transferring bundled pathing data + *

+ * Users could define associated data to pass from track to stock + */ +public final class PathingContext { + private final Map, Object> dataMap; + + //We have next found pos by default + public final Vec3 pos; + //And some built-in fields that are filled in + //Moved distance between current pos and next pos + public static final TrackData PREV_POS = createOrGetKey("prevPos", Vec3.class); + public static final TrackData DELTA_MOVEMENT = createOrGetKey("deltaMovement", Double.class); + public static final TrackData GAUGE = createOrGetKey("gauge", Double.class); + //And we expect you to fill in these + //Track roll for stocks to do superelevation (rotated from middle of the rails) + public static final TrackData ROLL_DEGREES = createOrGetKey("rollDegrees", Double.class); + + //Wrapper for vanilla Vec3d + public PathingContext(Vec3d pos) { + this(new Vec3(pos)); + } + + public PathingContext(Vec3 pos) { + this.pos = Objects.requireNonNull(pos, "pos cannot be null"); + this.dataMap = new IdentityHashMap<>(); + } + + public PathingContext with(TrackData key, T value) { + key.validate(value); + dataMap.put(key, value); + return this; + } + + public T get(TrackData key) { + return key.type().cast(dataMap.get(key)); + } + + public void reset(TrackData key) { + dataMap.remove(key); + } + + @SuppressWarnings("unchecked") + public static TrackData createOrGetKey(String name, Class type) { + TrackData existing = TrackData.registered.get(name); + if (existing != null) { + if (!existing.type().equals(type)) { + throw new IllegalStateException("Key '" + name + "' already registered with different type"); + } + return (TrackData) existing; + } + TrackData data = new TrackData<>(name, type); + TrackData.registered.put(name, data); + return data; + } + + /** + * Typed key for PathingContext's data storage + *

+ * Please note this is only used in IdentityHashMap, and should not be used externally + * @param type of the value + */ + public static class TrackData { + private static final Map> registered = new ConcurrentHashMap<>(); + private final String name; + private final Class type; + + private TrackData(String name, Class type) { + this.name = Objects.requireNonNull(name); + this.type = Objects.requireNonNull(type); + } + + void validate(Object value) { + if (value != null && !type.isInstance(value)) { + throw new IllegalArgumentException("Invalid value for key '" + name + "', expected " + type.getSimpleName()); + } + } + + public Class type() { + return type; + } + + @Override + public String toString() { + return "[Name:" + name + ",Type:" + type.getName() + "]"; + } + } +} \ No newline at end of file From 8ad3bd7ab769aa275dd90a0c911f098a30fbd7e1 Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Sun, 22 Feb 2026 12:49:52 +0800 Subject: [PATCH 03/16] ref: add more predefined gauges --- src/main/java/trackapi/lib/Gauges.java | 39 ++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/main/java/trackapi/lib/Gauges.java b/src/main/java/trackapi/lib/Gauges.java index 9f913c4..044824d 100644 --- a/src/main/java/trackapi/lib/Gauges.java +++ b/src/main/java/trackapi/lib/Gauges.java @@ -1,13 +1,46 @@ package trackapi.lib; +/** + * Some gauge constants in meters + */ public class Gauges { /** - * US Standard Gauge in meters + * Minecraft Gauge + */ + public static final double MINECRAFT = 0.632; + + /** + * 2 Foot 6 Inches Narrow Gauge + */ + public static final double TWO_FOOT_SIX_INCHES = 0.762; + + /** + * 3 Foot Narrow Gauge + */ + public static final double THREE_FOOT = 0.9144; + + /** + * Meter Gauge + */ + public static final double METER = 1.000; + + /** + * Cape gauge + */ + public static final double CAPE = 1.067; + + /** + * US Standard Gauge */ public static final double STANDARD = 1.435; /** - * Minecraft Gauge in meters + * Russian Standard Gauge */ - public static final double MINECRAFT = 0.632; + public static final double RU_STANDARD = 1.524; + + /** + * Brunel Gauge + */ + public static final double BRUNEL = 2.140; } From 0d4e601d3ceb63e06bc57ccb68ff18311abb51e7 Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Sun, 22 Feb 2026 13:32:03 +0800 Subject: [PATCH 04/16] feat: add ITrackV2 for complex pathing logics --- .../java/trackapi/compat/MinecraftRail.java | 30 ++++--- src/main/java/trackapi/lib/ITrack.java | 10 +-- src/main/java/trackapi/lib/ITrackBlock.java | 20 +++-- src/main/java/trackapi/lib/ITrackV2.java | 38 ++++++++ .../java/trackapi/lib/PathingContext.java | 37 ++++---- src/main/java/trackapi/lib/Util.java | 86 +++++++++++-------- src/main/java/trackapi/lib/Vec3.java | 60 +++++++++++++ 7 files changed, 201 insertions(+), 80 deletions(-) create mode 100644 src/main/java/trackapi/lib/ITrackV2.java create mode 100644 src/main/java/trackapi/lib/Vec3.java diff --git a/src/main/java/trackapi/compat/MinecraftRail.java b/src/main/java/trackapi/compat/MinecraftRail.java index 8fdebf8..ad76463 100644 --- a/src/main/java/trackapi/compat/MinecraftRail.java +++ b/src/main/java/trackapi/compat/MinecraftRail.java @@ -6,13 +6,15 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import trackapi.lib.Gauges; -import trackapi.lib.ITrack; +import trackapi.lib.*; import java.util.HashMap; import java.util.Map; -public class MinecraftRail implements ITrack { +/** + * Wrapper for vanilla rail + */ +public class MinecraftRail implements ITrackV2 { private static Map vectors = new HashMap<>(); private static Map centers = new HashMap<>(); static { @@ -57,33 +59,37 @@ public MinecraftRail(World world, BlockPos pos) { } @Override - public double getTrackGauge() { - return Gauges.MINECRAFT; + public double[] getTrackGauges() { + return new double[]{Gauges.MINECRAFT}; } @Override - public Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { + public PathingContext getNextPosition(Vec3 currentPosition, Vec3 motion, double gauge, PathingContext inputCtx) { + Vec3d currentPositionWrapped = currentPosition.toVanilla(); + Vec3d motionWrapped = motion.toVanilla(); + Vec3d trackMovement = vectors.get(direction); Vec3d trackCenter = centers.get(direction); - Vec3d posRelativeToCenter = currentPosition.subtractReverse(new Vec3d(pos).add(trackCenter)); + Vec3d pos = new Vec3d(this.pos).add(trackCenter); + Vec3d posRelativeToCenter = currentPositionWrapped.subtractReverse(pos); double distanceToCenter = posRelativeToCenter.length(); // Determine if trackMovement should be positive or negative as relative to block center boolean trackPosMotionInverted = posRelativeToCenter.distanceTo(trackMovement) < posRelativeToCenter.scale(-1).distanceTo(trackMovement); - boolean trackMotionInverted = motion.distanceTo(trackMovement) > motion.scale(-1).distanceTo(trackMovement); + boolean trackMotionInverted = motionWrapped.distanceTo(trackMovement) > motionWrapped.scale(-1).distanceTo(trackMovement); - Vec3d newPosition = new Vec3d(pos).add(trackCenter); + Vec3d newPosition = pos; //Correct new pos to track alignment newPosition = newPosition.add(trackMovement.scale(trackPosMotionInverted ? -distanceToCenter : distanceToCenter)); // Move new pos along track alignment - newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motion.length() : motion.length())); - return newPosition; + newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motionWrapped.length() : motionWrapped.length())); + return new PathingContext(newPosition, 0d) + .with(PathingContext.DELTA_MOVEMENT, currentPositionWrapped.distanceTo(newPosition)); } public static boolean isRail(World world, BlockPos pos) { return BlockRailBase.isRailBlock(world, pos); } - } diff --git a/src/main/java/trackapi/lib/ITrack.java b/src/main/java/trackapi/lib/ITrack.java index 8baff44..b3756a4 100644 --- a/src/main/java/trackapi/lib/ITrack.java +++ b/src/main/java/trackapi/lib/ITrack.java @@ -7,16 +7,16 @@ public interface ITrack { /** * The distance between the rails measured in meters * - * @see Gauges#STANDARD - * @see Gauges#MINECRAFT + * @see Gauges */ double getTrackGauge(); /** - * Used by rolling stock to look up their next position. + * Used by rolling stocks to look up their next position (and related data). * - * @param currentPosition - Current entity or bogey position - * @return The new position of the entity or bogey + * @param currentPosition Current position of entity or bogey + * @param motion Current velocity of entity or bogey + * @return Next found position on the track */ Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion); } diff --git a/src/main/java/trackapi/lib/ITrackBlock.java b/src/main/java/trackapi/lib/ITrackBlock.java index b1b4e88..714881e 100644 --- a/src/main/java/trackapi/lib/ITrackBlock.java +++ b/src/main/java/trackapi/lib/ITrackBlock.java @@ -5,24 +5,28 @@ import net.minecraft.world.World; /** - * Compatibility layer for block only tracks - * + * Compatibility layer between ITrack and blocks which only contain tracks + *

+ * use ITrackV2 instead */ +@Deprecated public interface ITrackBlock { /** * The distance between the rails measured in meters * - * @see Gauges#STANDARD - * @see Gauges#MINECRAFT + * @see Gauges */ double getTrackGauge(World world, BlockPos pos); /** - * Used by rolling stock to look up their next position. - * - * @param currentPosition - Current entity or bogey position - * @return The new position of the entity or bogey + * Used by rolling stock to look up their next position (and related data). + * + * @param world World to query + * @param pos Position of the block + * @param currentPosition Current entity or bogey position + * @param motion Current velocity of entity or bogey + * @return Next found position on the track */ Vec3d getNextPosition(World world, BlockPos pos, Vec3d currentPosition, Vec3d motion); } diff --git a/src/main/java/trackapi/lib/ITrackV2.java b/src/main/java/trackapi/lib/ITrackV2.java new file mode 100644 index 0000000..58f91c4 --- /dev/null +++ b/src/main/java/trackapi/lib/ITrackV2.java @@ -0,0 +1,38 @@ +package trackapi.lib; + +import net.minecraft.util.math.Vec3d; + +public interface ITrackV2 extends ITrack { + + /** + * Find available gauges within this track + * + * @return All available gauges + */ + double[] getTrackGauges(); + + /** + * Find next position and related data + * @param currentPosition Current entity or bogey position + * @param motion Current velocity of entity or bogey + * @param gauge Gauge of the pathing stock + * @param inputCtx The object contains other required input parameters + * @return PathingContext + */ + PathingContext getNextPosition(Vec3 currentPosition, Vec3 motion, double gauge, PathingContext inputCtx); + + //Overrides for forward compatibility, don't use + @Override + @Deprecated + default double getTrackGauge() { + return getTrackGauges()[0]; + } + + @Override + @Deprecated + default Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { + PathingContext ctx = new PathingContext(currentPosition, 0d); + getNextPosition(new Vec3(currentPosition), new Vec3(motion), getTrackGauge(), ctx); + return ctx.nextPos.toVanilla(); + } +} diff --git a/src/main/java/trackapi/lib/PathingContext.java b/src/main/java/trackapi/lib/PathingContext.java index a6c207c..ac9ed17 100644 --- a/src/main/java/trackapi/lib/PathingContext.java +++ b/src/main/java/trackapi/lib/PathingContext.java @@ -13,41 +13,42 @@ * Users could define associated data to pass from track to stock */ public final class PathingContext { - private final Map, Object> dataMap; - //We have next found pos by default - public final Vec3 pos; - //And some built-in fields that are filled in + //We have next found pos and roll by default + public final Vec3 nextPos; + public final double roll; + private final Map, Object> extension; + //And some common fields //Moved distance between current pos and next pos - public static final TrackData PREV_POS = createOrGetKey("prevPos", Vec3.class); public static final TrackData DELTA_MOVEMENT = createOrGetKey("deltaMovement", Double.class); - public static final TrackData GAUGE = createOrGetKey("gauge", Double.class); - //And we expect you to fill in these - //Track roll for stocks to do superelevation (rotated from middle of the rails) - public static final TrackData ROLL_DEGREES = createOrGetKey("rollDegrees", Double.class); //Wrapper for vanilla Vec3d - public PathingContext(Vec3d pos) { - this(new Vec3(pos)); + public PathingContext(Vec3d nextPos, double roll) { + this(new Vec3(nextPos), roll); } - public PathingContext(Vec3 pos) { - this.pos = Objects.requireNonNull(pos, "pos cannot be null"); - this.dataMap = new IdentityHashMap<>(); + public PathingContext(Vec3 nextPos, double roll) { + this.nextPos = Objects.requireNonNull(nextPos, "nextPos cannot be null"); + this.roll = roll; + this.extension = new IdentityHashMap<>(); } public PathingContext with(TrackData key, T value) { key.validate(value); - dataMap.put(key, value); + extension.put(key, value); return this; } public T get(TrackData key) { - return key.type().cast(dataMap.get(key)); + return key.type().cast(extension.get(key)); } - public void reset(TrackData key) { - dataMap.remove(key); + public void remove(TrackData key) { + extension.remove(key); + } + + public boolean containsKey(TrackData key) { + return extension.containsKey(key); } @SuppressWarnings("unchecked") diff --git a/src/main/java/trackapi/lib/Util.java b/src/main/java/trackapi/lib/Util.java index 40a8410..9d9ac42 100644 --- a/src/main/java/trackapi/lib/Util.java +++ b/src/main/java/trackapi/lib/Util.java @@ -1,6 +1,5 @@ package trackapi.lib; -import net.minecraft.block.state.IBlockState; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -8,52 +7,65 @@ import trackapi.compat.MinecraftRail; public class Util { - private static ITrack getInternalTileEntity(final World world, Vec3d pos, boolean acceptMinecraftRails) { - final BlockPos bp = new BlockPos(Math.floor(pos.x), Math.floor(pos.y), Math.floor(pos.z)); - IBlockState bs = world.getBlockState(bp); - - if (bs.getBlock() instanceof ITrackBlock) { - final ITrackBlock track = (ITrackBlock) bs.getBlock(); - // Wrap block in ITrack - - return new ITrack() { - @Override - public double getTrackGauge() { - return track.getTrackGauge(world, bp); - } - @Override - public Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { - return track.getNextPosition(world, bp, currentPosition, motion); - } - }; - } - - TileEntity te = world.getTileEntity(bp); - if (te instanceof ITrack) { - return (ITrack) te; - } - if (acceptMinecraftRails) { - if (MinecraftRail.isRail(world, bp)) { - return new MinecraftRail(world, bp); - } - } - return null; - } - - public static ITrack getTileEntity(World world, Vec3d pos, boolean acceptMinecraftRails) { - ITrack track = getInternalTileEntity(world, pos, acceptMinecraftRails); + + /** + * Used for finding acceptable track in given world + * @param world World to query + * @param pos Current position of stock or bogey + * @param acceptMinecraftRails Should we take vanilla rails into consideration? + * @return Potential ITrack, or null if failed to find a valid one + */ + + public static T findTrackBlocks(World world, Vec3d pos, boolean acceptMinecraftRails, Class type) { + T track = getInternalTileEntity(world, pos, acceptMinecraftRails, type); if (track != null) { return track; } // Allow a bit of vertical fuzziness - track = getInternalTileEntity(world, pos.add(0, 0.4, 0), acceptMinecraftRails); + track = getInternalTileEntity(world, pos.add(0, 0.4, 0), acceptMinecraftRails, type); if (track != null) { return track; } - track = getInternalTileEntity(world, pos.add(0, -0.4, 0), acceptMinecraftRails); + track = getInternalTileEntity(world, pos.add(0, -0.4, 0), acceptMinecraftRails, type); if (track != null) { return track; } return null; } + + //Compatibility + @Deprecated + public static ITrack getTileEntity(World world, Vec3d pos, boolean acceptMinecraftRails) { + return findTrackBlocks(world, pos, acceptMinecraftRails, ITrack.class); + } + + private static T getInternalTileEntity(final World world, Vec3d pos, boolean acceptMinecraftRails, Class type) { + final BlockPos bp = new BlockPos(Math.floor(pos.x), Math.floor(pos.y), Math.floor(pos.z)); + +// IBlockState bs = world.getBlockState(bp); +// if (bs.getBlock() instanceof ITrackBlock) { +// final ITrackBlock track = (ITrackBlock) bs.getBlock(); +// // Wrap block in ITrack +// +// return new ITrack() { +// @Override +// public double getTrackGauge() { +// return track.getTrackGauge(world, bp); +// } +// @Override +// public Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { +// return track.getNextPosition(world, bp, currentPosition, motion); +// } +// }; +// } + + TileEntity te = world.getTileEntity(bp); + if (type.isInstance(te)) { + return type.cast(te); + } + if (acceptMinecraftRails && type.isAssignableFrom(MinecraftRail.class) && MinecraftRail.isRail(world, bp)) { + return type.cast(new MinecraftRail(world, bp)); + } + return null; + } } diff --git a/src/main/java/trackapi/lib/Vec3.java b/src/main/java/trackapi/lib/Vec3.java new file mode 100644 index 0000000..07bc3c7 --- /dev/null +++ b/src/main/java/trackapi/lib/Vec3.java @@ -0,0 +1,60 @@ +package trackapi.lib; + +import net.minecraft.util.math.Vec3d; + +/** + * A simple vanilla Vec3d wrapper for universality, mutable + */ +public class Vec3 { + private double x; + private double y; + private double z; + + public Vec3(Vec3d vec3d) { + this(vec3d.x, vec3d.y, vec3d.z); + } + + public Vec3(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Vec3 add(Vec3 vec3) { + this.x += vec3.x; + this.y += vec3.y; + this.z += vec3.z; + return this; + } + + public Vec3 subtract(Vec3 vec3) { + this.x -= vec3.x; + this.y -= vec3.y; + this.z -= vec3.z; + return this; + } + + public Vec3 scale(double factor) { + this.x *= factor; + this.y *= factor; + this.z *= factor; + return this; + } + + public Vec3 normalize() { + double length = this.length(); + return scale(1 / length); + } + + public double length() { + return Math.sqrt(this.lengthSquared()); + } + + public double lengthSquared() { + return x * x + y * y + z * z; + } + + public Vec3d toVanilla() { + return new Vec3d(this.x, this.y, this.z); + } +} From 4d53af6469c3dd7a69b0cae531f5d2686a983f01 Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Sun, 22 Feb 2026 13:32:09 +0800 Subject: [PATCH 05/16] bump version to 1.3 --- build.gradle | 2 +- src/main/java/trackapi/TrackAPI.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 897f9e9..df7a3b0 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ apply plugin: 'net.minecraftforge.gradle.forge' apply plugin: 'maven' -String baseVersion = "1.2" +String baseVersion = "1.3" if (!"release".equalsIgnoreCase(System.getProperty("target"))) { baseVersion += "-" + Util.GitRevision() } diff --git a/src/main/java/trackapi/TrackAPI.java b/src/main/java/trackapi/TrackAPI.java index a2241d7..8059599 100644 --- a/src/main/java/trackapi/TrackAPI.java +++ b/src/main/java/trackapi/TrackAPI.java @@ -6,5 +6,5 @@ public class TrackAPI { public static final String MODID = "trackapi"; - public static final String VERSION = "1.2"; + public static final String VERSION = "1.3"; } From 0e85b7a212c014352abf0ac538259dcf84b5d633 Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Sun, 22 Feb 2026 13:48:19 +0800 Subject: [PATCH 06/16] ref: refactor PathingContext --- .../java/trackapi/compat/MinecraftRail.java | 15 +++--- src/main/java/trackapi/lib/ITrack.java | 2 +- src/main/java/trackapi/lib/ITrackV2.java | 14 +++--- src/main/java/trackapi/lib/Vec3.java | 4 ++ .../{PathingContext.java => WheelData.java} | 50 +++++++++++-------- 5 files changed, 46 insertions(+), 39 deletions(-) rename src/main/java/trackapi/lib/{PathingContext.java => WheelData.java} (58%) diff --git a/src/main/java/trackapi/compat/MinecraftRail.java b/src/main/java/trackapi/compat/MinecraftRail.java index ad76463..2259a48 100644 --- a/src/main/java/trackapi/compat/MinecraftRail.java +++ b/src/main/java/trackapi/compat/MinecraftRail.java @@ -15,8 +15,8 @@ * Wrapper for vanilla rail */ public class MinecraftRail implements ITrackV2 { - private static Map vectors = new HashMap<>(); - private static Map centers = new HashMap<>(); + private static final Map vectors = new HashMap<>(); + private static final Map centers = new HashMap<>(); static { Vec3d north = new Vec3d(0, 0, 1); Vec3d south = new Vec3d(0, 0, -1); @@ -48,8 +48,8 @@ public class MinecraftRail implements ITrackV2 { } - private EnumRailDirection direction; - private BlockPos pos; + private final EnumRailDirection direction; + private final BlockPos pos; public MinecraftRail(World world, BlockPos pos) { this.pos = pos; @@ -64,8 +64,8 @@ public double[] getTrackGauges() { } @Override - public PathingContext getNextPosition(Vec3 currentPosition, Vec3 motion, double gauge, PathingContext inputCtx) { - Vec3d currentPositionWrapped = currentPosition.toVanilla(); + public WheelData getNextPosition(WheelData inputData, Vec3 motion, double gauge) { + Vec3d currentPositionWrapped = inputData.position.toVanilla(); Vec3d motionWrapped = motion.toVanilla(); Vec3d trackMovement = vectors.get(direction); @@ -85,8 +85,7 @@ public PathingContext getNextPosition(Vec3 currentPosition, Vec3 motion, double newPosition = newPosition.add(trackMovement.scale(trackPosMotionInverted ? -distanceToCenter : distanceToCenter)); // Move new pos along track alignment newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motionWrapped.length() : motionWrapped.length())); - return new PathingContext(newPosition, 0d) - .with(PathingContext.DELTA_MOVEMENT, currentPositionWrapped.distanceTo(newPosition)); + return new WheelData(newPosition, 0d).fromPrev(inputData); } public static boolean isRail(World world, BlockPos pos) { diff --git a/src/main/java/trackapi/lib/ITrack.java b/src/main/java/trackapi/lib/ITrack.java index b3756a4..3221b95 100644 --- a/src/main/java/trackapi/lib/ITrack.java +++ b/src/main/java/trackapi/lib/ITrack.java @@ -12,7 +12,7 @@ public interface ITrack { double getTrackGauge(); /** - * Used by rolling stocks to look up their next position (and related data). + * Used by rolling stocks to look up their next position. * * @param currentPosition Current position of entity or bogey * @param motion Current velocity of entity or bogey diff --git a/src/main/java/trackapi/lib/ITrackV2.java b/src/main/java/trackapi/lib/ITrackV2.java index 58f91c4..1a3a92f 100644 --- a/src/main/java/trackapi/lib/ITrackV2.java +++ b/src/main/java/trackapi/lib/ITrackV2.java @@ -12,14 +12,13 @@ public interface ITrackV2 extends ITrack { double[] getTrackGauges(); /** - * Find next position and related data - * @param currentPosition Current entity or bogey position + * Used by rolling stocks to look up their next position and related data + * @param inputData WheelData contains required input parameters like current position and roll * @param motion Current velocity of entity or bogey * @param gauge Gauge of the pathing stock - * @param inputCtx The object contains other required input parameters - * @return PathingContext + * @return WheelData contains required output data for stock */ - PathingContext getNextPosition(Vec3 currentPosition, Vec3 motion, double gauge, PathingContext inputCtx); + WheelData getNextPosition(WheelData inputData, Vec3 motion, double gauge); //Overrides for forward compatibility, don't use @Override @@ -31,8 +30,7 @@ default double getTrackGauge() { @Override @Deprecated default Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { - PathingContext ctx = new PathingContext(currentPosition, 0d); - getNextPosition(new Vec3(currentPosition), new Vec3(motion), getTrackGauge(), ctx); - return ctx.nextPos.toVanilla(); + WheelData ctx = new WheelData(currentPosition, 0d); + return getNextPosition(ctx, new Vec3(motion), getTrackGauge()).position.toVanilla(); } } diff --git a/src/main/java/trackapi/lib/Vec3.java b/src/main/java/trackapi/lib/Vec3.java index 07bc3c7..236d427 100644 --- a/src/main/java/trackapi/lib/Vec3.java +++ b/src/main/java/trackapi/lib/Vec3.java @@ -54,6 +54,10 @@ public double lengthSquared() { return x * x + y * y + z * z; } + public Double distanceTo(Vec3 other) { + return Math.sqrt((x - other.x) * (x - other.x) + (y - other.y) * (y - other.y) + (z - other.z) * (z - other.z)); + } + public Vec3d toVanilla() { return new Vec3d(this.x, this.y, this.z); } diff --git a/src/main/java/trackapi/lib/PathingContext.java b/src/main/java/trackapi/lib/WheelData.java similarity index 58% rename from src/main/java/trackapi/lib/PathingContext.java rename to src/main/java/trackapi/lib/WheelData.java index ac9ed17..20f3f70 100644 --- a/src/main/java/trackapi/lib/PathingContext.java +++ b/src/main/java/trackapi/lib/WheelData.java @@ -12,71 +12,77 @@ *

* Users could define associated data to pass from track to stock */ -public final class PathingContext { +public final class WheelData { //We have next found pos and roll by default - public final Vec3 nextPos; + public final Vec3 position; public final double roll; - private final Map, Object> extension; + private final Map, Object> extension; //And some common fields //Moved distance between current pos and next pos - public static final TrackData DELTA_MOVEMENT = createOrGetKey("deltaMovement", Double.class); + public static final Key DELTA_MOVEMENT = createOrGetKey("deltaMovement", Double.class); + public static final Key DELTA_ROLL = createOrGetKey("deltaRoll", Double.class); //Wrapper for vanilla Vec3d - public PathingContext(Vec3d nextPos, double roll) { - this(new Vec3(nextPos), roll); + public WheelData(Vec3d position, double roll) { + this(new Vec3(position), roll); } - public PathingContext(Vec3 nextPos, double roll) { - this.nextPos = Objects.requireNonNull(nextPos, "nextPos cannot be null"); + public WheelData(Vec3 position, double roll) { + this.position = Objects.requireNonNull(position, "position cannot be null"); this.roll = roll; this.extension = new IdentityHashMap<>(); } - public PathingContext with(TrackData key, T value) { + public WheelData with(Key key, T value) { key.validate(value); extension.put(key, value); return this; } - public T get(TrackData key) { + public T get(Key key) { return key.type().cast(extension.get(key)); } - public void remove(TrackData key) { + public void remove(Key key) { extension.remove(key); } - public boolean containsKey(TrackData key) { + public boolean containsKey(Key key) { return extension.containsKey(key); } + public WheelData fromPrev(WheelData inputData) { + return this.with(DELTA_MOVEMENT, position.distanceTo(inputData.position)) + .with(DELTA_ROLL, roll - inputData.roll); + } + @SuppressWarnings("unchecked") - public static TrackData createOrGetKey(String name, Class type) { - TrackData existing = TrackData.registered.get(name); + public static Key createOrGetKey(String name, Class type) { + Key existing = Key.registered.get(name); if (existing != null) { if (!existing.type().equals(type)) { throw new IllegalStateException("Key '" + name + "' already registered with different type"); } - return (TrackData) existing; + return (Key) existing; } - TrackData data = new TrackData<>(name, type); - TrackData.registered.put(name, data); - return data; + Key key = new Key<>(name, type); + Key.registered.put(name, key); + return key; } /** - * Typed key for PathingContext's data storage + * Typed key for WheelData's data storage *

* Please note this is only used in IdentityHashMap, and should not be used externally * @param type of the value */ - public static class TrackData { - private static final Map> registered = new ConcurrentHashMap<>(); + public static class Key { + private static final Map> registered = new ConcurrentHashMap<>(); private final String name; private final Class type; - private TrackData(String name, Class type) { + private Key(String name, Class type) { this.name = Objects.requireNonNull(name); this.type = Objects.requireNonNull(type); } From bb874ddf9a2e21381aacbb3505bacb0febe1ceae Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Sun, 22 Feb 2026 14:46:29 +0800 Subject: [PATCH 07/16] ref: add Vec3 getter --- src/main/java/trackapi/lib/Util.java | 11 ++++++----- src/main/java/trackapi/lib/Vec3.java | 10 ++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/java/trackapi/lib/Util.java b/src/main/java/trackapi/lib/Util.java index 9d9ac42..94ab6cc 100644 --- a/src/main/java/trackapi/lib/Util.java +++ b/src/main/java/trackapi/lib/Util.java @@ -16,17 +16,18 @@ public class Util { * @return Potential ITrack, or null if failed to find a valid one */ - public static T findTrackBlocks(World world, Vec3d pos, boolean acceptMinecraftRails, Class type) { - T track = getInternalTileEntity(world, pos, acceptMinecraftRails, type); + public static T findTrackBlocks(World world, Vec3 pos, boolean acceptMinecraftRails, Class type) { + Vec3d vanilla = pos.toVanilla(); + T track = getInternalTileEntity(world, vanilla, acceptMinecraftRails, type); if (track != null) { return track; } // Allow a bit of vertical fuzziness - track = getInternalTileEntity(world, pos.add(0, 0.4, 0), acceptMinecraftRails, type); + track = getInternalTileEntity(world, vanilla.add(0, 0.4, 0), acceptMinecraftRails, type); if (track != null) { return track; } - track = getInternalTileEntity(world, pos.add(0, -0.4, 0), acceptMinecraftRails, type); + track = getInternalTileEntity(world, vanilla.add(0, -0.4, 0), acceptMinecraftRails, type); if (track != null) { return track; } @@ -36,7 +37,7 @@ public static T findTrackBlocks(World world, Vec3d pos, boole //Compatibility @Deprecated public static ITrack getTileEntity(World world, Vec3d pos, boolean acceptMinecraftRails) { - return findTrackBlocks(world, pos, acceptMinecraftRails, ITrack.class); + return findTrackBlocks(world, new Vec3(pos), acceptMinecraftRails, ITrack.class); } private static T getInternalTileEntity(final World world, Vec3d pos, boolean acceptMinecraftRails, Class type) { diff --git a/src/main/java/trackapi/lib/Vec3.java b/src/main/java/trackapi/lib/Vec3.java index 236d427..3d88301 100644 --- a/src/main/java/trackapi/lib/Vec3.java +++ b/src/main/java/trackapi/lib/Vec3.java @@ -58,6 +58,16 @@ public Double distanceTo(Vec3 other) { return Math.sqrt((x - other.x) * (x - other.x) + (y - other.y) * (y - other.y) + (z - other.z) * (z - other.z)); } + public double x() { + return x; + } + public double y() { + return y; + } + public double z() { + return z; + } + public Vec3d toVanilla() { return new Vec3d(this.x, this.y, this.z); } From 0e81f737eb06588bd9cc68b9bc2c46368122fa4f Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Sun, 22 Feb 2026 17:51:47 +0800 Subject: [PATCH 08/16] rename WheelData to PathingData --- src/main/java/trackapi/compat/MinecraftRail.java | 4 ++-- src/main/java/trackapi/lib/ITrackV2.java | 8 ++++---- .../lib/{WheelData.java => PathingData.java} | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) rename src/main/java/trackapi/lib/{WheelData.java => PathingData.java} (90%) diff --git a/src/main/java/trackapi/compat/MinecraftRail.java b/src/main/java/trackapi/compat/MinecraftRail.java index 2259a48..e146d19 100644 --- a/src/main/java/trackapi/compat/MinecraftRail.java +++ b/src/main/java/trackapi/compat/MinecraftRail.java @@ -64,7 +64,7 @@ public double[] getTrackGauges() { } @Override - public WheelData getNextPosition(WheelData inputData, Vec3 motion, double gauge) { + public PathingData getNextPosition(PathingData inputData, Vec3 motion, double gauge) { Vec3d currentPositionWrapped = inputData.position.toVanilla(); Vec3d motionWrapped = motion.toVanilla(); @@ -85,7 +85,7 @@ public WheelData getNextPosition(WheelData inputData, Vec3 motion, double gauge) newPosition = newPosition.add(trackMovement.scale(trackPosMotionInverted ? -distanceToCenter : distanceToCenter)); // Move new pos along track alignment newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motionWrapped.length() : motionWrapped.length())); - return new WheelData(newPosition, 0d).fromPrev(inputData); + return new PathingData(newPosition, 0d).fromPrev(inputData); } public static boolean isRail(World world, BlockPos pos) { diff --git a/src/main/java/trackapi/lib/ITrackV2.java b/src/main/java/trackapi/lib/ITrackV2.java index 1a3a92f..1c7a313 100644 --- a/src/main/java/trackapi/lib/ITrackV2.java +++ b/src/main/java/trackapi/lib/ITrackV2.java @@ -13,12 +13,12 @@ public interface ITrackV2 extends ITrack { /** * Used by rolling stocks to look up their next position and related data - * @param inputData WheelData contains required input parameters like current position and roll + * @param inputData PathingData contains required input parameters like current position and roll * @param motion Current velocity of entity or bogey * @param gauge Gauge of the pathing stock - * @return WheelData contains required output data for stock + * @return PathingData contains required output data for stock */ - WheelData getNextPosition(WheelData inputData, Vec3 motion, double gauge); + PathingData getNextPosition(PathingData inputData, Vec3 motion, double gauge); //Overrides for forward compatibility, don't use @Override @@ -30,7 +30,7 @@ default double getTrackGauge() { @Override @Deprecated default Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { - WheelData ctx = new WheelData(currentPosition, 0d); + PathingData ctx = new PathingData(currentPosition, 0d); return getNextPosition(ctx, new Vec3(motion), getTrackGauge()).position.toVanilla(); } } diff --git a/src/main/java/trackapi/lib/WheelData.java b/src/main/java/trackapi/lib/PathingData.java similarity index 90% rename from src/main/java/trackapi/lib/WheelData.java rename to src/main/java/trackapi/lib/PathingData.java index 20f3f70..ec5f1c8 100644 --- a/src/main/java/trackapi/lib/WheelData.java +++ b/src/main/java/trackapi/lib/PathingData.java @@ -12,7 +12,7 @@ *

* Users could define associated data to pass from track to stock */ -public final class WheelData { +public final class PathingData { //We have next found pos and roll by default public final Vec3 position; @@ -24,17 +24,17 @@ public final class WheelData { public static final Key DELTA_ROLL = createOrGetKey("deltaRoll", Double.class); //Wrapper for vanilla Vec3d - public WheelData(Vec3d position, double roll) { + public PathingData(Vec3d position, double roll) { this(new Vec3(position), roll); } - public WheelData(Vec3 position, double roll) { + public PathingData(Vec3 position, double roll) { this.position = Objects.requireNonNull(position, "position cannot be null"); this.roll = roll; this.extension = new IdentityHashMap<>(); } - public WheelData with(Key key, T value) { + public PathingData with(Key key, T value) { key.validate(value); extension.put(key, value); return this; @@ -52,7 +52,7 @@ public boolean containsKey(Key key) { return extension.containsKey(key); } - public WheelData fromPrev(WheelData inputData) { + public PathingData fromPrev(PathingData inputData) { return this.with(DELTA_MOVEMENT, position.distanceTo(inputData.position)) .with(DELTA_ROLL, roll - inputData.roll); } @@ -72,7 +72,7 @@ public static Key createOrGetKey(String name, Class type) { } /** - * Typed key for WheelData's data storage + * Typed key for PathingData's data storage *

* Please note this is only used in IdentityHashMap, and should not be used externally * @param type of the value From bb9f4d3a68de14d22105b6c220b910ad53cbe63f Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Sun, 22 Feb 2026 17:57:21 +0800 Subject: [PATCH 09/16] ref: add comment on roll --- src/main/java/trackapi/lib/PathingData.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/trackapi/lib/PathingData.java b/src/main/java/trackapi/lib/PathingData.java index ec5f1c8..1083b87 100644 --- a/src/main/java/trackapi/lib/PathingData.java +++ b/src/main/java/trackapi/lib/PathingData.java @@ -16,6 +16,7 @@ public final class PathingData { //We have next found pos and roll by default public final Vec3 position; + //Clockwise is positive when facing the direction of motion. public final double roll; private final Map, Object> extension; //And some common fields From 8ce4db98af0ac29dfdf1e45a3addb9df3992c1c0 Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Sun, 22 Feb 2026 18:06:07 +0800 Subject: [PATCH 10/16] ref: remove Vec3 as it may introduce more unnecessary calculation --- .../java/trackapi/compat/MinecraftRail.java | 13 ++-- src/main/java/trackapi/lib/ITrackV2.java | 4 +- src/main/java/trackapi/lib/PathingData.java | 6 +- src/main/java/trackapi/lib/Util.java | 11 ++- src/main/java/trackapi/lib/Vec3.java | 74 ------------------- 5 files changed, 14 insertions(+), 94 deletions(-) delete mode 100644 src/main/java/trackapi/lib/Vec3.java diff --git a/src/main/java/trackapi/compat/MinecraftRail.java b/src/main/java/trackapi/compat/MinecraftRail.java index e146d19..0e11ec2 100644 --- a/src/main/java/trackapi/compat/MinecraftRail.java +++ b/src/main/java/trackapi/compat/MinecraftRail.java @@ -64,27 +64,26 @@ public double[] getTrackGauges() { } @Override - public PathingData getNextPosition(PathingData inputData, Vec3 motion, double gauge) { - Vec3d currentPositionWrapped = inputData.position.toVanilla(); - Vec3d motionWrapped = motion.toVanilla(); + public PathingData getNextPosition(PathingData inputData, Vec3d motion, double gauge) { + Vec3d currentPosition = inputData.position; - Vec3d trackMovement = vectors.get(direction); + Vec3d trackMovement = vectors.get(direction); Vec3d trackCenter = centers.get(direction); Vec3d pos = new Vec3d(this.pos).add(trackCenter); - Vec3d posRelativeToCenter = currentPositionWrapped.subtractReverse(pos); + Vec3d posRelativeToCenter = currentPosition.subtractReverse(pos); double distanceToCenter = posRelativeToCenter.length(); // Determine if trackMovement should be positive or negative as relative to block center boolean trackPosMotionInverted = posRelativeToCenter.distanceTo(trackMovement) < posRelativeToCenter.scale(-1).distanceTo(trackMovement); - boolean trackMotionInverted = motionWrapped.distanceTo(trackMovement) > motionWrapped.scale(-1).distanceTo(trackMovement); + boolean trackMotionInverted = motion.distanceTo(trackMovement) > motion.scale(-1).distanceTo(trackMovement); Vec3d newPosition = pos; //Correct new pos to track alignment newPosition = newPosition.add(trackMovement.scale(trackPosMotionInverted ? -distanceToCenter : distanceToCenter)); // Move new pos along track alignment - newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motionWrapped.length() : motionWrapped.length())); + newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motion.length() : motion.length())); return new PathingData(newPosition, 0d).fromPrev(inputData); } diff --git a/src/main/java/trackapi/lib/ITrackV2.java b/src/main/java/trackapi/lib/ITrackV2.java index 1c7a313..2f510b1 100644 --- a/src/main/java/trackapi/lib/ITrackV2.java +++ b/src/main/java/trackapi/lib/ITrackV2.java @@ -18,7 +18,7 @@ public interface ITrackV2 extends ITrack { * @param gauge Gauge of the pathing stock * @return PathingData contains required output data for stock */ - PathingData getNextPosition(PathingData inputData, Vec3 motion, double gauge); + PathingData getNextPosition(PathingData inputData, Vec3d motion, double gauge); //Overrides for forward compatibility, don't use @Override @@ -31,6 +31,6 @@ default double getTrackGauge() { @Deprecated default Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { PathingData ctx = new PathingData(currentPosition, 0d); - return getNextPosition(ctx, new Vec3(motion), getTrackGauge()).position.toVanilla(); + return getNextPosition(ctx, motion, getTrackGauge()).position; } } diff --git a/src/main/java/trackapi/lib/PathingData.java b/src/main/java/trackapi/lib/PathingData.java index 1083b87..f820888 100644 --- a/src/main/java/trackapi/lib/PathingData.java +++ b/src/main/java/trackapi/lib/PathingData.java @@ -15,7 +15,7 @@ public final class PathingData { //We have next found pos and roll by default - public final Vec3 position; + public final Vec3d position; //Clockwise is positive when facing the direction of motion. public final double roll; private final Map, Object> extension; @@ -26,10 +26,6 @@ public final class PathingData { //Wrapper for vanilla Vec3d public PathingData(Vec3d position, double roll) { - this(new Vec3(position), roll); - } - - public PathingData(Vec3 position, double roll) { this.position = Objects.requireNonNull(position, "position cannot be null"); this.roll = roll; this.extension = new IdentityHashMap<>(); diff --git a/src/main/java/trackapi/lib/Util.java b/src/main/java/trackapi/lib/Util.java index 94ab6cc..9d9ac42 100644 --- a/src/main/java/trackapi/lib/Util.java +++ b/src/main/java/trackapi/lib/Util.java @@ -16,18 +16,17 @@ public class Util { * @return Potential ITrack, or null if failed to find a valid one */ - public static T findTrackBlocks(World world, Vec3 pos, boolean acceptMinecraftRails, Class type) { - Vec3d vanilla = pos.toVanilla(); - T track = getInternalTileEntity(world, vanilla, acceptMinecraftRails, type); + public static T findTrackBlocks(World world, Vec3d pos, boolean acceptMinecraftRails, Class type) { + T track = getInternalTileEntity(world, pos, acceptMinecraftRails, type); if (track != null) { return track; } // Allow a bit of vertical fuzziness - track = getInternalTileEntity(world, vanilla.add(0, 0.4, 0), acceptMinecraftRails, type); + track = getInternalTileEntity(world, pos.add(0, 0.4, 0), acceptMinecraftRails, type); if (track != null) { return track; } - track = getInternalTileEntity(world, vanilla.add(0, -0.4, 0), acceptMinecraftRails, type); + track = getInternalTileEntity(world, pos.add(0, -0.4, 0), acceptMinecraftRails, type); if (track != null) { return track; } @@ -37,7 +36,7 @@ public static T findTrackBlocks(World world, Vec3 pos, boolea //Compatibility @Deprecated public static ITrack getTileEntity(World world, Vec3d pos, boolean acceptMinecraftRails) { - return findTrackBlocks(world, new Vec3(pos), acceptMinecraftRails, ITrack.class); + return findTrackBlocks(world, pos, acceptMinecraftRails, ITrack.class); } private static T getInternalTileEntity(final World world, Vec3d pos, boolean acceptMinecraftRails, Class type) { diff --git a/src/main/java/trackapi/lib/Vec3.java b/src/main/java/trackapi/lib/Vec3.java deleted file mode 100644 index 3d88301..0000000 --- a/src/main/java/trackapi/lib/Vec3.java +++ /dev/null @@ -1,74 +0,0 @@ -package trackapi.lib; - -import net.minecraft.util.math.Vec3d; - -/** - * A simple vanilla Vec3d wrapper for universality, mutable - */ -public class Vec3 { - private double x; - private double y; - private double z; - - public Vec3(Vec3d vec3d) { - this(vec3d.x, vec3d.y, vec3d.z); - } - - public Vec3(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - - public Vec3 add(Vec3 vec3) { - this.x += vec3.x; - this.y += vec3.y; - this.z += vec3.z; - return this; - } - - public Vec3 subtract(Vec3 vec3) { - this.x -= vec3.x; - this.y -= vec3.y; - this.z -= vec3.z; - return this; - } - - public Vec3 scale(double factor) { - this.x *= factor; - this.y *= factor; - this.z *= factor; - return this; - } - - public Vec3 normalize() { - double length = this.length(); - return scale(1 / length); - } - - public double length() { - return Math.sqrt(this.lengthSquared()); - } - - public double lengthSquared() { - return x * x + y * y + z * z; - } - - public Double distanceTo(Vec3 other) { - return Math.sqrt((x - other.x) * (x - other.x) + (y - other.y) * (y - other.y) + (z - other.z) * (z - other.z)); - } - - public double x() { - return x; - } - public double y() { - return y; - } - public double z() { - return z; - } - - public Vec3d toVanilla() { - return new Vec3d(this.x, this.y, this.z); - } -} From f6213da7fa0039a8b7fcbec51dec93f8c70e05e0 Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Sun, 22 Feb 2026 21:33:59 +0800 Subject: [PATCH 11/16] remove final on PathingData --- src/main/java/trackapi/lib/PathingData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/trackapi/lib/PathingData.java b/src/main/java/trackapi/lib/PathingData.java index f820888..c7b29ef 100644 --- a/src/main/java/trackapi/lib/PathingData.java +++ b/src/main/java/trackapi/lib/PathingData.java @@ -12,7 +12,7 @@ *

* Users could define associated data to pass from track to stock */ -public final class PathingData { +public class PathingData { //We have next found pos and roll by default public final Vec3d position; From b39d7d2c11aea20867ded60ceaec27e0db1bddf0 Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Sun, 22 Feb 2026 21:37:38 +0800 Subject: [PATCH 12/16] change visibility of PathingData.position & roll --- src/main/java/trackapi/compat/MinecraftRail.java | 2 +- src/main/java/trackapi/lib/ITrackV2.java | 2 +- src/main/java/trackapi/lib/PathingData.java | 12 ++++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/trackapi/compat/MinecraftRail.java b/src/main/java/trackapi/compat/MinecraftRail.java index 0e11ec2..510e0f9 100644 --- a/src/main/java/trackapi/compat/MinecraftRail.java +++ b/src/main/java/trackapi/compat/MinecraftRail.java @@ -65,7 +65,7 @@ public double[] getTrackGauges() { @Override public PathingData getNextPosition(PathingData inputData, Vec3d motion, double gauge) { - Vec3d currentPosition = inputData.position; + Vec3d currentPosition = inputData.getPosition(); Vec3d trackMovement = vectors.get(direction); Vec3d trackCenter = centers.get(direction); diff --git a/src/main/java/trackapi/lib/ITrackV2.java b/src/main/java/trackapi/lib/ITrackV2.java index 2f510b1..c2891df 100644 --- a/src/main/java/trackapi/lib/ITrackV2.java +++ b/src/main/java/trackapi/lib/ITrackV2.java @@ -31,6 +31,6 @@ default double getTrackGauge() { @Deprecated default Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { PathingData ctx = new PathingData(currentPosition, 0d); - return getNextPosition(ctx, motion, getTrackGauge()).position; + return getNextPosition(ctx, motion, getTrackGauge()).getPosition(); } } diff --git a/src/main/java/trackapi/lib/PathingData.java b/src/main/java/trackapi/lib/PathingData.java index c7b29ef..2d36419 100644 --- a/src/main/java/trackapi/lib/PathingData.java +++ b/src/main/java/trackapi/lib/PathingData.java @@ -15,9 +15,9 @@ public class PathingData { //We have next found pos and roll by default - public final Vec3d position; + private final Vec3d position; //Clockwise is positive when facing the direction of motion. - public final double roll; + private final double roll; private final Map, Object> extension; //And some common fields //Moved distance between current pos and next pos @@ -37,6 +37,14 @@ public PathingData with(Key key, T value) { return this; } + public Vec3d getPosition() { + return position; + } + + public double getRoll() { + return roll; + } + public T get(Key key) { return key.type().cast(extension.get(key)); } From 6d38fd19b054f1f4b96dbe712db87b8b0eddcc1a Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Sun, 22 Feb 2026 22:06:22 +0800 Subject: [PATCH 13/16] Revert "ref: remove Vec3 as it may introduce more unnecessary calculation" --- .../java/trackapi/compat/MinecraftRail.java | 13 ++++++----- src/main/java/trackapi/lib/ITrackV2.java | 4 ++-- src/main/java/trackapi/lib/PathingData.java | 18 ++++++--------- src/main/java/trackapi/lib/Util.java | 11 +++++----- src/main/java/trackapi/lib/Vec3.java | 22 +++++++++++++++++++ 5 files changed, 44 insertions(+), 24 deletions(-) create mode 100644 src/main/java/trackapi/lib/Vec3.java diff --git a/src/main/java/trackapi/compat/MinecraftRail.java b/src/main/java/trackapi/compat/MinecraftRail.java index 510e0f9..e146d19 100644 --- a/src/main/java/trackapi/compat/MinecraftRail.java +++ b/src/main/java/trackapi/compat/MinecraftRail.java @@ -64,26 +64,27 @@ public double[] getTrackGauges() { } @Override - public PathingData getNextPosition(PathingData inputData, Vec3d motion, double gauge) { - Vec3d currentPosition = inputData.getPosition(); + public PathingData getNextPosition(PathingData inputData, Vec3 motion, double gauge) { + Vec3d currentPositionWrapped = inputData.position.toVanilla(); + Vec3d motionWrapped = motion.toVanilla(); - Vec3d trackMovement = vectors.get(direction); + Vec3d trackMovement = vectors.get(direction); Vec3d trackCenter = centers.get(direction); Vec3d pos = new Vec3d(this.pos).add(trackCenter); - Vec3d posRelativeToCenter = currentPosition.subtractReverse(pos); + Vec3d posRelativeToCenter = currentPositionWrapped.subtractReverse(pos); double distanceToCenter = posRelativeToCenter.length(); // Determine if trackMovement should be positive or negative as relative to block center boolean trackPosMotionInverted = posRelativeToCenter.distanceTo(trackMovement) < posRelativeToCenter.scale(-1).distanceTo(trackMovement); - boolean trackMotionInverted = motion.distanceTo(trackMovement) > motion.scale(-1).distanceTo(trackMovement); + boolean trackMotionInverted = motionWrapped.distanceTo(trackMovement) > motionWrapped.scale(-1).distanceTo(trackMovement); Vec3d newPosition = pos; //Correct new pos to track alignment newPosition = newPosition.add(trackMovement.scale(trackPosMotionInverted ? -distanceToCenter : distanceToCenter)); // Move new pos along track alignment - newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motion.length() : motion.length())); + newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motionWrapped.length() : motionWrapped.length())); return new PathingData(newPosition, 0d).fromPrev(inputData); } diff --git a/src/main/java/trackapi/lib/ITrackV2.java b/src/main/java/trackapi/lib/ITrackV2.java index c2891df..1c7a313 100644 --- a/src/main/java/trackapi/lib/ITrackV2.java +++ b/src/main/java/trackapi/lib/ITrackV2.java @@ -18,7 +18,7 @@ public interface ITrackV2 extends ITrack { * @param gauge Gauge of the pathing stock * @return PathingData contains required output data for stock */ - PathingData getNextPosition(PathingData inputData, Vec3d motion, double gauge); + PathingData getNextPosition(PathingData inputData, Vec3 motion, double gauge); //Overrides for forward compatibility, don't use @Override @@ -31,6 +31,6 @@ default double getTrackGauge() { @Deprecated default Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { PathingData ctx = new PathingData(currentPosition, 0d); - return getNextPosition(ctx, motion, getTrackGauge()).getPosition(); + return getNextPosition(ctx, new Vec3(motion), getTrackGauge()).position.toVanilla(); } } diff --git a/src/main/java/trackapi/lib/PathingData.java b/src/main/java/trackapi/lib/PathingData.java index 2d36419..790e18e 100644 --- a/src/main/java/trackapi/lib/PathingData.java +++ b/src/main/java/trackapi/lib/PathingData.java @@ -15,9 +15,9 @@ public class PathingData { //We have next found pos and roll by default - private final Vec3d position; + public final Vec3 position; //Clockwise is positive when facing the direction of motion. - private final double roll; + public final double roll; private final Map, Object> extension; //And some common fields //Moved distance between current pos and next pos @@ -26,6 +26,10 @@ public class PathingData { //Wrapper for vanilla Vec3d public PathingData(Vec3d position, double roll) { + this(new Vec3(position), roll); + } + + public PathingData(Vec3 position, double roll) { this.position = Objects.requireNonNull(position, "position cannot be null"); this.roll = roll; this.extension = new IdentityHashMap<>(); @@ -37,14 +41,6 @@ public PathingData with(Key key, T value) { return this; } - public Vec3d getPosition() { - return position; - } - - public double getRoll() { - return roll; - } - public T get(Key key) { return key.type().cast(extension.get(key)); } @@ -58,7 +54,7 @@ public boolean containsKey(Key key) { } public PathingData fromPrev(PathingData inputData) { - return this.with(DELTA_MOVEMENT, position.distanceTo(inputData.position)) + return this.with(DELTA_MOVEMENT, position.toVanilla().distanceTo(inputData.position.toVanilla())) .with(DELTA_ROLL, roll - inputData.roll); } diff --git a/src/main/java/trackapi/lib/Util.java b/src/main/java/trackapi/lib/Util.java index 9d9ac42..94ab6cc 100644 --- a/src/main/java/trackapi/lib/Util.java +++ b/src/main/java/trackapi/lib/Util.java @@ -16,17 +16,18 @@ public class Util { * @return Potential ITrack, or null if failed to find a valid one */ - public static T findTrackBlocks(World world, Vec3d pos, boolean acceptMinecraftRails, Class type) { - T track = getInternalTileEntity(world, pos, acceptMinecraftRails, type); + public static T findTrackBlocks(World world, Vec3 pos, boolean acceptMinecraftRails, Class type) { + Vec3d vanilla = pos.toVanilla(); + T track = getInternalTileEntity(world, vanilla, acceptMinecraftRails, type); if (track != null) { return track; } // Allow a bit of vertical fuzziness - track = getInternalTileEntity(world, pos.add(0, 0.4, 0), acceptMinecraftRails, type); + track = getInternalTileEntity(world, vanilla.add(0, 0.4, 0), acceptMinecraftRails, type); if (track != null) { return track; } - track = getInternalTileEntity(world, pos.add(0, -0.4, 0), acceptMinecraftRails, type); + track = getInternalTileEntity(world, vanilla.add(0, -0.4, 0), acceptMinecraftRails, type); if (track != null) { return track; } @@ -36,7 +37,7 @@ public static T findTrackBlocks(World world, Vec3d pos, boole //Compatibility @Deprecated public static ITrack getTileEntity(World world, Vec3d pos, boolean acceptMinecraftRails) { - return findTrackBlocks(world, pos, acceptMinecraftRails, ITrack.class); + return findTrackBlocks(world, new Vec3(pos), acceptMinecraftRails, ITrack.class); } private static T getInternalTileEntity(final World world, Vec3d pos, boolean acceptMinecraftRails, Class type) { diff --git a/src/main/java/trackapi/lib/Vec3.java b/src/main/java/trackapi/lib/Vec3.java new file mode 100644 index 0000000..5913526 --- /dev/null +++ b/src/main/java/trackapi/lib/Vec3.java @@ -0,0 +1,22 @@ +package trackapi.lib; + +import net.minecraft.util.math.Vec3d; + +/** + * A simple vanilla Vec3d wrapper for universality + */ +public class Vec3 { + private final Vec3d internal; + + public Vec3(double x, double y, double z) { + this(new Vec3d(x, y, z)); + } + + public Vec3(Vec3d vec3d) { + this.internal = vec3d; + } + + public Vec3d toVanilla() { + return internal; + } +} From ff8b3aa98e7136c93bfd06d7179a1cf7ded62b54 Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Wed, 25 Feb 2026 10:54:02 +0800 Subject: [PATCH 14/16] ref: reconstruct PathingData --- .../java/trackapi/compat/MinecraftRail.java | 16 +-- src/main/java/trackapi/lib/ITrackV2.java | 14 ++- src/main/java/trackapi/lib/PathingData.java | 105 +++--------------- src/main/java/trackapi/lib/Util.java | 11 +- src/main/java/trackapi/lib/Vec3.java | 22 ---- 5 files changed, 39 insertions(+), 129 deletions(-) delete mode 100644 src/main/java/trackapi/lib/Vec3.java diff --git a/src/main/java/trackapi/compat/MinecraftRail.java b/src/main/java/trackapi/compat/MinecraftRail.java index e146d19..1f143e8 100644 --- a/src/main/java/trackapi/compat/MinecraftRail.java +++ b/src/main/java/trackapi/compat/MinecraftRail.java @@ -64,28 +64,28 @@ public double[] getTrackGauges() { } @Override - public PathingData getNextPosition(PathingData inputData, Vec3 motion, double gauge) { - Vec3d currentPositionWrapped = inputData.position.toVanilla(); - Vec3d motionWrapped = motion.toVanilla(); + public boolean getNextPosition(PathingData inputData, Vec3d motion, double gauge) { + Vec3d currentPosition = inputData.getVanillaPos(); - Vec3d trackMovement = vectors.get(direction); + Vec3d trackMovement = vectors.get(direction); Vec3d trackCenter = centers.get(direction); Vec3d pos = new Vec3d(this.pos).add(trackCenter); - Vec3d posRelativeToCenter = currentPositionWrapped.subtractReverse(pos); + Vec3d posRelativeToCenter = currentPosition.subtractReverse(pos); double distanceToCenter = posRelativeToCenter.length(); // Determine if trackMovement should be positive or negative as relative to block center boolean trackPosMotionInverted = posRelativeToCenter.distanceTo(trackMovement) < posRelativeToCenter.scale(-1).distanceTo(trackMovement); - boolean trackMotionInverted = motionWrapped.distanceTo(trackMovement) > motionWrapped.scale(-1).distanceTo(trackMovement); + boolean trackMotionInverted = motion.distanceTo(trackMovement) > motion.scale(-1).distanceTo(trackMovement); Vec3d newPosition = pos; //Correct new pos to track alignment newPosition = newPosition.add(trackMovement.scale(trackPosMotionInverted ? -distanceToCenter : distanceToCenter)); // Move new pos along track alignment - newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motionWrapped.length() : motionWrapped.length())); - return new PathingData(newPosition, 0d).fromPrev(inputData); + newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motion.length() : motion.length())); + inputData.setVanillaPosition(newPosition).setRoll(0d); + return newPosition.squareDistanceTo(currentPosition) > 1E-8; } public static boolean isRail(World world, BlockPos pos) { diff --git a/src/main/java/trackapi/lib/ITrackV2.java b/src/main/java/trackapi/lib/ITrackV2.java index 1c7a313..9ed2618 100644 --- a/src/main/java/trackapi/lib/ITrackV2.java +++ b/src/main/java/trackapi/lib/ITrackV2.java @@ -13,12 +13,12 @@ public interface ITrackV2 extends ITrack { /** * Used by rolling stocks to look up their next position and related data - * @param inputData PathingData contains required input parameters like current position and roll + * @param inputData Mutable PathingData contains input parameters, like position and roll, and will be overridden with output data * @param motion Current velocity of entity or bogey * @param gauge Gauge of the pathing stock - * @return PathingData contains required output data for stock + * @return True if inputData is successfully overridden, false if cannot find next path */ - PathingData getNextPosition(PathingData inputData, Vec3 motion, double gauge); + boolean getNextPosition(D inputData, Vec3d motion, double gauge); //Overrides for forward compatibility, don't use @Override @@ -30,7 +30,11 @@ default double getTrackGauge() { @Override @Deprecated default Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { - PathingData ctx = new PathingData(currentPosition, 0d); - return getNextPosition(ctx, new Vec3(motion), getTrackGauge()).position.toVanilla(); + //Create another PathingData impl may confuse user and that action is discouraged, so don't process V1 logic in V2 + PathingData data = new PathingData(currentPosition, 0d); + if (getNextPosition(data, motion, getTrackGauge())) { + return data.getVanillaPos(); + } + return currentPosition; } } diff --git a/src/main/java/trackapi/lib/PathingData.java b/src/main/java/trackapi/lib/PathingData.java index 790e18e..872dffa 100644 --- a/src/main/java/trackapi/lib/PathingData.java +++ b/src/main/java/trackapi/lib/PathingData.java @@ -2,105 +2,34 @@ import net.minecraft.util.math.Vec3d; -import java.util.IdentityHashMap; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; - /** - * Helper class for transferring bundled pathing data - *

- * Users could define associated data to pass from track to stock + * Mutable data storaging object used by stocks to query data */ public class PathingData { + //Reserve position/pos name for mods that may not use MC's Vec3d + private Vec3d vanillaPosition; + private double roll; - //We have next found pos and roll by default - public final Vec3 position; - //Clockwise is positive when facing the direction of motion. - public final double roll; - private final Map, Object> extension; - //And some common fields - //Moved distance between current pos and next pos - public static final Key DELTA_MOVEMENT = createOrGetKey("deltaMovement", Double.class); - public static final Key DELTA_ROLL = createOrGetKey("deltaRoll", Double.class); - - //Wrapper for vanilla Vec3d - public PathingData(Vec3d position, double roll) { - this(new Vec3(position), roll); - } - - public PathingData(Vec3 position, double roll) { - this.position = Objects.requireNonNull(position, "position cannot be null"); + public PathingData(Vec3d vanillaPosition, double roll) { + this.vanillaPosition = vanillaPosition; this.roll = roll; - this.extension = new IdentityHashMap<>(); - } - - public PathingData with(Key key, T value) { - key.validate(value); - extension.put(key, value); - return this; - } - - public T get(Key key) { - return key.type().cast(extension.get(key)); } - public void remove(Key key) { - extension.remove(key); + public Vec3d getVanillaPos() { + return vanillaPosition; } - public boolean containsKey(Key key) { - return extension.containsKey(key); - } - - public PathingData fromPrev(PathingData inputData) { - return this.with(DELTA_MOVEMENT, position.toVanilla().distanceTo(inputData.position.toVanilla())) - .with(DELTA_ROLL, roll - inputData.roll); + public PathingData setVanillaPosition(Vec3d vanillaPosition) { + this.vanillaPosition = vanillaPosition; + return this; } - @SuppressWarnings("unchecked") - public static Key createOrGetKey(String name, Class type) { - Key existing = Key.registered.get(name); - if (existing != null) { - if (!existing.type().equals(type)) { - throw new IllegalStateException("Key '" + name + "' already registered with different type"); - } - return (Key) existing; - } - Key key = new Key<>(name, type); - Key.registered.put(name, key); - return key; + public double getRoll() { + return roll; } - /** - * Typed key for PathingData's data storage - *

- * Please note this is only used in IdentityHashMap, and should not be used externally - * @param type of the value - */ - public static class Key { - private static final Map> registered = new ConcurrentHashMap<>(); - private final String name; - private final Class type; - - private Key(String name, Class type) { - this.name = Objects.requireNonNull(name); - this.type = Objects.requireNonNull(type); - } - - void validate(Object value) { - if (value != null && !type.isInstance(value)) { - throw new IllegalArgumentException("Invalid value for key '" + name + "', expected " + type.getSimpleName()); - } - } - - public Class type() { - return type; - } - - @Override - public String toString() { - return "[Name:" + name + ",Type:" + type.getName() + "]"; - } + public PathingData setRoll(double roll) { + this.roll = roll; + return this; } -} \ No newline at end of file +} diff --git a/src/main/java/trackapi/lib/Util.java b/src/main/java/trackapi/lib/Util.java index 94ab6cc..e5e65bd 100644 --- a/src/main/java/trackapi/lib/Util.java +++ b/src/main/java/trackapi/lib/Util.java @@ -16,18 +16,17 @@ public class Util { * @return Potential ITrack, or null if failed to find a valid one */ - public static T findTrackBlocks(World world, Vec3 pos, boolean acceptMinecraftRails, Class type) { - Vec3d vanilla = pos.toVanilla(); - T track = getInternalTileEntity(world, vanilla, acceptMinecraftRails, type); + public static T findTrackBlocks(World world, Vec3d pos, boolean acceptMinecraftRails, Class type) { + T track = getInternalTileEntity(world, pos, acceptMinecraftRails, type); if (track != null) { return track; } // Allow a bit of vertical fuzziness - track = getInternalTileEntity(world, vanilla.add(0, 0.4, 0), acceptMinecraftRails, type); + track = getInternalTileEntity(world, pos.add(0, 0.4, 0), acceptMinecraftRails, type); if (track != null) { return track; } - track = getInternalTileEntity(world, vanilla.add(0, -0.4, 0), acceptMinecraftRails, type); + track = getInternalTileEntity(world, pos.add(0, -0.4, 0), acceptMinecraftRails, type); if (track != null) { return track; } @@ -37,7 +36,7 @@ public static T findTrackBlocks(World world, Vec3 pos, boolea //Compatibility @Deprecated public static ITrack getTileEntity(World world, Vec3d pos, boolean acceptMinecraftRails) { - return findTrackBlocks(world, new Vec3(pos), acceptMinecraftRails, ITrack.class); + return findTrackBlocks(world, pos, acceptMinecraftRails, ITrack.class); } private static T getInternalTileEntity(final World world, Vec3d pos, boolean acceptMinecraftRails, Class type) { diff --git a/src/main/java/trackapi/lib/Vec3.java b/src/main/java/trackapi/lib/Vec3.java deleted file mode 100644 index 5913526..0000000 --- a/src/main/java/trackapi/lib/Vec3.java +++ /dev/null @@ -1,22 +0,0 @@ -package trackapi.lib; - -import net.minecraft.util.math.Vec3d; - -/** - * A simple vanilla Vec3d wrapper for universality - */ -public class Vec3 { - private final Vec3d internal; - - public Vec3(double x, double y, double z) { - this(new Vec3d(x, y, z)); - } - - public Vec3(Vec3d vec3d) { - this.internal = vec3d; - } - - public Vec3d toVanilla() { - return internal; - } -} From 4cf6bb0009683d0603c31a4de7da85df6d65f069 Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Wed, 25 Feb 2026 14:18:09 +0800 Subject: [PATCH 15/16] ref: cleanup calculation --- .../java/trackapi/compat/MinecraftRail.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/trackapi/compat/MinecraftRail.java b/src/main/java/trackapi/compat/MinecraftRail.java index 1f143e8..29b5ca1 100644 --- a/src/main/java/trackapi/compat/MinecraftRail.java +++ b/src/main/java/trackapi/compat/MinecraftRail.java @@ -80,12 +80,18 @@ public boolean getNextPosition(PathingData inputData, Vec3d motion, double gauge boolean trackMotionInverted = motion.distanceTo(trackMovement) > motion.scale(-1).distanceTo(trackMovement); Vec3d newPosition = pos; - //Correct new pos to track alignment - newPosition = newPosition.add(trackMovement.scale(trackPosMotionInverted ? -distanceToCenter : distanceToCenter)); - // Move new pos along track alignment - newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motion.length() : motion.length())); - inputData.setVanillaPosition(newPosition).setRoll(0d); - return newPosition.squareDistanceTo(currentPosition) > 1E-8; + double factor = + //Correct new pos to track alignment + (trackPosMotionInverted ? -distanceToCenter : distanceToCenter) + // Move new pos along track alignment + + (trackMotionInverted ? -motion.length() : motion.length()); + if (Math.abs(factor) > 1E-4) { + //If it's significantly enough, update it + newPosition = newPosition.add(trackMovement.scale(factor)); + inputData.setVanillaPosition(newPosition).setRoll(0d); + return true; + } + return false; } public static boolean isRail(World world, BlockPos pos) { From 7b91a9ddfdf1aa79ec2ef0b1a42c9c881cc5ebd7 Mon Sep 17 00:00:00 2001 From: Goldenfield192 <1437356849@qq.com> Date: Wed, 25 Feb 2026 20:09:53 +0800 Subject: [PATCH 16/16] ref: rename --- src/main/java/trackapi/compat/MinecraftRail.java | 2 +- src/main/java/trackapi/lib/PathingData.java | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/trackapi/compat/MinecraftRail.java b/src/main/java/trackapi/compat/MinecraftRail.java index 29b5ca1..0af7761 100644 --- a/src/main/java/trackapi/compat/MinecraftRail.java +++ b/src/main/java/trackapi/compat/MinecraftRail.java @@ -88,7 +88,7 @@ public boolean getNextPosition(PathingData inputData, Vec3d motion, double gauge if (Math.abs(factor) > 1E-4) { //If it's significantly enough, update it newPosition = newPosition.add(trackMovement.scale(factor)); - inputData.setVanillaPosition(newPosition).setRoll(0d); + inputData.setVanillaPos(newPosition).setRoll(0d); return true; } return false; diff --git a/src/main/java/trackapi/lib/PathingData.java b/src/main/java/trackapi/lib/PathingData.java index 872dffa..4e386cf 100644 --- a/src/main/java/trackapi/lib/PathingData.java +++ b/src/main/java/trackapi/lib/PathingData.java @@ -7,20 +7,20 @@ */ public class PathingData { //Reserve position/pos name for mods that may not use MC's Vec3d - private Vec3d vanillaPosition; + private Vec3d vanillaPos; private double roll; - public PathingData(Vec3d vanillaPosition, double roll) { - this.vanillaPosition = vanillaPosition; + public PathingData(Vec3d vanillaPos, double roll) { + this.vanillaPos = vanillaPos; this.roll = roll; } public Vec3d getVanillaPos() { - return vanillaPosition; + return vanillaPos; } - public PathingData setVanillaPosition(Vec3d vanillaPosition) { - this.vanillaPosition = vanillaPosition; + public PathingData setVanillaPos(Vec3d vanillaPos) { + this.vanillaPos = vanillaPos; return this; }