start removing the "new" MJ API, commit RedBuildCraft engine implementation

This commit is contained in:
asiekierka 2014-09-03 11:21:08 +02:00
parent 75d8779d65
commit ab84e095cd
31 changed files with 539 additions and 1811 deletions

View file

@ -1,200 +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.api.mj;
import java.lang.reflect.Field;
import org.apache.logging.log4j.Level;
import buildcraft.api.core.BCLog;
import buildcraft.api.core.JavaTools;
/**
* A battery object is a wrapper around a battery field in an object. This
* 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, MjReconfigurator.IConfigurableBatteryObject {
protected Field energyStored;
protected Object obj;
protected MjBattery batteryData;
/**
* {@inheritDoc}
*/
@Override
public double getEnergyRequested() {
if (!batteryData.mode().canReceive) {
return 0;
}
try {
return JavaTools.bounds(batteryData.maxCapacity() - energyStored.getDouble(obj),
batteryData.minimumConsumption(), batteryData.maxReceivedPerCycle());
} catch (IllegalAccessException e) {
BCLog.logger.log(Level.WARN, "can't get energy requested", e);
}
return 0;
}
/**
* {@inheritDoc}
*/
@Override
public double addEnergy(double mj) {
return addEnergy(mj, false);
}
/**
* {@inheritDoc}
*/
@Override
public double addEnergy(double mj, boolean ignoreCycleLimit) {
try {
double contained = energyStored.getDouble(obj);
double maxAccepted = batteryData.maxCapacity() - contained + batteryData.minimumConsumption();
if (!ignoreCycleLimit && maxAccepted > batteryData.maxReceivedPerCycle()) {
maxAccepted = batteryData.maxReceivedPerCycle();
}
double used = Math.min(maxAccepted, mj);
if (used > 0) {
energyStored.setDouble(obj, Math.min(contained + used, batteryData.maxCapacity()));
return used;
}
} catch (IllegalAccessException e) {
BCLog.logger.log(Level.WARN, "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.WARN, "can't extract energy", e);
}
return 0;
}
/**
* {@inheritDoc}
*/
@Override
public double getEnergyStored() {
try {
return energyStored.getDouble(obj);
} catch (IllegalAccessException e) {
BCLog.logger.log(Level.WARN, "can't get return energy stored", e);
return 0;
}
}
/**
* {@inheritDoc}
*/
@Override
public void setEnergyStored(double mj) {
try {
energyStored.setDouble(obj, mj);
} catch (IllegalAccessException e) {
BCLog.logger.log(Level.WARN, "can't set energy stored", e);
throw new RuntimeException(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public double maxCapacity() {
return batteryData.maxCapacity();
}
/**
* {@inheritDoc}
*/
@Override
public double minimumConsumption() {
return batteryData.minimumConsumption();
}
/**
* {@inheritDoc}
*/
@Override
public double maxReceivedPerCycle() {
return batteryData.maxReceivedPerCycle();
}
@Override
public String kind() {
return batteryData.kind();
}
@Override
public void init(Object object, Field storedField, MjBattery battery) {
this.obj = object;
this.energyStored = storedField;
this.batteryData = battery;
}
@Override
public double maxSendedPerCycle() {
return batteryData.maxSendedPerCycle();
}
@Override
public IOMode mode() {
return batteryData.mode();
}
@Override
public boolean canSend() {
return batteryData.mode().canSend;
}
@Override
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;
}
}

View file

@ -1,27 +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.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();
}

View file

@ -1,77 +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.api.mj;
import java.lang.reflect.Field;
public interface IBatteryObject {
/**
* @return Current energy requirement for keeping machine state
*/
double getEnergyRequested();
/**
* Add energy to this battery
*
* @param mj Energy amount
* @return Used energy
*/
double addEnergy(double mj);
/**
* Add energy to this battery
*
* @param mj Energy amount
* @param ignoreCycleLimit Force add all energy even if "maxReceivedPerCycle" limit is reached
* @return Used energy
*/
double addEnergy(double mj, boolean ignoreCycleLimit);
/**
* @return Current stored energy amount in this battery
*/
double getEnergyStored();
/**
* Set current stored energy amount.
* Doesn't use it for your machines! Decrease your battery field directly.
*
* @param mj New energy amount
*/
void setEnergyStored(double mj);
/**
* @return Maximal energy amount for this battery.
*/
double maxCapacity();
/**
* @return Minimal energy amount for keep your machine in active state
*/
double minimumConsumption();
/**
* @return Maximal energy received per one tick
*/
double maxReceivedPerCycle();
/**
* @return kind of this energy battery
*/
String kind();
/**
* Basic initialization method
*
* @param object Basic object which hold a battery field
* @param storedField Field for energy storing
* @param battery Battery data
*/
void init(Object object, Field storedField, MjBattery battery);
}

View file

@ -1,13 +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.api.mj;
public interface IBatteryProvider {
IBatteryObject getMjBattery(String kind);
}

View file

@ -1,30 +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.api.mj;
public enum IOMode {
Both(true, true, false),
BothActive(true, true, true),
Receive(true, false, false),
ReceiveActive(true, false, true),
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;
}
}

View file

@ -1,15 +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.api.mj;
import net.minecraftforge.common.util.ForgeDirection;
public interface ISidedBatteryProvider {
IBatteryObject getMjBattery(String kind, ForgeDirection direction);
}

View file

