PC: Auto upload

This commit is contained in:
Rseifert 2012-10-24 18:55:14 -04:00
parent b5ac676610
commit 168cf1f049
48 changed files with 6 additions and 3358 deletions

View file

@ -141,7 +141,7 @@ public class BasicPipesMain{
GameRegistry.addShapelessRecipe(new ItemStack(itemPipes, 1,3), new Object[] { new ItemStack(parts, 1,1),new ItemStack(parts, 1,4),new ItemStack(Item.dyePowder, 1,0)});
//fuel
GameRegistry.addShapelessRecipe(new ItemStack(itemPipes, 1,4), new Object[] { new ItemStack(parts, 1,1),new ItemStack(parts, 1,4),new ItemStack(Item.dyePowder, 1,11)});
GameRegistry.addRecipe(new ItemStack(parts, 1,7), new Object[] { "T@T", 'T',new ItemStack(parts,1,0),'@',Block.lever});//valve
GameRegistry.addRecipe(new ItemStack(parts, 1,7), new Object[] { "T@T", 'T',new ItemStack(parts,1,1),'@',Block.lever});//valve
GameRegistry.addRecipe(new ItemStack(parts, 1,6), new Object[] { " @ ","@ @"," @ ", '@',Item.ingotIron});//tank
GameRegistry.addShapelessRecipe(new ItemStack(itemTank, 1,0), new Object[] { new ItemStack(parts, 1,6),new ItemStack(parts, 1,4),new ItemStack(Item.dyePowder, 1,15)});

View file

@ -1,118 +0,0 @@
package railcraft.common.api.carts;
import net.minecraft.src.EntityItem;
import net.minecraft.src.EntityMinecart;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.ItemStack;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.minecart.MinecartInteractEvent;
/**
* Generally minecarts should extend this class or there will be
* oddities if a user links two carts with different max speeds.
*
* It also contains some generic code that most carts will find useful.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public abstract class CartBase extends EntityMinecart implements IMinecart
{
private float trainSpeed = 1.2f;
public CartBase(World world)
{
super(world);
CartTools.setCartOwner(this, "[Railcraft]");
}
public World getWorld()
{
return worldObj;
}
@Override
public final float getMaxSpeedRail()
{
return Math.min(getCartMaxSpeed(), trainSpeed);
}
@Override
public float getCartMaxSpeed()
{
return 1.2f;
}
@Override
public final void setTrainSpeed(float speed)
{
this.trainSpeed = speed;
}
@Override
public final boolean interact(EntityPlayer player)
{
if(MinecraftForge.EVENT_BUS.post(new MinecartInteractEvent(this, player))) {
return true;
}
if(CartTools.getCartOwner(this).equals("[Railcraft]")) {
CartTools.setCartOwner(this, player);
}
return doInteract(player);
}
public boolean doInteract(EntityPlayer player)
{
return super.interact(player);
}
@Override
public boolean doesCartMatchFilter(ItemStack stack, EntityMinecart cart)
{
if(stack == null || cart == null) {
return false;
}
ItemStack cartItem = cart.getCartItem();
return cartItem != null && stack.isItemEqual(cartItem);
}
@Override
public void setDead()
{
for(int var1 = 0; var1 < this.getSizeInventory(); ++var1) {
ItemStack var2 = this.getStackInSlot(var1);
this.setInventorySlotContents(var1, null);
if(!worldObj.isRemote && var2 != null) {
float var3 = this.rand.nextFloat() * 0.8F + 0.1F;
float var4 = this.rand.nextFloat() * 0.8F + 0.1F;
float var5 = this.rand.nextFloat() * 0.8F + 0.1F;
while(var2.stackSize > 0) {
int var6 = this.rand.nextInt(21) + 10;
if(var6 > var2.stackSize) {
var6 = var2.stackSize;
}
var2.stackSize -= var6;
EntityItem var7 = new EntityItem(this.worldObj, this.posX + (double)var3, this.posY + (double)var4, this.posZ + (double)var5, new ItemStack(var2.itemID, var6, var2.getItemDamage()));
if(var2.hasTagCompound()) {
var7.item.setTagCompound((NBTTagCompound)var2.getTagCompound().copy());
}
float var8 = 0.05F;
var7.motionX = (double)((float)this.rand.nextGaussian() * var8);
var7.motionY = (double)((float)this.rand.nextGaussian() * var8 + 0.2F);
var7.motionZ = (double)((float)this.rand.nextGaussian() * var8);
this.worldObj.spawnEntityInWorld(var7);
}
}
}
super.setDead();
}
}

View file

@ -1,364 +0,0 @@
package railcraft.common.api.carts;
import railcraft.common.api.core.items.IMinecartItem;
import cpw.mods.fml.common.registry.EntityRegistry;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.src.AxisAlignedBB;
import net.minecraft.src.BlockRail;
import net.minecraft.src.EntityMinecart;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.ItemMinecart;
import net.minecraft.src.ItemStack;
import net.minecraft.src.World;
import net.minecraftforge.common.ForgeDirection;
public abstract class CartTools
{
public static ILinkageManager serverLinkageManager;
/**
* Registers a subclass of EntityMinecart with the game engine.
*
* This is just a convenience function, it is not required to call this function
* if you call ModLoader.registerEntityID() and MinecraftForge.registerEntity()
* elsewhere.
*
* @param mod The mod doing the registration
* @param type The class of the cart
* @param tag The String identifier
* @param internalId The mods internal entity id
*/
public static void registerMinecart(Object mod, Class<? extends EntityMinecart> type, String tag, int internalId) {
EntityRegistry.registerModEntity(type, tag, internalId, mod, 80, 3, true);
}
/**
* Returns an instance of ILinkageManager.
*
* Will return null if Railcraft is not installed.
*
* @param world The World, may be required in the future
* @return an instance of ILinkageManager
*/
public static ILinkageManager getLinkageManager(World world) {
return serverLinkageManager;
}
/**
* Sets a carts owner.
*
* The is really only needed by the bukkit ports.
*
* @param owner
*/
public static void setCartOwner(EntityMinecart cart, EntityPlayer owner) {
cart.getEntityData().setString("owner", owner.username);
}
/**
* Sets a carts owner.
*
* The is really only needed by the bukkit ports.
*
* @param owner
*/
public static void setCartOwner(EntityMinecart cart, String owner) {
cart.getEntityData().setString("owner", owner);
}
/**
* Gets a carts owner. (player.username)
*
* The is really only needed by the bukkit ports.
*
* @param owner
*/
public static String getCartOwner(EntityMinecart cart) {
return cart.getEntityData().getString("owner");
}
/**
* Will return true if the cart matches the provided filter item.
*
* @param stack the Filter
* @param cart the Cart
* @return true if the item matches the cart
* @see IMinecart
*/
public static boolean doesCartMatchFilter(ItemStack stack, EntityMinecart cart) {
if(stack == null) {
return false;
}
if(cart instanceof IMinecart) {
return ((IMinecart)cart).doesCartMatchFilter(stack, cart);
}
ItemStack cartItem = cart.getCartItem();
return cartItem != null && isItemEqual(stack, cartItem);
}
private static boolean isItemEqual(ItemStack a, ItemStack b) {
if(a == null || b == null) {
return false;
}
if(a.itemID != b.itemID) {
return false;
}
if(a.stackTagCompound != null && !a.stackTagCompound.equals(b.stackTagCompound)) {
return false;
}
if(a.getHasSubtypes() && (a.getItemDamage() == -1 || b.getItemDamage() == -1)) {
return true;
}
if(a.getHasSubtypes() && a.getItemDamage() != b.getItemDamage()) {
return false;
}
return true;
}
/**
* Spawns a new cart entity using the provided item.
*
* The backing item must implement <code>IMinecartItem</code>
* and/or extend <code>ItemMinecart</code>.
*
* Generally Forge requires all cart items to extend ItemMinecart.
*
* @param owner The player name that should used as the owner
* @param cart An ItemStack containing a cart item, will not be changed by the function
* @param world The World object
* @param i x-Coord
* @param j y-Coord
* @param k z-Coord
* @return the cart placed or null if failed
* @see IMinecartItem, ItemMinecart
*/
public static EntityMinecart placeCart(String owner, ItemStack cart, World world, int i, int j, int k) {
if(cart == null) {
return null;
}
cart = cart.copy();
if(cart.getItem() instanceof IMinecartItem) {
IMinecartItem mi = (IMinecartItem)cart.getItem();
return mi.placeCart(owner, cart, world, i, j, k);
} else if(cart.getItem() instanceof ItemMinecart) {
try {
boolean placed = cart.getItem().onItemUse(cart, null, world, i, j, k, 0, 0, 0, 0);
if(placed) {
List<EntityMinecart> carts = getMinecartsAt(world, i, j, k, 0.3f);
if(carts.size() > 0) {
setCartOwner(carts.get(0), owner);
return carts.get(0);
}
}
} catch (Exception e) {
return null;
}
}
return null;
}
/**
* Offers an item stack to linked carts or drops it if no one wants it.
* @param cart
* @param stack
*/
public static void offerOrDropItem(EntityMinecart cart, ItemStack stack) {
EntityMinecart link_A = getLinkageManager(cart.worldObj).getLinkedCartA(cart);
EntityMinecart link_B = getLinkageManager(cart.worldObj).getLinkedCartB(cart);
if(stack != null && stack.stackSize > 0 && link_A instanceof IItemTransfer) {
stack = ((IItemTransfer)link_A).offerItem(cart, stack);
}
if(stack != null && stack.stackSize > 0 && link_B instanceof IItemTransfer) {
stack = ((IItemTransfer)link_B).offerItem(cart, stack);
}
if(stack != null && stack.stackSize > 0) {
cart.entityDropItem(stack, 1);
}
}
public static boolean isMinecartOnRailAt(World world, int i, int j, int k, float sensitivity) {
return isMinecartOnRailAt(world, i, j, k, sensitivity, null, true);
}
public static boolean isMinecartOnRailAt(World world, int i, int j, int k, float sensitivity, Class<? extends EntityMinecart> type, boolean subclass) {
if(BlockRail.isRailBlockAt(world, i, j, k)) {
return isMinecartAt(world, i, j, k, sensitivity, type, subclass);
}
return false;
}
public static boolean isMinecartOnAnySide(World world, int i, int j, int k, float sensitivity) {
return isMinecartOnAnySide(world, i, j, k, sensitivity, null, true);
}
public static boolean isMinecartOnAnySide(World world, int i, int j, int k, float sensitivity, Class<? extends EntityMinecart> type, boolean subclass) {
List<EntityMinecart> list = new ArrayList<EntityMinecart>();
for(int side = 0; side < 6; side++) {
list.addAll(getMinecartsOnSide(world, i, j, k, sensitivity, ForgeDirection.getOrientation(side)));
}
if(type == null) {
return !list.isEmpty();
} else {
for(EntityMinecart cart : list) {
if((subclass && type.isInstance(cart)) || cart.getClass() == type) {
return true;
}
}
}
return false;
}
public static boolean isMinecartAt(World world, int i, int j, int k, float sensitivity) {
return isMinecartAt(world, i, j, k, sensitivity, null, true);
}
public static boolean isMinecartAt(World world, int i, int j, int k, float sensitivity, Class<? extends EntityMinecart> type, boolean subclass) {
List<EntityMinecart> list = getMinecartsAt(world, i, j, k, sensitivity);
if(type == null) {
return !list.isEmpty();
} else {
for(EntityMinecart cart : list) {
if((subclass && type.isInstance(cart)) || cart.getClass() == type) {
return true;
}
}
}
return false;
}
public static List<EntityMinecart> getMinecartsOnAllSides(World world, int i, int j, int k, float sensitivity) {
List<EntityMinecart> carts = new ArrayList<EntityMinecart>();
for(int side = 0; side < 6; side++) {
carts.addAll(getMinecartsOnSide(world, i, j, k, sensitivity, ForgeDirection.getOrientation(side)));
}
return carts;
}
public static List<EntityMinecart> getMinecartsOnAllSides(World world, int i, int j, int k, float sensitivity, Class<? extends EntityMinecart> type, boolean subclass) {
List<EntityMinecart> list = new ArrayList<EntityMinecart>();
List<EntityMinecart> carts = new ArrayList<EntityMinecart>();
for(int side = 0; side < 6; side++) {
list.addAll(getMinecartsOnSide(world, i, j, k, sensitivity, ForgeDirection.getOrientation(side)));
}
for(EntityMinecart cart : list) {
if((subclass && type.isInstance(cart)) || cart.getClass() == type) {
carts.add(cart);
}
}
return carts;
}
private static int getYOnSide(int y, ForgeDirection side) {
switch (side) {
case UP:
return y + 1;
case DOWN:
return y - 1;
default:
return y;
}
}
private static int getXOnSide(int x, ForgeDirection side) {
switch (side) {
case EAST:
return x + 1;
case WEST:
return x - 1;
default:
return x;
}
}
private static int getZOnSide(int z, ForgeDirection side) {
switch (side) {
case NORTH:
return z - 1;
case SOUTH:
return z + 1;
default:
return z;
}
}
public static List<EntityMinecart> getMinecartsOnSide(World world, int i, int j, int k, float sensitivity, ForgeDirection side) {
return getMinecartsAt(world, getXOnSide(i, side), getYOnSide(j, side), getZOnSide(k, side), sensitivity);
}
public static boolean isMinecartOnSide(World world, int i, int j, int k, float sensitivity, ForgeDirection side) {
return getMinecartOnSide(world, i, j, k, sensitivity, side) != null;
}
public static EntityMinecart getMinecartOnSide(World world, int i, int j, int k, float sensitivity, ForgeDirection side) {
for(EntityMinecart cart : getMinecartsOnSide(world, i, j, k, sensitivity, side)) {
return cart;
}
return null;
}
public static boolean isMinecartOnSide(World world, int i, int j, int k, float sensitivity, ForgeDirection side, Class<? extends EntityMinecart> type, boolean subclass) {
return getMinecartOnSide(world, i, j, k, sensitivity, side, type, subclass) != null;
}
public static EntityMinecart getMinecartOnSide(World world, int i, int j, int k, float sensitivity, ForgeDirection side, Class<? extends EntityMinecart> type, boolean subclass) {
for(EntityMinecart cart : getMinecartsOnSide(world, i, j, k, sensitivity, side)) {
if(type == null || (subclass && type.isInstance(cart)) || cart.getClass() == type) {
return cart;
}
}
return null;
}
/**
*
* @param world
* @param i
* @param j
* @param k
* @param sensitivity Controls the size of the search box, ranges from (-inf, 0.49].
* @return
*/
public static List<EntityMinecart> getMinecartsAt(World world, int i, int j, int k, float sensitivity) {
sensitivity = Math.min(sensitivity, 0.49f);
List entities = world.getEntitiesWithinAABB(net.minecraft.src.EntityMinecart.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool(i + sensitivity, j + sensitivity, k + sensitivity, i + 1 - sensitivity, j + 1 - sensitivity, k + 1 - sensitivity));
List<EntityMinecart> carts = new ArrayList<EntityMinecart>();
for(Object o : entities) {
carts.add((EntityMinecart)o);
}
return carts;
}
public static List<EntityMinecart> getMinecartsIn(World world, int i1, int j1, int k1, int i2, int j2, int k2) {
List entities = world.getEntitiesWithinAABB(net.minecraft.src.EntityMinecart.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool(i1, j1, k1, i2, j2, k2));
List<EntityMinecart> carts = new ArrayList<EntityMinecart>();
for(Object o : entities) {
carts.add((EntityMinecart)o);
}
return carts;
}
/**
* Returns the cart's "speed". It is not capped by the carts max speed,
* it instead returns the cart's "potential" speed.
* Used by collision and linkage logic.
* Do not use this to determine how fast a cart is currently moving.
* @param cart
* @return speed
*/
public static double getCartSpeedUncapped(EntityMinecart cart) {
return Math.sqrt(cart.motionX * cart.motionX + cart.motionZ * cart.motionZ);
}
public static boolean cartVelocityIsLessThan(EntityMinecart cart, float vel) {
return Math.abs(cart.motionX) < vel && Math.abs(cart.motionZ) < vel;
}
}

