Replace the ore-specific energy values with one global constant, to make it possible to determine the constant with cheap ores

Fix a crash when interacting with the top/bottom side of a HV capacitor
This commit is contained in:
malte0811 2017-08-14 21:56:44 +02:00
parent c18d94899a
commit 2b2f5ca6c1
5 changed files with 77 additions and 109 deletions

View file

@ -30,7 +30,7 @@ sourceCompatibility = 1.8
targetCompatibility = 1.8
minecraft {
version = "14.21.1.2443"
version = "14.22.0.2453"
runDir = "run"
replace '${version}', project.version

View file

@ -30,7 +30,7 @@ import javax.annotation.Nonnull;
@Mod.EventBusSubscriber
public class IWSaveData extends WorldSavedData {
private final static String MARX_ORES = "marxOres";
private final static String MARX_MOD = "marxOreModifier";
public static IWSaveData INSTANCE = new IWSaveData();
public IWSaveData() {
@ -43,15 +43,17 @@ public class IWSaveData extends WorldSavedData {
@Override
public void readFromNBT(@Nonnull NBTTagCompound nbt) {
NBTTagCompound ores = nbt.getCompoundTag(MARX_ORES);
MarxOreHandler.reset();
MarxOreHandler.load(ores);
if (nbt.hasKey(MARX_MOD)) {
MarxOreHandler.modifier = nbt.getDouble(MARX_MOD);
} else {
MarxOreHandler.resetModifier();
}
}
@Nonnull
@Override
public NBTTagCompound writeToNBT(@Nonnull NBTTagCompound compound) {
compound.setTag(MARX_ORES, MarxOreHandler.save());
compound.setDouble(MARX_MOD, MarxOreHandler.modifier);
return compound;
}
@ -62,8 +64,7 @@ public class IWSaveData extends WorldSavedData {
INSTANCE = (IWSaveData) w.loadData(IWSaveData.class, IndustrialWires.MODID);
if (INSTANCE==null) {
INSTANCE = new IWSaveData();
MarxOreHandler.reset();
MarxOreHandler.load(new NBTTagCompound());
MarxOreHandler.resetModifier();
w.setData(IndustrialWires.MODID, INSTANCE);
INSTANCE.setDirty(true);
}

View file

@ -67,6 +67,9 @@ public class MultiblockMarx implements IMultiblock {
@SuppressWarnings("unchecked")
@Override
public boolean createStructure(World world, BlockPos pos, EnumFacing side, EntityPlayer player) {
if (side.getAxis().isVertical()) {
return false;
}
facing = side.rotateY();
boolean mirrored = false;
Predicate<BlockPos> hvCap = (local) -> {

View file

@ -27,13 +27,11 @@ import blusunrize.immersiveengineering.api.energy.wires.redstone.IRedstoneConnec
import blusunrize.immersiveengineering.api.energy.wires.redstone.RedstoneWireNetwork;
import blusunrize.immersiveengineering.common.IEContent;
import blusunrize.immersiveengineering.common.blocks.BlockTypes_MetalsIE;
import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces;
import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IDirectionalTile;
import blusunrize.immersiveengineering.common.blocks.metal.*;
import blusunrize.immersiveengineering.common.blocks.wooden.TileEntityWallmount;
import blusunrize.immersiveengineering.common.util.Utils;
import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4;
import ic2.api.item.IC2Items;
import malte0811.industrialWires.*;
import malte0811.industrialWires.blocks.IBlockBoundsIW;
import malte0811.industrialWires.blocks.ISyncReceiver;
@ -59,14 +57,19 @@ import net.minecraft.potion.PotionEffect;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.*;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiConsumer;
import static malte0811.industrialWires.util.MiscUtils.getOffset;
@ -82,7 +85,7 @@ public class TileEntityMarx extends TileEntityIWMultiblock implements ITickable,
private double rcTimeConst;
private double timeFactor;
private double timeFactorBottom;
private final static double CAPACITANCE = 0.00_000_5;
private final static double CAPACITANCE = 0.000_001_6;
private final static double MAX_VOLTAGE = 250_000;
private boolean allowSlowDischarge = true;
@ -212,8 +215,8 @@ public class TileEntityMarx extends TileEntityIWMultiblock implements ITickable,
if (capVoltages==null||capVoltages.length!=stageCount) {
capVoltages = new double[stageCount];
}
double oldTopVoltage = capVoltages[stageCount-1];
double oldBottomVoltage = capVoltages[0];
final double oldTopVoltage = capVoltages[stageCount-1];
final double oldBottomVoltage = capVoltages[0];
for (int i = stageCount-1;i>0;i--) {
double oldVoltage = capVoltages[i];
double u0 = capVoltages[i-1];
@ -230,14 +233,13 @@ public class TileEntityMarx extends TileEntityIWMultiblock implements ITickable,
u0 = capVoltages[0];
}
if (allowSlowDischarge || u0 > capVoltages[0]) {
if (u0<0) {
IndustrialWires.logger.info("VOLTAGE: "+u0+", "+voltageControl);
}
double tmp = u0 - (u0 - oldBottomVoltage) * timeFactorBottom;
double energyUsed = .5*(tmp * tmp - oldBottomVoltage * oldBottomVoltage)*CAPACITANCE;
if (energyUsed > 0 && storage.extractEU(energyUsed, false)==energyUsed) {// energyUsed can be negative when discharging the caps
storage.extractEU(energyUsed, true);
capVoltages[0] = tmp;
} else if (energyUsed<=0) {
capVoltages[0] = tmp;
}
if (Math.round(15*oldBottomVoltage/MAX_VOLTAGE)!=Math.round(15*capVoltages[0]/MAX_VOLTAGE)) {
net.updateValues();
@ -316,13 +318,13 @@ public class TileEntityMarx extends TileEntityIWMultiblock implements ITickable,
public void handleEntities(double energyStored) {
Vec3d v0 = getMiddle();
AxisAlignedBB aabb = new AxisAlignedBB(v0, v0);
aabb = aabb.expand(0, stageCount/2-1,0);
aabb = aabb.grow(0, stageCount/2-1,0);
final double sqrtStages = Math.sqrt(stageCount);
aabb = aabb.grow(5*sqrtStages);
List<Entity> fools = world.getEntitiesWithinAABB(Entity.class, aabb);
double energyNormed = getNormedEnergy(energyStored);
double damageDistSqu = energyNormed * sqrtStages;
double tinnitusDistSqu = 5 * energyNormed * sqrtStages;
double damageDistSqu = energyNormed * stageCount;
double tinnitusDistSqu = 5 * energyNormed * stageCount;
damageDistSqu *= damageDistSqu;
tinnitusDistSqu *= tinnitusDistSqu;
if (IWConfig.HVStuff.marxSoundDamage == 2) {

View file

@ -20,111 +20,84 @@ package malte0811.industrialWires.hv;
import blusunrize.immersiveengineering.api.ApiUtils;
import blusunrize.immersiveengineering.api.crafting.IngredientStack;
import blusunrize.immersiveengineering.common.util.Utils;
import malte0811.industrialWires.IndustrialWires;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.oredict.OreDictionary;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class MarxOreHandler {
private static final Map<String, Double> oreEnergies = new HashMap<>();
private static final Map<String, OreInfo> defaultOreData = new HashMap<>();
private static final Map<String, OreInfo> oreData = new HashMap<>();
private static double defaultEnergy = 100_000;
public static double modifier;
private static void init() {
// Vanilla ores
defaultOreData.put("oreIron", new OreInfo(.5, 5, "dustIron", "nuggetIron"));
defaultOreData.put("oreGold", new OreInfo(1, 5, "dustGold", "nuggetGold"));
defaultOreData.put("oreDiamond", new OreInfo(2, 5, "gemDiamond"));
defaultOreData.put("oreEmerald", new OreInfo(3, 5, "gemEmerald"));
defaultOreData.put("oreLapis", new OreInfo(.75, 10, "gemLapis"));
defaultOreData.put("oreCoal", new OreInfo(.75, 6, Items.COAL, 0));
defaultOreData.put("oreRedstone", new OreInfo(1, 10, "dustRedstone"));
defaultOreData.put("oreQuartz", new OreInfo(1, 5, "gemQuartz"));
oreData.put("oreIron", new OreInfo(.5, 4, "dustIron", "nuggetIron"));
oreData.put("oreGold", new OreInfo(1, 4, "dustGold", "nuggetGold"));
oreData.put("oreDiamond", new OreInfo(2, 4, "gemDiamond"));
oreData.put("oreEmerald", new OreInfo(3, 4, "gemEmerald"));
oreData.put("oreLapis", new OreInfo(.75, 10, "gemLapis"));
oreData.put("oreCoal", new OreInfo(.75, 8, Items.COAL, 0));
oreData.put("oreRedstone", new OreInfo(1, 12, "dustRedstone"));
oreData.put("oreQuartz", new OreInfo(1, 6, "gemQuartz"));
// IE ores
String[] ores = {"Copper", "Aluminium"/*TODO um or ium?*/, "Lead", "Silver", "Nickel"};
String[] ores = {"Copper", "Aluminum", "Lead", "Silver", "Nickel", "Tin"};
for (String ore : ores) {
defaultOreData.put("ore" + ore, new OreInfo(.75, 5, "ingot" + ore, "nugget" + ore));
oreData.put("ore" + ore, new OreInfo(.75, 4, "ingot" + ore, "nugget" + ore));
}
// TODO Uranium: IC2 output since IE has no useful ones
oreData.put("oreUranium", new OreInfo(1.25, 4, "crushedUranium", "nuggetUranium"));
}
public static void reset() {
oreEnergies.clear();
}
public static void load(NBTTagCompound nbt) {
if (!defaultOreData.containsKey("oreIron")) {
init();
}
for (String ore : nbt.getKeySet()) {
if (defaultOreData.containsKey(ore)) {
oreEnergies.put(ore, nbt.getDouble(ore));
}
}
for (String ore : OreDictionary.getOreNames()) {
if (oreEnergies.containsKey(ore)) {
continue;
}
double energy = 0;
if (defaultOreData.containsKey(ore)) {
energy = defaultOreData.get(ore).avgEnergy;
}
//TODO auto-add other ores?
if (energy > 0) {
double sigma = defaultEnergy * energy / 20;
double mu = defaultEnergy * energy;
double avg = new Random().nextGaussian();
avg *= sigma;
avg = MathHelper.clamp(avg, -sigma, sigma);
avg += mu;
oreEnergies.put(ore, avg);
}
}
public static void resetModifier() {
modifier = MathHelper.clamp(Utils.RAND.nextGaussian()*.1+1, .9, 1.1);
}
public static ItemStack[] getYield(ItemStack in, double energy) {
if (oreEnergies.isEmpty()) {
IndustrialWires.logger.error("The energy-ore map for Marx generators wasn't loaded correctly. The energy values will be reset.");
load(new NBTTagCompound());
if (oreData.isEmpty()) {
init();
}
if (modifier<.89||modifier>1.11) {
IndustrialWires.logger.error("The energy-modifier for Marx generators wasn't loaded correctly. It will be reset.");
resetModifier();
}
int[] ores = OreDictionary.getOreIDs(in);
for (int id : ores) {
String name = OreDictionary.getOreName(id);
if (oreEnergies.containsKey(name) && energy >= .75 * oreEnergies.get(name)) {
OreInfo info = defaultOreData.get(name);
double idealE = oreEnergies.get(name);
double sigma = idealE / 18;
double dist = getNormalizedNormalDist(energy, sigma, idealE);
double out = dist * info.maxYield;
int yield = (int) Math.floor(out);
out -= yield;
int yieldNuggets = (int) Math.round(out*9);
if (yieldNuggets>=9||(info.outputSmall==null&&yieldNuggets>=5)) {
yield++;
yieldNuggets = 0;
}
if (yield>0&&yieldNuggets>0&&info.outputSmall!=null) {
return new ItemStack[] {
ApiUtils.copyStackWithAmount(info.output.getExampleStack(), yield),
ApiUtils.copyStackWithAmount(info.outputSmall.getExampleStack(), yieldNuggets)
};
} else if (yield>0) {
return new ItemStack[] {
ApiUtils.copyStackWithAmount(info.output.getExampleStack(), yield)
};
} else if (yieldNuggets>0&&info.outputSmall!=null) {
return new ItemStack[] {
ApiUtils.copyStackWithAmount(info.outputSmall.getExampleStack(), yieldNuggets)
};
if (oreData.containsKey(name)) {
OreInfo info = oreData.get(name);
double idealE = modifier * info.avgEnergy * defaultEnergy;
if (energy >= .75 * idealE) {
double sigma = idealE / 9;
double dist = getNormalizedNormalDist(energy, sigma, idealE);
double out = dist * info.maxYield;
int yield = (int) Math.floor(out);
out -= yield;
int yieldNuggets = (int) Math.round(out * 9);
if (yieldNuggets >= 9 || (info.outputSmall == null && yieldNuggets >= 5)) {
yield++;
yieldNuggets = 0;
}
if (yield > 0 && yieldNuggets > 0 && info.outputSmall != null) {
return new ItemStack[]{
ApiUtils.copyStackWithAmount(info.output.getExampleStack(), yield),
ApiUtils.copyStackWithAmount(info.outputSmall.getExampleStack(), yieldNuggets)
};
} else if (yield > 0) {
return new ItemStack[]{
ApiUtils.copyStackWithAmount(info.output.getExampleStack(), yield)
};
} else if (yieldNuggets > 0 && info.outputSmall != null) {
return new ItemStack[]{
ApiUtils.copyStackWithAmount(info.outputSmall.getExampleStack(), yieldNuggets)
};
}
}
}
}
@ -135,17 +108,6 @@ public class MarxOreHandler {
return Math.exp(-(x - mu) * (x - mu) / (2 * sigma * sigma));
}
public static NBTBase save() {
NBTTagCompound ret = new NBTTagCompound();
if (oreEnergies.isEmpty()) {
load(new NBTTagCompound());
}
for (String name:oreEnergies.keySet()) {
ret.setDouble(name, oreEnergies.get(name));
}
return ret;
}
public static class OreInfo {
public final double avgEnergy;
public final double maxYield;