updated UE API and its required APIs

This commit is contained in:
DarkGuardsman 2013-08-26 13:36:24 -04:00
parent f891904849
commit cd5f64d05e
27 changed files with 618 additions and 471 deletions

View file

@ -1,119 +0,0 @@
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

@ -4,6 +4,11 @@ import ic2.api.energy.tile.IEnergyTile;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.event.world.WorldEvent;
/**
* Base class for energy net events, don't use it directly.
*
* See ic2/api/energy/usage.txt for an overall description of the energy net api.
*/
public class EnergyTileEvent extends WorldEvent
{
public final IEnergyTile energyTile;

View file

@ -13,6 +13,8 @@ import ic2.api.energy.tile.IEnergyTile;
*
* 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.
*
* See ic2/api/energy/usage.txt for an overall description of the energy net api.
*/
public class EnergyTileLoadEvent extends EnergyTileEvent
{

View file

@ -1,32 +0,0 @@
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

@ -14,6 +14,8 @@ import ic2.api.energy.tile.IEnergyTile;
*
* 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.
*
* See ic2/api/energy/usage.txt for an overall description of the energy net api.
*/
public class EnergyTileUnloadEvent extends EnergyTileEvent
{

View file

@ -1,21 +1,26 @@
package ic2.api.energy.tile;
import ic2.api.Direction;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
/**
* For internal usage only.
* For internal/multi-block usage only.
*
* @see IEnergySink
* @see IEnergyConductor
*
* See ic2/api/energy/usage.txt for an overall description of the energy net api.
*/
public interface IEnergyAcceptor extends IEnergyTile
{
/**
* Determine if this acceptor can accept current from an adjacent emitter in a direction.
*
* The TileEntity in the emitter parameter is what was originally added to the energy net, which
* may be normal in-world TileEntity, a delegate or an IMetaDelegate.
*
* @param emitter energy emitter
* @param direction direction the energy is being received from
*/
boolean acceptsEnergyFrom(TileEntity emitter, Direction direction);
boolean acceptsEnergyFrom(TileEntity emitter, ForgeDirection direction);
}

View file

@ -3,6 +3,8 @@ package ic2.api.energy.tile;
/**
* Tile entities which conduct energy pulses without buffering (mostly cables) have to implement
* this interface.
*
* See ic2/api/energy/usage.txt for an overall description of the energy net api.
*/
public interface IEnergyConductor extends IEnergyAcceptor, IEnergyEmitter
{

View file

@ -1,22 +1,27 @@
package ic2.api.energy.tile;
import ic2.api.Direction;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
/**
* For internal usage only.
* For internal/multi-block usage only.
*
* @see IEnergySource
* @see IEnergyConductor
*
* See ic2/api/energy/usage.txt for an overall description of the energy net api.
*/
public interface IEnergyEmitter extends IEnergyTile
{
/**
* Determine if this emitter can emit energy to an adjacent receiver.
*
* @param receiver receiver
* The TileEntity in the receiver parameter is what was originally added to the energy net,
* which may be normal in-world TileEntity, a delegate or an IMetaDelegate.
*
* @param receiver receiver, may be an IMetaDelegate
* @param direction direction the receiver is from the emitter
* @return Whether energy should be emitted
*/
boolean emitsEnergyTo(TileEntity receiver, Direction direction);
boolean emitsEnergyTo(TileEntity receiver, ForgeDirection direction);
}

View file

@ -1,9 +1,11 @@
package ic2.api.energy.tile;
import ic2.api.Direction;
import net.minecraftforge.common.ForgeDirection;
/**
* Allows a tile entity (mostly a machine) to receive energy.
*
* See ic2/api/energy/usage.txt for an overall description of the energy net api.
*/
public interface IEnergySink extends IEnergyAcceptor
{
@ -16,7 +18,7 @@ public interface IEnergySink extends IEnergyAcceptor
*
* @return max accepted input in eu
*/
int demandsEnergy();
double demandedEnergyUnits();
/**
* Transfer energy to the sink.
@ -25,7 +27,7 @@ public interface IEnergySink extends IEnergyAcceptor
* @param amount energy to be transferred
* @return Energy not consumed (leftover)
*/
int injectEnergy(Direction directionFrom, int amount);
double injectEnergyUnits(ForgeDirection directionFrom, double amount);
/**
* Determine the amount of eu which can be safely injected into the specific energy sink without

View file

@ -2,13 +2,25 @@ package ic2.api.energy.tile;
/**
* Allows a tile entity (mostly a generator) to emit energy.
*
* See ic2/api/energy/usage.txt for an overall description of the energy net api.
*/
public interface IEnergySource extends IEnergyEmitter
{
/**
* Maximum energy output provided by the source. If unsure, use Integer.MAX_VALUE.
* Energy output provided by the source this tick. This is typically Math.min(stored energy, max
* output/tick).
*
* @return Maximum energy output
* @return Energy offered this tick
*/
int getMaxEnergyOutput();
double getOfferedEnergy();
/**
* Draw energy from this source's buffer.
*
* If the source doesn't have a buffer, this is a no-op.
*
* @param amount amount of EU to draw
*/
void drawEnergy(double amount);
}

View file

@ -1,18 +1,14 @@
package ic2.api.energy.tile;
/**
* For internal usage only.
* For internal usage only, base class for all energy tiles.
*
* @see IEnergySink
* @see IEnergySource
* @see IEnergyConductor
*
* See ic2/api/energy/usage.txt for an overall description of the energy net api.
*/
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,33 @@
package ic2.api.energy.tile;
import java.util.List;
import net.minecraft.tileentity.TileEntity;
/**
* Interface for grouping multi-block structures to a single energy net delegate.
*
* The energy net uses TileEntity to refer to a specific xyz+world position. If multiple of those
* positions should belong to the same functional structure, i.e. they consume or produce energy
* only once for the whole multi-block instead of once per every single block, this interface allows
* to do so.
*
* The tile entity implementing IMetaDelegate has to be added/removed to/from the energy net instead
* of every single sub-TileEntity. The energy net interaction will be handled by the IMetaDelegate
* TileEntity as well.
*
* The sub tile array TileEntity[] just provides optional connectivity (IEnergyAcceptor,
* IEnergyEmitter) and mandatory position (x, y, z, World) data. If the connectivity data on the sub
* tile is missing, the meta delegate is queried instead.
*
* See ic2/api/energy/usage.txt for an overall description of the energy net api.
*/
public interface IMetaDelegate extends IEnergyTile
{
/**
* Get the sub-TileEntities belonging to this Meta TileEntity.
*
* @return sub-TileEntity array
*/
List<TileEntity> getSubTiles();
}

View file

@ -0,0 +1,115 @@
package ic2.api.item;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* Allows for charging, discharging and using electric items (IElectricItem).
*
* The charge or remaining capacity of an item can be determined by calling charge/discharge with
* ignoreTransferLimit and simulate set to true.
*/
public final class ElectricItem
{
/**
* IElectricItemManager to use for interacting with IElectricItem ItemStacks.
*
* This manager will act as a gateway and delegate the tasks to the final implementation
* (rawManager or a custom one) as necessary.
*/
public static IElectricItemManager manager;
/**
* Standard IElectricItemManager implementation, only call it directly from another
* IElectricItemManager. Use manager instead.
*/
public static IElectricItemManager rawManager;
/**
* 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
*
* @deprecated use manager.charge() instead
*/
@Deprecated
public static int charge(ItemStack itemStack, int amount, int tier, boolean ignoreTransferLimit, boolean simulate)
{
return manager.charge(itemStack, amount, tier, ignoreTransferLimit, 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
*
* @deprecated use manager.discharge() instead
*/
@Deprecated
public static int discharge(ItemStack itemStack, int amount, int tier, boolean ignoreTransferLimit, boolean simulate)
{
return manager.discharge(itemStack, amount, tier, ignoreTransferLimit, simulate);
}
/**
* 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
*
* @deprecated use manager.canUse() instead
*/
@Deprecated
public static boolean canUse(ItemStack itemStack, int amount)
{
return manager.canUse(itemStack, 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 player player holding the item
* @return true if the operation succeeded
*
* @deprecated use manager.use() instead
*/
@Deprecated
public static boolean use(ItemStack itemStack, int amount, EntityPlayer player)
{
return manager.use(itemStack, amount, player);
}
/**
* 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 player player holding the item
*
* @deprecated use manager.chargeFromArmor() instead
*/
@Deprecated
public static void chargeFromArmor(ItemStack itemStack, EntityPlayer player)
{
manager.chargeFromArmor(itemStack, player);
}
}

View file

@ -0,0 +1,14 @@
package ic2.api.item;
import net.minecraft.item.ItemStack;
public interface IBoxable
{
/**
* Determine whether an item can be stored in a toolbox or not.
*
* @param itemstack item to be stored
* @return Whether to store the item in the toolbox or not
*/
public abstract boolean canBeStoredInToolbox(ItemStack itemstack);
}

View file

@ -0,0 +1,68 @@
package ic2.api.item;
import net.minecraft.item.ItemStack;
/**
* Provides the ability to store energy on the implementing item.
*
* This interface is a special version of IElectricItem which delegates the implementation of
* charge(), discharge() and canUse() to the implementing Item.
*
* The default implementation (when not using ICustomElectricItem) 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 ICustomElectricItem must not call the ElectricItem methods charge, discharge or canUse
*
* @deprecated Use ISpecialElectricItem instead.
*/
@Deprecated
public interface ICustomElectricItem extends IElectricItem
{
/**
* 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
*/
public 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
*/
public int discharge(ItemStack itemStack, int amount, int tier, boolean ignoreTransferLimit, boolean simulate);
/**
* 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
*/
public boolean canUse(ItemStack itemStack, int amount);
/**
* Determine whether to show the charge tool tip with NEI or other means.
*
* Return false if IC2's handler is incompatible, you want to implement your own or you don't
* want to display the charge at all.
*
* @return true to show the tool tip (x/y EU)
*/
public boolean canShowChargeToolTip(ItemStack itemStack);
}

View file

@ -0,0 +1,22 @@
package ic2.api.item;
/**
* Allows a tile entity to output a debug message when the debugItem is used on it. Suggestions by
* Myrathi
*/
public abstract interface IDebuggable
{
/**
* Checks if the tile entity is in a state that can be debugged.
*
* @return True if the tile entity can be debugged
*/
public abstract boolean isDebuggable();
/**
* Gets the debug text for the tile entity.
*
* @return The text that the debugItem should show
*/
public abstract String getDebugText();
}

View file

@ -0,0 +1,20 @@
package ic2.api.item;
import java.util.List;
import net.minecraft.item.ItemStack;
public interface IItemHudInfo
{
/*
* Add Info to Nano- and Quantum-Suit Helm Hud for itemStack
*
* @Override public List<String> getHudInfo(ItemStack itemStack) { List<String> info = new
* LinkedList<String>(); info.add("i am a Cool Item"); info.add("and have Cool info"); return
* info; }
*/
public List<String> getHudInfo(ItemStack itemStack);
}

View file

@ -0,0 +1,21 @@
package ic2.api.item;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* Armor items implementing this can be considered metal armor.
*
* Currently used for determining which boots can be used to slide up a magnetic pole.
*/
public interface IMetalArmor
{
/**
* Determine if the given armor piece is metal armor.
*
* @param itemstack Armor piece as worn by the player
* @param player The player
* @return Whether the armor piece is metal armor
*/
public boolean isMetalArmor(ItemStack itemstack, EntityPlayer player);
}

View file

@ -0,0 +1,34 @@
package ic2.api.item;
import net.minecraft.world.World;
/**
* Allows an item to act as a terraformer blueprint.
*/
public interface ITerraformingBP
{
/**
* Get the energy consumption per operation of the blueprint.
*
* @return Energy consumption in EU
*/
public abstract int getConsume();
/**
* Get the maximum range of the blueprint. Should be a divisor of 5.
*
* @return Maximum range in blocks
*/
public abstract int getRange();
/**
* Perform the terraforming operation.
*
* @param world world to terraform
* @param x X position to terraform
* @param z Z position to terraform
* @param yCoord Y position of the terraformer
* @return Whether the operation was successful and the terraformer should consume energy.
*/
public abstract boolean terraform(World world, int x, int z, int yCoord);
}

View file

@ -0,0 +1,61 @@
package ic2.api.item;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
/**
* Wrapper for inserting interfaces into items you don't own.
*
* @author Richard
*/
public class ItemWrapper
{
private static final Multimap<Item, IBoxable> boxableItems = ArrayListMultimap.create();
private static final Multimap<Item, IMetalArmor> metalArmorItems = ArrayListMultimap.create();
public static void registerBoxable(Item item, IBoxable boxable)
{
boxableItems.put(item, boxable);
}
public static boolean canBeStoredInToolbox(ItemStack stack)
{
Item item = stack.getItem();
// use customs first to allow for overriding behavior
for (IBoxable boxable : boxableItems.get(item))
{
if (boxable.canBeStoredInToolbox(stack))
return true;
}
if (item instanceof IBoxable && ((IBoxable) item).canBeStoredInToolbox(stack))
return true;
return false;
}
public static void registerMetalArmor(Item item, IMetalArmor armor)
{
metalArmorItems.put(item, armor);
}
public static boolean isMetalArmor(ItemStack stack, EntityPlayer player)
{
Item item = stack.getItem();
// use customs first to allow for overriding behavior
for (IMetalArmor metalArmor : metalArmorItems.get(item))
{
if (metalArmor.isMetalArmor(stack, player))
return true;
}
if (item instanceof IMetalArmor && ((IMetalArmor) item).isMetalArmor(stack, player))
return true;
return false;
}
}

View file

@ -1,24 +1,20 @@
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.IEnergyEmitter;
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.
@ -26,199 +22,148 @@ import buildcraft.api.power.PowerHandler.PowerReceiver;
* Extend this class or use as a reference for your own implementation of compatible conductor
* tiles.
*
* TODO: Need working BuildCraft support!
*
* @author micdoodle8
*
*/
public abstract class TileEntityUniversalConductor extends TileEntityConductor implements IEnergySink, IPowerReceptor
public abstract class TileEntityUniversalConductor extends TileEntityConductor implements IEnergySink
{
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;
}
protected boolean isAddedToEnergyNet;
@Override
public TileEntity[] getAdjacentConnections()
{
TileEntity[] adjecentConnections = new TileEntity[6];
for (byte i = 0; i < 6; i++)
if (this.adjacentConnections == null)
{
ForgeDirection side = ForgeDirection.getOrientation(i);
TileEntity tileEntity = VectorHelper.getTileEntityFromSide(this.worldObj, new Vector3(this), side);
this.adjacentConnections = new TileEntity[6];
if (tileEntity instanceof IConnector)
for (byte i = 0; i < 6; i++)
{
if (((IConnector) tileEntity).canConnect(side.getOpposite()))
ForgeDirection side = ForgeDirection.getOrientation(i);
TileEntity tileEntity = VectorHelper.getTileEntityFromSide(this.worldObj, new Vector3(this), side);
if (tileEntity instanceof IConnector)
{
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()))
if (((IConnector) tileEntity).canConnect(side.getOpposite()))
{
adjecentConnections[i] = tileEntity;
this.adjacentConnections[i] = tileEntity;
}
}
else
else if (Compatibility.isIndustrialCraft2Loaded() && tileEntity instanceof IEnergyTile)
{
adjecentConnections[i] = tileEntity;
if (tileEntity instanceof IEnergyAcceptor)
{
if (((IEnergyAcceptor) tileEntity).acceptsEnergyFrom(this, side.getOpposite()))
{
this.adjacentConnections[i] = tileEntity;
continue;
}
}
if (tileEntity instanceof IEnergyEmitter)
{
if (((IEnergyEmitter) tileEntity).emitsEnergyTo(tileEntity, side.getOpposite()))
{
this.adjacentConnections[i] = tileEntity;
continue;
}
}
this.adjacentConnections[i] = tileEntity;
}
else if (Compatibility.isBuildcraftLoaded() && tileEntity instanceof IPowerReceptor)
{
this.adjacentConnections[i] = tileEntity;
}
}
else if (Compatibility.isBuildcraftLoaded() && tileEntity instanceof IPowerReceptor)
{
adjecentConnections[i] = tileEntity;
}
}
return adjecentConnections;
return this.adjacentConnections;
}
/**
* BuildCraft Methods
*/
@Override
public PowerReceiver getPowerReceiver(ForgeDirection side)
{
return null;
}
@Override
public boolean canUpdate()
{
return !this.isAddedToEnergyNet;
}
@Override
public void doWork(PowerHandler workProvider)
{
@Override
public void updateEntity()
{
if (!this.worldObj.isRemote)
{
if (!this.isAddedToEnergyNet)
{
this.initIC();
}
}
}
}
@Override
public void invalidate()
{
this.unloadTileIC2();
super.invalidate();
}
@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)); } } }
*/
@Override
public void onChunkUnload()
{
this.unloadTileIC2();
super.onChunkUnload();
}
protected void initIC()
{
if (Compatibility.isIndustrialCraft2Loaded())
{
MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
}
this.isAddedToEnergyNet = true;
}
private void unloadTileIC2()
{
if (this.isAddedToEnergyNet && this.worldObj != null)
{
if (Compatibility.isIndustrialCraft2Loaded())
{
MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
}
this.isAddedToEnergyNet = false;
}
}
@Override
public double demandedEnergyUnits()
{
if (this.getNetwork() == null)
{
return 0.0;
}
return this.getNetwork().getRequest(this).getWatts() * Compatibility.TO_IC2_RATIO;
}
@Override
public double injectEnergyUnits(ForgeDirection directionFrom, double amount)
{
TileEntity tile = VectorHelper.getTileEntityFromSide(this.worldObj, new Vector3(this), directionFrom);
return this.getNetwork().produce(ElectricityPack.getFromWatts((float) (amount * Compatibility.IC2_RATIO), 120.0F / 1000.0F), this, tile);
}
@Override
public int getMaxSafeInput()
{
return Integer.MAX_VALUE;
}
@Override
public boolean acceptsEnergyFrom(TileEntity emitter, ForgeDirection direction)
{
return true;
}
}

View file

@ -1,8 +1,6 @@
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;
@ -147,31 +145,11 @@ public abstract class TileEntityUniversalElectrical extends TileEntityElectrical
for (ForgeDirection outputDirection : this.getOutputDirections())
{
this.produceUE(outputDirection);
this.produceIC2(outputDirection);
this.produceBuildCraft(outputDirection);
}
}
}
public void produceIC2(ForgeDirection outputDirection)
{
if (!this.worldObj.isRemote && outputDirection != null && outputDirection != ForgeDirection.UNKNOWN)
{
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.provideElectricity((ic2Provide * Compatibility.IC2_RATIO) - (event.amount * Compatibility.IC2_RATIO), true);
}
}
}
}
public void produceBuildCraft(ForgeDirection outputDirection)
{
if (!this.worldObj.isRemote && outputDirection != null && outputDirection != ForgeDirection.UNKNOWN)
@ -204,15 +182,21 @@ public abstract class TileEntityUniversalElectrical extends TileEntityElectrical
* IC2 Methods
*/
@Override
public boolean acceptsEnergyFrom(TileEntity emitter, Direction direction)
public boolean acceptsEnergyFrom(TileEntity emitter, ForgeDirection direction)
{
return this.canConnect(direction.toForgeDirection());
return this.getInputDirections().contains(direction);
}
@Override
public boolean isAddedToEnergyNet()
public double getOfferedEnergy()
{
return this.isAddedToEnergyNet;
return this.getProvide(ForgeDirection.UNKNOWN) * Compatibility.TO_IC2_RATIO;
}
@Override
public void drawEnergy(double amount)
{
this.provideElectricity((float) amount * Compatibility.IC2_RATIO, true);
}
@Override
@ -253,19 +237,19 @@ public abstract class TileEntityUniversalElectrical extends TileEntityElectrical
}
@Override
public int demandsEnergy()
public double demandedEnergyUnits()
{
return (int) Math.ceil(this.getRequest(ForgeDirection.UNKNOWN) * Compatibility.TO_IC2_RATIO);
return Math.ceil(this.getRequest(ForgeDirection.UNKNOWN) * Compatibility.TO_IC2_RATIO);
}
@Override
public int injectEnergy(Direction directionFrom, int amount)
public double injectEnergyUnits(ForgeDirection direction, double amount)
{
if (this.getInputDirections().contains(directionFrom.toForgeDirection()))
if (this.getInputDirections().contains(direction))
{
float convertedEnergy = amount * Compatibility.IC2_RATIO;
float convertedEnergy = (float) (amount * Compatibility.IC2_RATIO);
ElectricityPack toSend = ElectricityPack.getFromWatts(convertedEnergy, this.getVoltage());
float receive = this.receiveElectricity(directionFrom.toForgeDirection(), toSend, true);
float receive = this.receiveElectricity(direction, toSend, true);
// Return the difference, since injectEnergy returns left over energy, and
// receiveElectricity returns energy used.
@ -276,15 +260,9 @@ public abstract class TileEntityUniversalElectrical extends TileEntityElectrical
}
@Override
public int getMaxEnergyOutput()
public boolean emitsEnergyTo(TileEntity receiver, ForgeDirection direction)
{
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());
return receiver instanceof IEnergyTile && this.getOutputDirections().contains(direction);
}
@Override

