From dd2f929821ee9432429cf927ab1809b0c295f11d Mon Sep 17 00:00:00 2001 From: Boblet Date: Wed, 3 May 2023 10:42:58 +0200 Subject: [PATCH] EntityRailCarBase --- .../java/com/hbm/blocks/machine/Watz.java | 8 + .../java/com/hbm/blocks/rail/IRailNTM.java | 17 +- .../hbm/blocks/rail/RailStandardStraight.java | 15 +- .../hbm/entity/train/EntityRailCarBase.java | 157 ++++++++++++++++++ 4 files changed, 189 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/hbm/entity/train/EntityRailCarBase.java diff --git a/src/main/java/com/hbm/blocks/machine/Watz.java b/src/main/java/com/hbm/blocks/machine/Watz.java index 8a975bbc2..4f195b722 100644 --- a/src/main/java/com/hbm/blocks/machine/Watz.java +++ b/src/main/java/com/hbm/blocks/machine/Watz.java @@ -1,5 +1,7 @@ package com.hbm.blocks.machine; +import java.util.Random; + import com.hbm.blocks.BlockDummyable; import com.hbm.blocks.ModBlocks; import com.hbm.handler.MultiblockHandlerXR; @@ -11,6 +13,7 @@ import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; @@ -29,6 +32,11 @@ public class Watz extends BlockDummyable { if(meta >= 6) return new TileEntityProxyCombo().inventory().fluid(); return null; } + + @Override + public Item getItemDropped(int i, Random rand, int j) { + return null; + } @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { diff --git a/src/main/java/com/hbm/blocks/rail/IRailNTM.java b/src/main/java/com/hbm/blocks/rail/IRailNTM.java index 87738ed77..0bb68d517 100644 --- a/src/main/java/com/hbm/blocks/rail/IRailNTM.java +++ b/src/main/java/com/hbm/blocks/rail/IRailNTM.java @@ -1,8 +1,11 @@ package com.hbm.blocks.rail; +import com.hbm.util.fauxpointtwelve.BlockPos; + import net.minecraft.util.Vec3; import net.minecraft.world.World; +/** in retrospect, not the best name i could have chosen */ public interface IRailNTM { /** Returns a vector pointing to the closest snapping position given the starting position */ @@ -16,12 +19,22 @@ public interface IRailNTM { * 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, double[] leftover); + 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); - /** Returns that rail'S gauge. Trains will derail if the gauge does not match. */ + /** 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); public static enum TrackGauge { STANDARD //roughly 1.5m } + + /** A wrapper for all relevant info required when leaving a rail */ + public static class RailLeaveInfo { + /** 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; } + } } diff --git a/src/main/java/com/hbm/blocks/rail/RailStandardStraight.java b/src/main/java/com/hbm/blocks/rail/RailStandardStraight.java index 66a188e6a..d28329aca 100644 --- a/src/main/java/com/hbm/blocks/rail/RailStandardStraight.java +++ b/src/main/java/com/hbm/blocks/rail/RailStandardStraight.java @@ -2,6 +2,7 @@ package com.hbm.blocks.rail; import com.hbm.blocks.BlockDummyable; import com.hbm.lib.Library; +import com.hbm.util.fauxpointtwelve.BlockPos; import net.minecraft.block.material.Material; import net.minecraft.tileentity.TileEntity; @@ -47,16 +48,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 double[1]); + return snapAndMove(world, x, y, z, trainX, trainY, trainZ, 0, 0, 0, 0, new RailLeaveInfo()); } @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, double[] leftover) { - return snapAndMove(world, x, y, z, trainX, trainY, trainZ, motionX, motionY, motionZ, speed, leftover); + 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) { + 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, double[] leftover) { + 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) { int[] pos = this.findCore(world, x, y, z); if(pos == null) return Vec3.createVectorHelper(trainX, trainY, trainZ); int cX = pos[0]; @@ -81,7 +82,8 @@ public class RailStandardStraight extends BlockDummyable implements IRailNTM { vec.xCoord = MathHelper.clamp_double(targetX, x - 2, x + 3); vec.yCoord = y; vec.zCoord = z + 0.5; - leftover[0] = Math.abs(targetX - vec.xCoord); + info.dist(Math.abs(targetX - vec.xCoord)); + info.pos(new BlockPos(vec.xCoord + (motionX > 0 ? 1 : -1), y, z)); } else { double targetZ = trainZ; if(motionZ > 0) { @@ -92,7 +94,8 @@ public class RailStandardStraight extends BlockDummyable implements IRailNTM { vec.xCoord = x + 0.5; vec.yCoord = y; vec.zCoord = MathHelper.clamp_double(targetZ, z - 2, z + 3); - leftover[0] = Math.abs(targetZ - vec.zCoord); + info.dist(Math.abs(targetZ - vec.zCoord)); + info.pos(new BlockPos(x, y, vec.zCoord + (motionZ > 0 ? 1 : -1))); } return vec; diff --git a/src/main/java/com/hbm/entity/train/EntityRailCarBase.java b/src/main/java/com/hbm/entity/train/EntityRailCarBase.java new file mode 100644 index 000000000..f5c800bb0 --- /dev/null +++ b/src/main/java/com/hbm/entity/train/EntityRailCarBase.java @@ -0,0 +1,157 @@ +package com.hbm.entity.train; + +import com.hbm.blocks.rail.IRailNTM; +import com.hbm.blocks.rail.IRailNTM.RailLeaveInfo; +import com.hbm.blocks.rail.IRailNTM.TrackGauge; +import com.hbm.util.fauxpointtwelve.BlockPos; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.MathHelper; +import net.minecraft.util.Vec3; +import net.minecraft.world.World; + +public abstract class EntityRailCarBase extends Entity { + + public boolean isOnRail = true; + private int turnProgress; + private double trainX; + private double trainY; + private double trainZ; + private double trainYaw; + private double trainPitch; + @SideOnly(Side.CLIENT) private double velocityX; + @SideOnly(Side.CLIENT) private double velocityY; + @SideOnly(Side.CLIENT) private double velocityZ; + + public EntityRailCarBase(World world) { + super(world); + } + + @Override protected void entityInit() { } + @Override protected void readEntityFromNBT(NBTTagCompound nbt) { } + @Override protected void writeEntityToNBT(NBTTagCompound nbt) { } + + @Override + public void onUpdate() { + + if(this.worldObj.isRemote) { + if(this.turnProgress > 0) { + 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; + double yaw = MathHelper.wrapAngleTo180_double(this.trainYaw - (double) this.rotationYaw); + this.rotationYaw = (float) ((double) this.rotationYaw + yaw / (double) this.turnProgress); + this.rotationPitch = (float) ((double) this.rotationPitch + (this.trainPitch - (double) this.rotationPitch) / (double) this.turnProgress); + --this.turnProgress; + this.setPosition(x, y, z); + this.setRotation(this.rotationYaw, this.rotationPitch); + } else { + this.setPosition(this.posX, this.posY, this.posZ); + this.setRotation(this.rotationYaw, this.rotationPitch); + } + } else { + + BlockPos anchor = this.getCurentAnchorPos(); + Vec3 corePos = getRelPosAlongRail(anchor, this.getCurrentSpeed()); + + if(corePos == null) { + this.derail(); + } else { + 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()); + + if(frontPos == null) this.derail(); + if(backPos == null) this.derail(); + + if(frontPos != null && backPos != null) this.rotationYaw = generateYaw(frontPos, backPos); + } + } + } + + public Vec3 getRelPosAlongRail(BlockPos anchor, double distanceToCover) { + + double overshoot = 0; + float yaw = this.rotationYaw; + + Vec3 next = null; + + do { + + int x = anchor.getX(); + int y = anchor.getY(); + int z = anchor.getZ(); + Block block = worldObj.getBlock(x, y, z); + + Vec3 rot = Vec3.createVectorHelper(1, 0, 0); + rot.rotateAroundY(yaw); + + if(block instanceof IRailNTM) { + IRailNTM rail = (IRailNTM) block; + + if(rail.getGauge(worldObj, x, y, z) == this.getGauge()) { + RailLeaveInfo info = new RailLeaveInfo(); + Vec3 prev = next; + next = rail.getTravelLocation(worldObj, x, y, z, posX, posY, posZ, rot.xCoord, rot.yCoord, rot.zCoord, distanceToCover, info); + overshoot = info.overshoot; + anchor = info.pos; + yaw = generateYaw(next, prev); + + } else { + return null; + } + } else { + return null; + } + + } while(overshoot != 0); //if there's still length to cover, keep going + + return next; + } + + public float generateYaw(Vec3 front, Vec3 back) { + return 0F; //TODO + } + + /** Returns the amount of blocks that the train should move per tick */ + public abstract double getCurrentSpeed(); + /** Returns the gauge of this train */ + public abstract TrackGauge getGauge(); + /** Returns the length between the core and one of the bogies */ + public abstract double getLengthSpan(); + + /** Returns the "true" position of the train, i.e. the block it wants to snap to */ + public BlockPos getCurentAnchorPos() { + return new BlockPos(posX, posY, posZ); + } + + public void derail() { + isOnRail = false; + } + + @SideOnly(Side.CLIENT) + public void setPositionAndRotation2(double posX, double posY, double posZ, float yaw, float pitch, int turnProg) { + this.trainX = posX; + this.trainY = posY; + this.trainZ = posZ; + this.trainYaw = (double) yaw; + this.trainPitch = (double) pitch; + this.turnProgress = turnProg + 2; + this.motionX = this.velocityX; + this.motionY = this.velocityY; + this.motionZ = this.velocityZ; + } + + @SideOnly(Side.CLIENT) + public void setVelocity(double mX, double mY, double mZ) { + this.velocityX = this.motionX = mX; + this.velocityY = this.motionY = mY; + this.velocityZ = this.motionZ = mZ; + } +}