diff --git a/src/main/java/com/hbm/blocks/rail/IRailNTM.java b/src/main/java/com/hbm/blocks/rail/IRailNTM.java index 0bb68d517..430395012 100644 --- a/src/main/java/com/hbm/blocks/rail/IRailNTM.java +++ b/src/main/java/com/hbm/blocks/rail/IRailNTM.java @@ -15,11 +15,11 @@ public interface IRailNTM { * Returns a location on the rail based on the train's current X/Y/Z momentum as well as the intended speed along the rail. * If the train would leave the rail within that tick, the position is the last valid position on that rail. * Inherently safer than simply adding the motion to the position and then snapping, since that may lead to derailing. - * The motion has to be calculated from the train's rotation, the scalar doesn't matter since it's only used for determining orientation in a clear way. + * The motion has to be calculated from the train's rotation (rotated 180° when going backwards), the scalar doesn't matter since it's only used for determining orientation in a clear way. * Motion ends up being *-1 if the train is going in reverse, still pointing forwards despite the speed being negative. * Also features a double[] wrapper with size 1 which holds the speed value that overshoots the rail. * */ - public Vec3 getTravelLocation(World world, int x, int y, int z, double trainX, double trainY, double trainZ, double motionX, double motionY, double motionZ, double speed, RailLeaveInfo info); + public Vec3 getTravelLocation(World world, int x, int y, int z, double trainX, double trainY, double trainZ, double motionX, double motionY, double motionZ, double speed, RailContext info); /** Returns that rail's gauge. Trains will derail if the gauge does not match. */ public TrackGauge getGauge(World world, int x, int y, int z); @@ -29,12 +29,15 @@ public interface IRailNTM { } /** A wrapper for all relevant info required when leaving a rail */ - public static class RailLeaveInfo { + public static class RailContext { + /** The angle at which the train ends up being on this rail */ + public float yaw; /** The amount of blocks still left to travel after completing the rail */ public double overshoot; /** The exit position of that rail */ public BlockPos pos; - public RailLeaveInfo dist(double d) { this.overshoot = d; return this; } - public RailLeaveInfo pos(BlockPos d) { this.pos = d; return this; } + public RailContext yaw(float y) { this.yaw = y; return this; } + public RailContext dist(double d) { this.overshoot = d; return this; } + public RailContext pos(BlockPos d) { this.pos = d; return this; } } } diff --git a/src/main/java/com/hbm/blocks/rail/RailStandardCurve.java b/src/main/java/com/hbm/blocks/rail/RailStandardCurve.java index 3bfa512dc..35a6a9b4a 100644 --- a/src/main/java/com/hbm/blocks/rail/RailStandardCurve.java +++ b/src/main/java/com/hbm/blocks/rail/RailStandardCurve.java @@ -11,6 +11,7 @@ import com.hbm.util.ParticleUtil; import com.hbm.util.fauxpointtwelve.BlockPos; import net.minecraft.block.material.Material; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; @@ -39,16 +40,16 @@ public class RailStandardCurve extends BlockDummyable implements IRailNTM { @Override public Vec3 getSnappingPos(World world, int x, int y, int z, double trainX, double trainY, double trainZ) { - return snapAndMove(world, x, y, z, trainX, trainY, trainZ, 0, 0, 0, 0, new RailLeaveInfo()); + return snapAndMove(world, x, y, z, trainX, trainY, trainZ, 0, 0, 0, 0, new RailContext()); } @Override - public Vec3 getTravelLocation(World world, int x, int y, int z, double trainX, double trainY, double trainZ, double motionX, double motionY, double motionZ, double speed, RailLeaveInfo info) { + public Vec3 getTravelLocation(World world, int x, int y, int z, double trainX, double trainY, double trainZ, double motionX, double motionY, double motionZ, double speed, RailContext info) { return snapAndMove(world, x, y, z, trainX, trainY, trainZ, motionX, motionY, motionZ, speed, info); } /* Very simple function determining the snapping position and adding the motion value to it, if desired. */ - public Vec3 snapAndMove(World world, int x, int y, int z, double trainX, double trainY, double trainZ, double motionX, double motionY, double motionZ, double speed, RailLeaveInfo info) { + public Vec3 snapAndMove(World world, int x, int y, int z, double trainX, double trainY, double trainZ, double motionX, double motionY, double motionZ, double speed, RailContext info) { int[] pos = this.findCore(world, x, y, z); if(pos == null) return Vec3.createVectorHelper(trainX, trainY, trainZ); int cX = pos[0]; @@ -69,15 +70,17 @@ public class RailStandardCurve extends BlockDummyable implements IRailNTM { dist.xCoord *= turnRadius; dist.zCoord *= turnRadius; + double moveAngle = Math.atan2(motionX, motionZ) * 180D / Math.PI + 90; + if(speed == 0) { - info.dist(0).pos(new BlockPos(x, y, z)); + info.dist(0).pos(new BlockPos(x, y, z)).yaw((float) moveAngle); return Vec3.createVectorHelper(axisX + dist.xCoord, y, axisZ + dist.zCoord); } - - double angleDeg = -Math.atan(dist.zCoord / dist.xCoord) * 180D / Math.PI; - if(dir == Library.NEG_X) angleDeg += 90; - if(dir == Library.POS_X) angleDeg -= 90; + double angleDeg = Math.atan2(dist.xCoord, dist.zCoord) * 180D / Math.PI + 90; + if(dir == Library.NEG_X) angleDeg -= 90; + if(dir == Library.POS_X) angleDeg += 90; + if(dir == Library.POS_Z) angleDeg += 180; angleDeg = MathHelper.wrapAngleTo180_double(angleDeg); double length90Deg = turnRadius * Math.PI / 2D; double angularChange = speed / length90Deg * 90D; @@ -95,20 +98,22 @@ public class RailStandardCurve extends BlockDummyable implements IRailNTM { } double effAngle = angleDeg + angularChange; - effAngle = MathHelper.wrapAngleTo180_double(effAngle); + moveAngle += angularChange; if(effAngle > 90) { double angleOvershoot = effAngle - 90D; + moveAngle -= angleOvershoot; double lengthOvershoot = angleOvershoot * length90Deg / 90D; - info.dist(lengthOvershoot * Math.signum(speed * angularChange)).pos(new BlockPos(cX - dir.offsetX * 4 + rot.offsetX * 5, y, cZ - dir.offsetZ * 4 + rot.offsetZ * 5)); + info.dist(lengthOvershoot * Math.signum(speed * angularChange)).pos(new BlockPos(cX - dir.offsetX * 4 + rot.offsetX * 5, y, cZ - dir.offsetZ * 4 + rot.offsetZ * 5)).yaw((float) moveAngle); return Vec3.createVectorHelper(axisX - dir.offsetX * turnRadius, y, axisZ - dir.offsetZ * turnRadius); } if(effAngle < 0) { double angleOvershoot = -effAngle; + moveAngle -= angleOvershoot; double lengthOvershoot = angleOvershoot * length90Deg / 90D; - info.dist(-lengthOvershoot * Math.signum(speed * angularChange)).pos(new BlockPos(cX + dir.offsetX , y, cZ + dir.offsetZ)); - return Vec3.createVectorHelper(axisX + 0.5 + dir.offsetX * 0.5, y, axisZ * 0.5 + dir.offsetZ * 0.5); + info.dist(-lengthOvershoot * Math.signum(speed * angularChange)).pos(new BlockPos(cX + dir.offsetX , y, cZ + dir.offsetZ)).yaw((float) moveAngle); + return Vec3.createVectorHelper(axisX - rot.offsetX * turnRadius, y, axisZ -rot.offsetZ * turnRadius); } double radianChange = angularChange * Math.PI / 180D; diff --git a/src/main/java/com/hbm/blocks/rail/RailStandardStraight.java b/src/main/java/com/hbm/blocks/rail/RailStandardStraight.java index 1129155e3..1c8889b0b 100644 --- a/src/main/java/com/hbm/blocks/rail/RailStandardStraight.java +++ b/src/main/java/com/hbm/blocks/rail/RailStandardStraight.java @@ -52,16 +52,16 @@ public class RailStandardStraight extends BlockDummyable implements IRailNTM { @Override public Vec3 getSnappingPos(World world, int x, int y, int z, double trainX, double trainY, double trainZ) { - return snapAndMove(world, x, y, z, trainX, trainY, trainZ, 0, 0, 0, 0, new RailLeaveInfo()); + return snapAndMove(world, x, y, z, trainX, trainY, trainZ, 0, 0, 0, 0, new RailContext()); } @Override - public Vec3 getTravelLocation(World world, int x, int y, int z, double trainX, double trainY, double trainZ, double motionX, double motionY, double motionZ, double speed, RailLeaveInfo info) { + public Vec3 getTravelLocation(World world, int x, int y, int z, double trainX, double trainY, double trainZ, double motionX, double motionY, double motionZ, double speed, RailContext info) { return snapAndMove(world, x, y, z, trainX, trainY, trainZ, motionX, motionY, motionZ, speed, info); } /* Very simple function determining the snapping position and adding the motion value to it, if desired. */ - public Vec3 snapAndMove(World world, int x, int y, int z, double trainX, double trainY, double trainZ, double motionX, double motionY, double motionZ, double speed, RailLeaveInfo info) { + public Vec3 snapAndMove(World world, int x, int y, int z, double trainX, double trainY, double trainZ, double motionX, double motionY, double motionZ, double speed, RailContext info) { int[] pos = this.findCore(world, x, y, z); if(pos == null) return Vec3.createVectorHelper(trainX, trainY, trainZ); int cX = pos[0]; @@ -80,8 +80,10 @@ public class RailStandardStraight extends BlockDummyable implements IRailNTM { double targetX = trainX; if(motionX > 0) { targetX += speed; + info.yaw(-90F); } else { targetX -= speed; + info.yaw(90F); } vec.xCoord = MathHelper.clamp_double(targetX, cX - 2, cX + 3); vec.yCoord = y; @@ -92,8 +94,10 @@ public class RailStandardStraight extends BlockDummyable implements IRailNTM { double targetZ = trainZ; if(motionZ > 0) { targetZ += speed; + info.yaw(0F); } else { targetZ -= speed; + info.yaw(180F); } vec.xCoord = cX + 0.5; vec.yCoord = y; diff --git a/src/main/java/com/hbm/entity/train/EntityRailCarBase.java b/src/main/java/com/hbm/entity/train/EntityRailCarBase.java index 74f9030ec..750dc5765 100644 --- a/src/main/java/com/hbm/entity/train/EntityRailCarBase.java +++ b/src/main/java/com/hbm/entity/train/EntityRailCarBase.java @@ -1,7 +1,7 @@ package com.hbm.entity.train; import com.hbm.blocks.rail.IRailNTM; -import com.hbm.blocks.rail.IRailNTM.RailLeaveInfo; +import com.hbm.blocks.rail.IRailNTM.RailContext; import com.hbm.blocks.rail.IRailNTM.TrackGauge; import com.hbm.main.MainRegistry; import com.hbm.packet.PacketDispatcher; @@ -31,6 +31,7 @@ public abstract class EntityRailCarBase extends Entity { private double trainZ; private double trainYaw; private double trainPitch; + private float movementYaw; @SideOnly(Side.CLIENT) private double velocityX; @SideOnly(Side.CLIENT) private double velocityY; @SideOnly(Side.CLIENT) private double velocityZ; @@ -57,7 +58,9 @@ public abstract class EntityRailCarBase extends Entity { public void onUpdate() { if(this.worldObj.isRemote) { + if(this.turnProgress > 0) { + this.prevRotationYaw = this.rotationYaw; double x = this.posX + (this.trainX - this.posX) / (double) this.turnProgress; double y = this.posY + (this.trainY - this.posY) / (double) this.turnProgress; double z = this.posZ + (this.trainZ - this.posZ) / (double) this.turnProgress; @@ -67,11 +70,9 @@ public abstract class EntityRailCarBase extends Entity { --this.turnProgress; this.setPosition(x, y, z); this.setRotation(this.rotationYaw, this.rotationPitch); - this.setRotation((float)this.trainYaw, this.rotationPitch); } else { this.setPosition(this.posX, this.posY, this.posZ); this.setRotation(this.rotationYaw, this.rotationPitch); - this.setRotation((float)this.trainYaw, this.rotationPitch); } } else { @@ -81,11 +82,7 @@ public abstract class EntityRailCarBase extends Entity { if(corePos == null) { this.derail(); } else { - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; this.setPosition(corePos.xCoord, corePos.yCoord, corePos.zCoord); - anchor = this.getCurentAnchorPos(); //reset origin to new position Vec3 frontPos = getRelPosAlongRail(anchor, this.getLengthSpan()); Vec3 backPos = getRelPosAlongRail(anchor, -this.getLengthSpan()); @@ -93,11 +90,15 @@ public abstract class EntityRailCarBase extends Entity { if(frontPos == null || backPos == null) { this.derail(); } else { - this.rotationYaw = generateYaw(frontPos, backPos); + this.prevRotationYaw = this.rotationYaw; + this.rotationYaw = this.movementYaw = generateYaw(frontPos, backPos); + this.motionX = this.rotationYaw / 360D; // hijacking this crap for easy syncing + this.velocityChanged = true; } } - - PacketDispatcher.wrapper.sendTo(new PlayerInformPacket(new ChatComponentText("Yaw: " + this.rotationYaw), 665, 3000), (EntityPlayerMP) worldObj.playerEntities.get(0)); + + PacketDispatcher.wrapper.sendTo(new PlayerInformPacket(new ChatComponentText("Yaw: " + this.rotationYaw), 664, 3000), (EntityPlayerMP) worldObj.playerEntities.get(0)); + PacketDispatcher.wrapper.sendTo(new PlayerInformPacket(new ChatComponentText("MYaw: " + this.movementYaw), 665, 3000), (EntityPlayerMP) worldObj.playerEntities.get(0)); } } @@ -105,6 +106,11 @@ public abstract class EntityRailCarBase extends Entity { float yaw = this.rotationYaw; + if(distanceToCover < 0) { + distanceToCover *= -1; + yaw += 180; + } + Vec3 next = Vec3.createVectorHelper(posX, posY, posZ); int it = 0; @@ -129,13 +135,20 @@ public abstract class EntityRailCarBase extends Entity { if(block instanceof IRailNTM) { IRailNTM rail = (IRailNTM) block; + if(it == 1) { + next = rail.getTravelLocation(worldObj, x, y, z, next.xCoord, next.yCoord, next.zCoord, rot.xCoord, rot.yCoord, rot.zCoord, 0, new RailContext()); + } + + boolean flip = distanceToCover < 0; + if(rail.getGauge(worldObj, x, y, z) == this.getGauge()) { - RailLeaveInfo info = new RailLeaveInfo(); + RailContext info = new RailContext(); Vec3 prev = next; - next = rail.getTravelLocation(worldObj, x, y, z, posX, posY, posZ, rot.xCoord, rot.yCoord, rot.zCoord, distanceToCover, info); + next = rail.getTravelLocation(worldObj, x, y, z, prev.xCoord, prev.yCoord, prev.zCoord, rot.xCoord, rot.yCoord, rot.zCoord, distanceToCover, info); distanceToCover = info.overshoot; anchor = info.pos; - yaw = generateYaw(next, prev); + + yaw = generateYaw(next, prev) * (flip ? -1 : 1); } else { return null; @@ -178,16 +191,18 @@ public abstract class EntityRailCarBase extends Entity { this.trainX = posX; this.trainY = posY; this.trainZ = posZ; - this.trainYaw = (double) yaw; + //this.trainYaw = (double) yaw; this.trainPitch = (double) pitch; this.turnProgress = turnProg + 2; this.motionX = this.velocityX; this.motionY = this.velocityY; this.motionZ = this.velocityZ; + this.trainYaw = this.movementYaw; } @SideOnly(Side.CLIENT) public void setVelocity(double mX, double mY, double mZ) { + this.movementYaw = (float) this.motionX * 360F; this.velocityX = this.motionX = mX; this.velocityY = this.motionY = mY; this.velocityZ = this.motionZ = mZ; diff --git a/src/main/java/com/hbm/items/tool/ItemWandD.java b/src/main/java/com/hbm/items/tool/ItemWandD.java index f8c7643da..2d22a2182 100644 --- a/src/main/java/com/hbm/items/tool/ItemWandD.java +++ b/src/main/java/com/hbm/items/tool/ItemWandD.java @@ -3,7 +3,7 @@ package com.hbm.items.tool; import java.util.List; import com.hbm.blocks.rail.IRailNTM; -import com.hbm.blocks.rail.IRailNTM.RailLeaveInfo; +import com.hbm.blocks.rail.IRailNTM.RailContext; import com.hbm.lib.Library; import com.hbm.packet.PacketDispatcher; import com.hbm.packet.PlayerInformPacket; diff --git a/src/main/java/com/hbm/main/ModEventHandlerClient.java b/src/main/java/com/hbm/main/ModEventHandlerClient.java index f89a281d2..9393a59c8 100644 --- a/src/main/java/com/hbm/main/ModEventHandlerClient.java +++ b/src/main/java/com/hbm/main/ModEventHandlerClient.java @@ -13,11 +13,12 @@ import com.hbm.blocks.ILookOverlay; import com.hbm.blocks.ModBlocks; import com.hbm.blocks.generic.BlockAshes; import com.hbm.blocks.rail.IRailNTM; -import com.hbm.blocks.rail.IRailNTM.RailLeaveInfo; +import com.hbm.blocks.rail.IRailNTM.RailContext; import com.hbm.config.GeneralConfig; import com.hbm.entity.effect.EntityNukeTorex; import com.hbm.entity.mob.EntityHunterChopper; import com.hbm.entity.projectile.EntityChopperMine; +import com.hbm.entity.train.EntityRailCarRidable; import com.hbm.extprop.HbmLivingProps; import com.hbm.extprop.HbmPlayerProps; import com.hbm.handler.ArmorModHandler; @@ -217,7 +218,6 @@ public class ModEventHandlerClient { float yaw = player.rotationYaw; Vec3 next = Vec3.createVectorHelper(pos.hitVec.xCoord, pos.hitVec.yCoord, pos.hitVec.zCoord); - Vec3 first = next; int it = 0; BlockPos anchor = new BlockPos(pos.blockX, pos.blockY, pos.blockZ); @@ -243,12 +243,12 @@ public class ModEventHandlerClient { if(block instanceof IRailNTM) { IRailNTM rail = (IRailNTM) block; - RailLeaveInfo info = new RailLeaveInfo(); + RailContext info = new RailContext(); boolean flip = distanceToCover < 0; if(it == 1) { - Vec3 snap = rail.getTravelLocation(world, x, y, z, next.xCoord, next.yCoord, next.zCoord, rot.xCoord, rot.yCoord, rot.zCoord, 0, info); + Vec3 snap = next = rail.getTravelLocation(world, x, y, z, next.xCoord, next.yCoord, next.zCoord, rot.xCoord, rot.yCoord, rot.zCoord, 0, info); if(i == 0) world.spawnParticle("reddust", snap.xCoord, snap.yCoord + 0.25, snap.zCoord, 0.1, 1, 0.1); } @@ -264,7 +264,7 @@ public class ModEventHandlerClient { double radians = -Math.atan2(deltaX, deltaZ); yaw = (float) MathHelper.wrapAngleTo180_double(radians * 180D / Math.PI + (flip ? 180 : 0)); - text.add(it + ": " + distanceToCover); + text.add(it + ": " + yaw); } else { break;