Merged in MCL branch

This commit is contained in:
LexManos 2012-01-12 07:38:23 +00:00
parent ad378151cf
commit e5a16e25df
12 changed files with 2622 additions and 18 deletions

View file

@ -6,6 +6,8 @@
package net.minecraft.src.forge;
import net.minecraft.src.Block;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityMinecart;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.IInventory;
import net.minecraft.src.ItemStack;
@ -71,6 +73,36 @@ public class ForgeHooks {
static LinkedList<ISleepHandler> sleepHandlers = new LinkedList<ISleepHandler>();
public static void onMinecartUpdate(EntityMinecart minecart, int x, int y, int z)
{
for (IMinecartHandler handler : minecartHandlers)
{
handler.onMinecartUpdate(minecart, x, y, z);
}
}
public static void onMinecartEntityCollision(EntityMinecart minecart, Entity entity)
{
for (IMinecartHandler handler : minecartHandlers)
{
handler.onMinecartEntityCollision(minecart, entity);
}
}
public static boolean onMinecartInteract(EntityMinecart minecart, EntityPlayer player)
{
boolean canceled = true;
for (IMinecartHandler handler : minecartHandlers)
{
boolean tmp = handler.onMinecartInteract(minecart, player, canceled);
canceled = canceled && tmp;
}
return canceled;
}
static LinkedList<IMinecartHandler> minecartHandlers = new LinkedList<IMinecartHandler>();
// Plant Management
// ------------------------------------------------------------
static class ProbableItem {

View file

@ -0,0 +1,50 @@
package net.minecraft.src.forge;
import net.minecraft.src.AxisAlignedBB;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityMinecart;
/**
* This class defines a replacement for the default minecart collision code.
* Only one handler can be registered at a time. It it registered with EntityMinecart.registerCollisionHandler().
* If you use this, make it a configuration option.
* @author CovertJaguar
*/
public interface IMinecartCollisionHandler
{
/**
* This basically replaces the function of the same name in EnityMinecart.
* Code in IMinecartHooks.applyEntityCollisionHook is still run.
* @param cart The cart that called the collision.
* @param other The object it collided with.
*/
public void onEntityCollision(EntityMinecart cart, Entity other);
/**
* This function replaced the function of the same name in EntityMinecart.
* It is used to define whether minecarts collide with specific entities,
* for example items.
* @param cart The cart for which the collision box was requested.
* @param other The entity requesting the collision box.
* @return The collision box or null.
*/
public AxisAlignedBB getCollisionBox(EntityMinecart cart, Entity other);
/**
* This function is used to define the box used for detecting minecart collisions.
* It is generally bigger that the normal collision box.
* @param cart The cart for which the collision box was requested.
* @return The collision box, cannot be null.
*/
public AxisAlignedBB getMinecartCollisionBox(EntityMinecart cart);
/**
* This function replaces the function of the same name in EntityMinecart.
* It defines whether minecarts are solid to the player.
* @param cart The cart for which the bounding box was requested.
* @return The bounding box or null.
*/
public AxisAlignedBB getBoundingBox(EntityMinecart cart);
}

View file

@ -0,0 +1,38 @@
package net.minecraft.src.forge;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityMinecart;
import net.minecraft.src.EntityPlayer;
public interface IMinecartHandler {
/**
* This functions is called at the end of every minecart's doUpdate loop.
* If you override EntityMinecart.doUpdate(), is recommended that you retain the code that calls this function.
* @param cart The cart that called the function.
* @param i X coordinate of the rail
* @param j Y coordinate of the rail
* @param k Z coordinate of the rail
*/
public void onMinecartUpdate(EntityMinecart minecart, int x, int y, int z);
/**
* This function allows several mods to add code into the collision routine at the same time regardless of the collision handler registered.
* If you override EntityMinecart.applyEntityCollision(), is recommended that you retain the code that calls this function.
* @param cart The cart that called the function.
* @param other
*/
public void onMinecartEntityCollision(EntityMinecart minecart, Entity entity);
/**
* This function is called whenever a player attempts to interact with a minecart.
* The primary reason for this hook is to fix a few bugs and put restrictions on how a minecart can be used under certain circumstances.
* If you override EntityMinecart.interact(), is recommended that you retain the code that calls this function.
* @param cart The cart that called the function.
* @param player The player that tried to interact with the minecart.
* @param canceled Wither or not a pervious hook has canceled the interaction of a player.
* @return Whether the player can interact with the minecart.
*/
public boolean onMinecartInteract(EntityMinecart minecart, EntityPlayer player, boolean canceled);
}

View file

@ -0,0 +1,49 @@
package net.minecraft.src.forge;
import net.minecraft.src.EntityMinecart;
/**
* Used to create hashmap values for Minecart/type pairs
* Written by CovertJaguar
*/
public class MinecartKey {
public final Class<? extends EntityMinecart> minecart;
public final int type;
public MinecartKey(Class<? extends EntityMinecart> c, int t)
{
minecart = c;
type = t;
}
@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;
}
}

View file

@ -6,6 +6,7 @@
package net.minecraft.src.forge;
import net.minecraft.src.Block;
import net.minecraft.src.EntityMinecart;
import net.minecraft.src.Item;
import net.minecraft.src.ItemStack;
import net.minecraft.src.World;
@ -57,6 +58,15 @@ public class MinecraftForge {
ForgeHooks.craftingHandlers.add(handler);
}
/**
* Registers a new minecart handler
* @param handler The Handler to be registered
*/
public static void registerMinecartHandler(IMinecartHandler handler)
{
ForgeHooks.minecartHandlers.add(handler);
}
/**
* This is not supposed to be called outside of Minecraft internals.
*/
@ -560,7 +570,6 @@ public class MinecraftForge {
return rarity;
}
/**
* Gets a random item stack to place in a dungeon chest during world generation
* @param rand World generation random number generator
@ -587,6 +596,149 @@ public class MinecraftForge {
return null;
}
//Minecart Dictionary --------------------------------------
private static Map<MinecartKey, ItemStack> itemForMinecart = new HashMap<MinecartKey, ItemStack>();
private static Map<ItemStack, MinecartKey> minecartForItem = new HashMap<ItemStack, MinecartKey>();
/**
* 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<? extends EntityMinecart> 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<? extends EntityMinecart> minecart, int type, ItemStack item)
{
MinecartKey k = new MinecartKey(minecart, type);
itemForMinecart.put(k, item);
minecartForItem.put(item, k);
}
/**
* Removes a previously registered Minecart. Useful for replacing the vanilla minecarts.
* @param minecart
* @param type
*/
public static void removeMinecart(Class<? extends EntityMinecart> minecart, int type)
{
MinecartKey k = new MinecartKey(minecart, type);
ItemStack item = itemForMinecart.remove(k);
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<? extends EntityMinecart> 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<? extends EntityMinecart> 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)
{
if(cart.getClass() == EntityMinecart.class)
{
return getItemForCart(cart.getClass(), cart.getMinecartType());
}
return getItemForCart(cart.getClass(), 0);
}
/**
* 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<? extends EntityMinecart> getCartClassForItem(ItemStack item)
{
MinecartKey k = minecartForItem.get(item);
if(k != null)
{
return k.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 k = minecartForItem.get(item);
if(k != null)
{
return k.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<ItemStack> getAllCartItems()
{
Set<ItemStack> ret = new HashSet<ItemStack>();
for(ItemStack item : minecartForItem.keySet())
{
ret.add(item.copy());
}
return ret;
}
static
{
addDungeonMob("Skeleton", 1.0f);
@ -605,6 +757,10 @@ public class MinecraftForge {
addDungeonLoot(new ItemStack(Item.record13), 0.05f );
addDungeonLoot(new ItemStack(Item.recordCat), 0.05f );
addDungeonLoot(new ItemStack(Item.dyePowder, 1, 3), 1.00f );
registerMinecart(EntityMinecart.class, 0, new ItemStack(Item.minecartEmpty));
registerMinecart(EntityMinecart.class, 1, new ItemStack(Item.minecartCrate));
registerMinecart(EntityMinecart.class, 2, new ItemStack(Item.minecartPowered));
}
}

View file

@ -1,6 +1,23 @@
--- ../src_base/minecraft/net/minecraft/src/BlockRail.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft/net/minecraft/src/BlockRail.java 0000-00-00 00:00:00.000000000 -0000
@@ -18,12 +18,12 @@
@@ -14,16 +14,29 @@
{
private final boolean isPowered;
+
+ /**
+ * 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;
+ }
public static final boolean isRailBlockAt(World world, int i, int j, int k)
{
int l = world.getBlockId(i, j, k);
@ -15,7 +32,16 @@
}
protected BlockRail(int i, int j, boolean flag)
@@ -99,7 +99,7 @@
@@ -89,7 +102,7 @@
public int getRenderType()
{
- return 9;
+ return renderType;
}
public int quantityDropped(Random random)
@@ -99,7 +112,7 @@
public boolean canPlaceBlockAt(World world, int i, int j, int k)
{
@ -24,7 +50,7 @@
}
public void onBlockAdded(World world, int i, int j, int k)
@@ -123,23 +123,23 @@
@@ -123,23 +136,23 @@
j1 &= 7;
}
boolean flag = false;
@ -53,3 +79,122 @@
{
flag = true;
}
@@ -313,8 +326,118 @@
return 0;
}
+ /**
+ * This function is no longer called by Minecraft
+ */
static boolean isPoweredBlockRail(BlockRail blockrail)
{
return blockrail.isPowered;
}
+
+ /**
+ * Return true if the rail can make corners.
+ * Used by placement logic.
+ * @param world The world.
+ * @param i The rail X coordinate.
+ * @param j The rail Y coordinate.
+ * @param k The rail Z coordinate.
+ * @return True if the rail can make corners.
+ */
+ public boolean isFlexibleRail(World world, int i, int j, int k)
+ {
+ return !isPowered;
+ }
+
+ /**
+ * Returns true if the rail can make up and down slopes.
+ * Used by placement logic.
+ * @param world The world.
+ * @param i The rail X coordinate.
+ * @param j The rail Y coordinate.
+ * @param k The rail Z coordinate.
+ * @return True if the rail can make slopes.
+ */
+ public boolean canMakeSlopes(World world, int i, int j, int k)
+ {
+ return true;
+ }
+
+ /**
+ * Return the rails 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)
+ *
+ * All directions are Notch defined.
+ * In MC Beta 1.8.3 the Sun rises in the North.
+ * In MC 1.0.0 the Sun rises in the East.
+ * @param world The world.
+ * @param cart The cart asking for the metadata, null if it is not called by EntityMinecart.
+ * @param i The rail X coordinate.
+ * @param j The rail Y coordinate.
+ * @param k The rail Z coordinate.
+ * @return The metadata.
+ */
+ public int getBasicRailMetadata(IBlockAccess world, EntityMinecart cart, int i, int j, int k)
+ {
+ int meta = world.getBlockMetadata(i, j, k);
+ if(isPowered) {
+ meta = meta & 7;
+ }
+ return meta;
+ }
+
+ /**
+ * Returns the max speed of the rail at [i, j, k].
+ * @param world The world.
+ * @param cart The cart on the rail, may be null.
+ * @param i The rail X coordinate.
+ * @param j The rail Y coordinate.
+ * @param k The rail Z coordinate.
+ * @return The max speed of the current rail.
+ */
+ public float getRailMaxSpeed(World world, EntityMinecart cart, int i, int j, int k)
+ {
+ 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 i The rail X coordinate.
+ * @param j The rail Y coordinate.
+ * @param k The rail Z coordinate.
+ */
+ public void onMinecartPass(World world, EntityMinecart cart, int i, int j, int k)
+ {
+ }
+
+ /**
+ * Return true if this rail uses the 4th bit as a power bit.
+ * Avoid using this function when getBasicRailMetadata() can be used instead.
+ * The only reason to use this function is if you wish to change the rails metadata.
+ * @param world The world.
+ * @param i The rail X coordinate.
+ * @param j The rail Y coordinate.
+ * @param k The rail Z coordinate.
+ * @return True if the 4th bit is a power bit.
+ */
+ public boolean hasPowerBit(World world, int i, int j, int k)
+ {
+ return isPowered;
+ }
}

View file

@ -0,0 +1,915 @@
--- ../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
@@ -4,9 +4,14 @@
package net.minecraft.src;
+import java.util.ArrayList;
import java.util.List;
import java.util.Random;
+import net.minecraft.src.forge.ForgeHooks;
+import net.minecraft.src.forge.IMinecartCollisionHandler;
+import net.minecraft.src.forge.MinecraftForge;
+
// Referenced classes of package net.minecraft.src:
// Entity, IInventory, ItemStack, DataWatcher,
// World, Item, EntityItem, Block,
@@ -18,13 +23,13 @@
implements IInventory
{
- private ItemStack cargoItems[];
- private int fuel;
- private boolean field_856_i;
+ protected ItemStack cargoItems[];
+ protected int fuel;
+ protected boolean field_856_i;
public int minecartType;
public double pushX;
public double pushZ;
- private static final int field_855_j[][][] = {
+ protected static final int field_855_j[][][] = {
{
{
0, 0, -1
@@ -87,16 +92,36 @@
}
}
};
- private int minecartPosRotationIncrements;
- 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 minecartPosRotationIncrements;
+ 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 world)
{
super(world);
@@ -106,6 +131,18 @@
preventEntitySpawning = true;
setSize(0.98F, 0.7F);
yOffset = height / 2.0F;
+
+ maxSpeedRail = defaultMaxSpeedRail;
+ maxSpeedGround = defaultMaxSpeedGround;
+ maxSpeedAirLateral = defaultMaxSpeedAirLateral;
+ maxSpeedAirVertical = defaultMaxSpeedAirVertical;
+ dragAir = defaultDragAir;
+ }
+
+ public EntityMinecart(World world, int type)
+ {
+ this(world);
+ minecartType = type;
}
protected boolean canTriggerWalking()
@@ -123,17 +160,27 @@
public AxisAlignedBB getCollisionBox(Entity entity)
{
+ if (getCollisionHandler() != null)
+ {
+ return getCollisionHandler().getCollisionBox(this, entity);
+ }
+
return entity.boundingBox;
}
public AxisAlignedBB getBoundingBox()
{
+ if (getCollisionHandler() != null)
+ {
+ return getCollisionHandler().getBoundingBox(this);
+ }
+
return null;
}
public boolean canBePushed()
{
- return true;
+ return canBePushed;
}
public EntityMinecart(World world, double d, double d1, double d2,
@@ -172,8 +219,10 @@
riddenByEntity.mountEntity(this);
}
setEntityDead();
- dropItemWithOffset(Item.minecartEmpty.shiftedIndex, 1, 0.0F);
- if(minecartType == 1)
+
+ dropCartAsItem();
+
+ if(getSizeInventory() > 0)
{
EntityMinecart entityminecart = this;
label0:
@@ -207,12 +256,6 @@
worldObj.spawnEntityInWorld(entityitem);
} while(true);
}
-
- dropItemWithOffset(Block.chest.blockID, 1, 0.0F);
- } else
- if(minecartType == 2)
- {
- dropItemWithOffset(Block.stoneOvenIdle.blockID, 1, 0.0F);
}
}
return true;
@@ -277,7 +320,7 @@
{
func_41024_b(func_41025_i() - 1);
}
- if(isMinecartPowered() && rand.nextInt(4) == 0)
+ if(isMinecartPowered() && rand.nextInt(4) == 0 && minecartType == 2 && getClass() == EntityMinecart.class)
{
worldObj.spawnParticle("largesmoke", posX, posY + 0.80000000000000004D, posZ, 0.0D, 0.0D, 0.0D);
}
@@ -317,22 +360,19 @@
double d2 = 0.40000000000000002D;
double d4 = 0.0078125D;
int l = worldObj.getBlockId(i, j, k);
- if(BlockRail.isRailBlock(l))
+ if(canUseRail() && BlockRail.isRailBlock(l))
{
Vec3D vec3d = func_514_g(posX, posY, posZ);
- int i1 = worldObj.getBlockMetadata(i, j, k);
+ int i1 = ((BlockRail)Block.blocksList[l]).getBasicRailMetadata(worldObj, this, i, j, k);
posY = j;
boolean flag = false;
boolean flag1 = false;
if(l == Block.railPowered.blockID)
{
- flag = (i1 & 8) != 0;
+ flag = (worldObj.getBlockMetadata(i, j, k) & 8) != 0;
flag1 = !flag;
}
- if(((BlockRail)Block.blocksList[l]).getIsPowered())
- {
- i1 &= 7;
- }
+
if(i1 >= 2 && i1 <= 5)
{
posY = j + 1;
@@ -366,7 +406,8 @@
double d13 = Math.sqrt(motionX * motionX + motionZ * motionZ);
motionX = (d13 * d9) / d11;
motionZ = (d13 * d10) / d11;
- if(flag1)
+
+ if(flag1 && shouldDoRailFunctions())
{
double d16 = Math.sqrt(motionX * motionX + motionZ * motionZ);
if(d16 < 0.029999999999999999D)
@@ -407,30 +448,9 @@
posX = d18 + d9 * d17;
posZ = d19 + d10 * d17;
setPosition(posX, posY + (double)yOffset, posZ);
- double d23 = motionX;
- double d25 = motionZ;
- if(riddenByEntity != null)
- {
- d23 *= 0.75D;
- d25 *= 0.75D;
- }
- if(d23 < -d2)
- {
- d23 = -d2;
- }
- if(d23 > d2)
- {
- d23 = d2;
- }
- if(d25 < -d2)
- {
- d25 = -d2;
- }
- if(d25 > d2)
- {
- d25 = d2;
- }
- moveEntity(d23, 0.0D, d25);
+
+ moveMinecartOnRail(i, j, k);
+
if(ai[0][1] != 0 && MathHelper.floor_double(posX) - i == ai[0][0] && MathHelper.floor_double(posZ) - k == ai[0][2])
{
setPosition(posX, posY + (double)ai[0][1], posZ);
@@ -439,37 +459,9 @@
{
setPosition(posX, posY + (double)ai[1][1], posZ);
}
- if(riddenByEntity != null)
- {
- motionX *= 0.99699997901916504D;
- motionY *= 0.0D;
- motionZ *= 0.99699997901916504D;
- } else
- {
- if(minecartType == 2)
- {
- double d27 = MathHelper.sqrt_double(pushX * pushX + pushZ * pushZ);
- if(d27 > 0.01D)
- {
- pushX /= d27;
- pushZ /= d27;
- double d29 = 0.040000000000000001D;
- motionX *= 0.80000001192092896D;
- motionY *= 0.0D;
- motionZ *= 0.80000001192092896D;
- motionX += pushX * d29;
- motionZ += pushZ * d29;
- } else
- {
- motionX *= 0.89999997615814209D;
- motionY *= 0.0D;
- motionZ *= 0.89999997615814209D;
- }
- }
- motionX *= 0.95999997854232788D;
- motionY *= 0.0D;
- motionZ *= 0.95999997854232788D;
- }
+
+ applyDragAndPushForces();
+
Vec3D vec3d1 = func_514_g(posX, posY, posZ);
if(vec3d1 != null && vec3d != null)
{
@@ -490,25 +482,15 @@
motionX = d15 * (double)(k1 - i);
motionZ = d15 * (double)(l1 - k);
}
- if(minecartType == 2)
+
+ updatePushForces();
+
+ if (shouldDoRailFunctions())
{
- double d30 = MathHelper.sqrt_double(pushX * pushX + pushZ * pushZ);
- if(d30 > 0.01D && motionX * motionX + motionZ * motionZ > 0.001D)
- {
- pushX /= d30;
- pushZ /= d30;
- if(pushX * motionX + pushZ * motionZ < 0.0D)
- {
- pushX = 0.0D;
- pushZ = 0.0D;
- } else
- {
- pushX = motionX;
- pushZ = motionZ;
- }
- }
+ ((BlockRail)Block.blocksList[l]).onMinecartPass(worldObj, this, i, j, k);
}
- if(flag)
+
+ if(flag && shouldDoRailFunctions())
{
double d31 = Math.sqrt(motionX * motionX + motionZ * motionZ);
if(d31 > 0.01D)
@@ -540,37 +522,10 @@
}
}
}
- } else
+ }
+ else
{
- if(motionX < -d2)
- {
- motionX = -d2;
- }
- if(motionX > d2)
- {
- motionX = d2;
- }
- if(motionZ < -d2)
- {
- motionZ = -d2;
- }
- if(motionZ > d2)
- {
- motionZ = d2;
- }
- if(onGround)
- {
- motionX *= 0.5D;
- motionY *= 0.5D;
- motionZ *= 0.5D;
- }
- moveEntity(motionX, motionY, motionZ);
- if(!onGround)
- {
- motionX *= 0.94999998807907104D;
- motionY *= 0.94999998807907104D;
- motionZ *= 0.94999998807907104D;
- }
+ moveMinecartOffRail(i, j, k);
}
rotationPitch = 0.0F;
double d6 = prevPosX - posX;
@@ -592,7 +547,20 @@
field_856_i = !field_856_i;
}
setRotation(rotationYaw, rotationPitch);
- List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D));
+
+ AxisAlignedBB box = null;
+
+ if (getCollisionHandler() != null)
+ {
+ box = getCollisionHandler().getMinecartCollisionBox(this);
+ }
+ else
+ {
+
+ box = boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D);
+ }
+
+ List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, box);
if(list != null && list.size() > 0)
{
for(int j1 = 0; j1 < list.size(); j1++)
@@ -613,6 +581,178 @@
}
riddenByEntity = null;
}
+ updateFuel();
+ ForgeHooks.onMinecartUpdate(this, i, j, k);
+ }
+
+ /**
+ * Carts should return their drag factor here
+ * @return The drag rate.
+ */
+ protected double getDrag()
+ {
+ if(riddenByEntity != null)
+ {
+ return 0.99699997901916504D;
+ }
+ return 0.95999997854232788D;
+ }
+
+ /**
+ * 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.040000000000000001D;
+ motionX *= 0.80000001192092896D;
+ motionY *= 0.0D;
+ motionZ *= 0.80000001192092896D;
+ motionX += pushX * d29;
+ motionZ += pushZ * d29;
+ } else
+ {
+ motionX *= 0.89999997615814209D;
+ motionY *= 0.0D;
+ motionZ *= 0.89999997615814209D;
+ }
+ }
+ 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 d23 = motionX;
+ double d25 = motionZ;
+ if(riddenByEntity != null)
+ {
+ d23 *= 0.75D;
+ d25 *= 0.75D;
+ }
+ if(d23 < -maxSpeed)
+ {
+ d23 = -maxSpeed;
+ }
+ if(d23 > maxSpeed)
+ {
+ d23 = maxSpeed;
+ }
+ if(d25 < -maxSpeed)
+ {
+ d25 = -maxSpeed;
+ }
+ if(d25 > maxSpeed)
+ {
+ d25 = maxSpeed;
+ }
+ moveEntity(d23, 0.0D, d25);
+ }
+
+ /**
+ * 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--;
@@ -636,11 +776,8 @@
int l = worldObj.getBlockId(i, j, k);
if(BlockRail.isRailBlock(l))
{
- int i1 = worldObj.getBlockMetadata(i, j, k);
- if(((BlockRail)Block.blocksList[l]).getIsPowered())
- {
- i1 &= 7;
- }
+ int i1 = ((BlockRail)Block.blocksList[l]).getBasicRailMetadata(worldObj, this, i, j, k);
+
d1 = j;
if(i1 >= 2 && i1 <= 5)
{
@@ -681,12 +818,8 @@
int l = worldObj.getBlockId(i, j, k);
if(BlockRail.isRailBlock(l))
{
- int i1 = worldObj.getBlockMetadata(i, j, k);
+ int i1 = ((BlockRail)Block.blocksList[l]).getBasicRailMetadata(worldObj, this, i, j, k);
d1 = j;
- if(((BlockRail)Block.blocksList[l]).getIsPowered())
- {
- i1 &= 7;
- }
if(i1 >= 2 && i1 <= 5)
{
d1 = j + 1;
@@ -739,13 +872,14 @@
protected void writeEntityToNBT(NBTTagCompound nbttagcompound)
{
nbttagcompound.setInteger("Type", minecartType);
- if(minecartType == 2)
+ if(isPoweredCart())
{
nbttagcompound.setDouble("PushX", pushX);
nbttagcompound.setDouble("PushZ", pushZ);
- nbttagcompound.setShort("Fuel", (short)fuel);
- } else
- if(minecartType == 1)
+ nbttagcompound.setInteger("Fuel", fuel);
+ }
+
+ if(getSizeInventory() > 0)
{
NBTTagList nbttaglist = new NBTTagList();
for(int i = 0; i < cargoItems.length; i++)
@@ -766,13 +900,14 @@
protected void readEntityFromNBT(NBTTagCompound nbttagcompound)
{
minecartType = nbttagcompound.getInteger("Type");
- if(minecartType == 2)
+ if(isPoweredCart())
{
pushX = nbttagcompound.getDouble("PushX");
pushZ = nbttagcompound.getDouble("PushZ");
- fuel = nbttagcompound.getShort("Fuel");
- } else
- if(minecartType == 1)
+ fuel = nbttagcompound.getInteger("Fuel");
+ }
+
+ if(getSizeInventory() > 0)
{
NBTTagList nbttaglist = nbttagcompound.getTagList("Items");
cargoItems = new ItemStack[getSizeInventory()];
@@ -796,6 +931,16 @@
public void applyEntityCollision(Entity entity)
{
+ ForgeHooks.onMinecartEntityCollision(this, entity);
+
+
+ if (getCollisionHandler() != null)
+ {
+ getCollisionHandler().onEntityCollision(this, entity);
+ return;
+ }
+
+
if(worldObj.multiplayerWorld)
{
return;
@@ -804,7 +949,7 @@
{
return;
}
- if((entity instanceof EntityLiving) && !(entity instanceof EntityPlayer) && minecartType == 0 && motionX * motionX + motionZ * motionZ > 0.01D && riddenByEntity == null && entity.ridingEntity == null)
+ if((entity instanceof EntityLiving) && !(entity instanceof EntityPlayer) && canBeRidden() && motionX * motionX + motionZ * motionZ > 0.01D && riddenByEntity == null && entity.ridingEntity == null)
{
entity.mountEntity(this);
}
@@ -842,7 +987,7 @@
}
double d7 = entity.motionX + motionX;
double d8 = entity.motionZ + motionZ;
- if(((EntityMinecart)entity).minecartType == 2 && minecartType != 2)
+ if(((EntityMinecart)entity).isPoweredCart() && !isPoweredCart())
{
motionX *= 0.20000000298023224D;
motionZ *= 0.20000000298023224D;
@@ -850,7 +995,7 @@
entity.motionX *= 0.94999998807907104D;
entity.motionZ *= 0.94999998807907104D;
} else
- if(((EntityMinecart)entity).minecartType != 2 && minecartType == 2)
+ if(!((EntityMinecart)entity).isPoweredCart() && isPoweredCart())
{
entity.motionX *= 0.20000000298023224D;
entity.motionZ *= 0.20000000298023224D;
@@ -878,7 +1023,7 @@
public int getSizeInventory()
{
- return 27;
+ return (minecartType == 1 && getClass() == EntityMinecart.class ? 27 : 0);
}
public ItemStack getStackInSlot(int i)
@@ -933,7 +1078,12 @@
public boolean interact(EntityPlayer entityplayer)
{
- if(minecartType == 0)
+ if (!ForgeHooks.onMinecartInteract(this, entityplayer))
+ {
+ return true;
+ }
+
+ if(canBeRidden())
{
if(riddenByEntity != null && (riddenByEntity instanceof EntityPlayer) && riddenByEntity != entityplayer)
{
@@ -944,14 +1094,14 @@
entityplayer.mountEntity(this);
}
} else
- if(minecartType == 1)
+ if(getSizeInventory() > 0)
{
if(!worldObj.multiplayerWorld)
{
entityplayer.displayGUIChest(this);
}
} else
- if(minecartType == 2)
+ if(minecartType == 2 && getClass() == EntityMinecart.class)
{
ItemStack itemstack = entityplayer.inventory.getCurrentItem();
if(itemstack != null && itemstack.itemID == Item.coal.shiftedIndex)
@@ -998,7 +1148,7 @@
return entityplayer.getDistanceSqToEntity(this) <= 64D;
}
- protected boolean isMinecartPowered()
+ public boolean isMinecartPowered()
{
return (dataWatcher.getWatchableObjectByte(16) & 1) != 0;
}
@@ -1051,5 +1201,203 @@
{
return 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;
+ }
+
+ /**
+ * 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;
+ }
}

View file

@ -0,0 +1,86 @@
--- ../src_base/minecraft/net/minecraft/src/RailLogic.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft/net/minecraft/src/RailLogic.java 0000-00-00 00:00:00.000000000 -0000
@@ -10,7 +10,7 @@
// Referenced classes of package net.minecraft.src:
// World, Block, BlockRail, ChunkPosition
-class RailLogic
+public class RailLogic
{
private World worldObj;
@@ -20,6 +20,7 @@
private final boolean isPoweredRail;
private List connectedTracks;
final BlockRail rail; /* synthetic field */
+ private final boolean canMakeSlopes;
public RailLogic(BlockRail blockrail, World world, int i, int j, int k)
{
@@ -31,15 +32,12 @@
trackY = j;
trackZ = k;
int l = world.getBlockId(i, j, k);
- int i1 = world.getBlockMetadata(i, j, k);
- if(BlockRail.isPoweredBlockRail((BlockRail)Block.blocksList[l]))
- {
- isPoweredRail = true;
- i1 &= -9;
- } else
- {
- isPoweredRail = false;
- }
+
+ BlockRail target = (BlockRail)Block.blocksList[l];
+ int i1 = target.getBasicRailMetadata(world, null, i, j, k);
+ isPoweredRail = !target.isFlexibleRail(world, i, j, k);
+ canMakeSlopes = target.canMakeSlopes(world, i, j, k);
+
setConnections(i1);
}
@@ -249,7 +247,7 @@
byte0 = 9;
}
}
- if(byte0 == 0)
+ if(byte0 == 0 && canMakeSlopes)
{
if(BlockRail.isRailBlockAt(worldObj, trackX, trackY + 1, trackZ - 1))
{
@@ -260,7 +258,7 @@
byte0 = 5;
}
}
- if(byte0 == 1)
+ if(byte0 == 1 && canMakeSlopes)
{
if(BlockRail.isRailBlockAt(worldObj, trackX + 1, trackY + 1, trackZ))
{
@@ -381,7 +379,7 @@
}
}
}
- if(byte0 == 0)
+ if(byte0 == 0 && canMakeSlopes)
{
if(BlockRail.isRailBlockAt(worldObj, trackX, trackY + 1, trackZ - 1))
{
@@ -392,7 +390,7 @@
byte0 = 5;
}
}
- if(byte0 == 1)
+ if(byte0 == 1 && canMakeSlopes)
{
if(BlockRail.isRailBlockAt(worldObj, trackX + 1, trackY + 1, trackZ))
{
@@ -433,7 +431,7 @@
}
}
- static int getNAdjacentTracks(RailLogic raillogic)
+ public static int getNAdjacentTracks(RailLogic raillogic)
{
return raillogic.getAdjacentTracks();
}