View file

@ -1,6 +1,5 @@
package universalelectricity.compatibility;
import ic2.api.Direction;
import ic2.api.energy.tile.IEnergyAcceptor;
import ic2.api.energy.tile.IEnergySink;
@ -77,9 +76,9 @@ public class UniversalNetwork extends ElectricityNetwork
{
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)))
if (((IEnergySink) tileEntity).acceptsEnergyFrom(VectorHelper.getTileEntityFromSide(tileEntity.worldObj, new Vector3(tileEntity), direction), ForgeDirection.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));
requests.add(ElectricityPack.getFromWatts((float) (Math.min(((IEnergySink) tileEntity).demandedEnergyUnits(), ((IEnergySink) tileEntity).getMaxSafeInput()) * Compatibility.IC2_RATIO), 120));
}
}
@ -107,7 +106,7 @@ public class UniversalNetwork extends ElectricityNetwork
}
ElectricityPack mergedPack = ElectricityPack.merge(requests);
ElectricityRequestEvent evt = new ElectricityRequestEvent(mergedPack, ignoreTiles);
ElectricityRequestEvent evt = new ElectricityRequestEvent(this, mergedPack, ignoreTiles);
MinecraftForge.EVENT_BUS.post(evt);
return mergedPack;
}
@ -179,7 +178,7 @@ public class UniversalNetwork extends ElectricityNetwork
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))))
if (((IEnergyAcceptor) acceptor).acceptsEnergyFrom(VectorHelper.getTileEntityFromSide(acceptor.worldObj, new Vector3(acceptor), ForgeDirection.getOrientation(i)), ForgeDirection.values()[(i + 2) % 6]) && this.getConductors().contains(VectorHelper.getConnectorFromSide(acceptor.worldObj, new Vector3(acceptor), ForgeDirection.getOrientation(i))))
{
possibleDirections.add(ForgeDirection.getOrientation(i));
}

