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;
}