More work

Changed waveform system to be more usable in code
Added some max speeds
This commit is contained in:
malte0811 2018-03-24 17:45:25 +01:00
parent 1fb01d9abd
commit 87f4dc8f93
16 changed files with 402 additions and 206 deletions

View file

@ -62,6 +62,17 @@ public class IWConfig {
@Comment({"The conversion factor between Joules (the SI unit) and RF. Used for the Marx generator and the rotary converters"})
//Default value assumes the IE diesel generator is 200kW
public static double joulesPerRF = 200e3/(20*IEConfig.Machines.dieselGen_output);
@Comment({"What energy types can be used with the mechanical multiblock. 0: None (Probably useless),",
"1: EU (Currently useless), 2: FE, 3:EU and FE (allows conversion, default)"})
public static int multiblockEnergyType = 3;
public static boolean allowMBFE() {
return (multiblockEnergyType&2)!=0;
}
public static boolean allowMBEU() {
return (multiblockEnergyType&1)!=0;
}
}
public static HVStuff hv;

View file

@ -27,11 +27,7 @@ import ic2.api.energy.tile.IEnergySource;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.ISyncReceiver;
import malte0811.industrialWires.blocks.TileEntityIWMultiblock;
import malte0811.industrialWires.converter.EUCapability;
import malte0811.industrialWires.converter.IMBPartElectric;
import malte0811.industrialWires.converter.IMBPartElectric.Waveform;
import malte0811.industrialWires.converter.MechEnergy;
import malte0811.industrialWires.converter.MechMBPart;
import malte0811.industrialWires.converter.*;
import malte0811.industrialWires.network.MessageTileSyncIW;
import malte0811.industrialWires.util.LocalSidedWorld;
import net.minecraft.block.state.IBlockState;
@ -61,7 +57,6 @@ import java.util.*;
import static blusunrize.immersiveengineering.common.IEContent.blockMetalDecoration0;
import static blusunrize.immersiveengineering.common.blocks.metal.BlockTypes_MetalDecoration0.HEAVY_ENGINEERING;
import static malte0811.industrialWires.converter.EUCapability.ENERGY_IC2;
import static malte0811.industrialWires.converter.IMBPartElectric.Waveform.*;
import static malte0811.industrialWires.util.MiscUtils.getOffset;
import static malte0811.industrialWires.util.MiscUtils.offset;
import static malte0811.industrialWires.util.NBTKeys.PARTS;
@ -73,7 +68,7 @@ import static malte0811.industrialWires.util.NBTKeys.SPEED;
})
public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implements ITickable, ISyncReceiver,
IEnergySource, IEnergySink, IPlayerInteraction, IRedstoneOutput {
private static final double DECAY_BASE = Math.exp(Math.log(.5)/(2*60*60*20));
private static final double DECAY_BASE = Math.exp(Math.log(.8)/(2*60*60*20));
public static final double TICK_ANGLE_PER_SPEED = 180/20/Math.PI;
private static final double SYNC_THRESHOLD = .95;
public MechMBPart[] mechanical = null;
@ -149,43 +144,44 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
double[] available = new double[sectionLength];
Waveform[] availableWf = new Waveform[sectionLength];
boolean hasEnergy = false;
Set<Waveform> availableWaveforms = new HashSet<>();
for (int i = section[0]; i < section[1]; i++) {
IMBPartElectric electricalComp = ((IMBPartElectric) mechanical[i]);
Waveform localWf = electricalComp.getProduced(energyState);
if (localWf == NONE) {
availableWf[i - section[0]] = NONE;
availableWf[i - section[0]] = localWf.getForSpeed(energyState.getSpeed());
if (!localWf.isEnergyWaveform()) {
continue;
}
if (localWf == AC_ASYNC && Math.abs(energyState.getSpeed() - EXTERNAL_SPEED) <= SYNC_TOLERANCE * EXTERNAL_SPEED) {
localWf = AC_SYNC;
}
double availableLocal = electricalComp.getAvailableEEnergy();
available[i - section[0]] = availableLocal;
availableWf[i - section[0]] = localWf;
availableWaveforms.add(localWf);
if (availableLocal>0) {
hasEnergy = true;
}
}
if (hasEnergy) {
double[][] requested = new double[VALUES.length][sectionLength];
List<Waveform> availableWfList = new ArrayList<>(availableWaveforms);
double[][] requested = new double[availableWfList.size()][sectionLength];
for (int i = 0; i < requested.length; i++) {
if (VALUES[i].isEnergyWaveform()) {
Waveform wf = availableWfList.get(i);
if (wf.isEnergyWaveform()) {
for (int j = 0; j < sectionLength; j++) {
requested[i][j] = ((IMBPartElectric) mechanical[j + section[0]]).requestEEnergy(VALUES[i], energyState);
requested[i][j] = ((IMBPartElectric) mechanical[j + section[0]]).requestEEnergy(wf, energyState);
}
}
}
Waveform maxWf = NONE;
int maxId = -1;
double maxTransferred = 0;
for (int i = 0; i < VALUES.length; i++) {
double transferred = transferElectric(section, Arrays.copyOf(available, sectionLength), availableWf, VALUES[i], requested[i], true);
for (int i = 0; i < requested.length; i++) {
Waveform wf = availableWfList.get(i);
double transferred = transferElectric(section, Arrays.copyOf(available, sectionLength), availableWf, wf, requested[i], true);
if (transferred > maxTransferred) {
maxTransferred = transferred;
maxWf = VALUES[i];
maxId = i;
}
}
if (maxWf!=NONE) {
transferElectric(section, available, availableWf, maxWf, requested[maxWf.ordinal()], false);
if (maxId>=0) {
transferElectric(section, available, availableWf, availableWfList.get(maxId), requested[maxId], false);
}
}
}
@ -263,7 +259,8 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
MechMBPart[] mech = new MechMBPart[mechParts.tagCount()];
int offset = 1;
for (int i = 0; i < mechParts.tagCount(); i++) {
mech[i] = MechMBPart.fromNBT(mechParts.getCompoundTagAt(i), new LocalSidedWorld(world, offset(pos, facing, mirrored, 0, -offset, 0), facing, mirrored));
mech[i] = MechMBPart.fromNBT(mechParts.getCompoundTagAt(i),
new LocalSidedWorld(world, offset(pos, facing, mirrored, 0, -offset, 0), facing.getOpposite(), mirrored));
offset += mech[i].getLength();
}
setMechanical(mech, in.getDouble(SPEED));
@ -353,12 +350,12 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) {
Vec3i offsetDirectional = getOffsetDir();
TileEntityMultiblockConverter master = masterOr(this, this);
int id = getPart(offsetDirectional.getY(), master);
int id = getPart(offsetDirectional.getZ(), master);
if (id<0) {
return false;
}
MechMBPart part = master.mechanical[id];
Vec3i offsetPart = new Vec3i(offsetDirectional.getX(), offsetDirectional.getY()-master.offsets[id], offsetDirectional.getZ());
BlockPos offsetPart = new BlockPos(offsetDirectional.getX(), offsetDirectional.getY(), offsetDirectional.getZ()-master.offsets[id]);
return part.hasCapability(capability, part.world.realToTransformed(facing), offsetPart);
}
@ -367,12 +364,12 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) {
Vec3i offsetDirectional = getOffsetDir();
TileEntityMultiblockConverter master = masterOr(this, this);
int id = getPart(offsetDirectional.getY(), master);
int id = getPart(offsetDirectional.getZ(), master);
if (id<0) {
return null;
}
MechMBPart part = master.mechanical[id];
Vec3i offsetPart = new Vec3i(offsetDirectional.getX(), offsetDirectional.getY()-master.offsets[id], offsetDirectional.getZ());
BlockPos offsetPart = new BlockPos(offsetDirectional.getX(), offsetDirectional.getY(), offsetDirectional.getZ()-master.offsets[id]);
return part.getCapability(capability, part.world.realToTransformed(facing), offsetPart);
}
@ -433,8 +430,18 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
@Override
public boolean emitsEnergyTo(IEnergyAcceptor output, EnumFacing side) {
EUCapability.IC2EnergyHandler cap = getIC2Cap();
return cap!=null&&cap.emitsEnergyTo(side);
if (ENERGY_IC2==null)
return false;
Vec3i offsetDirectional = getOffsetDir();
TileEntityMultiblockConverter master = masterOr(this, this);
int id = getPart(offsetDirectional.getZ(), master);
if (id<0) {
return false;
}
MechMBPart part = master.mechanical[id];
BlockPos offsetPart = new BlockPos(offsetDirectional.getX(), offsetDirectional.getY(), offsetDirectional.getZ()-master.offsets[id]);
EUCapability.IC2EnergyHandler cap = part.getCapability(ENERGY_IC2, part.world.realToTransformed(facing), offsetPart);
return cap!=null&&cap.emitsEnergyTo(side, offsetPart);
}
@Override
@ -457,8 +464,18 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
@Override
public boolean acceptsEnergyFrom(IEnergyEmitter input, EnumFacing side) {
EUCapability.IC2EnergyHandler cap = getIC2Cap();
return cap!=null&&cap.acceptsEnergyFrom(side);
if (ENERGY_IC2==null)
return false;
Vec3i offsetDirectional = getOffsetDir();
TileEntityMultiblockConverter master = masterOr(this, this);
int id = getPart(offsetDirectional.getZ(), master);
if (id<0) {
return false;
}
MechMBPart part = master.mechanical[id];
BlockPos offsetPart = new BlockPos(offsetDirectional.getX(), offsetDirectional.getY(), offsetDirectional.getZ()-master.offsets[id]);
EUCapability.IC2EnergyHandler cap = part.getCapability(ENERGY_IC2, part.world.realToTransformed(facing), offsetPart);
return cap!=null&&cap.acceptsEnergyFrom(side, offsetPart);
}
@Override
@ -502,7 +519,7 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
public boolean interact(@Nonnull EnumFacing side, @Nonnull EntityPlayer player, @Nonnull EnumHand hand,
@Nonnull ItemStack heldItem, float hitX, float hitY, float hitZ) {
TileEntityMultiblockConverter master = masterOr(this, this);
int id = getPart(getOffsetDir().getY(), master);
int id = getPart(getOffsetDir().getZ(), master);
if (id>=0&&master.mechanical[id] instanceof IPlayerInteraction) {
return ((IPlayerInteraction)master.mechanical[id]).interact(side, player, hand, heldItem, hitX, hitY, hitZ);
}
@ -510,13 +527,14 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
}
private Vec3i getOffsetDir() {
return getOffset(BlockPos.NULL_VECTOR, facing, mirrored, offset);
BlockPos offset = getOffset(BlockPos.NULL_VECTOR, facing, mirrored, this.offset);
return new BlockPos(offset.getX(), offset.getZ(), offset.getY());
}
@Override
public int getStrongRSOutput(@Nonnull IBlockState state, @Nonnull EnumFacing side) {
TileEntityMultiblockConverter master = masterOr(this, this);
int id = getPart(getOffsetDir().getY(), master);
int id = getPart(getOffsetDir().getZ(), master);
if (id>=0&&master.mechanical[id] instanceof IRedstoneOutput) {
MechMBPart part = master.mechanical[id];
return ((IRedstoneOutput)part).getStrongRSOutput(state,
@ -528,7 +546,7 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
@Override
public boolean canConnectRedstone(@Nonnull IBlockState state, @Nonnull EnumFacing side) {
TileEntityMultiblockConverter master = masterOr(this, this);
int id = getPart(getOffsetDir().getY(), master);
int id = getPart(getOffsetDir().getZ(), master);
if (id>=0&&master.mechanical[id] instanceof IRedstoneOutput) {
MechMBPart part = master.mechanical[id];
return ((IRedstoneOutput)part).canConnectRedstone(state,

View file

@ -17,6 +17,7 @@ package malte0811.industrialWires.converter;
import net.minecraft.nbt.NBTBase;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.CapabilityManager;
@ -51,9 +52,9 @@ public class EUCapability {
return tier;
}
public abstract boolean acceptsEnergyFrom(EnumFacing side);
public abstract boolean acceptsEnergyFrom(EnumFacing side, BlockPos offset);
public abstract boolean emitsEnergyTo(EnumFacing side);
public abstract boolean emitsEnergyTo(EnumFacing side, BlockPos offset);
public abstract double injectEnergy(EnumFacing enumFacing, double v, double v1);
@ -66,12 +67,12 @@ public class EUCapability {
public static class IC2EnergyHandlerDummy extends IC2EnergyHandler {
@Override
public boolean acceptsEnergyFrom(EnumFacing side) {
public boolean acceptsEnergyFrom(EnumFacing side, BlockPos offset) {
return false;
}
@Override
public boolean emitsEnergyTo(EnumFacing side) {
public boolean emitsEnergyTo(EnumFacing side, BlockPos offset) {
return false;
}

View file

@ -15,7 +15,17 @@
package malte0811.industrialWires.converter;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableSet;
import malte0811.industrialWires.util.ConversionUtil;
import malte0811.industrialWires.util.LocalSidedWorld;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Set;
public interface IMBPartElectric {
/**
@ -30,80 +40,24 @@ public interface IMBPartElectric {
double requestEEnergy(Waveform waveform, MechEnergy energy);
void insertEEnergy(double given, Waveform waveform, MechEnergy energy);
enum Waveform {
NONE(null, 0, true),
//Sync/async refers to multiblock rotation speed, not to line frequency
AC_SYNC(true, 4, true),
AC_ASYNC(true, 5, 4, true),
AC_4PHASE_SYNC(true, 4, false),
AC_4PHASE_ASYNC(true, 4, false),
DC(false, 1, true) {
@Override
public Waveform getCommutated(double speed, boolean fourPhase) {
if (!fourPhase) {
return super.getCommutated(speed, false);
} else {
if (isSyncSpeed(speed)) {
return AC_4PHASE_ASYNC;
} else {
return AC_4PHASE_SYNC;
}
default Set<Pair<BlockPos, EnumFacing>> getEnergyConnections() {
return ImmutableSet.of();
}
default double outputFE(LocalSidedWorld world, int available) {
double extracted = 0;
for (Pair<BlockPos, EnumFacing> output : getEnergyConnections()) {
BlockPos outTE = output.getLeft().offset(output.getRight());
TileEntity te = world.getTileEntity(outTE);
EnumFacing sideReal = world.transformedToReal(output.getRight()).getOpposite();
if (te != null && te.hasCapability(CapabilityEnergy.ENERGY, sideReal)) {
IEnergyStorage energy = te.getCapability(CapabilityEnergy.ENERGY, sideReal);
if (energy != null && energy.canReceive()) {
int received = energy.receiveEnergy(available, false);
available -= received;
extracted += ConversionUtil.joulesPerIf() * received;
}
}
},
MESS(null, 5, true);
public static final double EXTERNAL_SPEED = 20;
public static final double SYNC_TOLERANCE = .1;
public static final double MIN_COMM_SPEED = 4;
public static final Waveform[] VALUES = values();
public static boolean isSyncSpeed(double speed) {
return Math.abs(speed- EXTERNAL_SPEED)<SYNC_TOLERANCE* EXTERNAL_SPEED;
}
@Nullable
private Boolean isAC;
boolean single;
private int dualId, syncDualId;
public Waveform dual, syncDual;
Waveform(@Nullable Boolean ac, int dualId, boolean singlePhase) {
this(ac, dualId, dualId, singlePhase);
}
Waveform(@Nullable Boolean ac, int dualId, int syncDual, boolean singlePhase) {
isAC = ac;
this.dualId = dualId;
syncDualId = syncDual;
single = singlePhase;
}
public static void init() {
for (Waveform f:VALUES) {
f.dual = VALUES[f.dualId];
f.syncDual = VALUES[f.syncDualId];
}
}
public Waveform getCommutated(double speed, boolean fourPhase) {
if (isSyncSpeed(speed)) {
return syncDual;
}
return speed<MIN_COMM_SPEED?this:dual;
}
public boolean isAC() {
return isAC==Boolean.TRUE;
}
public boolean isDC() {
return isAC==Boolean.FALSE;
}
public boolean isEnergyWaveform() {
return isAC!=null;
}
public boolean isSinglePhase() {
return single;
}
return extracted;
}
}

View file

@ -32,7 +32,6 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@ -80,11 +79,11 @@ public abstract class MechMBPart {
for (int j = 0; j < 2; j++) {
IBlockState state = w.getBlockState(new BlockPos(2*i-1, j-1, 0));
if (!isLightEngineering(state)) {
return true;
return false;
}
}
}
return false;
return true;
}
public abstract short getFormPattern();
@ -96,11 +95,11 @@ public abstract class MechMBPart {
public abstract MechanicalMBBlockType getType();
public <T> boolean hasCapability(Capability<T> cap, EnumFacing side, Vec3i pos) {
public <T> boolean hasCapability(Capability<T> cap, EnumFacing side, BlockPos pos) {
return false;
}
public <T> T getCapability(Capability<T> cap, EnumFacing side, Vec3i pos) {
public <T> T getCapability(Capability<T> cap, EnumFacing side, BlockPos pos) {
return null;
}
@ -110,8 +109,6 @@ public abstract class MechMBPart {
(c)->-MiscUtils.count1Bits(c.getFormPattern())
);
public static void preInit() {
IMBPartElectric.Waveform.init();
REGISTRY.put("flywheel", MechPartFlywheel.class);
REGISTRY.put("singleCoil", MechPartSingleCoil.class);
REGISTRY.put("twoElectrodes", MechPartTwoElectrodes.class);

View file

@ -15,6 +15,8 @@
package malte0811.industrialWires.converter;
import com.google.common.collect.ImmutableSet;
import malte0811.industrialWires.IWConfig;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.converter.MechanicalMBBlockType;
import malte0811.industrialWires.converter.EUCapability.IC2EnergyHandler;
@ -25,18 +27,29 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.energy.IEnergyStorage;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Set;
import static malte0811.industrialWires.converter.EUCapability.ENERGY_IC2;
import static malte0811.industrialWires.converter.Waveform.Phases.get;
import static malte0811.industrialWires.converter.Waveform.Speed.EXTERNAL;
import static malte0811.industrialWires.converter.Waveform.Speed.ROTATION;
import static malte0811.industrialWires.converter.Waveform.Type.DC;
import static malte0811.industrialWires.converter.Waveform.Type.NONE;
import static malte0811.industrialWires.util.NBTKeys.*;
import static net.minecraft.util.EnumFacing.UP;
import static net.minecraft.util.math.BlockPos.ORIGIN;
import static net.minecraftforge.energy.CapabilityEnergy.ENERGY;
public class MechPartCommutator extends MechMBPart implements IMBPartElectric {
private double bufferToMB;
private Waveform wfToMB = Waveform.NONE;
private Waveform wfToMB = Waveform.forParameters(NONE, get(has4Phases()), ROTATION);
private double bufferToWorld;
private Waveform wfToWorld = Waveform.NONE;
private Waveform wfToWorld = Waveform.forParameters(NONE, get(has4Phases()), ROTATION);
@Override
public Waveform getProduced(MechEnergy state) {
return wfToMB.getCommutated(state.getSpeed(), has4Phases());
@ -65,26 +78,32 @@ public class MechPartCommutator extends MechMBPart implements IMBPartElectric {
}
@Override
public void insertEEnergy(double given, Waveform waveform, MechEnergy energy) {
waveform = waveform.getCommutated(energy.getSpeed(), has4Phases());
public void insertEEnergy(double given, Waveform waveform, MechEnergy mechEnergy) {
waveform = waveform.getCommutated(mechEnergy.getSpeed(), has4Phases());
if (waveform!=wfToWorld) {
wfToWorld = waveform;
bufferToWorld = 0;
}
bufferToWorld += given;
int available = (int) (Math.min(ConversionUtil.ifPerJoule() * bufferToWorld,
getMaxBuffer()/getEnergyConnections().size()));
if (available > 0 && wfToWorld.isAC()) {//The IC2 net will deal with DC by itself
bufferToWorld -= outputFE(world, available);
}
}
private final IC2EnergyHandler capIc2 = new IC2EnergyHandler() {
{
tier = 3;//TODO does this mean everything blows up?
}
@Override
public boolean acceptsEnergyFrom(EnumFacing side) {
public boolean acceptsEnergyFrom(EnumFacing side, BlockPos offset) {
return side==EnumFacing.UP&&bufferToMB<getMaxBuffer();
}
@Override
public boolean emitsEnergyTo(EnumFacing side) {
public boolean emitsEnergyTo(EnumFacing side, BlockPos offset) {
return side==EnumFacing.UP&&bufferToWorld>0;
}
@ -98,7 +117,7 @@ public class MechPartCommutator extends MechMBPart implements IMBPartElectric {
input = Math.min(input, getMaxBuffer()-buffer);
buffer += input;
bufferToMB = buffer;
wfToMB = Waveform.AC_ASYNC;
wfToMB = Waveform.forParameters(DC, get(has4Phases()), EXTERNAL);
return amount-ConversionUtil.euPerJoule()*input;
}
@ -128,7 +147,7 @@ public class MechPartCommutator extends MechMBPart implements IMBPartElectric {
buffer += input;
if (!simulate) {
bufferToMB = buffer;
wfToMB = Waveform.AC_ASYNC;
wfToMB = Waveform.forParameters(Waveform.Type.AC, get(has4Phases()), EXTERNAL);
}
return (int) (ConversionUtil.ifPerJoule()*input);
}
@ -170,23 +189,28 @@ public class MechPartCommutator extends MechMBPart implements IMBPartElectric {
};
@Override
public <T> T getCapability(Capability<T> cap, EnumFacing side, Vec3i pos) {
if (cap==EUCapability.ENERGY_IC2) {
return EUCapability.ENERGY_IC2.cast(capIc2);
}
if (side==EnumFacing.UP&&cap== ENERGY) {
return ENERGY.cast(capForge);
public <T> T getCapability(Capability<T> cap, EnumFacing side, BlockPos pos) {
IndustrialWires.logger.info("{}, {}", pos, side);
if (getEnergyConnections().contains(new ImmutablePair<>(pos, side))) {
if (cap == ENERGY_IC2) {
return ENERGY_IC2.cast(capIc2);
}
if (cap == ENERGY) {
return ENERGY.cast(capForge);
}
}
return super.getCapability(cap, side, pos);
}
@Override
public <T> boolean hasCapability(Capability<T> cap, EnumFacing side, Vec3i pos) {
if (cap==EUCapability.ENERGY_IC2) {
return true;
}
if (side==EnumFacing.UP&&cap== ENERGY) {
return true;
public <T> boolean hasCapability(Capability<T> cap, EnumFacing side, BlockPos pos) {
if (getEnergyConnections().contains(new ImmutablePair<>(pos, side))) {
if (cap == ENERGY_IC2) {
return true;
}
if (cap == ENERGY) {
return true;
}
}
return super.hasCapability(cap, side, pos);
}
@ -209,15 +233,15 @@ public class MechPartCommutator extends MechMBPart implements IMBPartElectric {
@Override
public double getMaxSpeed() {
return Double.MAX_VALUE;
return IWConfig.MechConversion.allowMBEU()?100:-1;
}
@Override
public void writeToNBT(NBTTagCompound out) {
out.setDouble(BUFFER_IN, bufferToMB);
out.setDouble(BUFFER_OUT, bufferToWorld);
out.setInteger(BUFFER_IN+WAVEFORM, wfToMB.ordinal());
out.setInteger(BUFFER_OUT+WAVEFORM, wfToWorld.ordinal());
out.setInteger(BUFFER_IN+WAVEFORM, wfToMB.getIndex());
out.setInteger(BUFFER_OUT+WAVEFORM, wfToWorld.getIndex());//TODO better way of doing this that doesn't break when I change anything
}
@Override
@ -237,6 +261,9 @@ public class MechPartCommutator extends MechMBPart implements IMBPartElectric {
new ResourceLocation("ic2", "kinetic_generator");
@Override
public boolean canForm(LocalSidedWorld w) {
if (!IWConfig.MechConversion.allowMBEU()) {
return false;
}
//Center is an IC2 kinetic generator
TileEntity te = w.getTileEntity(BlockPos.ORIGIN);
if (te!=null) {
@ -275,4 +302,12 @@ public class MechPartCommutator extends MechMBPart implements IMBPartElectric {
protected boolean has4Phases() {
return false;
}
private static final ImmutableSet<Pair<BlockPos, EnumFacing>> outputs = ImmutableSet.of(
new ImmutablePair<>(ORIGIN, UP)
);
public Set<Pair<BlockPos, EnumFacing>> getEnergyConnections() {
return outputs;
}
}

View file

@ -15,11 +15,21 @@
package malte0811.industrialWires.converter;
import com.google.common.collect.ImmutableSet;
import malte0811.industrialWires.IWConfig;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.converter.MechanicalMBBlockType;
import malte0811.industrialWires.util.LocalSidedWorld;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Set;
import static net.minecraft.util.EnumFacing.EAST;
import static net.minecraft.util.EnumFacing.WEST;
public class MechPartCommutator4Phase extends MechPartCommutator {
@Override
@ -62,4 +72,21 @@ public class MechPartCommutator4Phase extends MechPartCommutator {
public ResourceLocation getRotatingBaseModel() {
return new ResourceLocation(IndustrialWires.MODID, "block/mech_mb/shaft_comm4.obj");
}
@Override
public double getMaxSpeed() {
return IWConfig.MechConversion.allowMBEU()?100:-1;
}
private static final Set<Pair<BlockPos, EnumFacing>> outputs = ImmutableSet.of(
new ImmutablePair<>(new BlockPos(1, 0, 0), EAST),
new ImmutablePair<>(new BlockPos(1, -1, 0), EAST),
new ImmutablePair<>(new BlockPos(-1, 0, 0), WEST),
new ImmutablePair<>(new BlockPos(-1, -1, 0), WEST)
);
@Override
public Set<Pair<BlockPos, EnumFacing>> getEnergyConnections() {
return outputs;
}
}

View file

@ -38,9 +38,6 @@ import net.minecraftforge.oredict.OreDictionary;
import java.util.List;
import java.util.stream.Collectors;
import static blusunrize.immersiveengineering.common.IEContent.blockMetalDecoration0;
import static blusunrize.immersiveengineering.common.blocks.metal.BlockTypes_MetalDecoration0.LIGHT_ENGINEERING;
public class MechPartFlywheel extends MechMBPart {
private static final double RADIUS = 1.25;
private static final double THICKNESS = 1;
@ -127,8 +124,7 @@ public class MechPartFlywheel extends MechMBPart {
@Override
public void disassemble(boolean failed, MechEnergy energy) {
world.setBlockState(BlockPos.ORIGIN,
blockMetalDecoration0.getDefaultState().withProperty(blockMetalDecoration0.property, LIGHT_ENGINEERING));
setDefaultShaft(BlockPos.ORIGIN);
IBlockState state = Blocks.AIR.getDefaultState();
if (!failed) {
for (ItemStack block: OreDictionary.getOres("block"+material.oreName())) {
@ -153,7 +149,7 @@ public class MechPartFlywheel extends MechMBPart {
mat.rotate(Math.PI/4, 0, 0, 1);
Vec3d pos = mat.apply(baseVec);
EntityBrokenPart e = new EntityBrokenPart(world.getWorld(), material.blockTexture);
e.setPosition(pos.x, pos.y, .5);
e.setPosition(pos.x, pos.y, -.5);
double speed = (energy.getSpeed()/ getMaxSpeed())/1.5;
e.motionX = pos.y*speed;
e.motionY = -pos.x*speed;

View file

@ -87,4 +87,9 @@ public class MechPartFourCoils extends MechPartSingleCoil {
public ResourceLocation getRotatingBaseModel() {
return new ResourceLocation(IndustrialWires.MODID, "block/mech_mb/four_coil.obj");
}
@Override
public double getMaxSpeed() {
return 500;
}
}

View file

@ -15,11 +15,20 @@
package malte0811.industrialWires.converter;
import com.google.common.collect.ImmutableSet;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.converter.MechanicalMBBlockType;
import malte0811.industrialWires.util.LocalSidedWorld;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Set;
import static net.minecraft.util.EnumFacing.EAST;
import static net.minecraft.util.EnumFacing.WEST;
public class MechPartFourElectrodes extends MechPartTwoElectrodes {
@Override
@ -53,6 +62,17 @@ public class MechPartFourElectrodes extends MechPartTwoElectrodes {
}
}
private static final Set<Pair<BlockPos, EnumFacing>> outputs = ImmutableSet.of(
new ImmutablePair<>(new BlockPos(1, 0, 0), EAST),
new ImmutablePair<>(new BlockPos(1, -1, 0), EAST),
new ImmutablePair<>(new BlockPos(-1, 0, 0), WEST),
new ImmutablePair<>(new BlockPos(-1, -1, 0), WEST)
);
@Override
public Set<Pair<BlockPos, EnumFacing>> getEnergyConnections() {
return outputs;
}
@Override
public MechanicalMBBlockType getType() {
return MechanicalMBBlockType.SHAFT_4_PHASE;

View file

@ -26,6 +26,7 @@ import net.minecraft.util.math.BlockPos;
import static blusunrize.immersiveengineering.common.IEContent.blockMetalDecoration0;
import static blusunrize.immersiveengineering.common.blocks.metal.BlockTypes_MetalDecoration0.COIL_LV;
import static malte0811.industrialWires.converter.Waveform.Phases.get;
import static malte0811.industrialWires.util.NBTKeys.BUFFER_IN;
import static malte0811.industrialWires.util.NBTKeys.BUFFER_OUT;
@ -35,7 +36,7 @@ public class MechPartSingleCoil extends MechMBPart implements IMBPartElectric {
@Override
public Waveform getProduced(MechEnergy state) {
return Waveform.AC_SYNC;
return Waveform.forParameters(Waveform.Type.AC, get(has4Phases()), Waveform.Speed.ROTATION);
}
@Override
@ -88,7 +89,7 @@ public class MechPartSingleCoil extends MechMBPart implements IMBPartElectric {
@Override
public double getMaxSpeed() {
return Double.MAX_VALUE;//TODO I'm fine with shafts having infinite max speed. Not coils though.
return 200;
}
@Override

View file

@ -42,7 +42,7 @@ import static net.minecraft.util.EnumFacing.AxisDirection.POSITIVE;
import static net.minecraft.util.math.BlockPos.ORIGIN;
public class MechPartSpeedometer extends MechMBPart implements IPlayerInteraction, IRedstoneOutput {
private double speedFor15RS = 2 * IMBPartElectric.Waveform.EXTERNAL_SPEED;
private double speedFor15RS = 2 * Waveform.EXTERNAL_SPEED;
private int currentOutputLin = -1;
private int currentOutputLog = -1;
private double logFactor = 15 / Math.log(speedFor15RS + 1);

View file

@ -15,49 +15,43 @@
package malte0811.industrialWires.converter;
import com.google.common.collect.ImmutableSet;
import malte0811.industrialWires.IWConfig;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.converter.MechanicalMBBlockType;
import malte0811.industrialWires.util.ConversionUtil;
import malte0811.industrialWires.util.LocalSidedWorld;
import net.minecraft.block.state.IBlockState;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Set;
import static blusunrize.immersiveengineering.common.IEContent.blockMetalDecoration0;
import static blusunrize.immersiveengineering.common.blocks.metal.BlockTypes_MetalDecoration0.GENERATOR;
import static malte0811.industrialWires.converter.IMBPartElectric.Waveform.*;
import static malte0811.industrialWires.converter.Waveform.Phases.get;
import static malte0811.industrialWires.util.ConversionUtil.ifPerJoule;
import static malte0811.industrialWires.util.ConversionUtil.joulesPerIf;
import static malte0811.industrialWires.util.NBTKeys.*;
import static net.minecraft.util.EnumFacing.UP;
import static net.minecraft.util.math.BlockPos.ORIGIN;
public class MechPartTwoElectrodes extends MechMBPart implements IMBPartElectric {
private double bufferToMB;
private boolean isACInMBBuffer;
private Waveform wfToMB = Waveform.forParameters(Waveform.Type.NONE, get(has4Phases()), Waveform.Speed.EXTERNAL);
private double bufferToWorld;
private boolean isACInWBuffer;
private Waveform wfToWorld = Waveform.forParameters(Waveform.Type.NONE, get(has4Phases()), Waveform.Speed.ROTATION);
@Override
public Waveform getProduced(MechEnergy state) {
if (bufferToMB > 0) {
if (isACInMBBuffer)
if (has4Phases()) {
return AC_4PHASE_ASYNC;
} else {
return AC_ASYNC;
}
else {
return DC;
}
} else {
return NONE;
}
return wfToMB;
}
@Override
@ -72,7 +66,7 @@ public class MechPartTwoElectrodes extends MechMBPart implements IMBPartElectric
@Override
public double requestEEnergy(Waveform waveform, MechEnergy energy) {
if (waveform.isSinglePhase()) {
if (waveform.isSinglePhase()^has4Phases()) {
return getMaxBuffer()-bufferToWorld;
}
return 0;
@ -80,13 +74,11 @@ public class MechPartTwoElectrodes extends MechMBPart implements IMBPartElectric
@Override
public void insertEEnergy(double given, Waveform waveform, MechEnergy energy) {
if (bufferToWorld > 0 && (isACInWBuffer ^ waveform.isAC())) {
if (bufferToWorld > 0 && (wfToWorld.isAC() ^ waveform.isAC())) {
bufferToWorld = 0;
}
if (waveform.isAC() || waveform.isAC()) {
bufferToWorld += given;
isACInWBuffer = waveform.isAC();
}
bufferToWorld += given;
wfToWorld = waveform;
}
@Override
@ -99,44 +91,37 @@ public class MechPartTwoElectrodes extends MechMBPart implements IMBPartElectric
@Override
public void insertMEnergy(double added) {
int available = (int) (ConversionUtil.ifPerJoule()*bufferToWorld);
if (available>0&&isACInWBuffer) {//The IC2 net will deal with DC by itself
BlockPos up = BlockPos.ORIGIN.up();
TileEntity te = world.getTileEntity(up);
if (te != null && te.hasCapability(CapabilityEnergy.ENERGY, EnumFacing.DOWN)) {
IEnergyStorage energy = te.getCapability(CapabilityEnergy.ENERGY, EnumFacing.DOWN);
if (energy != null && energy.canReceive()) {
int received = energy.receiveEnergy(available, false);
bufferToWorld -= ConversionUtil.joulesPerIf() * received;
}
}
int available = (int) (Math.min(ConversionUtil.ifPerJoule() * bufferToWorld,
getMaxBuffer()/getEnergyConnections().size()));
if (available > 0 && wfToWorld.isAC()) {//The IC2 net will deal with DC by itself
bufferToWorld -= outputFE(world, available);
}
}
@Override
public double getInertia() {
return 50;//Random value. Does this work reasonably well?
return 50;
}
@Override
public double getMaxSpeed() {
return Double.MAX_VALUE;//TODO
return IWConfig.MechConversion.allowMBFE()?200:-1;
}
@Override
public void writeToNBT(NBTTagCompound out) {
out.setDouble(BUFFER_IN, bufferToMB);
out.setBoolean(BUFFER_IN+AC, isACInMBBuffer);
out.setInteger(BUFFER_IN+AC, wfToMB.getIndex());
out.setDouble(BUFFER_OUT, bufferToWorld);
out.setBoolean(BUFFER_OUT+AC, isACInWBuffer);
out.setInteger(BUFFER_OUT+AC, wfToWorld.getIndex());
}
@Override
public void readFromNBT(NBTTagCompound in) {
bufferToMB = in.getDouble(BUFFER_IN);
isACInMBBuffer = in.getBoolean(BUFFER_IN+AC);
wfToMB = Waveform.VALUES[in.getInteger(BUFFER_IN+AC)];
bufferToWorld = in.getDouble(BUFFER_OUT);
isACInWBuffer = in.getBoolean(BUFFER_OUT+AC);
wfToWorld = Waveform.VALUES[in.getInteger(BUFFER_OUT+AC)];
}
@Override
@ -147,7 +132,10 @@ public class MechPartTwoElectrodes extends MechMBPart implements IMBPartElectric
@Override
public boolean canForm(LocalSidedWorld w) {
IBlockState state = w.getBlockState(BlockPos.ORIGIN);
if (!IWConfig.MechConversion.allowMBFE()) {
return false;
}
IBlockState state = w.getBlockState(ORIGIN);
return state.getBlock()== blockMetalDecoration0 &&
state.getValue(blockMetalDecoration0.property)== GENERATOR;
}
@ -159,7 +147,7 @@ public class MechPartTwoElectrodes extends MechMBPart implements IMBPartElectric
@Override
public void disassemble(boolean failed, MechEnergy energy) {
world.setBlockState(BlockPos.ORIGIN,
world.setBlockState(ORIGIN,
blockMetalDecoration0.getDefaultState().withProperty(blockMetalDecoration0.property, GENERATOR));
}
@ -168,16 +156,22 @@ public class MechPartTwoElectrodes extends MechMBPart implements IMBPartElectric
return MechanicalMBBlockType.SHAFT_1_PHASE;
}
private static final ImmutableSet<Pair<BlockPos, EnumFacing>> outputs = ImmutableSet.of(
new ImmutablePair<>(ORIGIN, UP)
);
public Set<Pair<BlockPos, EnumFacing>> getEnergyConnections() {
return outputs;
}
private IEnergyStorage energy = new IEnergyStorage() {
@Override
public int receiveEnergy(int maxReceive, boolean simulate) {
double joules = joulesPerIf()*maxReceive;
double insert = Math.min(joules, getMaxBuffer()-bufferToMB);
double insert = Math.min(Math.min(joules, getMaxBuffer()-bufferToMB), getMaxBuffer()/getEnergyConnections().size());
if (!simulate) {
if (!isACInMBBuffer) {
if (!wfToMB.isAC()) {
bufferToMB = 0;
isACInMBBuffer = true;
wfToMB = Waveform.forParameters(Waveform.Type.AC, get(has4Phases()), Waveform.Speed.EXTERNAL);
}
bufferToMB += insert;
}
@ -186,9 +180,9 @@ public class MechPartTwoElectrodes extends MechMBPart implements IMBPartElectric
@Override
public int extractEnergy(int maxExtract, boolean simulate) {
if (isACInWBuffer) {
if (wfToWorld.isAC()) {
double joules = joulesPerIf() * maxExtract;
double extract = Math.min(joules, bufferToWorld);
double extract = Math.min(Math.min(joules, bufferToWorld), getMaxBuffer()/getEnergyConnections().size());
if (!simulate)
bufferToWorld -= extract;
return (int) Math.floor(extract * ifPerJoule());
@ -219,8 +213,8 @@ public class MechPartTwoElectrodes extends MechMBPart implements IMBPartElectric
};
@Override
public <T> boolean hasCapability(Capability<T> cap, EnumFacing side, Vec3i pos) {
if (pos.equals(BlockPos.ORIGIN)&&side==EnumFacing.UP) {
public <T> boolean hasCapability(Capability<T> cap, EnumFacing side, BlockPos pos) {
if (getEnergyConnections().contains(new ImmutablePair<>(pos, side))) {
if (cap==CapabilityEnergy.ENERGY)
return true;
//TODO return true for internal IC2 cap that doesn't exist yet
@ -229,8 +223,8 @@ public class MechPartTwoElectrodes extends MechMBPart implements IMBPartElectric
}
@Override
public <T> T getCapability(Capability<T> cap, EnumFacing side, Vec3i pos) {
if (pos.equals(BlockPos.ORIGIN)&&side==EnumFacing.UP&&cap== CapabilityEnergy.ENERGY)
public <T> T getCapability(Capability<T> cap, EnumFacing side, BlockPos pos) {
if (getEnergyConnections().contains(new ImmutablePair<>(pos, side))&&cap== CapabilityEnergy.ENERGY)
return CapabilityEnergy.ENERGY.cast(energy);
return super.getCapability(cap, side, pos);
}

View file

@ -94,6 +94,7 @@ public class MultiblockConverter implements MultiblockHandler.IMultiblock {
instances.sort(MechMBPart.SORT_BY_COUNT);
int lastCount = 0;
for (MechMBPart part:instances) {
IndustrialWires.logger.info(w.getRealPos(BlockPos.ORIGIN)+", "+part);
int newCount = MiscUtils.count1Bits(part.getFormPattern());
if (newCount==1&&lastCount>1&&checkEnd(w, mutPos)) {
foundAll = true;

View file

@ -0,0 +1,134 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2018 malte0811
* Industrial Wires is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Industrial Wires is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Industrial Wires. If not, see <http://www.gnu.org/licenses/>.
*/
package malte0811.industrialWires.converter;
import static malte0811.industrialWires.converter.Waveform.Phases.SINGLE;
import static malte0811.industrialWires.converter.Waveform.Speed.EXTERNAL;
import static malte0811.industrialWires.converter.Waveform.Speed.ROTATION;
import static malte0811.industrialWires.converter.Waveform.Type.*;
public class Waveform {
public static final double EXTERNAL_SPEED = 20;
public static final double SYNC_TOLERANCE = .1;
public static final double MIN_COMM_SPEED = 4;
public static final Waveform[] VALUES = new Waveform[Type.VALUES.length*Phases.VALUES.length* Speed.VALUES.length];
public static boolean isSyncSpeed(double speed) {
return Math.abs(speed - EXTERNAL_SPEED) < SYNC_TOLERANCE * EXTERNAL_SPEED;
}
static {
for (Type t:Type.VALUES) {
for (Phases p:Phases.VALUES) {
for (Speed s: Speed.VALUES) {
VALUES[getIndex(t, p, s)] = new Waveform(t, p, s);
}
}
}
}
public static Waveform forParameters(Type t, Phases p, Speed s) {
return VALUES[getIndex(t, p, s)];
}
private static int getIndex(Type t, Phases p, Speed s) {
return t.ordinal()* Phases.VALUES.length* Speed.VALUES.length
+p.ordinal()* Speed.VALUES.length
+s.ordinal();
}
private Type type;
private Phases phases;
private Speed speed;
private Waveform(Type type, Phases phases, Speed speed) {
this.type = type;
this.phases = phases;
this.speed = speed;
}
public Waveform getCommutated(double speed, boolean fourPhase) {
if (speed < MIN_COMM_SPEED) {
return this;
}
Type commType = type;
if (type==AC) {
commType = DC;
} else if (type==DC) {
commType = AC;
}
Speed commSpeed = ROTATION;
if (isSyncSpeed(speed)) {
commSpeed = EXTERNAL;
} else if (type==AC && this.speed ==EXTERNAL) {
commType = MESS;
}
return forParameters(commType, phases, commSpeed);
}
public boolean isAC() {
return type==AC;
}
public boolean isDC() {
return type == DC;
}
public boolean isEnergyWaveform() {
return type!=NONE&&type!=MESS;
}
public boolean isSinglePhase() {
return phases== SINGLE;
}
public Waveform getForSpeed(double speed) {
if (this.speed==ROTATION&&isSyncSpeed(speed)) {
return forParameters(type, phases, EXTERNAL);
}
return this;
}
public int getIndex() {
return getIndex(type, phases, speed);
}
public enum Type {
NONE,
MESS,//AC commutated at a wrong speed
AC,
DC;
public static final Type[] VALUES = values();
}
public enum Phases {
SINGLE,
FOUR;
public static final Phases[] VALUES = values();
public static Phases get(boolean has4Phases) {
return has4Phases?FOUR:SINGLE;
}
}
public enum Speed {
ROTATION,
EXTERNAL;
public static final Speed[] VALUES = values();
}
}

View file

@ -15,6 +15,7 @@
package malte0811.industrialWires.util;
import malte0811.industrialWires.IndustrialWires;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity;
@ -60,6 +61,7 @@ public class LocalSidedWorld {
public void spawnEntity(Entity e) {
Vec3d pos = getRealPos(e.getPositionVector());
IndustrialWires.logger.info("Spawning at {} (relative), {} (absolute)", e.getPositionVector(), pos);
e.setPosition(pos.x, pos.y, pos.z);
Vec3d motion = getRealDirection(new Vec3d(e.motionX, e.motionY, e.motionZ));
e.motionX = motion.x;
@ -97,14 +99,14 @@ public class LocalSidedWorld {
if (f==null||f.getAxis()== EnumFacing.Axis.Y) {
return f;
}
return EnumFacing.getHorizontal(f.getHorizontalIndex()+facing.getHorizontalIndex());
return EnumFacing.getHorizontal(f.getHorizontalIndex()-facing.getHorizontalIndex()+2);
}
public EnumFacing transformedToReal(@Nullable EnumFacing f) {
if (f==null||f.getAxis()== EnumFacing.Axis.Y) {
return f;
}
return EnumFacing.getHorizontal(f.getHorizontalIndex()-facing.getHorizontalIndex());
return EnumFacing.getHorizontal(f.getHorizontalIndex()+facing.getHorizontalIndex()+2);
}
//Getters+Setters