Merge branch 'marmot' into builder

This commit is contained in:
CovertJaguar 2014-01-04 11:26:48 -08:00
commit 8ee5270145
13 changed files with 119 additions and 69 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

View file

@ -21,7 +21,7 @@ import net.minecraftforge.common.ForgeDirection;
* 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.
*
*
* See TileRefinery for a simple example of a power using machine.
*
* @see IPowerReceptor
@ -94,12 +94,10 @@ public final class PowerHandler {
* @return
*/
public double applyPerdition(PowerHandler powerHandler, double current, long ticksPassed) {
// float prev = current;
current -= powerLoss * ticksPassed;
if (current < 0) {
current = 0;
}
// powerHandler.totalLostPower += prev - current;
return current;
}
@ -115,6 +113,9 @@ public final class PowerHandler {
}
}
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;
private double minEnergyReceived;
private double maxEnergyReceived;
private double maxEnergyStored;
@ -128,11 +129,10 @@ public final class PowerHandler {
private PerditionCalculator perdition;
private final PowerReceiver receiver;
private final Type type;
// Debug
// private double totalLostPower = 0;
// private double totalReceivedPower = 0;
// private double totalUsedPower = 0;
// private long startTime = -1;
// Tracking
private double averageLostPower = 0;
private double averageReceivedPower = 0;
private double averageUsedPower = 0;
public PowerHandler(IPowerReceptor receptor, Type type) {
this.receptor = receptor;
@ -242,13 +242,6 @@ public final class PowerHandler {
* design around this though if you are aware of the limitations.
*/
public void update() {
// if (startTime == -1)
// startTime = receptor.getWorld().getTotalWorldTime();
// else {
// long duration = receptor.getWorld().getTotalWorldTime() - startTime;
// System.out.printf("Power Stats: %s - Stored: %.2f Gained: %.2f - %.2f/t Lost: %.2f - %.2f/t Used: %.2f - %.2f/t%n", receptor.getClass().getSimpleName(), energyStored, totalReceivedPower, totalReceivedPower / duration, totalLostPower, totalLostPower / duration, totalUsedPower, totalUsedPower / duration);
// }
applyPerdition();
applyWork();
validateEnergy();
@ -256,12 +249,15 @@ public final class PowerHandler {
private void applyPerdition() {
if (perditionTracker.markTimeIfDelay(receptor.getWorld(), 1) && energyStored > 0) {
double prev = energyStored;
double newEnergy = getPerdition().applyPerdition(this, energyStored, perditionTracker.durationOfLastDelay());
if (newEnergy == 0 || newEnergy < energyStored)
energyStored = newEnergy;
else
energyStored = DEFAULT_PERDITION.applyPerdition(this, energyStored, perditionTracker.durationOfLastDelay());
validateEnergy();
averageLostPower = (averageLostPower * ROLLING_AVERAGE_NUMERATOR + (prev - energyStored)) * ROLLING_AVERAGE_DENOMINATOR;
}
}
@ -317,8 +313,8 @@ public final class PowerHandler {
validateEnergy();
// if (doUse)
// totalUsedPower += result;
if (doUse)
averageUsedPower = (averageUsedPower * ROLLING_AVERAGE_NUMERATOR + result) * ROLLING_AVERAGE_DENOMINATOR;
return result;
}
@ -367,6 +363,18 @@ public final class PowerHandler {
return energyStored;
}
public double getAveragePowerReceived() {
return averageReceivedPower;
}
public double getAveragePowerUsed() {
return averageUsedPower;
}
public double getAveragePowerLost() {
return averageLostPower;
}
public Type getType() {
return type;
}
@ -416,7 +424,7 @@ public final class PowerHandler {
used = Math.min(quantity, maxEnergyReceived);
}
// totalReceivedPower += used;
averageReceivedPower = (averageReceivedPower * ROLLING_AVERAGE_NUMERATOR + used) * ROLLING_AVERAGE_DENOMINATOR;
return used;
}

View file

@ -1,3 +1,3 @@
@API(apiVersion="1.0",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;

View file

@ -8,12 +8,8 @@
package buildcraft.builders.filler.pattern;
import buildcraft.api.core.IBox;
import buildcraft.builders.BuilderProxyClient;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
public class PatternFill extends FillerPattern {

View file

@ -8,7 +8,7 @@ import net.minecraft.util.Icon;
/**
* Don't put new Trigger Icons in here please, put them in the Trigger classes
* like the TriggerQuartzTimer. This class will go away someday.
* like the #TriggerClockTimer. This class will go away someday.
*
* @author CovertJaguar <http://www.railcraft.info/>
*/

View file

@ -23,6 +23,7 @@ import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -42,7 +43,8 @@ public final class Gate {
public ITrigger[] triggers = new ITrigger[8];
public ITriggerParameter[] triggerParameters = new ITriggerParameter[8];
public IAction[] actions = new IAction[8];
public boolean broadcastSignal[] = new boolean[4];
public BitSet broadcastSignal = new BitSet(PipeWire.VALUES.length);
public BitSet prevBroadcastSignal = new BitSet(PipeWire.VALUES.length);
public int redstoneOutput = 0;
// / CONSTRUCTOR
@ -108,8 +110,8 @@ public final class Gate {
}
}
for (int i = 0; i < 4; ++i) {
data.setBoolean("wireState[" + i + "]", broadcastSignal[i]);
for (PipeWire wire : PipeWire.VALUES) {
data.setBoolean("wireState[" + wire.ordinal() + "]", broadcastSignal.get(wire.ordinal()));
}
data.setByte("redstoneOutput", (byte) redstoneOutput);
}
@ -126,8 +128,8 @@ public final class Gate {
}
}
for (int i = 0; i < 4; ++i) {
broadcastSignal[i] = data.getBoolean("wireState[" + i + "]");
for (PipeWire wire : PipeWire.VALUES) {
broadcastSignal.set(wire.ordinal(), data.getBoolean("wireState[" + wire.ordinal() + "]"));
}
redstoneOutput = data.getByte("redstoneOutput");
}
@ -162,11 +164,12 @@ public final class Gate {
}
public boolean isGateActive() {
for (boolean b : broadcastSignal) {
if (b)
for (GateExpansionController expansion : expansions.values()) {
if (expansion.isActive())
return true;
}
return redstoneOutput > 0;
return redstoneOutput > 0 || !broadcastSignal.isEmpty();
}
public int getRedstoneOutput() {
@ -181,10 +184,12 @@ public final class Gate {
public void resolveActions() {
int oldRedstoneOutput = redstoneOutput;
boolean[] oldBroadcastSignal = broadcastSignal;
redstoneOutput = 0;
broadcastSignal = new boolean[4];
BitSet temp = prevBroadcastSignal;
temp.clear();
prevBroadcastSignal = broadcastSignal;
broadcastSignal = temp;
// Tell the gate to prepare for resolving actions. (Disable pulser)
startResolution();
@ -225,7 +230,7 @@ public final class Gate {
} else if (action instanceof ActionRedstoneFaderOutput) {
redstoneOutput = ((ActionRedstoneFaderOutput) action).level;
} else if (action instanceof ActionSignalOutput) {
broadcastSignal[((ActionSignalOutput) action).color.ordinal()] = true;
broadcastSignal.set(((ActionSignalOutput) action).color.ordinal());
} else {
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
TileEntity tile = pipe.container.getTile(side);
@ -246,12 +251,9 @@ public final class Gate {
pipe.updateNeighbors(true);
}
for (int i = 0; i < oldBroadcastSignal.length; ++i) {
if (oldBroadcastSignal[i] != broadcastSignal[i]) {
pipe.container.scheduleRenderUpdate();
pipe.updateSignalState();
break;
}
if (!prevBroadcastSignal.equals(broadcastSignal)) {
pipe.container.scheduleRenderUpdate();
pipe.updateSignalState();
}
}

View file

@ -277,30 +277,30 @@ public abstract class Pipe<T extends PipeTransport> implements IDropControlInven
}
}
private void updateSignalStateForColor(PipeWire color) {
if (!wireSet[color.ordinal()])
private void updateSignalStateForColor(PipeWire wire) {
if (!wireSet[wire.ordinal()])
return;
// STEP 1: compute internal signal strength
if (gate != null && gate.broadcastSignal[color.ordinal()]) {
receiveSignal(255, color);
if (gate != null && gate.broadcastSignal.get(wire.ordinal())) {
receiveSignal(255, wire);
} else {
readNearbyPipesSignal(color);
readNearbyPipesSignal(wire);
}
// STEP 2: transmit signal in nearby blocks
if (signalStrength[color.ordinal()] > 1) {
if (signalStrength[wire.ordinal()] > 1) {
for (ForgeDirection o : ForgeDirection.VALID_DIRECTIONS) {
TileEntity tile = container.getTile(o);
if (tile instanceof TileGenericPipe) {
TileGenericPipe tilePipe = (TileGenericPipe) tile;
if (BlockGenericPipe.isFullyDefined(tilePipe.pipe) && tilePipe.pipe.wireSet[color.ordinal()])
if (isWireConnectedTo(tile, color)) {
tilePipe.pipe.receiveSignal(signalStrength[color.ordinal()] - 1, color);
if (BlockGenericPipe.isFullyDefined(tilePipe.pipe) && tilePipe.pipe.wireSet[wire.ordinal()])
if (isWireConnectedTo(tile, wire)) {
tilePipe.pipe.receiveSignal(signalStrength[wire.ordinal()] - 1, wire);
}
}
}

View file

@ -61,6 +61,7 @@ public class PipeTransportPower extends PipeTransport {
private float[] internalPower = new float[6];
public float[] internalNextPower = new float[6];
public int maxPower = 8;
private double highestPower;
SafeTimeTracker tracker = new SafeTimeTracker();
public PipeTransportPower() {
@ -181,7 +182,7 @@ public class PipeTransportPower extends PipeTransport {
}
}
double highestPower = 0;
highestPower = 0;
for (int i = 0; i < 6; i++) {
displayPower[i] = (prevDisplayPower[i] * (DISPLAY_SMOOTHING - 1.0F) + displayPower[i]) / DISPLAY_SMOOTHING;
if (displayPower[i] > highestPower) {
@ -309,18 +310,6 @@ public class PipeTransportPower extends PipeTransport {
* Power Pipes or a subclass thereof.
*/
public float receiveEnergy(ForgeDirection from, float val) {
// Keep this in reserve for if too many idiots start bypassing the API
// Verify that it is BC calling this method.
// If its someone else take all their power and run!
// Note: This should be safe for PipePowerWood subclasses, aka custom input pipes.
// StackTraceElement[] stackTrace = (new Throwable()).getStackTrace();
// String caller = stackTrace[1].getClassName();
// if (!caller.equals("buildcraft.transport.PipeTransportPower")
// && !caller.equals("buildcraft.transport.pipes.PipePowerWood")) {
// return val;
// }
step();
if (this.container.pipe instanceof IPipeTransportPowerHook) {
float ret = ((IPipeTransportPowerHook) this.container.pipe).receiveEnergy(from, val);
@ -394,4 +383,33 @@ public class PipeTransportPower extends PipeTransport {
clientDisplayPower = packetPower.displayPower;
overload = packetPower.overload ? OVERLOAD_TICKS : 0;
}
/**
* This can be use to provide a rough estimate of how much power is flowing
* through a pipe. Measured in MJ/t.
*
* @return MJ/t
*/
public double getCurrentPowerTransferRate() {
return highestPower;
}
/**
* This can be use to provide a rough estimate of how much power is
* contained in a pipe. Measured in MJ.
*
* Max should be around (throughput * internalPower.length * 2), ie 112 MJ for a Cobblestone Pipe.
*
* @return MJ
*/
public double getCurrentPowerAmount() {
double amount = 0.0;
for (double d : internalPower) {
amount += d;
}
for (double d : internalNextPower) {
amount += d;
}
return amount;
}
}

View file

@ -90,6 +90,7 @@ public class GateFactory {
Gate gate = makeGate(pipe, material, logic);
gate.readFromNBT(nbt);
// Legacy support
if (nbt.hasKey("Pulser")) {
NBTTagCompound pulsarTag = nbt.getCompoundTag("Pulser");
GateExpansionController pulsarCon = GateExpansionPulsar.INSTANCE.makeController(pipe.container);

View file

@ -458,7 +458,13 @@ public class PipeRendererTESR extends TileEntitySpecialRenderer {
bindTexture(TextureMap.locationBlocksTexture);
renderGate(pipe, pipe.pipe.gate.logic.getIconDark(), 0);
Icon iconLogic;
if (pipe.pipe.gate.isGateActive())
iconLogic = pipe.pipe.gate.logic.getIconLit();
else
iconLogic = pipe.pipe.gate.logic.getIconDark();
renderGate(pipe, iconLogic, 0);
Icon materialIcon = pipe.pipe.gate.material.getIconBlock();
if (materialIcon != null)

View file

@ -1,23 +1,32 @@
package buildcraft.transport.triggers;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.util.Icon;
import buildcraft.core.triggers.ActionTriggerIconProvider;
import buildcraft.core.triggers.BCAction;
import buildcraft.core.utils.StringUtils;
public class ActionEnergyPulsar extends BCAction {
private Icon icon;
public ActionEnergyPulsar() {
super("buildcraft:pulsar.constant", "buildcraft.pulser.constant");
}
@Override
public int getIconIndex() {
return ActionTriggerIconProvider.Trigger_Machine_Active;
public Icon getIcon() {
return icon;
}
@Override
public String getDescription() {
return StringUtils.localize("gate.action.pulsar.constant");
}
@Override
public void registerIcons(IconRegister iconRegister) {
icon = iconRegister.registerIcon("buildcraft:triggers/action_pulsar");
}
}

View file

@ -1,22 +1,32 @@
package buildcraft.transport.triggers;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.util.Icon;
import buildcraft.core.triggers.ActionTriggerIconProvider;
import buildcraft.core.triggers.BCAction;
import buildcraft.core.utils.StringUtils;
public class ActionSingleEnergyPulse extends BCAction {
private Icon icon;
public ActionSingleEnergyPulse() {
super("buildcraft:pulsar.single", "buildcraft.pulser.single");
}
@Override
public int getIconIndex() {
return ActionTriggerIconProvider.Trigger_Machine_Active;
public Icon getIcon() {
return icon;
}
@Override
public String getDescription() {
return StringUtils.localize("gate.action.pulsar.single");
}
@Override
public void registerIcons(IconRegister iconRegister) {
icon = iconRegister.registerIcon("buildcraft:triggers/action_single_pulsar");
}
}