Moved APIs over from API bank to reduce repo count

This commit is contained in:
DarkGuardsman 2013-07-22 01:05:40 -04:00
parent 7e1ef517b9
commit fb37031651
147 changed files with 11449 additions and 0 deletions

View file

@ -0,0 +1,21 @@
/**
* Copyright (c) SpaceToad, 2011
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.core;
import net.minecraft.block.Block;
public class BuildCraftAPI
{
public static final int LAST_ORIGINAL_BLOCK = 122;
public static final int LAST_ORIGINAL_ITEM = 126;
public static final boolean[] softBlocks = new boolean[Block.blocksList.length];
}

View file

@ -0,0 +1,161 @@
/**
* Copyright (c) SpaceToad, 2011
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.core;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
public class Position
{
public double x, y, z;
public ForgeDirection orientation;
public Position(double ci, double cj, double ck)
{
x = ci;
y = cj;
z = ck;
orientation = ForgeDirection.UNKNOWN;
}
public Position(double ci, double cj, double ck, ForgeDirection corientation)
{
x = ci;
y = cj;
z = ck;
orientation = corientation;
}
public Position(Position p)
{
x = p.x;
y = p.y;
z = p.z;
orientation = p.orientation;
}
public Position(NBTTagCompound nbttagcompound)
{
x = nbttagcompound.getDouble("i");
y = nbttagcompound.getDouble("j");
z = nbttagcompound.getDouble("k");
orientation = ForgeDirection.UNKNOWN;
}
public Position(TileEntity tile)
{
x = tile.xCoord;
y = tile.yCoord;
z = tile.zCoord;
}
public void moveRight(double step)
{
switch (orientation)
{
case SOUTH:
x = x - step;
break;
case NORTH:
x = x + step;
break;
case EAST:
z = z + step;
break;
case WEST:
z = z - step;
break;
default:
}
}
public void moveLeft(double step)
{
moveRight(-step);
}
public void moveForwards(double step)
{
switch (orientation)
{
case UP:
y = y + step;
break;
case DOWN:
y = y - step;
break;
case SOUTH:
z = z + step;
break;
case NORTH:
z = z - step;
break;
case EAST:
x = x + step;
break;
case WEST:
x = x - step;
break;
default:
}
}
public void moveBackwards(double step)
{
moveForwards(-step);
}
public void moveUp(double step)
{
switch (orientation)
{
case SOUTH:
case NORTH:
case EAST:
case WEST:
y = y + step;
break;
default:
}
}
public void moveDown(double step)
{
moveUp(-step);
}
public void writeToNBT(NBTTagCompound nbttagcompound)
{
nbttagcompound.setDouble("i", x);
nbttagcompound.setDouble("j", y);
nbttagcompound.setDouble("k", z);
}
@Override
public String toString()
{
return "{" + x + ", " + y + ", " + z + "}";
}
public Position min(Position p)
{
return new Position(p.x > x ? x : p.x, p.y > y ? y : p.y, p.z > z ? z : p.z);
}
public Position max(Position p)
{
return new Position(p.x < x ? x : p.x, p.y < y ? y : p.y, p.z < z ? z : p.z);
}
}

View file

@ -0,0 +1,57 @@
/**
* Copyright (c) SpaceToad, 2011
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.core;
import net.minecraft.world.World;
public class SafeTimeTracker
{
private long lastMark = Long.MIN_VALUE;
private long duration = 0;
private boolean marked;
/**
* Return true if a given delay has passed since last time marked was called successfully.
*/
public boolean markTimeIfDelay(World world, long delay)
{
if (world == null)
return false;
long currentTime = world.getWorldTime();
if (currentTime < lastMark)
{
lastMark = currentTime;
return false;
}
else if (lastMark + delay <= currentTime)
{
duration = currentTime - lastMark;
lastMark = world.getWorldTime();
marked = true;
return true;
}
else
return false;
}
public long durationOfLastDelay()
{
return marked ? duration : 0;
}
public void markTime(World world)
{
lastMark = world.getWorldTime();
}
}

View file

@ -0,0 +1,106 @@
package buildcraft.api.gates;
import buildcraft.api.transport.IPipe;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
public class ActionManager {
public static Map<String, ITrigger> triggers = new HashMap<String, ITrigger>();
public static Map<String, IAction> actions = new HashMap<String, IAction>();
private static LinkedList<ITriggerProvider> triggerProviders = new LinkedList<ITriggerProvider>();
private static LinkedList<IActionProvider> actionProviders = new LinkedList<IActionProvider>();
public static void registerTriggerProvider(ITriggerProvider provider) {
if (provider != null && !triggerProviders.contains(provider)) {
triggerProviders.add(provider);
}
}
public static void registerTrigger(ITrigger trigger){
triggers.put(trigger.getUniqueTag(), trigger);
}
public static void registerAction(IAction action){
actions.put(action.getUniqueTag(), action);
}
public static LinkedList<ITrigger> getNeighborTriggers(Block block, TileEntity entity) {
LinkedList<ITrigger> triggers = new LinkedList<ITrigger>();
for (ITriggerProvider provider : triggerProviders) {
LinkedList<ITrigger> toAdd = provider.getNeighborTriggers(block, entity);
if (toAdd != null) {
for (ITrigger t : toAdd) {
if (!triggers.contains(t)) {
triggers.add(t);
}
}
}
}
return triggers;
}
public static void registerActionProvider(IActionProvider provider) {
if (provider != null && !actionProviders.contains(provider)) {
actionProviders.add(provider);
}
}
public static LinkedList<IAction> getNeighborActions(Block block, TileEntity entity) {
LinkedList<IAction> actions = new LinkedList<IAction>();
for (IActionProvider provider : actionProviders) {
LinkedList<IAction> toAdd = provider.getNeighborActions(block, entity);
if (toAdd != null) {
for (IAction t : toAdd) {
if (!actions.contains(t)) {
actions.add(t);
}
}
}
}
return actions;
}
public static LinkedList<ITrigger> getPipeTriggers(IPipe pipe) {
LinkedList<ITrigger> triggers = new LinkedList<ITrigger>();
for (ITriggerProvider provider : triggerProviders) {
LinkedList<ITrigger> toAdd = provider.getPipeTriggers(pipe);
if (toAdd != null) {
for (ITrigger t : toAdd) {
if (!triggers.contains(t)) {
triggers.add(t);
}
}
}
}
return triggers;
}
public static ITrigger getTriggerFromLegacyId(int legacyId){
for(ITrigger trigger : triggers.values()){
if(trigger.getLegacyId() == legacyId)
return trigger;
}
return null;
}
public static IAction getActionFromLegacyId(int legacyId){
for(IAction action : actions.values()){
if(action.getLegacyId() == legacyId)
return action;
}
return null;
}
}

View file

@ -0,0 +1,27 @@
package buildcraft.api.gates;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.util.Icon;
public interface IAction {
/**
* Return your ID from the old API here, this is only used to convert old
* saves to the new format.
*/
int getLegacyId();
String getUniqueTag();
@SideOnly(Side.CLIENT)
Icon getIcon();
@SideOnly(Side.CLIENT)
void registerIcons(IconRegister iconRegister);
boolean hasParameter();
String getDescription();
}

View file

@ -0,0 +1,23 @@
/**
* Copyright (c) SpaceToad, 2011
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.gates;
import java.util.LinkedList;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
public interface IActionProvider {
/**
* Returns the list of actions available to a gate next to the given block.
*/
public abstract LinkedList<IAction> getNeighborActions(Block block, TileEntity tile);
}

View file

@ -0,0 +1,16 @@
/**
* Copyright (c) SpaceToad, 2012
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.gates;
public interface IActionReceptor {
public void actionActivated(IAction action);
}

View file

@ -0,0 +1,21 @@
/**
* Copyright (c) SpaceToad, 2011
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.gates;
import java.util.LinkedList;
/**
* This interface has to be implemented by a TileEntity or a Pipe that wants to provide triggers different from the ones installed by default with BuildCraft.
*/
public interface IOverrideDefaultTriggers {
LinkedList<ITrigger> getTriggers();
}

View file

@ -0,0 +1,47 @@
package buildcraft.api.gates;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
import net.minecraftforge.common.ForgeDirection;
public interface ITrigger {
/**
* Return your ID from the old API here, this is only used to convert old
* saves to the new format.
*/
int getLegacyId();
String getUniqueTag();
@SideOnly(Side.CLIENT)
Icon getIcon();
@SideOnly(Side.CLIENT)
void registerIcons(IconRegister iconRegister);
/**
* Return true if this trigger can accept parameters
*/
boolean hasParameter();
/**
* Return the trigger description in the UI
*/
String getDescription();
/**
* Return true if the tile given in parameter activates the trigger, given
* the parameters.
*/
boolean isTriggerActive(ForgeDirection side, TileEntity tile, ITriggerParameter parameter);
/**
* Create parameters for the trigger. As for now, there is only one kind of
* trigger parameter available so this subprogram is final.
*/
ITriggerParameter createParameter();
}

View file

@ -0,0 +1,18 @@
package buildcraft.api.gates;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
public interface ITriggerParameter {
public abstract ItemStack getItemStack();
public abstract void set(ItemStack stack);
public abstract void writeToNBT(NBTTagCompound compound);
public abstract void readFromNBT(NBTTagCompound compound);
public abstract ItemStack getItem();
}

View file

@ -0,0 +1,29 @@
/**
* Copyright (c) SpaceToad, 2011
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.gates;
import buildcraft.api.transport.IPipe;
import java.util.LinkedList;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
public interface ITriggerProvider {
/**
* Returns the list of triggers that are available from the pipe holding the gate.
*/
public abstract LinkedList<ITrigger> getPipeTriggers(IPipe pipe);
/**
* Returns the list of triggers available to a gate next to the given block.
*/
public abstract LinkedList<ITrigger> getNeighborTriggers(Block block, TileEntity tile);
}

View file

@ -0,0 +1,79 @@
/**
* Copyright (c) SpaceToad, 2011
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.gates;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
public class TriggerParameter implements ITriggerParameter {
protected ItemStack stack;
/*
* (non-Javadoc)
*
* @see net.minecraft.src.buildcraft.api.gates.ITriggerParameter#getItemStack()
*/
@Override
public ItemStack getItemStack() {
return stack;
}
/*
* (non-Javadoc)
*
* @see net.minecraft.src.buildcraft.api.gates.ITriggerParameter#set(net.minecraft.src.ItemStack)
*/
@Override
public void set(ItemStack stack) {
if (stack != null) {
this.stack = stack.copy();
this.stack.stackSize = 1;
}
}
/*
* (non-Javadoc)
*
* @see net.minecraft.src.buildcraft.api.gates.ITriggerParameter#writeToNBT(net.minecraft.src.NBTTagCompound)
*/
@Override
public void writeToNBT(NBTTagCompound compound) {
if (stack != null) {
compound.setInteger("itemID", stack.itemID);
compound.setInteger("itemDMG", stack.getItemDamage());
}
}
/*
* (non-Javadoc)
*
* @see net.minecraft.src.buildcraft.api.gates.ITriggerParameter#readFromNBT(net.minecraft.src.NBTTagCompound)
*/
@Override
public void readFromNBT(NBTTagCompound compound) {
int itemID = compound.getInteger("itemID");
if (itemID != 0) {
stack = new ItemStack(itemID, 1, compound.getInteger("itemDMG"));
}
}
/*
* (non-Javadoc)
*
* @see net.minecraft.src.buildcraft.api.gates.ITriggerParameter#getItem()
*/
@Override
public ItemStack getItem() {
return stack;
}
}

View file

@ -0,0 +1,23 @@
package buildcraft.api.inventory;
import net.minecraftforge.common.ForgeDirection;
public interface ISecuredInventory {
/**
* @param name
* @return true if the user/player with the given name has access permissions on this machine.
*/
boolean canAccess(String name);
/**
* Informs the inventory with whose permissions the next item or liquid transaction will be performed. It is up to the inventory to determine the effect.
*
* @param orientation
* Orientation the transaction will be performed from.
* @param name
* Name of the user/player who owns the transaction.
*/
void prepareTransaction(ForgeDirection orientation, String name);
}

View file

@ -0,0 +1,23 @@
package buildcraft.api.inventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.ForgeDirection;
public interface ISelectiveInventory extends ISpecialInventory {
/**
* Requests specified items to be extracted from the inventory
*
* @param desired
* Array which can contain ItemStacks, Items, or classes describing the type of item accepted or excluded.
* @param exclusion
* If true desired items are not eligible for returning.
* @param doRemove
* If false no actual extraction may occur.
* @param from
* Orientation the ItemStack is requested from.
* @param maxItemCount
* Maximum amount of items to extract (spread over all returned item stacks)
* @return Array of item stacks extracted from the inventory
*/
ItemStack[] extractItem(Object[] desired, boolean exclusion, boolean doRemove, ForgeDirection from, int maxItemCount);
}

View file

@ -0,0 +1,36 @@
package buildcraft.api.inventory;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.ForgeDirection;
public interface ISpecialInventory extends IInventory {
/**
* Offers an ItemStack for addition to the inventory.
*
* @param stack
* ItemStack offered for addition. Do not manipulate this!
* @param doAdd
* If false no actual addition should take place. Implementors should simulate.
* @param from
* Orientation the ItemStack is offered from.
* @return Amount of items used from the passed stack.
*/
int addItem(ItemStack stack, boolean doAdd, ForgeDirection from);
/**
* Requests items to be extracted from the inventory
*
* @param doRemove
* If false no actual extraction may occur. Implementors should simulate.
* Can be used to "peek" at what the result would be
* @param from
* Orientation the ItemStack is requested from.
* @param maxItemCount
* Maximum amount of items to extract (spread over all returned item stacks)
* @return Array of item stacks that were/would be extracted from the inventory
*/
ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount);
}

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) SpaceToad, 2011-2012
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.power;
import net.minecraftforge.common.ForgeDirection;
/**
* Essentially only used for Wooden Power Pipe connection rules.
*
* This Tile Entity interface allows you to indicate that a block can emit power from a specific
* side.
*
* @author CovertJaguar <http://www.railcraft.info/>
*/
public interface IPowerEmitter
{
public boolean canEmitPowerFrom(ForgeDirection side);
}

View file

@ -0,0 +1,46 @@
/**
* Copyright (c) SpaceToad, 2011 http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public License
* 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.power;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import buildcraft.api.power.PowerHandler.PowerReceiver;
/**
* This interface should be implemented by any Tile Entity that wishes to be able to receive power.
*
* @author CovertJaguar <http://www.railcraft.info/>
*/
public interface IPowerReceptor
{
/**
* Get the PowerReceiver for this side of the block. You can return the same PowerReceiver for
* all sides or one for each side.
*
* You should NOT return null to this method unless you mean to NEVER receive power from that
* side. Returning null, after previous returning a PowerReceiver, will most likely cause pipe
* connections to derp out and engines to eventually explode.
*
* @param side
* @return
*/
public PowerReceiver getPowerReceiver(ForgeDirection side);
/**
* Call back from the PowerHandler that is called when the stored power exceeds the activation
* power.
*
* It can be triggered by update() calls or power modification calls.
*
* @param workProvider
*/
public void doWork(PowerHandler workProvider);
public World getWorld();
}

View file

@ -0,0 +1,455 @@
/**
* Copyright (c) SpaceToad, 2011 http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public License
* 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.power;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.ForgeDirection;
import buildcraft.api.core.SafeTimeTracker;
public final class PowerHandler
{
public static enum Type
{
ENGINE, GATE, MACHINE, PIPE, STORAGE;
public boolean canReceiveFromPipes()
{
switch (this)
{
case MACHINE:
case STORAGE:
return true;
default:
return false;
}
}
public boolean eatsEngineExcess()
{
switch (this)
{
case MACHINE:
case STORAGE:
return true;
default:
return false;
}
}
}
public static class PerditionCalculator
{
public static final float DEFAULT_POWERLOSS = 1F;
public static final float MIN_POWERLOSS = 0.01F;
private final float powerLoss;
public PerditionCalculator()
{
powerLoss = DEFAULT_POWERLOSS;
}
public PerditionCalculator(float powerLoss)
{
if (powerLoss < MIN_POWERLOSS)
{
powerLoss = MIN_POWERLOSS;
}
this.powerLoss = powerLoss;
}
/**
* Apply the perdition algorithm to the current stored energy. This function can only be
* called once per tick, but it might not be called every tick. It is triggered by any
* manipulation of the stored energy.
*
* @param powerHandler the PowerHandler requesting the perdition update
* @param current the current stored energy
* @param ticksPassed ticks since the last time this function was called
* @return
*/
public float applyPerdition(PowerHandler powerHandler, float current, long ticksPassed)
{
current -= powerLoss * ticksPassed;
if (current < 0)
{
current = 0;
}
return current;
}
}
public static final PerditionCalculator DEFUALT_PERDITION = new PerditionCalculator();
private float minEnergyReceived;
private float maxEnergyReceived;
private float maxEnergyStored;
private float activationEnergy;
private float energyStored = 0;
private final SafeTimeTracker doWorkTracker = new SafeTimeTracker();
private final SafeTimeTracker sourcesTracker = new SafeTimeTracker();
private final SafeTimeTracker perditionTracker = new SafeTimeTracker();
public final int[] powerSources = new int[6];
public final IPowerReceptor receptor;
private PerditionCalculator perdition;
private final PowerReceiver receiver;
private final Type type;
public PowerHandler(IPowerReceptor receptor, Type type)
{
this.receptor = receptor;
this.type = type;
this.receiver = new PowerReceiver();
}
public PowerReceiver getPowerReceiver()
{
return receiver;
}
public float getMinEnergyReceived()
{
return minEnergyReceived;
}
public float getMaxEnergyReceived()
{
return maxEnergyReceived;
}
public float getMaxEnergyStored()
{
return maxEnergyStored;
}
public float getActivationEnergy()
{
return activationEnergy;
}
public float getEnergyStored()
{
return energyStored;
}
/**
* Setup your PowerHandler's settings.
*
* @param minEnergyReceived This is the minimum about of power that will be accepted by the
* PowerHandler. This should generally be greater than the activationEnergy if you plan to use
* the doWork() callback. Anything greater than 1 will prevent Redstone Engines from powering
* this Provider.
* @param maxEnergyReceived The maximum amount of power accepted by the PowerHandler. This
* should generally be less than 500. Too low and larger engines will overheat while trying to
* power the machine. Too high, and the engines will never warm up. Greater values also place
* greater strain on the power net.
* @param activationEnergy If the stored energy is greater than this value, the doWork()
* callback is called (once per tick).
* @param maxStoredEnergy The maximum amount of power this PowerHandler can store. Values tend
* to range between 100 and 5000. With 1000 and 1500 being common.
*/
public void configure(float minEnergyReceived, float maxEnergyReceived, float activationEnergy, float maxStoredEnergy)
{
if (minEnergyReceived > maxEnergyReceived)
{
maxEnergyReceived = minEnergyReceived;
}
this.minEnergyReceived = minEnergyReceived;
this.maxEnergyReceived = maxEnergyReceived;
this.maxEnergyStored = maxStoredEnergy;
this.activationEnergy = activationEnergy;
}
public void configurePowerPerdition(int powerLoss, int powerLossRegularity)
{
if (powerLoss == 0 || powerLossRegularity == 0)
{
perdition = new PerditionCalculator(0);
return;
}
perdition = new PerditionCalculator((float) powerLoss / (float) powerLossRegularity);
}
/**
* Allows you to define a new PerditionCalculator class to handler perdition calculations.
*
* For example if you want exponentially increasing loss bases on amount stored.
*
* @param perdition
*/
public void setPerdition(PerditionCalculator perdition)
{
this.perdition = perdition;
}
public PerditionCalculator getPerdition()
{
if (perdition == null)
return DEFUALT_PERDITION;
return perdition;
}
/**
* Ticks the power handler. You should call this if you can, but its not required.
*
* If you don't call it, the possibility exists for some weirdness with the perdition algorithm
* and work callback as its possible they will not be called on every tick they otherwise would
* be. You should be able to design around this though if you are aware of the limitations.
*/
public void update()
{
applyPerdition();
applyWork();
validateEnergy();
}
private void applyPerdition()
{
if (perditionTracker.markTimeIfDelay(receptor.getWorld(), 1) && energyStored > 0)
{
float newEnergy = getPerdition().applyPerdition(this, energyStored, perditionTracker.durationOfLastDelay());
if (newEnergy == 0 || newEnergy < energyStored)
{
energyStored = newEnergy;
}
else
{
energyStored = DEFUALT_PERDITION.applyPerdition(this, energyStored, perditionTracker.durationOfLastDelay());
}
validateEnergy();
}
}
private void applyWork()
{
if (energyStored >= activationEnergy)
{
if (doWorkTracker.markTimeIfDelay(receptor.getWorld(), 1))
{
receptor.doWork(this);
}
}
}
private void updateSources(ForgeDirection source)
{
if (sourcesTracker.markTimeIfDelay(receptor.getWorld(), 1))
{
for (int i = 0; i < 6; ++i)
{
powerSources[i] -= sourcesTracker.durationOfLastDelay();
if (powerSources[i] < 0)
{
powerSources[i] = 0;
}
}
}
if (source != null)
powerSources[source.ordinal()] = 10;
}
/**
* Extract energy from the PowerHandler. You must call this even if doWork() triggers.
*
* @param min
* @param max
* @param doUse
* @return amount used
*/
public float useEnergy(float min, float max, boolean doUse)
{
applyPerdition();
float result = 0;
if (energyStored >= min)
{
if (energyStored <= max)
{
result = energyStored;
if (doUse)
{
energyStored = 0;
}
}
else
{
result = max;
if (doUse)
{
energyStored -= max;
}
}
}
validateEnergy();
return result;
}
public void readFromNBT(NBTTagCompound data)
{
readFromNBT(data, "powerProvider");
}
public void readFromNBT(NBTTagCompound data, String tag)
{
NBTTagCompound nbt = data.getCompoundTag(tag);
energyStored = nbt.getFloat("storedEnergy");
}
public void writeToNBT(NBTTagCompound data)
{
writeToNBT(data, "powerProvider");
}
public void writeToNBT(NBTTagCompound data, String tag)
{
NBTTagCompound nbt = new NBTTagCompound();
nbt.setFloat("storedEnergy", energyStored);
data.setCompoundTag(tag, nbt);
}
public final class PowerReceiver
{
private PowerReceiver()
{
}
public float getMinEnergyReceived()
{
return minEnergyReceived;
}
public float getMaxEnergyReceived()
{
return maxEnergyReceived;
}
public float getMaxEnergyStored()
{
return maxEnergyStored;
}
public float getActivationEnergy()
{
return activationEnergy;
}
public float getEnergyStored()
{
return energyStored;
}
public Type getType()
{
return type;
}
public void update()
{
PowerHandler.this.update();
}
/**
* The amount of power that this PowerHandler currently needs.
*
* @return
*/
public float powerRequest()
{
return Math.min(maxEnergyReceived, maxEnergyStored - energyStored);
}
/**
* Add power to the PowerReceiver from an external source.
*
* @param quantity
* @param from
* @return the amount of power used
*/
public float receiveEnergy(Type source, final float quantity, ForgeDirection from)
{
float used = quantity;
if (source == Type.ENGINE)
{
if (used < minEnergyReceived)
{
return 0;
}
else if (used > maxEnergyReceived)
{
used = maxEnergyReceived;
}
}
updateSources(from);
used = addEnergy(used);
applyWork();
if (source == Type.ENGINE && type.eatsEngineExcess())
{
return Math.min(quantity, maxEnergyReceived);
}
return used;
}
}
/**
*
* @return the amount the power changed by
*/
public float addEnergy(float quantity)
{
energyStored += quantity;
if (energyStored > maxEnergyStored)
{
quantity -= energyStored - maxEnergyStored;
energyStored = maxEnergyStored;
}
else if (energyStored < 0)
{
quantity -= energyStored;
energyStored = 0;
}
applyPerdition();
return quantity;
}
public void setEnergy(float quantity)
{
this.energyStored = quantity;
validateEnergy();
}
public boolean isPowerSource(ForgeDirection from)
{
return powerSources[from.ordinal()] != 0;
}
private void validateEnergy()
{
if (energyStored < 0)
{
energyStored = 0;
}
if (energyStored > maxEnergyStored)
{
energyStored = maxEnergyStored;
}
}
}

