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..0af7761 100644 --- a/src/main/java/trackapi/compat/MinecraftRail.java +++ b/src/main/java/trackapi/compat/MinecraftRail.java @@ -6,15 +6,17 @@ 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 { - private static Map vectors = new HashMap<>(); - private static Map centers = new HashMap<>(); +/** + * Wrapper for vanilla rail + */ +public class MinecraftRail implements ITrackV2 { + 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); @@ -46,8 +48,8 @@ public class MinecraftRail implements ITrack { } - private EnumRailDirection direction; - private BlockPos pos; + private final EnumRailDirection direction; + private final BlockPos pos; public MinecraftRail(World world, BlockPos pos) { this.pos = pos; @@ -57,33 +59,42 @@ 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) { - Vec3d trackMovement = vectors.get(direction); + public boolean getNextPosition(PathingData inputData, Vec3d motion, double gauge) { + Vec3d currentPosition = inputData.getVanillaPos(); + + Vec3d trackMovement = vectors.get(direction); Vec3d trackCenter = centers.get(direction); - Vec3d posRelativeToCenter = currentPosition.subtractReverse(new Vec3d(pos).add(trackCenter)); - double distanceToCenter = posRelativeToCenter.lengthVector(); + Vec3d pos = new Vec3d(this.pos).add(trackCenter); + 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 = motion.distanceTo(trackMovement) > motion.scale(-1).distanceTo(trackMovement); - Vec3d newPosition = new Vec3d(pos).add(trackCenter); - //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; + Vec3d newPosition = pos; + 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.setVanillaPos(newPosition).setRoll(0d); + return true; + } + return false; } public static boolean isRail(World world, BlockPos pos) { return BlockRailBase.isRailBlock(world, 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..3221b95 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. * - * @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 Next found position on the track */ - 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..714881e 100644 --- a/src/main/java/trackapi/lib/ITrackBlock.java +++ b/src/main/java/trackapi/lib/ITrackBlock.java @@ -5,27 +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 */ - 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 + * 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 */ - 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/ITrackV2.java b/src/main/java/trackapi/lib/ITrackV2.java new file mode 100644 index 0000000..9ed2618 --- /dev/null +++ b/src/main/java/trackapi/lib/ITrackV2.java @@ -0,0 +1,40 @@ +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(); + + /** + * Used by rolling stocks to look up their next position and related data + * @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 True if inputData is successfully overridden, false if cannot find next path + */ + boolean getNextPosition(D inputData, Vec3d motion, double gauge); + + //Overrides for forward compatibility, don't use + @Override + @Deprecated + default double getTrackGauge() { + return getTrackGauges()[0]; + } + + @Override + @Deprecated + default Vec3d getNextPosition(Vec3d currentPosition, Vec3d motion) { + //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 new file mode 100644 index 0000000..4e386cf --- /dev/null +++ b/src/main/java/trackapi/lib/PathingData.java @@ -0,0 +1,35 @@ +package trackapi.lib; + +import net.minecraft.util.math.Vec3d; + +/** + * 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 vanillaPos; + private double roll; + + public PathingData(Vec3d vanillaPos, double roll) { + this.vanillaPos = vanillaPos; + this.roll = roll; + } + + public Vec3d getVanillaPos() { + return vanillaPos; + } + + public PathingData setVanillaPos(Vec3d vanillaPos) { + this.vanillaPos = vanillaPos; + return this; + } + + public double getRoll() { + return roll; + } + + public PathingData setRoll(double roll) { + this.roll = roll; + return this; + } +} diff --git a/src/main/java/trackapi/lib/Util.java b/src/main/java/trackapi/lib/Util.java index 63f2d4a..e5e65bd 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.addVector(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.addVector(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; + } }