Mechanical MB's disassemble properly now

Started implementing mechanical failure (currently only for flywheels)
Changed the waveforms. This is supposed to be efficient!
This commit is contained in:
malte0811 2018-02-17 20:37:53 +01:00
parent 8d98e30b04
commit 23df4324ec
22 changed files with 876 additions and 326 deletions

View file

@ -32,6 +32,7 @@ package malte0811.industrialWires;
import malte0811.industrialWires.converter.MechMBPart;
import malte0811.industrialWires.converter.MultiblockConverter;
import malte0811.industrialWires.crafting.Recipes;
import malte0811.industrialWires.entities.EntityBrokenPart;
import malte0811.industrialWires.hv.MarxOreHandler;
import malte0811.industrialWires.hv.MultiblockMarx;
import malte0811.industrialWires.items.ItemIC2Coil;
@ -60,6 +61,7 @@ package malte0811.industrialWires;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.common.registry.EntityRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import org.apache.logging.log4j.Logger;
@ -169,6 +171,8 @@ public class IndustrialWires {
GameRegistry.registerTileEntity(TileEntityUnfinishedPanel.class, MODID + ":unfinished_panel");
GameRegistry.registerTileEntity(TileEntityComponentPanel.class, MODID + ":single_component_panel");
GameRegistry.registerTileEntity(TileEntityDischargeMeter.class, MODID + ":discharge_meter");
EntityRegistry.registerModEntity(new ResourceLocation(MODID, "broken_part"), EntityBrokenPart.class,
"broken_part", 0, this, 64, 1, true);
proxy.preInit();
Compat.preInit();

View file

@ -21,7 +21,6 @@ package malte0811.industrialWires.blocks;
import malte0811.industrialWires.util.MiscUtils;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;

View file

@ -8,7 +8,7 @@ public enum MechanicalMBBlockType implements IStringSerializable {
OTHER_END,
COIL_4_PHASE,
COIL_1_PHASE,
SHAFT_INSULATING,
SHAFT_BASIC,
SHAFT_4_PHASE,
SHAFT_1_PHASE,
SHAFT_COMMUTATOR,

View file

@ -1,18 +1,19 @@
package malte0811.industrialWires.blocks.converter;
import blusunrize.immersiveengineering.api.ApiUtils;
import blusunrize.immersiveengineering.common.IEContent;
import com.google.common.collect.ImmutableSet;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.ISyncReceiver;
import malte0811.industrialWires.blocks.TileEntityIWMultiblock;
import malte0811.industrialWires.converter.IMBPartElectric;
import malte0811.industrialWires.converter.IMBPartElectric.Waveform;
import malte0811.industrialWires.converter.MechEnergy;
import malte0811.industrialWires.converter.MechMBPart;
import malte0811.industrialWires.network.MessageTileSyncIW;
import malte0811.industrialWires.util.LocalSidedWorld;
import malte0811.industrialWires.util.MiscUtils;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumFacing;
@ -27,11 +28,13 @@ import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.*;
import static blusunrize.immersiveengineering.common.IEContent.blockMetalDecoration0;
import static blusunrize.immersiveengineering.common.blocks.metal.BlockTypes_MetalDecoration0.LIGHT_ENGINEERING;
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;
import static malte0811.industrialWires.util.NBTKeys.SPEED;
@ -66,7 +69,7 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
int offset = 1;
for (MechMBPart part:mechanical) {
part.world.setWorld(world);
part.world.setOrigin(MiscUtils.offset(pos, facing, mirrored, 0, -offset, 0));
part.world.setOrigin(offset(pos, facing, mirrored, 0, -offset, 0));
offset += part.getLength();
}
shouldInitWorld = false;
@ -88,42 +91,55 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
for (MechMBPart part:mechanical) {
part.insertMEnergy(factor*individualRequests.get(part));
}
//TODO proper failure!
Set<MechMBPart> failed = new HashSet<>();
for (MechMBPart part:mechanical) {
if (energyState.getSpeed()>part.getMaxSpeed()) {
energyState.setSpeed(0);//TODO
break;
failed.add(part);
}
}
if (!failed.isEmpty()) {
disassemble(failed);
return;
}
//Electrical
electricMain: for (int[] section:electricalStartEnd) {
Boolean ac = null;
for (int[] section:electricalStartEnd) {
double[] available = new double[section[1]-section[0]];
double totalAvailable = 0;
double[] availablePerWf = new double[Waveform.VALUES.length];
double[] requested = new double[section[1]-section[0]];
double totalRequested = 0;
for (int i = section[0];i<section[1];i++) {
IMBPartElectric electricalComp = ((IMBPartElectric)mechanical[i]);
if (ac==null) {
ac = electricalComp.getProduced().isAC;
} else {
Boolean acLocal = electricalComp.getProduced().isAC;
if (acLocal!=null&&acLocal!=ac) {
//TODO break things!
IndustrialWires.logger.info("This should break. Currently only breaks the loop, because NYI");
break electricMain;
}
IMBPartElectric electricalComp = ((IMBPartElectric) mechanical[i]);
Waveform localWf = electricalComp.getProduced();
if (localWf==NONE) {
continue;
}
if (localWf == AC_ASYNC&&Math.abs(energyState.getSpeed() - ASYNC_SPEED) >= SYNC_TOLERANCE * ASYNC_SPEED) {
localWf = AC_SYNC;
}
double availableLocal = electricalComp.getAvailableEEnergy();
availableLocal *= electricalComp.getProduced().efficiency;
totalAvailable += availableLocal;
available[i-section[0]] = availableLocal;
double requestedLocal = electricalComp.requestEEnergy();
totalRequested += requestedLocal;
requested[i-section[0]] = requestedLocal;
available[i - section[0]] = availableLocal;
availablePerWf[localWf.ordinal()] += availableLocal;
}
//TODO this isn't quite ideal. It's a lot better than before though
Waveform maxWf = NONE;
{
double max = 0;
for (int i = 0;i<availablePerWf.length;i++) {
if (availablePerWf[i]>max) {
maxWf = Waveform.VALUES[i];
max = availablePerWf[i];
}
}
}
for (int i = section[0];i<section[1];i++) {
IMBPartElectric electricalComp = ((IMBPartElectric) mechanical[i]);
double requestedLocal = electricalComp.requestEEnergy(maxWf);
totalRequested += requestedLocal;
requested[i - section[0]] = requestedLocal;
}
// this isn't ideal. It's a lot better than before though
if (totalAvailable>0&&totalRequested>0) {
for (int i = section[0]; i < section[1]; i++) {
IMBPartElectric electricalComp = ((IMBPartElectric) mechanical[i]);
@ -132,12 +148,12 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
double otherAvailable = totalAvailable-available[i0];
double ins = Math.min(requested[i0], otherAvailable);
double extractFactor = ins/otherAvailable;
electricalComp.insertEEnergy(ins);
electricalComp.insertEEnergy(ins, maxWf);
for (int j = section[0];j<section[1];j++) {
if (i!=j) {
IMBPartElectric compJ = (IMBPartElectric) mechanical[j];
double extractRaw = extractFactor * available[j - section[0]];
compJ.extractEEnergy(extractRaw/compJ.getProduced().efficiency);
compJ.extractEEnergy(extractRaw);
available[j-section[0]] -= extractFactor * available[j - section[0]];
}
}
@ -178,7 +194,7 @@ 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, MiscUtils.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, mirrored));
offset += mech[i].getLength();
}
setMechanical(mech, in.getDouble(SPEED));
@ -231,12 +247,12 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
@Nonnull
@Override
protected BlockPos getOrigin() {
return pos;//TODO
return pos;//Irrelevant, since this uses a custome disassembly method
}
@Override
public IBlockState getOriginalBlock() {
return IEContent.blockMetalDecoration0.getDefaultState();//TODO
return Blocks.AIR.getDefaultState();//Mostly irrelevant, since this uses a custome disassembly method
}
@Override
@ -252,8 +268,8 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
if (isLogicDummy()) {
rBB = new AxisAlignedBB(pos, pos);
} else {
rBB = new AxisAlignedBB(MiscUtils.offset(pos, facing, mirrored, -1, 0, -1),
MiscUtils.offset(pos, facing, mirrored, 2, mechanical.length, 2));
rBB = new AxisAlignedBB(offset(pos, facing, mirrored, -1, 0, -1),
offset(pos, facing, mirrored, 2, mechanical.length, 2));
}
}
return rBB;
@ -285,4 +301,52 @@ public class TileEntityMultiblockConverter extends TileEntityIWMultiblock implem
Vec3i offsetPart = new Vec3i(offsetDirectional.getX(), offsetDirectional.getY()-master.offsets[id], offsetDirectional.getZ());
return part.getCapability(capability, facing, offsetPart);
}
@Override
public void disassemble() {
if (formed) {
TileEntityMultiblockConverter master = master(this);
if (master!=null) {
boolean disassembled = false;
int part = master.getPart(offset.getX(), master);
if (part>=0) {
MechMBPart m = master.mechanical[part];
if (master.energyState.getSpeed()>.05*m.getMaxSpeed()) {
master.disassemble(ImmutableSet.of(m));
disassembled = true;
}
}
if (!disassembled)
master.disassemble(ImmutableSet.of());
}
}
}
private void disassemble(Set<MechMBPart> failed) {
if (!world.isRemote&&formed) {
formed = false;
world.setBlockState(pos,
blockMetalDecoration0.getDefaultState().withProperty(blockMetalDecoration0.property, LIGHT_ENGINEERING));
world.setBlockState(pos.down(),
blockMetalDecoration0.getDefaultState().withProperty(blockMetalDecoration0.property, LIGHT_ENGINEERING));
for (MechMBPart mech:mechanical) {
mech.disassemble(failed.contains(mech), energyState);
short pattern = mech.getFormPattern();
for (int i = 0;i<9;i++) {
if (((pattern>>i)&1)!=0) {
BlockPos pos = new BlockPos(i%3-1, i/3-1, 0);
if (mech.world.getBlockState(pos).getBlock()==IndustrialWires.mechanicalMB) {
mech.world.setBlockState(pos, Blocks.AIR.getDefaultState());
}
}
}
}
BlockPos otherEnd = offset(pos, facing.getOpposite(), mirrored, 0,
offsets[offsets.length-1]+mechanical[mechanical.length-1].getLength(), 0);
world.setBlockState(otherEnd,
blockMetalDecoration0.getDefaultState().withProperty(blockMetalDecoration0.property, LIGHT_ENGINEERING));
world.setBlockState(otherEnd.down(),
blockMetalDecoration0.getDefaultState().withProperty(blockMetalDecoration0.property, LIGHT_ENGINEERING));
}
}
}

View file

@ -43,12 +43,10 @@ import malte0811.industrialWires.client.gui.GuiRSPanelConn;
import malte0811.industrialWires.client.gui.GuiRenameKey;
import malte0811.industrialWires.client.manual.TextSplitter;
import malte0811.industrialWires.client.panelmodel.PanelModelLoader;
import malte0811.industrialWires.client.render.Shaders;
import malte0811.industrialWires.client.render.TileRenderJacobsLadder;
import malte0811.industrialWires.client.render.TileRenderMBConverter;
import malte0811.industrialWires.client.render.TileRenderMarx;
import malte0811.industrialWires.client.render.*;
import malte0811.industrialWires.controlpanel.PanelComponent;
import malte0811.industrialWires.crafting.IC2TRHelper;
import malte0811.industrialWires.entities.EntityBrokenPart;
import malte0811.industrialWires.hv.MarxOreHandler;
import malte0811.industrialWires.hv.MultiblockMarx;
import malte0811.industrialWires.items.ItemIC2Coil;
@ -76,6 +74,7 @@ import net.minecraftforge.client.ClientCommandHandler;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.obj.OBJLoader;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import java.util.Arrays;
import java.util.List;
@ -131,6 +130,8 @@ public class ClientProxy extends CommonProxy {
TileRenderMBConverter tesr = new TileRenderMBConverter();
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMultiblockConverter.class, tesr);
((IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager()).registerReloadListener(tesr);
RenderingRegistry.registerEntityRenderingHandler(EntityBrokenPart.class, EntityRenderBrokenPart::new);
Shaders.initShaders(true);
}

View file

@ -0,0 +1,64 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2017 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.render;
import blusunrize.immersiveengineering.client.ClientUtils;
import malte0811.industrialWires.entities.EntityBrokenPart;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import org.lwjgl.opengl.GL11;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class EntityRenderBrokenPart extends Render<EntityBrokenPart> {
public EntityRenderBrokenPart(RenderManager renderManager) {
super(renderManager);
}
@Override
public void doRender(@Nonnull EntityBrokenPart entity, double x, double y, double z, float entityYaw, float partialTicks) {
GlStateManager.pushMatrix();
AxisAlignedBB aabb = entity.getEntityBoundingBox();
ClientUtils.bindAtlas();
Tessellator tes = Tessellator.getInstance();
BufferBuilder bb = tes.getBuffer();
bb.setTranslation(x - entity.lastTickPosX, y - entity.lastTickPosY, z - entity.lastTickPosZ);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
bb.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
TextureAtlasSprite tex = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(entity.texture.toString());
ClientUtils.renderTexturedBox(bb, aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ,
tex.getMinU(), tex.getMinV(), tex.getInterpolatedU(8), tex.getInterpolatedV(8));
tes.draw();
bb.setTranslation(0, 0, 0);
GlStateManager.popMatrix();
super.doRender(entity, x, y, z, entityYaw, partialTicks);
}
@Nullable
@Override
protected ResourceLocation getEntityTexture(@Nonnull EntityBrokenPart entity) {
return entity.texture;
}
}

View file

@ -47,8 +47,7 @@ public class TileRenderMBConverter extends TileEntitySpecialRenderer<TileEntityM
public static final Set<TileEntityMultiblockConverter> TES_WITH_MODELS = Collections.newSetFromMap(new WeakHashMap<>());
@Override
public void render(TileEntityMultiblockConverter te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) {
if (BASE_MODELS.isEmpty())
{
if (BASE_MODELS.isEmpty()) {
for (MechMBPart type:MechMBPart.INSTANCES.values()) {
ResourceLocation loc = type.getRotatingBaseModel();
try {
@ -64,7 +63,8 @@ public class TileRenderMBConverter extends TileEntitySpecialRenderer<TileEntityM
}
}
if (te.mechanical!=null) {
if (te.rotatingModel == null) {
if (te.rotatingModel == null)
{
te.rotatingModel = new ArrayList<>();
int offset = 0;
for (MechMBPart part : te.mechanical) {

View file

@ -27,25 +27,35 @@ public interface IMBPartElectric {
// All four in Joules
double getAvailableEEnergy();
void extractEEnergy(double energy);
double requestEEnergy();
void insertEEnergy(double given);
double requestEEnergy(Waveform waveform);
void insertEEnergy(double given, Waveform waveform);
enum Waveform {
NONE(null, 0, 0),
AC(true, 1, 2),
PULSED_DC(false, 2/Math.PI, 1),
MULTI_AC(true, 1, 4),//"4-phase" AC, magically transported by a single wire
MULTI_AC_RECT(true, 2*Math.sqrt(2)/Math.PI, 6),
DC(false, 1, 6),
SQUARE(true, Math.PI/4, 5);
NONE(null, 0),
//Sync/async refers to multiblock rotation speed, not to line frequency
AC_SYNC(true, 3),
AC_ASYNC(true, 4) {
@Override
public Waveform getCommutated(double speed) {
if (Math.abs(speed-ASYNC_SPEED)<SYNC_TOLERANCE*ASYNC_SPEED) {
return DC;
}
return super.getCommutated(speed);
}
},
AC_4PHASE(true, 4),//TODO what should this rectify into? If anything at all
DC(false, 1),
MESS(null, 4);
public static final double ASYNC_SPEED = 10;//TODO is this a good value
public static final double SYNC_TOLERANCE = .1;//TODO is this a good value
public static final Waveform[] VALUES = values();
@Nullable
public Boolean isAC;
public double efficiency;
private Boolean isAC;
private int dualId;
public Waveform dual;
Waveform(@Nullable Boolean ac, double efficiency, int dualId) {
Waveform(@Nullable Boolean ac, int dualId) {
isAC = ac;
this.efficiency = efficiency;
this.dualId = dualId;
}
@ -55,5 +65,17 @@ public interface IMBPartElectric {
f.dual = values[f.dualId];
}
}
public Waveform getCommutated(double speed) {
return dual;
}
public boolean isAC() {
return isAC==Boolean.TRUE;
}
public boolean isDC() {
return isAC==Boolean.FALSE;
}
}
}

View file

@ -15,36 +15,45 @@
package malte0811.industrialWires.converter;
import blusunrize.immersiveengineering.ImmersiveEngineering;
import blusunrize.immersiveengineering.common.util.Utils;
import malte0811.industrialWires.util.LocalSidedWorld;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.oredict.OreDictionary;
public enum Material {
//TODO max speed
COPPER(8.96, 220),
ALUMINUM(2.7, 45),
LEAD(11.34, 12),
SILVER(10.49, 170),
NICKEL(8.908, 165),
GOLD(19.3, 100),
URANIUM(19.1, 400),// This is a bit silly. But why not.
CONSTANTAN(8.885, 600),
ELECTRUM((SILVER.density + GOLD.density) / 2, (SILVER.tensileStrength + GOLD.tensileStrength) / 2),//Tensile strength is a guess ((GOLD+SILVER)/2), if anyone has better data I'll put it in
STEEL(7.874, 1250),
IRON(7.874, 350),
DIAMOND(3.5, 2800);
COPPER(8.96, 220, "blocks/storage_copper"),
ALUMINUM(2.7, 45, "blocks/storage_aluminum"),
LEAD(11.34, 12, "blocks/storage_lead"),
SILVER(10.49, 170, "blocks/storage_silver"),
NICKEL(8.908, 165, "blocks/storage_nickel"),
GOLD(19.3, 100, new ResourceLocation("minecraft", "blocks/gold_block")),
URANIUM(19.1, 400, "blocks/storage_uranium"),// This is a bit silly. But why not.
CONSTANTAN(8.885, 600, "blocks/storage_constantan"),
ELECTRUM((SILVER.density + GOLD.density) / 2, (SILVER.tensileStrength + GOLD.tensileStrength) / 2, "blocks/storage_electrum"),//Tensile strength is a guess ((GOLD+SILVER)/2), if anyone has better data I'll put it in
STEEL(7.874, 1250, "blocks/storage_steel"),
IRON(7.874, 350, new ResourceLocation("minecraft", "blocks/iron_block")),
DIAMOND(3.5, 2800, new ResourceLocation("minecraft", "blocks/diamond_block"));
//in kg/m^3
public double density;
public double maxSpeed;
public double tensileStrength;
public final double density;
public final double tensileStrength;
public final ResourceLocation blockTexture;
// density as parameter: g/cm^3
// tStrength: MPa
Material(double density, double tensileStrength) {
// assumes that resource domain is IE
Material(double density, double tensileStrength, String path) {
this.density = density*1e3;
this.tensileStrength = tensileStrength*1e6;
this.blockTexture = new ResourceLocation(ImmersiveEngineering.MODID, path);
}
Material(double density, double tensileStrength, ResourceLocation loc) {
this.density = density*1e3;
this.tensileStrength = tensileStrength*1e6;
this.blockTexture = loc;
}
public boolean matchesBlock(ItemStack block, String prefix) {
@ -57,7 +66,7 @@ public enum Material {
return false;
}
private String oreName() {
public String oreName() {
return name().substring(0, 1)+name().substring(1).toLowerCase();
}

View file

@ -72,6 +72,12 @@ public abstract class MechMBPart {
public abstract short getFormPattern();
/**
* @param failed whether the MB is being disassembled because this part failed
* @param energy
*/
public abstract void disassemble(boolean failed, MechEnergy energy);
public abstract MechanicalMBBlockType getType();
public <T> boolean hasCapability(Capability<T> cap, EnumFacing side, Vec3i pos) {
@ -89,7 +95,8 @@ public abstract class MechMBPart {
REGISTRY.put("flywheel", MechPartFlywheel.class);
REGISTRY.put("singleCoil", MechPartSingleCoil.class);
//REGISTRY.put("twoElectrodes", MechPartTwoElectrodes.class);
REGISTRY.put("commutator", MechPartCommutator.class);
REGISTRY.put("commutator", MechPartTwoElectrodes.class);//TODO rename
REGISTRY.put("shaft", MechPartShaft.class);
for (String key : REGISTRY.keySet()) {
cacheNewInstance(key);
@ -128,7 +135,7 @@ public abstract class MechMBPart {
return nbt;
}
public static boolean isValidCenter(IBlockState state) {
public static boolean isValidDefaultCenter(IBlockState state) {
return state.getBlock()== IEContent.blockMetalDecoration0&&
state.getValue(IEContent.blockMetalDecoration0.property)==BlockTypes_MetalDecoration0.LIGHT_ENGINEERING;
}

View file

@ -1,191 +0,0 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2017 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 blusunrize.immersiveengineering.common.blocks.metal.BlockTypes_MetalDecoration0;
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 static blusunrize.immersiveengineering.common.IEContent.blockMetalDecoration0;
import static malte0811.industrialWires.util.ConversionUtil.ifPerJoule;
import static malte0811.industrialWires.util.ConversionUtil.joulesPerIf;
import static malte0811.industrialWires.util.NBTKeys.BUFFER_IN;
import static malte0811.industrialWires.util.NBTKeys.BUFFER_OUT;
public class MechPartCommutator extends MechMBPart implements IMBPartElectric {
private final static double MAX_BUFFER = 10e3;//200kW
double bufferToMB;
double bufferToWorld;
@Override
public Waveform getProduced() {
return bufferToMB>0?Waveform.SQUARE:Waveform.NONE;
}
@Override
public double getAvailableEEnergy() {
return bufferToMB;//TODO lower efficiency?
}
@Override
public void extractEEnergy(double energy) {
bufferToMB -= energy;
}
@Override
public double requestEEnergy() {
return MAX_BUFFER-bufferToWorld;
}
@Override
public void insertEEnergy(double given) {
bufferToWorld += given;
}
@Override
public void createMEnergy(MechEnergy e) {}
@Override
public double requestMEnergy(MechEnergy e) {
return 0;
}
@Override
public void insertMEnergy(double added) {
int available = (int) (ConversionUtil.ifPerJoule()*bufferToWorld);
if (available>0) {
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;
}
}
}
}
@Override
public double getInertia() {
return 50;//Random value. Does this work reasonably well?
}
@Override
public double getMaxSpeed() {
return Double.MAX_VALUE;//TODO
}
@Override
public void writeToNBT(NBTTagCompound out) {
out.setDouble(BUFFER_IN, bufferToMB);
out.setDouble(BUFFER_OUT, bufferToWorld);
}
@Override
public void readFromNBT(NBTTagCompound out) {
bufferToMB = out.getDouble(BUFFER_IN);
bufferToWorld = out.getDouble(BUFFER_OUT);
}
@Override
public ResourceLocation getRotatingBaseModel() {
return new ResourceLocation(IndustrialWires.MODID, "block/mech_mb/shaft.obj");//TODO texture
}
@Override
public boolean canForm(LocalSidedWorld w) {
IBlockState state = w.getBlockState(BlockPos.ORIGIN);
return state.getBlock()== blockMetalDecoration0 &&
state.getValue(blockMetalDecoration0.property)== BlockTypes_MetalDecoration0.GENERATOR;
}
@Override
public short getFormPattern() {
return 0b000_010_000;
}
@Override
public MechanicalMBBlockType getType() {
return MechanicalMBBlockType.SHAFT_COMMUTATOR;
}
private IEnergyStorage energy = new IEnergyStorage() {
@Override
public int receiveEnergy(int maxReceive, boolean simulate) {
double joules = joulesPerIf()*maxReceive;
double insert = Math.min(joules, MAX_BUFFER-bufferToMB);
if (!simulate)
bufferToMB += insert;
return (int) Math.ceil(insert* ifPerJoule());
}
@Override
public int extractEnergy(int maxExtract, boolean simulate) {
double joules = joulesPerIf()*maxExtract;
double extract = Math.min(joules, bufferToWorld);
if (!simulate)
bufferToWorld -= extract;
return (int) Math.floor(extract* ifPerJoule());
}
@Override
public int getEnergyStored() {
return (int) Math.round((bufferToMB+bufferToWorld)* ifPerJoule());
}
@Override
public int getMaxEnergyStored() {
return (int) Math.round(MAX_BUFFER*2* ifPerJoule());
}
@Override
public boolean canExtract() {
return true;
}
@Override
public boolean canReceive() {
return true;
}
};
@Override
public <T> boolean hasCapability(Capability<T> cap, EnumFacing side, Vec3i pos) {
if (pos.equals(BlockPos.ORIGIN)&&side==EnumFacing.UP&&cap== CapabilityEnergy.ENERGY)
return true;
return super.hasCapability(cap, side, pos);
}
@Override
public <T> T getCapability(Capability<T> cap, EnumFacing side, Vec3i pos) {
if (pos.equals(BlockPos.ORIGIN)&&side==EnumFacing.UP&&cap== CapabilityEnergy.ENERGY)
return CapabilityEnergy.ENERGY.cast(energy);
return super.getCapability(cap, side, pos);
}
}

View file

@ -15,16 +15,35 @@
package malte0811.industrialWires.converter;
import blusunrize.immersiveengineering.common.util.Utils;
import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.converter.MechanicalMBBlockType;
import malte0811.industrialWires.entities.EntityBrokenPart;
import malte0811.industrialWires.util.LocalSidedWorld;
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.BakedQuadRetextured;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
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;//TODO exact value from model?
private static final double THICKNESS = 1;
private static final double VOLUME = Math.PI*RADIUS*RADIUS*THICKNESS;
private Material material;
//A flywheel simply adds mass (lots of mass!), it doesn't actively change speeds/energy
@ -64,6 +83,13 @@ public class MechPartFlywheel extends MechMBPart {
return new ResourceLocation(IndustrialWires.MODID, "block/mech_mb/flywheel.obj");
}
@Override
public List<BakedQuad> getRotatingQuads() {
List<BakedQuad> orig = super.getRotatingQuads();
TextureAtlasSprite newTex = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(material.blockTexture.toString());
return orig.stream().map((quad)->new BakedQuadRetextured(quad, newTex)).collect(Collectors.toList());
}
@Override
public boolean canForm(LocalSidedWorld w) {
BlockPos.PooledMutableBlockPos pos = BlockPos.PooledMutableBlockPos.retain(-1, 1, 0);
@ -87,15 +113,51 @@ public class MechPartFlywheel extends MechMBPart {
}
}
pos.setPos(0, 0, 0);
if (!isValidCenter(w.getBlockState(pos))) {
return false;
}
return true;
return isValidDefaultCenter(w.getBlockState(pos));
} finally {
pos.release();
}
}
@Override
public void disassemble(boolean failed, MechEnergy energy) {
world.setBlockState(BlockPos.ORIGIN,
blockMetalDecoration0.getDefaultState().withProperty(blockMetalDecoration0.property, LIGHT_ENGINEERING));
IBlockState state = Blocks.AIR.getDefaultState();
if (!failed) {
for (ItemStack block: OreDictionary.getOres("block"+material.oreName())) {
if (block.getItem() instanceof ItemBlock) {
ItemBlock ib = (ItemBlock) block.getItem();
state = ib.getBlock().getStateFromMeta(block.getMetadata());
}
}
}
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
if (x != 0 || y != 0) {
world.setBlockState(new BlockPos(x, y, 0), state);
}
}
}
if (failed) {
Matrix4 mat = new Matrix4();
mat.rotate(Utils.RAND.nextDouble(), 0, 0, 1);
Vec3d baseVec = new Vec3d(0, 1.5, 0);
for (int i = 0;i<8;i++) {
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);
double speed = (energy.getSpeed()/getMaxSpeed())/1.5;
e.motionX = pos.y*speed;
e.motionY = -pos.x*speed;
e.motionZ = (Utils.RAND.nextDouble()-.5)*speed/10;
world.spawnEntity(e);
e.breakBlocks(speed*speed*1.5*1.5);
}
}
}
@Override
public short getFormPattern() {
return 0b111_111_111;

View file

@ -0,0 +1,99 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2017 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 blusunrize.immersiveengineering.common.util.IELogger;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.converter.MechanicalMBBlockType;
import malte0811.industrialWires.util.LocalSidedWorld;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import static blusunrize.immersiveengineering.common.IEContent.blockMetalDecoration0;
import static blusunrize.immersiveengineering.common.blocks.metal.BlockTypes_MetalDecoration0.LIGHT_ENGINEERING;
import static malte0811.industrialWires.blocks.converter.MechanicalMBBlockType.SHAFT_BASIC;
public class MechPartShaft extends MechMBPart {
@Override
public void createMEnergy(MechEnergy e) {}
@Override
public double requestMEnergy(MechEnergy e) {
return 0;
}
@Override
public void insertMEnergy(double added) {}
@Override
public double getInertia() {
return 5;//TODO
}
@Override
public double getMaxSpeed() {
return Double.MAX_VALUE;
}
@Override
public void writeToNBT(NBTTagCompound out) {}
@Override
public void readFromNBT(NBTTagCompound out) {}
@Override
public ResourceLocation getRotatingBaseModel() {
return new ResourceLocation(IndustrialWires.MODID, "block/mech_mb/shaft.obj");
}
@Override
public boolean canForm(LocalSidedWorld world) {
if (!isValidDefaultCenter(world.getBlockState(BlockPos.ORIGIN)))
return false;
BlockPos.PooledMutableBlockPos pos = BlockPos.PooledMutableBlockPos.retain(0, 0, 0);
for (int i = -1;i<=1;i++) {
for (int j = -1;j<=1;j++) {
if (j!=0||i!=0) {
pos.setPos(i, j, 0);
if (!world.isAir(pos)) {
pos.release();
return false;
}
}
}
}
pos.release();
return true;
}
@Override
public short getFormPattern() {
return 0b000_010_000;
}
@Override
public void disassemble(boolean failed, MechEnergy energy) {
IELogger.info(world.getOrigin());
world.setBlockState(BlockPos.ORIGIN,
blockMetalDecoration0.getDefaultState().withProperty(blockMetalDecoration0.property, LIGHT_ENGINEERING));
}
@Override
public MechanicalMBBlockType getType() {
return SHAFT_BASIC;
}
}

View file

@ -15,7 +15,6 @@
package malte0811.industrialWires.converter;
import blusunrize.immersiveengineering.common.IEContent;
import blusunrize.immersiveengineering.common.blocks.metal.BlockTypes_MetalDecoration0;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.converter.MechanicalMBBlockType;
@ -27,6 +26,9 @@ import net.minecraft.util.math.BlockPos;
import java.util.function.Predicate;
import static blusunrize.immersiveengineering.common.IEContent.blockMetalDecoration0;
import static blusunrize.immersiveengineering.common.blocks.metal.BlockTypes_MetalDecoration0.COIL_LV;
import static blusunrize.immersiveengineering.common.blocks.metal.BlockTypes_MetalDecoration0.LIGHT_ENGINEERING;
import static malte0811.industrialWires.util.NBTKeys.BUFFER_IN;
import static malte0811.industrialWires.util.NBTKeys.BUFFER_OUT;
@ -36,7 +38,7 @@ public class MechPartSingleCoil extends MechMBPart implements IMBPartElectric {
private double bufferToE;
@Override
public Waveform getProduced() {
return Waveform.AC;
return Waveform.AC_SYNC;
}
@Override
public double getAvailableEEnergy() {
@ -49,13 +51,17 @@ public class MechPartSingleCoil extends MechMBPart implements IMBPartElectric {
}
@Override
public double requestEEnergy() {
public double requestEEnergy(Waveform waveform) {
return MAX_BUFFER- bufferToMech;
}
@Override
public void insertEEnergy(double given) {
bufferToMech += given;
public void insertEEnergy(double given, Waveform waveform) {
if (waveform.isDC()) {
bufferToMech = 0;//TODO something more spectacular
} else {
bufferToMech += given;
}
}
@Override
@ -102,13 +108,13 @@ public class MechPartSingleCoil extends MechMBPart implements IMBPartElectric {
}
private static final Predicate<IBlockState> IS_COIL = (b)->
b.getBlock()== IEContent.blockMetalDecoration0&&
b.getValue(IEContent.blockMetalDecoration0.property)== BlockTypes_MetalDecoration0.COIL_LV;
b.getBlock()== blockMetalDecoration0&&
b.getValue(blockMetalDecoration0.property)== BlockTypes_MetalDecoration0.COIL_LV;
@Override
public boolean canForm(LocalSidedWorld w) {
BlockPos.PooledMutableBlockPos pos = BlockPos.PooledMutableBlockPos.retain(0, 0, 0);
try {
if (!isValidCenter(w.getBlockState(pos))) {
if (!isValidDefaultCenter(w.getBlockState(pos))) {
return false;
}
pos.setPos(0, 1, 0);
@ -139,6 +145,18 @@ public class MechPartSingleCoil extends MechMBPart implements IMBPartElectric {
return 0b111_111_111;
}
@Override
public void disassemble(boolean failed, MechEnergy energy) {
world.setBlockState(BlockPos.ORIGIN,
blockMetalDecoration0.getDefaultState().withProperty(blockMetalDecoration0.property, LIGHT_ENGINEERING));
if (!failed) {
for (int i = -1;i<=1;i+=2) {
world.setBlockState(BlockPos.ORIGIN.up(i),
blockMetalDecoration0.getDefaultState().withProperty(blockMetalDecoration0.property, COIL_LV));
}
}
}
@Override
public MechanicalMBBlockType getType() {
return MechanicalMBBlockType.COIL_1_PHASE;

View file

@ -15,42 +15,67 @@
package malte0811.industrialWires.converter;
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 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.util.ConversionUtil.ifPerJoule;
import static malte0811.industrialWires.util.ConversionUtil.joulesPerIf;
import static malte0811.industrialWires.util.NBTKeys.*;
public class MechPartTwoElectrodes extends MechMBPart implements IMBPartElectric {
private final static double MAX_BUFFER = 10e3;//200kW
private double bufferToMB;
private boolean isACInMBBuffer;
private double bufferToWorld;
private boolean isACInWBuffer;
@Override
public Waveform getProduced() {
return null;
return bufferToMB>0?(isACInMBBuffer? AC_ASYNC: DC): NONE;
}
@Override
public double getAvailableEEnergy() {
return 0;
return bufferToMB;
}
@Override
public void extractEEnergy(double energy) {
bufferToMB -= energy;
}
@Override
public double requestEEnergy() {
return 0;
public double requestEEnergy(Waveform waveform) {
return MAX_BUFFER-bufferToWorld;
}
@Override
public void insertEEnergy(double given) {
public void insertEEnergy(double given, Waveform waveform) {
if (bufferToWorld > 0 && (isACInWBuffer ^ waveform.isAC())) {
bufferToWorld = 0;
}
if (waveform.isAC() || waveform.isAC()) {
bufferToWorld += given;
isACInWBuffer = waveform.isAC();
}
}
@Override
public void createMEnergy(MechEnergy e) {
}
public void createMEnergy(MechEnergy e) {}
@Override
public double requestMEnergy(MechEnergy e) {
@ -59,46 +84,139 @@ 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;
}
}
}
}
@Override
public double getInertia() {
return 0;
return 50;//Random value. Does this work reasonably well?
}
@Override
public double getMaxSpeed() {
return 0;
return Double.MAX_VALUE;//TODO
}
@Override
public void writeToNBT(NBTTagCompound out) {
out.setDouble(BUFFER_IN, bufferToMB);
out.setBoolean(BUFFER_IN+AC, isACInMBBuffer);
out.setDouble(BUFFER_OUT, bufferToWorld);
out.setBoolean(BUFFER_OUT+AC, isACInWBuffer);
}
@Override
public void readFromNBT(NBTTagCompound out) {
bufferToMB = out.getDouble(BUFFER_IN);
isACInMBBuffer = out.getBoolean(BUFFER_IN+AC);
bufferToWorld = out.getDouble(BUFFER_OUT);
isACInWBuffer = out.getBoolean(BUFFER_OUT+AC);
}
@Override
public ResourceLocation getRotatingBaseModel() {
return null;
return new ResourceLocation(IndustrialWires.MODID, "block/mech_mb/shaft.obj");//TODO texture
}
@Override
public boolean canForm(LocalSidedWorld w) {
return false;
IBlockState state = w.getBlockState(BlockPos.ORIGIN);
return state.getBlock()== blockMetalDecoration0 &&
state.getValue(blockMetalDecoration0.property)== GENERATOR;
}
@Override
public short getFormPattern() {
return 0;
return 0b000_010_000;
}
@Override
public void disassemble(boolean failed, MechEnergy energy) {
world.setBlockState(BlockPos.ORIGIN,
blockMetalDecoration0.getDefaultState().withProperty(blockMetalDecoration0.property, GENERATOR));
}
@Override
public MechanicalMBBlockType getType() {
return null;
return MechanicalMBBlockType.SHAFT_COMMUTATOR;
}
private IEnergyStorage energy = new IEnergyStorage() {
@Override
public int receiveEnergy(int maxReceive, boolean simulate) {
double joules = joulesPerIf()*maxReceive;
double insert = Math.min(joules, MAX_BUFFER-bufferToMB);
if (!simulate) {
if (!isACInMBBuffer) {
bufferToMB = 0;
isACInMBBuffer = true;
}
bufferToMB += insert;
}
return (int) Math.ceil(insert* ifPerJoule());
}
@Override
public int extractEnergy(int maxExtract, boolean simulate) {
if (isACInWBuffer) {
double joules = joulesPerIf() * maxExtract;
double extract = Math.min(joules, bufferToWorld);
if (!simulate)
bufferToWorld -= extract;
return (int) Math.floor(extract * ifPerJoule());
} else {
return 0;
}
}
@Override
public int getEnergyStored() {
return (int) Math.round((bufferToMB+bufferToWorld)* ifPerJoule());
}
@Override
public int getMaxEnergyStored() {
return (int) Math.round(MAX_BUFFER*2* ifPerJoule());
}
@Override
public boolean canExtract() {
return true;
}
@Override
public boolean canReceive() {
return true;
}
};
@Override
public <T> boolean hasCapability(Capability<T> cap, EnumFacing side, Vec3i pos) {
if (pos.equals(BlockPos.ORIGIN)&&side==EnumFacing.UP) {
if (cap==CapabilityEnergy.ENERGY)
return true;
//TODO return true for internal IC2 cap that doesn't exist yet
}
return super.hasCapability(cap, side, pos);
}
@Override
public <T> T getCapability(Capability<T> cap, EnumFacing side, Vec3i pos) {
if (pos.equals(BlockPos.ORIGIN)&&side==EnumFacing.UP&&cap== CapabilityEnergy.ENERGY)
return CapabilityEnergy.ENERGY.cast(energy);
return super.getCapability(cap, side, pos);
}
}

View file

@ -22,7 +22,6 @@ import malte0811.industrialWires.blocks.converter.MechanicalMBBlockType;
import malte0811.industrialWires.blocks.converter.TileEntityMultiblockConverter;
import malte0811.industrialWires.util.LocalSidedWorld;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
@ -46,16 +45,16 @@ public class MultiblockConverter implements MultiblockHandler.IMultiblock {
@Override
public boolean isBlockTrigger(IBlockState state) {
return MechMBPart.isValidCenter(state);
return MechMBPart.isValidDefaultCenter(state);
}
private boolean checkEnd(LocalSidedWorld w, BlockPos.PooledMutableBlockPos p) {
p.setPos(0, 0, 0);
if (!MechMBPart.isValidCenter(w.getBlockState(p))) {
if (!MechMBPart.isValidDefaultCenter(w.getBlockState(p))) {
return false;
}
p.setPos(0, -1, 0);
return MechMBPart.isValidCenter(w.getBlockState(p));
return MechMBPart.isValidDefaultCenter(w.getBlockState(p));
}
private void formEnd(LocalSidedWorld w, BlockPos.PooledMutableBlockPos p, MechanicalMBBlockType type,
@ -78,7 +77,6 @@ public class MultiblockConverter implements MultiblockHandler.IMultiblock {
public boolean createStructure(World world, BlockPos pos, EnumFacing side, EntityPlayer player) {
boolean b = true;
BlockPos.PooledMutableBlockPos mutPos = BlockPos.PooledMutableBlockPos.retain();
Minecraft.getMinecraft().mouseHelper.ungrabMouseCursor();
try {
LocalSidedWorld w = new LocalSidedWorld(world, pos, side.getOpposite(), false);
if (!checkEnd(w, mutPos)) {
@ -126,20 +124,22 @@ public class MultiblockConverter implements MultiblockHandler.IMultiblock {
te.offset = new BlockPos(0, -1, 0);
}
te.facing = side;
te.formed = true;
});
lastLength = 1;
Consumer<TileEntityMultiblockConverter> init = (te)-> {
te.offset = te.getPos().subtract(pos);
te.facing = side;
te.formed = true;
};
for (MechMBPart part:parts) {
mutPos.setPos(0, 0, lastLength);
w = new LocalSidedWorld(world, w.getRealPos(mutPos), side.getOpposite(), false);
w = new LocalSidedWorld(world, w.getRealPos(mutPos), w.getFacing(), w.isMirrored());
part.form(w, init);
lastLength = part.getLength();
}
mutPos.setPos(0, 0, lastLength);
w.setOrigin(w.getRealPos(mutPos));
w = new LocalSidedWorld(w.getWorld(), w.getRealPos(mutPos), w.getFacing(), w.isMirrored());
formEnd(w, mutPos, OTHER_END, (te, __)->init.accept(te));
break;
} while (!b);

View file

@ -0,0 +1,204 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2017 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.entities;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.MoverType;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializer;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.List;
import static malte0811.industrialWires.util.NBTKeys.TEXTURE;
public class EntityBrokenPart extends EntityArrow {
public static final DataSerializer<ResourceLocation> RES_LOC_SERIALIZER = new DataSerializer<ResourceLocation>() {
@Override
public void write(@Nonnull PacketBuffer buf, @Nonnull ResourceLocation value) {
buf.writeString(value.getResourceDomain());
buf.writeString(value.getResourcePath());
}
@Nonnull
@Override
public ResourceLocation read(@Nonnull PacketBuffer buf) throws IOException {
String domain = buf.readString(128);
return new ResourceLocation(domain, buf.readString(1024));
}
@Nonnull
@Override
public DataParameter<ResourceLocation> createKey(int id) {
return new DataParameter<>(id, this);
}
@Nonnull
@Override
public ResourceLocation copyValue(@Nonnull ResourceLocation value) {
return new ResourceLocation(value.getResourceDomain(), value.getResourcePath());
}
};
private static DataParameter<ResourceLocation> MARKER_TEXTURE;
static {
DataSerializers.registerSerializer(RES_LOC_SERIALIZER);
MARKER_TEXTURE = EntityDataManager.createKey(EntityBrokenPart.class, RES_LOC_SERIALIZER);
}
private static final double HARDNESS_MAX = 15;
private static final double DESPAWN_DELAY = 400;
public ResourceLocation texture = new ResourceLocation("blocks/stone");
private int timeUnmoved = 0;
public EntityBrokenPart(World worldIn) {
super(worldIn);
setSize(.5F, .5F);
}
public EntityBrokenPart(World worldIn, ResourceLocation texture) {
this(worldIn);
this.texture = texture;
}
@Override
public void onUpdate() {
if (firstUpdate &&!world.isRemote && texture != null) {
dataManager.set(MARKER_TEXTURE, texture);
}
onEntityUpdate();
//movement logic, modified to simulate higher speed than MC is happy about
{
this.motionY -= 0.02;
this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ);
this.motionX *= 0.98;
this.motionY *= 0.98;
this.motionZ *= 0.98;
if (this.onGround) {
this.motionX *= .7;
this.motionZ *= .7;
this.motionY *= -0.5D;
}
}
if (world.isRemote) {
texture = dataManager.get(MARKER_TEXTURE);
return;
}
double speedSq = motionX * motionX + motionY * motionY + motionZ * motionZ;
breakBlocks(speedSq);
if (speedSq>.25) {
List<EntityLivingBase> entities = world.getEntitiesWithinAABB(EntityLivingBase.class, getEntityBoundingBox());
for (EntityLivingBase e:entities) {
e.attackEntityFrom(DamageSource.FALLING_BLOCK, 7);
}
}
if (speedSq<1e-3) {
timeUnmoved++;
if (timeUnmoved>DESPAWN_DELAY) {
setDead();
}
}
}
public void breakBlocks(double speedSq) {
AxisAlignedBB axisalignedbb = this.getEntityBoundingBox();
axisalignedbb = axisalignedbb.grow(motionX, motionY, motionZ);
BlockPos.PooledMutableBlockPos min = BlockPos.PooledMutableBlockPos.retain(axisalignedbb.minX - .1,
axisalignedbb.minY - .1, axisalignedbb.minZ - .1);
BlockPos.PooledMutableBlockPos max = BlockPos.PooledMutableBlockPos.retain(axisalignedbb.maxX + .1,
axisalignedbb.maxY + 0.1D, axisalignedbb.maxZ + .1);
BlockPos.PooledMutableBlockPos iter = BlockPos.PooledMutableBlockPos.retain();
double speed = -1;
if (this.world.isAreaLoaded(min, max)) {
for (int x = min.getX(); x <= max.getX(); ++x) {
for (int y = min.getY(); y <= max.getY(); ++y) {
for (int z = min.getZ(); z <= max.getZ(); ++z) {
iter.setPos(x, y, z);
if (!world.isAirBlock(iter)) {
IBlockState state = world.getBlockState(iter);
float hardness = state.getBlockHardness(world, iter);
if (speed < 0) {
speed = Math.sqrt(speedSq);
}
if (hardness>0&&hardness < HARDNESS_MAX*speed) {
world.setBlockToAir(iter);
double factor = (HARDNESS_MAX*speed - hardness) / (HARDNESS_MAX*speed);
motionX *= factor;
motionY *= factor;
motionZ *= factor;
speed *= factor;
} else {
motionX = 0;
motionY = 0;
motionZ = 0;
}
}
}
}
}
}
min.release();
max.release();
iter.release();
}
@Override
protected void entityInit() {
dataManager.register(MARKER_TEXTURE, new ResourceLocation("blocks/stone"));
}
@Override
public void readEntityFromNBT(@Nonnull NBTTagCompound compound) {
texture = new ResourceLocation(compound.getString(TEXTURE));
}
@Override
public void writeEntityToNBT(@Nonnull NBTTagCompound compound) {
compound.setString(TEXTURE, texture.toString());
}
@Nullable
@Override
public AxisAlignedBB getCollisionBoundingBox() {
return getEntityBoundingBox();
}
@Nonnull
@Override
protected ItemStack getArrowStack() {
return ItemStack.EMPTY;
}
}

View file

@ -17,6 +17,7 @@
*/
package malte0811.industrialWires.items;
import blusunrize.immersiveengineering.ImmersiveEngineering;
import blusunrize.immersiveengineering.api.ApiUtils;
import blusunrize.immersiveengineering.api.Lib;
import blusunrize.immersiveengineering.api.TargetingInfo;
@ -30,6 +31,7 @@ import blusunrize.immersiveengineering.common.util.ItemNBTHelper;
import blusunrize.immersiveengineering.common.util.Utils;
import malte0811.industrialWires.IWConfig;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.entities.EntityBrokenPart;
import malte0811.industrialWires.wires.IC2Wiretype;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.resources.I18n;
@ -239,6 +241,22 @@ public class ItemIC2Coil extends Item implements IWireCoil {
return EnumActionResult.PASS;
}
//TODO remove. This is for debugging
@Override
public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) {
if (!worldIn.isRemote) {
EntityBrokenPart e = new EntityBrokenPart(worldIn);
e.setPositionAndRotation(playerIn.posX, playerIn.posY+2, playerIn.posZ, playerIn.rotationYaw, playerIn.rotationPitch);
Vec3d look = playerIn.getLookVec();
e.motionX = look.x;
e.motionY = look.y;
e.motionZ = look.z;
e.texture = new ResourceLocation(ImmersiveEngineering.MODID, "blocks/storage_steel");
worldIn.spawnEntity(e);
}
return new ActionResult<>(EnumActionResult.SUCCESS, playerIn.getHeldItem(handIn));
}
public static void setLength(ItemStack i, int blocks) {
i.setTagInfo(lengthKey, new NBTTagInt(blocks));
}

View file

@ -16,9 +16,11 @@
package malte0811.industrialWires.util;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class LocalSidedWorld {
@ -33,6 +35,45 @@ public class LocalSidedWorld {
this.origin = origin;
}
public IBlockState getBlockState(BlockPos pos) {
return world.getBlockState(getRealPos(pos));
}
public TileEntity getTileEntity(BlockPos pos) {
return world.getTileEntity(getRealPos(pos));
}
public boolean isAir(BlockPos pos) {
return world.isAirBlock(getRealPos(pos));
}
public boolean setBlockState(BlockPos pos, IBlockState setTo) {
return world.setBlockState(getRealPos(pos), setTo);
}
public void spawnEntity(Entity e) {
Vec3d pos = getRealPos(e.getPositionVector());
e.setPosition(pos.x, pos.y, pos.z);
Vec3d motion = getRealDirection(new Vec3d(e.motionX, e.motionY, e.motionZ));
e.motionX = motion.x;
e.motionY = motion.y;
e.motionZ = motion.z;
world.spawnEntity(e);
}
public BlockPos getRealPos(BlockPos relative) {
return MiscUtils.offset(origin, facing, mirror, relative);
}
public Vec3d getRealPos(Vec3d relative) {
return MiscUtils.offset(new Vec3d(origin), facing, mirror, relative);
}
public Vec3d getRealDirection(Vec3d dir) {
return MiscUtils.offset(Vec3d.ZERO, facing, mirror, dir);
}
//Getters+Setters
public World getWorld() {
return world;
}
@ -53,27 +94,15 @@ public class LocalSidedWorld {
return origin;
}
public IBlockState getBlockState(BlockPos pos) {
return world.getBlockState(getRealPos(pos));
}
public TileEntity getTileEntity(BlockPos pos) {
return world.getTileEntity(getRealPos(pos));
}
public boolean setBlockState(BlockPos pos, IBlockState setTo) {
return world.setBlockState(getRealPos(pos), setTo);
}
public boolean isAir(BlockPos pos) {
return world.isAirBlock(getRealPos(pos));
}
public BlockPos getRealPos(BlockPos relative) {
return MiscUtils.offset(origin, facing, mirror, relative);
}
public void setWorld(World world) {
this.world = world;
}
public boolean isMirrored() {
return mirror;
}
public EnumFacing getFacing() {
return facing;
}
}

View file

@ -83,6 +83,24 @@ public final class MiscUtils {
return p.offset(f, forward).offset(f.rotateY(), right).add(0, up, 0);
}
public static Vec3d offset(Vec3d p, EnumFacing f, boolean mirror, Vec3d relative) {
return offset(p, f, mirror, relative.x, relative.z, relative.y);
}
public static Vec3d offset(Vec3d p, EnumFacing f, boolean mirror, double right, double forward, double up) {
if (mirror) {
right *= -1;
}
return offset(offset(p, f, forward), f.rotateY(), right).addVector(0, up, 0);
}
public static Vec3d offset(Vec3d in, EnumFacing f, double amount) {
if (amount==0) {
return in;
}
return in.addVector(f.getFrontOffsetX()*amount, f.getFrontOffsetY()*amount, f.getFrontOffsetZ()*amount);
}
/**
* Calculates the parameters for offset to generate here from origin
*

View file

@ -54,6 +54,9 @@ public final class NBTKeys {
public static final String PARTS = "parts";
public static final String POS = "pos";
public static final String SPEED = "speed";
public static final String TEXTURE = "texture";
public static final String AC = "Ac";
private NBTKeys() {}
}

View file

@ -27,6 +27,8 @@
},
"shaft_commutator": {
"model": "industrialwires:mech_mb/commutator.obj"
},
"shaft_basic": {
}
},
"facing":