View file

@ -0,0 +1,48 @@
package buildcraft.api.recipes;
import java.util.LinkedList;
import net.minecraft.item.ItemStack;
public class AssemblyRecipe {
public static LinkedList<AssemblyRecipe> assemblyRecipes = new LinkedList<AssemblyRecipe>();
public final ItemStack[] input;
public final ItemStack output;
public final float energy;
public AssemblyRecipe(ItemStack[] input, int energy, ItemStack output) {
this.input = input;
this.output = output;
this.energy = energy;
}
public boolean canBeDone(ItemStack[] items) {
for (ItemStack in : input) {
if (in == null) {
continue;
}
int found = 0; // Amount of ingredient found in inventory
for (ItemStack item : items) {
if (item == null) {
continue;
}
if (item.isItemEqual(in)) {
found += item.stackSize; // Adds quantity of stack to amount
// found
}
}
if (found < in.stackSize)
return false; // Return false if the amount of ingredient found
// is not enough
}
return true;
}
}

View file

@ -0,0 +1,126 @@
/**
* Copyright (c) SpaceToad, 2011 http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public License
* 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.recipes;
import com.google.common.base.Objects;
import java.util.Collections;
import java.util.SortedSet;
import java.util.TreeSet;
import net.minecraftforge.fluids.FluidStack;
public final class RefineryRecipes {
private static SortedSet<Recipe> recipes = new TreeSet<Recipe>();
public static void addRecipe(FluidStack ingredient, FluidStack result, int energy, int delay) {
addRecipe(ingredient, null, result, energy, delay);
}
public static void addRecipe(FluidStack ingredient1, FluidStack ingredient2, FluidStack result, int energy, int delay) {
Recipe recipe = new Recipe(ingredient1, ingredient2, result, energy, delay);
recipes.add(recipe);
}
public static SortedSet<Recipe> getRecipes() {
return Collections.unmodifiableSortedSet(recipes);
}
public static Recipe findRefineryRecipe(FluidStack liquid1, FluidStack liquid2) {
for (Recipe recipe : recipes) {
if (recipe.matches(liquid1, liquid2))
return recipe;
}
return null;
}
private RefineryRecipes() {
}
public static final class Recipe implements Comparable<Recipe> {
public final FluidStack ingredient1;
public final FluidStack ingredient2;
public final FluidStack result;
public final int energy;
public final int delay;
private Recipe(FluidStack ingredient1, FluidStack ingredient2, FluidStack result, int energy, int delay) {
if (ingredient1 == null)
throw new IllegalArgumentException("First Ingredient cannot be null!");
this.ingredient1 = ingredient1;
this.ingredient2 = ingredient2;
this.result = result;
this.energy = energy;
this.delay = delay;
}
public boolean matches(FluidStack liquid1, FluidStack liquid2) {
// No inputs, return.
if (liquid1 == null && liquid2 == null)
return false;
// Return if two ingredients are required but only one was supplied.
if ((ingredient1 != null && ingredient2 != null) && (liquid1 == null || liquid2 == null))
return false;
if (liquid1 != null && liquid2 != null) {
if (liquid1.containsFluid(ingredient1) && liquid1.containsFluid(ingredient2))
return true;
if (liquid1.containsFluid(ingredient2) && liquid1.containsFluid(ingredient1))
return true;
}
if (liquid1 != null)
return liquid1.containsFluid(ingredient1) || liquid1.containsFluid(ingredient2);
if (liquid2 != null)
return liquid2.containsFluid(ingredient1) || liquid2.containsFluid(ingredient2);
return false;
}
// Compares to only the types of source materials.
// We consider non-null < null in order that one-ingredient recipe is checked after
// the failure of matching two-ingredient recipes which include that liquid.
@Override
public int compareTo(Recipe other) {
if (other == null)
return -1;
else if (ingredient1.getFluid() != other.ingredient1.getFluid())
return ingredient1.getFluid().getName().compareTo(other.ingredient1.getFluid().getName());
else if (ingredient1.amount != other.ingredient1.amount)
return other.ingredient1.amount - ingredient1.amount;
else if (ingredient2 == null)
return other.ingredient2 == null ? 0 : 1;
else if (other.ingredient2 == null)
return -1;
else if (ingredient2.getFluid() != other.ingredient2.getFluid())
return ingredient2.getFluid().getName().compareTo(other.ingredient2.getFluid().getName());
else if (ingredient2.amount != other.ingredient2.amount)
return other.ingredient2.amount - ingredient2.amount;
return 0;
}
// equals() should be consistent with compareTo().
@Override
public boolean equals(Object obj) {
return obj instanceof Recipe
&& Objects.equal(ingredient1, ((Recipe) obj).ingredient1)
&& Objects.equal(ingredient2, ((Recipe) obj).ingredient2);
}
// hashCode() should be overridden because equals() was overridden.
@Override
public int hashCode() {
return Objects.hashCode(ingredient1, ingredient2);
}
}
}

View file

@ -0,0 +1,40 @@
package buildcraft.api.tools;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
public interface IToolPipette {
/**
* @param pipette
* ItemStack of the pipette.
* @return Capacity of the pipette.
*/
int getCapacity(ItemStack pipette);
/**
* @param pipette
* @return true if the pipette can pipette.
*/
boolean canPipette(ItemStack pipette);
/**
* Fills the pipette with the given liquid stack.
*
* @param pipette
* @param liquid
* @param doFill
* @return Amount of liquid used in filling the pipette.
*/
int fill(ItemStack pipette, FluidStack liquid, boolean doFill);
/**
* Drains liquid from the pipette
*
* @param pipette
* @param maxDrain
* @param doDrain
* @return Fluid stack representing the liquid and amount drained from the pipette.
*/
FluidStack drain(ItemStack pipette, int maxDrain, boolean doDrain);
}

View file

@ -0,0 +1,32 @@
package buildcraft.api.tools;
import net.minecraft.entity.player.EntityPlayer;
/***
* Implement this interface on subclasses of Item to have that item work as a wrench for buildcraft
*/
public interface IToolWrench {
/***
* Called to ensure that the wrench can be used. To get the ItemStack that is used, check player.inventory.getCurrentItem()
*
* @param player
* - The player doing the wrenching
* @param x
* ,y,z - The coordinates for the block being wrenched
*
* @return true if wrenching is allowed, false if not
*/
public boolean canWrench(EntityPlayer player, int x, int y, int z);
/***
* Callback after the wrench has been used. This can be used to decrease durability or for other purposes. To get the ItemStack that was used, check
* player.inventory.getCurrentItem()
*
* @param player
* - The player doing the wrenching
* @param x
* ,y,z - The coordinates of the block being wrenched
*/
public void wrenchUsed(EntityPlayer player, int x, int y, int z);
}

View file

@ -0,0 +1,25 @@
package buildcraft.api.transport;
import java.lang.reflect.Method;
import net.minecraft.item.ItemStack;
/**
* You can use this if you wish, but FML InterModComms are recommended.
*
* SYNTAX: add-facade:id@meta
*/
public class FacadeManager {
private static Method addFacade;
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void addFacade(ItemStack is) {
try {
if (addFacade == null) {
Class facade = Class.forName("buildcraft.transport.ItemFacade");
addFacade = facade.getMethod("addFacade", ItemStack.class);
}
addFacade.invoke(null, is);
} catch (Exception ex) {
}
}
}

View file

@ -0,0 +1,21 @@
package buildcraft.api.transport;
import net.minecraft.world.World;
/**
* Implement and register with the PipeManager if you want to suppress connections from wooden pipes.
*/
public interface IExtractionHandler {
/**
* Can this pipe extract items from the block located at these coordinates?
* param extractor can be null
*/
boolean canExtractItems(Object extractor, World world, int i, int j, int k);
/**
* Can this pipe extract liquids from the block located at these coordinates?
* param extractor can be null
*/
boolean canExtractFluids(Object extractor, World world, int i, int j, int k);
}

View file

@ -0,0 +1,20 @@
/**
* Copyright (c) SpaceToad, 2012
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.transport;
import net.minecraft.nbt.NBTTagCompound;
public interface IPassiveItemContribution {
public void readFromNBT(NBTTagCompound nbttagcompound);
public void writeToNBT(NBTTagCompound nbttagcompound);
}

View file

@ -0,0 +1,45 @@
/**
* Copyright (c) SpaceToad, 2011
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.transport;
import net.minecraft.tileentity.TileEntity;
public interface IPipe {
enum DrawingState {
DrawingPipe, DrawingRedWire, DrawingBlueWire, DrawingGreenWire, DrawingYellowWire, DrawingGate
}
enum WireColor {
Red, Blue, Green, Yellow;
public WireColor reverse() {
switch (this) {
case Red:
return Yellow;
case Blue:
return Green;
case Green:
return Blue;
default:
return Red;
}
}
}
public boolean isWired(WireColor color);
public boolean hasInterface();
public TileEntity getContainer();
public boolean isWireConnectedTo(TileEntity tile, WireColor color);
}

View file

@ -0,0 +1,17 @@
/**
* Copyright (c) SpaceToad, 2011
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.transport;
import net.minecraftforge.common.ForgeDirection;
public interface IPipeConnection {
public boolean isPipeConnected(ForgeDirection with);
}

View file

@ -0,0 +1,26 @@
/**
* Copyright (c) SpaceToad, 2011
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.transport;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.ForgeDirection;
/**
* Interface used to put objects into pipes, implemented by pipe tile entities.
*/
public interface IPipeEntry {
void entityEntering(ItemStack payload, ForgeDirection orientation);
void entityEntering(IPipedItem item, ForgeDirection orientation);
boolean acceptItems();
}

View file

@ -0,0 +1,17 @@
/**
* Copyright (c) SpaceToad, 2011
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.transport;
public interface IPipeTile {
IPipe getPipe();
boolean isInitialized();
}

View file

@ -0,0 +1,90 @@
package buildcraft.api.transport;
import buildcraft.api.core.Position;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
public interface IPipedItem {
public abstract void remove();
/* GETTING & SETTING */
public abstract void setWorld(World world);
public abstract Position getPosition();
public abstract void setPosition(double x, double y, double z);
/**
* @return the speed
*/
public abstract float getSpeed();
/**
* @param speed
* the speed to set
*/
public abstract void setSpeed(float speed);
/**
* @return the item
*/
public abstract ItemStack getItemStack();
/**
* @param item
* the item to set
*/
public abstract void setItemStack(ItemStack item);
/**
* @return the container
*/
public abstract TileEntity getContainer();
/**
* @param container
* the container to set
*/
public abstract void setContainer(TileEntity container);
/**
* @return the entityId
*/
public abstract int getEntityId();
/**
* @param entityId
* the entityId to set
*/
public abstract void setEntityId(int entityId);
/* SAVING & LOADING */
public abstract void readFromNBT(NBTTagCompound nbttagcompound);
public abstract void writeToNBT(NBTTagCompound nbttagcompound);
public abstract EntityItem toEntityItem(ForgeDirection dir);
public abstract float getEntityBrightness(float f);
public abstract boolean isCorrupted();
public abstract void addContribution(String key, IPassiveItemContribution contribution);
public abstract IPassiveItemContribution getContribution(String key);
public abstract boolean hasContributions();
/**
* @return the can this item be moved into this specific entity type.
* (basic BuildCraft PipedItems always return true)
*/
public abstract boolean canSinkTo(TileEntity entity);
}

View file

@ -0,0 +1,7 @@
package buildcraft.api.transport;
import net.minecraftforge.common.ForgeDirection;
public interface ISolidSideTile {
public boolean isSolidOnSide(ForgeDirection side);
}

View file

@ -0,0 +1,36 @@
package buildcraft.api.transport;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.world.World;
public abstract class PipeManager {
public static List<IExtractionHandler> extractionHandlers = new ArrayList<IExtractionHandler>();
public static void registerExtractionHandler(IExtractionHandler handler) {
extractionHandlers.add(handler);
}
/**
* param extractor can be null
*/
public static boolean canExtractItems(Object extractor, World world, int i, int j, int k) {
for (IExtractionHandler handler : extractionHandlers)
if (!handler.canExtractItems(extractor, world, i, j, k))
return false;
return true;
}
/**
* param extractor can be null
*/
public static boolean canExtractFluids(Object extractor, World world, int i, int j, int k) {
for (IExtractionHandler handler : extractionHandlers)
if (!handler.canExtractFluids(extractor, world, i, j, k))
return false;
return true;
}
}

View file

@ -0,0 +1,163 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computer.api;
import java.lang.reflect.Method;
import net.minecraft.world.World;
/**
* The static entry point to the ComputerCraft API.
* Members in this class must be called after mod_ComputerCraft has been initialised,
* but may be called before it is fully loaded.
*/
public class ComputerCraftAPI
{
/**
* Creates a numbered directory in a subfolder of the save directory for a given world, and returns that number.<br>
* Use in conjuction with createSaveDirMount() to create a unique place for your peripherals or media items to store files.<br>
* @param world The world for which the save dir should be created. This should be the serverside world object.
* @param parentSubPath The folder path within the save directory where the new directory should be created. eg: "computer/disk"
* @return The numerical value of the name of the new folder, or -1 if the folder could not be created for some reason.<br>
* eg: if createUniqueNumberedSaveDir( world, "computer/disk" ) was called returns 42, then "computer/disk/42" is now available for writing.
* @see #createSaveDirMount(World, String)
*/
public static int createUniqueNumberedSaveDir( World world, String parentSubPath )
{
findCC();
if( computerCraft_createUniqueNumberedSaveDir != null )
{
try {
return ((Integer)computerCraft_createUniqueNumberedSaveDir.invoke( null, world, parentSubPath )).intValue();
} catch (Exception e){
// It failed
}
}
return -1;
}
/**
* Creates a file system mount that maps to a subfolder of the save directory for a given world, and returns it.<br>
* Use in conjuction with IComputerAccess.mount() or IComputerAccess.mountWritable() to mount a folder from the
* users save directory onto a computers file system.<br>
* @param world The world for which the save dir can be found. This should be the serverside world object.
* @param subPath The folder path within the save directory that the mount should map to. eg: "computer/disk/42".<br>
* Use createUniqueNumberedSaveDir() to create a new numbered folder to use.
* @param capacity The ammount of data that can be stored in the directory before it fills up, in bytes.
* @return The mount, or null if it could be created for some reason. Use IComputerAccess.mount() or IComputerAccess.mountWritable()
* to mount this on a Computers' file system.
* @see #createUniqueNumberedSaveDir(World, String)
* @see IComputerAccess#mount(String, IMount)
* @see IComputerAccess#mountWritable(String, IWritableMount)
* @see IMount
* @see IMountWritable
*/
public static IWritableMount createSaveDirMount( World world, String subPath, long capacity )
{
findCC();
if( computerCraft_createSaveDirMount != null )
{
try {
return (IWritableMount)computerCraft_createSaveDirMount.invoke( null, world, subPath, capacity );
} catch (Exception e){
// It failed
}
}
return null;
}
/**
* Creates a file system mount to a resource folder, and returns it.<br>
* Use in conjuction with IComputerAccess.mount() or IComputerAccess.mountWritable() to mount a resource folder onto a computers file system.<br>
* The files in this mount will be a combination of files in the specified mod jar, and resource packs that contain resources with the same domain and path.<br>
* @param class A class in whose jar to look first for the resources to mount. Using your main mod class is recommended. eg: MyMod.class
* @param domain The domain under which to look for resources. eg: "mymod"
* @param subPath The domain under which to look for resources. eg: "mymod/lua/myfiles"
* @return The mount, or null if it could be created for some reason. Use IComputerAccess.mount() or IComputerAccess.mountWritable()
* to mount this on a Computers' file system.
* @see IComputerAccess#mount(String, IMount)
* @see IComputerAccess#mountWritable(String, IMountWritable)
* @see IMount
*/
public static IMount createResourceMount( Class modClass, String domain, String subPath )
{
findCC();
if( computerCraft_createResourceMount != null )
{
try {
return (IMount)computerCraft_createResourceMount.invoke( null, modClass, domain, subPath );
} catch (Exception e){
// It failed
}
}
return null;
}
/**
* Registers a peripheral handler for a TileEntity that you do not have access to. Only
* use this if you want to expose IPeripheral on a TileEntity from another mod. For your own
* mod, just implement IPeripheral on the TileEntity directly.
* @see IPeripheral
* @see IPeripheralHandler
*/
public static void registerExternalPeripheral( Class <? extends net.minecraft.tileentity.TileEntity> clazz, IPeripheralHandler handler )
{
findCC();
if (computerCraft_registerExternalPeripheral != null)
{
try {
computerCraft_registerExternalPeripheral.invoke(null, clazz, handler);
} catch (Exception e){
// It failed
}
}
}
// The functions below here are private, and are used to interface with the non-API ComputerCraft classes.
// Reflection is used here so you can develop your mod in MCP without decompiling ComputerCraft and including
// it in your solution.
private static void findCC()
{
if( !ccSearched ) {
try {
computerCraft = Class.forName( "dan200.ComputerCraft" );
computerCraft_createUniqueNumberedSaveDir = findCCMethod( "createUniqueNumberedSaveDir", new Class[] {
World.class, String.class
} );
computerCraft_createSaveDirMount = findCCMethod( "createSaveDirMount", new Class[] {
World.class, String.class, Long.TYPE
} );
computerCraft_createResourceMount = findCCMethod( "createResourceMount", new Class[] {
Class.class, String.class, String.class
} );
computerCraft_registerExternalPeripheral = findCCMethod( "registerExternalPeripheral", new Class[] {
Class.class, IPeripheralHandler.class
} );
} catch( Exception e ) {
net.minecraft.server.MinecraftServer.getServer().logInfo( "ComputerCraftAPI: ComputerCraft not found." );
} finally {
ccSearched = true;
}
}
}
private static Method findCCMethod( String name, Class[] args )
{
try {
return computerCraft.getMethod( name, args );
} catch( NoSuchMethodException e ) {
net.minecraft.server.MinecraftServer.getServer().logInfo( "ComputerCraftAPI: ComputerCraft method " + name + " not found." );
return null;
}
}
private static boolean ccSearched = false;
private static Class computerCraft = null;
private static Method computerCraft_createUniqueNumberedSaveDir = null;
private static Method computerCraft_createSaveDirMount = null;
private static Method computerCraft_createResourceMount = null;
private static Method computerCraft_registerExternalPeripheral = null;
}

