Basic separated energy inputs/outputs for MechMB's

This commit is contained in:
malte0811 2018-06-16 19:15:15 +02:00
parent 5364b14f5b
commit 3d2865aa93
21 changed files with 710 additions and 157 deletions

View file

@ -86,4 +86,8 @@ public class CommonProxy implements IGuiHandler {
public void updateMechMBTurningSound(TileEntityMechMB te, MechEnergy energy) {}
public void stopAllSoundsExcept(BlockPos pos, Set<?> excluded) {}
public boolean isSingleplayer() {
return false;
}
}

View file

@ -15,12 +15,15 @@
package malte0811.industrialWires.blocks;
import malte0811.industrialWires.util.MBSideConfig;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.util.IStringSerializable;
import net.minecraftforge.common.property.IUnlistedProperty;
public final class IWProperties {
private IWProperties() {}
public static PropertyEnum<MarxType> MARX_TYPE = PropertyEnum.create("marx_type", MarxType.class);
public static final PropertyEnum<MarxType> MARX_TYPE = PropertyEnum.create("marx_type", MarxType.class);
public static final IUnlistedProperty<MBSideConfig> MB_SIDES = new MBSideConfigProperty();
public enum MarxType implements IStringSerializable {
NO_MODEL,
BOTTOM,
@ -33,4 +36,27 @@ public final class IWProperties {
return name().toLowerCase();
}
}
public static class MBSideConfigProperty implements IUnlistedProperty<MBSideConfig> {
@Override
public String getName() {
return "mb_side";
}
@Override
public boolean isValid(MBSideConfig value) {
return value!=null;
}
@Override
public Class<MBSideConfig> getType() {
return MBSideConfig.class;
}
@Override
public String valueToString(MBSideConfig value) {
return value.toString();
}
}
}

View file