View file

@ -1,24 +0,0 @@
package railcraft.common.api.carts;
import net.minecraft.src.Block;
/**
* Used by the renderer to renders blocks in carts.
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ICartRenderInterface
{
/**
* Return the block that should be rendered in the cart.
* @return The Block to render
*/
public Block getBlock();
/**
* Return the metadata for the block
* that should be rendered in the cart.
* @return metadata
*/
public int getBlockMetadata();
}

View file

@ -1,82 +0,0 @@
package railcraft.common.api.carts;
/**
* This interface is implemented by the Energy Cart
* and is used by the Energy Loaders to charge/discharge carts.
* It is roughly equivalent to the IItemTransfer interface
* and based on ElectricItem and IElectricItem.
*
* @author CovertJaguar <railcraft.wikispaces.com>
* @see IItemTransfer
*/
public interface IEnergyTransfer
{
/**
* Injects the specified amount of EU into the device.
*
* The function returns the remainder of the EU after
* any EU used is subtracted.
*
* @param source Object initiating the transfer, should be an Entity or Tile Entity
* @param amount amount of energy to transfer in EU
* @param tier tier of the source device, has to be at least as high as the target device
* @param ignoreTransferLimit ignore the transfer limit specified by getTransferLimit()
* @param simulate don't actually change the item, just determine the return value
* @return The amount of EU not used
*/
public int injectEnergy(Object source, int amount, int tier, boolean ignoreTransferLimit, boolean simulate, boolean passAlong);
/**
* Requests a certain amount of EU from the device.
*
* The is function will subtract EU from the device's store of power
* and return a portion up to, but not exceeding, the amount of EU requested.
*
* @param source Object initiating the transfer, should be an Entity or Tile Entity
* @param amount amount of energy to transfer in EU
* @param tier tier of the source device, has to be at least as high as the target device
* @param ignoreTransferLimit ignore the transfer limit specified by getTransferLimit()
* @param simulate don't actually change the item, just determine the return value
* @param passAlong whether neighboring carts should be asked to provide any missing power.
* @return The amount of EU transferred
*/
public int extractEnergy(Object source, int amount, int tier, boolean ignoreTransferLimit, boolean simulate, boolean passAlong);
/**
* Return true if energy can be injected into this device.
*
* @return true if can inject energy
*/
public boolean canInjectEnergy();
/**
* Return true if energy can be extracted from this device.
*
* @return true if can extract energy
*/
public boolean canExtractEnergy();
/**
* The max capacity of the device.
*
* @return max capacity
*/
public int getCapacity();
/**
* Returns the current energy contained in the device.
*
* @return current energy
*/
public int getEnergy();
public int getTier();
/**
* The device's transfer rate in EU/t.
*
* @return the transfer rate
*/
public int getTransferLimit();
}

View file

@ -1,65 +0,0 @@
package railcraft.common.api.carts;
import net.minecraft.src.ItemStack;
import railcraft.common.api.core.items.EnumItemType;
/**
* This interface allows items to be passed around with out needing
* to know anything about the underlying implementation of the inventories.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface IItemTransfer
{
/**
* Offers an ItemStack to the object implementing this interface.
* This function will return null if the item is accepted in full,
* otherwise it will return whatever is rejected.
*
* @param source The Object offering the item
* @param offer The ItemStack being offered
* @return Unused or unwanted portions of offer
*/
public ItemStack offerItem(Object source, ItemStack offer);
/**
* Requests an ItemStack from the object implementing this interface.
* It is up to the object implementing this interface to determine which
* ItemStack to return, or none at all.
*
* @param source The Object submitting the request
* @return An ItemStack to fulfill the request or null if refused.
*/
public ItemStack requestItem(Object source);
/**
* Requests an ItemStack from the object implementing this interface
* that matches the request parameter.
* It is up to the object implementing this interface to
* determine which ItemStack to return, or none at all.
* However, if the return value is not null
* it should fulfill the following condition:<br/>
* InventoryTools.isItemEqual(it.requestItem(this,request), request) == true
*
* @param source The Object submitting the request
* @param request The type of item requested
* @return An ItemStack to fulfill the request or null if refused.
*/
public ItemStack requestItem(Object source, ItemStack request);
/**
* Requests an ItemStack from the object implementing this interface
* that matches the request parameter.
* It is up to the object implementing this interface to
* determine which ItemStack to return, or none at all.
* However, if the return value is not null
* it should fulfill the following condition:<br/>
* EnumItemType.isItemType(it.requestItem(this,request), request) == true
*
* @param source The Object submitting the request
* @param request The type of item requested
* @return An ItemStack to fulfill the request or null if refused.
*/
public ItemStack requestItem(Object source, EnumItemType request);
}

View file