View file

@ -0,0 +1,89 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computer.api;
/**
* The interface passed to peripherals by computers or turtles, providing methods
* that they can call. This should not be implemented by your classes. Do not interact
* with computers except via this interface.
*/
public interface IComputerAccess
{
/**
* Mount a mount onto the computers' file system in a read only mode.<br>
* @param desiredLoction The location on the computer's file system where you would like the mount to be mounted.
* @param mount The mount object to mount on the computer. These can be obtained by calling ComputerCraftAPI.createSaveDirMount(), ComputerCraftAPI.createResourceMount() or by creating your own objects that implement the IMount interface.
* @return The location on the computer's file system where you the mount was actually mounted, this may be different from desiredLocation if there was already a file in the desired location. Store this value if you wish to unmount the mount later.
* @see ComputerCraftAPI#createSaveDirMount(World, String)
* @see ComputerCraftAPI#createResourceMount(Class, String, String)
* @see #mountWritable(String, IWritableMount)
* @see #unmount(String)
* @see IMount
*/
public String mount( String desiredLocation, IMount mount );
/**
* Mount a mount onto the computers' file system in a writable mode.<br>
* @param desiredLoction The location on the computer's file system where you would like the mount to be mounted.
* @param mount The mount object to mount on the computer. These can be obtained by calling ComputerCraftAPI.createSaveDirMount() or by creating your own objects that implement the IWritableMount interface.
* @return The location on the computer's file system where you the mount was actually mounted, this may be different from desiredLocation if there was already a file in the desired location. Store this value if you wish to unmount the mount later.
* @see ComputerCraftAPI#createSaveDirMount(World, String)
* @see ComputerCraftAPI#createResourceMount(Class, String, String)
* @see #mount(String, IMount)
* @see #unmount(String)
* @see IMount
*/
public String mountWritable( String desiredLocation, IWritableMount mount );
/**
* Unmounts a directory previously mounted onto the computers file system by mount() or mountWritable().<br>
* When a directory is unmounted, it will disappear from the computers file system, and the user will no longer be able to
* access it. All directories mounted by a mount or mountWritable are automatically unmounted when the peripheral
* is attached if they have not been explicitly unmounted.
* @param location The desired location in the computers file system of the directory to unmount.
* This must be the location of a directory previously mounted by mount() or mountWritable(), as
* indicated by their return value.
* @see #mount(String, IMount)
* @see #mountWritable(String, IWritableMount)
*/
public void unmount( String location );
/**
* Returns the numerical ID of this computer.<br>
* This is the same number obtained by calling os.getComputerID() or running the "id" program from lua,
* and is guarunteed unique. This number will be positive.
* @return The identifier.
*/
public int getID();
/**
* Causes an event to be raised on this computer, which the computer can respond to by calling
* os.pullEvent(). This can be used to notify the computer when things happen in the world or to
* this peripheral.
* @param event A string identifying the type of event that has occurred, this will be
* returned as the first value from os.pullEvent(). It is recommended that you
* you choose a name that is unique, and recognisable as originating from your
* peripheral. eg: If your peripheral type is "button", a suitable event would be
* "button_pressed".
* @param arguments In addition to a name, you may pass an array of extra arguments to the event, that will
* be supplied as extra return values to os.pullEvent(). Objects in the array will be converted
* to lua data types in the same fashion as the return values of IPeripheral.callMethod().<br>
* You may supply null to indicate that no arguments are to be supplied.
* @see IPeripheral#callMethod
*/
public void queueEvent( String event, Object[] arguments );
/**
* Get a string, unique to the computer, by which the computer refers to this peripheral.
* For directly attached peripherals this will be "left","right","front","back",etc, but
* for peripherals attached remotely it will be different. It is good practice to supply
* this string when raising events to the computer, so that the computer knows from
* which peripheral the event came.
* @return A string unique to the computer, but not globally.
*/
public String getAttachmentName();
}

View file

@ -0,0 +1,44 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computer.api;
import dan200.computer.api.IPeripheral;
/**
* A subclass of IPeripheral specifically for peripherals
* created by ITurtleUpgrade's of type Peripheral. When an
* IHostedPeripheral is created, its IPeripheral methods will be called
* just as if the peripheral was a seperate adjacent block in the world,
* and update() will be called once per tick.
* @see ITurtleUpgrade
*/
public interface IHostedPeripheral extends IPeripheral
{
/**
* A method called on each hosted peripheral once per tick, on the main thread
* over the lifetime of the turtle or block. May be used to update the state
* of the peripheral, and may interact with IComputerAccess or ITurtleAccess
* however it likes at this time.
*/
public void update();
/**
* A method called whenever data is read from the Turtle's NBTTag,
* over the lifetime of the turtle. You should only use this for
* reading data you want to stay with the peripheral.
* @param nbttagcompound The peripheral's NBTTag
*/
public void readFromNBT( net.minecraft.nbt.NBTTagCompound nbttagcompound );
/**
* A method called whenever data is written to the Turtle's NBTTag,
* over the lifetime of the turtle. You should only use this for
* writing data you want to stay with the peripheral.
* @param nbttagcompound The peripheral's NBTTag.
* @param ID The turtle's ID.
*/
public void writeToNBT( net.minecraft.nbt.NBTTagCompound nbttagcompound );
}

View file

@ -0,0 +1,45 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computer.api;
/**
* An interface passed to peripherals and ILuaObjects' by computers or turtles, providing methods
* that allow the peripheral call to wait for events before returning, just like in lua.
* This is very useful if you need to signal work to be performed on the main thread, and don't want to return
* until the work has been completed.
*/
public interface ILuaContext
{
/**
* Wait for an event to occur on the computer, suspending the thread until it arises. This method is exactly equivalent to os.pullEvent() in lua.
* @param filter A specific event to wait for, or null to wait for any event
* @return An object array containing the name of the event that occurred, and any event parameters
* @throws Exception If the user presses CTRL+T to terminate the current program while pullEvent() is waiting for an event, a "Terminated" exception will be thrown here.
* Do not attempt to block this exception, unless you wish to prevent termination, which is not recommended.
* @throws InterruptedException If the user shuts down or reboots the computer while pullEvent() is waiting for an event, InterruptedException will be thrown. This exception must not be caught or intercepted, or the computer will leak memory and end up in a broken state.
*/
public Object[] pullEvent( String filter ) throws Exception, InterruptedException;
/**
* The same as pullEvent(), except "terminated" events are ignored. Only use this if you want to prevent program termination, which is not recommended. This method is exactly equivalent to os.pullEventRaw() in lua.
* @param filter A specific event to wait for, or null to wait for any event
* @return An object array containing the name of the event that occurred, and any event parameters
* @throws InterruptedException If the user shuts down or reboots the computer while pullEventRaw() is waiting for an event, InterruptedException will be thrown. This exception must not be caught or intercepted, or the computer will leak memory and end up in a broken state.
* @see #pullEvent(String)
*/
public Object[] pullEventRaw( String filter ) throws InterruptedException;
/**
* Yield the current coroutine with some arguments until it is resumed. This method is exactly equivalent to coroutine.yield() in lua. Use pullEvent() if you wish to wait for events.
* @param arguments An object array containing the arguments to pass to coroutine.yield()
* @return An object array containing the return values from coroutine.yield()
* @throws InterruptedException If the user shuts down or reboots the computer the coroutine is suspended, InterruptedException will be thrown. This exception must not be caught or intercepted, or the computer will leak memory and end up in a broken state.
* @see #pullEvent(String)
*/
public Object[] yield( Object[] arguments ) throws InterruptedException;
}

View file

@ -0,0 +1,26 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computer.api;
/**
* An interface for representing custom objects returned by IPeripheral.callMethod() calls.
* Return objects implementing this interface to expose objects with methods to lua.
*/
public interface ILuaObject
{
/**
* Get the names of the methods that this object implements. This works the same as IPeripheral.getMethodNames(). See that method for detailed documentation.
* @see IPeripheral#getMethodNames()
*/
public String[] getMethodNames();
/**
* Called when a user calls one of the methods that this object implements. This works the same as IPeripheral.callMethod(). See that method for detailed documentation.
* @see IPeripheral#callMethod(IComputerAccess, ILuaContext, int, Object[])
*/
public Object[] callMethod( ILuaContext context, int method, Object[] arguments ) throws Exception;
}

View file

@ -0,0 +1,57 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computer.api;
import net.minecraft.world.World;
import net.minecraft.item.ItemStack;
/**
* Represents an item that can be placed in a disk drive and used by a Computer.
* Implement this interface on your Item class to allow it to be used in the drive.
*/
public interface IMedia
{
/**
* Get a string representing the label of this item. Will be called vi disk.getLabel() in lua.
* @param stack The itemstack to inspect
* @return The label. ie: "Dan's Programs"
*/
public String getLabel( ItemStack stack );
/**
* Set a string representing the label of this item. Will be called vi disk.setLabel() in lua.
* @param stack The itemstack to modify.
* @param label The string to set the label to.
* @return true if the label was updated, false if the label may not be modified.
*/
public boolean setLabel( ItemStack stack, String label );
/**
* If this disk represents an item with audio (like a record), get the readable name of the audio track. ie: "Jonathon Coulton - Still Alive"
* @param stack The itemstack to inspect.
* @return The name, or null if this item does not represent an item with audio.
*/
public String getAudioTitle( ItemStack stack );
/**
* If this disk represents an item with audio (like a record), get the resource name of the audio track to play.
* @param stack The itemstack to inspect.
* @return The name, or null if this item does not represent an item with audio.
*/
public String getAudioRecordName( ItemStack stack );
/**
* If this disk represents an item with data (like a floppy disk), get a mount representing it's contents. This will be mounted onto the filesystem of the computer while the media is in the disk drive.
* @param stack The itemstack to inspect.
* @param world The world in which the item and disk drive reside.
* @return The mount, or null if this item does not represent an item with data. If the IMount returned also implements IWritableMount, it will mounted using mountWritable()
* @see IMount
* @see IWritableMount
* @see ComputerCraftAPI#createSaveDirMount(World, String)
* @see ComputerCraftAPI#createResourceMount(Class, String, String)
*/
public IMount createDataMount( ItemStack stack, World world );
}

View file

@ -0,0 +1,57 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computer.api;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* Represents a read only part of a virtual filesystem that can be mounted onto a computer using IComputerAccess.mount().
* Ready made implementations of this interface can be created using ComputerCraftAPI.createSaveDirMount() or ComputerCraftAPI.createResourceMount(), or you're free to implement it yourselves!
* @see ComputerCraftAPI#createSaveDirMount(World, String)
* @see ComputerCraftAPI#createResourceMount(Class, String, String)
* @see IComputerAccess#mount(String, IMount)
* @see IWritableMount
*/
public interface IMount
{
/**
* Returns whether a file with a given path exists or not.
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram"
* @return true if the file exists, false otherwise
*/
public boolean exists( String path ) throws IOException;
/**
* Returns whether a file with a given path is a directory or not.
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprograms"
* @return true if the file exists and is a directory, false otherwise
*/
public boolean isDirectory( String path ) throws IOException;
/**
* Returns the file names of all the files in a directory.
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprograms"
* @param contents A list of strings. Add all the file names to this list
*/
public void list( String path, List<String> contents ) throws IOException;
/**
* Returns the size of a file with a given path, in bytes
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram"
* @return the size of the file, in bytes
*/
public long getSize( String path ) throws IOException;
/**
* Opens a file with a given path, and returns an inputstream representing it's contents.
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram"
* @return a stream representing the contents of the file
*/
public InputStream openForRead( String path ) throws IOException;
}

View file

@ -0,0 +1,106 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computer.api;
/**
* The interface that defines a peripheral. This should be implemented by the
* TileEntity of any block that you wish to be interacted with by
* computer or turtle.
*/
public interface IPeripheral
{
/**
* Should return a string that uniquely identifies this type of peripheral.
* This can be queried from lua by calling peripheral.getType()
* @return A string identifying the type of peripheral.
*/
public String getType();
/**
* Should return an array of strings that identify the methods that this
* peripheral exposes to Lua. This will be called once before each attachment,
* and should not change when called multiple times.
* @return An array of strings representing method names.
* @see #callMethod
*/
public String[] getMethodNames();
/**
* This is called when a lua program on an attached computer calls peripheral.call() with
* one of the methods exposed by getMethodNames().<br>
* <br>
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
* when interacting with minecraft objects.
* @param computer The interface to the computer that is making the call. Remember that multiple
* computers can be attached to a peripheral at once.
* @param context The context of the currently running lua thread. This can be used to wait for events
* or otherwise yield.
* @param method An integer identifying which of the methods from getMethodNames() the computer
* wishes to call. The integer indicates the index into the getMethodNames() table
* that corresponds to the string passed into peripheral.call()
* @param arguments An array of objects, representing the arguments passed into peripheral.call().<br>
* Lua values of type "string" will be represented by Object type String.<br>
* Lua values of type "number" will be represented by Object type Double.<br>
* Lua values of type "boolean" will be represented by Object type Boolean.<br>
* Lua values of any other type will be represented by a null object.<br>
* This array will be empty if no arguments are passed.
* @return An array of objects, representing values you wish to return to the lua program.<br>
* Integers, Doubles, Floats, Strings, Booleans and null be converted to their corresponding lua type.<br>
* All other types will be converted to nil.<br>
* You may return null to indicate no values should be returned.
* @throws Exception If you throw any exception from this function, a lua error will be raised with the
* same message as your exception. Use this to throw appropriate errors if the wrong
* arguments are supplied to your method.
* @see #getMethodNames
*/
public Object[] callMethod( IComputerAccess computer, ILuaContext context, int method, Object[] arguments ) throws Exception;
/**
* Is called before the computer attempts to attach to the peripheral, and should return whether to allow
* the attachment. Use this to restrict the number of computers that can attach, or to limit attachments to
* certain world directions.<br>
* If true is returned, attach() will be called shortly afterwards, and the computer will be able to make method calls.
* If false is returned, attach() will not be called, and the peripheral will be invisible to the computer.
* @param side The world direction (0=bottom, 1=top, etc) that the computer lies relative to the peripheral.
* @return Whether to allow the attachment, as a boolean.
* @see #attach
*/
public boolean canAttachToSide( int side );
/**
* Is called when canAttachToSide has returned true, and a computer is attaching to the peripheral.
* This will occur when a peripheral is placed next to an active computer, when a computer is turned on next to a peripheral,
* or when a turtle travels into a square next to a peripheral.
* Between calls to attach() and detach(), the attached computer can make method calls on the peripheral using peripheral.call().
* This method can be used to keep track of which computers are attached to the peripheral, or to take action when attachment
* occurs.<br>
* <br>
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
* when interacting with minecraft objects.
* @param computer The interface to the computer that is being attached. Remember that multiple
* computers can be attached to a peripheral at once.
* @see #canAttachToSide
* @see #detach
*/
public void attach( IComputerAccess computer );
/**
* Is called when a computer is detaching from the peripheral.
* This will occur when a computer shuts down, when the peripheral is removed while attached to computers,
* or when a turtle moves away from a square attached to a peripheral.
* This method can be used to keep track of which computers are attached to the peripheral, or to take action when detachment
* occurs.<br>
* <br>
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
* when interacting with minecraft objects.
* @param computer The interface to the computer that is being detached. Remember that multiple
* computers can be attached to a peripheral at once.
* @see #canAttachToSide
* @see #detach
*/
public void detach( IComputerAccess computer );
}

View file

@ -0,0 +1,15 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computer.api;
/**
* TODO: Document me
*/
public interface IPeripheralHandler
{
public IHostedPeripheral getPeripheral( net.minecraft.tileentity.TileEntity tile );
}

View file

@ -0,0 +1,53 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computer.api;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
/**
* Represents a part of a virtual filesystem that can be mounted onto a computer using IComputerAccess.mount() or IComputerAccess.mountWritable(), that can also be written to.
* Ready made implementations of this interface can be created using ComputerCraftAPI.createSaveDirMount(), or you're free to implement it yourselves!
* @see ComputerCraftAPI#createSaveDirMount(World, String)
* @see IComputerAccess#mountWritable(String, IMount)
* @see IMount
*/
public interface IWritableMount extends IMount
{
/**
* Creates a directory at a given path inside the virtual file system.
* @param path A file path in normalised format, relative to the mount location. ie: "programs/mynewprograms"
*/
public void makeDirectory( String path ) throws IOException;
/**
* Deletes a directory at a given path inside the virtual file system.
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myoldprograms"
*/
public void delete( String path ) throws IOException;
/**
* Opens a file with a given path, and returns an outputstream for writing to it.
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram"
* @return a stream for writing to
*/
public OutputStream openForWrite( String path ) throws IOException;
/**
* Opens a file with a given path, and returns an outputstream for appending to it.
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram"
* @return a stream for writing to
*/
public OutputStream openForAppend( String path ) throws IOException;
/**
* Get the ammount of free space on the mount, in bytes. You should decrease this value as the user writes to the mount, and write operations should fail once it reaches zero.
* @return The ammount of free space, in bytes.
*/
public long getRemainingSpace() throws IOException;
}

View file

@ -0,0 +1,158 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.turtle.api;
import dan200.computer.api.*;
/**
* The interface passed to upgrades by turtles, providing methods that they can call.
* This should not be implemented by your classes. Do not interact with turtles except via this interface and ITurtleUpgrade.
*/
public interface ITurtleAccess
{
/**
* Returns the world in which the turtle resides.
* @return the world in which the turtle resides.
*/
public net.minecraft.world.World getWorld();
/**
* Returns a vector containing the integer block co-ordinates at which the turtle resides.
* @return a vector containing the integer block co-ordinates at which the turtle resides.
*/
public net.minecraft.util.Vec3 getPosition();
/**
* Returns a vector containing the co-ordinates at which the turtle is rendered.
* This will shift when the turtle is moving.
* @param f The subframe fraction
* @return a vector containing the integer block co-ordinates at which the turtle resides.
*/
public net.minecraft.util.Vec3 getVisualPosition( float f );
/**
* Returns the world direction the turtle is currently facing.
* @return the world direction the turtle is currently facing.
*/
public int getFacingDir();
/**
* Returns the size of the turtles inventory, in number of slots. This will currently always be 16.
* @return the size of the turtles inventory, in number of slots. This will currently always be 16.
*/
public int getInventorySize();
/**
* Returns which slot the turtle currently has selected in its inventory using turtle.select().
* Unlike the 1-based lua representation, this will be between 0 and getInventorySize() - 1.
* @return which slot the turtle currently has selected in its inventory
*/
public int getSelectedSlot();
/**
* Returns the item stack that the turtle has in one of its inventory slots.
* @param index which inventory slot to retreive, should be between 0 and getInventorySize() - 1
* @return the item stack that the turtle has in one of its inventory slots. May be null.
*/
public net.minecraft.item.ItemStack getSlotContents( int index );
/**
* Changes the item stack that the turtle has in one of its inventory slots.
* @param index which inventory slot to change, should be between 0 and getInventorySize() - 1
* @param stack an item stack to put in the slot. May be null.
*/
public void setSlotContents( int index, net.minecraft.item.ItemStack stack );
/**
* Tries to store an item stack into the turtles current inventory, starting from the turtles
* currently selected inventory slot.
* @param stack The item stack to try and store.
* @return true if the stack was completely stored in the inventory, false if
* it was only partially stored, or could not fit at all. If false is returned
* and the stack was partially stored, the ItemStack passed into "stack" will now
* represent the stack of items that is left over.
*/
public boolean storeItemStack( net.minecraft.item.ItemStack stack );
/**
* Drops an item stack from the turtle onto the floor, or into an inventory is there is one
* adjacent to the turtle in the direction specified.
* @param stack The item stack to drop.
* @param dir The world direction to drop the item
* @return true if the stack was dropped, or completely stored in the adjacent inventory, false if
* it was only partially stored in the adjacent inventory, or could not fit at all. If false is returned
* and the stack was partially stored, the ItemStack passed into "stack" will now
* represent the stack of items that is left over.
*/
public boolean dropItemStack( net.minecraft.item.ItemStack stack, int dir );
/**
* "Deploys" an item stack in the direction specified. This simulates a player right clicking, and calls onItemUse() on the Item class.
* Will return true if some kind of deployment happened, and may modify the item stack. For block item types, this can be
* used to place blocks. Some kinds of items (such as shears when facing a sheep) may modify the turtles inventory during this call.
* @param stack The item stack to deploy
* @param dir The world direction to deploy the item
* @return true if the stack was deployed, false if it was not.
*/
public boolean deployWithItemStack( net.minecraft.item.ItemStack stack, int dir );
/**
* Tries to "attack" entities with an item stack in the direction specified. This simulates a player left clicking, but will
* not affect blocks. If an entity is attacked and killed during this call, its dropped items will end up in the turtles
* inventory.
* @param stack The item stack to attack with
* @param dir The world direction to attack with the item
* @return true if something was attacked, false if it was not
*/
public boolean attackWithItemStack( net.minecraft.item.ItemStack stack, int dir, float damageMultiplier );
/**
* Returns the current fuel level of the turtle, this is the same integer returned by turtle.getFuelLevel(),
* that decreases by 1 every time the turtle moves. Can be used to have your tool or peripheral require or supply
* fuel to the turtle.
* @return the fuel level
*/
public int getFuelLevel();
/**
* Tries to increase the fuel level of a turtle by burning an item stack. If the item passed in is a fuel source, fuel
* will increase and true will be returned. Otherwise, nothing will happen and false will be returned.
* @param stack The stack to try to refuel with
* @return Whether the turtle was refueled
*/
public boolean refuelWithItemStack( net.minecraft.item.ItemStack stack );
/**
* Removes some fuel from the turtles fuel supply. Negative numbers can be passed in to INCREASE the fuel level of the turtle.
* @return Whether the turtle was able to consume the ammount of fuel specified. Will return false if you supply a number
* greater than the current fuel level of the turtle.
*/
public boolean consumeFuel( int fuel );
/**
* Adds a custom command to the turtles command queue. Unlike peripheral methods, these custom commands will be executed
* on the main thread, so are guaranteed to be able to access Minecraft objects safely, and will be queued up
* with the turtles standard movement and tool commands. An issued command will return an unique integer, which will
* be supplied as a parameter to a "turtle_response" event issued to the turtle after the command has completed. Look at the
* lua source code for "rom/apis/turtle" for how to build a lua wrapper around this functionality.
* @param handler an object which will execute the custom command when its point in the queue is reached
* @return the unique command identifier described above
* @see ITurtleCommandHandler
*/
public int issueCommand( ITurtleCommandHandler handler );
/**
* Returns the upgrade on the specified side of the turtle, if there is one.
* @return the upgrade on the specified side of the turtle, if there is one.
*/
public ITurtleUpgrade getUpgrade( TurtleSide side );
/**
* Returns the peripheral created by the upgrade on the specified side of the turtle, if there is one.
* @return the peripheral created by the upgrade on the specified side of the turtle, if there is one.
*/
public IHostedPeripheral getPeripheral( TurtleSide side );
}