@ -1,440 +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.api.mj;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
import org.apache.logging.log4j.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.
* BuildCraft implements a default power model on top of this, the "kinesis"
* power model. Third party mods may provide they own version of Minecraft
* Joules batteries and provide different models.
*/
public final class MjAPI {
public static final String DEFAULT_POWER_FRAMEWORK = "buildcraft.kinesis";
private static Map<BatteryHolder, BatteryField> mjBatteryFields = new HashMap<BatteryHolder, BatteryField>();
private static Map<String, Class<? extends IBatteryObject>> mjBatteryKinds = new HashMap<String, Class<? extends IBatteryObject>>();
private static final BatteryField invalidBatteryField = new BatteryField();
private static final MjReconfigurator reconfigurator = new MjReconfigurator();
private static final Map<Object, BatteryCache> mjBatteryCache = new WeakHashMap<Object, BatteryCache>();
/**
* Deactivate constructor
*/
private MjAPI() {
}
/**
* @see #getMjBattery(Object, String, ForgeDirection)
*/
public static IBatteryObject getMjBattery(Object o) {
return getMjBattery(o, null, null);
}
/**
* @see #getMjBattery(Object, String, ForgeDirection)
*/
public static IBatteryObject getMjBattery(Object o, String kind) {
return getMjBattery(o, kind, null);
}
/**
* @see #getMjBattery(Object, String, ForgeDirection)
*/
public static IBatteryObject getMjBattery(Object o, ForgeDirection side) {
return getMjBattery(o, null, side);
}
/**
* Returns the battery related to the object given in parameter.
*/
public static IBatteryObject getMjBattery(Object o, String kindRaw, ForgeDirection sideRaw) {
if (o == null) {
return null;
}
String kind = kindRaw == null ? DEFAULT_POWER_FRAMEWORK : kindRaw;
ForgeDirection side = sideRaw == null ? ForgeDirection.UNKNOWN : sideRaw;
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);
}
} 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 && side != ForgeDirection.UNKNOWN) {
receiver = ((IPowerReceptor) o).getPowerReceiver(ForgeDirection.UNKNOWN);
}
if (receiver != null) {
battery = receiver.getMjBattery();
}
}
cache.put(kind, side, battery);
return battery;
}
/**
* Create new battery instance.
* This method ignore all providers/caches and only create battery for given kind/side.
*
* @param o Object which contains {@link MjBattery}
* @param kind Kind of power
* @param side Side of block
* @return New {@link IBatteryObject} implementation registered for given kind of power
*/
public static IBatteryObject createBattery(Object o, String kind, ForgeDirection side) {
if (o == null) {
return null;
}
BatteryField f = getMjBatteryField(o.getClass(), kind, side);
if (f == null && side != ForgeDirection.UNKNOWN) {
f = getMjBatteryField(o.getClass(), kind, ForgeDirection.UNKNOWN);
}
if (f == null) {
return null;
} else if (!mjBatteryKinds.containsKey(kind)) {
return null;
} else if (f.kind == BatteryKind.Value) {
try {
IBatteryObject obj = mjBatteryKinds.get(kind).newInstance();
obj.init(o, f.field, f.battery);
return obj;
} catch (InstantiationException e) {
BCLog.logger.log(Level.WARN, "can't instantiate class for energy kind \"" + kind + "\"");
return null;
} catch (IllegalAccessException e) {
BCLog.logger.log(Level.WARN, "can't instantiate class for energy kind \"" + kind + "\"");
return null;
}
} else {
try {
return createBattery(f.field.get(o), kind, side);
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
}
}
}
/**
* @return All non-sided batteries for passed object
*/
public static IBatteryObject[] getAllMjBatteries(Object o) {
return getAllMjBatteries(o, ForgeDirection.UNKNOWN);
}
/**
* @param direction Side of block
* @return All sided batteries for passed object
*/
public static IBatteryObject[] getAllMjBatteries(Object o, ForgeDirection direction) {
IBatteryObject[] result = new IBatteryObject[mjBatteryFields.size()];
int id = 0;
for (String kind : mjBatteryKinds.keySet()) {
result[id] = getMjBattery(o, kind, direction);
if (result[id] != null) {
id++;
}
}
return Arrays.copyOfRange(result, 0, id);
}
/**
* Register new battery kind implementation.
* Allowing to have a custom power types alongside default "kinesis" kind
* @param kind Kind name
* @param clazz Battery implementation class
*/
public static void registerMJBatteryKind(String kind, Class<? extends IBatteryObject> clazz) {
if (!mjBatteryKinds.containsKey(kind)) {
mjBatteryKinds.put(kind, clazz);
} else {
BCLog.logger.log(Level.WARN,
"energy kind \"" + kind + "\" already registered with " + clazz.getCanonicalName());
}
}
/**
* @see IOMode#canReceive
*/
public static boolean canReceive(IBatteryObject battery) {
return battery != null && (!(battery instanceof IBatteryIOObject) || ((IBatteryIOObject) battery).canReceive());
}
/**
* @see IOMode#canSend
*/
public static boolean canSend(IBatteryObject battery) {
return battery != null && battery instanceof IBatteryIOObject && ((IBatteryIOObject) battery).canSend();
}
/**
* @see IOMode#active
*/
public static boolean isActive(IBatteryObject battery) {
return battery != null && battery instanceof IBatteryIOObject && ((IBatteryIOObject) battery).isActive();
}
/**
* @see MjBattery#cacheable()
*/
public static boolean isCacheable(IBatteryObject battery) {
return battery != null && battery instanceof IBatteryIOObject && ((IBatteryIOObject) battery).isCacheable();
}
/**
* @see MjBattery#maxReceivedPerCycle()
* @see MjBattery#maxSendedPerCycle()
* @return Actual IO limit for passed mode (only send/receive supported)
*/
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;
}
/**
* Obtain battery parameters reconfigurator.
* Usage:<br />
* <code>
* MjAPI.reconfigure().maxCapacity(battery, 15000);
* </code>
* @return Reconfigurator instance
*/
public static MjReconfigurator reconfigure() {
return reconfigurator;
}
/**
* Transfer mj energy amount from battery "fromBattery" to "toBattery"
* @param fromBattery Source battery
* @param toBattery Target battery
* @param mj Amount of energy
* @return Transferred amount
*/
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;
}
/**
* Transfer maximal energy amount from battery "fromBattery" to "toBattery"
* @param fromBattery Source battery
* @param toBattery Target battery
* @return Transferred amount
*/
public static double transferEnergy(IBatteryObject fromBattery, IBatteryObject toBattery) {
return transferEnergy(fromBattery, toBattery, Math.min(
getIOLimit(fromBattery, IOMode.Send),
getIOLimit(toBattery, IOMode.Receive)));
}
/**
* Helper method which you should invoke in every game tick for supporting Active IO modes
* @param tile Tile which contains active battery
*/
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);
}
}
}
/**
* Reset all caches for passed tile
*/
public static void resetBatteriesCache(TileEntity tile) {
mjBatteryCache.remove(tile);
}
/**
* Remove cached instance of passed battery
*/
public static void resetBatteriesCache(IBatteryObject battery) {
for (BatteryCache cache : mjBatteryCache.values()) {
cache.reset(battery);
}
}
private enum BatteryKind {
Value, Container
}
private static final class BatteryCache {
TIntObjectMap<IBatteryObject> cache = new TIntObjectHashMap<IBatteryObject>();
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);
}
void reset(IBatteryObject battery) {
for (int key : cache.keys()) {
if (cache.get(key) == battery) {
cache.remove(key);
}
}
}
private int hash(String kind, ForgeDirection side) {
return kind.hashCode() * 31 + side.hashCode();
}
}
private static final class BatteryHolder {
private String kind;
private ForgeDirection side;
private Class<? extends Object> clazz;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
BatteryHolder that = (BatteryHolder) o;
return kind.equals(that.kind) && clazz.equals(that.clazz) && side.equals(that.side);
}
@Override
public int hashCode() {
int result = kind.hashCode();
result = 31 * result + clazz.hashCode();
result = 31 * result + side.hashCode();
return result;
}
}
private static class BatteryField {
public Field field;
public MjBattery battery;
public BatteryKind kind;
}
private static BatteryField getMjBatteryField(Class<?> c, String kind, ForgeDirection side) {
BatteryHolder holder = new BatteryHolder();
holder.clazz = c;
holder.kind = kind;
holder.side = side;
BatteryField bField = mjBatteryFields.get(holder);
if (bField == null) {
for (Field f : JavaTools.getAllFields(c)) {
MjBattery battery = f.getAnnotation(MjBattery.class);
if (battery != null && kind.equals(battery.kind())) {
if (!contains(battery.sides(), side) && !contains(battery.sides(), ForgeDirection.UNKNOWN)) {
continue;
}
f.setAccessible(true);
bField = new BatteryField();
bField.field = f;
bField.battery = battery;
if (double.class.equals(f.getType())) {
bField.kind = BatteryKind.Value;
} else if (f.getType().isPrimitive()) {
throw new RuntimeException(
"MJ battery needs to be object or double type");
} else {
bField.kind = BatteryKind.Container;
}
mjBatteryFields.put(holder, bField);
return bField;
}
}
mjBatteryFields.put(holder, invalidBatteryField);
}
return bField == invalidBatteryField ? null : bField;
}
private static <T> boolean contains(T[] array, T value) {
for (T t : array) {
if (t == value) {
return true;
}
}
return false;
}
static {
registerMJBatteryKind(DEFAULT_POWER_FRAMEWORK, BatteryObject.class);
}
}

View file

@ -1,60 +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.api.mj;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.power.IPowerReceptor;
import buildcraft.api.power.PowerHandler;
public class MjAPILegacy implements IPowerReceptor {
private final PowerHandler powerHandler;
private final World world;
protected MjAPILegacy(World world, IBatteryObject battery, PowerHandler.Type type) {
if (battery == null) {
throw new NullPointerException();
}
this.world = world;
this.powerHandler = new PowerHandler(this, type, battery);
}
public static MjAPILegacy from(World world, IBatteryObject battery, PowerHandler.Type type) {
if (battery == null) {
return null;
}
return new MjAPILegacy(world, battery, type);
}
public static MjAPILegacy from(World world, Object object, PowerHandler.Type type) {
return from(world, MjAPI.getMjBattery(object), type);
}
public static MjAPILegacy from(TileEntity tileEntity, PowerHandler.Type type) {
return from(tileEntity.getWorldObj(), MjAPI.getMjBattery(tileEntity), type);
}
@Override
public PowerHandler.PowerReceiver getPowerReceiver(ForgeDirection side) {
return powerHandler.getPowerReceiver();
}
@Override
public void doWork(PowerHandler workProvider) {
}
@Override
public World getWorld() {
return world;
}
}