@ -1,77 +0,0 @@
package railcraft.common.api.carts;
import net.minecraft.src.EntityMinecart;
/**
* This interface should be implemented by any minecart that wishes
* to change the default linkage behavior.
* It is NOT required to be able to link a cart,
* it merely gives you more control over the process.
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ILinkableCart
{
/**
* To disable linking altogether, return false here.
* @return True if this cart is linkable.
*/
public boolean isLinkable();
/**
* Check called when attempting to link carts.
* @param cart The cart that we are attempting to link with.
* @return True if we can link with this cart.
*/
public boolean canLinkWithCart(EntityMinecart cart);
/**
* Returns true if this cart has two links
* or false if it can only link with one cart.
* @return True if two links
*/
public boolean hasTwoLinks();
/**
* Gets the distance at which this cart can be linked.
* This is called on both carts and added together to determine
* how close two carts need to be for a successful link.
* Default = LinkageManager.LINKAGE_DISTANCE
* @param cart The cart that you are attempting to link with.
* @return The linkage distance
*/
public float getLinkageDistance(EntityMinecart cart);
/**
* Gets the optimal distance between linked carts.
* This is called on both carts and added together to determine
* the optimal rest distance between linked carts.
* The LinkageManager will attempt to maintain this distance
* between linked carts at all times.
* Default = LinkageManager.OPTIMAL_DISTANCE
* @param cart The cart that you are linked with.
* @return The optimal rest distance
*/
public float getOptimalDistance(EntityMinecart cart);
/**
* Return false if linked carts have no effect on the velocity of this cart.
* Use carefully, if you link two carts that can't be adjusted,
* it will behave as if they are not linked.
* @param cart The cart doing the adjusting.
* @return Whether the cart can have its velocity adjusted.
*/
public boolean canBeAdjusted(EntityMinecart cart);
/**
* Called upon successful link creation.
* @param cart The cart we linked with.
*/
public void onLinkCreated(EntityMinecart cart);
/**
* Called when a link is broken (usually).
* @param cart The cart we were linked with.
*/
public void onLinkBroken(EntityMinecart cart);
}

View file

@ -1,102 +0,0 @@
package railcraft.common.api.carts;
import net.minecraft.src.EntityMinecart;
/**
* The LinkageManager contains all the functions needed to link and interact
* with linked carts.
*
* To obtain an instance of this interface, call CartTools.getLinkageManager().
*
* Each cart can up to two links. They are called Link A and Link B.
* Some carts will have only Link A, for example the Tunnel Bore.
*
* @author CovertJaguar <railcraft.wikispaces.com>
* @see CartTools, ILinkableCart
*/
public interface ILinkageManager
{
/**
* The default max distance at which carts can be linked, divided by 2.
*/
public static final float LINKAGE_DISTANCE = 1.25f;
/**
* The default distance at which linked carts are maintained, divided by 2.
*/
public static final float OPTIMAL_DISTANCE = 0.78f;
/**
* Creates a link between two carts,
* but only if there is nothing preventing such a link.
*
* @param cart1
* @param cart2
* @return True if the link succeeded.
*/
public boolean createLink(EntityMinecart cart1, EntityMinecart cart2);
/**
* Returns the cart linked to Link A or null if nothing is currently
* occupying Link A.
*
* @param cart The cart for which to get the link
* @return The linked cart or null
*/
public EntityMinecart getLinkedCartA(EntityMinecart cart);
/**
* Returns the cart linked to Link B or null if nothing is currently
* occupying Link B.
*
* @param cart The cart for which to get the link
* @return The linked cart or null
*/
public EntityMinecart getLinkedCartB(EntityMinecart cart);
/**
* Returns true if the two carts are linked to each other.
*
* @param cart1
* @param cart2
* @return True if linked
*/
public boolean areLinked(EntityMinecart cart1, EntityMinecart cart2);
/**
* Breaks a link between two carts, if any link exists.
*
* @param cart1
* @param cart2
*/
public void breakLink(EntityMinecart cart1, EntityMinecart cart2);
/**
* Breaks all links the cart has.
*
* @param cart
*/
public void breakLinks(EntityMinecart cart);
/**
* Break only link A.
*
* @param cart
*/
public void breakLinkA(EntityMinecart cart);
/**
* Break only link B.
*
* @param cart
*/
public void breakLinkB(EntityMinecart cart);
/**
* Counts how many carts are in the train.
*
* @param cart Any cart in the train
* @return The number of carts in the train
*/
public int countCartsInTrain(EntityMinecart cart);
}

View file

@ -1,53 +0,0 @@
package railcraft.common.api.carts;
import buildcraft.api.liquids.LiquidStack;
/**
* This interface allows carts to transfer liquid between each other
* as well as adding a couple other functions related to liquids.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ILiquidTransfer
{
/**
* Offers liquid to this object.
*
* Is not used by the Liquid Loader to load carts,
* the traditional ILiquidContainer is used for that.
*
* @param source The Object offering the liquid, used to prevent request loops in trains
* @param quantity The quantity offered
* @param id The liquid id offered
* @return the liquid used
*/
public int offerLiquid(Object source, LiquidStack offer);
/**
* Requests liquid from this object.
*
* Is not used by the Liquid Unloader to drain carts,
* the traditional ILiquidContainer is used for that.
*
* @param source The Object requesting the liquid, used to prevent request loops in trains
* @param quantity The quantity requested
* @param id The liquid type requested
* @return the liquid provided
*/
public int requestLiquid(Object source, LiquidStack request);
/**
* Set by the Liquid Loader while filling,
* primarily used for rendering a visible
* change while being filled.
* @param filling
*/
public void setFilling(boolean filling);
/**
*
* @return true if being filled
*/
public boolean isFilling();
}

View file

@ -1,52 +0,0 @@
package railcraft.common.api.carts;
import net.minecraft.src.EntityMinecart;
import net.minecraft.src.ItemStack;
/**
* Some helper functions to make interacting with carts simpler.
*
* This interface is implemented by CartBase.
*
* @author CovertJaguar <railcraft.wikispaces.com>
* @see CartBase
*/
public interface IMinecart
{
/**
* Returns true if the Minecart matches the item provided.
* Generally just stack.isItemEqual(cart.getCartItem()),
* but some carts may need more control (the Tank Cart for example).
*
* @param stack the Filter
* @param cart the Cart
* @return true if the item matches the cart
*/
public boolean doesCartMatchFilter(ItemStack stack, EntityMinecart cart);
/**
* Unlike EntityMinecart.getMaxSpeedRail(),
* this function is independent of the actual max speed of the cart.
*
* It should represent the max possible speed at this point in time
* before any modifiers due to linked carts, etc are applied.
*
* This is really only used for Train speed calculations.
* Which ever cart in the train returns the lowest value here will be the max speed of the entire train.
*
* @return
*/
public float getCartMaxSpeed();
/**
* Sets the max speed of a train.
*
* This should be used to limit the return value for EntityMinecart.getMaxSpeedRail().
*
* @param speed
* @see CartBase
*/
public void setTrainSpeed(float speed);
}

View file

@ -1,252 +0,0 @@
package railcraft.common.api.carts;
import net.minecraft.src.EntityMinecart;
import net.minecraft.src.IInventory;
import net.minecraft.src.ItemStack;
import net.minecraft.src.World;
import railcraft.common.api.core.items.EnumItemType;
/**
* Abstract minecart class that implements the IItemTransfer
* interface for convenience and as example for others who wish
* to create carts that implements IItemTransfer.
* This particular implementation assumes a simple inventory
* and will attempt to pass along offers and requests to linked carts
* if it cannot fulfill them itself.
* <br/>
* <br/>
* Classes that extend this class:<br/>
* EntityCartChest<br/>
* EntityCartAnchor<br/>
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public abstract class TransferCartBase extends CartBase implements IItemTransfer
{
/**
* If passThrough == true, this cart will only pass requests along, it wont attempt to fulfill them.
*/
protected boolean passThrough = false;
public TransferCartBase(World world)
{
super(world);
}
@Override
public ItemStack offerItem(Object source, ItemStack offer)
{
if(!passThrough && getSizeInventory() > 0) {
offer = moveItemStack(offer, this);
if(offer == null) {
return null;
}
}
ILinkageManager lm = CartTools.getLinkageManager(worldObj);
EntityMinecart linkedCart = lm.getLinkedCartA(this);
if(linkedCart != source && linkedCart instanceof IItemTransfer) {
offer = ((IItemTransfer)linkedCart).offerItem(this, offer);
}
if(offer == null) {
return null;
}
linkedCart = lm.getLinkedCartB(this);
if(linkedCart != source && linkedCart instanceof IItemTransfer) {
offer = ((IItemTransfer)linkedCart).offerItem(this, offer);
}
return offer;
}
@Override
public ItemStack requestItem(Object source)
{
ItemStack result = null;
if(!passThrough && getSizeInventory() > 0) {
result = removeOneItem(this);
if(result != null) {
return result;
}
}
ILinkageManager lm = CartTools.getLinkageManager(worldObj);
EntityMinecart linkedCart = lm.getLinkedCartA(this);
if(linkedCart != source && linkedCart instanceof IItemTransfer) {
result = ((IItemTransfer)linkedCart).requestItem(this);
}
if(result != null) {
return result;
}
linkedCart = lm.getLinkedCartB(this);
if(linkedCart != source && linkedCart instanceof IItemTransfer) {
result = ((IItemTransfer)linkedCart).requestItem(this);
}
return result;
}
@Override
public ItemStack requestItem(Object source, ItemStack request)
{
ItemStack result = null;
if(!passThrough && getSizeInventory() > 0) {
result = removeOneItem(this, request);
if(result != null) {
return result;
}
}
ILinkageManager lm = CartTools.getLinkageManager(worldObj);
EntityMinecart linkedCart = lm.getLinkedCartA(this);
if(linkedCart != source && linkedCart instanceof IItemTransfer) {
result = ((IItemTransfer)linkedCart).requestItem(this, request);
}
if(result != null) {
return result;
}
linkedCart = lm.getLinkedCartB(this);
if(linkedCart != source && linkedCart instanceof IItemTransfer) {
result = ((IItemTransfer)linkedCart).requestItem(this, request);
}
return result;
}
@Override
public ItemStack requestItem(Object source, EnumItemType request)
{
ItemStack result = null;
if(!passThrough && getSizeInventory() > 0) {
result = removeOneItem(this, request);
if(result != null) {
return result;
}
}
ILinkageManager lm = CartTools.getLinkageManager(worldObj);
EntityMinecart linkedCart = lm.getLinkedCartA(this);
if(linkedCart != source && linkedCart instanceof IItemTransfer) {
result = ((IItemTransfer)linkedCart).requestItem(this, request);
}
if(result != null) {
return result;
}
linkedCart = lm.getLinkedCartB(this);
if(linkedCart != source && linkedCart instanceof IItemTransfer) {
result = ((IItemTransfer)linkedCart).requestItem(this, request);
}
return result;
}
/**
* Removes and returns a single item from the inventory.
* @param inv The inventory
* @return An ItemStack
*/
protected final ItemStack removeOneItem(IInventory inv)
{
for(int i = 0; i < inv.getSizeInventory(); i++) {
ItemStack slot = inv.getStackInSlot(i);
if(slot != null) {
return inv.decrStackSize(i, 1);
}
}
return null;
}
/**
* Removes and returns a single item from the inventory that matches the filter.
* @param inv The inventory
* @param filter ItemStack to match against
* @return An ItemStack
*/
protected final ItemStack removeOneItem(IInventory inv, ItemStack filter)
{
for(int i = 0; i < inv.getSizeInventory(); i++) {
ItemStack slot = inv.getStackInSlot(i);
if(slot != null && filter != null && slot.isItemEqual(filter)) {
return inv.decrStackSize(i, 1);
}
}
return null;
}
/**
* Removes and returns a single item from the inventory that matches the filter.
* @param inv The inventory
* @param filter EnumItemType to match against
* @return An ItemStack
*/
protected final ItemStack removeOneItem(IInventory inv, EnumItemType filter)
{
for(int i = 0; i < inv.getSizeInventory(); i++) {
ItemStack slot = inv.getStackInSlot(i);
if(slot != null && filter.isItemType(slot)) {
return inv.decrStackSize(i, 1);
}
}
return null;
}
protected final ItemStack moveItemStack(ItemStack stack, IInventory dest)
{
if(stack == null) {
return null;
}
stack = stack.copy();
if(dest == null) {
return stack;
}
boolean movedItem = false;
do {
movedItem = false;
ItemStack destStack = null;
for(int ii = 0; ii < dest.getSizeInventory(); ii++) {
destStack = dest.getStackInSlot(ii);
if(destStack != null && destStack.isItemEqual(stack)) {
int maxStack = Math.min(destStack.getMaxStackSize(), dest.getInventoryStackLimit());
int room = maxStack - destStack.stackSize;
if(room > 0) {
int move = Math.min(room, stack.stackSize);
destStack.stackSize += move;
stack.stackSize -= move;
if(stack.stackSize <= 0) {
return null;
}
movedItem = true;
}
}
}
if(!movedItem) {
for(int ii = 0; ii < dest.getSizeInventory(); ii++) {
destStack = dest.getStackInSlot(ii);
if(destStack == null) {
if(stack.stackSize > dest.getInventoryStackLimit()) {
dest.setInventorySlotContents(ii, stack.splitStack(dest.getInventoryStackLimit()));
} else {
dest.setInventorySlotContents(ii, stack);
return null;
}
movedItem = true;
}
}
}
} while(movedItem);
return stack;
}
}

