From 46394174c557ae02dff8def00aa71a62b1d1e018 Mon Sep 17 00:00:00 2001 From: CovertJaguar Date: Sat, 12 Jan 2013 11:10:39 -0800 Subject: [PATCH] MCL Update --- .../common/MinecartRegistry.java | 215 -------- .../minecraft/block/BlockBaseRail.java.patch | 136 +++++ .../block/BlockBaseRailLogic.java.patch | 70 +++ .../entity/ItemChestMinecart.java.patch | 22 + .../entity/ItemFurnaceMinecart.java.patch | 22 + .../entity/ItemRideableMinecart.java.patch | 22 + .../entity/item/EntityMinecart.java.patch | 497 ++++++++++++++++++ 7 files changed, 769 insertions(+), 215 deletions(-) delete mode 100644 common/net/minecraftforge/common/MinecartRegistry.java create mode 100644 patches/minecraft/net/minecraft/block/BlockBaseRail.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockBaseRailLogic.java.patch create mode 100644 patches/minecraft/net/minecraft/entity/ItemChestMinecart.java.patch create mode 100644 patches/minecraft/net/minecraft/entity/ItemFurnaceMinecart.java.patch create mode 100644 patches/minecraft/net/minecraft/entity/ItemRideableMinecart.java.patch create mode 100644 patches/minecraft/net/minecraft/entity/item/EntityMinecart.java.patch diff --git a/common/net/minecraftforge/common/MinecartRegistry.java b/common/net/minecraftforge/common/MinecartRegistry.java deleted file mode 100644 index 43cfd23d6..000000000 --- a/common/net/minecraftforge/common/MinecartRegistry.java +++ /dev/null @@ -1,215 +0,0 @@ -package net.minecraftforge.common; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import net.minecraft.entity.item.EntityMinecart; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; - -public class MinecartRegistry -{ - private static Map itemForMinecart = new HashMap(); - private static Map minecartForItem = new HashMap(); - /** - * Registers a custom minecart and its corresponding item. - * This should be the item used to place the minecart by the user, - * not the item dropped by the cart. - * @param cart The minecart. - * @param item The item used to place the cart. - */ - public static void registerMinecart(Class cart, ItemStack item) - { - registerMinecart(cart, 0, item); - } - - /** - * Registers a minecart and its corresponding item. - * This should be the item used to place the minecart by the user, - * not the item dropped by the cart. - * @param minecart The minecart. - * @param type The minecart type, used to differentiate carts that have the same class. - * @param item The item used to place the cart. - */ - public static void registerMinecart(Class minecart, int type, ItemStack item) - { - MinecartKey key = new MinecartKey(minecart, type); - itemForMinecart.put(key, item); - minecartForItem.put(item, key); - } - - /** - * Removes a previously registered Minecart. Useful for replacing the vanilla minecarts. - * @param minecart - * @param type - */ - public static void removeMinecart(Class minecart, int type) - { - MinecartKey key = new MinecartKey(minecart, type); - ItemStack item = itemForMinecart.remove(key); - if (item != null) - { - minecartForItem.remove(item); - } - } - - /** - * This function returns an ItemStack that represents this cart. - * The player should be able to use this item to place the minecart. - * 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. - * @param minecart The cart class - * @return An ItemStack that can be used to place the cart. - */ - public static ItemStack getItemForCart(Class minecart) - { - return getItemForCart(minecart, 0); - } - - /** - * This function returns an ItemStack that represents this cart. - * The player should be able to use this item to place the minecart. - * 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. - * @param minecart The cart class - * @param type The minecartType value - * @return An ItemStack that can be used to place the cart. - */ - public static ItemStack getItemForCart(Class minecart, int type) - { - ItemStack item = itemForMinecart.get(new MinecartKey(minecart, type)); - if (item == null) - { - return null; - } - return item.copy(); - } - - /** - * This function returns an ItemStack that represents this cart. - * The player should be able to use this item to place the minecart. - * 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. - * @param cart The cart entity - * @return An ItemStack that can be used to place the cart. - */ - public static ItemStack getItemForCart(EntityMinecart cart) - { - return getItemForCart(cart.getClass(), cart.getMinecartType()); - } - - /** - * The function will return the cart class for a given item. - * If the item was not registered via the registerMinecart function it will return null. - * @param item The item to test. - * @return Cart if mapping exists, null if not. - */ - public static Class getCartClassForItem(ItemStack item) - { - MinecartKey key = null; - for (Map.Entry entry : minecartForItem.entrySet()) - { - if (entry.getKey().isItemEqual(item)) - { - key = entry.getValue(); - break; - } - } - if (key != null) - { - return key.minecart; - } - return null; - } - - /** - * The function will return the cart type for a given item. - * Will return -1 if the mapping doesn't exist. - * If the item was not registered via the registerMinecart function it will return null. - * @param item The item to test. - * @return the cart minecartType value. - */ - public static int getCartTypeForItem(ItemStack item) - { - MinecartKey key = null; - for (Map.Entry entry : minecartForItem.entrySet()) - { - if (entry.getKey().isItemEqual(item)) - { - key = entry.getValue(); - break; - } - } - if (key != null) - { - return key.type; - } - return -1; - } - - /** - * Will return a set of all registered minecart items. - * @return a copy of the set of all minecart items - */ - public static Set getAllCartItems() - { - Set ret = new HashSet(); - for (ItemStack item : minecartForItem.keySet()) - { - ret.add(item.copy()); - } - return ret; - } - - static - { - registerMinecart(EntityMinecart.class, 0, new ItemStack(Item.minecartEmpty)); - registerMinecart(EntityMinecart.class, 1, new ItemStack(Item.minecartCrate)); - registerMinecart(EntityMinecart.class, 2, new ItemStack(Item.minecartPowered)); - } - - public static class MinecartKey - { - public final Class minecart; - public final int type; - - public MinecartKey(Class cls, int typtID) - { - minecart = cls; - type = typtID; - } - - @Override - public boolean equals(Object obj) - { - if (obj == null) - { - return false; - } - - if (getClass() != obj.getClass()) - { - return false; - } - - final MinecartKey other = (MinecartKey)obj; - if (this.minecart != other.minecart && (this.minecart == null || !this.minecart.equals(other.minecart))) - { - return false; - } - - return (this.type == other.type); - } - - @Override - public int hashCode() - { - int hash = 7; - hash = 59 * hash + (this.minecart != null ? this.minecart.hashCode() : 0); - hash = 59 * hash + this.type; - return hash; - } - } -} diff --git a/patches/minecraft/net/minecraft/block/BlockBaseRail.java.patch b/patches/minecraft/net/minecraft/block/BlockBaseRail.java.patch new file mode 100644 index 000000000..e5d440836 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockBaseRail.java.patch @@ -0,0 +1,136 @@ +--- ../src_base/minecraft/net/minecraft/block/BlockBaseRail.java ++++ ../src_work/minecraft/net/minecraft/block/BlockBaseRail.java +@@ -3,6 +3,7 @@ + import java.util.Random; + import net.minecraft.block.material.Material; + import net.minecraft.creativetab.CreativeTabs; ++import net.minecraft.entity.item.EntityMinecart; + import net.minecraft.util.AxisAlignedBB; + import net.minecraft.util.MovingObjectPosition; + import net.minecraft.util.Vec3; +@@ -28,7 +29,7 @@ + */ + public static final boolean isRailBlock(int par0) + { +- return par0 == Block.rail.blockID || par0 == Block.railPowered.blockID || par0 == Block.railDetector.blockID || par0 == Block.field_94337_cv.blockID; ++ return Block.blocksList[par0] instanceof BlockBaseRail; + } + + protected BlockBaseRail(int par1, boolean par2) +@@ -105,7 +106,7 @@ + */ + public int getRenderType() + { +- return 9; ++ return renderType; + } + + /** +@@ -216,4 +217,107 @@ + { + return 0; + } ++ ++ /** ++ * Return true if the rail can make corners. ++ * Used by placement logic. ++ * @param world The world. ++ * @param x The rail X coordinate. ++ * @param y The rail Y coordinate. ++ * @param z The rail Z coordinate. ++ * @return True if the rail can make corners. ++ */ ++ public boolean isFlexibleRail(World world, int y, int x, int z) ++ { ++ return !isPowered; ++ } ++ ++ /** ++ * Returns true if the rail can make up and down slopes. ++ * Used by placement logic. ++ * @param world The world. ++ * @param x The rail X coordinate. ++ * @param y The rail Y coordinate. ++ * @param z The rail Z coordinate. ++ * @return True if the rail can make slopes. ++ */ ++ public boolean canMakeSlopes(World world, int x, int y, int z) ++ { ++ return true; ++ } ++ ++ /** ++ * Return the rail's metadata (without the power bit if the rail uses one). ++ * Can be used to make the cart think the rail something other than it is, ++ * for example when making diamond junctions or switches. ++ * The cart parameter will often be null unless it it called from EntityMinecart. ++ * ++ * Valid rail metadata is defined as follows: ++ * 0x0: flat track going North-South ++ * 0x1: flat track going West-East ++ * 0x2: track ascending to the East ++ * 0x3: track ascending to the West ++ * 0x4: track ascending to the North ++ * 0x5: track ascending to the South ++ * 0x6: WestNorth corner (connecting East and South) ++ * 0x7: EastNorth corner (connecting West and South) ++ * 0x8: EastSouth corner (connecting West and North) ++ * 0x9: WestSouth corner (connecting East and North) ++ * ++ * @param world The world. ++ * @param cart The cart asking for the metadata, null if it is not called by EntityMinecart. ++ * @param y The rail X coordinate. ++ * @param x The rail Y coordinate. ++ * @param z The rail Z coordinate. ++ * @return The metadata. ++ */ ++ public int getBasicRailMetadata(IBlockAccess world, EntityMinecart cart, int x, int y, int z) ++ { ++ int meta = world.getBlockMetadata(x, y, z); ++ if(isPowered) ++ { ++ meta = meta & 7; ++ } ++ return meta; ++ } ++ ++ /** ++ * Returns the max speed of the rail at the specified position. ++ * @param world The world. ++ * @param cart The cart on the rail, may be null. ++ * @param x The rail X coordinate. ++ * @param y The rail Y coordinate. ++ * @param z The rail Z coordinate. ++ * @return The max speed of the current rail. ++ */ ++ public float getRailMaxSpeed(World world, EntityMinecart cart, int y, int x, int z) ++ { ++ return 0.4f; ++ } ++ ++ /** ++ * This function is called by any minecart that passes over this rail. ++ * It is called once per update tick that the minecart is on the rail. ++ * @param world The world. ++ * @param cart The cart on the rail. ++ * @param y The rail X coordinate. ++ * @param x The rail Y coordinate. ++ * @param z The rail Z coordinate. ++ */ ++ public void onMinecartPass(World world, EntityMinecart cart, int y, int x, int z) ++ { ++ } ++ ++ /** ++ * Forge: Moved render type to a field and a setter. ++ * This allows for a mod to change the render type ++ * for vanilla rails, and any mod rails that extend ++ * this class. ++ */ ++ private int renderType = 9; ++ ++ public void setRenderType(int value) ++ { ++ renderType = value; ++ } + } diff --git a/patches/minecraft/net/minecraft/block/BlockBaseRailLogic.java.patch b/patches/minecraft/net/minecraft/block/BlockBaseRailLogic.java.patch new file mode 100644 index 000000000..db7e4b111 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockBaseRailLogic.java.patch @@ -0,0 +1,70 @@ +--- ../src_base/minecraft/net/minecraft/block/BlockBaseRailLogic.java ++++ ../src_work/minecraft/net/minecraft/block/BlockBaseRailLogic.java +@@ -13,6 +13,8 @@ + private int field_94515_e; + private final boolean field_94512_f; + private List field_94513_g; ++ ++ private final boolean canMakeSlopes; + + final BlockBaseRail field_94518_a; + +@@ -25,17 +27,11 @@ + this.field_94514_d = par4; + this.field_94515_e = par5; + int l = par2World.getBlockId(par3, par4, par5); +- int i1 = par2World.getBlockMetadata(par3, par4, par5); +- +- if (((BlockBaseRail)Block.blocksList[l]).isPowered) +- { +- this.field_94512_f = true; +- i1 &= -9; +- } +- else +- { +- this.field_94512_f = false; +- } ++ ++ BlockBaseRail target = (BlockBaseRail)Block.blocksList[l]; ++ int i1 = target.getBasicRailMetadata(par2World, null, par3, par4, par5); ++ field_94512_f = !target.isFlexibleRail(par2World, par3, par4, par5); ++ canMakeSlopes = target.canMakeSlopes(par2World, par3, par4, par5); + + this.func_94504_a(i1); + } +@@ -227,7 +223,7 @@ + } + } + +- if (b0 == 0) ++ if (b0 == 0 && canMakeSlopes) + { + if (BlockBaseRail.isRailBlockAt(this.field_94516_b, this.field_94517_c, this.field_94514_d + 1, this.field_94515_e - 1)) + { +@@ -240,7 +236,7 @@ + } + } + +- if (b0 == 1) ++ if (b0 == 1 && canMakeSlopes) + { + if (BlockBaseRail.isRailBlockAt(this.field_94516_b, this.field_94517_c + 1, this.field_94514_d + 1, this.field_94515_e)) + { +@@ -385,7 +381,7 @@ + } + } + +- if (b0 == 0) ++ if (b0 == 0 && canMakeSlopes) + { + if (BlockBaseRail.isRailBlockAt(this.field_94516_b, this.field_94517_c, this.field_94514_d + 1, this.field_94515_e - 1)) + { +@@ -398,7 +394,7 @@ + } + } + +- if (b0 == 1) ++ if (b0 == 1 && canMakeSlopes) + { + if (BlockBaseRail.isRailBlockAt(this.field_94516_b, this.field_94517_c + 1, this.field_94514_d + 1, this.field_94515_e)) + { diff --git a/patches/minecraft/net/minecraft/entity/ItemChestMinecart.java.patch b/patches/minecraft/net/minecraft/entity/ItemChestMinecart.java.patch new file mode 100644 index 000000000..f6d1aafef --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/ItemChestMinecart.java.patch @@ -0,0 +1,22 @@ +--- ../src_base/minecraft/net/minecraft/entity/ItemChestMinecart.java ++++ ../src_work/minecraft/net/minecraft/entity/ItemChestMinecart.java +@@ -10,6 +10,8 @@ + import net.minecraft.nbt.NBTTagList; + import net.minecraft.util.DamageSource; + import net.minecraft.world.World; ++import net.minecraftforge.common.MinecraftForge; ++import net.minecraftforge.event.entity.minecart.MinecartInteractEvent; + + public class ItemChestMinecart extends EntityMinecart implements IInventory + { +@@ -292,6 +294,10 @@ + */ + public boolean interact(EntityPlayer par1EntityPlayer) + { ++ if(MinecraftForge.EVENT_BUS.post(new MinecartInteractEvent(this, par1EntityPlayer))) ++ { ++ return true; ++ } + if (!this.worldObj.isRemote) + { + par1EntityPlayer.displayGUIChest(this); diff --git a/patches/minecraft/net/minecraft/entity/ItemFurnaceMinecart.java.patch b/patches/minecraft/net/minecraft/entity/ItemFurnaceMinecart.java.patch new file mode 100644 index 000000000..548a35fa8 --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/ItemFurnaceMinecart.java.patch @@ -0,0 +1,22 @@ +--- ../src_base/minecraft/net/minecraft/entity/ItemFurnaceMinecart.java ++++ ../src_work/minecraft/net/minecraft/entity/ItemFurnaceMinecart.java +@@ -8,6 +8,8 @@ + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; ++import net.minecraftforge.common.MinecraftForge; ++import net.minecraftforge.event.entity.minecart.MinecartInteractEvent; + + public class ItemFurnaceMinecart extends EntityMinecart + { +@@ -116,6 +118,10 @@ + */ + public boolean interact(EntityPlayer par1EntityPlayer) + { ++ if(MinecraftForge.EVENT_BUS.post(new MinecartInteractEvent(this, par1EntityPlayer))) ++ { ++ return true; ++ } + ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem(); + + if (itemstack != null && itemstack.itemID == Item.coal.itemID) diff --git a/patches/minecraft/net/minecraft/entity/ItemRideableMinecart.java.patch b/patches/minecraft/net/minecraft/entity/ItemRideableMinecart.java.patch new file mode 100644 index 000000000..754997ec8 --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/ItemRideableMinecart.java.patch @@ -0,0 +1,22 @@ +--- ../src_base/minecraft/net/minecraft/entity/ItemRideableMinecart.java ++++ ../src_work/minecraft/net/minecraft/entity/ItemRideableMinecart.java +@@ -3,6 +3,8 @@ + import net.minecraft.entity.item.EntityMinecart; + import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.world.World; ++import net.minecraftforge.common.MinecraftForge; ++import net.minecraftforge.event.entity.minecart.MinecartInteractEvent; + + public class ItemRideableMinecart extends EntityMinecart + { +@@ -21,6 +23,10 @@ + */ + public boolean interact(EntityPlayer par1EntityPlayer) + { ++ if(MinecraftForge.EVENT_BUS.post(new MinecartInteractEvent(this, par1EntityPlayer))) ++ { ++ return true; ++ } + if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityPlayer && this.riddenByEntity != par1EntityPlayer) + { + return true; diff --git a/patches/minecraft/net/minecraft/entity/item/EntityMinecart.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityMinecart.java.patch new file mode 100644 index 000000000..4115e2f3f --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/item/EntityMinecart.java.patch @@ -0,0 +1,497 @@ +--- ../src_base/minecraft/net/minecraft/entity/item/EntityMinecart.java ++++ ../src_work/minecraft/net/minecraft/entity/item/EntityMinecart.java +@@ -24,6 +24,10 @@ + import net.minecraft.util.Vec3; + import net.minecraft.world.World; + import net.minecraft.world.WorldServer; ++import net.minecraftforge.common.IMinecartCollisionHandler; ++import net.minecraftforge.common.MinecraftForge; ++import net.minecraftforge.event.entity.minecart.MinecartCollisionEvent; ++import net.minecraftforge.event.entity.minecart.MinecartUpdateEvent; + + public abstract class EntityMinecart extends Entity + { +@@ -48,6 +52,20 @@ + @SideOnly(Side.CLIENT) + protected double velocityZ; + ++ /* Forge: Minecart Compatibility Layer Integration. */ ++ 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 */ ++ private float currentSpeedRail = getMaxCartSpeedOnRail(); ++ protected float maxSpeedAirLateral = defaultMaxSpeedAirLateral; ++ protected float maxSpeedAirVertical = defaultMaxSpeedAirVertical; ++ protected double dragAir = defaultDragAir; ++ + public EntityMinecart(World par1World) + { + super(par1World); +@@ -99,6 +117,10 @@ + */ + public AxisAlignedBB getCollisionBox(Entity par1Entity) + { ++ if (getCollisionHandler() != null) ++ { ++ return getCollisionHandler().getCollisionBox(this, par1Entity); ++ } + return par1Entity.canBePushed() ? par1Entity.boundingBox : null; + } + +@@ -107,6 +129,10 @@ + */ + public AxisAlignedBB getBoundingBox() + { ++ if (getCollisionHandler() != null) ++ { ++ return getCollisionHandler().getBoundingBox(this); ++ } + return null; + } + +@@ -115,7 +141,7 @@ + */ + public boolean canBePushed() + { +- return true; ++ return canBePushed; + } + + public EntityMinecart(World par1World, double par2, double par4, double par6) +@@ -349,13 +375,16 @@ + double d5 = 0.0078125D; + int l = this.worldObj.getBlockId(j, i, k); + +- if (BlockBaseRail.isRailBlock(l)) +- { +- this.func_94091_a(j, i, k, d4, d5, l, this.worldObj.getBlockMetadata(j, i, k)); ++ if (canUseRail() && BlockBaseRail.isRailBlock(l)) ++ { ++ BlockBaseRail rail = (BlockBaseRail)Block.blocksList[l]; ++ float railMaxSpeed = rail.getRailMaxSpeed(worldObj, this, j, i, k); ++ double maxSpeed = Math.min(railMaxSpeed, getCurrentCartSpeedCapOnRail()); ++ this.func_94091_a(j, i, k, maxSpeed, getSlopeAdjustment(), l, rail.getBasicRailMetadata(worldObj, this, j, i, k)); + } + else + { +- this.func_94088_b(d4); ++ this.func_94088_b(onGround ? d4 : getMaxSpeedAirLateral()); + } + + this.doBlockCollisions(); +@@ -382,7 +411,18 @@ + } + + this.setRotation(this.rotationYaw, this.rotationPitch); +- List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); ++ ++ AxisAlignedBB box; ++ if (getCollisionHandler() != null) ++ { ++ box = getCollisionHandler().getMinecartCollisionBox(this); ++ } ++ else ++ { ++ box = boundingBox.expand(0.2D, 0.0D, 0.2D); ++ } ++ ++ List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, box); + + if (list != null && !list.isEmpty()) + { +@@ -406,6 +446,8 @@ + + this.riddenByEntity = null; + } ++ ++ MinecraftForge.EVENT_BUS.post(new MinecartUpdateEvent(this, j, i, k)); + } + } + +@@ -431,6 +473,17 @@ + this.motionZ = par1; + } + ++ 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 (this.onGround) + { + this.motionX *= 0.5D; +@@ -438,13 +491,13 @@ + this.motionZ *= 0.5D; + } + +- this.moveEntity(this.motionX, this.motionY, this.motionZ); ++ this.moveEntity(this.motionX, moveY, this.motionZ); + + if (!this.onGround) + { +- this.motionX *= 0.949999988079071D; +- this.motionY *= 0.949999988079071D; +- this.motionZ *= 0.949999988079071D; ++ this.motionX *= getDragAir(); ++ this.motionY *= getDragAir(); ++ this.motionZ *= getDragAir(); + } + } + +@@ -458,7 +511,7 @@ + + if (par8 == Block.railPowered.blockID) + { +- flag = (par9 & 8) != 0; ++ flag = (worldObj.getBlockMetadata(par1, par2, par3) & 8) != 0; + flag1 = !flag; + } + +@@ -523,7 +576,7 @@ + } + } + +- if (flag1) ++ if (flag1 && shouldDoRailFunctions()) + { + d7 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + +@@ -571,36 +624,8 @@ + this.posX = d8 + d2 * d7; + this.posZ = d9 + d3 * d7; + this.setPosition(this.posX, this.posY + (double)this.yOffset, this.posZ); +- d12 = this.motionX; +- d13 = this.motionZ; +- +- if (this.riddenByEntity != null) +- { +- d12 *= 0.75D; +- d13 *= 0.75D; +- } +- +- if (d12 < -par4) +- { +- d12 = -par4; +- } +- +- if (d12 > par4) +- { +- d12 = par4; +- } +- +- if (d13 < -par4) +- { +- d13 = -par4; +- } +- +- if (d13 > par4) +- { +- d13 = par4; +- } +- +- this.moveEntity(d12, 0.0D, d13); ++ ++ moveMinecartOnRail(par1, par2, par3, par4); + + if (aint[0][1] != 0 && MathHelper.floor_double(this.posX) - par1 == aint[0][0] && MathHelper.floor_double(this.posZ) - par3 == aint[0][2]) + { +@@ -637,8 +662,13 @@ + this.motionX = d6 * (double)(j1 - par1); + this.motionZ = d6 * (double)(k1 - par3); + } +- +- if (flag) ++ ++ if(shouldDoRailFunctions()) ++ { ++ ((BlockBaseRail)Block.blocksList[par8]).onMinecartPass(worldObj, this, par1, par2, par3); ++ } ++ ++ if (flag && shouldDoRailFunctions()) + { + double d15 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + +@@ -709,12 +739,7 @@ + } + else + { +- int i1 = this.worldObj.getBlockMetadata(i, j, k); +- +- if (((BlockBaseRail)Block.blocksList[l]).isPowered()) +- { +- i1 &= 7; +- } ++ int i1 = ((BlockBaseRail)Block.blocksList[l]).getBasicRailMetadata(worldObj, this, i, j, k); + + par3 = (double)j; + +@@ -760,13 +785,8 @@ + + if (BlockBaseRail.isRailBlock(l)) + { +- int i1 = this.worldObj.getBlockMetadata(i, j, k); ++ int i1 = ((BlockBaseRail)Block.blocksList[l]).getBasicRailMetadata(worldObj, this, i, j, k); + par3 = (double)j; +- +- if (((BlockBaseRail)Block.blocksList[l]).isPowered()) +- { +- i1 &= 7; +- } + + if (i1 >= 2 && i1 <= 5) + { +@@ -872,11 +892,17 @@ + */ + public void applyEntityCollision(Entity par1Entity) + { ++ MinecraftForge.EVENT_BUS.post(new MinecartCollisionEvent(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.func_94087_l() == 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); + } +@@ -922,7 +948,7 @@ + double d7 = par1Entity.motionX + this.motionX; + double d8 = par1Entity.motionZ + this.motionZ; + +- if (((EntityMinecart)par1Entity).func_94087_l() == 2 && this.func_94087_l() != 2) ++ if (((EntityMinecart)par1Entity).isPoweredCart() && !isPoweredCart()) + { + this.motionX *= 0.20000000298023224D; + this.motionZ *= 0.20000000298023224D; +@@ -930,7 +956,7 @@ + par1Entity.motionX *= 0.949999988079071D; + par1Entity.motionZ *= 0.949999988079071D; + } +- else if (((EntityMinecart)par1Entity).func_94087_l() != 2 && this.func_94087_l() == 2) ++ else if (!((EntityMinecart)par1Entity).isPoweredCart() && isPoweredCart()) + { + par1Entity.motionX *= 0.20000000298023224D; + par1Entity.motionZ *= 0.20000000298023224D; +@@ -1118,4 +1144,206 @@ + { + return this.field_94102_c != null ? this.field_94102_c : super.getEntityName(); + } ++ ++ /** ++ * Moved to allow overrides. ++ * This code handles minecart movement and speed capping when on a rail. ++ */ ++ public void moveMinecartOnRail(int x, int y, int z, double par4){ ++ double d12 = this.motionX; ++ double d13 = this.motionZ; ++ ++ if (this.riddenByEntity != null) ++ { ++ d12 *= 0.75D; ++ d13 *= 0.75D; ++ } ++ ++ if (d12 < -par4) ++ { ++ d12 = -par4; ++ } ++ ++ if (d12 > par4) ++ { ++ d12 = par4; ++ } ++ ++ if (d13 < -par4) ++ { ++ d13 = -par4; ++ } ++ ++ if (d13 > par4) ++ { ++ d13 = par4; ++ } ++ ++ this.moveEntity(d12, 0.0D, d13); ++ } ++ ++ /** ++ * 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; ++ } ++ ++ /** ++ * 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, ++ * 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() { ++ if (this instanceof ItemChestMinecart) ++ { ++ return new ItemStack(Item.minecartCrate); ++ } ++ if (this instanceof ItemTntMinecart) ++ { ++ return new ItemStack(Item.field_94582_cb); ++ } ++ if (this instanceof ItemFurnaceMinecart) ++ { ++ return new ItemStack(Item.minecartPowered); ++ } ++ return new ItemStack(Item.minecartEmpty); ++ } ++ ++ /** ++ * 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 onMinecartPass() and should ignore Powered Rails. ++ * @return True if this cart should call onMinecartPass(). ++ */ ++ public boolean shouldDoRailFunctions() ++ { ++ return true; ++ } ++ ++ /** ++ * Returns true if this cart is self propelled. ++ * @return True if powered. ++ */ ++ public boolean isPoweredCart() ++ { ++ return func_94087_l() == 2; ++ } ++ ++ /** ++ * Returns true if this cart can be ridden by an Entity. ++ * @return True if this cart can be ridden. ++ */ ++ public boolean canBeRidden() ++ { ++ if(this instanceof ItemRideableMinecart) ++ { ++ return true; ++ } ++ return false; ++ } ++ ++ /** ++ * Getters/setters for physics variables ++ */ ++ ++ /** ++ * Returns the carts max speed when traveling on rails. 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 and the carts current speed cap to determine the carts current ++ * max speed. A normal rail's max speed is 0.4. ++ * ++ * @return Carts max speed. ++ */ ++ public float getMaxCartSpeedOnRail() ++ { ++ return 1.2f; ++ } ++ ++ /** ++ * Returns the current speed cap for the cart when traveling on rails. This ++ * functions differs from getMaxCartSpeedOnRail() in that it controls ++ * current movement and cannot be overridden. The value however can never be ++ * higher than getMaxCartSpeedOnRail(). ++ * ++ * @return ++ */ ++ public final float getCurrentCartSpeedCapOnRail() ++ { ++ return currentSpeedRail; ++ } ++ ++ public final void setCurrentCartSpeedCapOnRail(float value) ++ { ++ value = Math.min(value, getMaxCartSpeedOnRail()); ++ currentSpeedRail = 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; ++ } ++ ++ public double getSlopeAdjustment() ++ { ++ return 0.0078125D; ++ } + }