View file

@ -0,0 +1,25 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.turtle.api;
/**
* An interface for objects executing custom turtle commands, used with ITurtleAccess.issueCommand
* @see ITurtleAccess#issueCommand( ITurtleCommandHandler )
*/
public interface ITurtleCommandHandler
{
/**
* Will be called by the turtle on the main thread when it is time to execute the custom command.
* The handler should either perform the work of the command, and return true for success, or return
* false to indicate failure if the command cannot be executed at this time.
* @param turtle access to the turtle for whom the command was issued
* @return true for success, false for failure. If true is returned, the turtle will wait 0.4 seconds
* before executing the next command in its queue, as it does for the standard turtle commands.
* @see ITurtleAccess#issueCommand( ITurtleCommandHandler )
*/
public boolean handleCommand( ITurtleAccess turtle );
}

View file

@ -0,0 +1,92 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.turtle.api;
import net.minecraft.util.Icon;
import dan200.computer.api.*;
/**
* The primary interface for defining an upgrade for Turtles. A turtle upgrade
* can either be a new tool, or a new peripheral.
* @see TurtleAPI#registerUpgrade( ITurtleUpgrade )
*/
public interface ITurtleUpgrade
{
/**
* Gets a unique numerical identifier representing this type of turtle upgrade.
* Like Minecraft block and item IDs, you should strive to make this number unique
* among all turtle upgrades that have been released for ComputerCraft.
* The ID must be in the range 64 to 255, as the ID is stored as an 8-bit value,
* and 0-64 is reserved for future use by ComputerCraft. The upgrade will
* fail registration if an already used ID is specified.
* @see TurtleAPI#registerUpgrade( ITurtleUpgrade )
*/
public int getUpgradeID();
/**
* Return a String to describe this type of upgrade in turtle item names.
* Examples of built-in adjectives are "Wireless", "Mining" and "Crafty".
*/
public String getAdjective();
/**
* Return whether this upgrade adds a tool or a peripheral to the turtle.
* Currently, turtle crafting is restricted to one tool & one peripheral per turtle.
* @see TurtleUpgradeType for the differences between the two.
*/
public TurtleUpgradeType getType();
/**
* Return an item stack representing the type of item that a turtle must be crafted
* with to create a turtle which holds this upgrade.
* Currently, turtle crafting is restricted to one tool & one peripheral per turtle.
*/
public net.minecraft.item.ItemStack getCraftingItem();
/**
* Return whether this turtle upgrade is an easter egg, and should be attempted to be hidden
* from the creative mode inventory and recipe book plugins.
*/
public boolean isSecret();
/**
* Will only be called for Peripheral upgrades. Creates a peripheral for a turtle
* being placed using this upgrade. The peripheral created will be stored
* for the lifetime of the turtle, will have update() called once-per-tick, and will be
* attach'd detach'd and have methods called in the same manner as a Computer peripheral.
* @param turtle Access to the turtle that the peripheral is being created for.
* @param side Which side of the turtle (left or right) that the upgrade resides on.
* @returns The newly created peripheral. You may return null if this upgrade is a Tool
* and this method is not expected to be called.
*/
public IHostedPeripheral createPeripheral( ITurtleAccess turtle, TurtleSide side );
/**
* Will only be called for Tool upgrades. Called when turtle.dig() or turtle.attack() is called
* by the turtle, and the tool is required to do some work.
* @param turtle Access to the turtle that the tool resides on.
* @param side Which side of the turtle (left or right) the tool resides on.
* @param verb Which action (dig or attack) the turtle is being called on to perform.
* @param direction Which world direction the action should be performed in, relative to the turtles
* position. This will either be up, down, or the direction the turtle is facing, depending on
* whether dig, digUp or digDown was called.
* @return Whether the turtle was able to perform the action, and hence whether the turtle.dig()
* or turtle.attack() lua method should return true. If true is returned, the tool will perform
* a swinging animation. You may return false if this upgrade is a Peripheral
* and this method is not expected to be called.
*/
public boolean useTool( ITurtleAccess turtle, TurtleSide side, TurtleVerb verb, int direction );
/**
* Called to obtain the Icon to be used when rendering a turtle peripheral. Needs to be a "block"
* type Icon for now, as there is no way to determine which texture sheet an Icon is from by the
* Icon itself.
* @param turtle Access to the turtle that the peripheral resides on.
* @param side Which side of the turtle (left or right) the peripheral resides on.
* @return The Icon that you wish to be used to render your turtle peripheral.
*/
public Icon getIcon( ITurtleAccess turtle, TurtleSide side );
}

View file

@ -0,0 +1,78 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.turtle.api;
import java.lang.reflect.Method;
/**
* The static entry point to the ComputerCraft Turtle Upgrade API.
* Members in this class must be called after mod_CCTurtle has been initialised,
* but may be called before it is fully loaded.
*/
public class TurtleAPI
{
/**
* Registers a new turtle upgrade for use in ComputerCraft. After calling this,
* users should be able to craft Turtles with your new upgrade. It is recommended to call
* this during the load() method of your mod.
* @throws Exception if you try to register an upgrade with an already used or reserved upgradeID
* @see ITurtleUpgrade
*/
public static void registerUpgrade( ITurtleUpgrade upgrade )
{
if( upgrade != null )
{
findCCTurtle();
if( ccTurtle_registerTurtleUpgrade != null )
{
try {
ccTurtle_registerTurtleUpgrade.invoke( null, new Object[]{ upgrade } );
} catch( Exception e ) {
// It failed
}
}
}
}
// The functions below here are private, and are used to interface with the non-API ComputerCraft classes.
// Reflection is used here so you can develop your mod in MCP without decompiling ComputerCraft and including
// it in your solution.
private static void findCCTurtle()
{
if( !ccTurtleSearched ) {
// Search for CCTurtle
try {
ccTurtle = Class.forName( "dan200.CCTurtle" );
ccTurtle_registerTurtleUpgrade = findCCTurtleMethod( "registerTurtleUpgrade", new Class[] {
ITurtleUpgrade.class
} );
} catch( ClassNotFoundException e ) {
System.out.println("ComputerCraftAPI: CCTurtle not found.");
} finally {
ccTurtleSearched = true;
}
}
}
private static Method findCCTurtleMethod( String name, Class[] args )
{
try {
return ccTurtle.getMethod( name, args );
} catch( NoSuchMethodException e ) {
System.out.println("ComputerCraftAPI: CCTurtle method " + name + " not found.");
return null;
}
}
private static boolean ccTurtleSearched = false;
private static Class ccTurtle = null;
private static Method ccTurtle_registerTurtleUpgrade = null;
}

View file

@ -0,0 +1,23 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.turtle.api;
/**
* An enum representing the two sides of the turtle that a turtle upgrade might reside.
*/
public enum TurtleSide
{
/**
* The turtles left side (where the pickaxe usually is on a Wireless Mining Turtle)
*/
Left,
/**
* The turtles right side (where the modem usually is on a Wireless Mining Turtle)
*/
Right,
}

View file

@ -0,0 +1,27 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.turtle.api;
/**
* An enum representing the two different types of upgrades that an ITurtleUpgrade
* implementation can add to a turtle.
* @see ITurtleUpgrade
*/
public enum TurtleUpgradeType
{
/**
* A tool is rendered as an item on the side of the turtle, and responds to the turtle.dig()
* and turtle.attack() methods (Such as pickaxe or sword on Mining and Melee turtles).
*/
Tool,
/**
* A peripheral adds a special peripheral which is attached to the side of the turtle,
* and can be interacted with the peripheral API (Such as the modem on Wireless Turtles).
*/
Peripheral,
}

View file

@ -0,0 +1,26 @@
/**
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2013. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.turtle.api;
/**
* An enum representing the two different actions that an ITurtleUpgrade of type
* Tool may be called on to perform by a turtle.
* @see ITurtleUpgrade
* @see ITurtleUpgrade#useTool
*/
public enum TurtleVerb
{
/**
* The turtle called turtle.dig(), turtle.digUp() or turtle.digDown()
*/
Dig,
/**
* The turtle called turtle.attack(), turtle.attackUp() or turtle.attackDown()
*/
Attack,
}

View file

@ -0,0 +1,119 @@
package ic2.api;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
/**
* Represents the 6 possible directions along the axis of a block.
*/
public enum Direction
{
/**
* -X
*/
XN(0),
/**
* +X
*/
XP(1),
/**
* -Y
*/
YN(2), // MC-Code starts with 0 here
/**
* +Y
*/
YP(3), // 1...
/**
* -Z
*/
ZN(4),
/**
* +Z
*/
ZP(5);
Direction(int dir)
{
this.dir = dir;
}
/*
* public CoordinateTuple ApplyToCoordinates(CoordinateTuple coordinates) { CoordinateTuple ret
* = new CoordinateTuple(coordinates);
*
* ret.coords[dir/2] += GetSign();
*
* return ret; }
*/
/**
* Get the tile entity next to a tile entity following this direction.
*
* @param tileEntity tile entity to check
* @return Adjacent tile entity or null if none exists
*/
public TileEntity applyToTileEntity(TileEntity tileEntity)
{
int coords[] = { tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord };
coords[dir / 2] += getSign();
if (tileEntity.worldObj != null && tileEntity.worldObj.blockExists(coords[0], coords[1], coords[2]))
{
return tileEntity.worldObj.getBlockTileEntity(coords[0], coords[1], coords[2]);
}
else
{
return null;
}
}
/**
* Get the inverse of this direction (XN -> XP, XP -> XN, etc.)
*
* @return Inverse direction
*/
public Direction getInverse()
{
int inverseDir = dir - getSign();
for (Direction direction : directions)
{
if (direction.dir == inverseDir)
return direction;
}
return this;
}
/**
* Convert this direction to a Minecraft side value.
*
* @return Minecraft side value
*/
public int toSideValue()
{
return (dir + 4) % 6;
}
/**
* Determine direction sign (N for negative or P for positive).
*
* @return -1 if the direction is negative, +1 if the direction is positive
*/
private int getSign()
{
return (dir % 2) * 2 - 1;
}
public ForgeDirection toForgeDirection()
{
return ForgeDirection.getOrientation(toSideValue());
}
private int dir;
public static final Direction[] directions = Direction.values();
}

View file

@ -0,0 +1,17 @@
package ic2.api.energy.event;
import ic2.api.energy.tile.IEnergyTile;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.event.world.WorldEvent;
public class EnergyTileEvent extends WorldEvent
{
public final IEnergyTile energyTile;
public EnergyTileEvent(IEnergyTile energyTile)
{
super(((TileEntity) energyTile).worldObj);
this.energyTile = energyTile;
}
}

View file

@ -0,0 +1,23 @@
package ic2.api.energy.event;
import ic2.api.energy.tile.IEnergyTile;
/**
* Event announcing new energy tiles.
*
* This event notifies subscribers of loaded energy tiles, e.g. after getting loaded through the
* chunk they are in or after being placed down by the player or another deployer mechanism.
*
* Every energy tile which wants to get connected to the IC2 Energy Network has to either post this
* event or alternatively call EnergyNet.addTileEntity().
*
* You may use this event to build a static representation of energy tiles for your own energy grid
* implementation if you need to. It's not required if you always lookup energy paths on demand.
*/
public class EnergyTileLoadEvent extends EnergyTileEvent
{
public EnergyTileLoadEvent(IEnergyTile energyTile)
{
super(energyTile);
}
}

View file

@ -0,0 +1,32 @@
package ic2.api.energy.event;
import ic2.api.energy.tile.IEnergySource;
/**
* Event announcing an energy source operation.
*
* This event notifies subscribers of energy sources trying to push energy into an energy grid.
*
* The amount field indicates the maximum amount of energy left to be distributed. You have to
* substract the amount of energy you accepted from 'amount'.
*
* The IEnergySource posting this event has to check 'amount' to see how much energy has not been
* used up and adjust its output buffer accordingly (usually buffer -= 'initial amount' - 'amount
* after posting the event')
*/
public class EnergyTileSourceEvent extends EnergyTileEvent
{
/**
* Amount of energy provided by the energy source.
*
* amount needs to be adjusted to show the remaining unused energy.
*/
public int amount;
public EnergyTileSourceEvent(IEnergySource energySource, int amount)
{
super(energySource);
this.amount = amount;
}
}

View file

@ -0,0 +1,24 @@
package ic2.api.energy.event;
import ic2.api.energy.tile.IEnergyTile;
/**
* Event announcing terminated energy tiles.
*
* This event notifies subscribers of unloaded energy tiles, e.g. after getting unloaded through the
* chunk they are in or after being destroyed by the player or another block pick/destruction
* mechanism.
*
* Every energy tile which wants to get disconnected from the IC2 Energy Network has to either post
* this event or alternatively call EnergyNet.removeTileEntity().
*
* You may use this event to build a static representation of energy tiles for your own energy grid
* implementation if you need to. It's not required if you always lookup energy paths on demand.
*/
public class EnergyTileUnloadEvent extends EnergyTileEvent
{
public EnergyTileUnloadEvent(IEnergyTile energyTile)
{
super(energyTile);
}
}

View file

@ -0,0 +1,21 @@
package ic2.api.energy.tile;
import ic2.api.Direction;
import net.minecraft.tileentity.TileEntity;
/**
* For internal usage only.
*
* @see IEnergySink
* @see IEnergyConductor
*/
public interface IEnergyAcceptor extends IEnergyTile
{
/**
* Determine if this acceptor can accept current from an adjacent emitter in a direction.
*
* @param emitter energy emitter
* @param direction direction the energy is being received from
*/
boolean acceptsEnergyFrom(TileEntity emitter, Direction direction);
}

View file

@ -0,0 +1,51 @@
package ic2.api.energy.tile;
/**
* Tile entities which conduct energy pulses without buffering (mostly cables) have to implement
* this interface.
*/
public interface IEnergyConductor extends IEnergyAcceptor, IEnergyEmitter
{
/**
* Energy loss for the conductor in EU per block.
*
* @return Energy loss
*/
double getConductionLoss();
/**
* Amount of energy the insulation will handle before shocking nearby players and mobs.
*
* @return Insulation energy absorption in EU
*/
int getInsulationEnergyAbsorption();
/**
* Amount of energy the insulation will handle before it is destroyed. Ensure that this value is
* greater than the insulation energy absorption + 64.
*
* @return Insulation-destroying energy in EU
*/
int getInsulationBreakdownEnergy();
/**
* Amount of energy the conductor will handle before it melts.
*
* @return Conductor-destroying energy in EU
*/
int getConductorBreakdownEnergy();
/**
* Remove the conductor's insulation if the insulation breakdown energy was exceeded.
*
* @see #getInsulationBreakdownEnergy()
*/
void removeInsulation();
/**
* Remove the conductor if the conductor breakdown energy was exceeded.
*
* @see #getConductorBreakdownEnergy()
*/
void removeConductor();
}

View file

@ -0,0 +1,22 @@
package ic2.api.energy.tile;
import ic2.api.Direction;
import net.minecraft.tileentity.TileEntity;
/**
* For internal usage only.
*
* @see IEnergySource
* @see IEnergyConductor
*/
public interface IEnergyEmitter extends IEnergyTile
{
/**
* Determine if this emitter can emit energy to an adjacent receiver.
*
* @param receiver receiver
* @param direction direction the receiver is from the emitter
* @return Whether energy should be emitted
*/
boolean emitsEnergyTo(TileEntity receiver, Direction direction);
}

View file

@ -0,0 +1,42 @@
package ic2.api.energy.tile;
import ic2.api.Direction;
/**
* Allows a tile entity (mostly a machine) to receive energy.
*/
public interface IEnergySink extends IEnergyAcceptor
{
/**
* Determine how much energy the sink accepts.
*
* This value is unrelated to getMaxSafeInput().
*
* Make sure that injectEnergy() does accepts energy if demandsEnergy() returns anything > 0.
*
* @return max accepted input in eu
*/
int demandsEnergy();
/**
* Transfer energy to the sink.
*
* @param directionFrom direction from which the energy comes from
* @param amount energy to be transferred
* @return Energy not consumed (leftover)
*/
int injectEnergy(Direction directionFrom, int amount);
/**
* Determine the amount of eu which can be safely injected into the specific energy sink without
* exploding.
*
* Typical values are 32 for LV, 128 for MV, 512 for HV and 2048 for EV. A value of
* Integer.MAX_VALUE indicates no limit.
*
* This value is unrelated to demandsEnergy().
*
* @return max safe input in eu
*/
int getMaxSafeInput();
}

View file

@ -0,0 +1,14 @@
package ic2.api.energy.tile;
/**
* Allows a tile entity (mostly a generator) to emit energy.
*/
public interface IEnergySource extends IEnergyEmitter
{
/**
* Maximum energy output provided by the source. If unsure, use Integer.MAX_VALUE.
*
* @return Maximum energy output
*/
int getMaxEnergyOutput();
}

View file

@ -0,0 +1,18 @@
package ic2.api.energy.tile;
/**
* For internal usage only.
*
* @see IEnergySink
* @see IEnergySource
* @see IEnergyConductor
*/
public interface IEnergyTile
{
/**
* Determine if this tile entity has been added to the energy network
*
* @return Whether the tile entity has been added
*/
boolean isAddedToEnergyNet();
}

View file

@ -0,0 +1,54 @@
package ic2.api.item;
import net.minecraft.item.ItemStack;
/**
* Provides the ability to store energy on the implementing item.
*
* The item should have a maximum damage of 13.
*/
public interface IElectricItem
{
/**
* Determine if the item can be used in a machine or as an armor part to supply energy.
*
* @return Whether the item can supply energy
*/
boolean canProvideEnergy(ItemStack itemStack);
/**
* Get the item ID to use for a charge energy greater than 0.
*
* @return Item ID to use
*/
int getChargedItemId(ItemStack itemStack);
/**
* Get the item ID to use for a charge energy of 0.
*
* @return Item ID to use
*/
int getEmptyItemId(ItemStack itemStack);
/**
* Get the item's maximum charge energy in EU.
*
* @return Maximum charge energy
*/
int getMaxCharge(ItemStack itemStack);
/**
* Get the item's tier, lower tiers can't send energy to higher ones. Batteries are Tier 1,
* Energy Crystals are Tier 2, Lapotron Crystals are Tier 3.
*
* @return Item's tier
*/
int getTier(ItemStack itemStack);
/**
* Get the item's transfer limit in EU per transfer operation.
*
* @return Transfer limit
*/
int getTransferLimit(ItemStack itemStack);
}

