Finished implementation of stripes pipe (#1491 and #1512).

Started experiments migrating pipes to simpler energy framework (#1532)
This commit is contained in:
SpaceToad 2014-03-18 23:53:34 +01:00
parent 4bf1d3cd49
commit 0ea21b9162
6 changed files with 175 additions and 138 deletions

View file

@ -25,6 +25,10 @@ import java.lang.annotation.Target;
* receive up to "maxReceivedPerCyle" units of energy. As an optional behavior, * receive up to "maxReceivedPerCyle" units of energy. As an optional behavior,
* the system can have a minimum amount of energy consumed even if the system * the system can have a minimum amount of energy consumed even if the system
* is at max capacity, modelized by the "minimumConsumption" value. * is at max capacity, modelized by the "minimumConsumption" value.
*
* If the field designated by MjBattery is an object, then BuildCraft will
* consider that this is a case of a nested battery, and will look for the
* field in the designated object.
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD) @Target(ElementType.FIELD)

View file

@ -8,9 +8,14 @@ import buildcraft.api.mj.MjBattery;
public class ReflectMjAPI { public class ReflectMjAPI {
public static class BatteryField { enum BatteryKind {
Value, Container
}
private static class BatteryField {
public Field field; public Field field;
public MjBattery battery; public MjBattery battery;
public BatteryKind kind;
public double getEnergyRequested (Object obj) { public double getEnergyRequested (Object obj) {
try { try {
@ -35,27 +40,98 @@ public class ReflectMjAPI {
} }
} }
public static class BatteryObject {
BatteryField f;
Object o;
public double getEnergyRequested () {
return f.getEnergyRequested(o);
}
public double addEnergy(double watts) {
try {
double e = f.field.getDouble(o);
double max = f.battery.maxCapacity();
double used = 0;
if (e + watts <= max) {
used = watts;
} else {
used = max - e;
}
f.field.setDouble(o, e + used);
return used;
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return 0;
}
public double miniumConsumption() {
return f.battery.miniumConsumption();
}
}
public static BatteryObject getMjBattery (Object o) {
BatteryField f = getMjBattery (o.getClass());
if (f == null) {
return null;
} else if (f.kind == BatteryKind.Value) {
BatteryObject obj = new BatteryObject();
obj.o = o;
obj.f = f;
return obj;
} else {
try {
return getMjBattery(f.field.get(o));
} catch (IllegalArgumentException e) {
e.printStackTrace();
return null;
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
}
}
}
static Map <Class, BatteryField> MjBatteries = new HashMap <Class, BatteryField> (); static Map <Class, BatteryField> MjBatteries = new HashMap <Class, BatteryField> ();
public static BatteryField getMjBattery (Class c) { private static BatteryField getMjBattery (Class c) {
if (!MjBatteries.containsKey(c)) { if (!MjBatteries.containsKey(c)) {
for (Field f : c.getFields()) { for (Field f : c.getFields()) {
MjBattery battery = f.getAnnotation (MjBattery.class); MjBattery battery = f.getAnnotation (MjBattery.class);
if (battery != null) { if (battery != null) {
if (!f.getType().equals(double.class)) { BatteryField bField = new BatteryField();
throw new RuntimeException("MjBattery need to be of type double"); bField.field = f;
} else { bField.battery = battery;
BatteryField bField = new BatteryField();
bField.field = f;
bField.battery = battery;
return MjBatteries.put(c, bField); if (f.getType().equals(double.class)) {
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;
} }
MjBatteries.put(c, bField);
return bField;
} }
} }
return MjBatteries.put(c, null); MjBatteries.put(c, null);
return null;
} else { } else {
return MjBatteries.get(c); return MjBatteries.get(c);
} }

View file

@ -29,7 +29,7 @@ import buildcraft.api.transport.IPipeTile;
import buildcraft.api.transport.IPipeTile.PipeType; import buildcraft.api.transport.IPipeTile.PipeType;
import buildcraft.core.DefaultProps; import buildcraft.core.DefaultProps;
import buildcraft.core.ReflectMjAPI; import buildcraft.core.ReflectMjAPI;
import buildcraft.core.ReflectMjAPI.BatteryField; import buildcraft.core.ReflectMjAPI.BatteryObject;
import buildcraft.core.TileBuffer; import buildcraft.core.TileBuffer;
import buildcraft.core.TileBuildCraft; import buildcraft.core.TileBuildCraft;
import buildcraft.core.network.NetworkData; import buildcraft.core.network.NetworkData;
@ -238,8 +238,8 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto
return extractEnergy(receptor.getMinEnergyReceived(), return extractEnergy(receptor.getMinEnergyReceived(),
receptor.getMaxEnergyReceived(), false); receptor.getMaxEnergyReceived(), false);
} else { } else {
return extractEnergy(0, ReflectMjAPI.getMjBattery(tile.getClass()) return extractEnergy(0, ReflectMjAPI.getMjBattery(tile)
.getEnergyRequested(tile), false); .getEnergyRequested(), false);
} }
} }
@ -260,20 +260,10 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto
extractEnergy(receptor.getMinEnergyReceived(), needed, true); extractEnergy(receptor.getMinEnergyReceived(), needed, true);
} }
} else { } else {
try { BatteryObject battery = ReflectMjAPI.getMjBattery(tile);
BatteryField f = ReflectMjAPI.getMjBattery(tile.getClass());
f.field.set( battery.addEnergy(extractEnergy(0, battery.miniumConsumption(),
tile, true));
f.field.getDouble(tile)
+ extractEnergy(0,
extracted + f.battery.miniumConsumption(),
true) - f.battery.miniumConsumption());
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} }
} }
} }
@ -484,7 +474,7 @@ public abstract class TileEngine extends TileBuildCraft implements IPowerRecepto
return false; return false;
} else if (tile instanceof IPowerReceptor) { } else if (tile instanceof IPowerReceptor) {
return ((IPowerReceptor) tile).getPowerReceiver(side.getOpposite()) != null; return ((IPowerReceptor) tile).getPowerReceiver(side.getOpposite()) != null;
} else if (ReflectMjAPI.getMjBattery(tile.getClass()) != null) { } else if (ReflectMjAPI.getMjBattery(tile) != null) {
return true; return true;
} else { } else {
return false; return false;

View file

@ -26,7 +26,7 @@ import buildcraft.api.power.PowerHandler.Type;
import buildcraft.api.transport.IPipeTile.PipeType; import buildcraft.api.transport.IPipeTile.PipeType;
import buildcraft.core.DefaultProps; import buildcraft.core.DefaultProps;
import buildcraft.core.ReflectMjAPI; import buildcraft.core.ReflectMjAPI;
import buildcraft.core.ReflectMjAPI.BatteryField; import buildcraft.core.ReflectMjAPI.BatteryObject;
import buildcraft.transport.network.PacketPowerUpdate; import buildcraft.transport.network.PacketPowerUpdate;
import buildcraft.transport.pipes.PipePowerCobblestone; import buildcraft.transport.pipes.PipePowerCobblestone;
import buildcraft.transport.pipes.PipePowerDiamond; import buildcraft.transport.pipes.PipePowerDiamond;
@ -115,7 +115,7 @@ public class PipeTransportPower extends PipeTransport {
} }
} }
if (ReflectMjAPI.getMjBattery(tile.getClass()) != null) { if (ReflectMjAPI.getMjBattery(tile) != null) {
return true; return true;
} }
@ -180,7 +180,7 @@ public class PipeTransportPower extends PipeTransport {
if (tiles[j] != null if (tiles[j] != null
&& (tiles[j] instanceof TileGenericPipe && (tiles[j] instanceof TileGenericPipe
|| tiles[j] instanceof IPowerReceptor || ReflectMjAPI || tiles[j] instanceof IPowerReceptor || ReflectMjAPI
.getMjBattery(tiles[j].getClass()) != null)) { .getMjBattery(tiles[j]) != null)) {
totalPowerQuery += powerQuery[j]; totalPowerQuery += powerQuery[j];
} }
} }
@ -206,26 +206,13 @@ public class PipeTransportPower extends PipeTransport {
} else if (tiles[j] != null) { } else if (tiles[j] != null) {
// Look for the simplified power framework // Look for the simplified power framework
BatteryField f = ReflectMjAPI.getMjBattery(tiles [j].getClass()); BatteryObject battery = ReflectMjAPI.getMjBattery(tiles [j]);
try { if (battery != null) {
if (f != null) { watts = (internalPower[i] / totalPowerQuery)
watts = (internalPower[i] / totalPowerQuery) * powerQuery[j]; * powerQuery[j];
double energy = f.field.getDouble (tiles[j]); internalPower[i] -= battery.addEnergy(watts);
if (energy < 100) {
energy += watts;
f.field.setDouble(tiles [j], energy);
internalPower[i] -= watts;
}
}
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
} }
@ -267,10 +254,10 @@ public class PipeTransportPower extends PipeTransport {
} }
if (tile != null) { if (tile != null) {
BatteryField f = ReflectMjAPI.getMjBattery(tile.getClass()); BatteryObject battery = ReflectMjAPI.getMjBattery(tile);
if (f != null) { if (battery != null) {
requestEnergy(dir, f.getEnergyRequested(tile)); requestEnergy(dir, battery.getEnergyRequested());
} }
} }
} }