View file

@ -1,6 +1,23 @@
--- ../src_base/minecraft_server/net/minecraft/src/BlockRail.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft_server/net/minecraft/src/BlockRail.java 0000-00-00 00:00:00.000000000 -0000
@@ -18,12 +18,12 @@
@@ -14,16 +14,29 @@
{
private final boolean isPowered;
+
+ /**
+ * 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;
+ }
public static final boolean isRailBlockAt(World world, int i, int j, int k)
{
int l = world.getBlockId(i, j, k);
@ -15,7 +32,16 @@
}
protected BlockRail(int i, int j, boolean flag)
@@ -99,7 +99,7 @@
@@ -89,7 +102,7 @@
public int getRenderType()
{
- return 9;
+ return renderType;
}
public int quantityDropped(Random random)
@@ -99,7 +112,7 @@
public boolean canPlaceBlockAt(World world, int i, int j, int k)
{
@ -24,7 +50,7 @@
}
public void onBlockAdded(World world, int i, int j, int k)
@@ -123,23 +123,23 @@
@@ -123,23 +136,23 @@
j1 &= 7;
}
boolean flag = false;
@ -53,3 +79,122 @@
{
flag = true;
}
@@ -313,8 +326,118 @@
return 0;
}
+ /**
+ * This function is no longer called by Minecraft
+ */
static boolean isPoweredBlockRail(BlockRail blockrail)
{
return blockrail.isPowered;
}
+
+ /**
+ * Return true if the rail can make corners.
+ * Used by placement logic.
+ * @param world The world.
+ * @param i The rail X coordinate.
+ * @param j The rail Y coordinate.
+ * @param k The rail Z coordinate.
+ * @return True if the rail can make corners.
+ */
+ public boolean isFlexibleRail(World world, int i, int j, int k)
+ {
+ return !isPowered;
+ }
+
+ /**
+ * Returns true if the rail can make up and down slopes.
+ * Used by placement logic.
+ * @param world The world.
+ * @param i The rail X coordinate.
+ * @param j The rail Y coordinate.
+ * @param k The rail Z coordinate.
+ * @return True if the rail can make slopes.
+ */
+ public boolean canMakeSlopes(World world, int i, int j, int k)
+ {
+ return true;
+ }
+
+ /**
+ * Return the rails 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)
+ *
+ * All directions are Notch defined.
+ * In MC Beta 1.8.3 the Sun rises in the North.
+ * In MC 1.0.0 the Sun rises in the East.
+ * @param world The world.
+ * @param cart The cart asking for the metadata, null if it is not called by EntityMinecart.
+ * @param i The rail X coordinate.
+ * @param j The rail Y coordinate.
+ * @param k The rail Z coordinate.
+ * @return The metadata.
+ */
+ public int getBasicRailMetadata(IBlockAccess world, EntityMinecart cart, int i, int j, int k)
+ {
+ int meta = world.getBlockMetadata(i, j, k);
+ if(isPowered) {
+ meta = meta & 7;
+ }
+ return meta;
+ }
+
+ /**
+ * Returns the max speed of the rail at [i, j, k].
+ * @param world The world.
+ * @param cart The cart on the rail, may be null.
+ * @param i The rail X coordinate.
+ * @param j The rail Y coordinate.
+ * @param k The rail Z coordinate.
+ * @return The max speed of the current rail.
+ */
+ public float getRailMaxSpeed(World world, EntityMinecart cart, int i, int j, int k)
+ {
+ 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 i The rail X coordinate.
+ * @param j The rail Y coordinate.
+ * @param k The rail Z coordinate.
+ */
+ public void onMinecartPass(World world, EntityMinecart cart, int i, int j, int k)
+ {
+ }
+
+ /**
+ * Return true if this rail uses the 4th bit as a power bit.
+ * Avoid using this function when getBasicRailMetadata() can be used instead.
+ * The only reason to use this function is if you wish to change the rails metadata.
+ * @param world The world.
+ * @param i The rail X coordinate.
+ * @param j The rail Y coordinate.
+ * @param k The rail Z coordinate.
+ * @return True if the 4th bit is a power bit.
+ */
+ public boolean hasPowerBit(World world, int i, int j, int k)
+ {
+ return isPowered;
+ }
}

View file

@ -27,19 +27,20 @@
nbttagcompound.setShort("Fire", (short)fire);
nbttagcompound.setShort("Air", (short)getAir());
nbttagcompound.setBoolean("OnGround", onGround);
+ if(customEntityData!=null) {
+ nbttagcompound.setCompoundTag("ForgeData",
+ customEntityData);
+ if (customEntityData != null)
+ {
+ nbttagcompound.setCompoundTag("ForgeEntityData", customEntityData);
+ }
writeEntityToNBT(nbttagcompound);
}
@@ -907,6 +927,9 @@
@@ -907,6 +927,10 @@
onGround = nbttagcompound.getBoolean("OnGround");
setPosition(posX, posY, posZ);
setRotation(rotationYaw, rotationPitch);
+ if(nbttagcompound.hasKey("ForgeData")) {
+ customEntityData=nbttagcompound.getCompoundTag("ForgeData");
+ if (nbttagcompound.hasKey("ForgeEntityData"))
+ {
+ customEntityData.getCompoundTag("ForgeEntityData");
+ }
readEntityFromNBT(nbttagcompound);
}

View file

@ -0,0 +1,910 @@
--- ../src_base/minecraft_server/net/minecraft/src/EntityMinecart.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft_server/net/minecraft/src/EntityMinecart.java 0000-00-00 00:00:00.000000000 -0000
@@ -4,9 +4,14 @@
package net.minecraft.src;
+import java.util.ArrayList;
import java.util.List;
import java.util.Random;
+import net.minecraft.src.forge.ForgeHooks;
+import net.minecraft.src.forge.IMinecartCollisionHandler;
+import net.minecraft.src.forge.MinecraftForge;
+
// Referenced classes of package net.minecraft.src:
// Entity, IInventory, ItemStack, DataWatcher,
// World, Item, EntityItem, Block,
@@ -18,13 +23,13 @@
implements IInventory
{
- private ItemStack cargoItems[];
- private int fuel;
- private boolean field_469_aj;
+ protected ItemStack cargoItems[];
+ protected int fuel;
+ protected boolean field_469_aj;
public int minecartType;
public double pushX;
public double pushZ;
- private static final int field_468_ak[][][] = {
+ protected static final int field_468_ak[][][] = {
{
{
0, 0, -1
@@ -87,13 +92,36 @@
}
}
};
- private int turnProgress;
- private double minecartX;
- private double minecartY;
- private double minecartZ;
- private double field_9159_ar;
- private double minecartPitch;
-
+ protected int turnProgress;
+ protected double minecartX;
+ protected double minecartY;
+ protected double minecartZ;
+ protected double field_9159_ar;
+ protected double minecartPitch;
+
+ /*Forge: Minecart Compatibility Layer Integration.
+ */
+ protected double velocityX;
+ protected double velocityY;
+ protected double velocityZ;
+ 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 world)
{
super(world);
@@ -103,6 +131,18 @@
preventEntitySpawning = true;
setSize(0.98F, 0.7F);
yOffset = height / 2.0F;
+
+ maxSpeedRail = defaultMaxSpeedRail;
+ maxSpeedGround = defaultMaxSpeedGround;
+ maxSpeedAirLateral = defaultMaxSpeedAirLateral;
+ maxSpeedAirVertical = defaultMaxSpeedAirVertical;
+ dragAir = defaultDragAir;
+ }
+
+ public EntityMinecart(World world, int type)
+ {
+ this(world);
+ minecartType = type;
}
protected boolean canTriggerWalking()
@@ -120,17 +160,27 @@
public AxisAlignedBB getCollisionBox(Entity entity)
{
+ if (getCollisionHandler() != null)
+ {
+ return getCollisionHandler().getCollisionBox(this, entity);
+ }
+
return entity.boundingBox;
}
public AxisAlignedBB getBoundingBox()
{
+ if (getCollisionHandler() != null)
+ {
+ return getCollisionHandler().getBoundingBox(this);
+ }
+
return null;
}
public boolean canBePushed()
{
- return true;
+ return canBePushed;
}
public EntityMinecart(World world, double d, double d1, double d2,
@@ -169,8 +219,10 @@
riddenByEntity.mountEntity(this);
}
setEntityDead();
- dropItemWithOffset(Item.minecartEmpty.shiftedIndex, 1, 0.0F);
- if(minecartType == 1)
+
+ dropCartAsItem();
+
+ if(getSizeInventory() > 0)
{
EntityMinecart entityminecart = this;
label0:
@@ -204,12 +256,6 @@
worldObj.entityJoinedWorld(entityitem);
} while(true);
}
-
- dropItemWithOffset(Block.chest.blockID, 1, 0.0F);
- } else
- if(minecartType == 2)
- {
- dropItemWithOffset(Block.stoneOvenIdle.blockID, 1, 0.0F);
}
}
return true;
@@ -267,7 +313,7 @@
{
func_41018_e_(func_41020_o() - 1);
}
- if(isMinecartPowered() && rand.nextInt(4) == 0)
+ if(isMinecartPowered() && rand.nextInt(4) == 0 && minecartType == 2 && getClass() == EntityMinecart.class)
{
worldObj.spawnParticle("largesmoke", posX, posY + 0.80000000000000004D, posZ, 0.0D, 0.0D, 0.0D);
}
@@ -307,22 +353,19 @@
double d2 = 0.40000000000000002D;
double d4 = 0.0078125D;
int l = worldObj.getBlockId(i, j, k);
- if(BlockRail.isRailBlock(l))
+ if(canUseRail() && BlockRail.isRailBlock(l))
{
Vec3D vec3d = func_182_g(posX, posY, posZ);
- int i1 = worldObj.getBlockMetadata(i, j, k);
+ int i1 = ((BlockRail)Block.blocksList[l]).getBasicRailMetadata(worldObj, this, i, j, k);;
posY = j;
boolean flag = false;
boolean flag1 = false;
if(l == Block.railPowered.blockID)
{
- flag = (i1 & 8) != 0;
+ flag = (worldObj.getBlockMetadata(i, j, k) & 8) != 0;
flag1 = !flag;
}
- if(((BlockRail)Block.blocksList[l]).getIsPowered())
- {
- i1 &= 7;
- }
+
if(i1 >= 2 && i1 <= 5)
{
posY = j + 1;
@@ -356,7 +399,8 @@
double d13 = Math.sqrt(motionX * motionX + motionZ * motionZ);
motionX = (d13 * d9) / d11;
motionZ = (d13 * d10) / d11;
- if(flag1)
+
+ if(flag1 && shouldDoRailFunctions())
{
double d16 = Math.sqrt(motionX * motionX + motionZ * motionZ);
if(d16 < 0.029999999999999999D)
@@ -397,30 +441,9 @@
posX = d18 + d9 * d17;
posZ = d19 + d10 * d17;
setPosition(posX, posY + (double)yOffset, posZ);
- double d23 = motionX;
- double d25 = motionZ;
- if(riddenByEntity != null)
- {
- d23 *= 0.75D;
- d25 *= 0.75D;
- }
- if(d23 < -d2)
- {
- d23 = -d2;
- }
- if(d23 > d2)
- {
- d23 = d2;
- }
- if(d25 < -d2)
- {
- d25 = -d2;
- }
- if(d25 > d2)
- {
- d25 = d2;
- }
- moveEntity(d23, 0.0D, d25);
+
+ moveMinecartOnRail(i, j, k);
+
if(ai[0][1] != 0 && MathHelper.floor_double(posX) - i == ai[0][0] && MathHelper.floor_double(posZ) - k == ai[0][2])
{
setPosition(posX, posY + (double)ai[0][1], posZ);
@@ -429,37 +452,9 @@
{
setPosition(posX, posY + (double)ai[1][1], posZ);
}
- if(riddenByEntity != null)
- {
- motionX *= 0.99699997901916504D;
- motionY *= 0.0D;
- motionZ *= 0.99699997901916504D;
- } else
- {
- if(minecartType == 2)
- {
- double d27 = MathHelper.sqrt_double(pushX * pushX + pushZ * pushZ);
- if(d27 > 0.01D)
- {
- pushX /= d27;
- pushZ /= d27;
- double d29 = 0.040000000000000001D;
- motionX *= 0.80000001192092896D;
- motionY *= 0.0D;
- motionZ *= 0.80000001192092896D;
- motionX += pushX * d29;
- motionZ += pushZ * d29;
- } else
- {
- motionX *= 0.89999997615814209D;
- motionY *= 0.0D;
- motionZ *= 0.89999997615814209D;
- }
- }
- motionX *= 0.95999997854232788D;
- motionY *= 0.0D;
- motionZ *= 0.95999997854232788D;
- }
+
+ applyDragAndPushForces();
+
Vec3D vec3d1 = func_182_g(posX, posY, posZ);
if(vec3d1 != null && vec3d != null)
{
@@ -480,25 +475,15 @@
motionX = d15 * (double)(k1 - i);
motionZ = d15 * (double)(l1 - k);
}
- if(minecartType == 2)
+
+ updatePushForces();
+
+ if (shouldDoRailFunctions())
{
- double d30 = MathHelper.sqrt_double(pushX * pushX + pushZ * pushZ);
- if(d30 > 0.01D && motionX * motionX + motionZ * motionZ > 0.001D)
- {
- pushX /= d30;
- pushZ /= d30;
- if(pushX * motionX + pushZ * motionZ < 0.0D)
- {
- pushX = 0.0D;
- pushZ = 0.0D;
- } else
- {
- pushX = motionX;
- pushZ = motionZ;
- }
- }
+ ((BlockRail)Block.blocksList[l]).onMinecartPass(worldObj, this, i, j, k);
}
- if(flag)
+
+ if(flag && shouldDoRailFunctions())
{
double d31 = Math.sqrt(motionX * motionX + motionZ * motionZ);
if(d31 > 0.01D)
@@ -530,37 +515,10 @@
}
}
}
- } else
+ }
+ else
{
- if(motionX < -d2)
- {
- motionX = -d2;
- }
- if(motionX > d2)
- {
- motionX = d2;
- }
- if(motionZ < -d2)
- {
- motionZ = -d2;
- }
- if(motionZ > d2)
- {
- motionZ = d2;
- }
- if(onGround)
- {
- motionX *= 0.5D;
- motionY *= 0.5D;
- motionZ *= 0.5D;
- }
- moveEntity(motionX, motionY, motionZ);
- if(!onGround)
- {
- motionX *= 0.94999998807907104D;
- motionY *= 0.94999998807907104D;
- motionZ *= 0.94999998807907104D;
- }
+ moveMinecartOffRail(i, j, k);
}
rotationPitch = 0.0F;
double d6 = prevPosX - posX;
@@ -582,7 +540,20 @@
field_469_aj = !field_469_aj;
}
setRotation(rotationYaw, rotationPitch);
- List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D));
+
+ AxisAlignedBB box = null;
+
+ if (getCollisionHandler() != null)
+ {
+ box = getCollisionHandler().getMinecartCollisionBox(this);
+ }
+ else
+ {
+
+ box = boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D);
+ }
+
+ List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, box);
if(list != null && list.size() > 0)
{
for(int j1 = 0; j1 < list.size(); j1++)
@@ -603,6 +574,178 @@
}
riddenByEntity = null;
}
+ updateFuel();
+ ForgeHooks.onMinecartUpdate(this, i, j, k);
+ }
+
+ /**
+ * Carts should return their drag factor here
+ * @return The drag rate.
+ */
+ protected double getDrag()
+ {
+ if(riddenByEntity != null)
+ {
+ return 0.99699997901916504D;
+ }
+ return 0.95999997854232788D;
+ }
+
+ /**
+ * 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.040000000000000001D;
+ motionX *= 0.80000001192092896D;
+ motionY *= 0.0D;
+ motionZ *= 0.80000001192092896D;
+ motionX += pushX * d29;
+ motionZ += pushZ * d29;
+ } else
+ {
+ motionX *= 0.89999997615814209D;
+ motionY *= 0.0D;
+ motionZ *= 0.89999997615814209D;
+ }
+ }
+ 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 d23 = motionX;
+ double d25 = motionZ;
+ if(riddenByEntity != null)
+ {
+ d23 *= 0.75D;
+ d25 *= 0.75D;
+ }
+ if(d23 < -maxSpeed)
+ {
+ d23 = -maxSpeed;
+ }
+ if(d23 > maxSpeed)
+ {
+ d23 = maxSpeed;
+ }
+ if(d25 < -maxSpeed)
+ {
+ d25 = -maxSpeed;
+ }
+ if(d25 > maxSpeed)
+ {
+ d25 = maxSpeed;
+ }
+ moveEntity(d23, 0.0D, d25);
+ }
+
+ /**
+ * 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--;
@@ -626,12 +769,8 @@
int l = worldObj.getBlockId(i, j, k);
if(BlockRail.isRailBlock(l))
{
- int i1 = worldObj.getBlockMetadata(i, j, k);
+ int i1 = ((BlockRail)Block.blocksList[l]).getBasicRailMetadata(worldObj, this, i, j, k);
d1 = j;
- if(((BlockRail)Block.blocksList[l]).getIsPowered())
- {
- i1 &= 7;
- }
if(i1 >= 2 && i1 <= 5)
{
d1 = j + 1;
@@ -684,13 +823,14 @@
protected void writeEntityToNBT(NBTTagCompound nbttagcompound)
{
nbttagcompound.setInteger("Type", minecartType);
- if(minecartType == 2)
+ if(isPoweredCart())
{
nbttagcompound.setDouble("PushX", pushX);
nbttagcompound.setDouble("PushZ", pushZ);
- nbttagcompound.setShort("Fuel", (short)fuel);
- } else
- if(minecartType == 1)
+ nbttagcompound.setInteger("Fuel", fuel);
+ }
+
+ if(getSizeInventory() > 0)
{
NBTTagList nbttaglist = new NBTTagList();
for(int i = 0; i < cargoItems.length; i++)
@@ -703,7 +843,6 @@
nbttaglist.setTag(nbttagcompound1);
}
}
-
nbttagcompound.setTag("Items", nbttaglist);
}
}
@@ -711,13 +850,14 @@
protected void readEntityFromNBT(NBTTagCompound nbttagcompound)
{
minecartType = nbttagcompound.getInteger("Type");
- if(minecartType == 2)
+ if(isPoweredCart())
{
pushX = nbttagcompound.getDouble("PushX");
pushZ = nbttagcompound.getDouble("PushZ");
- fuel = nbttagcompound.getShort("Fuel");
- } else
- if(minecartType == 1)
+ fuel = nbttagcompound.getInteger("Fuel");
+ }
+
+ if(getSizeInventory() > 0)
{
NBTTagList nbttaglist = nbttagcompound.getTagList("Items");
cargoItems = new ItemStack[getSizeInventory()];
@@ -730,12 +870,19 @@
cargoItems[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
}
}
-
}
}
public void applyEntityCollision(Entity entity)
{
+ ForgeHooks.onMinecartEntityCollision(this, entity);
+
+ if (getCollisionHandler() != null)
+ {
+ getCollisionHandler().onEntityCollision(this, entity);
+ return;
+ }
+
if(worldObj.singleplayerWorld)
{
return;
@@ -744,7 +891,7 @@
{
return;
}
- if((entity instanceof EntityLiving) && !(entity instanceof EntityPlayer) && minecartType == 0 && motionX * motionX + motionZ * motionZ > 0.01D && riddenByEntity == null && entity.ridingEntity == null)
+ if((entity instanceof EntityLiving) && !(entity instanceof EntityPlayer) && canBeRidden() && motionX * motionX + motionZ * motionZ > 0.01D && riddenByEntity == null && entity.ridingEntity == null)
{
entity.mountEntity(this);
}
@@ -782,7 +929,7 @@
}
double d7 = entity.motionX + motionX;
double d8 = entity.motionZ + motionZ;
- if(((EntityMinecart)entity).minecartType == 2 && minecartType != 2)
+ if(((EntityMinecart)entity).isPoweredCart() && !isPoweredCart())
{
motionX *= 0.20000000298023224D;
motionZ *= 0.20000000298023224D;
@@ -790,7 +937,7 @@
entity.motionX *= 0.94999998807907104D;
entity.motionZ *= 0.94999998807907104D;
} else
- if(((EntityMinecart)entity).minecartType != 2 && minecartType == 2)
+ if(!((EntityMinecart)entity).isPoweredCart() && isPoweredCart())
{
entity.motionX *= 0.20000000298023224D;
entity.motionZ *= 0.20000000298023224D;
@@ -818,7 +965,7 @@
public int getSizeInventory()
{
- return 27;
+ return (minecartType == 1 && getClass() == EntityMinecart.class ? 27 : 0);
}
public ItemStack getStackInSlot(int i)
@@ -873,7 +1020,12 @@
public boolean interact(EntityPlayer entityplayer)
{
- if(minecartType == 0)
+ if (!ForgeHooks.onMinecartInteract(this, entityplayer))
+ {
+ return true;
+ }
+
+ if(canBeRidden())
{
if(riddenByEntity != null && (riddenByEntity instanceof EntityPlayer) && riddenByEntity != entityplayer)
{
@@ -884,14 +1036,14 @@
entityplayer.mountEntity(this);
}
} else
- if(minecartType == 1)
+ if(getSizeInventory() > 0)
{
if(!worldObj.singleplayerWorld)
{
entityplayer.displayGUIChest(this);
}
} else
- if(minecartType == 2)
+ if(minecartType == 2 && getClass() == EntityMinecart.class)
{
ItemStack itemstack = entityplayer.inventory.getCurrentItem();
if(itemstack != null && itemstack.itemID == Item.coal.shiftedIndex)
@@ -917,7 +1069,7 @@
return entityplayer.getDistanceSqToEntity(this) <= 64D;
}
- protected boolean isMinecartPowered()
+ public boolean isMinecartPowered()
{
return (dataWatcher.getWatchableObjectByte(16) & 1) != 0;
}
@@ -970,5 +1122,203 @@
{
return 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;
+ }
+
+ /**
+ * 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;
+ }
}

View file

@ -0,0 +1,77 @@
--- ../src_base/minecraft_server/net/minecraft/src/RailLogic.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft_server/net/minecraft/src/RailLogic.java 0000-00-00 00:00:00.000000000 -0000
@@ -10,7 +10,7 @@
// Referenced classes of package net.minecraft.src:
// World, Block, BlockRail, ChunkPosition
-class RailLogic
+public class RailLogic
{
private World worldObj;
@@ -20,6 +20,7 @@
private final boolean isPoweredRail;
private List connectedTracks;
final BlockRail rail; /* synthetic field */
+ private final boolean canMakeSlopes;
public RailLogic(BlockRail blockrail, World world, int i, int j, int k)
{
@@ -31,15 +32,12 @@
trackY = j;
trackZ = k;
int l = world.getBlockId(i, j, k);
- int i1 = world.getBlockMetadata(i, j, k);
- if(BlockRail.isPoweredBlockRail((BlockRail)Block.blocksList[l]))
- {
- isPoweredRail = true;
- i1 &= -9;
- } else
- {
- isPoweredRail = false;
- }
+
+ BlockRail target = (BlockRail)Block.blocksList[l];
+ int i1 = target.getBasicRailMetadata(world, null, i, j, k);
+ isPoweredRail = !target.isFlexibleRail(world, i, j, k);
+ canMakeSlopes = target.canMakeSlopes(world, i, j, k);
+
setConnections(i1);
}
@@ -249,7 +247,7 @@
byte0 = 9;
}
}
- if(byte0 == 0)
+ if(byte0 == 0 && canMakeSlopes)
{
if(BlockRail.isRailBlockAt(worldObj, trackX, trackY + 1, trackZ - 1))
{
@@ -260,7 +258,7 @@
byte0 = 5;
}
}
- if(byte0 == 1)
+ if(byte0 == 1 && canMakeSlopes)
{
if(BlockRail.isRailBlockAt(worldObj, trackX + 1, trackY + 1, trackZ))
{
@@ -381,7 +379,7 @@
}
}
}
- if(byte0 == 0)
+ if(byte0 == 0 && canMakeSlopes)
{
if(BlockRail.isRailBlockAt(worldObj, trackX, trackY + 1, trackZ - 1))
{
@@ -392,7 +390,7 @@
byte0 = 5;
}
}
- if(byte0 == 1)
+ if(byte0 == 1 && canMakeSlopes)
{
if(BlockRail.isRailBlockAt(worldObj, trackX + 1, trackY + 1, trackZ))
{