View file

@ -1,37 +0,0 @@
package railcraft.common.api.carts.bore;
/**
* This interface it used to define an item that can
* be used as a bore head for the Tunnel Bore.
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface IBoreHead
{
/**
* Return the texture file used for this bore head.
* @return The texture file path
*/
public String getBoreTexture();
/**
* Return the harvest level of this bore head.
*
* This value is compared against the tool classes
* "pickaxe", "axe", and "shovel" to determine if the
* block is harvestable by the bore head.
*
* @return The harvest level
*/
public int getHarvestLevel();
/**
* Return the dig speed modifier of this bore head.
*
* This value controls how much faster or slow this bore head
* mines each layer compared to the default time.
*
* @return The dig speed modifier
*/
public float getDigModifier();
}

View file

@ -1,36 +0,0 @@
package railcraft.common.api.carts.bore;
import net.minecraft.src.EntityMinecart;
import net.minecraft.src.ItemStack;
import net.minecraft.src.World;
/**
* This interface can be implemented by a block class to control whether a block can be
* mined by the bore without having to force the user to edit the configuration file.
*
* If the block is found to implement this class, any setting in the configuration
* is ignored for that block.
*
* Generally, the reason blocks are not minable by default is to prevent you
* from intentionally or accidentally boring through your base.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface IMineable
{
/**
* Called when the Bore attempts to mine the block. If it returns false,
* the Bore will halt operation.
*
* @param world The World
* @param i x-Coord
* @param j y-Coord
* @param k z-Coord
* @param bore The Bore entity
* @param head The BoreHead, item implements IBoreHead.
* @return true if mineable
* @see IBoreHead
*/
public boolean canMineBlock(World world, int i, int j, int k, EntityMinecart bore, ItemStack head);
}

View file

@ -1,16 +0,0 @@
package railcraft.common.api.core;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.src.World;
public interface INetworkedObject
{
public World getWorld();
public void writePacketData(DataOutputStream data) throws IOException;
public void readPacketData(DataInputStream data) throws IOException;
}

View file

@ -1,27 +0,0 @@
package railcraft.common.api.core;
import net.minecraft.src.World;
import net.minecraftforge.common.ForgeDirection;
/**
* If you want your block to connect (or not connect) to posts,
* implement this interface.
*
* The result takes priority over any other rules.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface IPostConnection
{
/**
* Return true if the block at this location should connect to a post.
* @param world The World
* @param i x-Coord
* @param j y-Coord
* @param k z-Coord
* @param side Side to connect to
* @return true if connect
*/
public boolean connectsAt(World world, int i, int j, int k, ForgeDirection side);
}

View file

@ -1,78 +0,0 @@
package railcraft.common.api.core;
/**
* This immutable class represents a point in the Minecraft world,
* while taking into account the possibility of coordinates in different dimensions.
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public class WorldCoordinate
{
/**
* The dimension
*/
public final int dimension;
/**
* x-Coord
*/
public final int x;
/**
* y-Coord
*/
public final int y;
/**
* z-Coord
*/
public final int z;
/**
* Creates a new WorldCoordinate
* @param dimension
* @param i
* @param j
* @param k
*/
public WorldCoordinate(int dimension, int i, int j, int k)
{
this.dimension = dimension;
x = i;
y = j;
z = k;
}
@Override
public boolean equals(Object obj)
{
if(obj == null) {
return false;
}
if(getClass() != obj.getClass()) {
return false;
}
final WorldCoordinate other = (WorldCoordinate)obj;
if(this.dimension != other.dimension) {
return false;
}
if(this.x != other.x) {
return false;
}
if(this.y != other.y) {
return false;
}
if(this.z != other.z) {
return false;
}
return true;
}
@Override
public int hashCode()
{
int hash = 3;
hash = 13 * hash + this.dimension;
hash = 13 * hash + this.x;
hash = 13 * hash + this.y;
hash = 13 * hash + this.z;
return hash;
}
}

View file

@ -1,93 +0,0 @@
package railcraft.common.api.core.items;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.minecraft.src.Block;
import net.minecraft.src.ItemBlock;
import net.minecraft.src.ItemStack;
/**
* Register an item here to designate it as a possible
* ballast that can be used in the Bore.
*
* It is expected that ballast is affected by gravity.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public abstract class BallastRegistry
{
private static Set<ItemWrapper> ballastRegistry = new HashSet<ItemWrapper>();
private static class ItemWrapper
{
public int itemID;
public int itemDamage;
public ItemStack stack;
public ItemWrapper(ItemStack stack)
{
itemID = stack.itemID;
itemDamage = stack.getItemDamage();
this.stack = stack;
}
@Override
public boolean equals(Object obj)
{
if(obj == null) {
return false;
}
if(getClass() != obj.getClass()) {
return false;
}
final ItemWrapper other = (ItemWrapper)obj;
if(this.itemID != other.itemID) {
return false;
}
if(this.itemDamage != other.itemDamage) {
return false;
}
return true;
}
@Override
public int hashCode()
{
int hash = 3;
hash = 47 * hash + this.itemID;
hash = 47 * hash + this.itemDamage;
return hash;
}
}
static {
registerBallast(new ItemStack(Block.gravel));
}
public static void registerBallast(ItemStack ballast)
{
if(ballast.getItem() instanceof ItemBlock) {
ballastRegistry.add(new ItemWrapper(ballast));
} else {
throw new RuntimeException("Attempted to register an invalid ballast, must be an ItemBlock item.");
}
}
public static boolean isItemBallast(ItemStack ballast)
{
return ballastRegistry.contains(new ItemWrapper(ballast));
}
public static List<ItemStack> getRegisteredBallasts()
{
List<ItemStack> list = new ArrayList<ItemStack>();
for(ItemWrapper item : ballastRegistry) {
list.add(item.stack);
}
return list;
}
}

View file

@ -1,47 +0,0 @@
package railcraft.common.api.core.items;
import net.minecraft.src.BlockRail;
import net.minecraft.src.Item;
import net.minecraft.src.ItemBlock;
import net.minecraft.src.ItemFood;
import net.minecraft.src.ItemStack;
import net.minecraft.src.TileEntityFurnace;
import net.minecraftforge.common.MinecartRegistry;
/**
* This interface is used with several of the functions in IItemTransfer
* to provide a convenient means of dealing with entire classes of items without
* having to specify each item individually.
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public enum EnumItemType
{
FUEL, RAIL, MINECART, BALLAST, FOOD;
public static boolean isItemType(ItemStack stack, EnumItemType filter)
{
return filter.isItemType(stack);
}
public boolean isItemType(ItemStack stack)
{
if(stack == null) {
return false;
}
switch (this) {
case FUEL:
return TileEntityFurnace.getItemBurnTime(stack) > 0;
case RAIL:
return stack.getItem() instanceof ITrackItem || (stack.getItem() instanceof ItemBlock && BlockRail.isRailBlock(stack.itemID));
case MINECART:
return MinecartRegistry.getCartClassForItem(stack) != null || stack.getItem() instanceof IMinecartItem;
case BALLAST:
return BallastRegistry.isItemBallast(stack);
case FOOD:
return stack.getItem() instanceof ItemFood || stack.itemID == Item.wheat.shiftedIndex;
default:
return false;
}
}
}

View file

@ -1,39 +0,0 @@
package railcraft.common.api.core.items;
import net.minecraft.src.EntityMinecart;
import net.minecraft.src.ItemStack;
import net.minecraft.src.World;
/**
* This interface should be implemented by any cart item,
* but it is generally optional.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface IMinecartItem
{
/**
* Controls whether this cart item can be placed by the Cart and Train Dispensers.
*
* Generally, you can ignore the placeCart() function if this returns false.
*
* @return true if it can be placed, false otherwise
*/
public boolean canBePlacedByNonPlayer(ItemStack cart);
/**
* Places a cart at the specified location.
*
* Implementing this function is optional.
*
* @param owner the name of the player placing the cart or "[MyMod]" with the brackets
* @param cart An ItemStack that contains the cart
* @param world The World
* @param i x-Coord
* @param j y-Coord
* @param k z-Coord
* @return the cart placed or null if failed
*/
public EntityMinecart placeCart(String owner, ItemStack cart, World world, int i, int j, int k);
}

View file