View file

@ -39,9 +39,7 @@ import buildcraft.api.gates.GateExpansions;
import buildcraft.api.gates.IGateExpansion; import buildcraft.api.gates.IGateExpansion;
import buildcraft.api.gates.IOverrideDefaultTriggers; import buildcraft.api.gates.IOverrideDefaultTriggers;
import buildcraft.api.gates.ITrigger; import buildcraft.api.gates.ITrigger;
import buildcraft.api.power.IPowerReceptor; import buildcraft.api.mj.MjBattery;
import buildcraft.api.power.PowerHandler;
import buildcraft.api.power.PowerHandler.PowerReceiver;
import buildcraft.api.transport.IPipeConnection; import buildcraft.api.transport.IPipeConnection;
import buildcraft.api.transport.IPipeTile; import buildcraft.api.transport.IPipeTile;
import buildcraft.api.transport.PipeWire; import buildcraft.api.transport.PipeWire;
@ -62,7 +60,8 @@ import buildcraft.transport.gates.GateFactory;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly; import cpw.mods.fml.relauncher.SideOnly;
public class TileGenericPipe extends TileEntity implements IPowerReceptor, IFluidHandler, IPipeTile, IOverrideDefaultTriggers, ITileBufferHolder, public class TileGenericPipe extends TileEntity implements IFluidHandler,
IPipeTile, IOverrideDefaultTriggers, ITileBufferHolder,
IDropControlInventory, ISyncedTile, ISolidSideTile, IGuiReturnHandler { IDropControlInventory, ISyncedTile, ISolidSideTile, IGuiReturnHandler {
public class CoreState implements IClientState { public class CoreState implements IClientState {
@ -101,7 +100,10 @@ public class TileGenericPipe extends TileEntity implements IPowerReceptor, IFlui
private TileBuffer[] tileBuffer; private TileBuffer[] tileBuffer;
public boolean[] pipeConnectionsBuffer = new boolean[6]; public boolean[] pipeConnectionsBuffer = new boolean[6];
public SafeTimeTracker networkSyncTracker = new SafeTimeTracker(); public SafeTimeTracker networkSyncTracker = new SafeTimeTracker();
@MjBattery
public Pipe pipe; public Pipe pipe;
private boolean sendClientUpdate = false; private boolean sendClientUpdate = false;
private boolean blockNeighborChange = false; private boolean blockNeighborChange = false;
private boolean refreshRenderState = false; private boolean refreshRenderState = false;
@ -272,12 +274,6 @@ public class TileGenericPipe extends TileEntity implements IPowerReceptor, IFlui
refreshRenderState = false; refreshRenderState = false;
} }
PowerReceiver provider = getPowerReceiver(null);
if (provider != null) {
provider.update();
}
if (sendClientUpdate) { if (sendClientUpdate) {
sendClientUpdate = false; sendClientUpdate = false;
@ -410,22 +406,6 @@ public class TileGenericPipe extends TileEntity implements IPowerReceptor, IFlui
return initialized; return initialized;
} }
@Override
public PowerHandler.PowerReceiver getPowerReceiver(ForgeDirection side) {
if (BlockGenericPipe.isValid(pipe) && pipe instanceof IPowerReceptor) {
return ((IPowerReceptor) pipe).getPowerReceiver(null);
} else {
return null;
}
}
@Override
public void doWork(PowerHandler workProvider) {
if (BlockGenericPipe.isValid(pipe) && pipe instanceof IPowerReceptor) {
((IPowerReceptor) pipe).doWork(workProvider);
}
}
public void scheduleNeighborChange() { public void scheduleNeighborChange() {
blockNeighborChange = true; blockNeighborChange = true;
} }

View file

@ -8,59 +8,82 @@
*/ */
package buildcraft.transport.pipes; package buildcraft.transport.pipes;
import java.util.ArrayList;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.BuildCraftTransport; import buildcraft.BuildCraftTransport;
import buildcraft.api.core.IIconProvider; import buildcraft.api.core.IIconProvider;
import buildcraft.api.core.Position; import buildcraft.api.core.Position;
import buildcraft.api.mj.MjBattery;
import buildcraft.core.proxy.CoreProxy; import buildcraft.core.proxy.CoreProxy;
import buildcraft.transport.BlockGenericPipe;
import buildcraft.transport.ItemPipe;
import buildcraft.transport.Pipe; import buildcraft.transport.Pipe;
import buildcraft.transport.PipeIconProvider; import buildcraft.transport.PipeIconProvider;
import buildcraft.transport.PipeTransportItems; import buildcraft.transport.PipeTransportItems;
import buildcraft.transport.TileGenericPipe; import buildcraft.transport.TileGenericPipe;
import buildcraft.transport.TravelingItem;
import buildcraft.transport.pipes.events.PipeEventItem; import buildcraft.transport.pipes.events.PipeEventItem;
import buildcraft.transport.utils.TransportUtils;
public class PipeItemsStripes extends Pipe { public class PipeItemsStripes extends Pipe <PipeTransportItems> {
@MjBattery (maxCapacity = 1, maxReceivedPerCycle = 1, miniumConsumption = 1)
public double mjStored = 0;
public PipeItemsStripes(Item item) { public PipeItemsStripes(Item item) {
super(new PipeTransportItems(), item); super(new PipeTransportItems(), item);
//((PipeTransportItems) transport).travelHook = this;
} }
/*@Override @Override
public void doWork() { public void updateEntity() {
if (powerProvider.useEnergy(1, 1, true) == 1) { super.updateEntity();
if (container.getWorldObj().isRemote) {
return;
}
if (mjStored > 0) {
ForgeDirection o = getOpenOrientation(); ForgeDirection o = getOpenOrientation();
if (o != ForgeDirection.Unknown) { if (o != ForgeDirection.UNKNOWN) {
Position p = new Position(xCoord, yCoord, zCoord, o); Position p = new Position(container.xCoord, container.yCoord,
container.zCoord, o);
p.moveForwards(1.0); p.moveForwards(1.0);
ArrayList<ItemStack> stacks = BuildCraftBlockUtil ArrayList<ItemStack> stacks = getWorld().getBlock(
.getItemStackFromBlock(worldObj, (int) p.x, (int) p.y, (int) p.x, (int) p.y, (int) p.z)
(int) p.z); .getDrops(
getWorld(),
(int) p.x,
(int) p.y,
(int) p.z,
getWorld().getBlockMetadata((int) p.x,
(int) p.y, (int) p.z), 0);
if (stacks != null) { if (stacks != null) {
for (ItemStack s : stacks) { for (ItemStack s : stacks) {
if (s != null) { if (s != null) {
IPipedItem newItem = new EntityPassiveItem( TravelingItem newItem = TravelingItem.make(
worldObj, xCoord + 0.5, yCoord container.xCoord + 0.5, container.yCoord
+ Utils.getPipeFloorOf(s), + TransportUtils.getPipeFloorOf(s),
zCoord + 0.5, s); container.zCoord + 0.5, s);
this.container.entityEntering(newItem, o.reverse()); transport.injectItem(newItem, o.getOpposite());
} }
} }
} }
worldObj.setBlock((int) p.x, (int) p.y, (int) p.z, 0); getWorld().setBlockToAir((int) p.x, (int) p.y, (int) p.z);
} }
} }
}*/ mjStored = 0;
}
public void eventHandler(PipeEventItem.DropItem event) { public void eventHandler(PipeEventItem.DropItem event) {
Position p = new Position(container.xCoord, container.yCoord, Position p = new Position(container.xCoord, container.yCoord,
@ -68,67 +91,44 @@ public class PipeItemsStripes extends Pipe {
Position from = new Position (p); Position from = new Position (p);
p.moveForwards(1.0); p.moveForwards(1.0);
if (getWorld().getBlock((int) p.x, (int) p.y, (int) p.z) == Blocks.air) { if (convertPipe(transport, event.item)) {
BuildCraftTransport.pipeItemsStripes.onItemUse(new ItemStack(
BuildCraftTransport.pipeItemsStripes), CoreProxy
.proxy.getBuildCraftPlayer(getWorld()), getWorld(), (int) p.x,
(int) p.y, (int) p.z, 1, 0, 0, 0);
} else if (getWorld().getBlock((int) p.x, (int) p.y, (int) p.z) == Blocks.air) {
event.entity.getEntityItem().tryPlaceItemIntoWorld(
CoreProxy.proxy.getBuildCraftPlayer(getWorld()),
getWorld(), (int) p.x, (int) p.y - 1, (int) p.z, 1, 0.0f, 0.0f,
0.0f);
} else {
event.entity.getEntityItem().tryPlaceItemIntoWorld( event.entity.getEntityItem().tryPlaceItemIntoWorld(
CoreProxy.proxy.getBuildCraftPlayer(getWorld()), CoreProxy.proxy.getBuildCraftPlayer(getWorld()),
getWorld(), (int) p.x, (int) p.y, (int) p.z, 1, 0.0f, 0.0f, getWorld(), (int) p.x, (int) p.y, (int) p.z, 1, 0.0f, 0.0f,
0.0f); 0.0f);
} }
/*if (convertPipe(pipe, data)) {
BuildCraftTransport.pipeItemsStipes.onItemUse(new ItemStack(
BuildCraftTransport.pipeItemsStipes), CoreProxy
.getBuildCraftPlayer(worldObj), worldObj, (int) p.x,
(int) p.y - 1, (int) p.z, 1);
} else else {
data.item
.getItemStack()
.getItem()
.tryPlaceIntoWorld(data.item.getItemStack(),
CoreProxy.getBuildCraftPlayer(worldObj), worldObj,
(int) p.x, (int) p.y, (int) p.z, 1, 0.0f, 0.0f,
0.0f);
}*/
} }
/*@Override @SuppressWarnings("unchecked")
public void centerReached(PipeTransportItems pipe, EntityData data) { public boolean convertPipe(PipeTransportItems pipe, TravelingItem item) {
convertPipe(pipe, data); if (item.getItemStack().getItem() instanceof ItemPipe) {
}*/ if (!(item.getItemStack().getItem() == BuildCraftTransport.pipeItemsStripes)) {
Pipe newPipe = BlockGenericPipe.createPipe(item.getItemStack().getItem());
/*@SuppressWarnings("unchecked")
public boolean convertPipe(PipeTransportItems pipe, EntityItem data) {
if (data.getEntityItem().getItem() instanceof ItemPipe) {
if (!(data.getEntityItem().getItem() == BuildCraftTransport.pipeItemsStripes)) {
Pipe newPipe = BlockGenericPipe.createPipe(data.getEntityItem().getItem());
newPipe.setTile(this.container); newPipe.setTile(this.container);
this.container.pipe = newPipe; this.container.pipe = newPipe;
((PipeTransportItems) newPipe.transport).travelingEntities = (TreeMap<Integer, EntityData>) pipe.travelingEntities
.clone();
data.getEntityItem().stackSize--; item.getItemStack().stackSize--;
if (data.getEntityItem().stackSize <= 0) { if (item.getItemStack().stackSize <= 0) {
((PipeTransportItems) newPipe.transport).travelingEntities ((PipeTransportItems) newPipe.transport).items.remove(item);
.remove(data.getEntityId());
} }
pipe.scheduleRemoval(data.item);
return true; return true;
} }
} }
return false; return false;
}*/ }
/*
@Override
public void endReached(PipeTransportItems pipe, EntityData data,
TileEntity tile) {
}*/
@Override @Override
public IIconProvider getIconProvider() { public IIconProvider getIconProvider() {