View file

@ -0,0 +1,94 @@
package ic2.api.item;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
/**
* This interface specifies a manager to handle the various tasks for electric items.
*
* The default implementation does the following: - store and retrieve the charge - handle charging,
* taking amount, tier, transfer limit, canProvideEnergy and simulate into account - replace item
* IDs if appropriate (getChargedItemId() and getEmptyItemId()) - update and manage the damage value
* for the visual charge indicator
*
* @note If you're implementing your own variant (ISpecialElectricItem), you can delegate to the
* default implementations through ElectricItem.rawManager. The default implementation is designed
* to minimize its dependency on its own constraints/structure and delegates most work back to the
* more atomic features in the gateway manager.
*/
public interface IElectricItemManager
{
/**
* Charge an item with a specified amount of energy
*
* @param itemStack electric item's stack
* @param amount amount of energy to charge in EU
* @param tier tier of the charging device, has to be at least as high as the item to charge
* @param ignoreTransferLimit ignore the transfer limit specified by getTransferLimit()
* @param simulate don't actually change the item, just determine the return value
* @return Energy transferred into the electric item
*/
int charge(ItemStack itemStack, int amount, int tier, boolean ignoreTransferLimit, boolean simulate);
/**
* Discharge an item by a specified amount of energy
*
* @param itemStack electric item's stack
* @param amount amount of energy to charge in EU
* @param tier tier of the discharging device, has to be at least as high as the item to
* discharge
* @param ignoreTransferLimit ignore the transfer limit specified by getTransferLimit()
* @param simulate don't actually discharge the item, just determine the return value
* @return Energy retrieved from the electric item
*/
int discharge(ItemStack itemStack, int amount, int tier, boolean ignoreTransferLimit, boolean simulate);
/**
* Determine the charge level for the specified item
*
* @param itemStack ItemStack containing the electric item
* @return charge level in EU
*/
int getCharge(ItemStack itemStack);
/**
* Determine if the specified electric item has at least a specific amount of EU. This is
* supposed to be used in the item code during operation, for example if you want to implement
* your own electric item. BatPacks are not taken into account.
*
* @param itemStack electric item's stack
* @param amount minimum amount of energy required
* @return true if there's enough energy
*/
boolean canUse(ItemStack itemStack, int amount);
/**
* Try to retrieve a specific amount of energy from an Item, and if applicable, a BatPack. This
* is supposed to be used in the item code during operation, for example if you want to
* implement your own electric item.
*
* @param itemStack electric item's stack
* @param amount amount of energy to discharge in EU
* @param entity entity holding the item
* @return true if the operation succeeded
*/
boolean use(ItemStack itemStack, int amount, EntityLivingBase entity);
/**
* Charge an item from the BatPack a player is wearing. This is supposed to be used in the item
* code during operation, for example if you want to implement your own electric item. use()
* already contains this functionality.
*
* @param itemStack electric item's stack
* @param entity entity holding the item
*/
void chargeFromArmor(ItemStack itemStack, EntityLivingBase entity);
/**
* Get the tool tip to display for electric items.
*
* @param itemStack ItemStack to determine the tooltip for
* @return tool tip string or null for none
*/
String getToolTip(ItemStack itemStack);
}

View file

@ -0,0 +1,14 @@
package ic2.api.item;
import net.minecraft.item.ItemStack;
public interface ISpecialElectricItem extends IElectricItem
{
/**
* Supply a custom IElectricItemManager.
*
* @param itemStack ItemStack to get the manager for
* @return IElectricItemManager instance
*/
IElectricItemManager getManager(ItemStack itemStack);
}

View file

@ -0,0 +1,362 @@
package ic2.api.item;
import net.minecraft.item.ItemStack;
/**
* Provides access to IC2 blocks and items.
*
* Some items can be acquired through the ore dictionary which is the recommended way. The items are
* initialized while IC2 is being loaded - try to use ModsLoaded() or load your mod after IC2. Some
* blocks/items can be disabled by a config setting, so it's recommended to check if they're null
* first.
*
* Getting the associated Block/Item for an ItemStack x: Blocks: Block.blocksList[x.itemID] Items:
* x.getItem()
*/
public final class Items
{
/**
* Get an ItemStack for a specific item name, example: Items.getItem("resin") See the list below
* for item names. Make sure to copy() the ItemStack if you want to modify it.
*
* @param name item name
* @return The item or null if the item does not exist or an error occurred
*/
public static ItemStack getItem(String name)
{
try
{
if (Ic2Items == null)
Ic2Items = Class.forName(getPackage() + ".core.Ic2Items");
Object ret = Ic2Items.getField(name).get(null);
if (ret instanceof ItemStack)
{
return (ItemStack) ret;
}
else
{
return null;
}
}
catch (Exception e)
{
System.out.println("IC2 API: Call getItem failed for " + name);
return null;
}
}
/*
* Possible values:
*
* ----- blocks -----
*
* ores copperOre Copper Ore block, currently not meta sensitive, meta in ItemStack set to 0,
* ore dictionary: oreCopper, null with enableWorldGenOreCopper=false tinOre Tin Ore block,
* currently not meta sensitive, meta in ItemStack set to 0, ore dictionary: oreTin, null with
* enableWorldGenOreTin=false uraniumOre Tin Ore block, currently not meta sensitive, meta in
* ItemStack set to 0, ore dictionary: oreUranium, null with enableWorldGenOreUranium=false
*
* rubber related Rubber wood block, meta reflects the state, meta in ItemStack set to 0, ore
* dictionary: woodRubber (with meta 0), null with enableWorldGenTreeRubber=false dropped (as an
* item) -> metadata 0 block, no resin spot -> metadata 0 or 1 block, wet resin spot -> metadata
* 2-5 (according to the side) block, dry resin spot -> metadata 8-11 (wet state + 6)
*
* rubberWood rubberLeaves Rubber Leaves block, currently not meta sensitive, meta in ItemStack
* set to 0, null with enableWorldGenTreeRubber=false rubberSapling Rubber Sapling block,
* currently not meta sensitive, meta in ItemStack set to 0, null with
* enableWorldGenTreeRubber=false resinSheet Resin Sheet block, currently not meta sensitive
* rubberTrampoline Rubber Trampoline block, meta reflects internal state, meta in ItemStack set
* to 0
*
* building/storage ironFence Iron Fence block, currently not meta sensitive
*
* reinforcedStone Reinforced Stone block, currently not meta sensitive reinforcedGlass
* Reinforced Glass block, currently not meta sensitive reinforcedDoorBlock Reinforced Door
* block, meta reflects the state (see vanilla doors), meta in ItemStack set to 0
*
* constructionFoam Construction Foam block, currently not meta sensitive constructionFoamWall
* Construction Foam Wall block, meta = color, implements IPaintableBlock scaffold Scaffold
* block, meta reflects internal physical model data
*
* bronzeBlock Bronze block, meta sensitive copperBlock Copper block, meta sensitive tinBlock
* Tin block, meta sensitive uraniumBlock Uranium block, meta sensitive
*
* cables (when placed as a block, inventory items are different TE implements IEnergyConductor)
* copperCableBlock Copper Cable block, meta sensitive insulatedCopperCableBlock Insulated
* Copper Cable block, meta sensitive
*
* goldCableBlock Gold Cable block, meta sensitive insulatedGoldCableBlock Insulated Gold Cable
* block, meta sensitive doubleInsulatedGoldCableBlock Double Insulated Gold Cable block, meta
* sensitive
*
* ironCableBlock Iron Cable block, meta sensitive insulatedIronCableBlock Insulated Iron Cable
* block, meta sensitive doubleInsulatedIronCableBlock Double Insulated Iron Cable block, meta
* sensitive trippleInsulatedIronCableBlock Tripple Insulated Iron Cable block, meta sensitive
*
* glassFiberCableBlock Glass Fiber Cable block, meta sensitive
*
* tinCableBlock Tin Cable block, meta sensitive
*
* detectorCableBlock Detector Cable block, meta sensitive splitterCableBlock Splitter Cable
* block, meta sensitive
*
* generators + related (TE implements IEnergySource ex. reactorChamber) generator Generator
* block, meta sensitive geothermalGenerator Geothermal Generator block, meta sensitive
* waterMill Water Mill block, meta sensitive solarPanel Solar Panel block, meta sensitive
* windMill Wind Mill block, meta sensitive nuclearReactor Nuclear Reactor block, meta sensitive
* reactorChamber Reactor Chamber block, currently not meta sensitive
*
* energy storages (TE implements IEnergySource and IEnergyConductor) batBox BatBox block, meta
* sensitive mfeUnit MFE Unit block, meta sensitive mfsUnit MFS Unit block, meta sensitive
*
* transformers (TE implements IEnergySource and IEnergyConductor) lvTransformer LV Transformer
* block, meta sensitive mvTransformer MV Transformer block, meta sensitive hvTransformer HV
* Transformer block, meta sensitive
*
* machines + related (TE implements IEnergySink ex. machine, miningPipe, miningPipeTip) machine
* Machine block, meta sensitive advancedMachine Advanced Machine block, meta sensitive
*
* ironFurnace Iron Furnace block, meta sensitive electroFurnace Electro Furnace block, meta
* sensitive macerator Macerator block, meta sensitive extractor Extractor block, meta sensitive
* compressor Compressor block, meta sensitive canner Canner block, meta sensitive miner Miner
* block, meta sensitive pump Pump block, meta sensitive magnetizer Magnetizer block, meta
* sensitive electrolyzer Electrolyzer block, meta sensitive recycler Recycler block, meta
* sensitive inductionFurnace Induction Furnace block, meta sensitive massFabricator Mass
* Fabricator block, meta sensitive terraformer Terraformer block, meta sensitive teleporter
* Teleporter block, meta sensitive teslaCoil Tesla Coil block, meta sensitive luminator Passive
* (dark) Luminator block, meta = facing activeLuminator Active (bright) Luminator block, meta =
* facing
*
* miningPipe Mining Pipe block, currently not meta sensitive, meta in ItemStack set to 0
* miningPipeTip Mining Pipe Tip block, currently not meta sensitive, meta in ItemStack set to 0
*
* personal blocks personalSafe Personal Safe block, meta sensitive tradeOMat Trade-O-Mat block,
* meta sensitive energyOMat Energy-O-Mat block, meta sensitive
*
* explosives industrialTnt Industrial TNT block, currently not meta sensitive nuke Nuke block,
* currently not meta sensitive dynamiteStick Dynamite Stick block, meta = placement, meta in
* ItemStack set to 0 dynamiteStickWithRemote Dynamite Stick with Remote block, meta =
* placement, meta in ItemStack set to 0
*
* Agriculture Stuff crop Crop Block, empty, not meta sensitive
*
*
* ----- items -----
*
* rubber + related resin Resin item, currently not meta sensitive rubber Rubber item, currently
* not meta sensitive, ore dictionary: itemRubber
*
* ore drops uraniumDrop Uranium Drop item, currently not meta sensitive, ore dictionary:
* itemDropUranium
*
* dusts bronzeDust Bronze Dust item, currently not meta sensitive clayDust Clay Dust item,
* currently not meta sensitive coalDust Coal Dust item, currently not meta sensitive copperDust
* Copper Dust item, currently not meta sensitive goldDust Gold Dust item, currently not meta
* sensitive ironDust Iron Dust item, currently not meta sensitive silverDust Silver Dust item,
* currently not meta sensitive smallIronDust Small Iron Dust item, currently not meta sensitive
* tinDust Tin Dust item, currently not meta sensitive hydratedCoalDust Hydrated Coal Dust item,
* currently not meta sensitive
*
* ingots refinedIronIngot Refined Iron Ingot item, currently not meta sensitive, ore
* dictionary: ingotRefinedIron copperIngot Copper Ingot item, currently not meta sensitive, ore
* dictionary: ingotCopper tinIngot Tin Ingot item, currently not meta sensitive, ore
* dictionary: ingotTin bronzeIngot Bronze Ingot item, currently not meta sensitive, ore
* dictionary: ingotBronze mixedMetalIngot Mixed Metal Ingot item, currently not meta sensitive
* uraniumIngot Uranium Ingot item, currently not meta sensitive, ore dictionary: ingotUranium
*
* tools/weapons (without electric tools) treetap Treetap item, meta = damage value wrench
* Wrench item, meta = damage value cutter Insulation Cutter item, meta = damage value
* constructionFoamSprayer Construction Foam Sprayer item, meta = charges (as of v1.45)
*
* bronzePickaxe Bronze Pickaxe item, meta = damage value bronzeAxe Bronze Axe item, meta =
* damage value bronzeSword Bronze Sword item, meta = damage value bronzeShovel Bronze Shovel
* item, meta = damage value bronzeHoe Bronze Hoe item, meta = damage value
*
* el. tools/devices/weapons miningDrill Mining Drill item, meta = visual charge indicator,
* implements IElectricItem diamondDrill Diamond Tipped Mining Drill item, meta = visual charge
* indicator, implements IElectricItem chainsaw Chainsaw item, meta = visual charge indicator,
* implements IElectricItem electricWrench Electric Wrench item, meta = visual charge indicator,
* implements IElectricItem electricTreetap Electric Treetap item, meta = visual charge
* indicator, implements IElectricItem miningLaser Mining Laser item, meta = visual charge
* indicator, implements IElectricItem
*
* ecMeter EC-Mater item, currently not meta sensitive odScanner Ore Density Scanner item, meta
* = damage value for charge level, implements IElectricItem ovScanner Ore Value Scanner item,
* meta = visual charge indicator, implements IElectricItem
*
* frequencyTransmitter Frequency Transmitter item, currently not meta sensitive
*
* nanoSaber Idle Nano Saber item, meta = visual charge indicator, implements IElectricItem
* enabledNanoSaber Enabled Nano Saber item, meta = visual charge indicator, implements
* IElectricItem
*
* armor/wearable rubberBoots Rubber Boots item, meta = damage value
*
* bronzeHelmet Bronze Helmet Armor item, meta = damage value bronzeChestplate Bronze Chestplate
* Armor item, meta = damage value bronzeLeggings Bronze Leggings Armor item, meta = damage
* value bronzeBoots Bronze Boots Armor item, meta = damage value
*
* compositeArmor Composite Armor item, meta = damage value for charge level
*
* nanoHelmet Nano Helmet Armor item, meta = visual charge indicator, implements IElectricItem
* nanoBodyarmor Nano Bodyarmor item, meta = visual charge indicator, implements IElectricItem
* nanoLeggings Nano Leggings Armor item, meta = visual charge indicator, implements
* IElectricItem nanoBoots Nano Boots Armor item, meta = visual charge indicator, implements
* IElectricItem
*
* quantumHelmet Quantum Helmet Armor item, meta = visual charge indicator, implements
* IElectricItem quantumBodyarmor Quantum Bodyarmor item, meta = visual charge indicator,
* implements IElectricItem quantumLeggings Quantum Leggings Armor item, meta = visual charge
* indicator, implements IElectricItem quantumBoots Quantum Boots Armor item, meta = visual
* charge indicator, implements IElectricItem
*
* jetpack Jetpack item, meta = damage value for fuel level electricJetpack Electric Jetpack
* item, meta = visual charge indicator, implements IElectricItem
*
* batPack BatPack item, meta = visual charge indicator, implements IElectricItem, can provide
* energy lapPack LapPack item, meta = visual charge indicator, implements IElectricItem, can
* provide energy
*
* cfPack CF Pack item, meta = charges (as of v1.45)
*
* solarHelmet Solar Helmet item, currently not meta sensitive staticBoots Static Boots item,
* currently not meta sensitive
*
* batteries reBattery Empty RE Battery item, currently not meta sensitive, implements
* IElectricItem chargedReBattery RE Battery item, meta = visual charge indicator, implements
* IElectricItem, can provide energy energyCrystal Energy Crystal item, meta = visual charge
* indicator, implements IElectricItem, can provide energy lapotronCrystal Lapotron Crystal
* item, meta = visual charge indicator, implements IElectricItem, can provide energy suBattery
* SU Battery item, currently not meta sensitive
*
* cables copperCableItem Copper Cable item, meta sensitive insulatedCopperCableItem Insulated
* Copper Cable item, meta sensitive
*
* goldCableItem Gold Cable item, meta sensitive insulatedGoldCableItem Insulated Gold Cable
* item, meta sensitive doubleInsulatedGoldCableItem Double Insulated Gold Cable item, meta
* sensitive
*
* ironCableItem Iron Cable item, meta sensitive insulatedIronCableItem Insulated Iron Cable
* item, meta sensitive doubleInsulatedIronCableItem Double Insulated Iron Cable item, meta
* sensitive trippleInsulatedIronCableItem Tripple Insulated Iron Cable item, meta sensitive
*
* glassFiberCableItem Glass Fiber Cable item, meta sensitive
*
* tinCableItem Tin Cable item, meta sensitive
*
* detectorCableItem Detector Cable item, meta sensitive splitterCableItem Splitter Cable item,
* meta sensitive
*
* cells/containers (without reactor components) cell Empty Cell item, currently not meta
* sensitive lavaCell Lava Cell item, currently not meta sensitive hydratedCoalCell Hydrated
* Coal Cell item, currently not meta sensitive bioCell Bio Cell item, currently not meta
* sensitive coalfuelCell Coalfuel Cell item, currently not meta sensitive biofuelCell Biofuel
* Cell item, currently not meta sensitive waterCell Water Cell item, currently not meta
* sensitive electrolyzedWaterCell Electrolyzed Water Cell item, currently not meta sensitive
*
* fuelCan Empty Fuel Can item, currently not meta sensitive filledFuelCan Fuel Can item, meta =
* fuel value (as of v1.45)
*
* tinCan Empty Tin Can item, currently not meta sensitive filledTinCan Filled Tin Can item,
* currently not meta sensitive
*
* reactor components uraniumCell Uranium Cell item, meta = damage value coolingCell Cooling
* Cell item, meta = damage value
*
* depletedIsotopeCell Depleted Isotope Cell item, meta = damage value reEnrichedUraniumCell
* Re-Enriched Uranium Cell item, currently not meta sensitive nearDepletedUraniumCell
* Near-Depleted Uranium Cell item, currently not meta sensitive
*
* integratedReactorPlating Integrated Reactor Plating item, meta = damage value
* integratedHeatDisperser Integrated Heat Disperser item, meta = damage value
*
* terraformer blueprints terraformerBlueprint Empty Terraformer Blueprint item, currently not
* meta sensitive cultivationTerraformerBlueprint Cultivation Terraformer Blueprint item,
* currently not meta sensitive irrigationTerraformerBlueprint Irrigation Terraformer Blueprint
* item, currently not meta sensitive chillingTerraformerBlueprint Chilling Terraformer
* Blueprint item, currently not meta sensitive desertificationTerraformerBlueprint
* Desertification Terraformer Blueprint item, currently not meta sensitive
* flatificatorTerraformerBlueprint Flatificator Terraformer Blueprint item, currently not meta
* sensitive mushroomTerraformerBlueprint Mushroom Terraformer Blueprint item, currently not
* meta sensitive
*
* diamond chain coalBall Coal Ball item, currently not meta sensitive compressedCoalBall
* Compressed Coal Ball item, currently not meta sensitive coalChunk Coal Chunk item, currently
* not meta sensitive industrialDiamond Industrial Diamond item, currently not meta sensitive,
* DEPRECATED
*
* recycler chain scrap Scrap item, currently not meta sensitive scrapBox Scrap Box item,
* currently not meta sensitive
*
* fuel production chain hydratedCoalClump Hydrated Coal Clump item, currently not meta
* sensitive plantBall Plant Ball item, currently not meta sensitive compressedPlantBall
* Compressed Plant Ball item, currently not meta sensitive
*
* painting painter Painter item, currently not meta sensitive
*
* blackPainter Black Painter item, meta = damage value redPainter Red Painter item, meta =
* damage value greenPainter Green Painter item, meta = damage value brownPainter Brown Painter
* item, meta = damage value bluePainter Blue Painter item, meta = damage value purplePainter
* Purple Painter item, meta = damage value cyanPainter Cyan Painter item, meta = damage value
* lightGreyPainter Light Grey Painter item, meta = damage value darkGreyPainter Dark Grey
* Painter item, meta = damage value pinkPainter Pink Painter item, meta = damage value
* limePainter Lime Painter item, meta = damage value yellowPainter Yellow Painter item, meta =
* damage value cloudPainter Cloud Painter item, meta = damage value magentaPainter Magenta
* Painter item, meta = damage value orangePainter Orange Painter item, meta = damage value
* whitePainter White Painter item, meta = damage value
*
* explosives + related dynamite Throwable Dynamite item, currently not meta sensitive
* stickyDynamite Throwable Sticky Dynamite item, currently not meta sensitive
*
* remote Dynamite Remote item, currently not meta sensitive
*
* misc intermediate recipe ingredients electronicCircuit Electronic Circuit item, currently not
* meta sensitive advancedCircuit Advanced Circuit item, currently not meta sensitive
*
* advancedAlloy Advanced Alloy item, currently not meta sensitive
*
* carbonFiber Raw Carbon Fiber item, currently not meta sensitive carbonMesh Raw Carbon Mesh
* item, currently not meta sensitive carbonPlate Carbon Plate item, currently not meta
* sensitive
*
* matter UU-Matter item, currently not meta sensitive iridiumOre Iridium Ore item, currently
* not meta sensitive iridiumPlate Iridium Plate item, currently not meta sensitive
*
* upgrade modules overclockerUpgrade overclocker upgrade item, meta sensitive
* transformerUpgrade transformer upgrade item, meta sensitive energyStorageUpgrade energy
* storage upgrade item, meta sensitive
*
* misc coin Coin item, currently not meta sensitive reinforcedDoor Reinforced Door item,
* currently not meta sensitive constructionFoamPellet Construction Foam Pellet item, currently
* not meta sensitive cropSeed Crop seeds, stuff stored in NBT, don't use for crafting recipes!
* cropnalyzer Cropnalyzer handheld device fertilizer Basic IC2Item, used to provide nutrients
* toCropBlocks hydratingCell Cell used to hydrate Crops, meta = Content, 0 = Full, 9999 = Near
* empty electricHoe Electric Hoe, meta = charge level solarHelmet Solar Helmet item, currently
* not meta sensitive terraWart Terra Wart item, cures potion effects weedEx Weed-EX can, meta =
* uses left
*/
/**
* Get the base IC2 package name, used internally.
*
* @return IC2 package name, if unable to be determined defaults to ic2
*/
private static String getPackage()
{
Package pkg = Items.class.getPackage();
if (pkg != null)
{
String packageName = pkg.getName();
return packageName.substring(0, packageName.length() - ".api.item".length());
}
return "ic2";
}
private static Class<?> Ic2Items;
}