@ -1,46 +0,0 @@
package railcraft.common.api.core.items;
import net.minecraft.src.ItemStack;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
/**
* Should be implemented by any rail item class that wishes to have
* it's rails placed by for example the Tunnel Bore or Track Relayer.
*
* If you defined your rails with a TrackSpec, you don't need to worry about this.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ITrackItem
{
/**
* Attempts to place a track.
*
* @param world The World object
* @param i x-Coord
* @param j y-Coord
* @param k z-Coord
* @return true if successful
*/
public boolean placeTrack(ItemStack stack, World world, int i, int j, int k);
/**
* Return the block id of a placed track.
*
* @return the blockId
*/
public int getPlacedBlockId();
/**
* Return true if the given tile entity corresponds to this Track item.
*
* If the track has no tile entity, return true on null.
*
* @param stack
* @param tile
* @return
*/
public boolean isPlacedTileEntity(ItemStack stack, TileEntity tile);
}

View file

@ -1,93 +0,0 @@
package railcraft.common.api.core.items;
import java.util.Map;
import java.util.TreeMap;
import net.minecraft.src.ItemStack;
/**
* This class contains a registry of all currently active Railcraft items.
* Which items are registered depends on the user's settings in "railcraft.cfg",
* so the available items may vary from one installation to the next.
*
* Initialization of the registry will occur during the BaseMod.load()
* function. It is strongly recommended you wait until the BaseMod.modsLoaded()
* function to reference the registry.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public final class ItemRegistry
{
private static final Map<String, ItemStack> registry = new TreeMap<String, ItemStack>();
private ItemRegistry()
{
}
/**
* This function will return an ItemStack containing the item that
* corresponds to the provided tag.
*
* Generally item tags will correspond to the tags used in "railcraft.cfg",
* but there will be some exceptions.
*
* This function can and will return null for just about every item
* if the item is disabled via the configuration files.
* You must test the return value for safety.
*
* For list of available tags see the printItemTags() function.
*
* @param tag The item tag
* @param qty The stackSize of the returned item
* @return The ItemStack or null if no item exists for that tag
*/
public static ItemStack getItem(String tag, int qty)
{
ItemStack stack = registry.get(tag);
if(stack != null) {
stack = stack.copy();
stack.stackSize = qty;
}
return stack;
}
/**
* Registers a new item with the Registry.
*
* This should generally only be called by Railcraft itself
* while the mod is initializing during the mod_Railcraft.load() call.
*
* @param tag The tag name
* @param item The item
*/
public static void registerItem(String tag, ItemStack item)
{
registry.put(tag, item);
}
/**
* This function will print a list of all currently registered items
* to the console.
*
* Use this for development purposes.
*/
public static void printItemTags()
{
System.out.println();
System.out.println("Printing all registered Railcraft items:");
for(String tag : registry.keySet()) {
System.out.println(tag);
}
System.out.println();
}
/**
* Returns the entire mapping of items.
*
* @return
*/
public static Map<String, ItemStack> getItems()
{
return registry;
}
}

View file

@ -1,25 +0,0 @@
package railcraft.common.api.crafting;
import java.util.List;
import net.minecraft.src.ItemStack;
/**
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface IBlastFurnaceCraftingManager
{
void addRecipe(int inputId, int inputDamage, int cookTime, ItemStack output);
void addRecipe(int inputId, int cookTime, ItemStack output);
List<ItemStack> getFuels();
IBlastFurnaceRecipe getRecipe(int inputId, int inputDamage);
IBlastFurnaceRecipe getRecipe(ItemStack stack);
List<IBlastFurnaceRecipe> getRecipes();
}

View file

@ -1,21 +0,0 @@
package railcraft.common.api.crafting;
import net.minecraft.src.ItemStack;
/**
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface IBlastFurnaceRecipe
{
public int getCookTime();
public ItemStack getInput();
public ItemStack getOutput();
int getOutputStackSize();
boolean isRoomForOutput(ItemStack out);
}

View file

@ -1,26 +0,0 @@
package railcraft.common.api.crafting;
import buildcraft.api.liquids.LiquidStack;
import java.util.List;
import net.minecraft.src.ItemStack;
/**
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ICokeOvenCraftingManager
{
void addRecipe(ItemStack input, ItemStack output, LiquidStack liquidOutput, int cookTime);
void addRecipe(int inputId, int inputDamage, ItemStack output, LiquidStack liquidOutput, int cookTime);
void addRecipe(int inputId, ItemStack output, LiquidStack liquidOutput, int cookTime);
ICokeOvenRecipe getRecipe(ItemStack stack);
ICokeOvenRecipe getRecipe(int inputId, int inputDamage);
List<ICokeOvenRecipe> getRecipes();
}

View file

@ -1,20 +0,0 @@
package railcraft.common.api.crafting;
import buildcraft.api.liquids.LiquidStack;
import net.minecraft.src.ItemStack;
/**
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ICokeOvenRecipe
{
public int getCookTime();
public ItemStack getInput();
public LiquidStack getLiquidOutput();
public ItemStack getOutput();
}

View file

@ -1,35 +0,0 @@
package railcraft.common.api.crafting;
import java.util.HashMap;
import java.util.List;
import net.minecraft.src.ItemStack;
/**
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface IRockCrusherCraftingManager
{
/**
*
* @param inputId
* @param inputDamage metadata or -1 for wildcard
* @param output A map of outputs and chances. If more than 9 types of items, there will be unexpected behavior.
*/
void addRecipe(int inputId, int inputDamage, HashMap<ItemStack, Float> output);
/**
*
* @param input
* @param output A map of outputs and chances. If more than 9 types of items, there will be unexpected behavior.
*/
void addRecipe(ItemStack input, HashMap<ItemStack, Float> output);
IRockCrusherRecipe getRecipe(ItemStack input);
IRockCrusherRecipe getRecipe(int inputId, int inputDamage);
List<IRockCrusherRecipe> getRecipes();
}

View file

@ -1,37 +0,0 @@
package railcraft.common.api.crafting;
import java.util.List;
import java.util.Map;
import net.minecraft.src.ItemStack;
/**
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface IRockCrusherRecipe
{
public ItemStack getInput();
/**
* Returns a map containing each output entry and its chance of being included.
*
* @return
*/
public Map<ItemStack, Float> getOutputs();
/**
* Returns a list of all possible outputs.
* This is basically a condensed version of getOutputs().keySet().
*
* @return
*/
public List<ItemStack> getPossibleOuput();
/**
* Returns a list of outputs after it has passed through the randomizer.
*
* @return
*/
public List<ItemStack> getRandomizedOuput();
}

View file

@ -1,23 +0,0 @@
package railcraft.common.api.crafting;
import java.util.List;
import net.minecraft.src.IRecipe;
import net.minecraft.src.InventoryCrafting;
import net.minecraft.src.ItemStack;
/**
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface IRollingMachineCraftingManager
{
void addRecipe(ItemStack output, Object[] components);
void addShapelessRecipe(ItemStack output, Object[] compenents);
ItemStack findMatchingRecipe(InventoryCrafting inventorycrafting);
List<IRecipe> getRecipeList();
}

View file

@ -1,16 +0,0 @@
package railcraft.common.api.crafting;
/**
* These variables are defined during the pre-init phase.
* Do not attempt to access them during pre-init.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public abstract class RailcraftCraftingManager
{
public static ICokeOvenCraftingManager cokeOven;
public static IBlastFurnaceCraftingManager blastFurnace;
public static IRockCrusherCraftingManager rockCrusher;
public static IRollingMachineCraftingManager rollingMachine;
}

View file

@ -1,155 +0,0 @@
package railcraft.common.api.signals;
/**
* Represents a Signal state.
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public enum EnumSignalAspect
{
/**
* The All Clear.
*/
GREEN(0),
/**
* Typically means pairing in progress.
*/
BLINK_YELLOW(1),
/**
* Caution, cart heading away.
*/
YELLOW(1),
/**
* Maintenance warning, the signal is malfunctioning.
*/
BLINK_RED(2),
/**
* Stop!
*/
RED(2),
/**
* Can't happen, really it can't (or shouldn't).
* Only used when rendering blink states (for the texture offset).
*/
OFF(3);
private final byte id;
private final int textureOffset;
private static byte nextId = 0;
private static boolean blinkState;
private EnumSignalAspect(int textureOffset)
{
this.textureOffset = textureOffset;
id = getNextId();
}
/**
* Returns the aspect id, used mainly for saving and network communication.
* @return id
*/
public byte getId()
{
return id;
}
/**
* Returns the texture offset for this specific aspect.
* @return offset
*/
public int getTextureOffset()
{
return textureOffset;
}
/**
* Returns true if the aspect is one of the blink states.
* @return true if blinks
*/
public boolean isBlinkAspect()
{
if(this == BLINK_YELLOW || this == BLINK_RED) {
return true;
}
return false;
}
/**
* Return true if the light is currently off.
* @return true if the light is currently off.
*/
public static boolean isBlinkOn()
{
return blinkState;
}
/**
* Don't call this, its used to change blink states by Railcraft.
*/
public static void invertBlinkState()
{
blinkState = !blinkState;
}
/**
* Takes an id and returns an Aspect.
* @param id
* @return
*/
public static EnumSignalAspect fromId(int id)
{
for(EnumSignalAspect a : EnumSignalAspect.values()) {
if(a.getId() == id) {
return a;
}
}
return RED;
}
/**
* Tests two Aspects and determines which is more restrictive.
* The concept of "most restrictive" refers to which aspect enforces the
* most limitations of movement to a train.
*
* In Railcraft the primary use is in Signal Box logic.
*
* @param first
* @param second
* @return The most restrictive Aspect
*/
public static EnumSignalAspect mostRestrictive(EnumSignalAspect first, EnumSignalAspect second)
{
if(first == null && second != null) {
return second;
} else if(first != null && second == null) {
return first;
} else if(first == null && second == null) {
return RED;
}
if(first == OFF || second == OFF) {
return RED;
}
if(first.getId() > second.getId()) {
return first;
}
return second;
}
private static byte getNextId()
{
byte i = nextId;
nextId++;
return i;
}
@Override
public String toString()
{
String[] sa = name().split("_");
String out = "";
for(String s : sa) {
out = out + s.substring(0, 1) + s.substring(1).toLowerCase() + " ";
}
out = out.trim();
return out;
}
}

View file