View file

@ -1,86 +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.api.mj;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import net.minecraftforge.common.util.ForgeDirection;
/**
* This annotation is used for tiles that need to interface with BuildCraft
* energy framework, a.k.a MinecraftJoule or MJ. In order to receive power,
* tiles, need to declare a double field, with the annotation MjBattery. MJ
* provider machines able to provide power will then connect to these tiles, and
* feed energy up to max capacity. It's the responsibility of the implementer to
* manually decrease the value of the energy, as he simulates energy
* consumption. On each cycle, per power input, machines can receive up to
* "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.
*
* All the properties defined in this annotation are class wide. If you need to
* change them on a tile by tile basis, you will need to use interfaces, either
* {@link IBatteryProvider} or {@link ISidedBatteryProvider}
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited
public @interface MjBattery {
/**
* @return Max energy capacity of battery
*/
double maxCapacity() default 100.0;
/**
* @return Max energy received per one tick
*/
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
*/
double minimumConsumption() default 0.1;
/**
* @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.
*/
String kind() default MjAPI.DEFAULT_POWER_FRAMEWORK;
/**
* @return Sides on which this battery should works.
*/
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(IBatteryObject)}
*/
boolean cacheable() default true;
}

View file

@ -1,183 +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.api.mj;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.core.BCLog;
/**
* Reconfiguration helper.
* Allow to change battery parameters in runtime.
*/
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<? extends Annotation> annotationType() {
return MjBattery.class;
}
}
/**
* Helper interface which should implement all configurable batteries.
*/
public interface IConfigurableBatteryObject extends IBatteryObject {
MjBattery getMjBattery();
void setMjBattery(MjBattery battery);
}
private ConfigurableMjBattery obtainConfigurableBattery(IBatteryObject battery) {
if (!(battery instanceof IConfigurableBatteryObject)) {
BCLog.logger.warn("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;
MjAPI.resetBatteriesCache(batteryObject);
}
}
/**
* Reconfigure passed battery instance for working with passed sides only
* @param sides Enabled sides
*/
public void sides(IBatteryObject batteryObject, ForgeDirection... sides) {
ConfigurableMjBattery battery = obtainConfigurableBattery(batteryObject);
if (battery != null) {
battery.sides = sides;
MjAPI.resetBatteriesCache(batteryObject);
}
}
/**
* Reconfigure passed battery instance for working with all sides exclude passed
* @param sides Disabled sides
*/
public void sidesExclude(IBatteryObject batteryObject, ForgeDirection... sides) {
List<ForgeDirection> newSides = new ArrayList<ForgeDirection>(Arrays.asList(ForgeDirection.VALID_DIRECTIONS));
for (ForgeDirection side : sides) {
newSides.remove(side);
}
sides(batteryObject, newSides.toArray(new ForgeDirection[newSides.size()]));
}
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;
}
}
}

View file

@ -1,11 +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
*/
@API(apiVersion = "1.1", owner = "BuildCraftAPI|core", provides = "BuildCraftAPI|mj")
package buildcraft.api.mj;
import cpw.mods.fml.common.API;

View file

@ -33,9 +33,9 @@ public interface ILaserTarget {
*/
boolean isInvalidTarget();
double getXCoord();
int getXCoord();
double getYCoord();
int getYCoord();
double getZCoord();
int getZCoord();
}

View file

@ -17,5 +17,6 @@ import net.minecraftforge.common.util.ForgeDirection;
* from a specific side.
*/
public interface IPowerEmitter {
boolean canEmitPowerFrom(ForgeDirection side);
public boolean canEmitPowerFrom(ForgeDirection side);
}

View file

@ -9,7 +9,6 @@
package buildcraft.api.power;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
/**
@ -28,8 +27,9 @@ public interface IPowerReceptor {
* engines to eventually explode.
*
* @param side
* @return
*/
PowerHandler.PowerReceiver getPowerReceiver(ForgeDirection side);
public PowerHandler.PowerReceiver getPowerReceiver(ForgeDirection side);
/**
* Call back from the PowerHandler that is called when the stored power
@ -39,7 +39,7 @@ public interface IPowerReceptor {
*
* @param workProvider
*/
void doWork(PowerHandler workProvider);
public void doWork(PowerHandler workProvider);
World getWorld();
public World getWorld();
}

View file