View file

@ -5,6 +5,7 @@ import net.minecraft.world.World;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
import universalelectricity.core.block.IElectrical;
import universalelectricity.core.grid.IElectricityNetwork;
public class ElectricalEvent extends Event
{
@ -27,34 +28,40 @@ public class ElectricalEvent extends Event
}
}
public static class NetworkEvent extends ElectricalEvent
{
public final IElectricityNetwork network;
public ElectricityPack electricityPack;
public TileEntity[] ignoreTiles;
public NetworkEvent(IElectricityNetwork network, ElectricityPack electricityPack, TileEntity... ignoreTiles)
{
this.network = network;
this.electricityPack = electricityPack;
this.ignoreTiles = ignoreTiles;
}
}
/**
* Internal Events
* Internal Events. These events are fired when something happens in the network.
*
* @author Calclavia
*
*/
@Cancelable
public static class ElectricityProductionEvent extends ElectricalEvent
public static class ElectricityProductionEvent extends NetworkEvent
{
public ElectricityPack electricityPack;
public TileEntity[] ignoreTiles;
public ElectricityProductionEvent(ElectricityPack electricityPack, TileEntity... ignoreTiles)
public ElectricityProductionEvent(IElectricityNetwork network, ElectricityPack electricityPack, TileEntity... ignoreTiles)
{
this.electricityPack = electricityPack;
this.ignoreTiles = ignoreTiles;
super(network, electricityPack, ignoreTiles);
}
}
public static class ElectricityRequestEvent extends ElectricalEvent
public static class ElectricityRequestEvent extends NetworkEvent
{
public ElectricityPack electricityPack;
public TileEntity[] ignoreTiles;
public ElectricityRequestEvent(ElectricityPack electricityPack, TileEntity... ignoreTiles)
public ElectricityRequestEvent(IElectricityNetwork network, ElectricityPack electricityPack, TileEntity... ignoreTiles)
{
this.electricityPack = electricityPack;
this.ignoreTiles = ignoreTiles;
super(network, electricityPack, ignoreTiles);
}
}