@ -1,47 +0,0 @@
package railcraft.common.api.signals;
/**
* This is not documented and needs some reworking to simplify usage.
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface IBlockSignal
{
public void startSignalBlockPairing();
public void endSignalBlockPairing();
public boolean locateRail();
public boolean attemptToPair(IBlockSignal other);
public void clearSignalBlockPairing(String reason, Object... args);
public boolean isSignalBlockBeingPaired();
public boolean isSignalBlockPaired();
public IBlockSignal getSignalBlockPair();
public int getSignalBlockPairX();
public int getSignalBlockPairY();
public int getSignalBlockPairZ();
public int getRailX();
public int getRailY();
public int getRailZ();
public int getX();
public int getY();
public int getZ();
public int getDimension();
public String getDescription();
}

View file

@ -1,45 +0,0 @@
package railcraft.common.api.signals;
import net.minecraft.src.World;
/**
* This is not documented and needs some reworking to simplify usage.
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ISignalController
{
public EnumSignalAspect getSignalAspect();
public boolean attemptToPairWithReceiver(ISignalReceiver receiver);
public void startReceiverPairing();
public void endReceiverPairing();
public void clearPairedReceiver();
public boolean isPairedWithReceiver();
public ISignalReceiver getReceiver();
public int getReceiverX();
public int getReceiverY();
public int getReceiverZ();
public int getX();
public int getY();
public int getZ();
public int getDimension();
public World getWorld();
public String getDescription();
public boolean isInvalid();
}

View file

@ -1,43 +0,0 @@
package railcraft.common.api.signals;
import net.minecraft.src.World;
/**
* This is not documented and needs some reworking to simplify usage.
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ISignalReceiver
{
public boolean doesActionOnAspect(EnumSignalAspect aspect);
public void doActionOnAspect(EnumSignalAspect aspect, boolean trigger);
public boolean attemptToPairWithController(ISignalController controller);
public void clearPairedController();
public boolean isPairedWithController();
public ISignalController getController();
public int getControllerX();
public int getControllerY();
public int getControllerZ();
public int getX();
public int getY();
public int getZ();
public int getDimension();
public World getWorld();
public boolean isInvalid();
public String getDescription();
}

View file

@ -1,159 +0,0 @@
package railcraft.common.api.signals;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.ItemStack;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
import railcraft.common.api.tracks.RailTools;
import railcraft.common.api.core.WorldCoordinate;
/**
* This is not documented and needs some reworking to simplify usage.
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public abstract class SignalTools
{
private static Map<PairingKey, WorldCoordinate> signalBlockPairingMap = new HashMap<PairingKey, WorldCoordinate>();
private static Map<PairingKey, WorldCoordinate> controllerReceiverPairingMap = new HashMap<PairingKey, WorldCoordinate>();
public static boolean isSignalBlockSectionValid(World world, IBlockSignal first, IBlockSignal second) {
return RailTools.areDistantRailsConnectedAlongAxis(world, first.getRailX(), first.getRailY(), first.getRailZ(), second.getRailX(), second.getRailY(), second.getRailZ());
}
public static boolean isControllerInRangeOfReceiver(ISignalController c, ISignalReceiver r, int range) {
int distX = c.getX() - r.getX();
int distY = c.getY() - r.getY();
int distZ = c.getZ() - r.getZ();
int distance = (int)Math.sqrt(distX * distX + distY * distY + distZ * distZ);
return distance <= range;
}
public static void startSignalBlockPairing(EntityPlayer player, ItemStack device, IBlockSignal first) {
endSignalBlockPairing(player, device);
int id = new Random().nextInt(Short.MAX_VALUE);
device.setItemDamage(id);
first.startSignalBlockPairing();
signalBlockPairingMap.put(new PairingKey(player.username, device.getItemDamage()), new WorldCoordinate(first.getDimension(), first.getX(), first.getY(), first.getZ()));
}
public static WorldCoordinate getSignalBlockPair(EntityPlayer player, ItemStack device) {
return signalBlockPairingMap.get(new PairingKey(player.username, device.getItemDamage()));
}
public static void endSignalBlockPairing(EntityPlayer player, ItemStack device) {
WorldCoordinate pos = signalBlockPairingMap.remove(new PairingKey(player.username, device.getItemDamage()));
if(pos != null) {
TileEntity t = player.worldObj.getBlockTileEntity(pos.x, pos.y, pos.z);
if(t instanceof IBlockSignal) {
((IBlockSignal)t).endSignalBlockPairing();
}
}
}
public static void startControllerReceiverPairing(EntityPlayer player, ItemStack device, ISignalController controller) {
endControllerReceiverPairing(player, device);
int id = new Random().nextInt(Short.MAX_VALUE);
device.setItemDamage(id);
controller.startReceiverPairing();
controllerReceiverPairingMap.put(new PairingKey(player.username, device.getItemDamage()), new WorldCoordinate(controller.getDimension(), controller.getX(), controller.getY(), controller.getZ()));
}
public static WorldCoordinate getSavedController(EntityPlayer player, ItemStack device) {
return controllerReceiverPairingMap.get(new PairingKey(player.username, device.getItemDamage()));
}
public static void endControllerReceiverPairing(EntityPlayer player, ItemStack device) {
WorldCoordinate pos = controllerReceiverPairingMap.remove(new PairingKey(player.username, device.getItemDamage()));
if(pos != null) {
TileEntity t = player.worldObj.getBlockTileEntity(pos.x, pos.y, pos.z);
if(t instanceof ISignalController) {
((ISignalController)t).endReceiverPairing();
}
}
}
public static ISignalReceiver getReceiverFor(ISignalController con) {
World world = con.getWorld();
if(world == null || con.getReceiverY() < 0) {
return null;
}
int i = con.getReceiverX();
int j = con.getReceiverY();
int k = con.getReceiverZ();
if(!world.blockExists(i, j, k)) {
return null;
}
TileEntity pair = world.getBlockTileEntity(i, j, k);
if(pair instanceof ISignalReceiver) {
return (ISignalReceiver)pair;
} else {
con.clearPairedReceiver();
}
return null;
}
public static ISignalController getControllerFor(ISignalReceiver rec) {
if(rec.getControllerY() < 0) {
return null;
}
World world = rec.getWorld();
if(world == null) {
return null;
}
int i = rec.getControllerX();
int j = rec.getControllerY();
int k = rec.getControllerZ();
if(!world.blockExists(i, j, k)) {
return null;
}
TileEntity pair = world.getBlockTileEntity(i, j, k);
if(pair instanceof ISignalController) {
return (ISignalController)pair;
} else {
rec.clearPairedController();
}
return null;
}
private static class PairingKey
{
protected String username;
protected int id;
public PairingKey(String username, int id) {
this.username = username;
this.id = id;
}
@Override
public int hashCode() {
int hash = 3;
hash = 59 * hash + (this.username != null ? this.username.hashCode() : 0);
hash = 59 * hash + this.id;
return hash;
}
@Override
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(getClass() != obj.getClass()) {
return false;
}
final PairingKey other = (PairingKey)obj;
if((this.username == null) ? (other.username != null) : !this.username.equals(other.username)) {
return false;
}
if(this.id != other.id) {
return false;
}
return true;
}
}
}

View file

@ -1,29 +0,0 @@
package railcraft.common.api.tracks;
import net.minecraft.src.World;
/**
* Have your ITrackInstance implement this to override normal track placement.
*
* Used by tracks such as the Suspended Track.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ITrackCustomPlaced extends ITrackInstance
{
/**
* Used to override normal track placement.
*
* Used by tracks such as the Suspended Track.
*
* Warning: This is called before the TileEntity is set.
*
* @param world The World
* @param i x-Coord
* @param j y-Coord
* @param k z-Coord
* @return true if the rail can placed at the specified location, false to prevent placement
*/
public boolean canPlaceRailAt(World world, int i, int j, int k);
}

View file

@ -1,24 +0,0 @@
package railcraft.common.api.tracks;
import net.minecraft.src.AxisAlignedBB;
import net.minecraft.src.MovingObjectPosition;
import net.minecraft.src.Vec3;
/**
* Used by rails that modify the bounding boxes.
*
* For example, the Gated Rails.
*
* Not very useful since there is no system in place to insert custom render code.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ITrackCustomShape extends ITrackInstance
{
public AxisAlignedBB getCollisionBoundingBoxFromPool();
public AxisAlignedBB getSelectedBoundingBoxFromPool();
public MovingObjectPosition collisionRayTrace(Vec3 vec3d, Vec3 vec3d1);
}

View file

@ -1,22 +0,0 @@
package railcraft.common.api.tracks;
/**
* Tracks that can emit a redstone signal should implement
* this interface.
*
* For example a detector track.
*
* A track cannot implement both ITrackPowered and ITrackEmitter.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ITrackEmitter extends ITrackInstance
{
/**
* Return true if the track is producing a redstone signal.
*
* @return true if powered
*/
public boolean isTrackPowering();
}

View file

@ -1,123 +0,0 @@
package railcraft.common.api.tracks;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityLiving;
import net.minecraft.src.EntityMinecart;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.TileEntity;
import railcraft.common.api.core.INetworkedObject;
/**
* This interface defines a track.
*
* Basically all block and tile entity functions for Tracks are delegated to an
* ITrackInstance.
*
* Instead of implementing this interface directly, you should probably
* extend TrackInstanceBase. It will simplify your life.
*
* All packet manipulation is handled by Railcraft's code,
* you just need to implement the functions in INetworkedObject
* to pass data from the server to the client.
*
* @author CovertJaguar
* @see TrackInstanceBase
*/
public interface ITrackInstance extends INetworkedObject
{
public TrackSpec getTrackSpec();
/**
* 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.
*
* 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 cart The cart asking for the metadata, null if it is not called by EntityMinecart.
* @return The metadata.
*/
public int getBasicRailMetadata(EntityMinecart cart);
/**
* 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 cart The cart on the rail.
*/
public void onMinecartPass(EntityMinecart cart);
/**
* Return the block texture to be used.
*
* @return
*/
public int getTextureIndex();
public void writeToNBT(NBTTagCompound data);
public void readFromNBT(NBTTagCompound data);
/**
* Return true if this track requires update ticks.
* @return
*/
public boolean canUpdate();
public void updateEntity();
public boolean blockActivated(EntityPlayer player);
public void onBlockPlaced(int side);
public void onBlockPlacedBy(EntityLiving entity);
public void onNeighborBlockChange(int id);
/**
* Internal function that sets the Track's TileEntity so it can
* be referenced for position information, etc...
* @param tile
*/
public void setTile(TileEntity tile);
public int getX();
public int getY();
public int getZ();
public float getExplosionResistance(double srcX, double srcY, double srcZ, Entity exploder);
/**
* Return true if the rail can make corners.
* Used by placement logic.
* @return true if the rail can make corners.
*/
public boolean isFlexibleRail();
/**
* Returns true if the rail can make up and down slopes.
* Used by placement logic.
* @return true if the rail can make slopes.
*/
public boolean canMakeSlopes();
/**
* Returns the max speed of the rail.
* @param cart The cart on the rail, may be null.
* @return The max speed of the current rail.
*/
public float getRailMaxSpeed(EntityMinecart cart);
}

View file

@ -1,18 +0,0 @@
package railcraft.common.api.tracks;
import net.minecraft.src.EntityMinecart;
/**
* Any rail tile entity that can completely halt
* all cart movement should implement this interface.
* (Used in collision handling)
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ITrackLockdown extends ITrackInstance
{
public boolean isCartLockedDown(EntityMinecart cart);
public void releaseCart();
}

View file

@ -1,24 +0,0 @@
package railcraft.common.api.tracks;
/**
* Implementing this interface will allow your track to be
* powered via Redstone.
*
* And so long as you inherit from TrackInstanceBase, all the code for updating
* the power state is already in place (including propagation).
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ITrackPowered extends ITrackInstance
{
public boolean isPowered();
public void setPowered(boolean powered);
/**
* The distance that a redstone signal will be passed along from track to track.
* @return int
*/
public int getPowerPropagation();
}

