Fixed IO parts getting stuck with bad waveforms

This commit is contained in:
malte0811 2018-06-24 18:48:28 +02:00
parent 880d350720
commit 33cc33170e
9 changed files with 76 additions and 42 deletions

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip

View File

@ -75,7 +75,7 @@ public class TileEntityMechMB extends TileEntityIWMultiblock implements ITickabl
private static final double SYNC_THRESHOLD = .95;
private static final Map<BlockPos, TileEntityMechMB> CLIENT_MASTER_BY_POS = new MapMaker().weakValues().makeMap();
public MechMBPart[] mechanical = null;
public int[] offsets = null;
int[] offsets = null;
private int[][] electricalStartEnd = null;
@ -157,7 +157,7 @@ public class TileEntityMechMB extends TileEntityIWMultiblock implements ITickabl
if (!localWf.isEnergyWaveform()) {
continue;
}
double availableLocal = electricalComp.getAvailableEEnergy();
double availableLocal = electricalComp.getAvailableEEnergy(energyState);
available[i - section[0]] = availableLocal;
availableWaveforms.add(localWf);
if (availableLocal > 0) {
@ -259,27 +259,27 @@ public class TileEntityMechMB extends TileEntityIWMultiblock implements ITickabl
totalAvailable += available[i];
}
}
if (totalAvailable==0)
return 0;
double[] ins = new double[section[1]-section[0]];
double[] extracted = new double[section[1]-section[0]];
for (int i = section[0]; i < section[1]; i++) {
int i0 = i - section[0];
double otherRequests = totalRequested-requested[i0];
double extractFactor = Math.min(1, otherRequests / totalAvailable);
double extr = available[i0] * extractFactor;
if (extr==0) {
continue;
}
for (int j = 0;j<section[1]-section[0];j++) {
if (j!=i0) {
ins[j] += extr*(requested[j]/otherRequests);
if (totalAvailable>0) {
for (int i = section[0]; i < section[1]; i++) {
int i0 = i - section[0];
double otherRequests = totalRequested - requested[i0];
double extractFactor = Math.min(1, otherRequests / totalAvailable);
double extr = available[i0] * extractFactor;
if (extr == 0) {
continue;
}
for (int j = 0; j < section[1] - section[0]; j++) {
if (j != i0) {
ins[j] += extr * (requested[j] / otherRequests);
}
}
extracted[i0] = extr;
if (!simulate) {
IMBPartElectric electric = (IMBPartElectric) mechanical[i];
electric.extractEEnergy(extr, energyState);
}
}
extracted[i0] = extr;
if (!simulate) {
IMBPartElectric electric = (IMBPartElectric) mechanical[i];
electric.extractEEnergy(extr);
}
}
if (!simulate) {

View File

@ -464,8 +464,6 @@ public class ClientProxy extends CommonProxy {
@Override
public void stopAllSoundsExcept(BlockPos pos, Set<?> excluded) {
IndustrialWires.logger.info("Stopping all except {} at {} (playing {})",
excluded, pos, playingSounds.get(pos));
if (playingSounds.containsKey(pos)) {
SoundHandler manager = Minecraft.getMinecraft().getSoundHandler();
List<ISound> sounds = playingSounds.get(pos);

View File

@ -18,8 +18,8 @@ package malte0811.industrialWires.mech_mb;
public interface IMBPartElectric {
Waveform getProduced(MechEnergy state);
// All four in Joules
double getAvailableEEnergy();
void extractEEnergy(double energy);
double getAvailableEEnergy(MechEnergy energy);
void extractEEnergy(double eEnergy, MechEnergy mEnergy);
double requestEEnergy(Waveform waveform, MechEnergy energy);
void insertEEnergy(double given, Waveform waveform, MechEnergy energy);
}

View File

@ -27,6 +27,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import java.util.List;
@ -41,6 +42,33 @@ public class MechPartCommutator extends MechPartEnergyIO {
return wf.getCommutated(e.getSpeed(), has4Phases());
}
@Override
protected double getTransformationLimit(MechEnergy me) {
double s = me.getSpeed();
if (s<5) {
return 0;
} else if (s<10) {
return ramp(5, 10, s);
} else {
return 1;
}
}
@SuppressWarnings("SameParameterValue")
private double ramp(double min, double max, double pos) {
double diff = max-min;
//Formulas come from Hermite interpolation
if (max>min) {
return MathHelper.clamp((pos-min)*(pos-min)*(1/(diff*diff)-2/(diff*diff*diff)*(pos-max)), 0, 1);
} else {
diff *= -1;
double tmp = max;
max = min;
min = tmp;
return MathHelper.clamp(1+(pos-min)*(pos-min)*(-1/(diff*diff)+2/(diff*diff*diff)*(pos-max)), 0, 1);
}
}
@Override
public double getInertia() {
return 50;

View File

@ -70,28 +70,35 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
return wf;
}
@Override
public double getAvailableEEnergy() {
return bufferToMB;
protected double getTransformationLimit(MechEnergy me) {
return 1;
}
@Override
public void extractEEnergy(double energy) {
bufferToMB -= energy;
public double getAvailableEEnergy(MechEnergy energy) {
return bufferToMB* getTransformationLimit(energy);
}
@Override
public void extractEEnergy(double eEnergy, MechEnergy mEnergy) {
if (eEnergy>0) {
bufferToMB -= eEnergy/ getTransformationLimit(mEnergy);
}
}
@Override
public double requestEEnergy(Waveform waveform, MechEnergy energy) {
if (!has4Phases()==waveform.isSinglePhase()) {
return getMaxBuffer() - bufferToWorld;
Waveform transformed = transform(waveform, energy);
if (!has4Phases()==transformed.isSinglePhase()) {
double ret = getMaxBuffer() - bufferToWorld;
return ret* getTransformationLimit(energy);
}
return 0;
}
@Override
public void insertEEnergy(double given, Waveform waveform, MechEnergy mechEnergy) {
waveform = transform(waveform, mechEnergy);
wfToWorld = waveform;
wfToWorld = transform(waveform, mechEnergy);
bufferToWorld += given;
}
@ -154,8 +161,8 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
public void writeToNBT(NBTTagCompound out) {
out.setDouble(BUFFER_IN, bufferToMB);
out.setDouble(BUFFER_OUT, bufferToWorld);
out.setString(BUFFER_IN+WAVEFORM, wfToMB.serializeToString());
out.setString(BUFFER_OUT+WAVEFORM, wfToWorld.serializeToString());
out.setString(BUFFER_IN+WAVEFORM, wfToMB.toString());
out.setString(BUFFER_OUT+WAVEFORM, wfToWorld.toString());
out.setTag(SIDE_CONFIG, sides.toNBT(getEnergyConnections()));
}

View File

@ -55,13 +55,13 @@ public class MechPartSingleCoil extends MechMBPart implements IMBPartElectric {
}
@Override
public double getAvailableEEnergy() {
public double getAvailableEEnergy(MechEnergy energy) {
return bufferToE;
}
@Override
public void extractEEnergy(double energy) {
bufferToE -= energy;
public void extractEEnergy(double eEnergy, MechEnergy mEnergy) {
bufferToE -= eEnergy;
}
@Override
@ -177,7 +177,7 @@ public class MechPartSingleCoil extends MechMBPart implements IMBPartElectric {
world.setBlockState(new BlockPos(i, y, 0), getLightEngineering());
}
}
spawnBrokenParts(8, energy, COIL_TEXTURE);
spawnBrokenParts(has4Phases()?8:4, energy, COIL_TEXTURE);
}
@Override

View File

@ -102,7 +102,8 @@ public class Waveform {
return this;
}
public String serializeToString() {
@Override
public String toString() {
return type+":"+phases+":"+speed;
}

View File

@ -151,7 +151,7 @@ ie.manual.entry.industrialwires.mech_mb=Mechanical multiblocks serve two main pu
ie.manual.entry.industrialwires.mech_mb_parts.name=Mechanical Multiblock Parts
ie.manual.entry.industrialwires.mech_mb_parts.subtext=
ie.manual.entry.industrialwires.mech_mb_parts=The shaft is the simplest part imaginable: It does not do anything. This can be useful for seperating electrical sections of the multiblock. It consists of a single heavy engineering block in the middle of the multiblock.<np><&0>The flywheel is another very simple part: Its only job is to add inertia to increase energy storage. Various materials can be used instead of the lead blocks in the above schematic. The table on the next page shows all available materials, their inertia and their maximum speed.<&1><np><&2>Coils produce synchronous AC power from the multiblocks rotation or convert AC power (both synchronous and asynchronous will work) into multiblock rotation. For a four-phase coil replace the light engineering blocks on the level of the shaft with copper coil blocks. The maximum speed is 100 radians/second for a single-phase coil and 500 radians/second for a four-phase coil, the maximum energy transfer is 200 kW (4096 Flux/tick) for single-phase coil and 8 times as much on the four-phase version.<np><&3>Electrodes are the standard way of transferring energy out of or into a mechanical multiblock. The above plan shows the four-phase version, the single phase version if formed from a single generator block in the place of the shaft. Both AC and DC power can be connected to it. The maximum energy transfer rates match those of the corresponding coils, but is split equally between the connections. The energy connections can be set to input, output and not connected by hitting them with an Engineer's hammer.<np>The speedometer does what one would expect it to do: It measures the speed the multiblock is turning at. It consists of a single redstone engineering block in the place of the shaft. Right-clicking with a Voltmeter will give the exact speed, but its most common use is to automatically limit the speed of a multiblock. One side (the one marked with a line) will output a redstone signal proportional to the speed, the other one (marked "ln") will output a signal proportional to the logarithm of the speed plus one. To change what speed equates to a full strength signal you can (shift-) right-click the speedometer with an engineer's hammer.<br>Both signals have hysteresis to prevent flickering: For the signal to drop from n to n-1 the exact signal strength has to drop below n-0.1. To rise from n to n+1 the exact strength has to be above n+1.1.
ie.manual.entry.industrialwires.mech_mb_parts.commutator=<np><&4>The commutator converts synchronous AC to DC and vice versa. The above plan shows the four-phase version, the single-phase version consists of a single kinetic generator from IC2 in the place of the shaft. It transfers half as much power as the corresponding electrodes can.
ie.manual.entry.industrialwires.mech_mb_parts.commutator=<np><&4>The commutator converts synchronous AC to DC and vice versa. This will only work if the multiblock is turning at more than 5 radians/second, with 100%% efficiency only above 10 radians/second. The above plan shows the four-phase version, the single-phase version consists of a single kinetic generator from IC2 in the place of the shaft. It transfers half as much power as the corresponding electrodes can.
ie.manual.entry.industrialwires.intro.name=Introduction
ie.manual.entry.industrialwires.intro.subtext=