View file

@ -0,0 +1,26 @@
package icbm.api;
/**
* Applied to all blocks that has a frequency.
*
* @author Calclavia
*/
public interface IBlockFrequency {
/**
* @param data
* - Pass an ItemStack if dealing with items with frequencies.
* @return The frequency of this object.
*/
public int getFrequency();
/**
* Sets the frequency
*
* @param frequency
* - The frequency of this object.
* @param data
* - Pass an ItemStack if dealing with items with frequencies.
*/
public void setFrequency(int frequency);
}

View file

@ -0,0 +1,60 @@
package icbm.api;
import icbm.api.explosion.IExplosive;
import java.lang.reflect.Method;
/**
* General ICBM references.
*
* @author Calclavia
*
*/
public class ICBM {
/**
* Name of the channel and mod ID.
*/
public static final String NAME = "ICBM";
/**
* The version of ICBM.
*/
public static final String MAJOR_VERSION = "@MAJOR@";
public static final String MINOR_VERSION = "@MINOR@";
public static final String REVISION_VERSION = "@REVIS@";
public static final String BUILD_VERSION = "@BUILD@";
public static final String VERSION = MAJOR_VERSION + "." + MINOR_VERSION
+ "." + REVISION_VERSION;
/**
* The block ID in which ICBM starts with. ICBM Explosion will count up,
* ICBM Contraption will count down.
*/
public static final int BLOCK_ID_PREFIX = 3880;
/**
* The item ID in which ICBM starts with.
*/
public static final int ITEM_ID_PREFIX = 3900;
public static Class explosionManager;
/**
* @return Gets an explosive object based on the name of the explosive.
*/
public static IExplosive getExplosive(String name) {
if (name != null) {
try {
Method method = explosionManager.getMethod("get", String.class);
return (IExplosive) method.invoke(null, name);
} catch (Exception e) {
System.out
.println("ICBM: Failed to get explosive with the name: "
+ name);
e.printStackTrace();
}
}
return null;
}
}

View file

@ -0,0 +1,13 @@
package icbm.api;
/**
* Applied to all blocks that can be used as a camouflage for the camouflage
* block. Use this interface if your block is not a normal block but yet would
* like it to be used as a camouflage material.
*
* @author Calclavia
*
*/
public interface ICamouflageMaterial {
}

View file

@ -0,0 +1,15 @@
package icbm.api;
import net.minecraft.entity.player.EntityPlayer;
public interface IHackable {
/**
* Causes the machine to generate a new pass key
*/
public void generateNewKey();
/**
* Checks to see if the pass key matches the stored one
*/
public boolean tryForAccess(EntityPlayer player, String pass);
}

View file

@ -0,0 +1,28 @@
package icbm.api;
import net.minecraft.item.ItemStack;
/**
* Applied to all items that has a frequency.
*
* @author Calclavia
*/
public interface IItemFrequency {
/**
* @param data
* - Pass an ItemStack if dealing with items with frequencies.
* @return The frequency of this object.
*/
public int getFrequency(ItemStack itemStack);
/**
* Sets the frequency
*
* @param frequency
* - The frequency of this object.
* @param data
* - Pass an ItemStack if dealing with items with frequencies.
*/
public void setFrequency(int frequency, ItemStack itemStack);
}

View file

@ -0,0 +1,18 @@
package icbm.api;
/**
* Applied to TileEntities that contains missiles within them.
*
* @author Calclavia
*
*/
public interface ILauncherContainer {
public IMissile getContainingMissile();
public void setContainingMissile(IMissile missile);
/**
* Retrieves the launcher controller controlling this container.
*/
public ILauncherController getController();
}

View file

@ -0,0 +1,52 @@
package icbm.api;
import net.minecraft.item.ItemStack;
import universalelectricity.core.block.IElectricalStorage;
import universalelectricity.core.vector.Vector3;
/**
* Applied to all launcher TileEntitiies that operates the launching of
* missiles.
*
* @author Calclavia
*/
public interface ILauncherController extends IElectricalStorage,
IBlockFrequency {
/**
* What type of launcher is this?
*/
public LauncherType getLauncherType();
/**
* Launches the missile into the specified target.
*/
public void launch();
/**
* Can the launcher launch the missile?
*/
public boolean canLaunch();
/**
* @return The status of the launcher.
*/
public String getStatus();
/**
* @return The target of the launcher.
*/
public Vector3 getTarget();
/**
* @param target
* Sets the target of the launcher
*/
public void setTarget(Vector3 target);
/**
* Places a missile into the launcher.
*/
public void placeMissile(ItemStack itemStack);
public IMissile getMissile();
}

View file

@ -0,0 +1,55 @@
package icbm.api;
import icbm.api.explosion.IExplosiveContainer;
import universalelectricity.core.vector.Vector3;
/**
* This is an interface applied by all missile entities. You may cast this into
* an @Entity. The "set" version of the function will make the entity do the
* action on the next tick.
*
* @author Calclavia
*/
public interface IMissile extends IExplosiveContainer {
/**
* Blows up this missile. It will detonate the missile with the appropriate
* explosion.
*/
public void explode();
public void setExplode();
/**
* Blows up this missile like a TNT explosion. Small explosion used for
* events such as a missile crashing or failure to explode will result in
* this function being called.
*/
public void normalExplode();
public void setNormalExplode();
/**
* Drops the specified missile as an item.
*/
public void dropMissileAsItem();
/**
* The amount of ticks this missile has been flying for. Returns -1 if the
* missile is not flying.
*/
public int getTicksInAir();
/**
* Gets the launcher this missile is launched from.
*/
public ILauncherContainer getLauncher();
/**
* Launches the missile into a specific target.
*
* @param target
*/
public void launch(Vector3 target);
public void launch(Vector3 target, int height);
}

View file

@ -0,0 +1,30 @@
package icbm.api;
import universalelectricity.core.vector.Vector3;
/**
* Implement this to your entity if you want antiballistic missiles to be able
* to lock onto it.
*
* @author Calclavia
*
*/
public interface IMissileLockable {
/**
* Can this entity be locked on by a missile?
*
* @return True if so.
*/
public boolean canLock(IMissile missile);
/**
* Gets the predicted position of this entity after a specified amount of
* ticks.
*
* @param ticks
* - The amount of time.
* @return The predicted Vector, or if not predictable, the current
* position.
*/
public Vector3 getPredictedPosition(int ticks);
}

View file

@ -0,0 +1,24 @@
package icbm.api;
/**
* This interface should be applied to all things that has a tier/level.
*
* @author Calclavia
*
*/
public interface ITier {
/**
* Gets the tier of this object
*
* @return - The tier
*/
public int getTier();
/**
* Sets the tier of the object
*
* @param tier
* - The tier to be set
*/
public void setTier(int tier);
}

View file

@ -0,0 +1,11 @@
package icbm.api;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
public interface ITracker {
public void setTrackingEntity(ItemStack itemStack, Entity entity);
public Entity getTrackingEntity(World worldObj, ItemStack itemStack);
}

View file

@ -0,0 +1,11 @@
package icbm.api;
/**
* Types of missile launchers
*
* @author Calclavia
*
*/
public enum LauncherType {
TRADITIONAL, CRUISE
}

View file

@ -0,0 +1,121 @@
package icbm.api.explosion;
import net.minecraft.entity.Entity;
import net.minecraft.world.Explosion;
import net.minecraft.world.World;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
/**
* Use ForgeSubscribe to subscribe to this event. This event is called every
* single time when an ICBM explosion happens.
*
* @author Calclavia
*
*/
@Cancelable
public class ExplosionEvent extends Event {
/**
* The explosion object. Can be cast into {@link Explosion}. This event can
* be canceled to prevent a specific part of an explosion from being
* executed.
*/
public World world;
public double x, y, z;
public IExplosion iExplosion;
/**
* Pre-cast explosion class.
*/
public Explosion explosion;
public ExplosionEvent(World world, IExplosion iExplosion) {
this.world = world;
this.iExplosion = iExplosion;
this.x = ((Explosion) iExplosion).explosionX;
this.y = ((Explosion) iExplosion).explosionY;
this.z = ((Explosion) iExplosion).explosionZ;
}
/**
* Called before an explosive is detonated to check if detonation is
* possible. You may cancel and explosion here if needed. After this it will
* be a bit too late to prevent destruction without any losses.
*
* @author Calclavia
*
*/
@Cancelable
public static class ExplosivePreDetonationEvent extends Event {
public World world;
public Entity entity;
public double x, y, z;
public IExplosive explosion;
public ExplosiveType type;
public ExplosivePreDetonationEvent(World world, double x, double y,
double z, ExplosiveType type, IExplosive explosion) {
this.world = world;
this.type = type;
this.explosion = explosion;
}
public ExplosivePreDetonationEvent(World world, Entity entity,
ExplosiveType type, IExplosive explosion) {
this.world = world;
this.entity = entity;
this.type = type;
this.explosion = explosion;
}
}
/**
* Called when an explosion is constructed.
*
* @author Calclavia
*
*/
public static class ExplosionConstructionEvent extends ExplosionEvent {
public ExplosionConstructionEvent(World world, IExplosion explosion) {
super(world, explosion);
}
}
/**
* Called before an explosion happens.
*
* @author Calclavia
*
*/
public static class PreExplosionEvent extends ExplosionEvent {
public PreExplosionEvent(World world, IExplosion explosion) {
super(world, explosion);
}
}
/**
* Called while an explosion happens. May be called every single tick if
* explosion is procedural. (E.g: Red matter explosive)
*
* @author Calclavia
*
*/
public static class DoExplosionEvent extends ExplosionEvent {
public DoExplosionEvent(World world, IExplosion explosion) {
super(world, explosion);
}
}
/**
* Called after an explosion happens.
*
* @author Calclavia
*
*/
public static class PostExplosionEvent extends ExplosionEvent {
public PostExplosionEvent(World world, IExplosion explosion) {
super(world, explosion);
}
}
}

View file

@ -0,0 +1,21 @@
package icbm.api.explosion;
public enum ExplosiveType {
ALL,
/** An explosive in TNT block form. */
BLOCK,
/** An explosive in item form such as a grenade. */
ITEM,
/** An explosive in aircraft form such as a missile. */
AIR,
/** An explosive in vehicle form such as a minecart. */
VEHICLE;
public static ExplosiveType get(int id) {
if (id >= 0 && id < ExplosiveType.values().length) {
return ExplosiveType.values()[id];
}
return null;
}
}

View file

@ -0,0 +1,25 @@
package icbm.api.explosion;
import net.minecraft.world.World;
import universalelectricity.core.vector.Vector3;
/**
* Applied to all blocks that has a custom reaction to EMPs. Blocks not
* TileEntities.
*
* @author Calclavia
*
*/
public interface IEMPBlock {
/**
* Called when this block gets attacked by EMP.
*
* @param world
* - The world object.
* @param position
* - The position.
* @param empExplosive
* - The explosion
*/
public void onEMP(World world, Vector3 position, IExplosion empExplosive);
}

View file

@ -0,0 +1,26 @@
package icbm.api.explosion;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import universalelectricity.core.item.IItemElectric;
/**
* Applied to all items that can be protected from EMP somehow.
*
* @author Calclavia
*
*/
public interface IEMPItem extends IItemElectric {
/**
* Called when this item is being EMPed
*
* @param itemStack
* - The itemstack attacked by EMP
* @param entity
* - The entity holding the item
* @param empExplosives
* - The IExplosive object
*/
public void onEMP(ItemStack itemStack, Entity entity,
IExplosion empExplosive);
}

View file

@ -0,0 +1,25 @@
package icbm.api.explosion;
/**
* The actual explosion interface. Extends Explosion.java.
*
* @author Calclavia
*
*/
public interface IExplosion {
/**
* Called to initiate the explosion.
*/
public void explode();
/**
* @return The radius of effect of the explosion.
*/
public float getRadius();
/**
* @return The energy emitted by this explosive. In Joules and approximately
* based off of a real life equivalent.
*/
public float getEnergy();
}

View file

@ -0,0 +1,70 @@
package icbm.api.explosion;
import icbm.api.ITier;
import net.minecraft.entity.Entity;
import net.minecraft.world.World;
/**
* An interface used to find various types of explosive's information.
*
* @author Calclavia
*
*/
public interface IExplosive extends ITier {
/**
* @return Gets the explosive's ID.
*/
public int getID();
/**
* @return The unique name key in the ICBM language file.
*/
public String getUnlocalizedName();
/**
* @return Gets the specific translated name of the block versions of the
* explosive.
*/
public String getExplosiveName();
/**
* @return Gets the specific translated name of the grenade versions of the
* explosive.
*/
public String getGrenadeName();
/**
* @return Gets the specific translated name of the missile versions of the
* explosive.
*/
public String getMissileName();
/**
* @return Gets the specific translated name of the minecart versions of the
* explosive.
*/
public String getMinecartName();
/**
* @return The tier of the explosive.
*/
@Override
public int getTier();
/**
* Creates a new explosion at a given location.
*
* @param world
* The world in which the explosion takes place.
* @param x
* The X-Coord
* @param y
* The Y-Coord
* @param z
* The Z-Coord
* @param entity
* Entity that caused the explosion.
*/
public void createExplosion(World world, double x, double y, double z,
Entity entity);
}

View file

@ -0,0 +1,16 @@
package icbm.api.explosion;
import net.minecraft.nbt.NBTTagCompound;
/**
* An object that contains a reference to IExplosive. Carried by explosives,
* grenades and missile entities etc.
*
* @author Calclavia
*
*/
public interface IExplosiveContainer {
public NBTTagCompound getTagCompound();
public IExplosive getExplosiveType();
}

View file

@ -0,0 +1,11 @@
package icbm.api.explosion;
/**
* Applied to entities that ignore the affects of a specific explosion.
*
* @author Calclavia
*
*/
public interface IExplosiveIgnore {
public boolean canIgnore(IExplosion explosion);
}

View file

@ -0,0 +1,38 @@
package icbm.api.sentry;
/**
* Apply this to an entity if it is meant to be targeted by the AA Turret.
*
* @author Calclavia
*
*/
public interface IAATarget {
/**
* destroys the target with a boom. This is a forced way for the sentry too
* kill the target if it doesn't take damage
*/
public void destroyCraft();
/**
* Applies damage to the the target
*
* @param damage
* - damage in half HP
* @return the amount of HP left. Return -1 if this target can't take
* damage, and will be chance killed. Return 0 if this target is
* dead and destroyCraft() will be called.
*/
public int doDamage(int damage);
/**
* Can this be targeted by automated targeting systems or AIs. Used to
* implement radar jammers, cloaking devices, and other addons for the
* Entity being targeted
*
* @param entity
* - entity that is targeting this, can be an Entity,
* EntityLiving, or TileEntity
* @return true if it can
*/
public boolean canBeTargeted(Object entity);
}

View file

@ -0,0 +1,34 @@
/**
* Copyright (c) <2012>, Oleg Romanovskiy <shedarhome@gmail.com> aka Shedar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.modstats;
public interface IModstatsReporter
{
public void registerMod(Object mod);
public void doManualCheck();
}

View file

@ -0,0 +1,114 @@
/**
* Copyright (c) <2012>, Oleg Romanovskiy <shedarhome@gmail.com> aka Shedar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.modstats;
import java.util.HashMap;
import java.util.Map;
public class ModVersionData
{
public String prefix;
public String name;
public String version;
public String downloadUrl;
public String changeLogUrl;
public Map<String, String> extraFields;
public ModVersionData()
{
extraFields = new HashMap<String, String>();
}
public ModVersionData(String prefix, String name, String version)
{
this.prefix = prefix;
this.name = name;
this.version = version;
extraFields = new HashMap<String, String>();
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((changeLogUrl == null) ? 0 : changeLogUrl.hashCode());
result = prime * result + ((downloadUrl == null) ? 0 : downloadUrl.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ModVersionData other = (ModVersionData) obj;
if (changeLogUrl == null)
{
if (other.changeLogUrl != null)
return false;
} else if (!changeLogUrl.equals(other.changeLogUrl))
return false;
if (downloadUrl == null)
{
if (other.downloadUrl != null)
return false;
} else if (!downloadUrl.equals(other.downloadUrl))
return false;
if (name == null)
{
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (prefix == null)
{
if (other.prefix != null)
return false;
} else if (!prefix.equals(other.prefix))
return false;
if (version == null)
{
if (other.version != null)
return false;
} else if (!version.equals(other.version))
return false;
return true;
}
}

View file

@ -0,0 +1,64 @@
/**
* Copyright (c) <2012>, Oleg Romanovskiy <shedarhome@gmail.com> aka Shedar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.modstats;
import java.util.LinkedList;
import java.util.List;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
import cpw.mods.fml.common.FMLLog;
@Cancelable
public class ModsUpdateEvent extends Event
{
private List<ModVersionData> updatedMods;
public ModsUpdateEvent()
{
updatedMods = new LinkedList<ModVersionData>();
}
public void add(ModVersionData data)
{
if(!updatedMods.contains(data))
{
updatedMods.add(data);
}
else
{
FMLLog.info("ModsUpdateEvent shouldn't have same mods data", data);
}
}
public List<ModVersionData> getUpdatedMods()
{
return updatedMods;
}
}

View file

@ -0,0 +1,56 @@
/**
* Copyright (c) <2012>, Oleg Romanovskiy <shedarhome@gmail.com> aka Shedar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.modstats;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ModstatInfo
{
/**
* Modstats mod prefix.
* @return
*/
public String prefix();
/**
* Mod name. Use this if your mod doesn't have @Mod annotation
* @return
*/
public String name() default "";
/**
* Mod version. Use this if your mod doesn't have @Mod annotation
* @return
*/
public String version() default "";
}

View file

