ForgePatch/patches/minecraft/net/minecraft/src/EntityMinecart.java.patch

976 lines
32 KiB
Diff

--- ../src_base/minecraft/net/minecraft/src/EntityMinecart.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft/net/minecraft/src/EntityMinecart.java 0000-00-00 00:00:00.000000000 -0000
@@ -1,30 +1,50 @@
package net.minecraft.src;
+import java.util.ArrayList;
import java.util.List;
+import net.minecraft.src.forge.*;
+
public class EntityMinecart extends Entity implements IInventory
{
/** Array of item stacks stored in minecart (for storage minecarts). */
- private ItemStack[] cargoItems;
- private int fuel;
- private boolean field_856_i;
+ protected ItemStack[] cargoItems;
+ protected int fuel;
+ protected boolean field_856_i;
/** The type of minecart, 2 for powered, 1 for storage. */
public int minecartType;
public double pushX;
public double pushZ;
- private static final int[][][] field_855_j = new int[][][] {{{0, 0, -1}, {0, 0, 1}}, {{ -1, 0, 0}, {1, 0, 0}}, {{ -1, -1, 0}, {1, 0, 0}}, {{ -1, 0, 0}, {1, -1, 0}}, {{0, 0, -1}, {0, -1, 1}}, {{0, -1, -1}, {0, 0, 1}}, {{0, 0, 1}, {1, 0, 0}}, {{0, 0, 1}, { -1, 0, 0}}, {{0, 0, -1}, { -1, 0, 0}}, {{0, 0, -1}, {1, 0, 0}}};
+ protected static final int[][][] field_855_j = new int[][][] {{{0, 0, -1}, {0, 0, 1}}, {{ -1, 0, 0}, {1, 0, 0}}, {{ -1, -1, 0}, {1, 0, 0}}, {{ -1, 0, 0}, {1, -1, 0}}, {{0, 0, -1}, {0, -1, 1}}, {{0, -1, -1}, {0, 0, 1}}, {{0, 0, 1}, {1, 0, 0}}, {{0, 0, 1}, { -1, 0, 0}}, {{0, 0, -1}, { -1, 0, 0}}, {{0, 0, -1}, {1, 0, 0}}};
/** appears to be the progress of the turn */
- private int turnProgress;
- private double minecartX;
- private double minecartY;
- private double minecartZ;
- private double minecartYaw;
- private double minecartPitch;
- private double velocityX;
- private double velocityY;
- private double velocityZ;
+ protected int turnProgress;
+ protected double minecartX;
+ protected double minecartY;
+ protected double minecartZ;
+ protected double minecartYaw;
+ protected double minecartPitch;
+ protected double velocityX;
+ protected double velocityY;
+ protected double velocityZ;
+
+ /* Forge: Minecart Compatibility Layer Integration. */
+ public static float defaultMaxSpeedRail = 0.4f;
+ public static float defaultMaxSpeedGround = 0.4f;
+ public static float defaultMaxSpeedAirLateral = 0.4f;
+ public static float defaultMaxSpeedAirVertical = -1f;
+ public static double defaultDragAir = 0.94999998807907104D;
+ protected boolean canUseRail = true;
+ protected boolean canBePushed = true;
+ private static IMinecartCollisionHandler collisionHandler = null;
+
+ /* Instance versions of the above physics properties */
+ protected float maxSpeedRail;
+ protected float maxSpeedGround;
+ protected float maxSpeedAirLateral;
+ protected float maxSpeedAirVertical;
+ protected double dragAir;
public EntityMinecart(World par1World)
{
@@ -35,6 +55,18 @@
this.preventEntitySpawning = true;
this.setSize(0.98F, 0.7F);
this.yOffset = this.height / 2.0F;
+
+ maxSpeedRail = defaultMaxSpeedRail;
+ maxSpeedGround = defaultMaxSpeedGround;
+ maxSpeedAirLateral = defaultMaxSpeedAirLateral;
+ maxSpeedAirVertical = defaultMaxSpeedAirVertical;
+ dragAir = defaultDragAir;
+ }
+
+ public EntityMinecart(World world, int type)
+ {
+ this(world);
+ minecartType = type;
}
/**
@@ -60,6 +92,10 @@
*/
public AxisAlignedBB getCollisionBox(Entity par1Entity)
{
+ if (getCollisionHandler() != null)
+ {
+ return getCollisionHandler().getCollisionBox(this, par1Entity);
+ }
return par1Entity.boundingBox;
}
@@ -68,6 +104,10 @@
*/
public AxisAlignedBB getBoundingBox()
{
+ if (getCollisionHandler() != null)
+ {
+ return getCollisionHandler().getBoundingBox(this);
+ }
return null;
}
@@ -76,7 +116,7 @@
*/
public boolean canBePushed()
{
- return true;
+ return canBePushed;
}
public EntityMinecart(World par1World, double par2, double par4, double par6, int par8)
@@ -120,48 +160,7 @@
}
this.setDead();
- this.dropItemWithOffset(Item.minecartEmpty.shiftedIndex, 1, 0.0F);
-
- if (this.minecartType == 1)
- {
- EntityMinecart var3 = this;
-
- for (int var4 = 0; var4 < var3.getSizeInventory(); ++var4)
- {
- ItemStack var5 = var3.getStackInSlot(var4);
-
- if (var5 != null)
- {
- float var6 = this.rand.nextFloat() * 0.8F + 0.1F;
- float var7 = this.rand.nextFloat() * 0.8F + 0.1F;
- float var8 = this.rand.nextFloat() * 0.8F + 0.1F;
-
- while (var5.stackSize > 0)
- {
- int var9 = this.rand.nextInt(21) + 10;
-
- if (var9 > var5.stackSize)
- {
- var9 = var5.stackSize;
- }
-
- var5.stackSize -= var9;
- EntityItem var10 = new EntityItem(this.worldObj, this.posX + (double)var6, this.posY + (double)var7, this.posZ + (double)var8, new ItemStack(var5.itemID, var9, var5.getItemDamage()));
- float var11 = 0.05F;
- var10.motionX = (double)((float)this.rand.nextGaussian() * var11);
- var10.motionY = (double)((float)this.rand.nextGaussian() * var11 + 0.2F);
- var10.motionZ = (double)((float)this.rand.nextGaussian() * var11);
- this.worldObj.spawnEntityInWorld(var10);
- }
- }
- }
-
- this.dropItemWithOffset(Block.chest.blockID, 1, 0.0F);
- }
- else if (this.minecartType == 2)
- {
- this.dropItemWithOffset(Block.stoneOvenIdle.blockID, 1, 0.0F);
- }
+ dropCartAsItem();
}
return true;
@@ -254,7 +253,7 @@
this.kill();
}
- if (this.isMinecartPowered() && this.rand.nextInt(4) == 0)
+ if (this.isMinecartPowered() && this.rand.nextInt(4) == 0 && minecartType == 2 && getClass() == EntityMinecart.class)
{
this.worldObj.spawnParticle("largesmoke", this.posX, this.posY + 0.8D, this.posZ, 0.0D, 0.0D, 0.0D);
}
@@ -309,49 +308,26 @@
double var6 = 0.0078125D;
int var8 = this.worldObj.getBlockId(var1, var2, var3);
- if (BlockRail.isRailBlock(var8))
+ if (canUseRail() && BlockRail.isRailBlock(var8))
{
Vec3D var9 = this.func_514_g(this.posX, this.posY, this.posZ);
- int var10 = this.worldObj.getBlockMetadata(var1, var2, var3);
+ int var10 = ((BlockRail)Block.blocksList[var8]).getBasicRailMetadata(worldObj, this, var1, var2, var3);
this.posY = (double)var2;
boolean var11 = false;
boolean var12 = false;
if (var8 == Block.railPowered.blockID)
{
- var11 = (var10 & 8) != 0;
+ var11 = (worldObj.getBlockMetadata(var1, var2, var3) & 8) != 0;
var12 = !var11;
}
- if (((BlockRail)Block.blocksList[var8]).isPowered())
- {
- var10 &= 7;
- }
-
if (var10 >= 2 && var10 <= 5)
{
this.posY = (double)(var2 + 1);
}
-
- if (var10 == 2)
- {
- this.motionX -= var6;
- }
-
- if (var10 == 3)
- {
- this.motionX += var6;
- }
-
- if (var10 == 4)
- {
- this.motionZ += var6;
- }
-
- if (var10 == 5)
- {
- this.motionZ -= var6;
- }
+
+ adjustSlopeVelocities(var10);
int[][] var13 = field_855_j[var10];
double var14 = (double)(var13[1][0] - var13[0][0]);
@@ -370,7 +346,7 @@
this.motionZ = var22 * var16 / var18;
double var24;
- if (var12)
+ if (var12 && shouldDoRailFunctions())
{
var24 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
@@ -420,36 +396,8 @@
this.posX = var26 + var14 * var24;
this.posZ = var28 + var16 * var24;
this.setPosition(this.posX, this.posY + (double)this.yOffset, this.posZ);
- var34 = this.motionX;
- var36 = this.motionZ;
-
- if (this.riddenByEntity != null)
- {
- var34 *= 0.75D;
- var36 *= 0.75D;
- }
-
- if (var34 < -var4)
- {
- var34 = -var4;
- }
-
- if (var34 > var4)
- {
- var34 = var4;
- }
-
- if (var36 < -var4)
- {
- var36 = -var4;
- }
-
- if (var36 > var4)
- {
- var36 = var4;
- }
-
- this.moveEntity(var34, 0.0D, var36);
+
+ moveMinecartOnRail(var1, var2, var3);
if (var13[0][1] != 0 && MathHelper.floor_double(this.posX) - var1 == var13[0][0] && MathHelper.floor_double(this.posZ) - var3 == var13[0][2])
{
@@ -460,41 +408,7 @@
this.setPosition(this.posX, this.posY + (double)var13[1][1], this.posZ);
}
- if (this.riddenByEntity != null)
- {
- this.motionX *= 0.996999979019165D;
- this.motionY *= 0.0D;
- this.motionZ *= 0.996999979019165D;
- }
- else
- {
- if (this.minecartType == 2)
- {
- var38 = (double)MathHelper.sqrt_double(this.pushX * this.pushX + this.pushZ * this.pushZ);
-
- if (var38 > 0.01D)
- {
- this.pushX /= var38;
- this.pushZ /= var38;
- double var40 = 0.04D;
- this.motionX *= 0.800000011920929D;
- this.motionY *= 0.0D;
- this.motionZ *= 0.800000011920929D;
- this.motionX += this.pushX * var40;
- this.motionZ += this.pushZ * var40;
- }
- else
- {
- this.motionX *= 0.8999999761581421D;
- this.motionY *= 0.0D;
- this.motionZ *= 0.8999999761581421D;
- }
- }
-
- this.motionX *= 0.9599999785423279D;
- this.motionY *= 0.0D;
- this.motionZ *= 0.9599999785423279D;
- }
+ applyDragAndPushForces();
Vec3D var52 = this.func_514_g(this.posX, this.posY, this.posZ);
@@ -523,30 +437,15 @@
}
double var41;
-
- if (this.minecartType == 2)
+
+ updatePushForces();
+
+ if(shouldDoRailFunctions())
{
- var41 = (double)MathHelper.sqrt_double(this.pushX * this.pushX + this.pushZ * this.pushZ);
-
- if (var41 > 0.01D && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.001D)
- {
- this.pushX /= var41;
- this.pushZ /= var41;
-
- if (this.pushX * this.motionX + this.pushZ * this.motionZ < 0.0D)
- {
- this.pushX = 0.0D;
- this.pushZ = 0.0D;
- }
- else
- {
- this.pushX = this.motionX;
- this.pushZ = this.motionZ;
- }
- }
+ ((BlockRail)Block.blocksList[var8]).onMinecartPass(worldObj, this, var1, var2, var3);
}
- if (var11)
+ if (var11 && shouldDoRailFunctions())
{
var41 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
@@ -582,41 +481,7 @@
}
else
{
- if (this.motionX < -var4)
- {
- this.motionX = -var4;
- }
-
- if (this.motionX > var4)
- {
- this.motionX = var4;
- }
-
- if (this.motionZ < -var4)
- {
- this.motionZ = -var4;
- }
-
- if (this.motionZ > var4)
- {
- this.motionZ = var4;
- }
-
- if (this.onGround)
- {
- this.motionX *= 0.5D;
- this.motionY *= 0.5D;
- this.motionZ *= 0.5D;
- }
-
- this.moveEntity(this.motionX, this.motionY, this.motionZ);
-
- if (!this.onGround)
- {
- this.motionX *= 0.949999988079071D;
- this.motionY *= 0.949999988079071D;
- this.motionZ *= 0.949999988079071D;
- }
+ moveMinecartOffRail(var1, var2, var3);
}
this.rotationPitch = 0.0F;
@@ -652,7 +517,18 @@
}
this.setRotation(this.rotationYaw, this.rotationPitch);
- List var15 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D));
+
+ AxisAlignedBB box = null;
+ if (getCollisionHandler() != null)
+ {
+ box = getCollisionHandler().getMinecartCollisionBox(this);
+ }
+ else
+ {
+ box = boundingBox.expand(0.2D, 0.0D, 0.2D);
+ }
+
+ List var15 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, box);
if (var15 != null && var15.size() > 0)
{
@@ -677,17 +553,8 @@
this.riddenByEntity = null;
}
- if (this.fuel > 0)
- {
- --this.fuel;
- }
-
- if (this.fuel <= 0)
- {
- this.pushX = this.pushZ = 0.0D;
- }
-
- this.setMinecartPowered(this.fuel > 0);
+ updateFuel();
+ ForgeHooks.onMinecartUpdate(this, var1, var2, var3);
}
}
@@ -710,12 +577,7 @@
}
else
{
- int var13 = this.worldObj.getBlockMetadata(var9, var10, var11);
-
- if (((BlockRail)Block.blocksList[var12]).isPowered())
- {
- var13 &= 7;
- }
+ int var13 = ((BlockRail)Block.blocksList[var12]).getBasicRailMetadata(worldObj, this, var9, var10, var11);
par3 = (double)var10;
@@ -761,14 +623,9 @@
if (BlockRail.isRailBlock(var10))
{
- int var11 = this.worldObj.getBlockMetadata(var7, var8, var9);
+ int var11 = ((BlockRail)Block.blocksList[var10]).getBasicRailMetadata(worldObj, this, var7, var8, var9);
par3 = (double)var8;
- if (((BlockRail)Block.blocksList[var10]).isPowered())
- {
- var11 &= 7;
- }
-
if (var11 >= 2 && var11 <= 5)
{
par3 = (double)(var8 + 1);
@@ -833,13 +690,14 @@
{
par1NBTTagCompound.setInteger("Type", this.minecartType);
- if (this.minecartType == 2)
+ if (isPoweredCart())
{
par1NBTTagCompound.setDouble("PushX", this.pushX);
par1NBTTagCompound.setDouble("PushZ", this.pushZ);
- par1NBTTagCompound.setShort("Fuel", (short)this.fuel);
+ par1NBTTagCompound.setInteger("Fuel", this.fuel);
}
- else if (this.minecartType == 1)
+
+ if (getSizeInventory() > 0)
{
NBTTagList var2 = new NBTTagList();
@@ -865,13 +723,21 @@
{
this.minecartType = par1NBTTagCompound.getInteger("Type");
- if (this.minecartType == 2)
+ if (isPoweredCart())
{
this.pushX = par1NBTTagCompound.getDouble("PushX");
this.pushZ = par1NBTTagCompound.getDouble("PushZ");
- this.fuel = par1NBTTagCompound.getShort("Fuel");
+ try
+ {
+ this.fuel = par1NBTTagCompound.getInteger("Fuel");
+ }
+ catch (ClassCastException e)
+ {
+ this.fuel = par1NBTTagCompound.getShort("Fuel");
+ }
}
- else if (this.minecartType == 1)
+
+ if (getSizeInventory() > 0)
{
NBTTagList var2 = par1NBTTagCompound.getTagList("Items");
this.cargoItems = new ItemStack[this.getSizeInventory()];
@@ -899,11 +765,18 @@
*/
public void applyEntityCollision(Entity par1Entity)
{
+ ForgeHooks.onMinecartEntityCollision(this, par1Entity);
+ if (getCollisionHandler() != null)
+ {
+ getCollisionHandler().onEntityCollision(this, par1Entity);
+ return;
+ }
+
if (!this.worldObj.isRemote)
{
if (par1Entity != this.riddenByEntity)
{
- if (par1Entity instanceof EntityLiving && !(par1Entity instanceof EntityPlayer) && !(par1Entity instanceof EntityIronGolem) && this.minecartType == 0 && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.01D && this.riddenByEntity == null && par1Entity.ridingEntity == null)
+ if (par1Entity instanceof EntityLiving && !(par1Entity instanceof EntityPlayer) && !(par1Entity instanceof EntityIronGolem) && canBeRidden() && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.01D && this.riddenByEntity == null && par1Entity.ridingEntity == null)
{
par1Entity.mountEntity(this);
}
@@ -949,7 +822,7 @@
double var18 = par1Entity.motionX + this.motionX;
double var20 = par1Entity.motionZ + this.motionZ;
- if (((EntityMinecart)par1Entity).minecartType == 2 && this.minecartType != 2)
+ if (((EntityMinecart)par1Entity).isPoweredCart() && !isPoweredCart())
{
this.motionX *= 0.20000000298023224D;
this.motionZ *= 0.20000000298023224D;
@@ -957,7 +830,7 @@
par1Entity.motionX *= 0.949999988079071D;
par1Entity.motionZ *= 0.949999988079071D;
}
- else if (((EntityMinecart)par1Entity).minecartType != 2 && this.minecartType == 2)
+ else if (!((EntityMinecart)par1Entity).isPoweredCart() && isPoweredCart())
{
par1Entity.motionX *= 0.20000000298023224D;
par1Entity.motionZ *= 0.20000000298023224D;
@@ -992,7 +865,7 @@
*/
public int getSizeInventory()
{
- return 27;
+ return (minecartType == 1 && getClass() == EntityMinecart.class ? 27 : 0);
}
/**
@@ -1095,7 +968,12 @@
*/
public boolean interact(EntityPlayer par1EntityPlayer)
{
- if (this.minecartType == 0)
+ if (!ForgeHooks.onMinecartInteract(this, par1EntityPlayer))
+ {
+ return true;
+ }
+
+ if (canBeRidden())
{
if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityPlayer && this.riddenByEntity != par1EntityPlayer)
{
@@ -1107,14 +985,14 @@
par1EntityPlayer.mountEntity(this);
}
}
- else if (this.minecartType == 1)
+ else if (getSizeInventory() > 0)
{
if (!this.worldObj.isRemote)
{
par1EntityPlayer.displayGUIChest(this);
}
}
- else if (this.minecartType == 2)
+ else if (this.minecartType == 2 && getClass() == EntityMinecart.class)
{
ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem();
@@ -1173,7 +1051,7 @@
/**
* Is this minecart powered (Fuel > 0)
*/
- protected boolean isMinecartPowered()
+ public boolean isMinecartPowered()
{
return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
}
@@ -1226,4 +1104,373 @@
{
return this.dataWatcher.getWatchableObjectInt(18);
}
+
+ /**
+ * Drops the cart as a item. The exact item dropped is defined by getItemDropped().
+ */
+ public void dropCartAsItem()
+ {
+ for(ItemStack item : getItemsDropped())
+ {
+ entityDropItem(item, 0);
+ }
+ }
+
+ /**
+ * Override this to define which items your cart drops when broken.
+ * This does not include items contained in the inventory,
+ * that is handled elsewhere.
+ * @return A list of items dropped.
+ */
+ public List<ItemStack> getItemsDropped()
+ {
+ List<ItemStack> items = new ArrayList<ItemStack>();
+ items.add(new ItemStack(Item.minecartEmpty));
+
+ switch(minecartType)
+ {
+ case 1:
+ items.add(new ItemStack(Block.chest));
+ break;
+ case 2:
+ items.add(new ItemStack(Block.stoneOvenIdle));
+ break;
+ }
+ return items;
+ }
+
+ /**
+ * This function returns an ItemStack that represents this cart.
+ * This should be an ItemStack that can be used by the player to place the cart.
+ * This is the item that was registered with the cart via the registerMinecart function,
+ * but is not necessary the item the cart drops when destroyed.
+ * @return An ItemStack that can be used to place the cart.
+ */
+ public ItemStack getCartItem()
+ {
+ return MinecraftForge.getItemForCart(this);
+ }
+
+ /**
+ * Returns true if this cart is self propelled.
+ * @return True if powered.
+ */
+ public boolean isPoweredCart()
+ {
+ return minecartType == 2 && getClass() == EntityMinecart.class;
+ }
+
+ /**
+ * Returns true if this cart is a storage cart
+ * Some carts may have inventories but not be storage carts
+ * and some carts without inventories may be storage carts.
+ * @return True if this cart should be classified as a storage cart.
+ */
+ public boolean isStorageCart()
+ {
+ return minecartType == 1 && getClass() == EntityMinecart.class;
+ }
+
+ /**
+ * Returns true if this cart can be ridden by an Entity.
+ * @return True if this cart can be ridden.
+ */
+ public boolean canBeRidden()
+ {
+ if(minecartType == 0 && getClass() == EntityMinecart.class)
+ {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if this cart can currently use rails.
+ * This function is mainly used to gracefully detach a minecart from a rail.
+ * @return True if the minecart can use rails.
+ */
+ public boolean canUseRail()
+ {
+ return canUseRail;
+ }
+
+ /**
+ * Set whether the minecart can use rails.
+ * This function is mainly used to gracefully detach a minecart from a rail.
+ * @param use Whether the minecart can currently use rails.
+ */
+ public void setCanUseRail(boolean use)
+ {
+ canUseRail = use;
+ }
+
+ /**
+ * Return false if this cart should not call IRail.onMinecartPass() and should ignore Powered Rails.
+ * @return True if this cart should call IRail.onMinecartPass().
+ */
+ public boolean shouldDoRailFunctions()
+ {
+ return true;
+ }
+
+ /**
+ * Simply returns the minecartType variable.
+ * @return minecartType
+ */
+ public int getMinecartType()
+ {
+ return minecartType;
+ }
+
+ /**
+ * Gets the current global Minecart Collision handler if none
+ * is registered, returns null
+ * @return The collision handler or null
+ */
+ public static IMinecartCollisionHandler getCollisionHandler()
+ {
+ return collisionHandler;
+ }
+
+ /**
+ * Sets the global Minecart Collision handler, overwrites any
+ * that is currently set.
+ * @param handler The new handler
+ */
+ public static void setCollisionHandler(IMinecartCollisionHandler handler)
+ {
+ collisionHandler = handler;
+ }
+
+ /**
+ * Carts should return their drag factor here
+ * @return The drag rate.
+ */
+ protected double getDrag()
+ {
+ return riddenByEntity != null ? 0.99D : 0.96D;
+ }
+
+ /**
+ * Moved to allow overrides.
+ * This code applies drag and updates push forces.
+ */
+ protected void applyDragAndPushForces()
+ {
+ if(isPoweredCart())
+ {
+ double d27 = MathHelper.sqrt_double(pushX * pushX + pushZ * pushZ);
+ if(d27 > 0.01D)
+ {
+ pushX /= d27;
+ pushZ /= d27;
+ double d29 = 0.04;
+ motionX *= 0.8D;
+ motionY *= 0.0D;
+ motionZ *= 0.8D;
+ motionX += pushX * d29;
+ motionZ += pushZ * d29;
+ } else
+ {
+ motionX *= 0.9D;
+ motionY *= 0.0D;
+ motionZ *= 0.9D;
+ }
+ }
+ motionX *= getDrag();
+ motionY *= 0.0D;
+ motionZ *= getDrag();
+ }
+
+ /**
+ * Moved to allow overrides.
+ * This code updates push forces.
+ */
+ protected void updatePushForces()
+ {
+ if(isPoweredCart())
+ {
+ double push = MathHelper.sqrt_double(pushX * pushX + pushZ * pushZ);
+ if(push > 0.01D && motionX * motionX + motionZ * motionZ > 0.001D)
+ {
+ pushX /= push;
+ pushZ /= push;
+ if(pushX * motionX + pushZ * motionZ < 0.0D)
+ {
+ pushX = 0.0D;
+ pushZ = 0.0D;
+ } else
+ {
+ pushX = motionX;
+ pushZ = motionZ;
+ }
+ }
+ }
+ }
+
+ /**
+ * Moved to allow overrides.
+ * This code handles minecart movement and speed capping when on a rail.
+ */
+ protected void moveMinecartOnRail(int i, int j, int k)
+ {
+ int id = worldObj.getBlockId(i, j, k);
+ if (!BlockRail.isRailBlock(id))
+ {
+ return;
+ }
+ float railMaxSpeed = ((BlockRail)Block.blocksList[id]).getRailMaxSpeed(worldObj, this, i, j, k);
+
+ double maxSpeed = Math.min(railMaxSpeed, getMaxSpeedRail());
+ double mX = motionX;
+ double mZ = motionZ;
+ if(riddenByEntity != null)
+ {
+ mX *= 0.75D;
+ mZ *= 0.75D;
+ }
+ if(mX < -maxSpeed) mX = -maxSpeed;
+ if(mX > maxSpeed) mX = maxSpeed;
+ if(mZ < -maxSpeed) mZ = -maxSpeed;
+ if(mZ > maxSpeed) mZ = maxSpeed;
+ moveEntity(mX, 0.0D, mZ);
+ }
+
+ /**
+ * Moved to allow overrides.
+ * This code handles minecart movement and speed capping when not on a rail.
+ */
+ protected void moveMinecartOffRail(int i, int j, int k)
+ {
+ double d2 = getMaxSpeedGround();
+ if(!onGround)
+ {
+ d2 = getMaxSpeedAirLateral();
+ }
+ if(motionX < -d2) motionX = -d2;
+ if(motionX > d2) motionX = d2;
+ if(motionZ < -d2) motionZ = -d2;
+ if(motionZ > d2) motionZ = d2;
+ double moveY = motionY;
+ if(getMaxSpeedAirVertical() > 0 && motionY > getMaxSpeedAirVertical())
+ {
+ moveY = getMaxSpeedAirVertical();
+ if(Math.abs(motionX) < 0.3f && Math.abs(motionZ) < 0.3f)
+ {
+ moveY = 0.15f;
+ motionY = moveY;
+ }
+ }
+ if(onGround)
+ {
+ motionX *= 0.5D;
+ motionY *= 0.5D;
+ motionZ *= 0.5D;
+ }
+ moveEntity(motionX, moveY, motionZ);
+ if(!onGround)
+ {
+ motionX *= getDragAir();
+ motionY *= getDragAir();
+ motionZ *= getDragAir();
+ }
+ }
+
+ /**
+ * Moved to allow overrides.
+ * This code applies fuel consumption.
+ */
+ protected void updateFuel()
+ {
+ if (fuel > 0) fuel--;
+ if (fuel <= 0) pushX = pushZ = 0.0D;
+ setMinecartPowered(fuel > 0);
+ }
+
+ /**
+ * Moved to allow overrides, This code handle slopes affecting velocity.
+ * @param metadata The blocks position metadata
+ */
+ protected void adjustSlopeVelocities(int metadata)
+ {
+ double acceleration = 0.0078125D;
+ if (metadata == 2)
+ {
+ motionX -= acceleration;
+ }
+ else if (metadata == 3)
+ {
+ motionX += acceleration;
+ }
+ else if (metadata == 4)
+ {
+ motionZ += acceleration;
+ }
+ else if (metadata == 5)
+ {
+ motionZ -= acceleration;
+ }
+ }
+
+ /**
+ * Getters/setters for physics variables
+ */
+
+ /**
+ * Returns the carts max speed.
+ * Carts going faster than 1.1 cause issues with chunk loading.
+ * Carts cant traverse slopes or corners at greater than 0.5 - 0.6.
+ * This value is compared with the rails max speed to determine
+ * the carts current max speed. A normal rails max speed is 0.4.
+ * @return Carts max speed.
+ */
+ public float getMaxSpeedRail()
+ {
+ return maxSpeedRail;
+ }
+
+ public void setMaxSpeedRail(float value)
+ {
+ maxSpeedRail = value;
+ }
+
+ public float getMaxSpeedGround()
+ {
+ return maxSpeedGround;
+ }
+
+ public void setMaxSpeedGround(float value)
+ {
+ maxSpeedGround = value;
+ }
+
+ public float getMaxSpeedAirLateral()
+ {
+ return maxSpeedAirLateral;
+ }
+
+ public void setMaxSpeedAirLateral(float value)
+ {
+ maxSpeedAirLateral = value;
+ }
+
+ public float getMaxSpeedAirVertical()
+ {
+ return maxSpeedAirVertical;
+ }
+
+ public void setMaxSpeedAirVertical(float value)
+ {
+ maxSpeedAirVertical = value;
+ }
+
+ public double getDragAir()
+ {
+ return dragAir;
+ }
+
+ public void setDragAir(double value)
+ {
+ dragAir = value;
+ }
}