| package ic2.api.energy.prefab; |
| |
| import net.minecraft.item.ItemStack; |
| import net.minecraft.nbt.NBTTagCompound; |
| import net.minecraft.tileentity.TileEntity; |
| |
| import cpw.mods.fml.common.FMLCommonHandler; |
| |
| import net.minecraftforge.common.MinecraftForge; |
| import net.minecraftforge.common.util.ForgeDirection; |
| |
| import ic2.api.energy.EnergyNet; |
| import ic2.api.energy.event.EnergyTileLoadEvent; |
| import ic2.api.energy.event.EnergyTileUnloadEvent; |
| import ic2.api.energy.tile.IEnergySink; |
| import ic2.api.info.Info; |
| import ic2.api.item.ElectricItem; |
| |
| /** |
| * BasicSink is a simple adapter to provide an ic2 energy sink. |
| * |
| * It's designed to be attached to a tile entity as a delegate. Functionally BasicSink acts as a |
| * one-time configurable input energy buffer, thus providing a common use case for machines. |
| * |
| * Sub-classing BasicSink instead of using it as a delegate works as well, but isn't recommended. |
| * The delegate can be extended with additional functionality through a sub class though. |
| * |
| * The constraints set by BasicSink like the strict tank-like energy buffering should provide a |
| * more easy to use and stable interface than using IEnergySink directly while aiming for |
| * optimal performance. |
| * |
| * Using BasicSink involves the following steps: |
| * - create a BasicSink instance in your TileEntity, typically in a field |
| * - forward invalidate, onChunkUnload, readFromNBT, writeToNBT and updateEntity to the BasicSink |
| * instance. |
| * If you have other means of determining when the tile entity is fully loaded, notify onLoaded |
| * that way instead of forwarding updateEntity. |
| * - call useEnergy whenever appropriate. canUseEnergy determines if enough energy is available |
| * without consuming the energy. |
| * - optionally use getEnergyStored to display the output buffer charge level |
| * - optionally use setEnergyStored to sync the stored energy to the client (e.g. in the Container) |
| * |
| * Example implementation code: |
| * @code{.java} |
| * public class SomeTileEntity extends TileEntity { |
| * // new basic energy sink, 1000 EU buffer, tier 1 (32 EU/t, LV) |
| * private BasicSink ic2EnergySink = new BasicSink(this, 1000, 1); |
| * |
| * @Override |
| * public void invalidate() { |
| * ic2EnergySink.invalidate(); // notify the energy sink |
| * ... |
| * super.invalidate(); // this is important for mc! |
| * } |
| * |
| * @Override |
| * public void onChunkUnload() { |
| * ic2EnergySink.onChunkUnload(); // notify the energy sink |
| * ... |
| * } |
| * |
| * @Override |
| * public void readFromNBT(NBTTagCompound tag) { |
| * super.readFromNBT(tag); |
| * |
| * ic2EnergySink.readFromNBT(tag); |
| * ... |
| * } |
| * |
| * @Override |
| * public void writeToNBT(NBTTagCompound tag) { |
| * super.writeToNBT(tag); |
| * |
| * ic2EnergySink.writeToNBT(tag); |
| * ... |
| * } |
| * |
| * @Override |
| * public void updateEntity() { |
| * ic2EnergySink.updateEntity(); // notify the energy sink |
| * ... |
| * if (ic2EnergySink.useEnergy(5)) { // use 5 eu from the sink's buffer this tick |
| * ... // do something with the energy |
| * } |
| * ... |
| * } |
| * |
| * ... |
| * } |
| * @endcode |
| */ |
| public class BasicSink extends TileEntity implements IEnergySink { |
| |
| // ********************************** |
| // *** Methods for use by the mod *** |
| // ********************************** |
| |
| /** |
| * Constructor for a new BasicSink delegate. |
| * |
| * @param parent1 TileEntity represented by this energy sink. |
| * @param capacity1 Maximum amount of eu to store. |
| * @param tier1 IC2 tier, 1=LV, 2=MV, ... |
| */ |
| public BasicSink(TileEntity parent1, int capacity1, int tier1) { |
| this.parent = parent1; |
| this.capacity = capacity1; |
| this.tier = tier1; |
| } |
| |
| // in-world te forwards >> |
| |
| /** |
| * Forward for the base TileEntity's updateEntity(), used for creating the energy net link. |
| * Either updateEntity or onLoaded have to be used. |
| */ |
| @Override |
| public void updateEntity() { |
| if (!addedToEnet) onLoaded(); |
| } |
| |
| /** |
| * Notification that the base TileEntity finished loaded, for advanced uses. |
| * Either updateEntity or onLoaded have to be used. |
| */ |
| public void onLoaded() { |
| if (!addedToEnet && |
| !FMLCommonHandler.instance().getEffectiveSide().isClient() && |
| Info.isIc2Available()) { |
| worldObj = parent.getWorldObj(); |
| xCoord = parent.xCoord; |
| yCoord = parent.yCoord; |
| zCoord = parent.zCoord; |
| |
| MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this)); |
| |
| addedToEnet = true; |
| } |
| } |
| |
| /** |
| * Forward for the base TileEntity's invalidate(), used for destroying the energy net link. |
| * Both invalidate and onChunkUnload have to be used. |
| */ |
| @Override |
| public void invalidate() { |
| super.invalidate(); |
| |
| onChunkUnload(); |
| } |
| |
| /** |
| * Forward for the base TileEntity's onChunkUnload(), used for destroying the energy net link. |
| * Both invalidate and onChunkUnload have to be used. |
| */ |
| @Override |
| public void onChunkUnload() { |
| if (addedToEnet && |
| Info.isIc2Available()) { |
| MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this)); |
| |
| addedToEnet = false; |
| } |
| } |
| |
| /** |
| * Forward for the base TileEntity's readFromNBT(), used for loading the state. |
| * |
| * @param tag Compound tag as supplied by TileEntity.readFromNBT() |
| */ |
| @Override |
| public void readFromNBT(NBTTagCompound tag) { |
| super.readFromNBT(tag); |
| |
| NBTTagCompound data = tag.getCompoundTag("IC2BasicSink"); |
| |
| energyStored = data.getDouble("energy"); |
| } |
| |
| /** |
| * Forward for the base TileEntity's writeToNBT(), used for saving the state. |
| * |
| * @param tag Compound tag as supplied by TileEntity.writeToNBT() |
| */ |
| @Override |
| public void writeToNBT(NBTTagCompound tag) { |
| try { |
| super.writeToNBT(tag); |
| } catch (RuntimeException e) { |
| // happens if this is a delegate, ignore |
| } |
| |
| NBTTagCompound data = new NBTTagCompound(); |
| |
| data.setDouble("energy", energyStored); |
| |
| tag.setTag("IC2BasicSink", data); |
| } |
| |
| // << in-world te forwards |
| // methods for using this adapter >> |
| |
| /** |
| * Get the maximum amount of energy this sink can hold in its buffer. |
| * |
| * @return Capacity in EU. |
| */ |
| public int getCapacity() { |
| return capacity; |
| } |
| |
| /** |
| * Set the maximum amount of energy this sink can hold in its buffer. |
| * |
| * @param capacity1 Capacity in EU. |
| */ |
| public void setCapacity(int capacity1) { |
| this.capacity = capacity1; |
| } |
| |
| /** |
| * Get the IC2 energy tier for this sink. |
| * |
| * @return IC2 Tier. |
| */ |
| public int getTier() { |
| return tier; |
| } |
| |
| /** |
| * Set the IC2 energy tier for this sink. |
| * |
| * @param tier1 IC2 Tier. |
| */ |
| public void setTier(int tier1) { |
| this.tier = tier1; |
| } |
| |
| /** |
| * Determine the energy stored in the sink's input buffer. |
| * |
| * @return amount in EU, may be above capacity |
| */ |
| public double getEnergyStored() { |
| return energyStored; |
| } |
| |
| /** |
| * Set the stored energy to the specified amount. |
| * |
| * This is intended for server -> client synchronization, e.g. to display the stored energy in |
| * a GUI through getEnergyStored(). |
| * |
| * @param amount |
| */ |
| public void setEnergyStored(double amount) { |
| energyStored = amount; |
| } |
| |
| /** |
| * Determine if the specified amount of energy is available. |
| * |
| * @param amount in EU |
| * @return true if the amount is available |
| */ |
| public boolean canUseEnergy(double amount) { |
| return energyStored >= amount; |
| } |
| |
| /** |
| * Use the specified amount of energy, if available. |
| * |
| * @param amount amount to use |
| * @return true if the amount was available |
| */ |
| public boolean useEnergy(double amount) { |
| if (canUseEnergy(amount) && !FMLCommonHandler.instance().getEffectiveSide().isClient()) { |
| energyStored -= amount; |
| |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Discharge the supplied ItemStack into this sink's energy buffer. |
| * |
| * @param stack ItemStack to discharge (null is ignored) |
| * @param limit Transfer limit, values <= 0 will use the battery's limit |
| * @return true if energy was transferred |
| */ |
| public boolean discharge(ItemStack stack, int limit) { |
| if (stack == null || !Info.isIc2Available()) return false; |
| |
| int amount = (int) Math.floor(capacity - energyStored); |
| if (amount <= 0) return false; |
| |
| if (limit > 0 && limit < amount) amount = limit; |
| |
| amount = ElectricItem.manager.discharge(stack, amount, tier, limit > 0, false); |
| |
| energyStored += amount; |
| |
| return amount > 0; |
| } |
| |
| // << methods for using this adapter |
| |
| // backwards compatibility (ignore these) >> |
| |
| @Deprecated |
| public void onUpdateEntity() { |
| updateEntity(); |
| } |
| |
| @Deprecated |
| public void onInvalidate() { |
| invalidate(); |
| } |
| |
| @Deprecated |
| public void onOnChunkUnload() { |
| onChunkUnload(); |
| } |
| |
| @Deprecated |
| public void onReadFromNbt(NBTTagCompound tag) { |
| readFromNBT(tag); |
| } |
| |
| @Deprecated |
| public void onWriteToNbt(NBTTagCompound tag) { |
| writeToNBT(tag); |
| } |
| |
| // << backwards compatibility |
| |
| // ****************************** |
| // *** Methods for use by ic2 *** |
| // ****************************** |
| |
| // energy net interface >> |
| |
| @Override |
| public boolean acceptsEnergyFrom(TileEntity emitter, ForgeDirection direction) { |
| return true; |
| } |
| |
| @Override |
| public double demandedEnergyUnits() { |
| return Math.max(0, capacity - energyStored); |
| } |
| |
| @Override |
| public double injectEnergyUnits(ForgeDirection directionFrom, double amount) { |
| energyStored += amount; |
| |
| return 0; |
| } |
| |
| @Override |
| public int getMaxSafeInput() { |
| return EnergyNet.instance.getPowerFromTier(tier); |
| } |
| |
| // << energy net interface |
| |
| |
| public final TileEntity parent; |
| |
| protected int capacity; |
| protected int tier; |
| protected double energyStored; |
| protected boolean addedToEnet; |
| } |