Redstone control, other misc Marx generator details

This commit is contained in:
malte0811 2017-06-09 11:37:23 +02:00
parent 206c1170f1
commit d65621a0b5
7 changed files with 129 additions and 22 deletions

View file

@ -31,6 +31,7 @@ import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
@ -45,7 +46,9 @@ import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.fml.common.registry.GameRegistry;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
public abstract class BlockIWBase extends Block {
@ -138,6 +141,15 @@ public abstract class BlockIWBase extends Block {
return super.getBoundingBox(state, source, pos);
}
@Override
public void addCollisionBoxToList(IBlockState state, @Nonnull World worldIn, @Nonnull BlockPos pos, @Nonnull AxisAlignedBB entityBox,
@Nonnull List<AxisAlignedBB> collidingBoxes, @Nullable Entity entityIn, boolean p_185477_7_) {
AxisAlignedBB aabb = getBoundingBox(state, worldIn, pos).offset(pos);
if (entityBox.intersectsWith(aabb)) {
collidingBoxes.add(aabb);
}
}
//mostly copied from IE
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player,

View file

@ -60,6 +60,11 @@ public abstract class TileEntityIWMultiblock extends TileEntityIWBase {
}
return null;
}
@Nonnull
public <T extends TileEntityIWMultiblock> T masterOr(T here, @Nonnull T def) {
T master = master(here);
return master!=null?master:def;
}
public void disassemble()
{
if(formed && !world.isRemote)

View file

@ -253,7 +253,7 @@ public class MultiblockMarx implements IMultiblock {
TileEntity te = world.getTileEntity(p);
if (te instanceof TileEntityMarx) {
TileEntityMarx marx = (TileEntityMarx) te;
marx.stageCount = stages;
marx.setStageCount(stages);
marx.offset = p.subtract(origin);
marx.formed = true;
marx.markDirty();

View file

@ -203,7 +203,7 @@ public class TileEntityJacobsLadder extends TileEntityIEBase implements ITickabl
initControl();
}
dummy = nbt.getInteger("dummy");
energy = DualEnergyStorage.readFromNBT(nbt.getCompoundTag("energy"));
energy.readFromNBT(nbt.getCompoundTag("energy"));
facing = EnumFacing.HORIZONTALS[nbt.getInteger("facing")];
salt = nbt.getDouble("salt");
}

View file

@ -31,11 +31,13 @@ import blusunrize.immersiveengineering.common.blocks.metal.*;
import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4;
import ic2.api.item.IC2Items;
import malte0811.industrialWires.IIC2Connector;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.IBlockBoundsIW;
import malte0811.industrialWires.blocks.ISyncReceiver;
import malte0811.industrialWires.blocks.IWProperties;
import malte0811.industrialWires.blocks.TileEntityIWMultiblock;
import malte0811.industrialWires.client.render.TileRenderMarx;
import malte0811.industrialWires.network.MessageTileSyncIW;
import malte0811.industrialWires.util.DualEnergyStorage;
import malte0811.industrialWires.util.MiscUtils;
import malte0811.industrialWires.wires.IC2Wiretype;
@ -44,6 +46,7 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
@ -69,14 +72,24 @@ public class TileEntityMarx extends TileEntityIWMultiblock implements ITickable,
private static final String TYPE = "type";
private static final String STAGES = "stages";
private static final String HAS_CONN = "hasConn";
private static final String CAP_VOLTAGES = "capVoltages";
private double rcTimeConst;
private double timeFactor;
private double cReciproke = 1_000_000;
private double maxVoltage = 250_000;
public IWProperties.MarxType type = IWProperties.MarxType.NO_MODEL;
public int stageCount = 0;
private int stageCount = 0;
public FiringState state = FiringState.CHARGING;
@SideOnly(Side.CLIENT)
public TileRenderMarx.Discharge dischargeData;
private DualEnergyStorage storage = new DualEnergyStorage(10000, 1000);
// Voltage=100*storedEU
private DualEnergyStorage storage = new DualEnergyStorage(10_000, 8192);
private boolean hasConnection;
private double[] capVoltages;
//RS channel 1/white
private int voltageControl = 0;
private boolean loaded = false;
public TileEntityMarx(EnumFacing facing, IWProperties.MarxType type, boolean mirrored) {
this.facing = facing;
@ -98,8 +111,13 @@ public class TileEntityMarx extends TileEntityIWMultiblock implements ITickable,
public void readNBT(NBTTagCompound in, boolean updatePacket) {
super.readNBT(in, updatePacket);
type = IWProperties.MarxType.values()[in.getInteger(TYPE)];
stageCount = in.getInteger(STAGES);
storage = DualEnergyStorage.readFromNBT(in.getCompoundTag(ENERGY_TAG));
setStageCount(in.getInteger(STAGES));
NBTTagList voltages = in.getTagList(CAP_VOLTAGES, 6);//DOUBLE
capVoltages = new double[stageCount];
for (int i = 0;i<stageCount;i++) {
capVoltages[i] = voltages.getDoubleAt(i);
}
storage.readFromNBT(in.getCompoundTag(ENERGY_TAG));
hasConnection = in.getBoolean(HAS_CONN);
boundingAabb = null;
renderAabb = null;
@ -178,16 +196,50 @@ public class TileEntityMarx extends TileEntityIWMultiblock implements ITickable,
} else if (state==FiringState.NEXT_TICK) {
state = FiringState.FIRE;
if (!world.isRemote) {
//TODO server-side effects of Marx discharges (damage (electric+sound), block processing, reset cap voltages, more?
//calculate energy
double energyStored = 0;
//TODO handle high cap voltage differences
for (int i = 0;i<stageCount;i++) {
energyStored += capVoltages[i]*capVoltages[i]/cReciproke;
capVoltages[i] = 0;
}
net.updateValues();
NBTTagCompound data = new NBTTagCompound();
data.setDouble("energy", energyStored);
IndustrialWires.packetHandler.sendToDimension(new MessageTileSyncIW(this, data), world.provider.getDimension());
} else {
dischargingMarxes.add(this);//TODO deal with breaking during discharges
}
}
if (!world.isRemote&&type== IWProperties.MarxType.BOTTOM) {
if (world.getTotalWorldTime()%40==0) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setFloat("energy", stageCount*9*9);
// IndustrialWires.packetHandler.sendToAll(new MessageTileSyncIW(this, nbt));
if (capVoltages==null||capVoltages.length!=stageCount) {
capVoltages = new double[stageCount];//TODO save to NBT
}
double oldTopVoltage = capVoltages[stageCount-1];
for (int i = stageCount-1;i>0;i--) {
double oldVoltage = capVoltages[i];
double u0 = capVoltages[i-1];
capVoltages[i] = u0-(u0-oldVoltage)*timeFactor;
capVoltages[i-1] -= capVoltages[i]-oldVoltage;
}
//charge bottom cap from storage
double u0 = 250_000*voltageControl/15D;
if (u0<=100*storage.getEnergyStoredEU()) {
double oldVoltage = capVoltages[0];
capVoltages[0] = u0 - (u0 - oldVoltage) * timeFactor;
double energyUsed = (capVoltages[0] * capVoltages[0] - oldVoltage * oldVoltage)/cReciproke;
if (energyUsed > 0) {// energyUsed can be negative when discharging the caps
storage.extractEURaw(energyUsed);
}
double vMax = 250_000;
if (Math.round(15*oldVoltage/vMax)!=Math.round(15*capVoltages[0]/vMax)) {
net.updateValues();
} else if (Math.round(15*oldTopVoltage/vMax)!=Math.round(15*capVoltages[stageCount-1]/vMax)) {
net.updateValues();
}
if (capVoltages[0] > 250_000 * 14 / 15) {
state = FiringState.NEXT_TICK;
}
}
}
}
@ -204,7 +256,7 @@ public class TileEntityMarx extends TileEntityIWMultiblock implements ITickable,
dischargeData = new TileRenderMarx.Discharge(stageCount);
}
dischargeData.energy = nbt.getFloat("energy");
dischargeData.diameter = dischargeData.energy/(stageCount*15*15);
dischargeData.diameter = dischargeData.energy/(stageCount*250*250);
dischargeData.genMarxPoint(0, dischargeData.vertices.length-1);
}
@ -225,7 +277,7 @@ public class TileEntityMarx extends TileEntityIWMultiblock implements ITickable,
private AxisAlignedBB boundingAabb = null;
@Override
public AxisAlignedBB getBoundingBox() {
if (boundingAabb==null||true) {
if (boundingAabb==null) {
int forward = getForward();
int right = getRight();
int up = offset.getY();
@ -389,20 +441,39 @@ public class TileEntityMarx extends TileEntityIWMultiblock implements ITickable,
return getRaytraceOffset(null);
}
private RedstoneWireNetwork net = new RedstoneWireNetwork().add(this);
private RedstoneWireNetwork net = new RedstoneWireNetwork();
@Override
public void setNetwork(RedstoneWireNetwork net) {
this.net = net;
masterOr(this, this).net = net;
}
@Override
public RedstoneWireNetwork getNetwork() {
return net;
TileEntityMarx master = masterOr(this, this);
if (!loaded) {
master.net.add(this);
loaded = true;
}
return master.net;
}
@Override
public void onChange() {
//TODO
TileEntityMarx master = masterOr(this, this);
master.voltageControl = master.net.channelValues[0];
if (master.net.channelValues[3]!=0) {//light blue is firing trigger
master.tryTriggeredDischarge();
}
}
public void tryTriggeredDischarge() {
if (capVoltages[0]>=8/15D*maxVoltage) {
state = FiringState.NEXT_TICK;
} else {
for (int i = 0;i<stageCount;i++) {
capVoltages[i] = 0;
}
net.updateValues();
}
}
@Override
@ -412,9 +483,24 @@ public class TileEntityMarx extends TileEntityIWMultiblock implements ITickable,
@Override
public void updateInput(byte[] signals) {
//TODO
TileEntityMarx master = masterOr(this, this);
if (master.capVoltages!=null&&master.capVoltages.length==stageCount) {
//1/orange is voltage measurement from the top cap
//2/magenta is for the bottom one
signals[1] = (byte)(Math.round(15*master.capVoltages[stageCount-1]/maxVoltage));
signals[2] = (byte)(Math.round(15*master.capVoltages[0]/maxVoltage));
}
}
public void setStageCount(int stageCount) {
this.stageCount = stageCount;
rcTimeConst = 5D/stageCount;
timeFactor = Math.exp(-1/(20*rcTimeConst));
}
public int getStageCount() {
return stageCount;
}
public enum FiringState {
CHARGING,

View file

@ -38,7 +38,7 @@ public class TileRenderMarx extends TileEntitySpecialRenderer<TileEntityMarx> {
@Override
public void renderTileEntityAt(TileEntityMarx te, double x, double y, double z, float partialTicks, int destroyStage) {
final boolean debug = false;
//noinspection PointlessBooleanExpression
//noinspection ConstantConditions,PointlessBooleanExpression
if (te.type== IWProperties.MarxType.BOTTOM&&(debug||te.state== TileEntityMarx.FiringState.FIRE)) {
prepare(x, y, z, te);
Tessellator tes = Tessellator.getInstance();
@ -53,7 +53,7 @@ public class TileRenderMarx extends TileEntitySpecialRenderer<TileEntityMarx> {
final float pos = .6875F;
GlStateManager.translate(-facing.getX()*pos, 0, -facing.getZ()*pos);
//draw firing spark gaps
for (int i = 0;i<te.stageCount-1;i++) {
for (int i = 0;i<te.getStageCount()-1;i++) {
GlStateManager.pushMatrix();
GlStateManager.translate(0, i, 0);
GlStateManager.rotate(-45, facing.getX(), facing.getY(), facing.getZ());

View file

@ -65,6 +65,10 @@ public class DualEnergyStorage {
return extr;
}
public void extractEURaw(double extract) {
storedEU -= extract;
}
public double extractIF(int extractMax, boolean doExtract) {
double eu = extractMax * ConversionUtil.euPerIfIdeal();
return ConversionUtil.ifPerEuIdeal() * extractEU(eu, doExtract);
@ -114,7 +118,7 @@ public class DualEnergyStorage {
}
}
public static DualEnergyStorage readFromNBT(NBTTagCompound nbt) {
return new DualEnergyStorage(nbt.getDouble("stored"), nbt.getDouble("maxStored"), nbt.getDouble("maxIn"), nbt.getDouble("maxOut"));
public void readFromNBT(NBTTagCompound nbt) {
storedEU = nbt.getDouble("stored");
}
}