@ -8,35 +8,27 @@
*/
package buildcraft.api.power;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
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;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
/**
* The PowerHandler is similar to FluidTank in that it holds your power and
* allows standardized interaction between machines.
* <p/>
*
* To receive power to your machine you needs create an instance of PowerHandler
* and implement IPowerReceptor on the TileEntity.
* <p/>
*
* If you plan emit power, you need only implement IPowerEmitter. You do not
* need a PowerHandler. Engines have a PowerHandler because they can also
* receive power from other Engines.
* <p/>
*
* See TileRefinery for a simple example of a power using machine.
*
* @see IPowerReceptor
* @see IPowerEmitter
*/
public final class PowerHandler implements IBatteryProvider {
public final class PowerHandler {
public static enum Type {
@ -65,7 +57,7 @@ public final class PowerHandler implements IBatteryProvider {
/**
* Extend this class to create custom Perdition algorithms (its not final).
* <p/>
*
* NOTE: It is not possible to create a Zero perdition algorithm.
*/
public static class PerditionCalculator {
@ -84,6 +76,9 @@ public final class PowerHandler implements IBatteryProvider {
* @param powerLoss power loss per tick
*/
public PerditionCalculator(double powerLoss) {
if (powerLoss < MIN_POWERLOSS) {
powerLoss = MIN_POWERLOSS;
}
this.powerLoss = powerLoss;
}
@ -93,22 +88,21 @@ public final class PowerHandler implements IBatteryProvider {
* every tick. It is triggered by any manipulation of the stored energy.
*
* @param powerHandler the PowerHandler requesting the perdition update
* @param current the current stored energy
* @param ticksPassed ticks since the last time this function was called
* @param current the current stored energy
* @param ticksPassed ticks since the last time this function was called
* @return
*/
public double applyPerdition(PowerHandler powerHandler, double current, long ticksPassed) {
double newPower = current - powerLoss * ticksPassed;
if (newPower < 0) {
newPower = 0;
current -= powerLoss * ticksPassed;
if (current < 0) {
current = 0;
}
return newPower;
return current;
}
/**
* Taxes a flat rate on all incoming power.
* <p/>
*
* Defaults to 0% tax rate.
*
* @return percent of input to tax
@ -117,50 +111,33 @@ public final class PowerHandler implements IBatteryProvider {
return 0;
}
}
public static final PerditionCalculator DEFAULT_PERDITION = new PerditionCalculator();
public static final double ROLLING_AVERAGE_WEIGHT = 100.0;
public static final double ROLLING_AVERAGE_NUMERATOR = ROLLING_AVERAGE_WEIGHT - 1;
public static final double ROLLING_AVERAGE_DENOMINATOR = 1.0 / ROLLING_AVERAGE_WEIGHT;
public static final double ROLLING_AVERAGE_DENOMINATOR = 1.0 / ROLLING_AVERAGE_WEIGHT;
private double minEnergyReceived;
private double maxEnergyReceived;
private double maxEnergyStored;
private double activationEnergy;
private double energyStored = 0;
private final SafeTimeTracker doWorkTracker = new SafeTimeTracker();
private final SafeTimeTracker sourcesTracker = new SafeTimeTracker();
private final SafeTimeTracker perditionTracker = new SafeTimeTracker();
public final int[] powerSources = new int[6];
public final IPowerReceptor receptor;
private double activationEnergy;
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;
private IBatteryObject battery;
// Tracking
private double averageLostPower = 0;
private double averageReceivedPower = 0;
private double averageUsedPower = 0;
public PowerHandler(IPowerReceptor receptor, Type type) {
this(receptor, type, null);
}
public PowerHandler(IPowerReceptor receptor, Type type, Object battery) {
this.receptor = receptor;
this.type = type;
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.createBattery(battery, MjAPI.DEFAULT_POWER_FRAMEWORK, ForgeDirection.UNKNOWN);
created = true;
} else {
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);
}
}
public PowerReceiver getPowerReceiver() {
@ -168,15 +145,15 @@ public final class PowerHandler implements IBatteryProvider {
}
public double getMinEnergyReceived() {
return battery.minimumConsumption();
return minEnergyReceived;
}
public double getMaxEnergyReceived() {
return battery.getEnergyRequested();
return maxEnergyReceived;
}
public double getMaxEnergyStored() {
return battery.maxCapacity();
return maxEnergyStored;
}
public double getActivationEnergy() {
@ -184,54 +161,40 @@ public final class PowerHandler implements IBatteryProvider {
}
public double getEnergyStored() {
return battery.getEnergyStored();
}
@Override
public IBatteryObject getMjBattery(String kind) {
return battery.kind().equals(kind) ? battery : null;
return energyStored;
}
/**
* Setup your PowerHandler's settings.
*
* @param minEnergyReceived
* This is the minimum about of power that will be accepted by
* the PowerHandler. This should generally be greater than the
* activationEnergy if you plan to use the doWork() callback.
* Anything greater than 1 will prevent Redstone Engines from
* powering this Provider.
* @param maxEnergyReceived
* The maximum amount of power accepted by the PowerHandler. This
* should generally be less than 500. Too low and larger engines
* will overheat while trying to power the machine. Too high, and
* the engines will never warm up. Greater values also place
* greater strain on the power net.
* @param activationEnergy
* If the stored energy is greater than this value, the doWork()
* callback is called (once per tick).
* @param maxStoredEnergy
* The maximum amount of power this PowerHandler can store.
* Values tend to range between 100 and 5000. With 1000 and 1500
* being common.
* @param minEnergyReceived This is the minimum about of power that will be
* accepted by the PowerHandler. This should generally be greater than the
* activationEnergy if you plan to use the doWork() callback. Anything
* greater than 1 will prevent Redstone Engines from powering this Provider.
* @param maxEnergyReceived The maximum amount of power accepted by the
* PowerHandler. This should generally be less than 500. Too low and larger
* engines will overheat while trying to power the machine. Too high, and
* the engines will never warm up. Greater values also place greater strain
* on the power net.
* @param activationEnergy If the stored energy is greater than this value,
* the doWork() callback is called (once per tick).
* @param maxStoredEnergy The maximum amount of power this PowerHandler can
* store. Values tend to range between 100 and 5000. With 1000 and 1500
* being common.
*/
public void configure(double minEnergyReceived, double maxEnergyReceived, double activationEnergy,
double maxStoredEnergy) {
double localMaxEnergyReceived = maxEnergyReceived;
if (minEnergyReceived > localMaxEnergyReceived) {
localMaxEnergyReceived = minEnergyReceived;
public void configure(double minEnergyReceived, double maxEnergyReceived, double activationEnergy, double maxStoredEnergy) {
if (minEnergyReceived > maxEnergyReceived) {
maxEnergyReceived = minEnergyReceived;
}
this.minEnergyReceived = minEnergyReceived;
this.maxEnergyReceived = maxEnergyReceived;
this.maxEnergyStored = maxStoredEnergy;
this.activationEnergy = activationEnergy;
MjAPI.reconfigure().maxCapacity(battery, maxStoredEnergy);
MjAPI.reconfigure().maxReceivedPerCycle(battery, localMaxEnergyReceived);
MjAPI.reconfigure().minimumConsumption(battery, minEnergyReceived);
}
/**
* Allows you define perdition in terms of loss/ticks.
* <p/>
*
* This function is mostly for legacy implementations. See
* PerditionCalculator for more complex perdition formulas.
*
@ -250,32 +213,28 @@ public final class PowerHandler implements IBatteryProvider {
/**
* Allows you to define a new PerditionCalculator class to handler perdition
* calculations.
* <p/>
*
* For example if you want exponentially increasing loss based on amount
* stored.
*
* @param perdition
*/
public void setPerdition(PerditionCalculator perdition) {
if (perdition == null) {
this.perdition = DEFAULT_PERDITION;
} else {
this.perdition = perdition;
}
if (perdition == null)
perdition = DEFAULT_PERDITION;
this.perdition = perdition;
}
public PerditionCalculator getPerdition() {
if (perdition == null) {
if (perdition == null)
return DEFAULT_PERDITION;
} else {
return perdition;
}
return perdition;
}
/**
* Ticks the power handler. You should call this if you can, but its not
* required.
* <p/>
*
* If you don't call it, the possibility exists for some weirdness with the
* perdition algorithm and work callback as its possible they will not be
* called on every tick they otherwise would be. You should be able to
@ -288,28 +247,29 @@ public final class PowerHandler implements IBatteryProvider {
}
private void applyPerdition() {
double energyStored = getEnergyStored();
if (perditionTracker.markTimeIfDelay(receptor.getWorld()) && energyStored > 0) {
if (perditionTracker.markTimeIfDelay(receptor.getWorld(), 1) && energyStored > 0) {
double prev = energyStored;
double newEnergy = getPerdition().applyPerdition(this, energyStored, perditionTracker.durationOfLastDelay());
if (newEnergy != energyStored) {
battery.setEnergyStored(energyStored = newEnergy);
}
if (newEnergy == 0 || newEnergy < energyStored)
energyStored = newEnergy;
else
energyStored = DEFAULT_PERDITION.applyPerdition(this, energyStored, perditionTracker.durationOfLastDelay());
validateEnergy();
averageLostPower = (averageLostPower * ROLLING_AVERAGE_NUMERATOR + (getEnergyStored() - energyStored)) * ROLLING_AVERAGE_DENOMINATOR;
averageLostPower = (averageLostPower * ROLLING_AVERAGE_NUMERATOR + (prev - energyStored)) * ROLLING_AVERAGE_DENOMINATOR;
}
}
private void applyWork() {
if (getEnergyStored() >= activationEnergy) {
if (doWorkTracker.markTimeIfDelay(receptor.getWorld())) {
if (energyStored >= activationEnergy) {
if (doWorkTracker.markTimeIfDelay(receptor.getWorld(), 1)) {
receptor.doWork(this);
}
}
}
private void updateSources(ForgeDirection source) {
if (sourcesTracker.markTimeIfDelay(receptor.getWorld())) {
if (sourcesTracker.markTimeIfDelay(receptor.getWorld(), 1)) {
for (int i = 0; i < 6; ++i) {
powerSources[i] -= sourcesTracker.durationOfLastDelay();
if (powerSources[i] < 0) {
@ -318,9 +278,8 @@ public final class PowerHandler implements IBatteryProvider {
}
}
if (source != null) {
if (source != null)
powerSources[source.ordinal()] = 10;
}
}
/**
@ -337,7 +296,6 @@ public final class PowerHandler implements IBatteryProvider {
double result = 0;
double energyStored = getEnergyStored();
if (energyStored >= min) {
if (energyStored <= max) {
result = energyStored;
@ -351,15 +309,11 @@ public final class PowerHandler implements IBatteryProvider {
}
}
}
if (energyStored != getEnergyStored()) {
battery.setEnergyStored(energyStored);
}
validateEnergy();
if (doUse) {
if (doUse)
averageUsedPower = (averageUsedPower * ROLLING_AVERAGE_NUMERATOR + result) * ROLLING_AVERAGE_DENOMINATOR;
}
return result;
}
@ -370,7 +324,7 @@ public final class PowerHandler implements IBatteryProvider {
public void readFromNBT(NBTTagCompound data, String tag) {
NBTTagCompound nbt = data.getCompoundTag(tag);
battery.setEnergyStored(nbt.getDouble("energyStored"));
energyStored = nbt.getDouble("energyStored");
}
public void writeToNBT(NBTTagCompound data) {
@ -379,7 +333,7 @@ public final class PowerHandler implements IBatteryProvider {
public void writeToNBT(NBTTagCompound data, String tag) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setDouble("energyStored", battery.getEnergyStored());
nbt.setDouble("energyStored", energyStored);
data.setTag(tag, nbt);
}
@ -389,15 +343,15 @@ public final class PowerHandler implements IBatteryProvider {
}
public double getMinEnergyReceived() {
return PowerHandler.this.getMinEnergyReceived();
return minEnergyReceived;
}
public double getMaxEnergyReceived() {
return PowerHandler.this.getMaxEnergyReceived();
return maxEnergyReceived;
}
public double getMaxEnergyStored() {
return PowerHandler.this.getMaxEnergyStored();
return maxEnergyStored;
}
public double getActivationEnergy() {
@ -405,7 +359,7 @@ public final class PowerHandler implements IBatteryProvider {
}
public double getEnergyStored() {
return PowerHandler.this.getEnergyStored();
return energyStored;
}
public double getAveragePowerReceived() {
@ -430,15 +384,17 @@ public final class PowerHandler implements IBatteryProvider {
/**
* The amount of power that this PowerHandler currently needs.
*
* @return
*/
public double powerRequest() {
update();
return battery.getEnergyRequested();
return Math.min(maxEnergyReceived, maxEnergyStored - energyStored);
}
/**
* Add power to the PowerReceiver from an external source.
* <p/>
*
* IPowerEmitters are responsible for calling this themselves.
*
* @param quantity
@ -448,10 +404,10 @@ public final class PowerHandler implements IBatteryProvider {
public double receiveEnergy(Type source, final double quantity, ForgeDirection from) {
double used = quantity;
if (source == Type.ENGINE) {
if (used < getMinEnergyReceived()) {
if (used < minEnergyReceived) {
return 0;
} else if (used > getMaxEnergyReceived()) {
used = getMaxEnergyReceived();
} else if (used > maxEnergyReceived) {
used = maxEnergyReceived;
}
}
@ -464,30 +420,37 @@ public final class PowerHandler implements IBatteryProvider {
applyWork();
if (source == Type.ENGINE && type.eatsEngineExcess()) {
used = Math.min(quantity, getMaxEnergyReceived());
used = Math.min(quantity, maxEnergyReceived);
}
averageReceivedPower = (averageReceivedPower * ROLLING_AVERAGE_NUMERATOR + used) * ROLLING_AVERAGE_DENOMINATOR;
return used;
}
public IBatteryObject getMjBattery() {
return battery;
}
}
/**
*
* @return the amount the power changed by
*/
public double addEnergy(double quantity) {
final double used = battery.addEnergy(quantity);
energyStored += quantity;
if (energyStored > maxEnergyStored) {
quantity -= energyStored - maxEnergyStored;
energyStored = maxEnergyStored;
} else if (energyStored < 0) {
quantity -= energyStored;
energyStored = 0;
}
applyPerdition();
return used;
return quantity;
}
public void setEnergy(double quantity) {
battery.setEnergyStored(quantity);
this.energyStored = quantity;
validateEnergy();
}
@ -496,21 +459,11 @@ public final class PowerHandler implements IBatteryProvider {
}
private void validateEnergy() {
double energyStored = getEnergyStored();
double maxEnergyStored = getMaxEnergyStored();
if (energyStored < 0) {
energyStored = 0;
}
if (energyStored > maxEnergyStored) {
energyStored = maxEnergyStored;
}
if (energyStored != battery.getEnergyStored()) {
battery.setEnergyStored(energyStored);
}
}
private static class AnonymousBattery {
@MjBattery
public double mjStored;
}
}

View file

@ -1,11 +1,3 @@
/**
* 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
*/
@API(apiVersion = "1.1", owner = "BuildCraftAPI|core", provides = "BuildCraftAPI|power")
@API(apiVersion="1.1",owner="BuildCraftAPI|core",provides="BuildCraftAPI|power")
package buildcraft.api.power;
import cpw.mods.fml.common.API;
import cpw.mods.fml.common.API;

View file

@ -61,7 +61,6 @@ import buildcraft.core.science.TechnoSimpleItem;
import buildcraft.core.science.TechnoStatement;
import buildcraft.core.science.Tier;
import buildcraft.energy.BlockBuildcraftFluid;
import buildcraft.energy.BlockEnergyConverter;
import buildcraft.energy.BlockEnergyEmitter;
import buildcraft.energy.BlockEnergyReceiver;
import buildcraft.energy.BlockEngine;
@ -69,10 +68,8 @@ import buildcraft.energy.BucketHandler;
import buildcraft.energy.EnergyProxy;
import buildcraft.energy.GuiHandler;
import buildcraft.energy.ItemBucketBuildcraft;
import buildcraft.energy.ItemEnergyConverter;
import buildcraft.energy.ItemEngine;
import buildcraft.energy.SchematicEngine;
import buildcraft.energy.TileEnergyConverter;
import buildcraft.energy.TileEnergyEmitter;
import buildcraft.energy.TileEnergyReceiver;
import buildcraft.energy.TileEngine;
@ -189,13 +186,6 @@ public class BuildCraftEnergy extends BuildCraftMod {
engineBlock = new BlockEngine();
CoreProxy.proxy.registerBlock(engineBlock, ItemEngine.class);
if (BuildCraftCore.mainConfiguration.get(Configuration.CATEGORY_GENERAL, "energyConverter", true,
"Set true for enable energy converter").getBoolean(true)) {
blockEnergyConverter = new BlockEnergyConverter();
CoreProxy.proxy.registerBlock(blockEnergyConverter, ItemEnergyConverter.class);
CoreProxy.proxy.registerTileEntity(TileEnergyConverter.class, "EnergyConverter");
}
// Oil and fuel
buildcraftFluidOil = new Fluid("oil").setDensity(800).setViscosity(1500);
FluidRegistry.registerFluid(buildcraftFluidOil);

View file

@ -1,83 +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.core.inventory;
import java.lang.reflect.Field;
import buildcraft.api.mj.IBatteryObject;
import buildcraft.api.mj.MjBattery;
/**
* Creates a deep copy of an existing IInventory.
*
* Useful for performing inventory manipulations and then examining the results
* without affecting the original inventory.
*/
public class BatteryCopy implements IBatteryObject {
private IBatteryObject orignal;
private double contents;
public BatteryCopy(IBatteryObject orignal) {
this.orignal = orignal;
contents = orignal.getEnergyStored();
}
@Override
public double getEnergyRequested() {
return 0;
}
@Override
public double addEnergy(double mj) {
return 0;
}
@Override
public double addEnergy(double mj, boolean ignoreCycleLimit) {
return 0;
}
@Override
public double getEnergyStored() {
return contents;
}
@Override
public void setEnergyStored(double mj) {
contents = mj;
}
@Override
public double maxCapacity() {
return orignal.maxCapacity();
}
@Override
public double minimumConsumption() {
return orignal.minimumConsumption();
}
@Override
public double maxReceivedPerCycle() {
return orignal.maxReceivedPerCycle();
}
@Override
public String kind() {
return orignal.kind();
}
@Override
public void init(Object object, Field storedField, MjBattery battery) {
}
}

View file

@ -22,8 +22,6 @@ import buildcraft.BuildCraftCore;
import buildcraft.api.gates.IOverrideDefaultTriggers;
import buildcraft.api.gates.ITrigger;
import buildcraft.api.gates.ITriggerProvider;
import buildcraft.api.mj.IBatteryObject;
import buildcraft.api.mj.MjAPI;
import buildcraft.api.transport.IPipeTile;
import buildcraft.core.IMachine;

View file

@ -1,65 +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.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
import net.minecraft.world.World;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.core.BlockBuildCraft;
import buildcraft.core.IItemPipe;
public class BlockEnergyConverter extends BlockBuildCraft {
@SideOnly(Side.CLIENT)
private IIcon blockTexture;
public BlockEnergyConverter() {
super(Material.ground);
setBlockName("energyConverter");
}
@Override
public boolean onBlockActivated(World world, int i, int j, int k, EntityPlayer player, int side, float par7, float par8, float par9) {
TileEntity tile = world.getTileEntity(i, j, k);
// Do not open guis when having a pipe in hand
if (player.getCurrentEquippedItem() != null &&
player.getCurrentEquippedItem().getItem() instanceof IItemPipe) {
return false;
}
return tile instanceof TileEnergyConverter
&& ((TileEnergyConverter) tile).onBlockActivated(player, ForgeDirection.getOrientation(side));
}
@Override
public TileEntity createNewTileEntity(World world, int metadata) {
return new TileEnergyConverter();
}
@Override
@SideOnly(Side.CLIENT)
public void registerBlockIcons(IIconRegister par1IconRegister) {
blockTexture = par1IconRegister.registerIcon("buildcraft:blockEnergyConverter");
}
@Override
@SideOnly(Side.CLIENT)
public IIcon getIcon(int i, int j) {
return blockTexture;
}
}

View file

@ -1,31 +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 java.util.List;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
public class ItemEnergyConverter extends ItemBlock {
public ItemEnergyConverter(Block block) {
super(block);
}
@Override
public void addInformation(ItemStack itemStack, EntityPlayer player, List list, boolean adv) {
super.addInformation(itemStack, player, list, adv);
list.add(TileEnergyConverter.getLocalizedModeName(itemStack));
list.add("");
// This is a bit too big in the tooltip at this stage.
// list.addAll(Arrays.asList(StringUtils.localize("tile.energyConverter.tooltip").split("\\|")));
}
}

View file

@ -1,168 +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.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChatComponentText;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.core.NetworkData;
import buildcraft.api.mj.IBatteryObject;
import buildcraft.api.mj.MjAPI;
import buildcraft.api.mj.MjBattery;
import buildcraft.api.power.IPowerEmitter;
import buildcraft.api.power.IPowerReceptor;
import buildcraft.api.power.PowerHandler;
import buildcraft.api.tools.IToolWrench;
import buildcraft.core.TileBuffer;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.utils.StringUtils;
public class TileEnergyConverter extends TileBuildCraft implements IPowerReceptor, IPowerEmitter {
private static enum Mode {
FromOldToNew("from_old_to_new"), FromNewToOld("from_new_to_old");
private final String localizeName;
Mode(String localizeName) {
this.localizeName = localizeName;
}
public Mode next() {
if (this == FromOldToNew) {
return FromNewToOld;
}
return FromOldToNew;
}
}
@MjBattery(maxCapacity = 1000, maxReceivedPerCycle = 64, minimumConsumption = 1)
@NetworkData
private double mjStored = 0;
@NetworkData
private Mode mode = Mode.FromOldToNew;
private TileBuffer[] tileCache;
private PowerHandler powerHandler, zeroPowerHandler;
public TileEnergyConverter() {
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);
}
public static String getLocalizedModeName(ItemStack stack) {
int mode = 0;
if (stack != null && stack.getTagCompound() != null) {
mode = stack.getTagCompound().getInteger("converterMode");
if (mode >= Mode.values().length || mode < 0) {
mode = 0;
}
}
return StringUtils.localize("chat.pipe.power.energyConverter." + Mode.values()[mode].localizeName);
}
public boolean onBlockActivated(EntityPlayer player, ForgeDirection side) {
if (!getWorld().isRemote) {
Item equipped = player.getCurrentEquippedItem() != null ? player.getCurrentEquippedItem().getItem() : null;
if (equipped instanceof IToolWrench && ((IToolWrench) equipped).canWrench(player, xCoord, yCoord, zCoord)) {
mode = mode.next();
player.addChatMessage(new ChatComponentText(String.format(
StringUtils.localize("chat.pipe.power.energyConverter"),
StringUtils.localize("chat.pipe.power.energyConverter." + mode.localizeName))));
sendNetworkUpdate();
((IToolWrench) equipped).wrenchUsed(player, xCoord, yCoord, zCoord);
return true;
}
}
return !player.isSneaking();
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
nbt.setDouble("mjStored", mjStored);
nbt.setInteger("converterMode", mode.ordinal());
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
mjStored = nbt.getDouble("mjStored");
mode = Mode.values()[nbt.getInteger("converterMode")];
}
public TileBuffer getTileBuffer(ForgeDirection side) {
if (tileCache == null) {
tileCache = TileBuffer.makeBuffer(worldObj, xCoord, yCoord, zCoord, false);
}
return tileCache[side.ordinal()];
}
@Override
public void updateEntity() {
super.updateEntity();
if (mode == Mode.FromOldToNew) {
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
TileEntity tile = getTileBuffer(side).getTile();
if (tile instanceof TileEnergyConverter) {
continue;
}
IBatteryObject object = MjAPI.getMjBattery(tile, MjAPI.DEFAULT_POWER_FRAMEWORK, side.getOpposite());
if (object != null && mjStored > 0) {
double wantToUse = Math.min(mjStored, object.getEnergyRequested());
object.addEnergy(wantToUse);
mjStored -= wantToUse;
}
}
} else if (mode == Mode.FromNewToOld) {
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
TileEntity tile = getTileBuffer(side).getTile();
if (tile instanceof TileEnergyConverter) {
continue;
}
if (tile instanceof IPowerReceptor && mjStored > 0) {
IPowerReceptor receptor = (IPowerReceptor) tile;
PowerHandler.PowerReceiver powerReceiver = receptor.getPowerReceiver(side.getOpposite());
if (powerReceiver == null) {
continue;
}
double wantToUse = Math.min(mjStored, powerReceiver.getMaxEnergyReceived());
if (wantToUse > powerReceiver.getMinEnergyReceived()) {
powerReceiver.receiveEnergy(PowerHandler.Type.MACHINE, wantToUse, side);
mjStored -= wantToUse;
}
}
}
}
}
@Override
public PowerHandler.PowerReceiver getPowerReceiver(ForgeDirection side) {
return (mode == Mode.FromOldToNew ? powerHandler : zeroPowerHandler).getPowerReceiver();
}
@Override
public void doWork(PowerHandler workProvider) {
}
@Override
public boolean canEmitPowerFrom(ForgeDirection side) {
return mode == Mode.FromOldToNew;
}
}

View file

@ -10,22 +10,17 @@ package buildcraft.energy;
import java.util.LinkedList;
import cofh.api.energy.IEnergyHandler;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ICrafting;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.util.ForgeDirection;
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;
import buildcraft.api.power.PowerHandler;
@ -37,11 +32,11 @@ 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 ISidedBatteryProvider, IPowerReceptor, IPowerEmitter, IOverrideDefaultTriggers, IPipeConnection {
public abstract class TileEngine extends TileBuildCraft implements IPowerReceptor, IPowerEmitter, IOverrideDefaultTriggers, IPipeConnection, IEnergyHandler {
protected boolean constantPower = false;
// Index corresponds to metadata
public static final ResourceLocation[] BASE_TEXTURES = new ResourceLocation[]{
new ResourceLocation(DefaultProps.TEXTURE_PATH_BLOCKS + "/base_wood.png"),
@ -79,8 +74,10 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
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;
@ -90,9 +87,6 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
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;
@ -101,32 +95,14 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
private boolean isPumping = false; // Used for SMP synch
public TileEngine() {
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;
powerHandler = new PowerHandler(this, Type.ENGINE);
powerHandler.configurePowerPerdition(1, 100);
}
@Override
public void initialize() {
if (!worldObj.isRemote) {
powerHandler.configure(minEnergyReceived(), maxEnergyReceived(), 1, getMaxEnergy());
checkRedstonePower();
}
}
@ -155,7 +131,7 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
}
public double getEnergyLevel() {
return mjStoredBattery.getEnergyStored() / mjStoredBattery.maxCapacity() + .01d;
return energy / getMaxEnergy();
}
protected EnergyStage computeEnergyStage() {
@ -228,7 +204,6 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
@Override
public void updateEntity() {
super.updateEntity();
MjAPI.updateEntity(this);
if (worldObj.isRemote) {
if (progressPart != 0) {
@ -253,9 +228,6 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
}
}
currentOutputAverage.tick();
burn();
updateHeatLevel();
getEnergyStage();
engineUpdate();
@ -267,29 +239,107 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
if (progress > 0.5 && progressPart == 1) {
progressPart = 2;
if(!constantPower)
sendPower();
} else if (progress >= 1) {
progress = 0;
progressPart = 0;
}
} else if (isRedstonePowered && isActive()) {
if (isPoweredTile(tile, orientation)) {
progressPart = 1;
/*progressPart = 1;
setPumping(true);
if (getPowerToExtract() > 0) {
progressPart = 1;
setPumping(true);
} else {
setPumping(false);
}*/
} else {
setPumping(false);
}
} else {
progressPart = 0;
setPumping(false);
}
// Uncomment for constant power
if(constantPower) {
if (isRedstonePowered && isActive()) {
sendPower();
} else currentOutput = 0;
}
burn();
}
private double getPowerToExtract() {
TileEntity tile = getTileBuffer(orientation).getTile();
if(tile instanceof IEnergyHandler) {
IEnergyHandler handler = ((IEnergyHandler)tile);
int minEnergy = 0;
int maxEnergy = handler.receiveEnergy(
orientation.getOpposite(),
(int)Math.round(this.energy * 10), true);
return extractEnergy((double)minEnergy / 10.0, (double)maxEnergy / 10.0, false);
} else if (tile instanceof IPowerReceptor) {
PowerReceiver receptor = ((IPowerReceptor) tile)
.getPowerReceiver(orientation.getOpposite());
return extractEnergy(receptor.getMinEnergyReceived(),
receptor.getMaxEnergyReceived(), false);
} else {
return 0;
}
}
protected void sendPower() {
TileEntity tile = getTileBuffer(orientation).getTile();
if (isPoweredTile(tile, orientation)) {
double extracted = getPowerToExtract();
if(extracted > 0) setPumping(true);
else setPumping(false);
if (tile instanceof IEnergyHandler) {
IEnergyHandler handler = ((IEnergyHandler) tile);
if (Math.round(extracted * 10) > 0) {
int neededRF = handler.receiveEnergy(
orientation.getOpposite(),
(int)Math.round(extracted * 10), false);
extractEnergy(0.0, (double)neededRF / 10.0, 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) {
mjStoredBattery.extractEnergy(1);
if (energy >= 1) {
energy -= 1;
} else if (energy < 1) {
energy = 0;
}
}
}
@ -327,6 +377,11 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
TileEntity tile = getTileBuffer(o).getTile();
if ((!pipesOnly || tile instanceof IPipeTile) && isPoweredTile(tile, o)) {
if((tile instanceof IPipeTile) && (((IPipeTile)tile).getPipeType() != PipeType.POWER))
constantPower = false;
else if(tile instanceof IEnergyHandler) constantPower = true;
else constantPower = false;
orientation = o;
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, worldObj.getBlock(xCoord, yCoord, zCoord));
@ -366,8 +421,10 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
orientation = ForgeDirection.getOrientation(data.getInteger("orientation"));
progress = data.getFloat("progress");
mjStoredBattery.setEnergyStored(data.getDouble("energy"));
energy = data.getDouble("energy");
heat = data.getFloat("heat");
if(data.hasKey("constantPower"))
constantPower = data.getBoolean("constantPower");
}
@Override
@ -376,21 +433,22 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
data.setInteger("orientation", orientation.ordinal());
data.setFloat("progress", progress);
data.setDouble("energy", mjStoredBattery.getEnergyStored());
data.setDouble("energy", energy);
data.setFloat("heat", heat);
data.setBoolean("constantPower", constantPower);
}
public void getGUINetworkData(int id, int value) {
switch (id) {
case 0:
int iEnergy = (int) Math.round(mjStoredBattery.getEnergyStored() * 10);
int iEnergy = (int) Math.round(energy * 10);
iEnergy = (iEnergy & 0xffff0000) | (value & 0xffff);
mjStoredBattery.setEnergyStored(iEnergy / 10);
energy = iEnergy / 10;
break;
case 1:
iEnergy = (int) Math.round(mjStoredBattery.getEnergyStored() * 10);
iEnergy = (int) Math.round(energy * 10);
iEnergy = (iEnergy & 0xffff) | ((value & 0xffff) << 16);
mjStoredBattery.setEnergyStored(iEnergy / 10);
energy = iEnergy / 10;
break;
case 2:
currentOutput = value / 10F;
@ -402,9 +460,9 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
}
public void sendGUINetworkData(ContainerEngine containerEngine, ICrafting iCrafting) {
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, 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, 3, Math.round(heat * 100));
}
@ -418,34 +476,92 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
@Override
public void doWork(PowerHandler workProvider) {
if (worldObj.isRemote) {
return;
}
addEnergy(powerHandler.useEnergy(1, maxEnergyReceived(), true) * 0.95F);
}
public void addEnergy(double 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);
}
energy += addition;
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) {
return MjAPI.getMjBattery(tile, MjAPI.DEFAULT_POWER_FRAMEWORK, side.getOpposite()) != null;
if (tile == null) {
return false;
} else if (tile instanceof IPowerReceptor) {
return ((IPowerReceptor) tile).getPowerReceiver(side.getOpposite()) != null;
} else if (tile instanceof IEnergyHandler){
return ((IEnergyHandler) tile).canConnectEnergy(side.getOpposite());
} else {
return false;
}
}
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 mjStoredBattery.getEnergyStored();
return energy;
}
public abstract double getCurrentOutput();
@Override
public LinkedList<ITrigger> getTriggers() {
LinkedList<ITrigger> triggers = new LinkedList<ITrigger>();
@ -477,4 +593,45 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
public void checkRedstonePower() {
isRedstonePowered = worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
}
// RF support
@Override
public int receiveEnergy(ForgeDirection from, int maxReceive,
boolean simulate) {
return 0;
}
@Override
public int extractEnergy(ForgeDirection from, int maxExtract,
boolean simulate) {
return 0;
/*if(!(from == orientation)) return 0;
int energyRF = (int)Math.round(10 * energy);
int energyExtracted = Math.min(maxExtract, energyRF);
if(!simulate) {
if(energyExtracted == energyRF) energy = 0;
else energy -= (double)energyExtracted / 10.0;
}
return energyExtracted;*/
}
@Override
public int getEnergyStored(ForgeDirection from) {
if(!(from == orientation)) return 0;
return (int)Math.round(10 * energy);
}
@Override
public int getMaxEnergyStored(ForgeDirection from) {
return getEnergyStored(from);
}
@Override
public boolean canConnectEnergy(ForgeDirection from) {
return from == orientation;
}
}

View file

@ -17,17 +17,11 @@ 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;
@ -59,8 +53,7 @@ public class TileEngineCreative extends TileEngine {
if (equipped instanceof IToolWrench && ((IToolWrench) equipped).canWrench(player, xCoord, yCoord, zCoord)) {
powerMode = powerMode.getNext();
reconfigure();
mjStored = 0;
energy = 0;
player.addChatMessage(new ChatComponentText(String.format(StringUtils.localize("chat.pipe.power.iron.mode"), powerMode.maxPower)));
@ -79,11 +72,6 @@ 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
@ -101,8 +89,9 @@ public class TileEngineCreative extends TileEngine {
@Override
public void engineUpdate() {
super.engineUpdate();
if (isRedstonePowered) {
mjStored = Math.min(mjStored + powerMode.maxPower, mjStoredBattery.maxCapacity());
addEnergy(getCurrentOutput());
}
}
@ -110,10 +99,29 @@ public class TileEngineCreative extends TileEngine {
public boolean isBurning() {
return isRedstonePowered;
}
@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 / 10.0;
}
@Override
public float explosionRange() {
return 0;
}
}

View file

@ -26,14 +26,11 @@ 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;
@ -53,16 +50,12 @@ public class TileEngineIron extends TileEngineWithInventory implements IFluidHan
public Tank tankCoolant = new Tank("tankCoolant", MAX_LIQUID, this);
private int burnTime = 0;
private TankManager<Tank> tankManager = new TankManager<Tank>();
private TankManager tankManager = new TankManager();
private Fuel currentFuel = null;
private int penaltyCooling = 0;
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);
@ -180,6 +173,7 @@ public class TileEngineIron extends TileEngineWithInventory implements IFluidHan
return;
}
}
if(!this.constantPower) currentOutput = currentFuel.powerPerCycle;
addEnergy(currentFuel.powerPerCycle);
heat += currentFuel.powerPerCycle * HEAT_PER_MJ * getBiomeTempScalar();
}
@ -334,7 +328,7 @@ public class TileEngineIron extends TileEngineWithInventory implements IFluidHan
@Override
public boolean isActive() {
return currentFuel != null && penaltyCooling <= 0;
return penaltyCooling <= 0;
}
/* ITANKCONTAINER */
@ -364,9 +358,6 @@ public class TileEngineIron extends TileEngineWithInventory implements IFluidHan
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
if (resource == null) {
return 0;
}
// Handle coolant
if (IronEngineCoolant.getCoolant(resource) != null) {
@ -411,6 +402,29 @@ 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<ITrigger> getTriggers() {
LinkedList<ITrigger> triggers = super.getTriggers();

View file

@ -0,0 +1,82 @@
/**
* 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.
* <p/>
* 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 double getCurrentOutput() {
return 1;
}
@Override
public double maxEnergyExtracted() {
return 1;
}
}

View file

@ -21,10 +21,7 @@ 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;
@ -42,19 +39,10 @@ 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];
@ -88,11 +76,9 @@ public class TileEngineStone extends TileEngineWithInventory {
if (burnTime > 0) {
burnTime--;
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;
double output = getCurrentOutput();
if(!constantPower) currentOutput = output; // Comment out for constant power
addEnergy(output);
}
if (burnTime == 0 && isRedstonePowered) {
@ -151,6 +137,28 @@ 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<ITrigger> getTriggers() {
LinkedList<ITrigger> triggers = super.getTriggers();

View file

@ -8,19 +8,16 @@
*/
package buildcraft.energy;
import net.minecraft.tileentity.TileEntity;
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.MjBattery;
import buildcraft.api.power.PowerHandler;
import buildcraft.api.transport.IPipeTile.PipeType;
import buildcraft.transport.TileGenericPipe;
public class TileEngineWood extends TileEngine {
@MjBattery(mode = IOMode.SendActive, maxCapacity = 100, maxSendedPerCycle = 1, minimumConsumption = 0)
@NetworkData
private double mjStored;
public static final float OUTPUT = 0.1F;
@Override
public ResourceLocation getBaseTexture() {
@ -37,6 +34,16 @@ 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();
@ -73,8 +80,10 @@ public class TileEngineWood extends TileEngine {
public void engineUpdate() {
super.engineUpdate();
if (isRedstonePowered && worldObj.getTotalWorldTime() % 16 == 0) {
addEnergy(1);
if (isRedstonePowered) {
if (worldObj.getTotalWorldTime() % 16 == 0) {
addEnergy(1);
}
}
}
@ -87,4 +96,34 @@ public class TileEngineWood extends TileEngine {
public boolean isBurning() {
return isRedstonePowered;
}
@Override
public double getMaxEnergy() {
return 100;
}
@Override
public double getCurrentOutput() {
return OUTPUT;
}
@Override
public double maxEnergyExtracted() {
return 1 + PowerHandler.PerditionCalculator.MIN_POWERLOSS;
}
// TODO: HACK
@Override
public boolean canConnectEnergy(ForgeDirection from) {
return false;
}
@Override
protected void sendPower() {
TileEntity tile = getTileBuffer(orientation).getTile();
if(tile instanceof TileGenericPipe && ((TileGenericPipe)tile).getPipeType() != PipeType.POWER)
super.sendPower();
else // pretend we're sending out our powers
this.energy = 0.0;
}
}

View file

@ -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.getCurrentOutputAverage()), x + 22, y + 32, textColour);
fontRendererObj.drawString(String.format("%.1f MJ/t", engine.getCurrentOutput()), 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.getCurrentOutputAverage());
return String.format("%.1f MJ/t", engine.getCurrentOutput());
}
}

View file

@ -21,8 +21,6 @@ import buildcraft.BuildCraftCore;
import buildcraft.BuildCraftTransport;
import buildcraft.api.core.SafeTimeTracker;
import buildcraft.api.gates.ITrigger;
import buildcraft.api.mj.IBatteryObject;
import buildcraft.api.mj.MjAPI;
import buildcraft.api.power.IPowerEmitter;
import buildcraft.api.power.IPowerReceptor;
import buildcraft.api.power.PowerHandler.PowerReceiver;
@ -112,10 +110,6 @@ public class PipeTransportPower extends PipeTransport {
}
}
if (MjAPI.canReceive(MjAPI.getMjBattery(tile, MjAPI.DEFAULT_POWER_FRAMEWORK, side.getOpposite()))) {
return true;
}
return false;
}
@ -208,23 +202,14 @@ public class PipeTransportPower extends PipeTransport {
powerConsumed);
tilePowered = true;
} else {
IBatteryObject battery = MjAPI.getMjBattery(tiles[out], MjAPI.DEFAULT_POWER_FRAMEWORK,
ForgeDirection.VALID_DIRECTIONS[out].getOpposite());
PowerReceiver prov = getReceiverOnSide(ForgeDirection.VALID_DIRECTIONS[out]);
if (battery != null) {
// Transmit power to the simplified power framework
powerConsumed = battery.addEnergy(powerConsumed);
if (prov != null) {
// Transmit power to the legacy power framework
powerConsumed = prov.receiveEnergy(Type.PIPE, powerConsumed,
ForgeDirection.VALID_DIRECTIONS[out].getOpposite());
tilePowered = true;
} else {
PowerReceiver prov = getReceiverOnSide(ForgeDirection.VALID_DIRECTIONS[out]);
if (prov != null) {
// Transmit power to the legacy power framework
powerConsumed = prov.receiveEnergy(Type.PIPE, powerConsumed,
ForgeDirection.VALID_DIRECTIONS[out].getOpposite());
tilePowered = true;
}
}
}
@ -285,14 +270,6 @@ public class PipeTransportPower extends PipeTransport {
requestEnergy(dir, request);
}
}
if (tile != null) {
IBatteryObject battery = MjAPI.getMjBattery(tile, MjAPI.DEFAULT_POWER_FRAMEWORK, dir.getOpposite());
if (battery != null) {
requestEnergy(dir, battery.getEnergyRequested());
}
}
}
}

View file

@ -44,7 +44,6 @@ import buildcraft.api.core.Position;
import buildcraft.api.gates.IGateExpansion;
import buildcraft.api.gates.IOverrideDefaultTriggers;
import buildcraft.api.gates.ITrigger;
import buildcraft.api.mj.MjBattery;
import buildcraft.api.power.IPowerReceptor;
import buildcraft.api.power.PowerHandler;
import buildcraft.api.power.PowerHandler.PowerReceiver;
@ -77,7 +76,6 @@ public class TileGenericPipe extends TileEntity implements IPowerReceptor, IFlui
public final CoreState coreState = new CoreState();
public boolean[] pipeConnectionsBuffer = new boolean[6];
@MjBattery
public Pipe pipe;
public int redstoneInput;
public int[] redstoneInputSide = new int[ForgeDirection.VALID_DIRECTIONS.length];