View file

@ -1,17 +0,0 @@
package railcraft.common.api.tracks;
/**
* Implementing this interface will allow your track to be direction specific.
*
* And so long as you inherit from TrackInstanceBase it will automatically be
* reversable via the Crowbar.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ITrackReversable extends ITrackInstance
{
public boolean isReversed();
public void setReversed(boolean reversed);
}

View file

@ -1,21 +0,0 @@
package railcraft.common.api.tracks;
public interface ITrackSwitch extends ITrackInstance
{
enum ArrowDirection
{
NORTH, SOUTH, EAST, WEST, NORTH_SOUTH, EAST_WEST
};
public boolean isSwitched();
public void setSwitched(boolean switched);
public boolean isMirrored();
public ArrowDirection getRedSignDirection();
public ArrowDirection getWhiteSignDirection();
}

View file

@ -1,13 +0,0 @@
package railcraft.common.api.tracks;
/**
* Don't use this, its an interface that allows other API code
* access to internal functions of the code.
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public interface ITrackTile
{
public ITrackInstance getTrackInstance();
}

View file

@ -1,175 +0,0 @@
package railcraft.common.api.tracks;
import railcraft.common.api.core.items.ITrackItem;
import net.minecraft.src.Block;
import net.minecraft.src.BlockRail;
import net.minecraft.src.EntityMinecart;
import net.minecraft.src.ItemBlock;
import net.minecraft.src.ItemStack;
import net.minecraft.src.MathHelper;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
/**
* A number of utility functions related to rails.
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public abstract class RailTools
{
/**
* Attempts to place a rail of the type provided.
* There is no need to verify that the ItemStack contains a valid rail
* prior to calling this function.
*
* The function takes care of that and will return false if the ItemStack
* is not a valid ITrackItem or an ItemBlock who's id
* will return true when passed to BlockRail.isRailBlock(itemID).
*
* That means this function can place any Railcraft or vanilla rail
* and has at least a decent chance of being able to place
* most third party rails.
*
* @param stack The ItemStack containing the rail
* @param world The World object
* @param i x-Coord
* @param j y-Coord
* @param k z-Coord
* @return true if successful
* @see ITrackItem
*/
public static boolean placeRailAt(ItemStack stack, World world, int i, int j, int k)
{
if(stack == null) {
return false;
}
if(stack.getItem() instanceof ITrackItem) {
return ((ITrackItem)stack.getItem()).placeTrack(stack.copy(), world, i, j, k);
}
if(stack.getItem() instanceof ItemBlock && stack.itemID < Block.blocksList.length && BlockRail.isRailBlock(stack.itemID)) {
boolean success = world.setBlockWithNotify(i, j, k, stack.itemID);
if(success) {
world.playSoundEffect((float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, Block.rail.stepSound.getStepSound(), (Block.rail.stepSound.getVolume() + 1.0F) / 2.0F, Block.rail.stepSound.getPitch() * 0.8F);
}
return success;
}
return false;
}
/**
* Returns true if the ItemStack contains a valid Railcraft Track item.
*
* Will return false is passed a vanilla rail.
*
* @param stack The ItemStack to test
* @return true if rail
* @see ITrackItem
*/
public static boolean isTrackItem(ItemStack stack)
{
return stack != null && stack.getItem() instanceof ITrackItem;
}
/**
* Checks to see if a cart is being held by a ITrackLockdown.
* @param cart The cart to check
* @return True if being held
*/
public static boolean isCartLockedDown(EntityMinecart cart)
{
int x = MathHelper.floor_double(cart.posX);
int y = MathHelper.floor_double(cart.posY);
int z = MathHelper.floor_double(cart.posZ);
if(BlockRail.isRailBlockAt(cart.worldObj, x, y - 1, z)) {
y--;
}
TileEntity tile = cart.worldObj.getBlockTileEntity(x, y, z);
if(tile instanceof ITrackTile) {
ITrackInstance track = ((ITrackTile)tile).getTrackInstance();
return track instanceof ITrackLockdown && ((ITrackLockdown)track).isCartLockedDown(cart);
}
return false;
}
/**
* Verifies that two rails are connected to each other
* along a straight line with no gaps or wanderings.
* @param world The World object
* @param i1 x-Coord of Rail #1
* @param j1 y-Coord of Rail #1
* @param k1 z-Coord of Rail #1
* @param i2 x-Coord of Rail #2
* @param j2 y-Coord of Rail #2
* @param k2 z-Coord of Rail #2
* @return true if they are connected
*/
public static boolean areDistantRailsConnectedAlongAxis(World world, int i1, int j1, int k1, int i2, int j2, int k2)
{
if(j1 < 0 || j2 < 0) {
return false;
}
if(i1 != i2 && k1 != k2) {
return false;
}
if(i1 != i2) {
int min = 0;
int max = 0;
int jj = 0;
if(i1 < i2) {
min = i1;
max = i2;
jj = j1;
} else {
min = i2;
max = i1;
jj = j2;
}
for(int ii = min; ii <= max; ii++) {
if(world.blockExists(ii, jj, k1)) {
if(BlockRail.isRailBlockAt(world, ii, jj, k1)) {
continue;
} else if(BlockRail.isRailBlockAt(world, ii, jj - 1, k1)) {
jj--;
continue;
} else if(BlockRail.isRailBlockAt(world, ii, jj + 1, k1)) {
jj++;
continue;
} else {
return false;
}
}
}
} else if(k1 != k2) {
int min = 0;
int max = 0;
int jj = 0;
if(k1 < k2) {
min = k1;
max = k2;
jj = j1;
} else {
min = k2;
max = k1;
jj = j2;
}
for(int kk = min; kk <= max; kk++) {
if(world.blockExists(i1, jj, kk)) {
if(BlockRail.isRailBlockAt(world, i1, jj, kk)) {
continue;
} else if(BlockRail.isRailBlockAt(world, i1, jj - 1, kk)) {
jj--;
continue;
} else if(BlockRail.isRailBlockAt(world, i1, jj + 1, kk)) {
jj++;
continue;
} else {
return false;
}
}
}
}
return true;
}
}

View file