@ -0,0 +1,89 @@
/**
* Copyright (c) <2012>, Oleg Romanovskiy <shedarhome@gmail.com> aka Shedar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.modstats;
import cpw.mods.fml.common.FMLLog;
public class Modstats
{
private static final Modstats INSTANCE = new Modstats();
private static final String CLASS_TEMPLATE = "org.modstats.reporter.v%d.Reporter";
private IModstatsReporter reporter;
private Modstats()
{
reporter = locateReporter();
}
public IModstatsReporter getReporter()
{
return reporter;
}
private IModstatsReporter locateReporter()
{
int i=1;
Class<?> latest = null;
while(i<100)
{
try
{
Class<?> candidate = Class.forName(String.format(CLASS_TEMPLATE, i));
if(IModstatsReporter.class.isAssignableFrom(candidate))
{
latest = candidate;
}
}
catch (Exception e) {
break;
}
i++;
}
if(latest == null)
{
FMLLog.warning("Modstats reporter class not found.");
}
else
{
try
{
return (IModstatsReporter)latest.newInstance();
} catch (Exception e)
{
FMLLog.warning("Modstats reporter class can't be instantiated.");
}
}
return null;
}
public static Modstats instance()
{
return INSTANCE;
}
}

View file

@ -0,0 +1,73 @@
/**
* Copyright (c) <2012>, Oleg Romanovskiy <shedarhome@gmail.com> aka Shedar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.modstats.reporter.v1;
import java.io.File;
import net.minecraftforge.common.Configuration;
import net.minecraftforge.common.Property;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
public class Config
{
private static final String CONFIG_NAME = "modstats.cfg";
public boolean allowUpdates;
public boolean betaNotifications;
public boolean forCurrentMinecraftVersion;
public boolean logOnly;
public Config()
{
File configLocation = new File(Loader.instance().getConfigDir(), CONFIG_NAME);
Configuration configuration = new Configuration(configLocation);
configuration.load();
Property prop = configuration.get("updates", "AllowUpdates", true);
prop.comment = "Allow to send current mod versions to the server and check for updates.\nIt allows to mod authors to see mod's popularity. Please don't disable it without necessity";
allowUpdates = prop.getBoolean(true);
prop = configuration.get("updates", "LogOnly", false);
prop.comment = "Don't display chat message, just add message to the log.";
logOnly = prop.getBoolean(false);
prop = configuration.get("updates", "BetaNotifications", false);
prop.comment = "Set true to receive notifications about beta versions. Otherwise you will only receive information about stable versions";
betaNotifications = prop.getBoolean(false);
prop = configuration.get("updates", "ForCurrentMinecraftVersion", false);
prop.comment = "Check for updates only for current MC version.\nEx:if you have MC 1.4.2 and ForCurrentMinecraftVersion is true, then you wouldn't receive notifications about versions for MC 1.4.5";
forCurrentMinecraftVersion = prop.getBoolean(false);
configuration.save();
FMLLog.info("[Modstats] Config loaded. allowUpdates: %b, betaNotification: %b, strict: %b", allowUpdates, betaNotifications, forCurrentMinecraftVersion);
}
}

View file

@ -0,0 +1,294 @@
/**
* Copyright (c) <2012>, Oleg Romanovskiy <shedarhome@gmail.com> aka Shedar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.modstats.reporter.v1;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.NetworkInterface;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import net.minecraft.client.Minecraft;
import net.minecraft.crash.CallableMinecraftVersion;
import net.minecraftforge.common.MinecraftForge;
import org.modstats.ModVersionData;
import org.modstats.ModsUpdateEvent;
import argo.jdom.JdomParser;
import argo.jdom.JsonNode;
import argo.jdom.JsonRootNode;
import argo.jdom.JsonStringNode;
import argo.saj.InvalidSyntaxException;
import com.google.common.base.Charsets;
import com.google.common.hash.Hashing;
import com.google.common.io.Files;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.versioning.ComparableVersion;
class DataSender extends Thread
{
private static final String urlAutoTemplate = "http://modstats.org/api/v1/report?mc=%s&user=%s&data=%s&sign=%s&beta=%b&strict=%b";
private static final String urlManualTemplate = "http://modstats.org/api/v1/check?mc=%s&user=%s&data=%s&sign=%s&beta=%b&strict=%b";
private final Reporter reporter;
public final boolean manual;
public DataSender(Reporter reporter, boolean manual)
{
this.reporter = reporter;
this.manual = manual;
}
private String toHexString(byte[] bytes) {
char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
char[] hexChars = new char[bytes.length * 2];
int v;
for ( int j = 0; j < bytes.length; j++ ) {
v = bytes[j] & 0xFF;
hexChars[j*2] = hexArray[v/16];
hexChars[j*2 + 1] = hexArray[v%16];
}
return new String(hexChars);
}
private String getPlayerId() throws IOException
{
File statDir = new File(Minecraft.getMinecraft().mcDataDir, "stats");
if(!statDir.exists())
{
statDir.mkdirs();
}
String mac = "";
try
{
InetAddress address = InetAddress.getLocalHost();
NetworkInterface ni = NetworkInterface.getByInetAddress(address);
byte[] macArray = ni.getHardwareAddress();
if(macArray != null)
{
mac = toHexString(macArray);
}
}
catch(Exception ex)
{
}
File uidFile = new File(statDir, "player.uid");
if(uidFile.exists() && uidFile.canRead() && uidFile.length() == 32+mac.length())
{
String data = Files.toString(uidFile, Charsets.US_ASCII);
String storedMac = data.substring(32);
if(storedMac.equalsIgnoreCase(mac))
return data.substring(0, 32);
}
uidFile.createNewFile();
if(uidFile.canWrite())
{
String uid = UUID.randomUUID().toString().replace("-", "");
FileOutputStream output = new FileOutputStream(uidFile);
output.write((uid+mac).getBytes());
output.close();
return uid;
}
return "";
}
private String getSignature(String data)
{
return Hashing.md5().hashString(data).toString();
}
private String getData()
{
StringBuilder b = new StringBuilder();
for (Map.Entry<String, ModVersionData> item : reporter.registeredMods.entrySet())
{
b.append(item.getKey()).append("+").append(item.getValue().version).append("$");
}
return b.toString();
}
private boolean checkIsNewer(String current, String received)
{
return new ComparableVersion(received).compareTo(new ComparableVersion(current)) > 0;
}
private void parseResponse(String response)
{
try
{
JsonRootNode json = (new JdomParser()).parse(response);
//empty result
if(!json.isNode("mods"))
{
FMLLog.info("[Modstats] Empty result");
return;
}
List<JsonNode> modList = json.getArrayNode("mods");
ModsUpdateEvent event = new ModsUpdateEvent();
for (JsonNode modObject : modList)
{
String prefix = modObject.getStringValue("code");
if(!reporter.registeredMods.containsKey(prefix))
{
FMLLog.warning("[Modstats] Extra mod '%s' in service response", prefix);
continue;
}
String version = modObject.getStringValue("ver");
if(version==null || version.equals(reporter.registeredMods.get(prefix).version))
{
continue;
}
if(checkIsNewer(reporter.registeredMods.get(prefix).version, version))
{
ModVersionData data = new ModVersionData(prefix, reporter.registeredMods.get(prefix).name, version);
Map<JsonStringNode, JsonNode> fields = modObject.getFields();
for (Map.Entry<JsonStringNode, JsonNode> entry : fields.entrySet())
{
String fieldName = entry.getKey().getText();
if(fieldName.equals("code") || fieldName.equals("ver"))
continue;
if(!(entry.getValue() instanceof JsonStringNode))
{
FMLLog.warning(String.format("[Modstats] Too complex data in response for field '%s'.", fieldName));
continue;
}
String value = ((JsonStringNode)entry.getValue()).getText();
if(fieldName.equals("chlog"))
{
data.changeLogUrl = value;
}
else if(fieldName.equals("link"))
{
data.downloadUrl = value;
}
else
{
data.extraFields.put(fieldName, value);
}
}
event.add(data);
}
}
if(event.getUpdatedMods().size() > 0)
{
MinecraftForge.EVENT_BUS.post(event);
}
if(!event.isCanceled() && event.getUpdatedMods().size() > 0)
{
List<ModVersionData> updatedModsToOutput = event.getUpdatedMods();
StringBuilder builder = new StringBuilder("Updates found: ");
Iterator<ModVersionData> iterator = updatedModsToOutput.iterator();
while(iterator.hasNext())
{
ModVersionData modVersionData = iterator.next();
builder.append(modVersionData.name)
.append(" (")
.append(modVersionData.version)
.append(")")
.append(iterator.hasNext()?",":".");
}
FMLLog.info("[Modstats] %s", builder.toString());
if(!reporter.config.logOnly && FMLCommonHandler.instance().getSide().isClient())
{
Minecraft mc = FMLClientHandler.instance().getClient();
int maxTries = 30;
while(mc.thePlayer==null && maxTries>0)
{
try
{
sleep(1000);
} catch (InterruptedException e)
{
}
maxTries--;
}
if(mc.thePlayer != null)
{
mc.thePlayer.addChatMessage(builder.toString());
}
}
}
} catch (InvalidSyntaxException e)
{
FMLLog.warning("[Modstats] Can't parse response: '%s'.", e.getMessage());
}
}
@Override
public void run()
{
try
{
String data = getData();
String playerId = getPlayerId();
String hash = getSignature(playerId+"!"+data);
String template = manual?urlManualTemplate:urlAutoTemplate;
String mcVersion = new CallableMinecraftVersion(null).minecraftVersion();
URL url = new URL(String.format(template, mcVersion, playerId, data, hash, reporter.config.betaNotifications, reporter.config.forCurrentMinecraftVersion));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
String out = "";
while ((line = reader.readLine()) != null) {
//in most cases it will contain just one line
out += line;
}
reader.close();
parseResponse(out);
} catch (MalformedURLException e)
{
FMLLog.warning("[Modstats] Invalid stat report url");
} catch (IOException e)
{
FMLLog.info("[Modstats] Stat wasn't reported '"+e.getMessage()+"'");
} catch(Exception e)
{
FMLLog.warning("[Modstats] Something wrong: "+e.toString());
}
}
}

View file

@ -0,0 +1,145 @@
/**
* Copyright (c) <2012>, Oleg Romanovskiy <shedarhome@gmail.com> aka Shedar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.modstats.reporter.v1;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.ForgeSubscribe;
import net.minecraftforge.event.world.WorldEvent;
import org.modstats.IModstatsReporter;
import org.modstats.ModVersionData;
import org.modstats.ModstatInfo;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Mod;
public class Reporter implements IModstatsReporter
{
public Map<String, ModVersionData> registeredMods;
private DataSender sender;
public Config config;
/**
* At least one auto check was completed successfully
*/
private boolean checkedAuto;
public Reporter()
{
checkedAuto = false;
registeredMods = new ConcurrentHashMap<String, ModVersionData>(2, 0.9f, 1);
MinecraftForge.EVENT_BUS.register(this);
config = new Config();
}
private void startCheck(boolean manual)
{
if(!config.allowUpdates)
return;
//only manual check is allowed on servers
if(!FMLCommonHandler.instance().getSide().isClient() && !manual)
return;
if(registeredMods.isEmpty())
return;
DataSender currentSender = sender;
if(!manual && checkedAuto)
return;
if(currentSender!=null && (currentSender.manual == false || manual))
return;
currentSender = new DataSender(this, manual);
currentSender.start();
sender = currentSender;
}
@ForgeSubscribe
public void worldLoad(WorldEvent.Load event)
{
startCheck(false);
}
@Override
public void registerMod(Object mod)
{
if(!config.allowUpdates)
return;
if(mod == null)
{
FMLLog.warning("[Modstats] Can't register null mod.");
return;
}
ModstatInfo info = mod.getClass().getAnnotation(ModstatInfo.class);
if(info == null)
{
FMLLog.warning("[Modstats] ModstatsInfo annotation not found for given mod.");
return;
}
if(info.prefix() == null || info.prefix().equals(""))
{
FMLLog.warning("[Modstats] Mod prefix can't be empty.");
return;
}
Mod modData = mod.getClass().getAnnotation(Mod.class);
ModVersionData data;
if(modData == null)
{
if(info.name() == null || info.name().equals(""))
{
FMLLog.warning("[Modstats] Mod name can't be empty.");
return;
}
if(info.version() == null || info.version().equals(""))
{
FMLLog.warning("[Modstats] Mod version can't be empty.");
return;
}
data = new ModVersionData(info.prefix(), info.name(), info.version());
}
else
{
data = new ModVersionData(info.prefix(), modData.name(), modData.version());
}
registeredMods.put(info.prefix(), data);
}
@Override
public void doManualCheck()
{
startCheck(true);
}
}

View file

@ -0,0 +1,46 @@
package thermalexpansion.api.item;
import net.minecraft.item.ItemStack;
/**
* Implement this interface on Item classes that support external manipulation of their internal
* energy storages. This interface does not provide methods for the underlying internal energy
* usage.
*/
public interface IChargeableItem
{
/**
* Adds energy to an item. Returns the quantity of energy that was accepted. This should always
* return 0 if the item cannot be externally charged.
*
* @param theItem ItemStack to be charged.
* @param energy Maximum amount of energy to be sent into the item.
* @param doReceive If false, the charge will only be simulated.
* @return Amount of energy that was accepted by the item.
*/
public float receiveEnergy(ItemStack theItem, float energy, boolean doReceive);
/**
* Removes energy from an item. Returns the quantity of energy that was removed. This should
* always return 0 if the item cannot be externally discharged.
*
* @param theItem ItemStack to be discharged.
* @param energy Maximum amount of energy to be removed from the item.
* @param doTransfer If false, the discharge will only be simulated.
* @return Amount of energy that was removed from the item.
*/
public float transferEnergy(ItemStack theItem, float energy, boolean doTransfer);
/**
* Get the amount of energy currently stored in the item.
*/
public float getEnergyStored(ItemStack theItem);
/**
* Get the max amount of energy that can be stored in the item.
*/
public float getMaxEnergyStored(ItemStack theItem);
}

View file

@ -0,0 +1,56 @@
package universalelectricity.compatibility;
import universalelectricity.core.UniversalElectricity;
import universalelectricity.core.electricity.NetworkLoader;
import cpw.mods.fml.common.Loader;
/**
* The Universal Electricity compatiblity module allows your mod to be compatible with most major
* power systems in Minecraft.
*
* @author Calclavia, Micdoodle
*
*/
public class Compatibility
{
/**
* Universal Electricity measures in Kilowatts.
*
* Multiply this to convert foreign energy into UE Joules.
*/
public static float BC3_RATIO = 1;
public static float IC2_RATIO = 0.4f;
/**
* Multiply this to convert UE Joules into foreign energy. The reciprocal conversion ratio.
*/
public static float TO_IC2_RATIO = 1 / IC2_RATIO;
public static float TO_BC_RATIO = 1 / BC3_RATIO;
/**
* You must call this function to enable the Universal Network module.
*/
public static void initiate()
{
/**
* Loads the configuration and sets all the values.
*/
UniversalElectricity.CONFIGURATION.load();
IC2_RATIO = (float) UniversalElectricity.CONFIGURATION.get("Compatiblity", "IndustrialCraft Conversion Ratio", IC2_RATIO).getDouble(IC2_RATIO);
BC3_RATIO = (float) UniversalElectricity.CONFIGURATION.get("Compatiblity", "BuildCraft Conversion Ratio", BC3_RATIO).getDouble(BC3_RATIO);
TO_IC2_RATIO = 1 / IC2_RATIO;
TO_BC_RATIO = 1 / BC3_RATIO;
UniversalElectricity.CONFIGURATION.save();
NetworkLoader.setNetworkClass(UniversalNetwork.class);
}
public static boolean isIndustrialCraft2Loaded()
{
return Loader.isModLoaded("IC2");
}
public static boolean isBuildcraftLoaded()
{
return Loader.isModLoaded("BuildCraft|Energy");
}
}

View file

@ -0,0 +1,150 @@
package universalelectricity.compatibility;
import ic2.api.item.IElectricItemManager;
import ic2.api.item.ISpecialElectricItem;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import thermalexpansion.api.item.IChargeableItem;
import universalelectricity.core.item.IItemElectric;
import universalelectricity.core.item.ItemElectric;
public abstract class ItemUniversalElectric extends ItemElectric implements ISpecialElectricItem, IChargeableItem
{
public static final float CHARGE_RATE = 0.005f;
public ItemUniversalElectric(int id)
{
super(id);
}
/**
* IC2
*/
@Override
public int getChargedItemId(ItemStack itemStack)
{
return this.itemID;
}
@Override
public int getEmptyItemId(ItemStack itemStack)
{
return this.itemID;
}
@Override
public int getMaxCharge(ItemStack itemStack)
{
return (int) (this.getMaxElectricityStored(itemStack) * Compatibility.TO_IC2_RATIO);
}
@Override
public int getTier(ItemStack itemStack)
{
return 1;
}
@Override
public int getTransferLimit(ItemStack itemStack)
{
return (int) ((this.getMaxElectricityStored(itemStack) * CHARGE_RATE) * Compatibility.TO_IC2_RATIO);
}
@Override
public IElectricItemManager getManager(ItemStack itemStack)
{
return IC2ElectricItemManager.MANAGER;
}
@Override
public boolean canProvideEnergy(ItemStack itemStack)
{
return this.recharge(itemStack, 1, false) > 0;
}
/**
* Thermal Expansion
*/
@Override
public float receiveEnergy(ItemStack theItem, float energy, boolean doReceive)
{
return this.recharge(theItem, energy * Compatibility.BC3_RATIO, doReceive) * Compatibility.TO_BC_RATIO;
}
@Override
public float transferEnergy(ItemStack theItem, float energy, boolean doTransfer)
{
return this.discharge(theItem, energy * Compatibility.BC3_RATIO, doTransfer) * Compatibility.TO_BC_RATIO;
}
@Override
public float getEnergyStored(ItemStack theItem)
{
return this.getElectricityStored(theItem) * Compatibility.TO_BC_RATIO;
}
@Override
public float getMaxEnergyStored(ItemStack theItem)
{
return this.getMaxElectricityStored(theItem) * Compatibility.TO_BC_RATIO;
}
public static class IC2ElectricItemManager implements IElectricItemManager
{
public static final IElectricItemManager MANAGER = new IC2ElectricItemManager();
private IItemElectric getElectricItem(ItemStack itemStack)
{
if (itemStack.getItem() instanceof IItemElectric)
{
return ((IItemElectric) itemStack.getItem());
}
return null;
}
@Override
public int charge(ItemStack itemStack, int amount, int tier, boolean ignoreTransferLimit, boolean simulate)
{
float inputElectricity = amount * Compatibility.IC2_RATIO;
return (int) (getElectricItem(itemStack).recharge(itemStack, inputElectricity, !simulate) * Compatibility.TO_IC2_RATIO);
}
@Override
public int discharge(ItemStack itemStack, int amount, int tier, boolean ignoreTransferLimit, boolean simulate)
{
float outputElectricity = amount * Compatibility.IC2_RATIO;
return (int) (getElectricItem(itemStack).discharge(itemStack, outputElectricity, !simulate) * Compatibility.TO_IC2_RATIO);
}
@Override
public boolean canUse(ItemStack itemStack, int amount)
{
return false;
}
@Override
public int getCharge(ItemStack itemStack)
{
return 0;
}
@Override
public boolean use(ItemStack itemStack, int amount, EntityLivingBase entity)
{
return false;
}
@Override
public void chargeFromArmor(ItemStack itemStack, EntityLivingBase entity)
{
}
@Override
public String getToolTip(ItemStack itemStack)
{
return null;
}
}
}

View file