View file

@ -23,56 +23,6 @@ import universalelectricity.core.vector.VectorHelper;
*/
public class ElectricityHelper
{
@ForgeSubscribe
public void onProduce(ElectricityProduceEvent evt)
{
// Needs work with shuffling to be able to evenly distribute to all
// connected networks
// instead of just defaulting to one of them.
Vector3 position = new Vector3((TileEntity) evt.tileEntity);
HashMap<IElectricityNetwork, ForgeDirection> networks = new HashMap<IElectricityNetwork, ForgeDirection>();
for (ForgeDirection direction : getDirections((TileEntity) evt.tileEntity))
{
IElectricityNetwork network = getNetworkFromTileEntity(VectorHelper.getTileEntityFromSide(evt.world, position, direction), direction.getOpposite());
if (network != null)
{
networks.put(network, direction);
ElectricityPack provided = evt.tileEntity.provideElectricity(direction, network.getRequest((TileEntity) evt.tileEntity), true);
if (provided != null && provided.getWatts() > 0)
{
network.produce(provided, (TileEntity) evt.tileEntity);
}
}
}
/*
* ElectricityPack request = this.getNetwork().getRequest(this);
*
* if (request.getWatts() > 0) { List<ElectricityPack> providedPacks = new
* ArrayList<ElectricityPack>(); List<TileEntity> tileEntities = new
* ArrayList<TileEntity>();
*
* for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) { Vector3 position = new
* Vector3(this).modifyPositionFromSide(direction); TileEntity tileEntity =
* position.getTileEntity(this.worldObj);
*
* if (tileEntity instanceof IElectrical) { tileEntities.add(tileEntity); IElectrical
* electrical = (IElectrical) tileEntity;
*
* if (electrical.canConnect(direction.getOpposite())) { if
* (electrical.getProvide(direction.getOpposite()) > 0) { providedPacks.add
* (electrical.provideElectricity(direction.getOpposite(), request, true)); } } } }
*
* ElectricityPack mergedPack = ElectricityPack.merge(providedPacks);
*
* if (mergedPack.getWatts() > 0) { this.getNetwork().produce(mergedPack,
* tileEntities.toArray(new TileEntity[0])); } }
*/
}
public static EnumSet<ForgeDirection> getDirections(TileEntity tileEntity)
{
EnumSet<ForgeDirection> possibleSides = EnumSet.noneOf(ForgeDirection.class);

View file

@ -42,14 +42,20 @@ public class ElectricityNetwork implements IElectricityNetwork
private final Set<IConductor> conductors = new HashSet<IConductor>();
public float acceptorResistance = 500;
@Override
public float produce(ElectricityPack electricity, TileEntity... ignoreTiles)
{
ElectricityProductionEvent evt = new ElectricityProductionEvent(electricity, ignoreTiles);
ElectricityProductionEvent evt = new ElectricityProductionEvent(this, electricity, ignoreTiles);
MinecraftForge.EVENT_BUS.post(evt);
float energy = electricity.getWatts();
float totalEnergy = energy;
float totalEnergy = electricity.getWatts();
float networkResistance = getTotalResistance();
float proportionWasted = getTotalResistance() / (getTotalResistance() + acceptorResistance);
float energyWasted = totalEnergy * proportionWasted;
float totalUsableEnergy = totalEnergy - energyWasted;
float remainingUsableEnergy = totalUsableEnergy;
float voltage = electricity.voltage;
if (!evt.isCanceled())
@ -72,19 +78,13 @@ public class ElectricityNetwork implements IElectricityNetwork
{
if (electricalTile.canConnect(direction) && this.getConductors().contains(VectorHelper.getConnectorFromSide(tileEntity.worldObj, new Vector3(tileEntity), direction)))
{
float energyToSend = totalEnergy * (electricalTile.getRequest(direction) / totalEnergyRequest);
float energyToSend = totalUsableEnergy * (electricalTile.getRequest(direction) / totalEnergyRequest);
if (energyToSend > 0)
{
ElectricityPack electricityToSend = ElectricityPack.getFromWatts(energyToSend, voltage);
// Calculate energy loss caused by resistance.
float ampsReceived = electricityToSend.amperes - (electricityToSend.amperes * electricityToSend.amperes * this.getTotalResistance()) / electricityToSend.voltage;
float voltsReceived = electricityToSend.voltage - (electricityToSend.amperes * this.getTotalResistance());
electricityToSend = new ElectricityPack(ampsReceived, voltsReceived);
energy -= ((IElectrical) tileEntity).receiveElectricity(direction, electricityToSend, true);
remainingUsableEnergy -= ((IElectrical) tileEntity).receiveElectricity(direction, electricityToSend, true);
}
}
}
@ -94,7 +94,7 @@ public class ElectricityNetwork implements IElectricityNetwork
}
}
return energy;
return remainingUsableEnergy;
}
/**
@ -136,7 +136,7 @@ public class ElectricityNetwork implements IElectricityNetwork
}
ElectricityPack mergedPack = ElectricityPack.merge(requests);
ElectricityRequestEvent evt = new ElectricityRequestEvent(mergedPack, ignoreTiles);
ElectricityRequestEvent evt = new ElectricityRequestEvent(this, mergedPack, ignoreTiles);
MinecraftForge.EVENT_BUS.post(evt);
return mergedPack;
}

View file

@ -47,7 +47,7 @@ public abstract class ItemElectric extends Item implements IItemElectric
color = "\u00a76";
}
list.add(color + ElectricityDisplay.getDisplay(joules, ElectricUnit.JOULES) + "/" + ElectricityDisplay.getDisplay(this.getMaxElectricityStored(itemStack), ElectricUnit.JOULES));
list.add(color + ElectricityDisplay.getDisplayShort(joules, ElectricUnit.JOULES) + "/" + ElectricityDisplay.getDisplayShort(this.getMaxElectricityStored(itemStack), ElectricUnit.JOULES));
}
/**