diff --git a/build.gradle b/build.gradle index 1db0c5c..df7a3b0 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 { @@ -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() } @@ -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/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"; } diff --git a/src/main/java/trackapi/compat/MinecraftRail.java b/src/main/java/trackapi/compat/MinecraftRail.java index f691143..5089575 100644 --- a/src/main/java/trackapi/compat/MinecraftRail.java +++ b/src/main/java/trackapi/compat/MinecraftRail.java @@ -8,13 +8,17 @@ import net.minecraft.world.World; import trackapi.lib.Gauges; import trackapi.lib.ITrack; +import trackapi.lib.PathingContext; import java.util.HashMap; import java.util.Map; +/** + * Wrapper for vanilla rail + */ public class MinecraftRail implements ITrack { - 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); @@ -62,12 +66,12 @@ public double getTrackGauge() { } @Override - public Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { + public PathingContext getNextPosition(Vec3d currentPosition, Vec3d motion) { Vec3d trackMovement = vectors.get(direction); 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,8 +82,8 @@ 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())); - return newPosition; + newPosition = newPosition.add(trackMovement.scale(trackMotionInverted ? -motion.length() : motion.length())); + return new PathingContext(newPosition).with(PathingContext.DELTA_MOVEMENT, newPosition.distanceTo(currentPosition)); } public static boolean isRail(World world, BlockPos pos) { 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; } diff --git a/src/main/java/trackapi/lib/ITrack.java b/src/main/java/trackapi/lib/ITrack.java index ca2362f..2054c6d 100644 --- a/src/main/java/trackapi/lib/ITrack.java +++ b/src/main/java/trackapi/lib/ITrack.java @@ -7,19 +7,16 @@ public interface ITrack { /** * The distance between the rails measured in meters * - * @see Gauges#STANDARD - * @see Gauges#MINECRAFT + * @see Gauges */ - public double getTrackGauge(); + 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 - * @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 + * @param currentPosition - Current position of entity or bogey + * @param motion Current velocity of entity or bogey + * @return PathingContext object contains related data regarding next found point */ - public Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion); + PathingContext 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..4f4d727 100644 --- a/src/main/java/trackapi/lib/ITrackBlock.java +++ b/src/main/java/trackapi/lib/ITrackBlock.java @@ -5,27 +5,25 @@ import net.minecraft.world.World; /** - * Compatibility layer for block only tracks - * + * Compatibility layer between ITrack and blocks which only contain tracks */ public interface ITrackBlock { /** * The distance between the rails measured in meters * - * @see Gauges#STANDARD - * @see Gauges#MINECRAFT + * @see Gauges */ - public double getTrackGauge(World world, BlockPos pos); + double getTrackGauge(World world, BlockPos pos); /** - * Used by rolling stock to look up their next position. - * + * 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 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 + * @param motion Current velocity of entity or bogey + * @return PathingContext object contains related data regarding next found point */ - public Vec3d getNextPosition(World world, BlockPos pos, Vec3d currentPosition, Vec3d motion); + PathingContext getNextPosition(World world, BlockPos pos, Vec3d currentPosition, Vec3d motion); } diff --git a/src/main/java/trackapi/lib/PathingContext.java b/src/main/java/trackapi/lib/PathingContext.java new file mode 100644 index 0000000..d9db5b8 --- /dev/null +++ b/src/main/java/trackapi/lib/PathingContext.java @@ -0,0 +1,117 @@ +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 static final Map> registered = new ConcurrentHashMap<>(); + + private final Map, Object> dataMap; + + //We have next found pos by default + public final Vec3d pos; + //And some built-in fields that are filled in + //Moved distance between current pos and next pos + public static final TrackData DELTA_MOVEMENT = createOrGetKey("delta_movement", Double.class, 0d); + //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("roll_degrees", Double.class, 0d); + + public PathingContext(Vec3d 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) { + Object value = dataMap.get(key); + if (value == null) { + return key.fallback(); + } + return key.type().cast(value); + } + + public void reset(TrackData key) { + dataMap.remove(key); + } + + //For those don't want to use Minecraft's Vec3d directly + public double x() { + return pos.x; + } + public double y() { + return pos.y; + } + public double z() { + return pos.z; + } + + public static TrackData createOrGetKey(String name, Class type) { + return createOrGetKey(name, type, null); + } + + @SuppressWarnings("unchecked") + public static TrackData createOrGetKey(String name, Class type, T fallback) { + TrackData existing = 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, fallback); + 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 final String name; + private final Class type; + private final T fallback; + + private TrackData(String name, Class type, T fallback) { + this.name = Objects.requireNonNull(name); + this.type = Objects.requireNonNull(type); + this.fallback = fallback; + } + + 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; + } + + public T fallback() { + return fallback; + } + + @Override + public String toString() { + return "[Name:" + name + ",Type:" + type.getName() + "]"; + } + } +} \ 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 63f2d4a..bd2b0bd 100644 --- a/src/main/java/trackapi/lib/Util.java +++ b/src/main/java/trackapi/lib/Util.java @@ -22,7 +22,7 @@ public double getTrackGauge() { return track.getTrackGauge(world, bp); } @Override - public Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { + public PathingContext getNextPosition(Vec3d currentPosition, Vec3d motion) { return track.getNextPosition(world, bp, currentPosition, motion); } }; @@ -39,18 +39,25 @@ public Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { } return null; } - + + /** + * 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 ITrack getTileEntity(World world, Vec3d pos, boolean acceptMinecraftRails) { ITrack track = getInternalTileEntity(world, pos, acceptMinecraftRails); if (track != null) { 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; }