diff --git a/api/buildcraft/api/mj/BatteryObject.java b/api/buildcraft/api/mj/BatteryObject.java index a762a4e0..0077d824 100755 --- a/api/buildcraft/api/mj/BatteryObject.java +++ b/api/buildcraft/api/mj/BatteryObject.java @@ -8,12 +8,9 @@ */ package buildcraft.api.mj; -import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.logging.Level; -import net.minecraftforge.common.util.ForgeDirection; - import buildcraft.api.core.BCLog; import buildcraft.api.core.JavaTools; @@ -22,7 +19,7 @@ import buildcraft.api.core.JavaTools; * battery field is of type double, and is the only piece of data specific to * this object. Others are class-wide. */ -public class BatteryObject implements IBatteryIOObject { +public class BatteryObject implements IBatteryIOObject, MjReconfigurator.IConfigurableBatteryObject { protected Field energyStored; protected Object obj; protected MjBattery batteryData; @@ -57,9 +54,6 @@ public class BatteryObject implements IBatteryIOObject { */ @Override public double addEnergy(double mj, boolean ignoreCycleLimit) { - if (!batteryData.mode().canReceive) { - return 0; - } try { double contained = energyStored.getDouble(obj); double maxAccepted = batteryData.maxCapacity() - contained + batteryData.minimumConsumption(); @@ -74,7 +68,30 @@ public class BatteryObject implements IBatteryIOObject { } catch (IllegalAccessException e) { BCLog.logger.log(Level.WARNING, "can't add energy", e); } + return 0; + } + @Override + public double extractEnergy(double mj) { + return extractEnergy(mj, false); + } + + @Override + public double extractEnergy(double mj, boolean ignoreCycleLimit) { + try { + double contained = energyStored.getDouble(obj); + double maxExtracted = contained; + if (!ignoreCycleLimit && maxExtracted > batteryData.maxSendedPerCycle()) { + maxExtracted = batteryData.maxSendedPerCycle(); + } + double used = Math.min(maxExtracted, mj); + if (used > 0) { + energyStored.setDouble(obj, Math.max(contained - used, 0)); + return used; + } + } catch (IllegalAccessException e) { + BCLog.logger.log(Level.WARNING, "can't extract energy", e); + } return 0; } @@ -128,61 +145,16 @@ public class BatteryObject implements IBatteryIOObject { return batteryData.maxReceivedPerCycle(); } - /** - * {@inheritDoc} - */ - @Override - public BatteryObject reconfigure(double maxCapacity, double maxReceivedPerCycle, double minimumConsumption) { - overrideBattery(maxCapacity, maxReceivedPerCycle, minimumConsumption, - batteryData.kind(), batteryData.sides(), batteryData.mode()); - return this; - } - - public void overrideBattery(final double maxCapacity, final double maxReceivedPerCycle, final double minimumConsumption, - final String kind, final ForgeDirection[] sides, final IOMode mode) { - batteryData = new MjBattery() { - @Override - public double maxCapacity() { - return maxCapacity; - } - - @Override - public double maxReceivedPerCycle() { - return maxReceivedPerCycle; - } - - @Override - public double minimumConsumption() { - return minimumConsumption; - } - - @Override - public Class annotationType() { - return MjBattery.class; - } - - @Override - public String kind() { - return kind; - } - - @Override - public ForgeDirection[] sides() { - return sides; - } - - @Override - public IOMode mode() { - return mode; - } - }; - } - @Override public String kind() { return batteryData.kind(); } + @Override + public double maxSendedPerCycle() { + return batteryData.maxSendedPerCycle(); + } + @Override public IOMode mode() { return batteryData.mode(); @@ -197,4 +169,24 @@ public class BatteryObject implements IBatteryIOObject { public boolean canReceive() { return batteryData.mode().canReceive; } + + @Override + public boolean isActive() { + return batteryData.mode().active; + } + + @Override + public boolean isCacheable() { + return batteryData.cacheable(); + } + + @Override + public MjBattery getMjBattery() { + return batteryData; + } + + @Override + public void setMjBattery(MjBattery battery) { + batteryData = battery; + } } \ No newline at end of file diff --git a/api/buildcraft/api/mj/IBatteryIOObject.java b/api/buildcraft/api/mj/IBatteryIOObject.java index 03947c93..a2cfb768 100644 --- a/api/buildcraft/api/mj/IBatteryIOObject.java +++ b/api/buildcraft/api/mj/IBatteryIOObject.java @@ -9,9 +9,19 @@ package buildcraft.api.mj; public interface IBatteryIOObject extends IBatteryObject { + double maxSendedPerCycle(); + + double extractEnergy(double mj); + + double extractEnergy(double mj, boolean ignoreCycleLimit); + IOMode mode(); boolean canSend(); boolean canReceive(); + + boolean isActive(); + + boolean isCacheable(); } diff --git a/api/buildcraft/api/mj/IBatteryObject.java b/api/buildcraft/api/mj/IBatteryObject.java index abbc00f0..d93997b3 100644 --- a/api/buildcraft/api/mj/IBatteryObject.java +++ b/api/buildcraft/api/mj/IBatteryObject.java @@ -45,37 +45,20 @@ public interface IBatteryObject { void setEnergyStored(double mj); /** - * Can be overrided via {@link #reconfigure(double, double, double)} - * * @return Maximal energy amount for this battery. */ double maxCapacity(); /** - * Can be overrided via {@link #reconfigure(double, double, double)} - * * @return Minimal energy amount for keep your machine in active state */ double minimumConsumption(); /** - * Can be overrided via {@link #reconfigure(double, double, double)} - * * @return Maximal energy received per one tick */ double maxReceivedPerCycle(); - /** - * Allow to dynamically reconfigure your battery. - * Usually it's not very good change battery parameters for already present machines, but if you want... - * - * @param maxCapacity {@link #maxCapacity()} - * @param maxReceivedPerCycle {@link #maxReceivedPerCycle()} - * @param minimumConsumption {@link #minimumConsumption()} - * @return Current battery object instance - */ - IBatteryObject reconfigure(double maxCapacity, double maxReceivedPerCycle, double minimumConsumption); - /** * @return kind of this energy battery */ diff --git a/api/buildcraft/api/mj/IOMode.java b/api/buildcraft/api/mj/IOMode.java index 20d7a897..8f15e840 100644 --- a/api/buildcraft/api/mj/IOMode.java +++ b/api/buildcraft/api/mj/IOMode.java @@ -9,12 +9,22 @@ package buildcraft.api.mj; public enum IOMode { - Both(true, true), Receive(true, false), Send(false, true), None(false, false); + Both(true, true, false), + BothActive(true, true, true), - public final boolean canReceive, canSend; + Receive(true, false, false), + ReceiveActive(true, false, true), - IOMode(boolean canReceive, boolean canSend) { + Send(false, true, false), + SendActive(false, true, true), + + None(false, false, false); + + public final boolean canReceive, canSend, active; + + IOMode(boolean canReceive, boolean canSend, boolean active) { this.canReceive = canReceive; this.canSend = canSend; + this.active = active; } } diff --git a/api/buildcraft/api/mj/MjAPI.java b/api/buildcraft/api/mj/MjAPI.java index 1a64b803..f4ca5854 100755 --- a/api/buildcraft/api/mj/MjAPI.java +++ b/api/buildcraft/api/mj/MjAPI.java @@ -12,12 +12,19 @@ import java.lang.reflect.Field; import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.WeakHashMap; import java.util.logging.Level; +import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; import buildcraft.api.core.BCLog; import buildcraft.api.core.JavaTools; +import buildcraft.api.power.IPowerReceptor; +import buildcraft.api.power.PowerHandler; + +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; /** * The class MjAPI provides services to the Minecraft Joules power framework. @@ -27,10 +34,11 @@ import buildcraft.api.core.JavaTools; */ public final class MjAPI { public static final String DEFAULT_POWER_FRAMEWORK = "buildcraft.kinesis"; - private static Map mjBatteries = new HashMap(); + private static Map mjBatteryFields = new HashMap(); private static Map> mjBatteryKinds = new HashMap>(); private static final BatteryField invalidBatteryField = new BatteryField(); - + private static final MjReconfigurator reconfigurator = new MjReconfigurator(); + private static final Map mjBatteryCache = new WeakHashMap(); /** * Deactivate constructor */ @@ -43,7 +51,7 @@ public final class MjAPI { * power framework if possible. */ public static IBatteryObject getMjBattery(Object o) { - return getMjBattery(o, DEFAULT_POWER_FRAMEWORK); + return getMjBattery(o, DEFAULT_POWER_FRAMEWORK, ForgeDirection.UNKNOWN); } /** @@ -55,6 +63,15 @@ public final class MjAPI { return getMjBattery(o, kind, ForgeDirection.UNKNOWN); } + /** + * Returns the battery related to the object given in parameter. For + * performance optimization, it's good to cache this object in the providing + * power framework if possible. + */ + public static IBatteryObject getMjBattery(Object o, ForgeDirection side) { + return getMjBattery(o, DEFAULT_POWER_FRAMEWORK, side); + } + /** * Returns the battery related to the object given in parameter. For * performance optimization, it's good to cache this object in the providing @@ -64,22 +81,44 @@ public final class MjAPI { if (o == null) { return null; } - - IBatteryObject battery = null; - + IBatteryObject battery; + BatteryCache cache = mjBatteryCache.get(o); + if (cache == null) { + cache = new BatteryCache(); + mjBatteryCache.put(o, cache); + } else { + battery = cache.get(kind, side); + if (isCacheable(battery)) { + return battery; + } + } if (o instanceof ISidedBatteryProvider) { battery = ((ISidedBatteryProvider) o).getMjBattery(kind, side); if (battery == null && side != ForgeDirection.UNKNOWN) { battery = ((ISidedBatteryProvider) o).getMjBattery(kind, ForgeDirection.UNKNOWN); } - } - - if (o instanceof IBatteryProvider) { + } else if (o instanceof IBatteryProvider) { battery = ((IBatteryProvider) o).getMjBattery(kind); + } else { + battery = createBattery(o, kind, side); } + if (battery == null && o instanceof IPowerReceptor) { + PowerHandler.PowerReceiver receiver = ((IPowerReceptor) o).getPowerReceiver(side); + if (receiver != null) { + battery = receiver.getMjBattery(); + } + } + cache.put(kind, side, battery); + return battery; + } - if (battery != null) { - return battery; + private static boolean isCacheable(IBatteryObject battery) { + return battery != null && battery instanceof IBatteryIOObject && ((IBatteryIOObject) battery).isCacheable(); + } + + public static IBatteryObject createBattery(Object o, String kind, ForgeDirection side) { + if (o == null) { + return null; } BatteryField f = getMjBatteryField(o.getClass(), kind, side); @@ -97,7 +136,6 @@ public final class MjAPI { obj.obj = o; obj.energyStored = f.field; obj.batteryData = f.battery; - return obj; } catch (InstantiationException e) { BCLog.logger.log(Level.WARNING, "can't instantiate class for energy kind \"" + kind + "\""); @@ -110,7 +148,7 @@ public final class MjAPI { } } else { try { - return getMjBattery(f.field.get(o), kind, side); + return createBattery(f.field.get(o), kind, side); } catch (IllegalAccessException e) { e.printStackTrace(); return null; @@ -123,7 +161,7 @@ public final class MjAPI { } public static IBatteryObject[] getAllMjBatteries(Object o, ForgeDirection direction) { - IBatteryObject[] result = new IBatteryObject[mjBatteries.size()]; + IBatteryObject[] result = new IBatteryObject[mjBatteryFields.size()]; int id = 0; @@ -146,10 +184,93 @@ public final class MjAPI { } } + public static boolean canReceive(IBatteryObject battery) { + return battery != null && (!(battery instanceof IBatteryIOObject) || ((IBatteryIOObject) battery).canReceive()); + } + + public static boolean canSend(IBatteryObject battery) { + return battery != null && battery instanceof IBatteryIOObject && ((IBatteryIOObject) battery).canSend(); + } + + public static boolean isActive(IBatteryObject battery) { + return battery != null && battery instanceof IBatteryIOObject && ((IBatteryIOObject) battery).isActive(); + } + + public static double getIOLimit(IBatteryObject batteryObject, IOMode mode) { + if (mode == IOMode.Receive && canReceive(batteryObject)) { + return batteryObject.maxReceivedPerCycle(); + } else if (mode == IOMode.Send && canSend(batteryObject)) { + return ((IBatteryIOObject) batteryObject).maxSendedPerCycle(); + } + return 0; + } + + public static MjReconfigurator reconfigure() { + return reconfigurator; + } + + public static double transferEnergy(IBatteryObject fromBattery, IBatteryObject toBattery, double mj) { + if (!canSend(fromBattery) || !canReceive(toBattery)) { + return 0; + } + IBatteryIOObject from = (IBatteryIOObject) fromBattery; + double attemptToTransfer = Math.min(getIOLimit(from, IOMode.Send), mj); + attemptToTransfer = Math.min(attemptToTransfer, getIOLimit(toBattery, IOMode.Receive)); + double extracted = from.extractEnergy(attemptToTransfer); + double received = toBattery.addEnergy(extracted); + if (extracted > received) { + from.addEnergy(extracted - received); + } + return received; + } + + public static double transferEnergy(IBatteryObject fromBattery, IBatteryObject toBattery) { + return transferEnergy(fromBattery, toBattery, Math.min( + getIOLimit(fromBattery, IOMode.Send), + getIOLimit(toBattery, IOMode.Receive))); + } + + public static void updateEntity(TileEntity tile) { + for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) { + IBatteryObject batteryObject = getMjBattery(tile, direction); + TileEntity anotherTile = tile.getWorldObj().getTileEntity(tile.xCoord + direction.offsetX, tile.yCoord + direction.offsetY, tile.zCoord + direction.offsetZ); + IBatteryObject anotherBattery = getMjBattery(anotherTile, direction.getOpposite()); + if (batteryObject == null || anotherBattery == null) { + continue; + } + if (canSend(batteryObject) && canReceive(anotherBattery) && isActive(batteryObject)) { + transferEnergy(batteryObject, anotherBattery); + } + if (canReceive(batteryObject) && canSend(anotherBattery) && isActive(anotherBattery) && !isActive(batteryObject)) { + transferEnergy(anotherBattery, batteryObject); + } + } + } + + public static void resetBatteriesCache(TileEntity tile) { + mjBatteryCache.remove(tile); + } + private enum BatteryKind { Value, Container } + private static final class BatteryCache { + TIntObjectMap cache = new TIntObjectHashMap(); + + IBatteryObject get(String kind, ForgeDirection side) { + return cache.get(hash(kind, side)); + } + + void put(String kind, ForgeDirection side, IBatteryObject battery) { + cache.put(hash(kind, side), battery); + } + + private int hash(String kind, ForgeDirection side) { + return kind.hashCode() * 31 + side.hashCode(); + } + } + private static final class BatteryHolder { private String kind; private ForgeDirection side; @@ -190,7 +311,7 @@ public final class MjAPI { holder.kind = kind; holder.side = side; - BatteryField bField = mjBatteries.get(holder); + BatteryField bField = mjBatteryFields.get(holder); if (bField == null) { for (Field f : JavaTools.getAllFields(c)) { @@ -214,12 +335,12 @@ public final class MjAPI { bField.kind = BatteryKind.Container; } - mjBatteries.put(holder, bField); + mjBatteryFields.put(holder, bField); return bField; } } - mjBatteries.put(holder, invalidBatteryField); + mjBatteryFields.put(holder, invalidBatteryField); } return bField == invalidBatteryField ? null : bField; diff --git a/api/buildcraft/api/mj/MjBattery.java b/api/buildcraft/api/mj/MjBattery.java index f5f39037..9d981eca 100755 --- a/api/buildcraft/api/mj/MjBattery.java +++ b/api/buildcraft/api/mj/MjBattery.java @@ -27,7 +27,7 @@ import net.minecraftforge.common.util.ForgeDirection; * "maxReceivedPerCycle" units of energy. As an optional behavior, the system * can have a minimum amount of energy consumed even if the system is at max * capacity, modelized by the "minimumConsumption" value. - * + * * If the field designated by MjBattery is an object, then it will be considered * as a nested battery, and will look for the field in the designated object. * @@ -49,6 +49,11 @@ public @interface MjBattery { */ double maxReceivedPerCycle() default 10.0; + /** + * @return Max energy received per one tick + */ + double maxSendedPerCycle() default 10.0; + /** * @return Minimal energy for keep machine is active */ @@ -56,18 +61,26 @@ public @interface MjBattery { /** * @return The kind of battery stored. Specific power systems can be created - * through this system, as several battery of different kind can - * coexist in the same tile. + * through this system, as several battery of different kind can + * coexist in the same tile. */ String kind() default MjAPI.DEFAULT_POWER_FRAMEWORK; /** * @return Sides on which this battery should works. */ - ForgeDirection[] sides() default { ForgeDirection.UNKNOWN }; + ForgeDirection[] sides() default {ForgeDirection.UNKNOWN}; /** * @return Current battery input/output mode */ IOMode mode() default IOMode.Receive; + + /** + * @return Ability to cache this battery instance for performance reasons. Usual + * not required to modify it for every battery, you can dynamicaly reconfigure + * your batteries with {@link MjAPI#reconfigure()} and reset cache + * for tile with {@link MjAPI#resetBatteriesCache()} + */ + boolean cacheable() default true; } \ No newline at end of file diff --git a/api/buildcraft/api/mj/MjReconfigurator.java b/api/buildcraft/api/mj/MjReconfigurator.java new file mode 100644 index 00000000..50c7ef8f --- /dev/null +++ b/api/buildcraft/api/mj/MjReconfigurator.java @@ -0,0 +1,155 @@ +/** + * Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team + * 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.mj; + +import java.lang.annotation.Annotation; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.core.BCLog; + +public class MjReconfigurator { + private static final class ConfigurableMjBattery implements MjBattery { + double maxCapacity, maxReceivedPerCycle, maxSendedPerCycle, minimumConsumption; + String kind; + ForgeDirection[] sides; + IOMode mode; + boolean cacheable; + + @Override + public double maxCapacity() { + return maxCapacity; + } + + @Override + public double maxReceivedPerCycle() { + return maxReceivedPerCycle; + } + + @Override + public double minimumConsumption() { + return minimumConsumption; + } + + @Override + public double maxSendedPerCycle() { + return maxSendedPerCycle; + } + + @Override + public String kind() { + return kind; + } + + @Override + public ForgeDirection[] sides() { + return sides; + } + + @Override + public IOMode mode() { + return mode; + } + + @Override + public boolean cacheable() { + return cacheable; + } + + @Override + public Class annotationType() { + return MjBattery.class; + } + } + + public interface IConfigurableBatteryObject extends IBatteryObject { + MjBattery getMjBattery(); + + void setMjBattery(MjBattery battery); + } + + private ConfigurableMjBattery obtainConfigurableBattery(IBatteryObject battery) { + if (!(battery instanceof IConfigurableBatteryObject)) { + BCLog.logger.warning("Attempt to reconfigure unsupported battery: " + battery); + return null; + } + IConfigurableBatteryObject configurableBattery = (IConfigurableBatteryObject) battery; + MjBattery mjBattery = configurableBattery.getMjBattery(); + if (mjBattery instanceof ConfigurableMjBattery) { + return (ConfigurableMjBattery) mjBattery; + } + ConfigurableMjBattery configurableMjBattery = new ConfigurableMjBattery(); + configurableMjBattery.maxCapacity = mjBattery.maxCapacity(); + configurableMjBattery.maxReceivedPerCycle = mjBattery.maxReceivedPerCycle(); + configurableMjBattery.maxSendedPerCycle = mjBattery.maxSendedPerCycle(); + configurableMjBattery.minimumConsumption = mjBattery.minimumConsumption(); + configurableMjBattery.kind = mjBattery.kind(); + configurableMjBattery.sides = mjBattery.sides(); + configurableMjBattery.mode = mjBattery.mode(); + configurableMjBattery.cacheable = mjBattery.cacheable(); + configurableBattery.setMjBattery(configurableMjBattery); + return configurableMjBattery; + } + + public void maxCapacity(IBatteryObject batteryObject, double maxCapacity) { + ConfigurableMjBattery battery = obtainConfigurableBattery(batteryObject); + if (battery != null) { + battery.maxCapacity = maxCapacity; + } + } + + public void maxReceivedPerCycle(IBatteryObject batteryObject, double maxReceivedPerCycle) { + ConfigurableMjBattery battery = obtainConfigurableBattery(batteryObject); + if (battery != null) { + battery.maxReceivedPerCycle = maxReceivedPerCycle; + } + } + + public void maxSendedPerCycle(IBatteryObject batteryObject, double maxSendedPerCycle) { + ConfigurableMjBattery battery = obtainConfigurableBattery(batteryObject); + if (battery != null) { + battery.maxSendedPerCycle = maxSendedPerCycle; + } + } + + public void minimumConsumption(IBatteryObject batteryObject, double minimumConsumption) { + ConfigurableMjBattery battery = obtainConfigurableBattery(batteryObject); + if (battery != null) { + battery.minimumConsumption = minimumConsumption; + } + } + + public void kind(IBatteryObject batteryObject, String kind) { + ConfigurableMjBattery battery = obtainConfigurableBattery(batteryObject); + if (battery != null) { + battery.kind = kind; + } + } + + public void sides(IBatteryObject batteryObject, ForgeDirection[] sides) { + ConfigurableMjBattery battery = obtainConfigurableBattery(batteryObject); + if (battery != null) { + battery.sides = sides; + } + } + + public void mode(IBatteryObject batteryObject, IOMode mode) { + ConfigurableMjBattery battery = obtainConfigurableBattery(batteryObject); + if (battery != null) { + battery.mode = mode; + } + } + + public void cacheable(IBatteryObject batteryObject, boolean cacheable) { + ConfigurableMjBattery battery = obtainConfigurableBattery(batteryObject); + if (battery != null) { + battery.cacheable = cacheable; + } + } +} diff --git a/api/buildcraft/api/power/PowerHandler.java b/api/buildcraft/api/power/PowerHandler.java index f8dd3a4b..bcf8bffb 100644 --- a/api/buildcraft/api/power/PowerHandler.java +++ b/api/buildcraft/api/power/PowerHandler.java @@ -16,6 +16,7 @@ import buildcraft.api.core.SafeTimeTracker; import buildcraft.api.mj.BatteryObject; import buildcraft.api.mj.IBatteryObject; import buildcraft.api.mj.IBatteryProvider; +import buildcraft.api.mj.IOMode; import buildcraft.api.mj.MjAPI; import buildcraft.api.mj.MjBattery; @@ -83,11 +84,7 @@ public final class PowerHandler implements IBatteryProvider { * @param powerLoss power loss per tick */ public PerditionCalculator(double powerLoss) { - if (powerLoss < MIN_POWERLOSS) { - this.powerLoss = MIN_POWERLOSS; - } else { - this.powerLoss = powerLoss; - } + this.powerLoss = powerLoss; } /** @@ -129,9 +126,9 @@ public final class PowerHandler implements IBatteryProvider { public final IPowerReceptor receptor; private double activationEnergy; - private final SafeTimeTracker doWorkTracker = new SafeTimeTracker(); - private final SafeTimeTracker sourcesTracker = new SafeTimeTracker(); - private final SafeTimeTracker perditionTracker = new SafeTimeTracker(); + private final SafeTimeTracker doWorkTracker = new SafeTimeTracker(1); + private final SafeTimeTracker sourcesTracker = new SafeTimeTracker(1); + private final SafeTimeTracker perditionTracker = new SafeTimeTracker(1); private PerditionCalculator perdition; private final PowerReceiver receiver; private final Type type; @@ -151,12 +148,18 @@ public final class PowerHandler implements IBatteryProvider { this.receiver = new PowerReceiver(); this.perdition = DEFAULT_PERDITION; + boolean created = false; if (battery instanceof IBatteryObject) { this.battery = (BatteryObject) battery; } else if (battery != null) { - this.battery = MjAPI.getMjBattery(battery); + this.battery = MjAPI.createBattery(battery, MjAPI.DEFAULT_POWER_FRAMEWORK, ForgeDirection.UNKNOWN); + created = true; } else { - this.battery = MjAPI.getMjBattery(new AnonymousBattery()); + this.battery = MjAPI.createBattery(new AnonymousBattery(), MjAPI.DEFAULT_POWER_FRAMEWORK, ForgeDirection.UNKNOWN); + created = true; + } + if (receptor instanceof IPowerEmitter && created) { + MjAPI.reconfigure().mode(this.battery, IOMode.Send); } } @@ -221,7 +224,9 @@ public final class PowerHandler implements IBatteryProvider { } this.activationEnergy = activationEnergy; - battery.reconfigure(maxStoredEnergy, localMaxEnergyReceived, minEnergyReceived); + MjAPI.reconfigure().maxCapacity(battery, maxStoredEnergy); + MjAPI.reconfigure().maxReceivedPerCycle(battery, localMaxEnergyReceived); + MjAPI.reconfigure().minimumConsumption(battery, minEnergyReceived); } /** @@ -284,30 +289,27 @@ public final class PowerHandler implements IBatteryProvider { private void applyPerdition() { double energyStored = getEnergyStored(); - if (perditionTracker.markTimeIfDelay(receptor.getWorld(), 1) && energyStored > 0) { - double prev = energyStored; + if (perditionTracker.markTimeIfDelay(receptor.getWorld()) && energyStored > 0) { double newEnergy = getPerdition().applyPerdition(this, energyStored, perditionTracker.durationOfLastDelay()); - if (newEnergy == 0 || newEnergy < energyStored) { + if (newEnergy != energyStored) { battery.setEnergyStored(energyStored = newEnergy); - } else { - battery.setEnergyStored(energyStored = DEFAULT_PERDITION.applyPerdition(this, energyStored, perditionTracker.durationOfLastDelay())); } validateEnergy(); - averageLostPower = (averageLostPower * ROLLING_AVERAGE_NUMERATOR + (prev - energyStored)) * ROLLING_AVERAGE_DENOMINATOR; + averageLostPower = (averageLostPower * ROLLING_AVERAGE_NUMERATOR + (getEnergyStored() - energyStored)) * ROLLING_AVERAGE_DENOMINATOR; } } private void applyWork() { if (getEnergyStored() >= activationEnergy) { - if (doWorkTracker.markTimeIfDelay(receptor.getWorld(), 1)) { + if (doWorkTracker.markTimeIfDelay(receptor.getWorld())) { receptor.doWork(this); } } } private void updateSources(ForgeDirection source) { - if (sourcesTracker.markTimeIfDelay(receptor.getWorld(), 1)) { + if (sourcesTracker.markTimeIfDelay(receptor.getWorld())) { for (int i = 0; i < 6; ++i) { powerSources[i] -= sourcesTracker.durationOfLastDelay(); if (powerSources[i] < 0) { @@ -469,6 +471,10 @@ public final class PowerHandler implements IBatteryProvider { return used; } + + public IBatteryObject getMjBattery() { + return battery; + } } /** diff --git a/common/buildcraft/energy/EnergyProxy.java b/common/buildcraft/energy/EnergyProxy.java index 916b4663..30f0ed61 100644 --- a/common/buildcraft/energy/EnergyProxy.java +++ b/common/buildcraft/energy/EnergyProxy.java @@ -16,7 +16,6 @@ public class EnergyProxy { public static EnergyProxy proxy; public void registerTileEntities() { - GameRegistry.registerTileEntity(TileEngineLegacy.class, "net.minecraft.src.buildcraft.energy.Engine"); GameRegistry.registerTileEntity(TileEngineWood.class, "net.minecraft.src.buildcraft.energy.TileEngineWood"); GameRegistry.registerTileEntity(TileEngineStone.class, "net.minecraft.src.buildcraft.energy.TileEngineStone"); GameRegistry.registerTileEntity(TileEngineIron.class, "net.minecraft.src.buildcraft.energy.TileEngineIron"); diff --git a/common/buildcraft/energy/TileEnergyConverter.java b/common/buildcraft/energy/TileEnergyConverter.java index ad1cd2e5..59d7aa57 100644 --- a/common/buildcraft/energy/TileEnergyConverter.java +++ b/common/buildcraft/energy/TileEnergyConverter.java @@ -55,7 +55,7 @@ public class TileEnergyConverter extends TileBuildCraft implements IPowerRecepto private PowerHandler powerHandler, zeroPowerHandler; public TileEnergyConverter() { - powerHandler = new PowerHandler(this, PowerHandler.Type.MACHINE, MjAPI.getMjBattery(this)); + powerHandler = new PowerHandler(this, PowerHandler.Type.MACHINE, MjAPI.createBattery(this, MjAPI.DEFAULT_POWER_FRAMEWORK, ForgeDirection.UNKNOWN)); zeroPowerHandler = new PowerHandler(this, PowerHandler.Type.MACHINE); zeroPowerHandler.configure(0, 0, 0, 0); } diff --git a/common/buildcraft/energy/TileEngine.java b/common/buildcraft/energy/TileEngine.java index 1ac3f073..fa1d52fc 100644 --- a/common/buildcraft/energy/TileEngine.java +++ b/common/buildcraft/energy/TileEngine.java @@ -22,7 +22,9 @@ import buildcraft.BuildCraftEnergy; import buildcraft.api.core.NetworkData; import buildcraft.api.gates.IOverrideDefaultTriggers; import buildcraft.api.gates.ITrigger; +import buildcraft.api.mj.IBatteryIOObject; import buildcraft.api.mj.IBatteryObject; +import buildcraft.api.mj.ISidedBatteryProvider; import buildcraft.api.mj.MjAPI; import buildcraft.api.power.IPowerEmitter; import buildcraft.api.power.IPowerReceptor; @@ -35,9 +37,10 @@ import buildcraft.api.transport.IPipeTile.PipeType; import buildcraft.core.DefaultProps; import buildcraft.core.TileBuffer; import buildcraft.core.TileBuildCraft; +import buildcraft.core.utils.AverageUtil; import buildcraft.energy.gui.ContainerEngine; -public abstract class TileEngine extends TileBuildCraft implements IPowerReceptor, IPowerEmitter, IOverrideDefaultTriggers, IPipeConnection { +public abstract class TileEngine extends TileBuildCraft implements ISidedBatteryProvider, IPowerReceptor, IPowerEmitter, IOverrideDefaultTriggers, IPipeConnection { // Index corresponds to metadata public static final ResourceLocation[] BASE_TEXTURES = new ResourceLocation[]{ @@ -76,10 +79,8 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto public static final float MIN_HEAT = 20; public static final float IDEAL_HEAT = 100; public static final float MAX_HEAT = 250; - public double currentOutput = 0; public boolean isRedstonePowered = false; public float progress; - public double energy; public float heat = MIN_HEAT; @NetworkData public EnergyStage energyStage = EnergyStage.BLUE; @@ -89,6 +90,9 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto protected int progressPart = 0; protected boolean lastPower = false; protected PowerHandler powerHandler; + protected IBatteryIOObject mjStoredBattery; + protected AverageUtil currentOutputAverage = new AverageUtil(20); + protected double currentOutput = -1; private boolean checkOrienation = false; private TileBuffer[] tileCache; @@ -97,14 +101,32 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto private boolean isPumping = false; // Used for SMP synch public TileEngine() { - powerHandler = new PowerHandler(this, Type.ENGINE); - powerHandler.configurePowerPerdition(1, 100); + mjStoredBattery = (IBatteryIOObject) MjAPI.createBattery(this, MjAPI.DEFAULT_POWER_FRAMEWORK, ForgeDirection.UNKNOWN); + if (mjStoredBattery == null) { + throw new NullPointerException("Engine " + this + " doesn't has a battery!"); + } + powerHandler = new PowerHandler(this, Type.ENGINE, mjStoredBattery); + powerHandler.configurePowerPerdition(0, 0); + } + + public double getCurrentOutputAverage() { + if (currentOutput != -1) { + return currentOutput; + } + return currentOutputAverage.getAverage(); + } + + @Override + public IBatteryObject getMjBattery(String kind, ForgeDirection direction) { + if (mjStoredBattery.kind().equals(kind) && direction == orientation) { + return mjStoredBattery; + } + return null; } @Override public void initialize() { if (!worldObj.isRemote) { - powerHandler.configure(minEnergyReceived(), maxEnergyReceived(), 1, getMaxEnergy()); checkRedstonePower(); } } @@ -133,7 +155,7 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto } public double getEnergyLevel() { - return energy / getMaxEnergy(); + return mjStoredBattery.getEnergyStored() / mjStoredBattery.maxCapacity() + .01d; } protected EnergyStage computeEnergyStage() { @@ -206,6 +228,7 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto @Override public void updateEntity() { super.updateEntity(); + MjAPI.updateEntity(this); if (worldObj.isRemote) { if (progressPart != 0) { @@ -230,12 +253,9 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto } } - if (!isRedstonePowered) { - if (energy > 1) { - energy--; - } - } + currentOutputAverage.tick(); + burn(); updateHeatLevel(); getEnergyStage(); engineUpdate(); @@ -247,92 +267,29 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto if (progress > 0.5 && progressPart == 1) { progressPart = 2; - sendPower(); // Comment out for constant power } else if (progress >= 1) { progress = 0; progressPart = 0; } } else if (isRedstonePowered && isActive()) { if (isPoweredTile(tile, orientation)) { - if (getPowerToExtract() > 0) { - progressPart = 1; - setPumping(true); - } else { - setPumping(false); - } + progressPart = 1; + setPumping(true); } else { setPumping(false); } } else { + progressPart = 0; setPumping(false); } - - // Uncomment for constant power -// if (isRedstonePowered && isActive()) { -// sendPower(); -// } else currentOutput = 0; - - burn(); } - private double getPowerToExtract() { - TileEntity tile = getTileBuffer(orientation).getTile(); - - IBatteryObject battery = MjAPI.getMjBattery(tile, MjAPI.DEFAULT_POWER_FRAMEWORK, orientation.getOpposite()); - - if (battery != null) { - return extractEnergy(0, battery.getEnergyRequested(), false); - } else if (tile instanceof IPowerReceptor) { - PowerReceiver receptor = ((IPowerReceptor) tile) - .getPowerReceiver(orientation.getOpposite()); - - return extractEnergy(receptor.getMinEnergyReceived(), - receptor.getMaxEnergyReceived(), false); - } else { - return 0; - } - } - - private void sendPower() { - TileEntity tile = getTileBuffer(orientation).getTile(); - if (isPoweredTile(tile, orientation)) { - double extracted = getPowerToExtract(); - - IBatteryObject battery = MjAPI.getMjBattery(tile, MjAPI.DEFAULT_POWER_FRAMEWORK, orientation.getOpposite()); - - if (battery != null) { - battery.addEnergy(extractEnergy(0, battery.maxReceivedPerCycle(), - true)); - } else if (tile instanceof IPowerReceptor) { - PowerReceiver receptor = ((IPowerReceptor) tile) - .getPowerReceiver(orientation.getOpposite()); - - if (extracted > 0) { - double needed = receptor.receiveEnergy( - PowerHandler.Type.ENGINE, extracted, - orientation.getOpposite()); - - extractEnergy(receptor.getMinEnergyReceived(), needed, true); - } - } - } - } - - // Uncomment out for constant power -// public float getActualOutput() { -// float heatLevel = getIdealHeatLevel(); -// return getCurrentOutput() * heatLevel; -// } protected void burn() { } protected void engineUpdate() { if (!isRedstonePowered) { - if (energy >= 1) { - energy -= 1; - } else if (energy < 1) { - energy = 0; - } + mjStoredBattery.extractEnergy(1); } } @@ -409,7 +366,7 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto orientation = ForgeDirection.getOrientation(data.getInteger("orientation")); progress = data.getFloat("progress"); - energy = data.getDouble("energy"); + mjStoredBattery.setEnergyStored(data.getDouble("energy")); heat = data.getFloat("heat"); } @@ -419,21 +376,21 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto data.setInteger("orientation", orientation.ordinal()); data.setFloat("progress", progress); - data.setDouble("energy", energy); + data.setDouble("energy", mjStoredBattery.getEnergyStored()); data.setFloat("heat", heat); } public void getGUINetworkData(int id, int value) { switch (id) { case 0: - int iEnergy = (int) Math.round(energy * 10); + int iEnergy = (int) Math.round(mjStoredBattery.getEnergyStored() * 10); iEnergy = (iEnergy & 0xffff0000) | (value & 0xffff); - energy = iEnergy / 10; + mjStoredBattery.setEnergyStored(iEnergy / 10); break; case 1: - iEnergy = (int) Math.round(energy * 10); + iEnergy = (int) Math.round(mjStoredBattery.getEnergyStored() * 10); iEnergy = (iEnergy & 0xffff) | ((value & 0xffff) << 16); - energy = iEnergy / 10; + mjStoredBattery.setEnergyStored(iEnergy / 10); break; case 2: currentOutput = value / 10F; @@ -445,9 +402,9 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto } public void sendGUINetworkData(ContainerEngine containerEngine, ICrafting iCrafting) { - iCrafting.sendProgressBarUpdate(containerEngine, 0, (int) Math.round(energy * 10) & 0xffff); - iCrafting.sendProgressBarUpdate(containerEngine, 1, (int) (Math.round(energy * 10) & 0xffff0000) >> 16); - iCrafting.sendProgressBarUpdate(containerEngine, 2, (int) Math.round(currentOutput * 10)); + iCrafting.sendProgressBarUpdate(containerEngine, 0, (int) Math.round(mjStoredBattery.getEnergyStored() * 10) & 0xffff); + iCrafting.sendProgressBarUpdate(containerEngine, 1, (int) (Math.round(mjStoredBattery.getEnergyStored() * 10) & 0xffff0000) >> 16); + iCrafting.sendProgressBarUpdate(containerEngine, 2, (int) Math.round(currentOutputAverage.getAverage() * 10)); iCrafting.sendProgressBarUpdate(containerEngine, 3, Math.round(heat * 100)); } @@ -463,92 +420,34 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto @Override public void doWork(PowerHandler workProvider) { - if (worldObj.isRemote) { - return; - } - addEnergy(powerHandler.useEnergy(1, maxEnergyReceived(), true) * 0.95F); } public void addEnergy(double addition) { - energy += addition; + double stored = mjStoredBattery.getEnergyStored(); + double used = Math.min(addition, mjStoredBattery.maxReceivedPerCycle()); + used = Math.min(used, mjStoredBattery.maxCapacity() - stored); + if (used > 0) { + currentOutputAverage.push(used); + mjStoredBattery.addEnergy(used); + } if (getEnergyStage() == EnergyStage.OVERHEAT) { worldObj.createExplosion(null, xCoord, yCoord, zCoord, explosionRange(), true); worldObj.setBlockToAir(xCoord, yCoord, zCoord); } - - if (energy > getMaxEnergy()) { - energy = getMaxEnergy(); - } - } - - public double extractEnergy(double min, double max, boolean doExtract) { - if (energy < min) { - return 0; - } - - double actualMax; - - if (max > maxEnergyExtracted()) { - actualMax = maxEnergyExtracted(); - } else { - actualMax = max; - } - - if (actualMax < min) { - return 0; - } - - double extracted; - - if (energy >= actualMax) { - extracted = actualMax; - - if (doExtract) { - energy -= actualMax; - } - } else { - extracted = energy; - - if (doExtract) { - energy = 0; - } - } - - return extracted; } public boolean isPoweredTile(TileEntity tile, ForgeDirection side) { - if (tile == null) { - return false; - } else if (MjAPI.getMjBattery(tile, MjAPI.DEFAULT_POWER_FRAMEWORK, orientation.getOpposite()) != null) { - return true; - } else if (tile instanceof IPowerReceptor) { - return ((IPowerReceptor) tile).getPowerReceiver(side.getOpposite()) != null; - } else { - return false; - } + return MjAPI.getMjBattery(tile, MjAPI.DEFAULT_POWER_FRAMEWORK, side.getOpposite()) != null; } - public abstract double getMaxEnergy(); - - public double minEnergyReceived() { - return 2; - } - - public abstract double maxEnergyReceived(); - - public abstract double maxEnergyExtracted(); - public abstract float explosionRange(); public double getEnergyStored() { - return energy; + return mjStoredBattery.getEnergyStored(); } - public abstract double getCurrentOutput(); - @Override public LinkedList getTriggers() { LinkedList triggers = new LinkedList(); diff --git a/common/buildcraft/energy/TileEngineCreative.java b/common/buildcraft/energy/TileEngineCreative.java index 2de2f95b..1e785b86 100644 --- a/common/buildcraft/energy/TileEngineCreative.java +++ b/common/buildcraft/energy/TileEngineCreative.java @@ -17,11 +17,17 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.util.ForgeDirection; import buildcraft.api.core.NetworkData; +import buildcraft.api.mj.IOMode; +import buildcraft.api.mj.MjAPI; +import buildcraft.api.mj.MjBattery; import buildcraft.api.tools.IToolWrench; import buildcraft.core.utils.StringUtils; import buildcraft.transport.pipes.PipePowerIron; public class TileEngineCreative extends TileEngine { + @MjBattery(mode = IOMode.SendActive, maxCapacity = 10000, maxReceivedPerCycle = 2, minimumConsumption = 0) + @NetworkData + private double mjStored; @NetworkData private PipePowerIron.PowerMode powerMode = PipePowerIron.PowerMode.M2; @@ -53,7 +59,8 @@ public class TileEngineCreative extends TileEngine { if (equipped instanceof IToolWrench && ((IToolWrench) equipped).canWrench(player, xCoord, yCoord, zCoord)) { powerMode = powerMode.getNext(); - energy = 0; + reconfigure(); + mjStored = 0; player.addChatMessage(new ChatComponentText(String.format(StringUtils.localize("chat.pipe.power.iron.mode"), powerMode.maxPower))); @@ -72,6 +79,11 @@ public class TileEngineCreative extends TileEngine { super.readFromNBT(data); powerMode = PipePowerIron.PowerMode.fromId(data.getByte("mode")); + reconfigure(); + } + + private void reconfigure() { + MjAPI.reconfigure().maxReceivedPerCycle(mjStoredBattery, powerMode.maxPower); } @Override @@ -89,9 +101,8 @@ public class TileEngineCreative extends TileEngine { @Override public void engineUpdate() { super.engineUpdate(); - if (isRedstonePowered) { - addEnergy(getCurrentOutput()); + mjStored = Math.min(mjStored + powerMode.maxPower, mjStoredBattery.maxCapacity()); } } @@ -105,26 +116,6 @@ public class TileEngineCreative extends TileEngine { return 0; } - @Override - public double maxEnergyReceived() { - return getCurrentOutput(); - } - - @Override - public double maxEnergyExtracted() { - return getCurrentOutput(); - } - - @Override - public double getMaxEnergy() { - return getCurrentOutput(); - } - - @Override - public double getCurrentOutput() { - return powerMode.maxPower; - } - @Override public float explosionRange() { return 0; diff --git a/common/buildcraft/energy/TileEngineIron.java b/common/buildcraft/energy/TileEngineIron.java index 3f122680..ee316c17 100644 --- a/common/buildcraft/energy/TileEngineIron.java +++ b/common/buildcraft/energy/TileEngineIron.java @@ -26,11 +26,14 @@ import net.minecraftforge.fluids.IFluidHandler; import buildcraft.BuildCraftCore; import buildcraft.BuildCraftEnergy; +import buildcraft.api.core.NetworkData; import buildcraft.api.fuels.IronEngineCoolant; import buildcraft.api.fuels.IronEngineCoolant.Coolant; import buildcraft.api.fuels.IronEngineFuel; import buildcraft.api.fuels.IronEngineFuel.Fuel; import buildcraft.api.gates.ITrigger; +import buildcraft.api.mj.IOMode; +import buildcraft.api.mj.MjBattery; import buildcraft.core.GuiIds; import buildcraft.core.IItemPipe; import buildcraft.core.fluids.FluidUtils; @@ -56,6 +59,10 @@ public class TileEngineIron extends TileEngineWithInventory implements IFluidHan private boolean lastPowered = false; private BiomeGenBase biomeCache; + @MjBattery(mode = IOMode.SendActive, maxCapacity = 10000, maxSendedPerCycle = 500, minimumConsumption = 0) + @NetworkData + private double mjStored; + public TileEngineIron() { super(1); tankManager.add(tankFuel); @@ -173,7 +180,6 @@ public class TileEngineIron extends TileEngineWithInventory implements IFluidHan return; } } - currentOutput = currentFuel.powerPerCycle; // Comment out for constant power addEnergy(currentFuel.powerPerCycle); heat += currentFuel.powerPerCycle * HEAT_PER_MJ * getBiomeTempScalar(); } @@ -339,7 +345,7 @@ public class TileEngineIron extends TileEngineWithInventory implements IFluidHan @Override public boolean isActive() { - return penaltyCooling <= 0; + return currentFuel != null && penaltyCooling <= 0; } /* ITANKCONTAINER */ @@ -413,29 +419,6 @@ public class TileEngineIron extends TileEngineWithInventory implements IFluidHan return tankCoolant.getFluid(); } - @Override - public double maxEnergyReceived() { - return 2000; - } - - @Override - public double maxEnergyExtracted() { - return 500; - } - - @Override - public double getMaxEnergy() { - return 10000; - } - - @Override - public double getCurrentOutput() { - if (currentFuel == null) { - return 0; - } - return currentFuel.powerPerCycle; - } - @Override public LinkedList getTriggers() { LinkedList triggers = super.getTriggers(); diff --git a/common/buildcraft/energy/TileEngineLegacy.java b/common/buildcraft/energy/TileEngineLegacy.java deleted file mode 100644 index b1f2b1bb..00000000 --- a/common/buildcraft/energy/TileEngineLegacy.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team - * 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.energy; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ResourceLocation; - -/** - * This class is just intended to update pre 4.0 engines to the design. - *

- * It can be deleted someday. - */ -public class TileEngineLegacy extends TileEngine { - - private NBTTagCompound nbt; - - @Override - public void updateEntity() { - worldObj.removeTileEntity(xCoord, yCoord, zCoord); - TileEntity newTile = worldObj.getTileEntity(xCoord, yCoord, zCoord); - if (newTile instanceof TileEngine) { - newTile.readFromNBT(nbt); - sendNetworkUpdate(); - worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); - } - } - - @Override - public void readFromNBT(NBTTagCompound data) { - nbt = (NBTTagCompound) data.copy(); - this.xCoord = data.getInteger("x"); - this.yCoord = data.getInteger("y"); - this.zCoord = data.getInteger("z"); - } - - @Override - public ResourceLocation getBaseTexture() { - return BASE_TEXTURES[0]; - } - - @Override - public ResourceLocation getChamberTexture() { - return CHAMBER_TEXTURES[0]; - } - - @Override - public double getMaxEnergy() { - return 1; - } - - @Override - public double maxEnergyReceived() { - return 0; - } - - @Override - public float explosionRange() { - return 0; - } - - @Override - public boolean isBurning() { - return false; - } - - @Override - public int getScaledBurnTime(int scale) { - return 0; - } - - @Override - public double getCurrentOutput() { - return 1; - } - - @Override - public double maxEnergyExtracted() { - return 1; - } -} diff --git a/common/buildcraft/energy/TileEngineStone.java b/common/buildcraft/energy/TileEngineStone.java index 684c9a05..786e392f 100644 --- a/common/buildcraft/energy/TileEngineStone.java +++ b/common/buildcraft/energy/TileEngineStone.java @@ -21,7 +21,10 @@ import net.minecraftforge.common.util.ForgeDirection; import buildcraft.BuildCraftCore; import buildcraft.BuildCraftEnergy; +import buildcraft.api.core.NetworkData; import buildcraft.api.gates.ITrigger; +import buildcraft.api.mj.IOMode; +import buildcraft.api.mj.MjBattery; import buildcraft.core.GuiIds; import buildcraft.core.inventory.InvUtils; import buildcraft.core.utils.MathUtils; @@ -39,10 +42,19 @@ public class TileEngineStone extends TileEngineWithInventory { int totalBurnTime = 0; double esum = 0; + @MjBattery(mode = IOMode.SendActive, maxCapacity = 1000, maxSendedPerCycle = 500, minimumConsumption = 0) + @NetworkData + private double mjStored; + public TileEngineStone() { super(1); } + @Override + public boolean isActive() { + return isBurning(); + } + @Override public ResourceLocation getBaseTexture() { return BASE_TEXTURES[1]; @@ -76,9 +88,11 @@ public class TileEngineStone extends TileEngineWithInventory { if (burnTime > 0) { burnTime--; - double output = getCurrentOutput(); - currentOutput = output; // Comment out for constant power - addEnergy(output); + double output = TARGET_OUTPUT * mjStoredBattery.maxCapacity() - mjStored; + esum = MathUtils.clamp(esum + output, -eLimit, eLimit); + addEnergy(MathUtils.clamp(output * kp + esum * ki, MIN_OUTPUT, MAX_OUTPUT)); + } else { + totalBurnTime = 0; } if (burnTime == 0 && isRedstonePowered) { @@ -138,28 +152,6 @@ public class TileEngineStone extends TileEngineWithInventory { iCrafting.sendProgressBarUpdate(containerEngine, 16, totalBurnTime); } - @Override - public double maxEnergyReceived() { - return 200; - } - - @Override - public double maxEnergyExtracted() { - return 100; - } - - @Override - public double getMaxEnergy() { - return 1000; - } - - @Override - public double getCurrentOutput() { - double e = TARGET_OUTPUT * getMaxEnergy() - energy; - esum = MathUtils.clamp(esum + e, -eLimit, eLimit); - return MathUtils.clamp(e * kp + esum * ki, MIN_OUTPUT, MAX_OUTPUT); - } - @Override public LinkedList getTriggers() { LinkedList triggers = super.getTriggers(); diff --git a/common/buildcraft/energy/TileEngineWood.java b/common/buildcraft/energy/TileEngineWood.java index 85f9f1f6..51966ec8 100644 --- a/common/buildcraft/energy/TileEngineWood.java +++ b/common/buildcraft/energy/TileEngineWood.java @@ -12,12 +12,15 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.util.ForgeDirection; -import buildcraft.api.power.PowerHandler; +import buildcraft.api.core.NetworkData; +import buildcraft.api.mj.IOMode; +import buildcraft.api.mj.MjBattery; import buildcraft.api.transport.IPipeTile.PipeType; public class TileEngineWood extends TileEngine { - - public static final float OUTPUT = 0.05F; + @MjBattery(mode = IOMode.SendActive, maxCapacity = 100, maxSendedPerCycle = 1, minimumConsumption = 0) + @NetworkData + private double mjStored; @Override public ResourceLocation getBaseTexture() { @@ -34,16 +37,6 @@ public class TileEngineWood extends TileEngine { return 1; } - @Override - public double minEnergyReceived() { - return 0; - } - - @Override - public double maxEnergyReceived() { - return 50; - } - @Override protected EnergyStage computeEnergyStage() { double energyLevel = getEnergyLevel(); @@ -80,10 +73,8 @@ public class TileEngineWood extends TileEngine { public void engineUpdate() { super.engineUpdate(); - if (isRedstonePowered) { - if (worldObj.getTotalWorldTime() % 16 == 0) { - addEnergy(1); - } + if (isRedstonePowered && worldObj.getTotalWorldTime() % 16 == 0) { + addEnergy(1); } } @@ -101,19 +92,4 @@ public class TileEngineWood extends TileEngine { public int getScaledBurnTime(int i) { return 0; } - - @Override - public double getMaxEnergy() { - return 100; - } - - @Override - public double getCurrentOutput() { - return OUTPUT; - } - - @Override - public double maxEnergyExtracted() { - return 1 + PowerHandler.PerditionCalculator.MIN_POWERLOSS; - } } diff --git a/common/buildcraft/energy/gui/GuiEngine.java b/common/buildcraft/energy/gui/GuiEngine.java index 465a03e5..22499ba4 100644 --- a/common/buildcraft/energy/gui/GuiEngine.java +++ b/common/buildcraft/energy/gui/GuiEngine.java @@ -52,7 +52,7 @@ public abstract class GuiEngine extends GuiBuildCraft { fontRendererObj.drawStringWithShadow(StringUtils.localize("gui.energy"), x + 22, y + 8, headerColour); fontRendererObj.drawStringWithShadow(StringUtils.localize("gui.currentOutput") + ":", x + 22, y + 20, subheaderColour); - fontRendererObj.drawString(String.format("%.1f MJ/t", engine.currentOutput), x + 22, y + 32, textColour); + fontRendererObj.drawString(String.format("%.1f MJ/t", engine.getCurrentOutputAverage()), x + 22, y + 32, textColour); fontRendererObj.drawStringWithShadow(StringUtils.localize("gui.stored") + ":", x + 22, y + 44, subheaderColour); fontRendererObj.drawString(String.format("%.1f MJ", engine.getEnergyStored()), x + 22, y + 56, textColour); fontRendererObj.drawStringWithShadow(StringUtils.localize("gui.heat") + ":", x + 22, y + 68, subheaderColour); @@ -62,7 +62,7 @@ public abstract class GuiEngine extends GuiBuildCraft { @Override public String getTooltip() { - return String.format("%.1f MJ/t", engine.currentOutput); + return String.format("%.1f MJ/t", engine.getCurrentOutputAverage()); } } diff --git a/common/buildcraft/transport/PipeTransportPower.java b/common/buildcraft/transport/PipeTransportPower.java index 70d32599..7babd429 100644 --- a/common/buildcraft/transport/PipeTransportPower.java +++ b/common/buildcraft/transport/PipeTransportPower.java @@ -112,7 +112,7 @@ public class PipeTransportPower extends PipeTransport { } } - if (MjAPI.getMjBattery(tile, MjAPI.DEFAULT_POWER_FRAMEWORK, side.getOpposite()) != null) { + if (MjAPI.canReceive(MjAPI.getMjBattery(tile, MjAPI.DEFAULT_POWER_FRAMEWORK, side.getOpposite()))) { return true; } diff --git a/common/buildcraft/transport/pipes/PipePowerWood.java b/common/buildcraft/transport/pipes/PipePowerWood.java index 2fd36715..d449f749 100644 --- a/common/buildcraft/transport/pipes/PipePowerWood.java +++ b/common/buildcraft/transport/pipes/PipePowerWood.java @@ -10,6 +10,7 @@ package buildcraft.transport.pipes; import net.minecraft.item.Item; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -19,7 +20,9 @@ import net.minecraftforge.common.util.ForgeDirection; import buildcraft.BuildCraftTransport; import buildcraft.api.core.IIconProvider; import buildcraft.api.core.SafeTimeTracker; -import buildcraft.api.mj.MjAPILegacy; +import buildcraft.api.mj.IBatteryObject; +import buildcraft.api.mj.IOMode; +import buildcraft.api.mj.MjAPI; import buildcraft.api.mj.MjBattery; import buildcraft.api.power.IPowerEmitter; import buildcraft.api.power.IPowerReceptor; @@ -39,15 +42,17 @@ public class PipePowerWood extends Pipe implements IPowerRec protected int standardIconIndex = PipeIconProvider.TYPE.PipePowerWood_Standard.ordinal(); protected int solidIconIndex = PipeIconProvider.TYPE.PipeAllWood_Solid.ordinal(); - @MjBattery(maxCapacity = 1500, maxReceivedPerCycle = 500, minimumConsumption = 0) + @MjBattery(mode = IOMode.ReceiveActive, maxCapacity = 1500, maxReceivedPerCycle = 500, minimumConsumption = 0) private double mjStored = 0; private final SafeTimeTracker sourcesTracker = new SafeTimeTracker(1); private boolean full; - private MjAPILegacy powerHandler; + private PowerHandler powerHandler; public PipePowerWood(Item item) { super(new PipeTransportPower(), item); + powerHandler = new PowerHandler(this, Type.PIPE); + powerHandler.configurePowerPerdition(0, 0); transport.initFromPipe(getClass()); } @@ -70,51 +75,51 @@ public class PipePowerWood extends Pipe implements IPowerRec return; } - if (mjStored > 0) { - int sources = 0; + int sources = 0; - for (ForgeDirection o : ForgeDirection.VALID_DIRECTIONS) { - if (!container.isPipeConnected(o)) { - powerSources[o.ordinal()] = false; - continue; - } - - if (isPowerSource(o)) { - powerSources[o.ordinal()] = true; - } - - if (powerSources[o.ordinal()]) { - sources++; - } + for (ForgeDirection o : ForgeDirection.VALID_DIRECTIONS) { + if (!container.isPipeConnected(o)) { + powerSources[o.ordinal()] = false; + continue; } - if (sources <= 0) { - mjStored = mjStored > 5 ? mjStored - 5 : 0; - return; + TileEntity tile = container.getTile(o); + + if (powerSources[o.ordinal()] = isPowerSource(tile, o)) { + sources++; + } + } + + if (sources <= 0) { + mjStored = mjStored > 5 ? mjStored - 5 : 0; + return; + } + + if (mjStored == 0) { + return; + } + + double energyToRemove; + + if (mjStored > 40) { + energyToRemove = mjStored / 40 + 4; + } else if (mjStored > 10) { + energyToRemove = mjStored / 10; + } else { + energyToRemove = 1; + } + energyToRemove /= sources; + + for (ForgeDirection o : ForgeDirection.VALID_DIRECTIONS) { + if (!powerSources[o.ordinal()]) { + continue; } - double energyToRemove; + double energyUsable = mjStored > energyToRemove ? energyToRemove : mjStored; + double energySent = transport.receiveEnergy(o, energyUsable); - if (mjStored > 40) { - energyToRemove = mjStored / 40 + 4; - } else if (mjStored > 10) { - energyToRemove = mjStored / 10; - } else { - energyToRemove = 1; - } - energyToRemove /= sources; - - for (ForgeDirection o : ForgeDirection.VALID_DIRECTIONS) { - if (!powerSources[o.ordinal()]) { - continue; - } - - double energyUsable = mjStored > energyToRemove ? energyToRemove : mjStored; - double energySent = transport.receiveEnergy(o, energyUsable); - - if (energySent > 0) { - mjStored -= energySent; - } + if (energySent > 0) { + mjStored -= energySent; } } } @@ -169,17 +174,17 @@ public class PipePowerWood extends Pipe implements IPowerRec } } - public boolean isPowerSource(ForgeDirection from) { - return container.getTile(from) instanceof IPowerEmitter; + public boolean isPowerSource(TileEntity tile, ForgeDirection from) { + if (tile instanceof IPowerEmitter && ((IPowerEmitter) tile).canEmitPowerFrom(from.getOpposite())) { + return true; + } + IBatteryObject battery = MjAPI.getMjBattery(tile, MjAPI.DEFAULT_POWER_FRAMEWORK, from.getOpposite()); + return MjAPI.canSend(battery) && MjAPI.isActive(battery); } @Override public PowerReceiver getPowerReceiver(ForgeDirection side) { - if (powerHandler == null) { - powerHandler = MjAPILegacy.from(container, Type.PIPE); - } - - return powerHandler.getPowerReceiver(ForgeDirection.UNKNOWN); + return powerHandler.getPowerReceiver(); } @Override