From ccfcbbba022380e1ae8d9e0b5527a88eee9de72e Mon Sep 17 00:00:00 2001 From: Jonathan Date: Tue, 8 Aug 2023 18:05:16 -0500 Subject: [PATCH] Merge 'origin/1.7-TiM' into 1.12.1-TiM --- src/main/java/ebf/tim/blocks/TileSwitch.java | 8 +- .../java/ebf/tim/entities/EntityBogie.java | 223 +++++---- .../ebf/tim/entities/EntityTrainCore.java | 88 ++-- .../tim/entities/GenericRailTransport.java | 433 +++++++++--------- .../tim/networking/PacketUpdateClients.java | 1 + src/main/java/ebf/tim/render/RenderWagon.java | 17 +- src/main/java/ebf/tim/utility/CommonUtil.java | 17 + .../java/ebf/tim/utility/FuelHandler.java | 9 +- .../java/ebf/tim/utility/HitboxDynamic.java | 8 +- .../fexcraft/tmt/slim/CylinderBuilder.java | 2 +- .../java/fexcraft/tmt/slim/ModelPool.java | 15 +- .../fexcraft/tmt/slim/ModelPoolEntry.java | 11 +- .../fexcraft/tmt/slim/ModelPoolObjEntry.java | 8 +- 13 files changed, 418 insertions(+), 422 deletions(-) diff --git a/src/main/java/ebf/tim/blocks/TileSwitch.java b/src/main/java/ebf/tim/blocks/TileSwitch.java index 1f467e61b8..6eb17e2d2f 100644 --- a/src/main/java/ebf/tim/blocks/TileSwitch.java +++ b/src/main/java/ebf/tim/blocks/TileSwitch.java @@ -189,7 +189,13 @@ public int checkBlockPower(int[] ... offset){ public int checkBlockPower(int[] offset, int depth){ int signalStrength=0; for(int o =-1;o movement management * this is modified movement from the super class, should be more efficient, and reliable, but generally does the same thing, minus ability to collide. @@ -197,188 +228,180 @@ public void readFromNBT(NBTTagCompound tag){} * @see CommonUtil * returns true or false depending on whether or not it derails from having no rail. */ - public void minecartMove(GenericRailTransport host, double moveX, double moveZ) { + public void minecartMove(GenericRailTransport host) { //server only if(!getWorld().isRemote) { - //define the yaw from the super - //this.setRotation(host.rotationYaw, host.rotationPitch); - //prevent moving without motion velocity - if (Math.abs(moveX) + Math.abs(moveZ) < 0.000001) { - return; + //prevent moving without velocity + if (Math.abs(velocity[0]) + Math.abs(velocity[1] + Math.abs(velocity[2]) + Math.abs(velocity[3])) < 0.0000001) { + //return; } + //reset rotation + velocity[4]=0;velocity[5]=0; //update old position, add the gravity, and get the block below this, this.prevPosX = this.posX; this.prevPosY = this.posY; this.prevPosZ = this.posZ; - - int floorX = CommonUtil.floorDouble(this.posX); - int floorY = CommonUtil.floorDouble(this.posY); - int floorZ = CommonUtil.floorDouble(this.posZ); - - - Block block = CommonUtil.getBlockAt(getWorld(), floorX, floorY, floorZ); - Block blockUp; + Block block = CommonUtil.getBlockAt(getWorld(), xFloor, yFloor, zFloor); //todo: if (block instanceof BlockRailCore) { //update using spline movement //} else if (block instanceof BlockRailBase) + if(!(block instanceof BlockRailBase)){ + if(CommonUtil.getBlockAt(getWorld(), xFloor, yFloor+1, zFloor) instanceof BlockRailBase) { + prevPosY=posY; + posY++; + yFloor++; + block = CommonUtil.getBlockAt(getWorld(), xFloor, yFloor, zFloor); + } else if(CommonUtil.getBlockAt(getWorld(), xFloor, yFloor-1, zFloor) instanceof BlockRailBase) { + prevPosY=posY; + posY--; + yFloor--; + block = CommonUtil.getBlockAt(getWorld(), xFloor, yFloor, zFloor); + } else if(block instanceof BlockAir) { + moveOffRail(); + } + } + //update on normal rails if (block instanceof BlockRailBase) { this.yOffset=(block instanceof BlockRailCore?0.425f:0.3425f); - loopVanilla(host, Math.abs(moveX) + Math.abs(moveZ), moveX,moveZ, floorX,floorY,floorZ, (BlockRailBase) block); + loopVanilla(host, Math.abs(velocity[0])+Math.abs(velocity[1])+Math.abs(velocity[2])+Math.abs(velocity[3]), (BlockRailBase) block); //update on ZnD rails, and ones that don't extend block rail base. //todo ZnD support, either by jar reference or API update //} else if (block instanceof ITrackBase) { //update position for ZnD rails. //moveBogieZnD(motionX, motionZ, floorX, floorY, floorZ, (ITrackBase) block); - } else if(block instanceof BlockAir) { - double velocity = Math.abs(moveX) + Math.abs(moveZ); - while (velocity>0) { - posX+=Math.min(0.35, moveX); - posZ+=Math.min(0.35, moveZ); - velocity -= 0.35; - - //update Y position and check for collision - if(floorX!=CommonUtil.floorDouble(this.posX) || floorZ!=CommonUtil.floorDouble(posZ)) { - floorX = CommonUtil.floorDouble(this.posX); - floorY = CommonUtil.floorDouble(this.posY); - floorZ = CommonUtil.floorDouble(this.posZ); - //check for collisions and skip update - for (int i = 0; i < host.getHitboxSize()[1] - 1; i++) { - blockUp = CommonUtil.getBlockAt(getWorld(), floorX, floorY + i, floorZ); - if (!(blockUp instanceof BlockAir)) { - host.frontBogie.motionX=0; - host.frontBogie.motionZ=0; - host.backBogie.motionX=0; - host.backBogie.motionZ=0; - return; - } - } - //fall - if (CommonUtil.getBlockAt(getWorld(), floorX, floorY - 1, floorZ) instanceof BlockAir) { - posY--; - } - } + } + velocity[2]=0;velocity[3]=0; + } + } + + private void moveOffRail(){ + railPathZ=0;railPathX=0; + double moveLength = Math.abs(velocity[0]) + Math.abs(velocity[1] + Math.abs(velocity[2]) + Math.abs(velocity[3])); + while (moveLength>0) { + posX+=Math.min(0.35, velocity[0]+velocity[2]); + posZ+=Math.min(0.35, velocity[1]+velocity[3]); + moveLength -= 0.35; + + //update Y position and check for collision + if(xFloor!=CommonUtil.floorDouble(this.posX) || zFloor!=CommonUtil.floorDouble(posZ)) { + xFloor = CommonUtil.floorDouble(this.posX); + yFloor = CommonUtil.floorDouble(this.posY); + zFloor = CommonUtil.floorDouble(this.posZ); + //fall + if (CommonUtil.getBlockAt(getWorld(), xFloor, yFloor - 1, zFloor) instanceof BlockAir) { + posY--; } - } else if(CommonUtil.getBlockAt(getWorld(), floorX, floorY+1, floorZ) instanceof BlockRailBase) { - prevPosY=posY; - posY++; } } } - private void loopVanilla(GenericRailTransport host, double velocity, double velocityX, double velocityZ, int floorX, int floorY,int floorZ, BlockRailBase block){ + private void loopVanilla(GenericRailTransport host, double moveLength, BlockRailBase block){ //try to adhere to limiter track - railmax = block.getRailMaxSpeed(getWorld(),this,new BlockPos(floorX, floorY, floorZ)); + railmax = block.getRailMaxSpeed(getWorld(),this,xFloor, yFloor, zFloor); Block blockUp; if(railmax!=0.4f){ - velocity=Math.min(velocity,railmax); + moveLength=Math.min(moveLength,railmax); } - railMetadata = CommonUtil.getRailMeta(getWorld(), this, floorX, floorY, floorZ); - loopDirection=new double[]{velocityX,velocityZ}; + railMetadata = CommonUtil.getRailMeta(getWorld(), this, xFloor, yFloor, zFloor); //actually move - while (velocity>0) { - loopDirection=moveBogieVanilla(Math.min(0.3, velocity), floorX, floorZ,loopDirection); - velocity -= 0.3; + while (moveLength>0) { + moveBogieVanilla(Math.min(0.3, moveLength)); + moveLength -= 0.3; //update the last used block to the one we just used, if it's actually different. - if(floorX!=CommonUtil.floorDouble(this.posX) || floorZ != CommonUtil.floorDouble(this.posZ)) { - floorX = CommonUtil.floorDouble(this.posX); - floorY = CommonUtil.floorDouble(this.posY); - floorZ = CommonUtil.floorDouble(this.posZ); + if(xFloor!=CommonUtil.floorDouble(this.posX) || zFloor != CommonUtil.floorDouble(this.posZ)) { xFloor = CommonUtil.floorDouble(this.posX); yFloor = CommonUtil.floorDouble(this.posY); zFloor = CommonUtil.floorDouble(this.posZ); blockCurrent=CommonUtil.getBlockAt(getWorld(),xFloor,yFloor,zFloor); //check for collisions and skip update for (int i = 1; i < host.getHitboxSize()[1] - 1; i++) { - blockUp = CommonUtil.getBlockAt(getWorld(), floorX, floorY + i, floorZ); + blockUp = CommonUtil.getBlockAt(getWorld(), xFloor, yFloor + i, zFloor); if (!(blockUp instanceof BlockAir)) { - host.frontBogie.motionX=0; - host.frontBogie.motionZ=0; host.backBogie.motionX=0; host.backBogie.motionZ=0; + host.frontBogie.motionX=0; + host.frontBogie.motionZ=0; return; } } //handle slope movement before other interactions - if(!CommonUtil.isRailBlockAt(getWorld(), floorX, floorY, floorZ)){ + if(!CommonUtil.isRailBlockAt(getWorld(), xFloor, yFloor, zFloor)){ this.prevPosY =posY; - if(CommonUtil.isRailBlockAt(getWorld(), floorX, floorY+1, floorZ)){ + if(CommonUtil.isRailBlockAt(getWorld(), xFloor, yFloor+1, zFloor)){ posY++; - } else if (CommonUtil.isRailBlockAt(getWorld(), floorX, floorY-1, floorZ)) { + } else if (CommonUtil.isRailBlockAt(getWorld(), xFloor, yFloor-1, zFloor)) { posY--; } - floorY = CommonUtil.floorDouble(this.posY); + yFloor = CommonUtil.floorDouble(this.posY); } - blockNext = CommonUtil.getBlockAt(getWorld(), floorX, floorY, floorZ); + blockNext = CommonUtil.getBlockAt(getWorld(), xFloor, yFloor, zFloor); //now loop this again for the next increment of movement, if there is one if (blockNext instanceof BlockRailBase) { block = (BlockRailBase) blockNext; //do the rail functions. if(shouldDoRailFunctions()) { - block.onMinecartPass(getWorld(), this, new BlockPos(floorX, floorY, floorZ)); + block.onMinecartPass(getWorld(), this, xFloor, yFloor, zFloor); } //get the direction of the rail from it's metadata - railMetadata = CommonUtil.getRailMeta(getWorld(), this, floorX, floorY, floorZ); + railMetadata = CommonUtil.getRailMeta(getWorld(), this, xFloor, yFloor, zFloor); } //get the direction of the rail from it's metadata - /*TODO:railcraft support - else if (getWorld().getTileEntity(floorX, floorY, floorZ) instanceof ITrackTile && (((ITrackTile)getWorld().getTileEntity(floorX, floorY, floorZ)).getTrackInstance() instanceof ITrackSwitch)){ - railMetadata = CommonUtil.getRailMeta(getWorld(),this,floorX, floorY, floorZ);//railcraft support - }*/ + else if (getWorld().getTileEntity(xFloor, yFloor, zFloor) instanceof ITrackTile && (((ITrackTile)getWorld().getTileEntity(xFloor, yFloor, zFloor)).getTrackInstance() instanceof ITrackSwitch)){ + railMetadata = CommonUtil.getRailMeta(getWorld(),this,xFloor, yFloor, zFloor);//railcraft support + } } } } - private double[] moveBogieVanilla(double currentMotion, double floorX, double floorZ, double[] moveDirection){ - if(Math.abs(currentMotion)<0.00001){return new double[]{0,0};} + private void moveBogieVanilla(double currentMotion){ + if(Math.abs(currentMotion)<0.000001){return;} //figure out the current rail's direction railPathX = (martix[railMetadata][2][0]); railPathZ = (martix[railMetadata][2][1]); //cover moving reverse of track direction using the rotation from the closed loop rather than the full motion - if(moveDirection[0] * railPathX + moveDirection[1] * railPathZ <= 0.0D) { + if((velocity[0]+velocity[2]) * railPathX + (velocity[1]+velocity[3]) * railPathZ <= 0.0D) { railPathX = -railPathX; railPathZ = -railPathZ; } - //for every iteration of the loop, use the current movement direction to update the position - // and rotate movement for the next cycle. - //NOTE: when moving on corners both X and Z are 1 or -1, which would double speed. don't do that. - //for some reason it actually ends up as more than double speed. setPositionRelative((currentMotion * railPathX), 0, (currentMotion * railPathZ)); - motionSqrt = (Math.abs(moveDirection[0])+Math.abs(moveDirection[1])); - moveDirection[0] = motionSqrt * (railPathX); - moveDirection[1] = motionSqrt * (railPathZ); + motionSqrt = Math.abs(velocity[0])+Math.abs(velocity[1]); + velocity[0] = (float)(motionSqrt * railPathX); + velocity[1] = (float)(motionSqrt * railPathZ); + motionSqrt = Math.abs(velocity[2])+Math.abs(velocity[3]); + velocity[2] = (float)(motionSqrt * railPathX); + velocity[3] = (float)(motionSqrt * railPathZ); + + motionSqrt = Math.abs(velocity[0])+Math.abs(velocity[1])+Math.abs(velocity[2])+Math.abs(velocity[3]); //define the rail path again, to center the transport. - railPathX2 = floorX + 0.5D + martix[railMetadata][0][0]; - railPathZ2 = floorZ + 0.5D + martix[railMetadata][0][1]; - railPathX = (floorX + 0.5D + martix[railMetadata][1][0]) - railPathX2; - railPathZ = (floorZ + 0.5D + martix[railMetadata][1][1]) - railPathZ2; + railPathX2 = xFloor + 0.5D + martix[railMetadata][0][0]; + railPathZ2 = zFloor + 0.5D + martix[railMetadata][0][1]; + railPathX = (xFloor + 0.5D + martix[railMetadata][1][0]) - railPathX2; + railPathZ = (zFloor + 0.5D + martix[railMetadata][1][1]) - railPathZ2; //based on the path direction, try to center the bogie on the track if (railPathX == 0.0D) { - motionSqrt = this.posZ - floorZ; + motionSqrt = this.posZ - zFloor; } else if (railPathZ == 0.0D) { - motionSqrt = this.posX - floorX; + motionSqrt = this.posX - xFloor; } else { motionSqrt = ((this.posX - railPathX2) * railPathX + (this.posZ - railPathZ2) * railPathZ) * 2.0D; } //do the centering movement setPosition((railPathX2 + railPathX * motionSqrt), posY, (railPathZ2 + railPathZ * motionSqrt)); - //endMagic(); - - return moveDirection; } @@ -481,11 +504,11 @@ public void setPosition(double x, double y, double z) { public void setPositionRelative(double x, double y, double z) { - posX+=((int)(x*1000))*0.001; + posX+=((int)(x*10000))*0.0001; if(y!=0) {//usually we won't be changing this, so this is more efficient - posY += ((int) (y * 1000)) * 0.001; + posY += ((int) (y * 10000)) * 0.0001; } - posZ+=((int)(z*1000))*0.001; + posZ+=((int)(z*10000))*0.0001; } diff --git a/src/main/java/ebf/tim/entities/EntityTrainCore.java b/src/main/java/ebf/tim/entities/EntityTrainCore.java index 8f38cf4682..6fa81a453a 100644 --- a/src/main/java/ebf/tim/entities/EntityTrainCore.java +++ b/src/main/java/ebf/tim/entities/EntityTrainCore.java @@ -3,8 +3,8 @@ import ebf.tim.registry.NBTKeys; import ebf.tim.utility.CommonProxy; import ebf.tim.utility.CommonUtil; +import ebf.tim.utility.DebugUtil; import ebf.tim.utility.FuelHandler; -import fexcraft.tmt.slim.Vec3d; import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; @@ -99,9 +99,6 @@ public void initInventorySlots(){ } - @Override - public boolean hasDrag(){return getAccelerator()==0;} - //gets the throttle position as a percentage with 1 as max and -1 as max reverse public float getAcceleratorPercentage(){ switch (Math.abs(getAccelerator())){ @@ -121,7 +118,7 @@ public float getAcceleratorPercentage(){ */ public void calculateAcceleration(){ //core accel speed from TC4 - float accel=0.02f* getAcceleratorPercentage(); + float accel=0.0025f* getAcceleratorPercentage(); //buff to match engine type if(getTypes().contains(STEAM)){ accel*=0.35f; @@ -131,26 +128,14 @@ public void calculateAcceleration(){ accel*=0.7f; } //scale based on power and velocity - //TODO: velocity breaks this hard. dont do that. BS a similar result. - cachedVectors[2].xCoord=accel* (100f * (float)Math.pow(8f,((2.35f * -(0.3557/getPower()))-2.35f))); - - //add back in the speed from last tick, if speed was nulled from going into neutral, get it from the velocity. - if(cachedVectors[2].yCoord!=0) { - cachedVectors[2].xCoord += cachedVectors[2].yCoord; - } else { - cachedVectors[2].xCoord += getVelocity()*0.99; - } + cachedVectors[2].xCoord=accel* (10000f * (float)Math.pow(8f,((2.35f * -(0.3557/getPower()))-2.35f))); //if speed is greater than top speed from km/h to m/s divided by 20 to get per tick - if (cachedVectors[2].xCoord < -unRatio(transportTopSpeed())) { - cachedVectors[2].xCoord = -unRatio(transportTopSpeed()); - } else if (cachedVectors[2].xCoord > unRatio(transportTopSpeedReverse())) { - cachedVectors[2].xCoord = unRatio(transportTopSpeedReverse()); + if (Math.abs(frontBogie.velocity[0])+Math.abs(frontBogie.velocity[1]) > + unRatio(accelerator>0?transportTopSpeed():transportTopSpeedReverse())) { + cachedVectors[2].xCoord=0; } - //set the last tick speed to this speed. - cachedVectors[2].yCoord=cachedVectors[2].xCoord; - //handle ice slipping if(!getBoolean(boolValues.BRAKE)) { float slip = !getBoolean(boolValues.DERAILED)?-1.0f: @@ -191,40 +176,27 @@ public int getAccelerator(){ */ @Override public void onUpdate() { - if(frontBogie != null && backBogie != null) { - - if (!world.isRemote) { - //twice a second, re-calculate the speed. - if (accelerator!=0 && getBoolean(boolValues.RUNNING)) { - if(Math.abs(accelerator)!=8 && ticksExisted % 10 == 0) { - calculateAcceleration(); - } - } else { - accelerator = 0; - this.dataManager.set(ACCELERATOR, accelerator); + if(!worldObj.isRemote && backBogie != null && frontBogie != null) { + cachedVectors[2].xCoord = 0; + //twice a second, re-calculate the speed. + if (getAccelerator()!=0 && getBoolean(boolValues.RUNNING)) { + if(Math.abs(getAccelerator())!=8 && ticksExisted % 10 == 0) { + calculateAcceleration(); } - - if(accelerator==0 && getBoolean(boolValues.BRAKE) && getVelocity()==0){ - frontBogie.setVelocity(0,0,0); - backBogie.setVelocity(0,0,0); - cachedVectors[2].xCoord = 0; - } else { - //add drag to the accelerator - if(accelerator==0){ - cachedVectors[2].yCoord*=0.99f; - } else { - Vec3d velocity = CommonUtil.rotateDistance(cachedVectors[2].xCoord, 0, rotationYaw); - moveBogies(velocity.xCoord,velocity.zCoord); - } - } - + } else { + accelerator = 0; + this.dataWatcher.updateObject(18, getAccelerator()); } - updatePosition(); + if(getAccelerator()==0 && getBoolean(boolValues.BRAKE) && getVelocity()==0){ + backBogie.setVelocity(0,0,0); + frontBogie.setVelocity(0,0,0); + } else if(getAccelerator()!=0){ + appendMovement(cachedVectors[2].xCoord); + } } super.onUpdate(); - updatePosition(); if(hornDelay >0) { hornDelay--; @@ -299,7 +271,7 @@ public boolean interact(int player, boolean isFront, boolean isBack, int key) { switch (key){ case 8:{ //toggle ignition setBoolean(boolValues.RUNNING, !getBoolean(boolValues.RUNNING)); - updateConsist(); + updateLinks(); return true; }case 9:{ //plays a sound on all clients within hearing distance if(hornDelay ==0){ @@ -317,8 +289,8 @@ public boolean interact(int player, boolean isFront, boolean isBack, int key) { } else { accelerator--; } - updateConsist(); - this.dataManager.set(ACCELERATOR, accelerator); + updateLinks(); + this.dataWatcher.updateObject(18, accelerator); } return true; }case 3:{ //increase speed @@ -332,8 +304,8 @@ public boolean interact(int player, boolean isFront, boolean isBack, int key) { } else { accelerator++; } - updateConsist(); - this.dataManager.set(ACCELERATOR, accelerator); + updateLinks(); + this.dataWatcher.updateObject(18, accelerator); } return true; } case 16:{//reset speed @@ -343,8 +315,8 @@ public boolean interact(int player, boolean isFront, boolean isBack, int key) { return true; } accelerator = 0; - updateConsist(); - this.dataManager.set(ACCELERATOR, accelerator); + updateLinks(); + this.dataWatcher.updateObject(18, accelerator); } return true; } case 11:{//TC control forward @@ -352,24 +324,28 @@ public boolean interact(int player, boolean isFront, boolean isBack, int key) { accelerator = 7; this.dataManager.set(ACCELERATOR, accelerator); } + updateLinks(); return true; }case 12:{//TC control reverse if(getBoolean(boolValues.RUNNING)) { accelerator = -7; this.dataManager.set(ACCELERATOR, accelerator); } + updateLinks(); return true; }case 4: {//TC control, keep speed if(getBoolean(boolValues.RUNNING)) { accelerator = (int)Math.copySign(8,accelerator); this.dataManager.set(ACCELERATOR, accelerator); } + updateLinks(); return true; }case 14: {//TC control, keep speed if(getBoolean(boolValues.RUNNING)) { accelerator = 0; this.dataManager.set(ACCELERATOR, accelerator); } + updateLinks(); return true; } } diff --git a/src/main/java/ebf/tim/entities/GenericRailTransport.java b/src/main/java/ebf/tim/entities/GenericRailTransport.java index 3f87ddc45f..168e09b07b 100644 --- a/src/main/java/ebf/tim/entities/GenericRailTransport.java +++ b/src/main/java/ebf/tim/entities/GenericRailTransport.java @@ -67,6 +67,7 @@ import static ebf.tim.TrainsInMotion.transportTypes.*; import static ebf.tim.utility.CommonUtil.radianF; +import static ebf.tim.utility.CommonUtil.rotatePoint; /** *

Generic Rail Transport

@@ -137,7 +138,6 @@ public class GenericRailTransport extends EntityMinecart implements IEntityAddit private float ticksSinceLastVelocityChange=1; private List consist = new ArrayList<>(); - boolean consistListInUse=false;//use of consist variable needs to be thread safe. //@SideOnly(Side.CLIENT) public TransportRenderData renderData = new TransportRenderData(); @@ -412,13 +412,13 @@ public AxisAlignedBB getCollisionBox(Entity collidedWith){ public boolean canBeCollidedWith() {return true;} /**client only positioning of the transport, this should help to smooth the movement*/ @SideOnly(Side.CLIENT) - public void setPositionAndRotationDirect(double p_70056_1_, double p_70056_3_, double p_70056_5_, float p_70056_7_, float p_70056_8_, int p_70056_9_, boolean teleport) { - if (frontBogie!=null && backBogie!= null){ + public void setPositionAndRotation2(double p_70056_1_, double p_70056_3_, double p_70056_5_, float p_70056_7_, float p_70056_8_, int p_70056_9_) { + if (backBogie !=null && frontBogie != null){ - setRotation((float)Math.toDegrees(CommonUtil.atan2f( - frontBogie.posZ - backBogie.posZ, - frontBogie.posX - backBogie.posX)), - CommonUtil.calculatePitch(frontBogie.posY,backBogie.posY,Math.abs(rotationPoints()[0]) + Math.abs(rotationPoints()[1]))); + setRotation(CommonUtil.atan2degreesf( + backBogie.posZ - frontBogie.posZ, + backBogie.posX - frontBogie.posX), + CommonUtil.calculatePitch(backBogie.posY, frontBogie.posY,Math.abs(rotationPoints()[0]) + Math.abs(rotationPoints()[1]))); transportX=p_70056_1_; transportY=p_70056_3_; @@ -554,7 +554,7 @@ else if (p.getHeldItem(EnumHand.MAIN_HAND).getItem() instanceof ItemStake){ return true; }case 15: {//toggle brake setBoolean(boolValues.BRAKE, !getBoolean(boolValues.BRAKE)); - updateConsist(); + updateLinks(); return true; }case 5: { //Toggle lamp setBoolean(boolValues.LAMP, !getBoolean(boolValues.LAMP)); @@ -869,7 +869,14 @@ public NBTTagCompound writeToNBT(NBTTagCompound tag) { @Override protected void playStepSound(BlockPos pos, Block p_145780_4_) {} - public boolean hasDrag(){return consistLeadID==null || consistLeadID==getEntityId();} + public boolean hasDrag(){ + for(GenericRailTransport t:getConsist()){ + if(t.getAccelerator()!=0){ + return false; + } + } + return true; + } public void updatePosition(){ @@ -886,15 +893,7 @@ public void updatePosition(){ //this part keeps it capped getVelocity() < maxBoost(b)) { float boost = CommonUtil.getMaxRailSpeed(getWorld(), (BlockRailBase) b, this, posX, posY, posZ) * 0.005f; - frontBogie.addVelocity(//this part boosts in the current direction, scaled by the speed of the rail - Math.copySign(boost, frontBogie.motionX), - 0, - Math.copySign(boost, frontBogie.motionZ)); - - backBogie.addVelocity(//this part boosts in the current direction, scaled by the speed of the rail - Math.copySign(boost, backBogie.motionX), - 0, - Math.copySign(boost, backBogie.motionZ)); + appendMovement(Math.copySign(cachedVectors[2].yCoord,boost)); } } } else { @@ -925,7 +924,7 @@ public void updatePosition(){ //actually move - moveBogies(null,null); + finalMove(); //only update velocity if we've moved to any significance. if(Math.abs(posX-prevPosX)>0.0625 || Math.abs(posZ-prevPosZ)>0.0625) { motionX = (posX - prevPosX)/ticksSinceLastVelocityChange; @@ -943,39 +942,56 @@ public void updatePosition(){ } } + public void appendMovement(double velocity){ + + //the logic gets stupid if it's not sorted from one end or another. + //todo: this is a trash fix, it would be better for the list to be reliably sorted + if(frontLinkedID!=null && backLinkedID!=null){ + return; + } + GenericRailTransport last = this; + for(GenericRailTransport t:getConsist()) { + if(t.backLinkedID!=null && last.backLinkedID!=null + && last.getEntityId()==t.backLinkedID + && t.getEntityId()==last.backLinkedID){ + t.backBogie.addVelocity(t, -velocity); + t.frontBogie.addVelocity(t, -velocity); + } else if(t.frontLinkedID!=null && last.frontLinkedID!=null + && last.getEntityId()==t.frontLinkedID + && t.getEntityId()==last.frontLinkedID){ + t.backBogie.addVelocity(t, -velocity); + t.frontBogie.addVelocity(t, -velocity); + } else { + t.backBogie.addVelocity(t, velocity); + t.frontBogie.addVelocity(t, velocity); + } + } + } + public void addLinkingMove(double velocity){ + backBogie.addLinking(this, velocity); + frontBogie.addLinking(this, velocity); + } + /** * if X or Z is null, the bogie's existing motion velocity will be used */ - public void moveBogies(Double velocityX, Double velocityZ){ - //move the bogies with the track. - if(velocityX==null||velocityZ==null){ - frontBogie.minecartMove(this, frontBogie.motionX, frontBogie.motionZ); - backBogie.minecartMove(this, backBogie.motionX, backBogie.motionZ); - - } else if(velocityX!=0 || velocityZ!=0) { - frontBogie.minecartMove(this, velocityX, velocityZ); - backBogie.minecartMove(this, velocityX, velocityZ); - } - - //center the entity based on the back bogie position - cachedVectors[1] = new Vec3f(rotationPoints()[0], 0, 0).rotatePoint(rotationPitch, rotationYaw, 0); - setPosition((backBogie.posX + cachedVectors[1].xCoord), - (backBogie.posY + cachedVectors[1].yCoord), (backBogie.posZ + cachedVectors[1].zCoord)); - //re-center the front bogie - cachedVectors[1] = new Vec3f(-rotationPoints()[1], 0, 0).rotatePoint(rotationPitch, rotationYaw, 0); - if(Math.abs((cachedVectors[1].xCoord + posX) - frontBogie.posX)+ Math.abs((cachedVectors[1].zCoord + posZ) - frontBogie.posZ)>0.01) { - frontBogie.minecartMove(this, - ((cachedVectors[1].xCoord + posX) - frontBogie.posX), - ((cachedVectors[1].zCoord + posZ) - frontBogie.posZ)); - setPosition((backBogie.posX + cachedVectors[1].xCoord), - (backBogie.posY + cachedVectors[1].yCoord), (backBogie.posZ + cachedVectors[1].zCoord)); - } - + public void finalMove(){ + cachedVectors[1] = new Vec3f(-rotationPoints()[0], 0, 0).rotatePoint(0, rotationYaw, 0) + .addVector(backBogie.posX,backBogie.posY,backBogie.posZ); + setPosition(cachedVectors[1].xCoord, cachedVectors[1].yCoord,cachedVectors[1].zCoord); + + frontBogie.minecartMove(this); + backBogie.minecartMove(this); + //reset the y coord so they will re-calculate the yaw + if(hasDrag()) { + applyDrag(); + } + cachedVectors[2].yCoord=0; //update rotation setRotation((CommonUtil.atan2degreesf( - frontBogie.posZ - backBogie.posZ, - frontBogie.posX - backBogie.posX)), - CommonUtil.calculatePitch(backBogie.posY + backBogie.yOffset, frontBogie.posY + frontBogie.yOffset, Math.abs(rotationPoints()[0]) + Math.abs(rotationPoints()[1]))); + backBogie.posZ - frontBogie.posZ, + backBogie.posX - frontBogie.posX)), + CommonUtil.calculatePitch(frontBogie.posY + frontBogie.yOffset, backBogie.posY + backBogie.yOffset, Math.abs(rotationPoints()[0]) + Math.abs(rotationPoints()[1]))); //reset the vector when we're done so it wont break trains. cachedVectors[1]= new Vec3f(0,0,0); @@ -1003,60 +1019,54 @@ public void moveBogies(Double velocityX, Double velocityZ){ */ @Override public void applyDrag(){ - if(pullingWeight==0){ - updateConsist(); + boolean canSlope=true; + float drag = 0.9998f, brakeBuff = 0, slope = 0; + //check if lope things can be done at all + for(GenericRailTransport stock : getConsist()) { + if(stock!=this && getAccelerator()!=0){ + canSlope=false; + break; + } } - - if(frontLinkedID==null || backLinkedID==null) { - - float drag = 0.9998f,brakeBuff=0,slopeX=0,slopeZ=0; - //iterate the consist to collect the stats, since only end units can do this. - for(GenericRailTransport stock : getConsist()) { - if(stock.getBoolean(boolValues.BRAKE)){ - //realistically would be more like 2.4, but 5 makes gameplay more dramatic - brakeBuff+=stock.weightKg()*5.0f; - } - if(stock.rotationPitch!=0 && getAccelerator()==0){ - //vanilla uses 0.0078125 per tick for slope speed. - //0.00017361 would be that divided by 45 since vanilla slopes are 45 degree angles. - //so we buff that to just under double to balance against drag, then scale by entity pitch - //pith goes from -90 to 90, so it's inherently directional. - slopeX+=(0.000017361f*0.5f)*-stock.rotationPitch; - } + if(canSlope) { + if (getBoolean(boolValues.BRAKE)) { + //realistically would be more like 2.4, but 5 makes gameplay more dramatic + brakeBuff += weightKg() * 5.0f; } - - //scale drag for derail, or air lateral friction. if you do both at the same time then it's way too much. - if(getBoolean(boolValues.DERAILED)){ - drag*=CommonUtil.getBlockAt(getWorld(),posX,posY,posZ).slipperiness; - } else if (cachedVectors[2].yCoord > 0) { - drag -= ((getFriction() * cachedVectors[2].yCoord * 4.448f)); + if (rotationPitch != 0) { + //vanilla uses 0.0078125 per tick for slope speed. + //0.00017361 would be that divided by 45 since vanilla slopes are 45 degree angles. + //scale by entity pitch + //pitch goes from -90 to 90, so it's inherently directional, stop that. + slope += (0.00017361f) * Math.abs(rotationPitch); } + appendMovement(slope * MathHelper.sin((rotationYaw-90)*radianF)); + } - //add in the drag from combined weight, plus brakes. - if(pullingWeight!=0) {//in theory this should never be 0, but we know forge is dumb - drag -= ((getAccelerator()==0?getFriction()*0.75:getFriction()*2.5) * (pullingWeight + brakeBuff)) / 44480; - } - //cap the drag to prevent weird behavior. - // if it goes to 1 or higher then we speed up, which is bad, if it's below 0 we reverse, which is also bad - if (drag > 0.9999f) { - drag = 0.9999f; - } else if (drag < 0f) { - drag = 0f; - } + //now do drag stuff - //split the slope buff into X and Z, then rotate based on yaw. - if (rotationYaw != 0.0F) { - slopeZ = (slopeX * MathHelper.sin((rotationYaw-90)*radianF)); - slopeX = (slopeX * MathHelper.cos((rotationYaw-90)*radianF)); - } - frontBogie.setVelocity( - (frontBogie.motionX * drag)+slopeX - , frontBogie.motionY, - (frontBogie.motionZ * drag)+slopeZ); - backBogie.setVelocity( - (backBogie.motionX * drag)+slopeX, - backBogie.motionY, - (backBogie.motionZ * drag)+slopeZ); + //scale drag for derail, or air lateral friction. if you do both at the same time then it's way too much. + if(getBoolean(boolValues.DERAILED)){ + drag*=CommonUtil.getBlockAt(getWorld(),posX,posY,posZ).slipperiness; + } else if (cachedVectors[2].yCoord > 0) { + drag -= ((getFriction() * cachedVectors[2].yCoord * 4.448f)); + } + + //add in the drag from combined weight, plus brakes. + if(pullingWeight!=0) {//in theory this should never be 0, but we know forge is dumb + drag -= ((getAccelerator()==0?getFriction()*0.75:getFriction()*2.5) * (pullingWeight + brakeBuff)) / 44480; + } + //cap the drag to prevent weird behavior. + // if it goes to 1 or higher then we speed up, which is bad, if it's below 0 we reverse, which is also bad + if (drag > 0.9999f) { + drag = 0.9999f; + } else if (drag < 0f) { + drag = 0f; + } + + for(GenericRailTransport t : getConsist()){ + t.frontBogie.drag(t,drag); + t.backBogie.drag(t,drag); } } @@ -1118,10 +1128,10 @@ public void onUpdate() { //always be sure the bogies exist on client and server. if (!getWorld().isRemote && (frontBogie == null || backBogie == null)) { //spawn front bogie - cachedVectors[1] = new Vec3f(rotationPoints()[0],0,0).rotatePoint(rotationPitch, rotationYaw,0); + cachedVectors[1] = new Vec3f(rotationPoints()[1],0,0).rotatePoint(rotationPitch, rotationYaw,0); frontBogie = new EntityBogie(getWorld(), posX + cachedVectors[1].xCoord, posY + cachedVectors[1].yCoord, posZ + cachedVectors[1].zCoord, getEntityId(), true); //spawn back bogie - cachedVectors[1] = new Vec3f(rotationPoints()[1],0,0).rotatePoint(rotationPitch, rotationYaw,0); + cachedVectors[1] = new Vec3f(rotationPoints()[0],0,0).rotatePoint(rotationPitch, rotationYaw,0); backBogie = new EntityBogie(getWorld(), posX + cachedVectors[1].xCoord, posY + cachedVectors[1].yCoord, posZ + cachedVectors[1].zCoord, getEntityId(), false); getWorld().spawnEntity(frontBogie); @@ -1176,16 +1186,15 @@ public void onUpdate() { } } - velocity[1] = (float) ((Math.abs(posX) - Math.abs(prevPosX)) + (Math.abs(posZ) - Math.abs(prevPosZ))); - if (frontBogie != null && backBogie != null) { - frontBogie.minecartMove(this, frontBogie.motionX, frontBogie.motionZ); - backBogie.minecartMove(this, frontBogie.motionX, frontBogie.motionZ); + if (backBogie != null && frontBogie != null) { + backBogie.minecartMove(this); + frontBogie.minecartMove(this); setRotation(CommonUtil.atan2degreesf( - frontBogie.posZ - backBogie.posZ, - frontBogie.posX - backBogie.posX), + backBogie.posZ - frontBogie.posZ, + backBogie.posX - frontBogie.posX), CommonUtil.calculatePitch( - backBogie.posY, frontBogie.posY, + frontBogie.posY, backBogie.posY, Math.abs(rotationPoints()[0]) + Math.abs(rotationPoints()[1]))); } if(ClientProxy.EnableAnimations && renderData!=null && renderData.bogies!=null){ @@ -1217,31 +1226,28 @@ public void onUpdate() { * * this stops updating if the transport derails. Why update positions of something that doesn't move? We compensate for first tick to be sure hitboxes, bogies, etc, spawn on join. */ - else if (frontBogie!=null && backBogie != null && ticksExisted>5){ + else if (backBogie !=null && frontBogie != null && ticksExisted>5){ + if((frontLinkedID!=null || backLinkedID!=null) && getConsist().size()==1){ + updateLinks(); + } //calculate for slopes, friction, and drag if (hasDrag()) { applyDrag(); } //update positions related to linking, this NEEDS to come after drag - //only run updates if either the front link or the back link is null. - //if there is a consist lead, only the lead can run updates - if(consistLeadID!=null && consistLeadID==getEntityId()){ - GenericRailTransport last = null; - for (GenericRailTransport transport : getConsist()){ - if(last!=null) { - last.manageLink(transport); - } - last = transport; - } - } else if (consistLeadID==null){ - if(frontLinkedID!=null && getWorld().getEntityByID(frontLinkedID) instanceof GenericRailTransport){ - manageLink((GenericRailTransport) getWorld().getEntityByID(frontLinkedID)); - } - if(backLinkedID!=null && getWorld().getEntityByID(backLinkedID) instanceof GenericRailTransport){ - manageLink((GenericRailTransport) getWorld().getEntityByID(backLinkedID)); - } - } + if(frontLinkedID!=null && getWorld().getEntityByID(frontLinkedID) instanceof GenericRailTransport){ + manageLink((GenericRailTransport) getWorld().getEntityByID(frontLinkedID)); + } + if(backLinkedID!=null && getWorld().getEntityByID(backLinkedID) instanceof GenericRailTransport){ + manageLink((GenericRailTransport) getWorld().getEntityByID(backLinkedID)); + } + //for some off reason, this madness works pretty reliably from my tests. + cachedVectors[1]=new Vec3f(rotationPoints()[1],0,0).rotatePoint(0,rotationYaw,0) + .addVector(posX,0,posZ).subtract((float)frontBogie.posX,0,(float)frontBogie.posZ); + frontBogie.velocity[2]+=cachedVectors[1].xCoord; + frontBogie.velocity[3]+=cachedVectors[1].zCoord; + updatePosition(); if(collisionHandler!=null){ collisionHandler.updateCollidingEntities(this); @@ -1252,10 +1258,6 @@ else if (frontBogie!=null && backBogie != null && ticksExisted>5){ manageCollision(pos); } } - - if(!(this instanceof EntityTrainCore)) { - updatePosition(); - } } //reposition the seats here to force the hand rather than relying on the update rider method @@ -1319,7 +1321,7 @@ else if (frontBogie!=null && backBogie != null && ticksExisted>5){ } } - if (backBogie!=null && !isDead && getWorld().isRemote) { + if (frontBogie !=null && !isDead && getWorld().isRemote) { //handle particles if (ClientProxy.EnableParticles){ if(getParticles().size()>0) { @@ -1365,6 +1367,7 @@ public void manageCollision(Entity e){ colliding.host.setFrontLinkedTransport(this); setFrontLinkedTransport(colliding.host); + updateConsist(); EntityPlayer listener = getWorld().getClosestPlayerToEntity(this,20); if(listener!=null){ @@ -1378,6 +1381,7 @@ public void manageCollision(Entity e){ } else if(colliding.host.getBoolean(boolValues.COUPLINGBACK)){ colliding.host.setbackLinkedTransport(this); setFrontLinkedTransport(colliding.host); + updateConsist(); EntityPlayer listener = getWorld().getClosestPlayerToEntity(this,20); if(listener!=null){ listener.sendMessage(new TextComponentString("Linked the " + @@ -1397,6 +1401,7 @@ public void manageCollision(Entity e){ colliding.host.setFrontLinkedTransport(this); setbackLinkedTransport(colliding.host); + updateConsist(); EntityPlayer listener = getWorld().getClosestPlayerToEntity(this,20); if(listener!=null){ listener.sendMessage(new TextComponentString("Linked the " + @@ -1408,6 +1413,7 @@ public void manageCollision(Entity e){ } else if(colliding.host.getBoolean(boolValues.COUPLINGBACK)) { colliding.host.setbackLinkedTransport(this); setbackLinkedTransport(colliding.host); + updateConsist(); EntityPlayer listener = getWorld().getClosestPlayerToEntity(this,20); if(listener!=null){ listener.sendMessage(new TextComponentString("Linked the " + @@ -1419,29 +1425,35 @@ public void manageCollision(Entity e){ } } - //calculate the distance to yeet based on how far one pushed into the other - double[] motion = CommonUtil.rotatePoint( - Math.max(Math.abs(getVelocity()), (Math.abs(colliding.host.getVelocity()))*0.25)+0.05, - 0, CommonUtil.atan2degreesf(e.posZ-posZ, e.posX-posX)); - if (getBoolean(boolValues.BRAKE)) { - moveBogies(-motion[0]*0.5,-motion[2]*0.5); + appendMovement(-(Math.max(Math.abs(getVelocity()), (Math.abs(colliding.host.getVelocity()))*0.25)+0.05)*0.5); } else { - moveBogies(-motion[0],-motion[2]); + appendMovement(-(Math.max(Math.abs(getVelocity()), (Math.abs(colliding.host.getVelocity()))*0.25)+0.05)); } if (colliding.host.getBoolean(boolValues.BRAKE)) { - colliding.host.moveBogies(motion[0]*0.5,motion[2]*0.5); + appendMovement((Math.max(Math.abs(getVelocity()), (Math.abs(colliding.host.getVelocity()))*0.25)+0.05)*0.5); } else { - colliding.host.moveBogies(motion[0],motion[2]); + appendMovement((Math.max(Math.abs(getVelocity()), (Math.abs(colliding.host.getVelocity()))*0.25)+0.05)); } } else if (e instanceof EntityPlayer || e instanceof EntityLiving) { - if (CommonProxy.pushabletrains && - !getBoolean(boolValues.BRAKE) && getAccelerator() == 0 && getVelocity() < 0.01) { - double[] motion = CommonUtil.rotatePoint(0.25, 0, - CommonUtil.atan2degreesf(posZ - e.posZ, posX - e.posX)); - moveBogies(motion[0], motion[2]); + if (CommonProxy.pushabletrains && !getBoolean(boolValues.BRAKE)) { + for (GenericRailTransport t: getConsist()){ + if(t.getAccelerator()!=0){ + return; + } + } + + double distanceFront = Math.sqrt((e.posX - collisionHandler.front.posX) * (e.posX - collisionHandler.front.posX) + + (e.posZ - collisionHandler.front.posZ) * (e.posZ - collisionHandler.front.posZ)); + double distanceBack = Math.sqrt((e.posX - collisionHandler.back.posX) * (e.posX - collisionHandler.back.posX) + + (e.posZ - collisionHandler.back.posZ) * (e.posZ - collisionHandler.back.posZ)); + if (distanceFront transports = new ArrayList<>(); + List IDs = new ArrayList<>(); Integer lead=null; - GenericRailTransport link=null; + GenericRailTransport link=this; + transports.add(link); + IDs.add(getEntityId()); + if(getAccelerator()!=0){ + lead=getEntityId(); + } if(frontLinkedID!=null){ link =(GenericRailTransport) getWorld().getEntityByID(frontLinkedID); } @@ -1496,14 +1512,14 @@ public void updateConsist(){ lead=link.getEntityId(); } transports.add(link); - if (link.frontLinkedID != null && getWorld().getEntityByID(link.frontLinkedID) instanceof GenericRailTransport) { + IDs.add(link.getEntityId()); + if (link.frontLinkedID != null && !IDs.contains(link.frontLinkedID)) { link = (GenericRailTransport) getWorld().getEntityByID(link.frontLinkedID); - } else if (link.backLinkedID != null && getWorld().getEntityByID(link.backLinkedID) instanceof GenericRailTransport) { + } else if (link.backLinkedID != null && !IDs.contains(link.backLinkedID)) { link = (GenericRailTransport) getWorld().getEntityByID(link.backLinkedID); } } else { link = null; - break; } } //repeat for back link @@ -1516,26 +1532,38 @@ public void updateConsist(){ lead=link.getEntityId(); } transports.add(link); - if (link.frontLinkedID != null && getWorld().getEntityByID(link.frontLinkedID) instanceof GenericRailTransport) { + IDs.add(link.getEntityId()); + if (link.frontLinkedID != null && !IDs.contains(link.frontLinkedID)) { link = (GenericRailTransport) getWorld().getEntityByID(link.frontLinkedID); - } else if (link.backLinkedID != null && getWorld().getEntityByID(link.backLinkedID) instanceof GenericRailTransport) { + } else if (link.backLinkedID != null && !IDs.contains(link.backLinkedID)) { link = (GenericRailTransport) getWorld().getEntityByID(link.backLinkedID); } } else { link = null; - break; } } - if(transports.size()>0) { - //now tell everything in the list, including this, that there's a new list, and provide said list. - for (GenericRailTransport t : transports) { - t.setValuesOnLinkUpdate(transports); - t.consistLeadID=lead; - } + for(GenericRailTransport t:transports){ + t.consist=transports; + t.consistLeadID=lead; } + + updateLinks(); } + public void updateLinks(){ + Integer running=null; + for (GenericRailTransport t : getConsist()) { + if(t.getAccelerator()!=0){ + running=t.getEntityId(); + } + } + //now tell everything in the list, including this, that there's a new list, and provide said list. + for (GenericRailTransport t : getConsist()) { + t.setValuesOnLinkUpdate(getConsist()); + t.consistLeadID=running; + } + } /** * called on linking changes and when a train changes running states @@ -1554,6 +1582,9 @@ public void setValuesOnLinkUpdate(List consist){ * May return a 0 length array when consist is being updated. */ public List getConsist(){ + if(consist.size()<2 && frontLinkedID!=null && backLinkedID!=null){ + updateConsist(); + } if(consist.size()>0) { return consist; } else { @@ -1591,85 +1622,36 @@ public boolean shouldRiderSit(){ * If coupling is on then it will check sides without linked transports for anything to link to. */ public void manageLink(GenericRailTransport other) { - if(other.frontBogie==null || other.backBogie==null || frontBogie==null || backBogie==null){ + if(other.backBogie ==null || other.frontBogie ==null || backBogie ==null || frontBogie ==null){ return; } - - boolean adj1 = other.canBeAdjusted(this); - boolean adj2 = this.canBeAdjusted(other); - - double d = other.posX - this.posX; - double d1 = other.posZ - this.posZ; - double vecX = other.posX - this.posX; - double vecZ = other.posZ - this.posZ; - - double cart1MotionX=0; - double cart1MotionZ=0; - double cart2MotionX=0; - double cart2MotionZ=0; - - - //spring to distance - double vecNorm = MathHelper.sqrt((d * d) + (d1 * d1)) - - (other.getOptimalDistance(this)+this.getOptimalDistance(other)); - - double springX = -0.4D * vecNorm * vecX; - double springZ = -0.4D * vecNorm * vecZ; - - if(springX>14d || springX<-14d){ - springX=Math.copySign(14d, springX); - } - if(springZ>14d || springZ<-14d){ - springZ=Math.copySign(14d, springZ); - } - - if (adj1) { - cart1MotionX += springX; - cart1MotionZ += springZ; - } - if (adj2) { - cart2MotionX -= springX; - cart2MotionZ -= springZ; + if(getAccelerator()!=0){ + return; } + double vecX = other.posX - posX; + double vecZ = other.posZ - posZ; - //dampen spring to smooth out - vecNorm = MathHelper.sqrt(vecX * vecX + vecZ * vecZ); - vecX /= vecNorm; - vecZ /= vecNorm; - - vecNorm = (cart1MotionX - cart2MotionX) * vecX + (cart1MotionZ - cart2MotionZ) * vecZ; - springX = -0.4D * vecNorm * vecX; - springZ = -0.4D * vecNorm * vecZ; - if(springX>14d || springX<-14d){ - springX=Math.copySign(14d, springX); - } - if(springZ>14d || springZ<-14d){ - springZ=Math.copySign(14d, springZ); - } + double springDist = MathHelper.sqrt_double(vecX * vecX + vecZ * vecZ) + -(getOptimalDistance(other)+other.getOptimalDistance(this)); - if (adj1) { - cart1MotionX += springX; - cart1MotionZ += springZ; - } - if (adj2) { - cart2MotionX -= springX; - cart2MotionZ -= springZ; + if(getVelocity()>0.3) { + springDist *= 0.45; + } else if (getVelocity()<0.1){ + springDist*=0.1; + } else { + springDist*=0.3; } - - //move bogies - if((cart1MotionX!=0 || cart1MotionZ!=0) && other.getAccelerator()==0) { - other.moveBogies(cart1MotionX, cart1MotionZ); + if(frontLinkedID!=null && other.getEntityId() == frontLinkedID) { + springDist *= -1; } - if((cart2MotionX!=0 || cart2MotionZ!=0) && getAccelerator()==0) { - this.moveBogies(cart2MotionX, cart2MotionZ); + if(Math.abs(springDist)>0.01) { + addLinkingMove(springDist); } - } - /** *

Permissions handler

* Used to check if the player has permission to do whatever it is the player is trying to do. Yes I could be more vague with that. @@ -1806,8 +1788,7 @@ public List getParticles(){ @SideOnly(Side.CLIENT) - public boolean isInRangeToRenderDist(double p_70112_1_) - { + public boolean isInRangeToRenderDist(double p_70112_1_) { return p_70112_1_ > 1D; } diff --git a/src/main/java/ebf/tim/networking/PacketUpdateClients.java b/src/main/java/ebf/tim/networking/PacketUpdateClients.java index e6ee8575ca..7809888be0 100644 --- a/src/main/java/ebf/tim/networking/PacketUpdateClients.java +++ b/src/main/java/ebf/tim/networking/PacketUpdateClients.java @@ -32,6 +32,7 @@ public void fromBytes(ByteBuf bbuf) { Entity e = Minecraft.getMinecraft().world.getEntityByID(bbuf.readInt()); if (e instanceof GenericRailTransport) { ((GenericRailTransport)e).entityData= new XmlBuilder(ByteBufUtils.readUTF8String(bbuf)); + ((GenericRailTransport) e).renderData.needsModelUpdate=true; } } /**puts the variables into a Byte Buffer so they can be sent to server*/ diff --git a/src/main/java/ebf/tim/render/RenderWagon.java b/src/main/java/ebf/tim/render/RenderWagon.java index 9db1e2260d..622bf5f408 100644 --- a/src/main/java/ebf/tim/render/RenderWagon.java +++ b/src/main/java/ebf/tim/render/RenderWagon.java @@ -62,13 +62,8 @@ public ResourceLocation getEntityTexture(GenericRailTransport entity){ /*@Override public void doRender(Entity entity, double x, double y, double z, float yaw, float partialTick){ if (entity instanceof GenericRailTransport){ - if(((GenericRailTransport) entity).frontBogie!=null) { - render((GenericRailTransport) entity, x, y, z, entity.prevRotationYaw + CommonUtil.wrapAngleTo180(entity.rotationYaw - entity.prevRotationYaw) * partialTick, - false); - } else { - render((GenericRailTransport) entity, x, y, z, entity.rotationYaw + CommonUtil.wrapAngleTo180(entity.rotationYaw - entity.prevRotationYaw) * partialTick, - true); - } + render((GenericRailTransport) entity, x, y, z, entity.rotationYaw + CommonUtil.wrapAngleTo180(entity.rotationYaw - entity.prevRotationYaw) * partialTick, + ((GenericRailTransport) entity).backBogie==null); } }*/ @@ -95,12 +90,14 @@ public void doRenderShadowAndFire(Entity entityIn, double x, double y, double z, {} public void render(GenericRailTransport entity, double x, double y, double z, float yaw, boolean isPaintBucket) { - doRender(entity,x,y,z,yaw,entity.frontBogie!=null?entity.frontBogie.yOffset:0, isPaintBucket, null, this); + renderBlocks=field_147909_c; + doRender(entity,x,y,z,yaw,entity.backBogie!=null?entity.backBogie.yOffset:0, isPaintBucket, null, this); } public void render(GenericRailTransport entity, double x, double y, double z, float yaw, boolean isPaintBucket, TransportSkin textureURI) { - doRender(entity,x,y,z,yaw,entity.frontBogie!=null?entity.frontBogie.yOffset:0, isPaintBucket, textureURI, this); + renderBlocks=field_147909_c; + doRender(entity,x,y,z,yaw,entity.backBogie !=null?entity.backBogie.yOffset:0, isPaintBucket, textureURI, this); } /** @@ -285,7 +282,7 @@ public static void doRender(GenericRailTransport entity, double x, double y, dou //set the render position GL11.glTranslated(x, y+ railOffset +bogieOffset+1.5, z); - GL11.glTranslated(0, -CommonUtil.rotatePoint(new Vec3f( + GL11.glTranslated(0, CommonUtil.rotatePoint(new Vec3f( Math.abs(entity.rotationPoints()[0])+Math.abs(entity.rotationPoints()[1]), 0,0), entity.rotationPitch,0,0).yCoord, 0); if(entity.frontBogie!=null && entity.backBogie!=null){ diff --git a/src/main/java/ebf/tim/utility/CommonUtil.java b/src/main/java/ebf/tim/utility/CommonUtil.java index c24fbf84bf..5154131bea 100644 --- a/src/main/java/ebf/tim/utility/CommonUtil.java +++ b/src/main/java/ebf/tim/utility/CommonUtil.java @@ -381,6 +381,23 @@ public static float power(float base, float power){ return (float)Math.pow(base,power); } + public static double getDistanceWithDirection(double fromX, double fromZ, double toX, double toZ, float rotationYaw) { + + double lookX = MathHelper.cos(-rotationYaw * 0.017453292F - (float) Math.PI); + double lookZ = -MathHelper.sin(-rotationYaw * 0.017453292F - (float) Math.PI); + + double vecX=fromX-toX; + double vecZ=fromZ-toZ; + + double dotProduct = vecX * lookX + vecZ * lookZ; + + if (dotProduct < 0) { + // Player 2 is behind Player 1 + return -Math.sqrt(dotProduct); + } else { + return Math.sqrt(dotProduct); + } + } /** *

rotate vector

diff --git a/src/main/java/ebf/tim/utility/FuelHandler.java b/src/main/java/ebf/tim/utility/FuelHandler.java index d6db614e38..ebed650c9a 100644 --- a/src/main/java/ebf/tim/utility/FuelHandler.java +++ b/src/main/java/ebf/tim/utility/FuelHandler.java @@ -189,7 +189,8 @@ public void manageSteam(EntityTrainCore train){ train.fill(getUseableFluid(train.waterSlot().getSlotID(),train), true); if (!train.getBoolean(GenericRailTransport.boolValues.CREATIVE)) { train.getSlotIndexByID(train.waterSlot().getSlotID()).decrStackSize(1); - train.addItem(new ItemStack(Items.BUCKET)); + train.addItem(new ItemStack(Items.bucket)); + train.markDirty(); } } @@ -418,11 +419,11 @@ public static void manageElectricFuel(EntityTrainCore train){ public static void manageTanker(GenericRailTransport transport){ if (getUseableFluid(transport.tankerInputSlot().getSlotID(),transport) !=null && - transport.fill(getUseableFluid(transport.tankerInputSlot().getSlotID(),transport),false)==getUseableFluid(transport.tankerInputSlot().getSlotID(),transport).amount) { - transport.fill(getUseableFluid(transport.tankerInputSlot().getSlotID(),transport), true); + transport.fill(null,getUseableFluid(transport.tankerInputSlot().getSlotID(),transport),false)==getUseableFluid(transport.tankerInputSlot().getSlotID(),transport).amount) { + transport.fill(null,getUseableFluid(transport.tankerInputSlot().getSlotID(),transport), true); if (!transport.getBoolean(GenericRailTransport.boolValues.CREATIVE)) { transport.getSlotIndexByID(transport.tankerInputSlot().getSlotID()).decrStackSize(1); - transport.addItem(new ItemStack(Items.BUCKET)); + transport.addItem(new ItemStack(Items.bucket)); } } //attempt to fill any buckets in the drain slot diff --git a/src/main/java/ebf/tim/utility/HitboxDynamic.java b/src/main/java/ebf/tim/utility/HitboxDynamic.java index f617158d8a..7415358749 100644 --- a/src/main/java/ebf/tim/utility/HitboxDynamic.java +++ b/src/main/java/ebf/tim/utility/HitboxDynamic.java @@ -19,6 +19,7 @@ public class HitboxDynamic { private float longest=0; public List interactionBoxes = new ArrayList<>(); + public CollisionBox front,back; public HitboxDynamic(float depth, float height, float width, GenericRailTransport entity){ @@ -40,7 +41,12 @@ public HitboxDynamic(float depth, float height, float width, GenericRailTranspor width*0.5,height,width*0.5)); c.setPosition(entity.posX, entity.posY, entity.posZ); interactionBoxes.add(c); - entity.world.spawnEntity(c); + entity.worldObj.spawnEntityInWorld(c); + if(front==null){ + front=c; + } else{ + back=c; + } } } } diff --git a/src/main/java/fexcraft/tmt/slim/CylinderBuilder.java b/src/main/java/fexcraft/tmt/slim/CylinderBuilder.java index e08eeff539..8ebb699163 100644 --- a/src/main/java/fexcraft/tmt/slim/CylinderBuilder.java +++ b/src/main/java/fexcraft/tmt/slim/CylinderBuilder.java @@ -276,4 +276,4 @@ public ModelRendererTurbo build(){ root.faces.addAll(polis); return root; } -} +} \ No newline at end of file diff --git a/src/main/java/fexcraft/tmt/slim/ModelPool.java b/src/main/java/fexcraft/tmt/slim/ModelPool.java index c9b1821bd7..93c9b15527 100644 --- a/src/main/java/fexcraft/tmt/slim/ModelPool.java +++ b/src/main/java/fexcraft/tmt/slim/ModelPool.java @@ -27,8 +27,8 @@ public static ModelPoolEntry addFile(String file, Class modelClass){ System.out.println(e.getMessage()); return null; } - File modelFile = entry.checkValidPath(file.substring(5)); - if(modelFile == null || !modelFile.exists()){ + InputStream modelFile = entry.checkValidPath(file.substring(5)); + if(modelFile == null){ System.out.println("The model with the name " + file + " does not exist."); return null; } @@ -54,22 +54,15 @@ public static ModelPoolEntry addFileF(String file, Class modelClass) throws I System.out.println(e.getMessage()); return null; } - File modelFile = null; InputStream in = entry.getClass().getResourceAsStream("/assets/" + file + ".obj"); - File tempfile = File.createTempFile(file, ".obj"); - FileOutputStream out = new FileOutputStream(tempfile); - tempfile.deleteOnExit(); - IOUtils.copy(in, out); - System.out.println("RENDER: " + tempfile.getPath().toString()); - modelFile = tempfile; - if(modelFile == null || !modelFile.exists()){ + if(in == null){ System.out.println("The model with the name " + file + " does not exist."); return null; } entry.textures = new HashMap(); entry.name = file; entry.setTextureGroup("0"); - entry.getModel(modelFile); + entry.getModel(in); modelMap.put(file, entry); return entry; } diff --git a/src/main/java/fexcraft/tmt/slim/ModelPoolEntry.java b/src/main/java/fexcraft/tmt/slim/ModelPoolEntry.java index 097512992d..ebf3412115 100644 --- a/src/main/java/fexcraft/tmt/slim/ModelPoolEntry.java +++ b/src/main/java/fexcraft/tmt/slim/ModelPoolEntry.java @@ -1,6 +1,7 @@ package fexcraft.tmt.slim; import java.io.File; +import java.io.InputStream; import java.util.Collection; import java.util.Iterator; import java.util.Map; @@ -13,15 +14,11 @@ public abstract class ModelPoolEntry { public Map textures; protected TextureGroup texture; - public File checkValidPath(String path){ - File file = new File(path); - if(!file.exists()){ - return null; - } - return file; + public InputStream checkValidPath(String path){ + return getClass().getResourceAsStream(path); } - public abstract void getModel(File file); + public abstract void getModel(InputStream file); /** * Sets the current texture group, which is used to switch the diff --git a/src/main/java/fexcraft/tmt/slim/ModelPoolObjEntry.java b/src/main/java/fexcraft/tmt/slim/ModelPoolObjEntry.java index 2f38ad390e..5e85531d82 100644 --- a/src/main/java/fexcraft/tmt/slim/ModelPoolObjEntry.java +++ b/src/main/java/fexcraft/tmt/slim/ModelPoolObjEntry.java @@ -1,17 +1,15 @@ package fexcraft.tmt.slim; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; +import java.io.*; import java.util.ArrayList; public class ModelPoolObjEntry extends ModelPoolEntry { public ModelPoolObjEntry(){} - public void getModel(File file){ + public void getModel(InputStream file){ try{ - BufferedReader in = new BufferedReader(new FileReader(file)); + BufferedReader in = new BufferedReader(new InputStreamReader(file)); String s; ArrayList verts = new ArrayList(); ArrayList uvs = new ArrayList();