@ -116,7 +116,7 @@ public class TileEntityPanel extends TileEntityIWBase implements IDirectionalTil
@Override
@Nonnull
public ItemStack getTileDrop(@Nonnull EntityPlayer player, @Nonnull IBlockState state) {
public ItemStack getTileDrop(@Nullable EntityPlayer player, @Nonnull IBlockState state) {
NBTTagCompound ret = new NBTTagCompound();
writeToItemNBT(ret, true);
ItemStack retStack = new ItemStack(IndustrialWires.panel, 1, BlockTypes_Panel.TOP.ordinal());

View file

@ -18,15 +18,21 @@ package malte0811.industrialWires.blocks.converter;
import blusunrize.immersiveengineering.api.IEProperties;
import malte0811.industrialWires.blocks.BlockIWMultiblock;
import malte0811.industrialWires.blocks.IMetaEnum;
import malte0811.industrialWires.blocks.IWProperties;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.property.ExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -50,6 +56,25 @@ public class BlockMechanicalMB extends BlockIWMultiblock implements IMetaEnum {
};
}
@Nonnull
@Override
protected BlockStateContainer createBlockState() {
BlockStateContainer base = super.createBlockState();
return new ExtendedBlockState(this, base.getProperties().toArray(new IProperty[0]), new IUnlistedProperty[]{
IWProperties.MB_SIDES
});
}
@Nonnull
@Override
public IBlockState getExtendedState(@Nonnull IBlockState state, IBlockAccess world, BlockPos pos) {
TileEntity te = world.getTileEntity(pos);
state = super.getExtendedState(state, world, pos);
if (te instanceof TileEntityMechMB)
state = ((TileEntityMechMB) te).getExtState(state);
return state;
}
@Override
public boolean hasTileEntity(IBlockState state) {
return true;

View file

@ -83,7 +83,6 @@ public class TileEntityMechMB extends TileEntityIWMultiblock implements ITickabl
public double angle;
@SideOnly(Side.CLIENT)
public List<BakedQuad> rotatingModel;
private boolean shouldInitWorld;
private boolean firstTick = true;
// To allow changing the MB structure later on without resulting in dupes/conversion
private int structureVersion = 0;
@ -227,6 +226,17 @@ public class TileEntityMechMB extends TileEntityIWMultiblock implements ITickabl
}
}
public IBlockState getExtState(IBlockState in) {//TODO make this work with multithreading
Vec3i offsetDirectional = getOffsetDir();
TileEntityMechMB master = masterOr(this, this);
int id = getPart(offsetDirectional.getZ(), master);
if (id < 0) {
return in;
}
MechMBPart part = master.mechanical[id];
return part.getExtState(in);
}
//return value is maximized to choose the waveform to use
private double transferElectric(int[] section, double[] available, Waveform[] availableWf, Waveform waveform,
double[] requested, boolean simulate) {
@ -240,19 +250,37 @@ public class TileEntityMechMB extends TileEntityIWMultiblock implements ITickabl
}
totalRequested += requested[i];
}
double extractFactor = Math.min(1, totalRequested / totalAvailable);
double insertFactor = Math.min(1, totalAvailable / totalRequested);
double totalTransf = 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 ins = requested[i0] * insertFactor;
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.insertEEnergy(ins, waveform, energyState);
electric.extractEEnergy(extr);
}
totalTransf += Math.abs(ins - extr);
}
if (!simulate) {
for (int i = section[0]; i < section[1]; i++) {
int i0 = i - section[0];
IMBPartElectric electric = (IMBPartElectric) mechanical[i];
electric.insertEEnergy(ins[i0], waveform, energyState);
}
}
double totalTransf = 0;
for (int i = 0; i < section[1] - section[0]; i++) {
totalTransf += Math.abs(ins[i]-extracted[i]);
}
return totalTransf;
}
@ -284,9 +312,6 @@ public class TileEntityMechMB extends TileEntityIWMultiblock implements ITickabl
offset += mech[i].getLength();
}
setMechanical(mech, in.getDouble(SPEED));
if (world == null) {
shouldInitWorld = true;
}
}
structureVersion = in.getInteger(VERSION);
rBB = null;
@ -363,6 +388,7 @@ public class TileEntityMechMB extends TileEntityIWMultiblock implements ITickabl
}
@Override
@SideOnly(Side.CLIENT)
public void onSync(NBTTagCompound nbt) {
energyState.setTargetSpeed(nbt.getDouble(SPEED));
}
@ -577,13 +603,19 @@ public class TileEntityMechMB extends TileEntityIWMultiblock implements ITickabl
@Nonnull ItemStack heldItem, float hitX, float hitY, float hitZ) {
TileEntityMechMB master = masterOr(this, this);
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);
if (id >= 0) {
MechMBPart part = master.mechanical[id];
side = part.world.realToTransformed(side);
if (part.interact(side, getOffsetDir().add(0, 0, - master.offsets[id]),
player, hand, heldItem)) {
master.triggerRenderUpdate();
return true;
}
}
return false;
}
private Vec3i getOffsetDir() {
private BlockPos getOffsetDir() {
BlockPos offset = getOffset(BlockPos.NULL_VECTOR, facing, mirrored, this.offset);
return new BlockPos(offset.getX(), offset.getZ(), offset.getY());
}

View file

@ -19,6 +19,7 @@ import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.BlockIWBase;
import malte0811.industrialWires.blocks.IMetaEnum;
import malte0811.industrialWires.wires.IC2Wiretype;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyEnum;
@ -37,6 +38,8 @@ import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.property.ExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -55,7 +58,7 @@ public class BlockIC2Connector extends BlockIWBase implements IMetaEnum {
}
@Override
public void onNeighborChange(IBlockAccess world, BlockPos pos, BlockPos posNeighbor) {
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos) {
TileEntity te = world.getTileEntity(pos);
if (te instanceof TileEntityIC2ConnectorTin) {
TileEntityIC2ConnectorTin connector = (TileEntityIC2ConnectorTin) te;
@ -150,6 +153,7 @@ public class BlockIC2Connector extends BlockIWBase implements IMetaEnum {
}
@Override
@SideOnly(Side.CLIENT)
public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag advanced) {
super.addInformation(stack, world, tooltip, advanced);
if (!stack.isEmpty() && stack.getMetadata() % 2 == 0) {

View file

@ -42,6 +42,7 @@ import malte0811.industrialWires.client.gui.GuiPanelCreator;
import malte0811.industrialWires.client.gui.GuiRSPanelConn;
import malte0811.industrialWires.client.gui.GuiRenameKey;
import malte0811.industrialWires.client.manual.TextSplitter;
import malte0811.industrialWires.client.multiblock_io_model.MBIOModelLoader;
import malte0811.industrialWires.client.panelmodel.PanelModelLoader;
import malte0811.industrialWires.client.render.*;
import malte0811.industrialWires.controlpanel.PanelComponent;
@ -132,6 +133,7 @@ public class ClientProxy extends CommonProxy {
OBJLoader.INSTANCE.addDomain(IndustrialWires.MODID);
ModelLoaderRegistry.registerLoader(new PanelModelLoader());
ModelLoaderRegistry.registerLoader(new MBIOModelLoader());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityJacobsLadder.class, new TileRenderJacobsLadder());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMarx.class, new TileRenderMarx());
TileRenderMechMB tesr = new TileRenderMechMB();
@ -487,6 +489,11 @@ public class ClientProxy extends CommonProxy {
}
}
@Override
public boolean isSingleplayer() {
return Minecraft.getMinecraft().isSingleplayer();
}
@Override
public Gui getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
if (ID == 0) {

View file

@ -0,0 +1,181 @@
/*
* 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.client.multiblock_io_model;
import blusunrize.immersiveengineering.api.IEEnums.SideConfig;
import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableList;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.IWProperties;
import malte0811.industrialWires.client.ClientUtilsIW;
import malte0811.industrialWires.client.RawQuad;
import malte0811.industrialWires.util.MBSideConfig;
import malte0811.industrialWires.util.MBSideConfig.BlockFace;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemOverrideList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.util.vector.Vector3f;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@SideOnly(Side.CLIENT)
public class BakedMBIOModel implements IBakedModel {
private static final MBSideConfig NULL_CONFIG = new MBSideConfig(ImmutableList.of(new BlockFace(new BlockPos(0, 2, 0), EnumFacing.DOWN)));
private static final Matrix4 ID = new Matrix4();
static final ResourceLocation IO_LOC = new ResourceLocation(IndustrialWires.MODID, "blocks/io");
static TextureAtlasSprite IO_TEX = null;
private final IBakedModel base;
private final int rotationInt;
private final Rotation rotation;
private final Cache<MBSideConfig, List<BakedQuad>> cache = CacheBuilder.newBuilder().expireAfterAccess(1, TimeUnit.MINUTES)
.maximumSize(100).build();
BakedMBIOModel(IBakedModel base, int rotationOffset) {
this.base = base;
this.rotationInt = rotationOffset;
this.rotation = Rotation.values()[rotationOffset];
}
@Nonnull
@Override
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
MBSideConfig config = NULL_CONFIG;
if (state instanceof IExtendedBlockState) {
MBSideConfig tmpConfig = ((IExtendedBlockState) state).getValue(IWProperties.MB_SIDES);
if (tmpConfig!=null) {
config = tmpConfig;
}
}
List<BakedQuad> ret = cache.getIfPresent(config);
if (ret==null) {
if (IO_TEX==null) {
IO_TEX = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(IO_LOC.toString());
}
ret = new ArrayList<>(base.getQuads(state, side, rand));
for (Map.Entry<BlockFace, SideConfig> f:config.sides.entrySet()) {
if (f.getKey().face==null) {
continue;
}
BlockPos transformedPos = f.getKey().offset.rotate(rotation);
EnumFacing transformedFace = f.getKey().face;
if (transformedFace.getAxis()!=EnumFacing.Axis.Y) {
for (int i = 0; i < rotationInt; i++) {
transformedFace = transformedFace.rotateY();
}
}
Vector3f[] verts = getVerticesFromFace(transformedPos, transformedFace);
RawQuad q = new RawQuad(verts[0], verts[1], verts[2], verts[3], transformedFace,
IO_TEX, new float[]{1, 1, 1, 1}, getNormal(transformedFace),
getUVsForConfig(f.getValue()));
ret.add(ClientUtilsIW.bakeQuad(q, ID, ID));
}
ret = ImmutableList.copyOf(ret);
cache.put(config.copy(), ret);
}
return ret;
}
private static final Vector3f[] NORMALS = new Vector3f[6];
private static final Vector3f[][] VERTICES = new Vector3f[6][4];
static {
float[] vec = new float[3];
for (int i = 0; i < EnumFacing.VALUES.length; i++) {
EnumFacing f = EnumFacing.VALUES[i];
NORMALS[i] = new Vector3f(f.getFrontOffsetX(), f.getFrontOffsetY(), f.getFrontOffsetZ());
int axis = f.getAxis().ordinal();
vec[axis] = f.getAxisDirection()==EnumFacing.AxisDirection.POSITIVE?1.001F:-.001F;
float x1 = f.getAxisDirection()==EnumFacing.AxisDirection.POSITIVE?.625F:.375F;
for (int j = 0;j<4;j++) {
vec[(axis+1)%3] = 0<j&&j<3?x1:1-x1;
vec[(axis+2)%3] = j<2?.375F:.625F;
VERTICES[i][j] = vecFromArray(vec);
}
}
}
private static Vector3f vecFromArray(float[] in) {
return new Vector3f(in[0], in[1], in[2]);
}
private Vector3f[] getVerticesFromFace(BlockPos p, EnumFacing f) {
Vector3f[] orig = VERTICES[f.ordinal()];
Vector3f[] ret = new Vector3f[4];
Vector3f offset = new Vector3f(p.getX(), p.getY(), p.getZ());
for (int i = 0; i < 4; i++) {
ret[i] = Vector3f.add(orig[i], offset, null);
}
return ret;
}
private float[] getUVsForConfig(SideConfig sc) {
return new float[]{sc.ordinal()*4, 0, (sc.ordinal()+1)*4, 4};
}
private Vector3f getNormal(EnumFacing face) {
return NORMALS[face.ordinal()];
}
@Override
public boolean isAmbientOcclusion() {
return base.isAmbientOcclusion();
}
@Override
public boolean isGui3d() {
return base.isGui3d();
}
@Override
public boolean isBuiltInRenderer() {
return base.isBuiltInRenderer();
}
@Nonnull
@Override
public TextureAtlasSprite getParticleTexture() {
return base.getParticleTexture();
}
@Nonnull
@Override
public ItemOverrideList getOverrides() {
return base.getOverrides();
}
public void clearCache() {
cache.invalidateAll();
}
}

View file

@ -0,0 +1,121 @@
/*
* 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.client.multiblock_io_model;
import blusunrize.immersiveengineering.api.IEApi;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import malte0811.industrialWires.IndustrialWires;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.ICustomModelLoader;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.common.model.IModelState;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Function;
import static net.minecraftforge.fml.relauncher.Side.CLIENT;
@SideOnly(CLIENT)
public class MBIOModelLoader implements ICustomModelLoader {
private static final Set<BakedMBIOModel> activeModels = new HashSet<>();
static {
IEApi.renderCacheClearers.add(()-> {
for (BakedMBIOModel m:activeModels) {
m.clearCache();
}
});
}
@Override
public boolean accepts(@Nonnull ResourceLocation modelLocation) {
return IndustrialWires.MODID.equals(modelLocation.getResourceDomain())
&& "models/block/mbio".equals(modelLocation.getResourcePath());
}
@Nonnull
@Override
public IModel loadModel(@Nonnull ResourceLocation modelLocation) throws Exception {
return new MBIOModel();
}
@Override
public void onResourceManagerReload(@Nonnull IResourceManager resourceManager) {
activeModels.clear();
BakedMBIOModel.IO_TEX = null;
}
@SideOnly(CLIENT)
private static class MBIOModel implements IModel {
private static final Collection<ResourceLocation> TEXTURES = ImmutableList.of(
BakedMBIOModel.IO_LOC
);
private ResourceLocation baseModel = new ResourceLocation(IndustrialWires.MODID, "missing");
private ImmutableMap<String, String> custom = ImmutableMap.of();
private int rotationOffset = 0;
@Nonnull
@Override
public Collection<ResourceLocation> getDependencies() {
return ImmutableList.of(baseModel);
}
@Nonnull
@Override
public Collection<ResourceLocation> getTextures() {
return TEXTURES;
}
@Nonnull
@Override
public IBakedModel bake(@Nonnull IModelState state, @Nonnull VertexFormat format,
@Nonnull Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) {
try {
IModel baseBaked = ModelLoaderRegistry.getModel(baseModel);
baseBaked = baseBaked.process(custom);
IBakedModel baked = baseBaked.bake(state, format, bakedTextureGetter);
BakedMBIOModel ret = new BakedMBIOModel(baked, rotationOffset);
activeModels.add(ret);
return ret;
} catch (Exception e) {
e.printStackTrace();
}
return ModelLoaderRegistry.getMissingModel().bake(state, format, bakedTextureGetter);
}
@Nonnull
@Override
public IModel process(ImmutableMap<String, String> customData) {
MBIOModel ret = new MBIOModel();
String bm = customData.get("base_model");
ret.baseModel = new ResourceLocation(bm.substring(1, bm.length()-1));
String rotOffsetTmp = customData.get("rotation_offset");
if (rotOffsetTmp!=null) {
ret.rotationOffset = Integer.parseInt(rotOffsetTmp)&3;
}
ret.custom = customData;
return ret;
}
}
}

View file

@ -17,8 +17,6 @@ package malte0811.industrialWires.mech_mb;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public final class MechEnergy {
private double speed = 0;
@ -66,14 +64,12 @@ public final class MechEnergy {
private int ticksTillReached = -1;
//ONLY USE FOR SYNCING
@SideOnly(Side.CLIENT)
public void setTargetSpeed(double speed) {
targetSpeed = speed;
oldSpeed = getSpeed();
ticksTillReached = TICKS_FOR_ADJUSTMENT;
}
@SideOnly(Side.CLIENT)
public boolean clientUpdate() {
if (ticksTillReached >= 0) {
speed = ((TICKS_FOR_ADJUSTMENT - ticksTillReached) * targetSpeed +

View file

@ -32,19 +32,23 @@ import malte0811.industrialWires.util.MiscUtils;
import malte0811.industrialWires.util.MultiblockTemplateManual;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
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.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@ -74,6 +78,10 @@ public abstract class MechMBPart {
public abstract void writeToNBT(NBTTagCompound out);
public abstract void readFromNBT(NBTTagCompound in);
public IBlockState getExtState(IBlockState in) {
return in;
}
@SideOnly(Side.CLIENT)
public List<BakedQuad> getRotatingQuads() {
return TileRenderMechMB.BASE_MODELS.get(getRotatingBaseModel())
@ -120,6 +128,11 @@ public abstract class MechMBPart {
return null;
}
public boolean interact(@Nonnull EnumFacing side, @Nonnull Vec3i offset, @Nonnull EntityPlayer player,
@Nonnull EnumHand hand, @Nonnull ItemStack heldItem) {
return false;
}
public static final BiMap<String, Class<? extends MechMBPart>> REGISTRY = HashBiMap.create();
public static final String SHAFT_KEY = "shaft";

View file

@ -15,22 +15,20 @@
package malte0811.industrialWires.mech_mb;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableList;
import malte0811.industrialWires.IWConfig;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.converter.MechanicalMBBlockType;
import malte0811.industrialWires.util.LocalSidedWorld;
import malte0811.industrialWires.util.MBSideConfig.BlockFace;
import net.minecraft.item.ItemStack;
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.AxisAlignedBB;
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 java.util.List;
import static net.minecraft.util.EnumFacing.UP;
import static net.minecraft.util.math.BlockPos.ORIGIN;
@ -113,10 +111,10 @@ public class MechPartCommutator extends MechPartEnergyIO {
return false;
}
private static final ImmutableSet<Pair<BlockPos, EnumFacing>> outputs = ImmutableSet.of(
new ImmutablePair<>(ORIGIN, UP), new ImmutablePair<>(ORIGIN, null)
private static final List<BlockFace> outputs = ImmutableList.of(
new BlockFace(ORIGIN, UP)
);
public Set<Pair<BlockPos, EnumFacing>> getEnergyConnections() {
public List<BlockFace> getEnergyConnections() {
return outputs;
}

View file

@ -15,21 +15,19 @@
package malte0811.industrialWires.mech_mb;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableList;
import malte0811.industrialWires.IWConfig;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.converter.MechanicalMBBlockType;
import malte0811.industrialWires.util.LocalSidedWorld;
import malte0811.industrialWires.util.MBSideConfig.BlockFace;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
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 java.util.List;
import static net.minecraft.util.EnumFacing.EAST;
import static net.minecraft.util.EnumFacing.WEST;
@ -79,14 +77,14 @@ public class MechPartCommutator4Phase extends MechPartCommutator {
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, 0, 0), null),
new ImmutablePair<>(new BlockPos(1, -1, 0), EAST), new ImmutablePair<>(new BlockPos(1, -1, 0), null),
new ImmutablePair<>(new BlockPos(-1, 0, 0), WEST), new ImmutablePair<>(new BlockPos(-1, 0, 0), null),
new ImmutablePair<>(new BlockPos(-1, -1, 0), WEST), new ImmutablePair<>(new BlockPos(-1, -1, 0), null)
private static final List<BlockFace> outputs = ImmutableList.of(
new BlockFace(new BlockPos(1, 0, 0), EAST),
new BlockFace(new BlockPos(1, -1, 0), EAST),
new BlockFace(new BlockPos(-1, 0, 0), WEST),
new BlockFace(new BlockPos(-1, -1, 0), WEST)
);
@Override
public Set<Pair<BlockPos, EnumFacing>> getEnergyConnections() {
public List<BlockFace> getEnergyConnections() {
return outputs;
}

View file

@ -15,23 +15,35 @@
package malte0811.industrialWires.mech_mb;
import blusunrize.immersiveengineering.api.IEEnums.SideConfig;
import blusunrize.immersiveengineering.common.util.Utils;
import malte0811.industrialWires.IWConfig;
import malte0811.industrialWires.blocks.IWProperties;
import malte0811.industrialWires.mech_mb.EUCapability.IC2EnergyHandler;
import malte0811.industrialWires.util.ConversionUtil;
import malte0811.industrialWires.util.MBSideConfig;
import malte0811.industrialWires.util.MBSideConfig.BlockFace;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.util.Constants;
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 javax.annotation.Nonnull;
import java.util.List;
import static blusunrize.immersiveengineering.api.IEEnums.SideConfig.INPUT;
import static blusunrize.immersiveengineering.api.IEEnums.SideConfig.OUTPUT;
import static malte0811.industrialWires.mech_mb.EUCapability.ENERGY_IC2;
import static malte0811.industrialWires.mech_mb.MechPartEnergyIO.IOState.*;
import static malte0811.industrialWires.mech_mb.Waveform.Phases.get;
import static malte0811.industrialWires.mech_mb.Waveform.Speed.EXTERNAL;
import static malte0811.industrialWires.mech_mb.Waveform.Speed.ROTATION;
@ -45,10 +57,9 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
private Waveform wfToMB = Waveform.forParameters(NONE, get(has4Phases()), ROTATION);
private double bufferToWorld;
private Waveform wfToWorld = Waveform.forParameters(NONE, get(has4Phases()), ROTATION);
private final IEnergyStorage capForge = new EnergyStorageMMB();
private final IC2EnergyHandler capIc2 = new IC2EHandlerMB();
private IOState lastIOState = NO_TRANSFER;
private long lastStateChange = Long.MIN_VALUE;
private final IEnergyStorage[] capForge = {new EnergyStorageMMB(INPUT), new EnergyStorageMMB(OUTPUT)};
private final IC2EnergyHandler[] capIc2 = {new IC2EHandlerMB(INPUT), new IC2EHandlerMB(OUTPUT)};
private MBSideConfig sides = new MBSideConfig(getEnergyConnections());
@Override
public Waveform getProduced(MechEnergy state) {
@ -84,25 +95,16 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
bufferToWorld += given;
}
public void setLastIOState(IOState state) {
if (lastIOState.canSwitchTo(state)) {
lastIOState = state;
lastStateChange = world.getWorld().getTotalWorldTime();
}
}
public IOState getLastIOState() {
return lastIOState;
}
@Override
public <T> T getCapability(Capability<T> cap, EnumFacing side, BlockPos pos) {
if (getEnergyConnections().contains(new ImmutablePair<>(pos, side))) {
BlockFace s = new BlockFace(pos, side);
SideConfig conf = sides.getConfigForFace(s);
if (conf!=SideConfig.NONE) {
if (cap == ENERGY_IC2) {
return ENERGY_IC2.cast(capIc2);
return ENERGY_IC2.cast(capIc2[conf.ordinal()-1]);
}
if (cap == ENERGY) {
return ENERGY.cast(capForge);
return ENERGY.cast(capForge[conf.ordinal()-1]);
}
}
return super.getCapability(cap, side, pos);
@ -110,7 +112,7 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
@Override
public <T> boolean hasCapability(Capability<T> cap, EnumFacing side, BlockPos pos) {
if (getEnergyConnections().contains(new ImmutablePair<>(pos, side))) {
if (sides.getConfigForFace(new BlockFace(pos, side))!=SideConfig.NONE) {
if (cap == ENERGY_IC2) {
return true;
}
@ -131,9 +133,6 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
@Override
public void insertMEnergy(double added) {
if (world.getWorld().getTotalWorldTime()>lastStateChange+1) {
setLastIOState(NO_TRANSFER);
}
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
@ -157,6 +156,7 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
out.setDouble(BUFFER_OUT, bufferToWorld);
out.setString(BUFFER_IN+WAVEFORM, wfToMB.serializeToString());
out.setString(BUFFER_OUT+WAVEFORM, wfToWorld.serializeToString());
out.setTag(SIDE_CONFIG, sides.toNBT(getEnergyConnections()));
}
@Override
@ -165,24 +165,48 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
bufferToWorld = in.getDouble(BUFFER_OUT);
wfToMB = Waveform.fromString(in.getString(BUFFER_IN+WAVEFORM));
wfToWorld = Waveform.fromString(in.getString(BUFFER_OUT+WAVEFORM));
sides = new MBSideConfig(getEnergyConnections(), in.getTagList(SIDE_CONFIG, Constants.NBT.TAG_INT));
}
@Override
public boolean interact(@Nonnull EnumFacing side, @Nonnull Vec3i offset, @Nonnull EntityPlayer player,
@Nonnull EnumHand hand, @Nonnull ItemStack heldItem) {
if (Utils.isHammer(heldItem)) {
BlockFace s = new BlockFace(new BlockPos(offset), side);
if (sides.isValid(s)) {
if (!world.isRemote) {
sides.cycleSide(s);
world.markForUpdate(BlockPos.ORIGIN);
}
return true;
}
}
return false;
}
@Override
public IBlockState getExtState(IBlockState in) {
in = super.getExtState(in);
if (in instanceof IExtendedBlockState) {
in = ((IExtendedBlockState) in).withProperty(IWProperties.MB_SIDES, sides);
}
return in;
}
protected abstract double getMaxBuffer();
protected abstract boolean has4Phases();
public abstract Set<Pair<BlockPos, EnumFacing>> getEnergyConnections();
public abstract List<BlockFace> getEnergyConnections();
private double outputFE(int available) {
if (!getLastIOState().canSwitchToOutput())
return 0;
double extracted = 0;
for (Pair<BlockPos, EnumFacing> output : getEnergyConnections()) {
if (output.getRight()==null)
for (BlockFace output : getEnergyConnections()) {
if (output.face==null||sides.getConfigForFace(output)!=OUTPUT)
continue;
BlockPos outTE = output.getLeft().offset(output.getRight());
BlockPos outTE = output.offset.offset(output.face);
TileEntity te = world.getTileEntity(outTE);
EnumFacing sideReal = world.transformedToReal(output.getRight()).getOpposite();
EnumFacing sideReal = world.transformedToReal(output.face).getOpposite();
if (te != null && te.hasCapability(CapabilityEnergy.ENERGY, sideReal)) {
IEnergyStorage energy = te.getCapability(CapabilityEnergy.ENERGY, sideReal);
if (energy != null && energy.canReceive()) {
@ -192,17 +216,20 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
}
}
}
if (extracted>0) {
setLastIOState(IOState.OUTPUT);
}
return extracted;
}
class IC2EHandlerMB extends IC2EnergyHandler {
private SideConfig type;
{
tier = 3;//TODO does this mean everything blows up?
}
IC2EHandlerMB(SideConfig type) {
this.type = type;
}
@Override
public double injectEnergy(EnumFacing side, double amount, double voltage) {
double buffer = bufferToMB;
@ -214,24 +241,23 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
buffer += input;
bufferToMB = buffer;
wfToMB = Waveform.forParameters(DC, get(has4Phases()), EXTERNAL);
setLastIOState(INPUT);
return amount-ConversionUtil.euPerJoule()*input;
}
@Override
public double getOfferedEnergy() {
if (wfToWorld.isDC() && getLastIOState().canSwitchToOutput()) {
if (wfToWorld.isDC() && type==OUTPUT) {
return Math.min(ConversionUtil.euPerJoule()*bufferToWorld,
ConversionUtil.euPerJoule()*getMaxBuffer())/getEnergyConnections().size()*2;
ConversionUtil.euPerJoule()*getMaxBuffer())/getEnergyConnections().size();
}
return 0;
}
@Override
public double getDemandedEnergy() {
if (getLastIOState().canSwitchToInput()) {
if (type==INPUT) {
return Math.min(ConversionUtil.euPerJoule()*(getMaxBuffer()-bufferToMB),
ConversionUtil.euPerJoule()*getMaxBuffer())/getEnergyConnections().size()*2;
ConversionUtil.euPerJoule()*getMaxBuffer())/getEnergyConnections().size();
}
return 0;
}
@ -239,14 +265,19 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
@Override
public void drawEnergy(double amount) {
bufferToWorld -= ConversionUtil.joulesPerEu()*amount;
setLastIOState(OUTPUT);
}
};
}
class EnergyStorageMMB implements IEnergyStorage {
private SideConfig type;
EnergyStorageMMB(SideConfig type) {
this.type = type;
}
@Override
public int receiveEnergy(int maxReceive, boolean simulate) {
if (!getLastIOState().canSwitchToInput()) {
if (type!=INPUT) {
return 0;
}
double buffer = bufferToMB;
@ -259,16 +290,13 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
if (!simulate) {
bufferToMB = buffer;
wfToMB = Waveform.forParameters(Waveform.Type.AC, get(has4Phases()), EXTERNAL);
if (input > 0) {
setLastIOState(INPUT);
}
}
return (int) (ConversionUtil.ifPerJoule() * input);
}
@Override
public int extractEnergy(int maxExtract, boolean simulate) {
if (!wfToWorld.isAC() || !getLastIOState().canSwitchToOutput()) {
if (!wfToWorld.isAC() || type!=OUTPUT) {
return 0;
}
double buffer = bufferToWorld;
@ -277,9 +305,6 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
buffer -= output;
if (!simulate) {
bufferToWorld = buffer;
if (output > 0) {
setLastIOState(OUTPUT);
}
}
return (int) (ConversionUtil.ifPerJoule() * output);
}
@ -304,30 +329,4 @@ public abstract class MechPartEnergyIO extends MechMBPart implements IMBPartElec
return true;
}
}
enum IOState {
NO_TRANSFER,
OUTPUT,
INPUT;
boolean canSwitchToOutput() {
return NO_TRANSFER ==this||OUTPUT==this;
}
boolean canSwitchToInput() {
return NO_TRANSFER ==this||INPUT==this;
}
public boolean canSwitchTo(IOState state) {
switch (state) {
case NO_TRANSFER:
return true;
case OUTPUT:
return canSwitchToOutput();
case INPUT:
return canSwitchToInput();
}
return true;
}
}
}

View file

@ -15,21 +15,19 @@
package malte0811.industrialWires.mech_mb;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableList;
import malte0811.industrialWires.IWConfig;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.converter.MechanicalMBBlockType;
import malte0811.industrialWires.util.LocalSidedWorld;
import malte0811.industrialWires.util.MBSideConfig.BlockFace;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
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 java.util.List;
import static net.minecraft.util.EnumFacing.EAST;
import static net.minecraft.util.EnumFacing.WEST;
@ -64,14 +62,15 @@ public class MechPartFourElectrodes extends MechPartTwoElectrodes {
return 0b000_111_101;
}
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)
private static final List<BlockFace> outputs = ImmutableList.of(
new BlockFace(new BlockPos(1, 0, 0), EAST),
new BlockFace(new BlockPos(1, -1, 0), EAST),
new BlockFace(new BlockPos(-1, 0, 0), WEST),
new BlockFace(new BlockPos(-1, -1, 0), WEST)
);
@Override
public Set<Pair<BlockPos, EnumFacing>> getEnergyConnections() {
public List<BlockFace> getEnergyConnections() {
return outputs;
}

View file

@ -16,7 +16,6 @@
package malte0811.industrialWires.mech_mb;
import blusunrize.immersiveengineering.common.IEContent;
import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IPlayerInteraction;
import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IRedstoneOutput;
import blusunrize.immersiveengineering.common.items.ItemIETool;
import blusunrize.immersiveengineering.common.util.ChatUtils;
@ -35,6 +34,7 @@ import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraftforge.oredict.OreDictionary;
@ -49,7 +49,7 @@ import static net.minecraft.util.EnumFacing.Axis.X;
import static net.minecraft.util.EnumFacing.AxisDirection.POSITIVE;
import static net.minecraft.util.math.BlockPos.ORIGIN;
public class MechPartSpeedometer extends MechMBPart implements IPlayerInteraction, IRedstoneOutput {
public class MechPartSpeedometer extends MechMBPart implements IRedstoneOutput {
private double speedFor15RS = 2 * Waveform.EXTERNAL_SPEED;
private int currentOutputLin = -1;
private int currentOutputLog = -1;
@ -156,9 +156,9 @@ public class MechPartSpeedometer extends MechMBPart implements IPlayerInteractio
private static ItemStack voltMeter = ItemStack.EMPTY;
private static DecimalFormat format = new DecimalFormat("###.000");
@Override
public boolean interact(@Nonnull EnumFacing side, @Nonnull EntityPlayer player, @Nonnull EnumHand hand,
@Nonnull ItemStack heldItem, float hitX, float hitY, float hitZ) {
public boolean interact(@Nonnull EnumFacing side, @Nonnull Vec3i offset, @Nonnull EntityPlayer player, @Nonnull EnumHand hand, @Nonnull ItemStack heldItem) {
if (voltMeter.isEmpty()) {
voltMeter = new ItemStack(IEContent.itemTool, 1, ItemIETool.VOLTMETER_META);
}

View file

@ -15,20 +15,18 @@
package malte0811.industrialWires.mech_mb;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableList;
import malte0811.industrialWires.IWConfig;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.converter.MechanicalMBBlockType;
import malte0811.industrialWires.util.LocalSidedWorld;
import malte0811.industrialWires.util.MBSideConfig.BlockFace;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
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 java.util.List;
import static blusunrize.immersiveengineering.common.IEContent.blockMetalDecoration0;
import static blusunrize.immersiveengineering.common.blocks.metal.BlockTypes_MetalDecoration0.GENERATOR;
@ -71,10 +69,10 @@ public class MechPartTwoElectrodes extends MechPartEnergyIO {
return MechanicalMBBlockType.SHAFT_1_PHASE;
}
private static final ImmutableSet<Pair<BlockPos, EnumFacing>> outputs = ImmutableSet.of(
new ImmutablePair<>(ORIGIN, UP)
private static final List<BlockFace> outputs = ImmutableList.of(
new BlockFace(ORIGIN, UP)
);
public Set<Pair<BlockPos, EnumFacing>> getEnergyConnections() {
public List<BlockFace> getEnergyConnections() {
return outputs;
}

View file

@ -0,0 +1,139 @@
/*
* 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.util;
import blusunrize.immersiveengineering.api.IEEnums.SideConfig;
import com.google.common.collect.ImmutableList;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static blusunrize.immersiveengineering.api.IEEnums.SideConfig.*;
public class MBSideConfig {
private static final SideConfig[] CONFIG_VALUES = SideConfig.values();
public final Map<BlockFace, SideConfig> sides = new HashMap<>();
public MBSideConfig(List<BlockFace> sides) {
for (BlockFace side:sides) {
updateConfig(side, INPUT);
}
}
public MBSideConfig(List<BlockFace> sides, NBTTagList nbt) {
for (int i = 0; i < sides.size(); i++) {
BlockFace side = sides.get(i);
updateConfig(side, i<nbt.tagCount()?CONFIG_VALUES[nbt.getIntAt(i)]:INPUT);
}
}
public void updateConfig(BlockFace s, SideConfig state) {
sides.put(s, state);
}
public SideConfig getConfigForFace(BlockFace s) {
if (s.face==null) {
//Temporary solution, I hope
for (BlockFace f:sides.keySet()) {
if (f.offset.equals(s.offset)) {
return sides.get(f);
}
}
}
return sides.getOrDefault(s, NONE);
}
public void cycleSide(BlockFace s) {
updateConfig(s, next(getConfigForFace(s)));
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MBSideConfig that = (MBSideConfig) o;
return sides.equals(that.sides);
}
@Override
public int hashCode() {
return sides.hashCode();
}
@Override
public String toString() {
return sides.toString();
}
public boolean isValid(BlockFace s) {
return sides.containsKey(s);
}
public NBTTagList toNBT(List<BlockFace> order) {
NBTTagList ret = new NBTTagList();
for (BlockFace f:order) {
ret.appendTag(new NBTTagInt(getConfigForFace(f).ordinal()));
}
return ret;
}
public MBSideConfig copy() {
MBSideConfig ret = new MBSideConfig(ImmutableList.of());
ret.sides.putAll(sides);
return ret;
}
public static class BlockFace {
@Nonnull
public final BlockPos offset;
@Nullable
public final EnumFacing face;
public BlockFace(@Nonnull BlockPos offset, @Nullable EnumFacing face) {
this.offset = offset;
this.face = face;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BlockFace blockFace = (BlockFace) o;
if (!offset.equals(blockFace.offset)) return false;
return face == blockFace.face;
}
@Override
public int hashCode() {
int result = offset.hashCode();
result = 31 * result + (face != null ? face.hashCode() : 0);
return result;
}
}
}

View file

@ -26,7 +26,6 @@ import com.google.common.collect.ImmutableSet;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.hv.MultiblockMarx;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
@ -40,10 +39,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.util.vector.Vector3f;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.function.BiPredicate;
public final class MiscUtils {
@ -52,16 +48,16 @@ public final class MiscUtils {
public static List<BlockPos> discoverLocal(World w, BlockPos here, BiPredicate<BlockPos, Integer> isValid) {
List<BlockPos> ret = new ArrayList<>();
List<BlockPos> open = new ArrayList<>();
Queue<BlockPos> open = new ArrayDeque<>();
open.add(here);
while (!open.isEmpty()) {
BlockPos curr = open.get(0);
BlockPos curr = open.poll();
assert curr!=null;
ret.add(curr);
open.remove(0);
for (EnumFacing f : EnumFacing.VALUES) {
BlockPos next = curr.offset(f);
if (!open.contains(next) && !ret.contains(next) && isValid.test(next, ret.size())) {
open.add(next);
open.offer(next);
}
}
}
@ -199,7 +195,7 @@ public final class MiscUtils {
public static void loadConnsFromNBT(NBTTagCompound nbt, TileEntity te) {
World world = te.getWorld();
if (world != null && world.isRemote && !Minecraft.getMinecraft().isSingleplayer() && nbt != null) {
if (world != null && world.isRemote && !IndustrialWires.proxy.isSingleplayer() && nbt != null) {
NBTTagList connectionList = nbt.getTagList("connectionList", 10);
ImmersiveNetHandler.INSTANCE.clearConnectionsOriginatingFrom(Utils.toCC(te), world);
for (int i = 0; i < connectionList.tagCount(); i++) {

View file

@ -59,6 +59,7 @@ public final class NBTKeys {
public static final String AC = "Ac";
public static final String WAVEFORM = "Wf";
public static final String MAX_SPEED = "maxSpeed";
public static final String SIDE_CONFIG = "sideConfig";
private NBTKeys() {}

View file

@ -37,20 +37,36 @@
"coil_1_phase": {
"model": "industrialwires:mech_mb/mag_ring.obj"
},
"shaft_commutator": {
"model": "industrialwires:mech_mb/commutator.obj"
},
"shaft_1_phase": {
"model": "industrialwires:mech_mb/two_electrodes.obj"
},
"coil_4_phase": {
"model": "industrialwires:mech_mb/mag_ring.obj"
},
"shaft_commutator": {
"model": "industrialwires:mbio",
"custom": {
"base_model": "industrialwires:block/mech_mb/commutator.obj",
"rotation_offset": 3
}
},
"shaft_1_phase": {
"model": "industrialwires:mbio",
"custom": {
"base_model": "industrialwires:block/mech_mb/two_electrodes.obj",
"rotation_offset": 3
}
},
"shaft_commutator_4": {
"model": "industrialwires:mech_mb/commutator4.obj"
"model": "industrialwires:mbio",
"custom": {
"base_model": "industrialwires:block/mech_mb/commutator4.obj",
"rotation_offset": 3
}
},
"shaft_4_phase": {
"model": "industrialwires:mech_mb/four_electrodes.obj"
"model": "industrialwires:mbio",
"custom": {
"base_model": "industrialwires:block/mech_mb/four_electrodes.obj",
"rotation_offset": 3
}
},
"speedometer": {
"model": "industrialwires:mech_mb/speedometer.obj"