oh HELL yeah

This commit is contained in:
Bob 2023-05-06 14:44:11 +02:00
parent a558b1d83b
commit c0488324b0
6 changed files with 67 additions and 40 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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