@ -1,385 +0,0 @@
package railcraft.common.api.tracks;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.src.Block;
import net.minecraft.src.BlockRail;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityLiving;
import net.minecraft.src.EntityMinecart;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.ItemStack;
import net.minecraft.src.MathHelper;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.RailLogic;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
import net.minecraftforge.common.ForgeDirection;
import railcraft.common.api.core.items.ICrowbar;
/**
* All ITrackInstances should extend this class. It contains a number of
* default functions and standard behavior for Tracks that should
* greatly simplify implementing new Tracks when using this API.
*
* @author CovertJaguar <railcraft.wikispaces.com>
* @see ITrackInstance
* @see TrackRegistry
* @see TrackSpec
*/
public abstract class TrackInstanceBase implements ITrackInstance
{
private Block block;
public TileEntity tileEntity;
private Block getBlock()
{
if(block == null) {
int id = getWorld().getBlockId(getX(), getY(), getZ());
block = Block.blocksList[id];
}
return block;
}
@Override
public void setTile(TileEntity tile)
{
tileEntity = tile;
}
@Override
public int getBasicRailMetadata(EntityMinecart cart)
{
return tileEntity.getBlockMetadata();
}
@Override
public void onMinecartPass(EntityMinecart cart)
{
}
@Override
public boolean blockActivated(EntityPlayer player)
{
if(this instanceof ITrackReversable) {
ItemStack current = player.getCurrentEquippedItem();
if(current != null && current.getItem() instanceof ICrowbar) {
ITrackReversable track = (ITrackReversable)this;
track.setReversed(!track.isReversed());
markBlockNeedsUpdate();
if(current.isItemStackDamageable()) {
current.damageItem(1, player);
}
return true;
}
}
return false;
}
@Override
public void onBlockPlaced(int side)
{
switchTrack(true);
testPower();
markBlockNeedsUpdate();
}
@Override
public void onBlockPlacedBy(EntityLiving entityliving)
{
if(entityliving == null) {
return;
}
if(this instanceof ITrackReversable) {
int dir = MathHelper.floor_double((double)((entityliving.rotationYaw * 4F) / 360F) + 0.5D) & 3;
((ITrackReversable)this).setReversed(dir == 0 || dir == 1);
}
markBlockNeedsUpdate();
}
public void markBlockNeedsUpdate()
{
getWorld().markBlockNeedsUpdate(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);
}
protected boolean isRailValid(World world, int i, int j, int k, int meta)
{
boolean valid = true;
if(!world.isBlockSolidOnSide(i, j - 1, k, ForgeDirection.UP)) {
valid = false;
}
if(meta == 2 && !world.isBlockSolidOnSide(i + 1, j, k, ForgeDirection.UP)) {
valid = false;
} else if(meta == 3 && !world.isBlockSolidOnSide(i - 1, j, k, ForgeDirection.UP)) {
valid = false;
} else if(meta == 4 && !world.isBlockSolidOnSide(i, j, k - 1, ForgeDirection.UP)) {
valid = false;
} else if(meta == 5 && !world.isBlockSolidOnSide(i, j, k + 1, ForgeDirection.UP)) {
valid = false;
}
return valid;
}
@Override
public void onNeighborBlockChange(int id)
{
int meta = tileEntity.getBlockMetadata();
boolean valid = isRailValid(getWorld(), tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord, meta);
if(!valid) {
Block blockTrack = getBlock();
blockTrack.dropBlockAsItem(getWorld(), tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord, 0, 0);
getWorld().setBlockWithNotify(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord, 0);
return;
}
BlockRail blockTrack = (BlockRail)getBlock();
if(id > 0 && Block.blocksList[id].canProvidePower() && isFlexibleRail() && RailLogic.getAdjacentTracks(new RailLogic(blockTrack, getWorld(), tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord)) == 3) {
switchTrack(false);
}
testPower();
}
protected void switchTrack(boolean flag)
{
int i = tileEntity.xCoord;
int j = tileEntity.yCoord;
int k = tileEntity.zCoord;
BlockRail blockTrack = (BlockRail)getBlock();
(new RailLogic(blockTrack, getWorld(), i, j, k)).refreshTrackShape(getWorld().isBlockIndirectlyGettingPowered(i, j, k), flag);
}
protected void testPower()
{
if(!(this instanceof ITrackPowered)) {
return;
}
int i = tileEntity.xCoord;
int j = tileEntity.yCoord;
int k = tileEntity.zCoord;
ITrackPowered r = (ITrackPowered)this;
int meta = tileEntity.getBlockMetadata();
boolean powered = getWorld().isBlockIndirectlyGettingPowered(i, j, k) || getWorld().isBlockIndirectlyGettingPowered(i, j + 1, k) || testPowerPropagation(getWorld(), i, j, k, getTrackSpec(), meta, r.getPowerPropagation());
if(powered != r.isPowered()) {
r.setPowered(powered);
Block blockTrack = getBlock();
getWorld().notifyBlocksOfNeighborChange(i, j, k, blockTrack.blockID);
getWorld().notifyBlocksOfNeighborChange(i, j - 1, k, blockTrack.blockID);
if(meta == 2 || meta == 3 || meta == 4 || meta == 5) {
getWorld().notifyBlocksOfNeighborChange(i, j + 1, k, blockTrack.blockID);
}
markBlockNeedsUpdate();
// System.out.println("Setting power [" + i + ", " + j + ", " + k + "]");
}
}
protected boolean testPowerPropagation(World world, int i, int j, int k, TrackSpec spec, int meta, int maxDist)
{
return isConnectedRailPowered(world, i, j, k, spec, meta, true, 0, maxDist) || isConnectedRailPowered(world, i, j, k, spec, meta, false, 0, maxDist);
}
protected boolean isConnectedRailPowered(World world, int i, int j, int k, TrackSpec spec, int meta, boolean dir, int dist, int maxDist)
{
if(dist >= maxDist) {
return false;
}
boolean powered = true;
switch (meta) {
case 0: // '\0'
if(dir) {
k++;
} else {
k--;
}
break;
case 1: // '\001'
if(dir) {
i--;
} else {
i++;
}
break;
case 2: // '\002'
if(dir) {
i--;
} else {
i++;
j++;
powered = false;
}
meta = 1;
break;
case 3: // '\003'
if(dir) {
i--;
j++;
powered = false;
} else {
i++;
}
meta = 1;
break;
case 4: // '\004'
if(dir) {
k++;
} else {
k--;
j++;
powered = false;
}
meta = 0;
break;
case 5: // '\005'
if(dir) {
k++;
j++;
powered = false;
} else {
k--;
}
meta = 0;
break;
}
if(testPowered(world, i, j, k, spec, dir, dist, maxDist, meta)) {
return true;
}
return powered && testPowered(world, i, j - 1, k, spec, dir, dist, maxDist, meta);
}
protected boolean testPowered(World world, int i, int j, int k, TrackSpec spec, boolean dir, int dist, int maxDist, int orientation)
{
// System.out.println("Testing Power at <" + i + ", " + j + ", " + k + ">");
int id = world.getBlockId(i, j, k);
Block blockTrack = getBlock();
if(id == blockTrack.blockID) {
int meta = world.getBlockMetadata(i, j, k);
TileEntity tile = world.getBlockTileEntity(i, j, k);
if(tile instanceof ITrackTile) {
ITrackInstance track = ((ITrackTile)tile).getTrackInstance();
if(!(track instanceof ITrackPowered) || track.getTrackSpec() != spec) {
return false;
}
if(orientation == 1 && (meta == 0 || meta == 4 || meta == 5)) {
return false;
}
if(orientation == 0 && (meta == 1 || meta == 2 || meta == 3)) {
return false;
}
if(((ITrackPowered)track).isPowered()) {
if(world.isBlockIndirectlyGettingPowered(i, j, k) || world.isBlockIndirectlyGettingPowered(i, j + 1, k)) {
return true;
} else {
return isConnectedRailPowered(world, i, j, k, spec, meta, dir, dist + 1, maxDist);
}
}
}
}
return false;
}
@Override
public int getTextureIndex()
{
return getTrackSpec().getTextureIndex();
}
@Override
public void writeToNBT(NBTTagCompound data)
{
}
@Override
public void readFromNBT(NBTTagCompound data)
{
}
@Override
public boolean canUpdate()
{
return false;
}
@Override
public void updateEntity()
{
}
@Override
public float getExplosionResistance(double srcX, double srcY, double srcZ, Entity exploder)
{
return 3.5f;
}
@Override
public void writePacketData(DataOutputStream data) throws IOException
{
}
@Override
public void readPacketData(DataInputStream data) throws IOException
{
}
@Override
public World getWorld()
{
return tileEntity.worldObj;
}
@Override
public int getX()
{
return tileEntity.xCoord;
}
@Override
public int getY()
{
return tileEntity.yCoord;
}
@Override
public int getZ()
{
return tileEntity.zCoord;
}
/**
* Return true if the rail can make corners.
* Used by placement logic.
* @return true if the rail can make corners.
*/
@Override
public boolean isFlexibleRail()
{
return false;
}
/**
* Returns true if the rail can make up and down slopes.
* Used by placement logic.
* @return true if the rail can make slopes.
*/
@Override
public boolean canMakeSlopes()
{
return true;
}
/**
* Returns the max speed of the rail.
* @param cart The cart on the rail, may be null.
* @return The max speed of the current rail.
*/
@Override
public float getRailMaxSpeed(EntityMinecart cart)
{
return 0.4f;
}
}

View file

@ -1,62 +0,0 @@
package railcraft.common.api.tracks;
import cpw.mods.fml.common.FMLCommonHandler;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
/**
* The TrackRegistry is part of a system that allows 3rd party addons to simply,
* quickly, and easily define new Tracks with unique behaviors without requiring
* that any additional block ids be used.
*
* All the tracks in RailcraftProxy are implemented using this system 100%
* (except for Gated Tracks and Switch Tracks which have some custom render code).
*
* To define a new track, you need to define a TrackSpec and create a ITrackInstance.
*
* The TrackSpec contains basic constant information about the Track, while the TrackInstace
* controls how an individual Track block interact with the world.
*
* @author CovertJaguar <railcraft.wikispaces.com>
* @see TrackSpec
* @see ITrackInstance
* @see TrackInstanceBase
*/
public class TrackRegistry
{
private static Map<Short, TrackSpec> trackSpecs = new HashMap<Short, TrackSpec>();
public static void registerTrackSpec(TrackSpec trackSpec)
{
if(trackSpecs.put(trackSpec.getTrackId(), trackSpec) != null) {
throw new RuntimeException("TrackId conflict detected, please adjust your config or contact the author of the " + trackSpec.getTrackTag());
}
}
/**
* Returns a cached copy of a TrackSpec object.
*
* @param trackId
* @return
*/
public static TrackSpec getTrackSpec(int trackId)
{
TrackSpec spec = trackSpecs.get((short)trackId);
if(spec == null) {
FMLCommonHandler.instance().getFMLLogger().log(Level.WARNING, "[Railcraft] Unknown Track Spec ID({0}), reverting to normal track", trackId);
spec = trackSpecs.get(-1);
}
return spec;
}
/**
* Returns all Registered TrackSpecs.
* @return list of TrackSpecs
*/
public static Map<Short, TrackSpec> getTrackSpecs()
{
return trackSpecs;
}
}

View file

@ -1,86 +0,0 @@
package railcraft.common.api.tracks;
import net.minecraft.src.ItemStack;
import railcraft.common.api.core.items.ItemRegistry;
/**
* Each type of Track has a single instance of TrackSpec
* that corresponds with it.
*
* Each Track block in the world has a ITrackInstance that
* corresponds with it.
*
* Take note of the difference (similar to block classes and tile entities classes).
*
* TrackSpecs must be registered with the TrackRegistry.
*
* Track Items can be acquired with the ItemRegistry.
*
* @see TrackRegistry
* @see ITrackInstance
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public final class TrackSpec
{
public static int blockID = 0;
private final String tag;
private final String textureFile;
private final short trackId;
private final int textureId;
private final Class<? extends ITrackInstance> instanceClass;
/**
* Defines a new track spec.
*
* @param trackId A unique identifier for the track type. 0-512 are reserved for Railcraft. Capped at Short.MAX_VALUE
* @param tag A unique internal string identifier (ex. "track.speed.transition")
* @param textureFile See ITextureProvider
* @param textureId The texture index used by the track's item
* @param instanceClass The ITrackInstance class that corresponds to this TrackSpec
* @see ITextureProvider
*/
public TrackSpec(short trackId, String tag, String textureFile, int textureId, Class<? extends ITrackInstance> instanceClass) {
this.trackId = trackId;
this.tag = tag;
this.textureFile = textureFile;
this.textureId = textureId;
this.instanceClass = instanceClass;
}
public String getTrackTag() {
return tag;
}
public short getTrackId() {
return trackId;
}
public ItemStack getItem() {
return getItem(1);
}
public ItemStack getItem(int qty) {
if(blockID <= 0) {
return null;
}
return new ItemStack(blockID, qty, getTrackId());
}
public ITrackInstance createInstanceFromSpec() {
try {
return (ITrackInstance)instanceClass.newInstance();
} catch (Exception ex) {
throw new RuntimeException("Improper Track Instance Constructor");
}
}
public String getTextureFile() {
return textureFile;
}
public int getTextureIndex() {
return textureId;
}
}

View file

@ -102,18 +102,18 @@ public class SteamPowerMain{
'@',new ItemStack(BasicComponents.itemSteelPlate),
'O',new ItemStack(BasicComponents.itemCircuit,1,0),
'V',new ItemStack(BasicComponents.itemMotor)});
GameRegistry.addRecipe(new ItemStack(machine, 1, 1), new Object [] {"@T@", "OVO", "@T@",
GameRegistry.addRecipe(new ItemStack(machine, 1, 1), new Object [] {"TT", "VV", "TT",
'T',new ItemStack(BasicPipesMain.parts, 1,6),
'@',new ItemStack(BasicComponents.itemSteelPlate),
'O',new ItemStack(BasicPipesMain.parts, 1,0),
'V',new ItemStack(BasicPipesMain.parts, 1,7)});
GameRegistry.addRecipe(new ItemStack(machine, 1, 2), new Object [] { "@", "F",
'F',Block.stoneOvenIdle,
'@',new ItemStack(BasicComponents.itemSteelPlate)});
GameRegistry.addRecipe(new ItemStack(itemEngine, 1,0), new Object [] {"@T@", "PMP", "@T@",
'T',new ItemStack(BasicPipesMain.parts, 1,0),
GameRegistry.addRecipe(new ItemStack(itemEngine, 1,0), new Object [] {"GGG", "VPV", "@T@",
'T',new ItemStack(BasicPipesMain.parts, 1,1),
'G',BasicPipesMain.rod,
'@',new ItemStack(BasicComponents.itemSteelPlate),
'P',Block.pistonBase,
'V',new ItemStack(BasicPipesMain.parts, 1,7),
'M',new ItemStack(BasicComponents.itemMotor)});}
catch(Exception e)
{