@ -0,0 +1,224 @@
package universalelectricity.compatibility;
import ic2.api.Direction;
import ic2.api.energy.event.EnergyTileLoadEvent;
import ic2.api.energy.event.EnergyTileUnloadEvent;
import ic2.api.energy.tile.IEnergyAcceptor;
import ic2.api.energy.tile.IEnergySink;
import ic2.api.energy.tile.IEnergyTile;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.common.MinecraftForge;
import universalelectricity.core.block.IConnector;
import universalelectricity.core.electricity.ElectricityPack;
import universalelectricity.core.grid.IElectricityNetwork;
import universalelectricity.core.vector.Vector3;
import universalelectricity.core.vector.VectorHelper;
import universalelectricity.prefab.tile.TileEntityConductor;
import buildcraft.api.power.IPowerReceptor;
import buildcraft.api.power.PowerHandler;
import buildcraft.api.power.PowerHandler.PowerReceiver;
/**
* A universal conductor class.
*
* Extend this class or use as a reference for your own implementation of compatible conductor
* tiles.
*
* @author micdoodle8
*
*/
public abstract class TileEntityUniversalConductor extends TileEntityConductor implements IEnergySink, IPowerReceptor
{
protected boolean addedToIC2Network = false;
/*
* private DummyPowerProvider powerProvider;
*
* public TileEntityUniversalConductor() { this.powerProvider = new
* DummyPowerProvider(this.getNetwork(), this); this.powerProvider.configure(0, 0, 100, 0, 100);
* }
*/
@Override
public void setNetwork(IElectricityNetwork network)
{
super.setNetwork(network);
/*
* if (this.powerProvider != null) { this.powerProvider.network = network; }
*/
}
@Override
public void invalidate()
{
this.unloadTileIC2();
super.invalidate();
}
@Override
public void onChunkUnload()
{
this.unloadTileIC2();
super.onChunkUnload();
}
private void unloadTileIC2()
{
if (this.addedToIC2Network && this.worldObj != null)
{
if (Compatibility.isIndustrialCraft2Loaded())
{
MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
}
this.addedToIC2Network = false;
}
}
@Override
public boolean canUpdate()
{
return true;
}
@Override
public void updateEntity()
{
super.updateEntity();
if (!this.worldObj.isRemote && !this.addedToIC2Network)
{
if (Compatibility.isIndustrialCraft2Loaded())
{
MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
}
this.addedToIC2Network = true;
}
}
/**
* IC2 Methods
*/
@Override
public boolean acceptsEnergyFrom(TileEntity emitter, Direction direction)
{
return emitter instanceof IEnergyTile;
}
@Override
public boolean isAddedToEnergyNet()
{
return this.addedToIC2Network;
}
@Override
public int demandsEnergy()
{
if (this.getNetwork() == null)
{
return 0;
}
return (int) Math.floor(Math.min(this.getNetwork().getRequest(this).getWatts() * Compatibility.TO_IC2_RATIO, 100));
}
@Override
public int injectEnergy(Direction directionFrom, int amount)
{
if (this.getNetwork() == null)
{
return amount;
}
return (int) Math.floor(this.getNetwork().produce(ElectricityPack.getFromWatts(amount, 120), VectorHelper.getTileEntityFromSide(this.worldObj, new Vector3(this), directionFrom.toForgeDirection())));
}
@Override
public int getMaxSafeInput()
{
return Integer.MAX_VALUE;
}
@Override
public TileEntity[] getAdjacentConnections()
{
TileEntity[] adjecentConnections = new TileEntity[6];
for (byte i = 0; i < 6; i++)
{
ForgeDirection side = ForgeDirection.getOrientation(i);
TileEntity tileEntity = VectorHelper.getTileEntityFromSide(this.worldObj, new Vector3(this), side);
if (tileEntity instanceof IConnector)
{
if (((IConnector) tileEntity).canConnect(side.getOpposite()))
{
adjecentConnections[i] = tileEntity;
}
}
else if (Compatibility.isIndustrialCraft2Loaded() && tileEntity instanceof IEnergyTile)
{
if (tileEntity instanceof IEnergyAcceptor)
{
if (((IEnergyAcceptor) tileEntity).acceptsEnergyFrom(this, Direction.values()[(i + 2) % 6].getInverse()))
{
adjecentConnections[i] = tileEntity;
}
}
else
{
adjecentConnections[i] = tileEntity;
}
}
else if (Compatibility.isBuildcraftLoaded() && tileEntity instanceof IPowerReceptor)
{
adjecentConnections[i] = tileEntity;
}
}
return adjecentConnections;
}
/**
* BuildCraft Methods
*/
@Override
public PowerReceiver getPowerReceiver(ForgeDirection side)
{
return null;
}
@Override
public void doWork(PowerHandler workProvider)
{
}
@Override
public World getWorld()
{
return this.getWorldObj();
}
/*
* @Override public int powerRequest(ForgeDirection from) { if (this.getNetwork() == null) {
* return 0; }
*
* return (int)
* Math.floor(Math.min(this.getNetwork().getRequest(VectorHelper.getTileEntityFromSide
* (this.worldObj, new Vector3(this), from)).getWatts() * Compatibility.TO_BC_RATIO, 100)); }
*/
/*
* private class DummyPowerProvider extends PowerProvider { public IElectricityNetwork network;
* private final TileEntityUniversalConductor conductor;
*
* public DummyPowerProvider(IElectricityNetwork network, TileEntityUniversalConductor
* conductor) { this.network = network; this.conductor = conductor; }
*
* @Override public void receiveEnergy(float quantity, ForgeDirection from) { if (this.network
* != null) { this.network.produce(ElectricityPack.getFromWatts(this.getEnergyStored(), 120),
* VectorHelper.getTileEntityFromSide(this.conductor.worldObj, new Vector3(this.conductor),
* from)); } } }
*/
}

View file

@ -0,0 +1,240 @@
package universalelectricity.compatibility;
import ic2.api.Direction;
import ic2.api.energy.event.EnergyTileLoadEvent;
import ic2.api.energy.event.EnergyTileSourceEvent;
import ic2.api.energy.event.EnergyTileUnloadEvent;
import ic2.api.energy.tile.IEnergySink;
import ic2.api.energy.tile.IEnergySource;
import ic2.api.energy.tile.IEnergyTile;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.common.MinecraftForge;
import universalelectricity.core.electricity.ElectricityPack;
import universalelectricity.core.vector.Vector3;
import universalelectricity.prefab.tile.TileEntityElectrical;
import buildcraft.api.power.IPowerReceptor;
import buildcraft.api.power.PowerHandler;
import buildcraft.api.power.PowerHandler.PowerReceiver;
import buildcraft.api.power.PowerHandler.Type;
/**
* A universal electricity tile used for tiles that consume or produce electricity.
*
* Extend this class or use as a reference for your own implementation of compatible electrical
* tiles.
*
* @author micdoodle8, Calclavia
*
*/
public abstract class TileEntityUniversalElectrical extends TileEntityElectrical implements IEnergySink, IEnergySource, IPowerReceptor
{
protected boolean isAddedToEnergyNet;
public PowerHandler bcPowerHandler;
public Type bcBlockType = Type.MACHINE;
public void initiate()
{
super.initiate();
this.bcPowerHandler = new PowerHandler(this, this.bcBlockType);
this.bcPowerHandler.configure(0, 100, 0, (int) Math.ceil(this.getMaxEnergyStored() * Compatibility.BC3_RATIO));
}
@Override
public void updateEntity()
{
super.updateEntity();
// Register to the IC2 Network
if (!this.worldObj.isRemote && !this.isAddedToEnergyNet)
{
if (Compatibility.isIndustrialCraft2Loaded())
{
MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
}
this.isAddedToEnergyNet = true;
}
this.produce();
}
@Override
public void produce()
{
if (!this.worldObj.isRemote)
{
for (ForgeDirection outputDirection : this.getOutputDirections())
{
this.produceUE(outputDirection);
this.produceIC2(outputDirection);
this.produceBuildCraft(outputDirection);
}
}
if (Compatibility.isBuildcraftLoaded())
{
/**
* Cheat BuildCraft powerHandler and always empty energy inside of it.
*/
this.receiveElectricity(this.bcPowerHandler.getEnergyStored(), true);
this.bcPowerHandler.setEnergy(0);
}
}
public void produceIC2(ForgeDirection outputDirection)
{
if (!this.worldObj.isRemote)
{
float provide = this.getProvide(outputDirection);
if (this.getEnergyStored() >= provide && provide > 0)
{
if (Compatibility.isIndustrialCraft2Loaded())
{
int ic2Provide = (int) Math.ceil(provide * Compatibility.TO_IC2_RATIO);
EnergyTileSourceEvent event = new EnergyTileSourceEvent(this, ic2Provide);
MinecraftForge.EVENT_BUS.post(event);
this.setEnergyStored(this.getEnergyStored() - ((ic2Provide * Compatibility.IC2_RATIO) - (event.amount * Compatibility.IC2_RATIO)));
}
}
}
}
public void produceBuildCraft(ForgeDirection outputDirection)
{
if (!this.worldObj.isRemote)
{
float provide = this.getProvide(outputDirection);
if (this.getEnergyStored() >= provide && provide > 0)
{
if (Compatibility.isBuildcraftLoaded())
{
TileEntity tileEntity = new Vector3(this).modifyPositionFromSide(outputDirection).getTileEntity(this.worldObj);
if (tileEntity instanceof IPowerReceptor)
{
PowerReceiver receiver = ((IPowerReceptor) tileEntity).getPowerReceiver(outputDirection.getOpposite());
if (receiver != null)
{
float bc3Provide = provide * Compatibility.TO_BC_RATIO;
float energyUsed = Math.min(receiver.receiveEnergy(this.bcBlockType, bc3Provide, outputDirection.getOpposite()), bc3Provide);
this.setEnergyStored(this.getEnergyStored() - (bc3Provide - (energyUsed * Compatibility.TO_BC_RATIO)));
}
}
}
}
}
}
/**
* IC2 Methods
*/
@Override
public boolean acceptsEnergyFrom(TileEntity emitter, Direction direction)
{
return this.canConnect(direction.toForgeDirection());
}
@Override
public boolean isAddedToEnergyNet()
{
return this.isAddedToEnergyNet;
}
@Override
public void invalidate()
{
this.unloadTileIC2();
super.invalidate();
}
@Override
public void onChunkUnload()
{
this.unloadTileIC2();
super.onChunkUnload();
}
private void unloadTileIC2()
{
if (this.isAddedToEnergyNet && this.worldObj != null)
{
if (Compatibility.isIndustrialCraft2Loaded())
{
MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
}
this.isAddedToEnergyNet = false;
}
}
@Override
public int demandsEnergy()
{
return (int) Math.ceil(this.getRequest(ForgeDirection.UNKNOWN) * Compatibility.TO_IC2_RATIO);
}
@Override
public int injectEnergy(Direction directionFrom, int amount)
{
if (!directionFrom.toForgeDirection().equals(this.getInputDirections()))
{
return amount;
}
float convertedEnergy = amount * Compatibility.IC2_RATIO;
ElectricityPack toSend = ElectricityPack.getFromWatts(convertedEnergy, this.getVoltage());
int receive = (int) Math.floor(this.receiveElectricity(directionFrom.toForgeDirection(), toSend, true));
// Return the difference, since injectEnergy returns left over energy, and
// receiveElectricity returns energy used.
return (int) Math.floor(amount - receive * Compatibility.TO_IC2_RATIO);
}
@Override
public int getMaxEnergyOutput()
{
return (int) Math.ceil(this.getProvide(ForgeDirection.UNKNOWN));
}
@Override
public boolean emitsEnergyTo(TileEntity receiver, Direction direction)
{
return receiver instanceof IEnergyTile && direction.toForgeDirection().equals(this.getOutputDirections());
}
@Override
public int getMaxSafeInput()
{
return Integer.MAX_VALUE;
}
/**
* BuildCraft power support
*/
@Override
public PowerReceiver getPowerReceiver(ForgeDirection side)
{
return this.bcPowerHandler.getPowerReceiver();
}
@Override
public void doWork(PowerHandler workProvider)
{
}
@Override
public World getWorld()
{
return this.getWorldObj();
}
}

View file

@ -0,0 +1,318 @@
package universalelectricity.compatibility;
import ic2.api.Direction;
import ic2.api.energy.tile.IEnergyAcceptor;
import ic2.api.energy.tile.IEnergySink;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.common.MinecraftForge;
import universalelectricity.core.block.IConductor;
import universalelectricity.core.block.IElectrical;
import universalelectricity.core.block.INetworkConnection;
import universalelectricity.core.block.INetworkProvider;
import universalelectricity.core.electricity.ElectricalEvent.ElectricityRequestEvent;
import universalelectricity.core.electricity.ElectricityPack;
import universalelectricity.core.grid.ElectricityNetwork;
import universalelectricity.core.grid.IElectricityNetwork;
import universalelectricity.core.path.Pathfinder;
import universalelectricity.core.path.PathfinderChecker;
import universalelectricity.core.vector.Vector3;
import universalelectricity.core.vector.VectorHelper;
import buildcraft.api.power.IPowerReceptor;
import cpw.mods.fml.common.FMLLog;
/**
* A universal network that words with multiple energy systems.
*
* @author micdoodle8, Calclavia, Aidancbrady
*
*/
public class UniversalNetwork extends ElectricityNetwork
{
@Override
public ElectricityPack getRequest(TileEntity... ignoreTiles)
{
List<ElectricityPack> requests = new ArrayList<ElectricityPack>();
Iterator<TileEntity> it = this.getAcceptors().iterator();
while (it.hasNext())
{
TileEntity tileEntity = it.next();
if (Arrays.asList(ignoreTiles).contains(tileEntity))
{
continue;
}
if (tileEntity instanceof IElectrical)
{
if (!tileEntity.isInvalid())
{
if (tileEntity.worldObj.getBlockTileEntity(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord) == tileEntity)
{
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS)
{
if (((IElectrical) tileEntity).canConnect(direction) && this.getConductors().contains(VectorHelper.getConnectorFromSide(tileEntity.worldObj, new Vector3(tileEntity), direction)))
{
requests.add(ElectricityPack.getFromWatts(((IElectrical) tileEntity).getRequest(direction), ((IElectrical) tileEntity).getVoltage()));
}
}
continue;
}
}
}
if (Compatibility.isIndustrialCraft2Loaded() && tileEntity instanceof IEnergySink)
{
if (!tileEntity.isInvalid())
{
if (tileEntity.worldObj.getBlockTileEntity(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord) == tileEntity)
{
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS)
{
if (((IEnergySink) tileEntity).acceptsEnergyFrom(VectorHelper.getTileEntityFromSide(tileEntity.worldObj, new Vector3(tileEntity), direction), Direction.values()[(direction.ordinal() + 2) % 6]) && this.getConductors().contains(VectorHelper.getConnectorFromSide(tileEntity.worldObj, new Vector3(tileEntity), direction)))
{
requests.add(ElectricityPack.getFromWatts(Math.min(((IEnergySink) tileEntity).demandsEnergy(), ((IEnergySink) tileEntity).getMaxSafeInput()) * Compatibility.IC2_RATIO, 120));
}
}
continue;
}
}
}
if (Compatibility.isBuildcraftLoaded() && tileEntity instanceof IPowerReceptor)
{
if (!tileEntity.isInvalid())
{
if (tileEntity.worldObj.getBlockTileEntity(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord) == tileEntity)
{
/*
* TODO: Fix unkown direction
*
* TODO: Fix inaccurate BuildCraft request calculation.
*/
requests.add(ElectricityPack.getFromWatts(((IPowerReceptor) tileEntity).getPowerReceiver(ForgeDirection.UNKNOWN).getActivationEnergy() * Compatibility.BC3_RATIO, 120));
continue;
}
}
}
}
ElectricityPack mergedPack = ElectricityPack.merge(requests);
ElectricityRequestEvent evt = new ElectricityRequestEvent(mergedPack, ignoreTiles);
MinecraftForge.EVENT_BUS.post(evt);
return mergedPack;
}
@Override
public void refresh()
{
this.electricalTiles.clear();
try
{
Iterator<IConductor> it = this.getConductors().iterator();
while (it.hasNext())
{
IConductor conductor = it.next();
if (conductor == null)
{
it.remove();
}
else if (((TileEntity) conductor).isInvalid())
{
it.remove();
}
else
{
conductor.setNetwork(this);
}
for (int i = 0; i < conductor.getAdjacentConnections().length; i++)
{
TileEntity acceptor = conductor.getAdjacentConnections()[i];
if (!(acceptor instanceof IConductor))
{
if (acceptor instanceof IElectrical)
{
ArrayList<ForgeDirection> possibleDirections = null;
if (this.electricalTiles.containsKey(acceptor))
{
possibleDirections = this.electricalTiles.get(acceptor);
}
else
{
possibleDirections = new ArrayList<ForgeDirection>();
}
if (((IElectrical) acceptor).canConnect(ForgeDirection.getOrientation(i)) && this.getConductors().contains(VectorHelper.getConnectorFromSide(acceptor.worldObj, new Vector3(acceptor), ForgeDirection.getOrientation(i))))
{
possibleDirections.add(ForgeDirection.getOrientation(i));
}
this.electricalTiles.put(acceptor, possibleDirections);
continue;
}
if (Compatibility.isIndustrialCraft2Loaded() && acceptor instanceof IEnergyAcceptor)
{
ArrayList<ForgeDirection> possibleDirections = null;
if (this.electricalTiles.containsKey(acceptor))
{
possibleDirections = this.electricalTiles.get(acceptor);
}
else
{
possibleDirections = new ArrayList<ForgeDirection>();
}
if (((IEnergyAcceptor) acceptor).acceptsEnergyFrom(VectorHelper.getTileEntityFromSide(acceptor.worldObj, new Vector3(acceptor), ForgeDirection.getOrientation(i)), Direction.values()[(i + 2) % 6]) && this.getConductors().contains(VectorHelper.getConnectorFromSide(acceptor.worldObj, new Vector3(acceptor), ForgeDirection.getOrientation(i))))
{
possibleDirections.add(ForgeDirection.getOrientation(i));
}
this.electricalTiles.put(acceptor, possibleDirections);
continue;
}
if (Compatibility.isBuildcraftLoaded() && acceptor instanceof IPowerReceptor)
{
ArrayList<ForgeDirection> possibleDirections = null;
if (this.electricalTiles.containsKey(acceptor))
{
possibleDirections = this.electricalTiles.get(acceptor);
}
else
{
possibleDirections = new ArrayList<ForgeDirection>();
}
if (this.getConductors().contains(VectorHelper.getConnectorFromSide(acceptor.worldObj, new Vector3(acceptor), ForgeDirection.getOrientation(i))))
{
possibleDirections.add(ForgeDirection.getOrientation(i));
}
this.electricalTiles.put(acceptor, possibleDirections);
continue;
}
}
}
}
}
catch (Exception e)
{
FMLLog.severe("Universal Electricity: Failed to refresh conductor.");
e.printStackTrace();
}
}
@Override
public void merge(IElectricityNetwork network)
{
if (network != null && network != this)
{
UniversalNetwork newNetwork = new UniversalNetwork();
newNetwork.getConductors().addAll(this.getConductors());
newNetwork.getConductors().addAll(network.getConductors());
newNetwork.refresh();
}
}
@Override
public void split(IConductor splitPoint)
{
if (splitPoint instanceof TileEntity)
{
this.getConductors().remove(splitPoint);
/**
* Loop through the connected blocks and attempt to see if there are connections between
* the two points elsewhere.
*/
TileEntity[] connectedBlocks = splitPoint.getAdjacentConnections();
for (int i = 0; i < connectedBlocks.length; i++)
{
TileEntity connectedBlockA = connectedBlocks[i];
if (connectedBlockA instanceof INetworkConnection)
{
for (int ii = 0; ii < connectedBlocks.length; ii++)
{
final TileEntity connectedBlockB = connectedBlocks[ii];
if (connectedBlockA != connectedBlockB && connectedBlockB instanceof INetworkConnection)
{
Pathfinder finder = new PathfinderChecker(((TileEntity) splitPoint).worldObj, (INetworkConnection) connectedBlockB, splitPoint);
finder.init(new Vector3(connectedBlockA));
if (finder.results.size() > 0)
{
/**
* The connections A and B are still intact elsewhere. Set all
* references of wire connection into one network.
*/
for (Vector3 node : finder.closedSet)
{
TileEntity nodeTile = node.getTileEntity(((TileEntity) splitPoint).worldObj);
if (nodeTile instanceof INetworkProvider)
{
if (nodeTile != splitPoint)
{
((INetworkProvider) nodeTile).setNetwork(this);
}
}
}
}
else
{
/**
* The connections A and B are not connected anymore. Give both of
* them a new network.
*/
IElectricityNetwork newNetwork = new UniversalNetwork();
for (Vector3 node : finder.closedSet)
{
TileEntity nodeTile = node.getTileEntity(((TileEntity) splitPoint).worldObj);
if (nodeTile instanceof INetworkProvider)
{
if (nodeTile != splitPoint)
{
newNetwork.getConductors().add((IConductor) nodeTile);
}
}
}
newNetwork.refresh();
}
}
}
}
}
}
}
@Override
public String toString()
{
return "UniversalNetwork[" + this.hashCode() + "|Wires:" + this.getConductors().size() + "|Acceptors:" + this.electricalTiles.size() + "]";
}
}

View file

@ -0,0 +1,83 @@
package universalelectricity.core;
import java.io.File;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.material.Material;
import net.minecraftforge.common.Configuration;
import net.minecraftforge.common.MinecraftForge;
import cpw.mods.fml.common.Loader;
/**
* General Universal Electricity class.
*
* @author Calclavia
*
*/
public class UniversalElectricity
{
/**
* The version of the Universal Electricity API.
*/
public static final String MAJOR_VERSION = "@MAJOR@";
public static final String MINOR_VERSION = "@MINOR@";
public static final String REVISION_VERSION = "@REVIS@";
public static final String BUILD_VERSION = "@BUILD@";
public static final String VERSION = MAJOR_VERSION + "." + MINOR_VERSION + "." + REVISION_VERSION;
/**
* The Universal Electricity configuration file.
*/
public static final Configuration CONFIGURATION = new Configuration(new File(Loader.instance().getConfigDir(), "UniversalElectricity.cfg"));
/**
* Is Universal Electricity currently being voltage sensitive? If so, all machines should
* explode under high voltage and react to different amounts of voltage differently.
*/
public static boolean isVoltageSensitive = false;
/**
* Set this value to true if your mod contains and has the ability to transfer electricity via
* the ElectricityNetwork. Examples would be a mod that adds any sort of wire. This value will
* be true as long as there is a way to conduct electricity.
*/
@Deprecated
public static boolean isNetworkActive = false;
/**
* A general material that can be used by machines. Breakable by hand, suitable for machines.
*/
public static final Material machine = new Material(MapColor.ironColor);
private static boolean INIT = false;
static
{
initiate();
}
public static void initiate()
{
if (!INIT)
{
/**
* Loads the configuration and sets all the values.
*/
CONFIGURATION.load();
isVoltageSensitive = CONFIGURATION.get("Compatiblity", "Is Voltage Sensitive", isVoltageSensitive).getBoolean(isVoltageSensitive);
isNetworkActive = CONFIGURATION.get("Compatiblity", "Is Network Active", isNetworkActive).getBoolean(isNetworkActive);
CONFIGURATION.save();
try
{
MinecraftForge.EVENT_BUS.register(Class.forName("universalelectricity.core.electricity.ElectricityHelper").newInstance());
}
catch (Exception e)
{
e.printStackTrace();
}
}
INIT = true;
}
}

Some files were not shown because too many files have changed in this diff Show more