diff --git a/src/main/java/malte0811/industrialWires/IWConfig.java b/src/main/java/malte0811/industrialWires/IWConfig.java index 99eec2e..0f7fbe8 100644 --- a/src/main/java/malte0811/industrialWires/IWConfig.java +++ b/src/main/java/malte0811/industrialWires/IWConfig.java @@ -71,7 +71,7 @@ public class IWConfig { } public static boolean allowMBEU() { - return (multiblockEnergyType&1)!=0; + return (multiblockEnergyType&1)!=0 && IndustrialWires.hasIC2; } } diff --git a/src/main/java/malte0811/industrialWires/client/ClientProxy.java b/src/main/java/malte0811/industrialWires/client/ClientProxy.java index d27b95c..f559f4e 100644 --- a/src/main/java/malte0811/industrialWires/client/ClientProxy.java +++ b/src/main/java/malte0811/industrialWires/client/ClientProxy.java @@ -45,8 +45,7 @@ import malte0811.industrialWires.client.manual.TextSplitter; import malte0811.industrialWires.client.panelmodel.PanelModelLoader; import malte0811.industrialWires.client.render.*; import malte0811.industrialWires.controlpanel.PanelComponent; -import malte0811.industrialWires.converter.MechEnergy; -import malte0811.industrialWires.converter.MechMBPart; +import malte0811.industrialWires.converter.*; import malte0811.industrialWires.crafting.IC2TRHelper; import malte0811.industrialWires.entities.EntityBrokenPart; import malte0811.industrialWires.hv.MarxOreHandler; @@ -54,6 +53,7 @@ import malte0811.industrialWires.hv.MultiblockMarx; import malte0811.industrialWires.items.ItemIC2Coil; import malte0811.industrialWires.items.ItemPanelComponent; import malte0811.industrialWires.util.CommandIWClient; +import malte0811.industrialWires.util.ConversionUtil; import malte0811.industrialWires.util.MiscUtils; import net.minecraft.client.Minecraft; import net.minecraft.client.audio.ISound; @@ -211,6 +211,7 @@ public class ClientProxy extends CommonProxy { }, IndustrialWires.panelComponent); Config.manual_doubleA.put("iwJacobsUsage", IWConfig.HVStuff.jacobsUsageWatt); + Config.manual_double.put("iwFluxPerJoule", ConversionUtil.ifPerJoule()); Config.manual_int.put("iwKeysOnRing", IWConfig.maxKeysOnRing); m.addEntry("industrialwires.jacobs", IndustrialWires.MODID, new ManualPages.CraftingMulti(m, "industrialwires.jacobs0", new ItemStack(IndustrialWires.jacobsLadder, 1, 0), new ItemStack(IndustrialWires.jacobsLadder, 1, 1), new ItemStack(IndustrialWires.jacobsLadder, 1, 2)), @@ -276,7 +277,7 @@ public class ClientProxy extends CommonProxy { text = I18n.format("ie.manual.entry.industrialwires.mech_mb"); splitter = new TextSplitter(m); - splitter.addSpecialPage(0, 0, 8, (s)->new ManualPageMultiblock(m, s, + splitter.addSpecialPage(0, 0, 8, (s) -> new ManualPageMultiblock(m, s, MiscUtils.getMBFromName(MechMBPart.EXAMPLE_MECHMB_LOC.toString()))); uni = m.fontRenderer.getUnicodeFlag(); m.fontRenderer.setUnicodeFlag(true); @@ -287,6 +288,36 @@ public class ClientProxy extends CommonProxy { List mechMBEntry = splitter.toManualEntry(); m.addEntry("industrialwires.mech_mb", IndustrialWires.MODID, mechMBEntry.toArray(new IManualPage[0])); + String[][] flywheelTable; + { + List flywheelTableList = new ArrayList<>(1+Material.values().length); + flywheelTableList.add(new String[]{"industrialwires.desc.material", "industrialwires.desc.inertia", "industrialwires.desc.max_speed"}); + for (Material mat:Material.values()) { + MechPartFlywheel f = new MechPartFlywheel(mat); + flywheelTableList.add(new String[]{mat.oreName(), Utils.formatDouble(f.getInertia(), "0.#"), + Utils.formatDouble(f.getMaxSpeed(), "0.#")}); + } + flywheelTable = flywheelTableList.toArray(new String[0][]); + } + + List partsEntry = new ArrayList<>(ImmutableList.of( + new ManualPages.Text(m, "industrialwires.mech_mb_parts.shaft"), + new ManualPageMultiblock(m, "industrialwires.mech_mb_parts.flywheel", + MechMBPart.getManualMBForPart(MechPartFlywheel.class)), + new ManualPages.Table(m, "", flywheelTable, true), + new ManualPageMultiblock(m, "industrialwires.mech_mb_parts.coils0", + MechMBPart.getManualMBForPart(MechPartSingleCoil.class)), + new ManualPages.Text(m, "industrialwires.mech_mb_parts.coils1"), + new ManualPageMultiblock(m, "industrialwires.mech_mb_parts.electrodes", + MechMBPart.getManualMBForPart(MechPartFourElectrodes.class)), + new ManualPages.Text(m, "industrialwires.mech_mb_parts.speedometer0"), + new ManualPages.Text(m, "industrialwires.mech_mb_parts.speedometer1"))); + if (IWConfig.MechConversion.allowMBEU()) { + partsEntry.add(new ManualPageMultiblock(m, "industrialwires.mech_mb_parts.commutator", + MechMBPart.getManualMBForPart(MechPartCommutator4Phase.class))); + } + m.addEntry("industrialwires.mech_mb_parts", IndustrialWires.MODID, partsEntry.toArray(new IManualPage[0])); + ClientCommandHandler.instance.registerCommand(new CommandIWClient()); } diff --git a/src/main/java/malte0811/industrialWires/compat/Compat.java b/src/main/java/malte0811/industrialWires/compat/Compat.java index 93d4993..fdda965 100644 --- a/src/main/java/malte0811/industrialWires/compat/Compat.java +++ b/src/main/java/malte0811/industrialWires/compat/Compat.java @@ -24,20 +24,27 @@ import ic2.api.energy.event.EnergyTileUnloadEvent; import ic2.api.energy.tile.IEnergyTile; import ic2.api.item.IBoxable; import ic2.api.item.IC2Items; +import ic2.core.block.TileEntityBlock; import malte0811.industrialWires.converter.MechPartCommutator; import malte0811.industrialWires.hv.MarxOreHandler; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.world.gen.structure.template.Template; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.Loader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; +import java.util.function.BiFunction; import java.util.function.Consumer; public class Compat { + public static BiFunction stackFromInfo = (s, i)->s; static Consumer addMarx = (o) -> { }; static Consumer removeMarx = (o) -> { @@ -55,7 +62,7 @@ public class Compat { static { try { preInit = CompatModule.class.getMethod("preInit"); - CompatModule.class.getMethod("init"); + init = CompatModule.class.getMethod("init"); } catch (NoSuchMethodException e) { e.printStackTrace(); } @@ -93,14 +100,14 @@ public class Compat { } } - private static class CompatCT extends CompatModule { + public static class CompatCT extends CompatModule { @Override public void preInit() { CraftTweakerAPI.registerClass(CTMarxGenerator.class); } } - private static class CompatIC2 extends CompatModule { + public static class CompatIC2 extends CompatModule { public void init() { Item tinnedFood = IC2Items.getItem("filled_tin_can").getItem(); ItemStack emptyMug = IC2Items.getItem("mug", "empty"); @@ -115,8 +122,37 @@ public class Compat { return a instanceof IBoxable && ((IBoxable) a).canBeStoredInToolbox(s); }); MechPartCommutator.originalStack = IC2Items.getItem("te", "kinetic_generator"); - loadIC2Tile = (te) -> MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent((IEnergyTile) te)); - unloadIC2Tile = (te) -> MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent((IEnergyTile) te)); + loadIC2Tile = (te) -> { + if (!te.getWorld().isRemote) { + MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent((IEnergyTile) te)); + } + }; + unloadIC2Tile = (te) ->{ + if (!te.getWorld().isRemote) { + MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent((IEnergyTile) te)); + } + }; + try { + Class teb = Class.forName("ic2.core.block.TileEntityBlock"); + Method getPickBlock = teb.getDeclaredMethod("getPickBlock", EntityPlayer.class, RayTraceResult.class); + getPickBlock.setAccessible(true); + final ResourceLocation IC2_TE = new ResourceLocation("ic2", "te"); + stackFromInfo = (stack, info) -> { + try { + if (info.tileentityData != null && IC2_TE.equals(info.blockState.getBlock().getRegistryName())) { + TileEntity te = TileEntity.create(null, info.tileentityData); + if (te instanceof TileEntityBlock) + stack = (ItemStack) getPickBlock.invoke(te, null, null); + } + } catch (NullPointerException | IllegalAccessException | InvocationTargetException x) { + x.printStackTrace(); + } + return stack; + }; + } catch (Exception x) { + x.printStackTrace(); + } + } } } \ No newline at end of file diff --git a/src/main/java/malte0811/industrialWires/converter/Material.java b/src/main/java/malte0811/industrialWires/converter/Material.java index 7fba2ff..4278411 100644 --- a/src/main/java/malte0811/industrialWires/converter/Material.java +++ b/src/main/java/malte0811/industrialWires/converter/Material.java @@ -33,7 +33,7 @@ public enum Material { URANIUM(19.1, 400, "blocks/storage_uranium_side"),// This is a bit silly. But why not. CONSTANTAN(8.885, 600, "blocks/storage_constantan"), //Tensile strength is a guess ((GOLD+SILVER)/2), if anyone has better data I'll put it in - ELECTRUM((SILVER.density + GOLD.density) / 2, (SILVER.tensileStrength + GOLD.tensileStrength) / 2, "blocks/storage_electrum"), + ELECTRUM((SILVER.density + GOLD.density) / 2e3, (SILVER.tensileStrength + GOLD.tensileStrength) / 2e6, "blocks/storage_electrum"), 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")); diff --git a/src/main/java/malte0811/industrialWires/converter/MechMBPart.java b/src/main/java/malte0811/industrialWires/converter/MechMBPart.java index d50444f..8122930 100644 --- a/src/main/java/malte0811/industrialWires/converter/MechMBPart.java +++ b/src/main/java/malte0811/industrialWires/converter/MechMBPart.java @@ -168,6 +168,10 @@ public abstract class MechMBPart { return new ResourceLocation(MODID, name); } + public static MultiblockHandler.IMultiblock getManualMBForPart(Class cl) { + return MiscUtils.getMBFromName(getSchematicLocationForPart(cl).toString()); + } + public static void cacheNewInstance(String key) { try { MechMBPart instance = REGISTRY.get(key).newInstance(); diff --git a/src/main/java/malte0811/industrialWires/converter/MechPartFlywheel.java b/src/main/java/malte0811/industrialWires/converter/MechPartFlywheel.java index e3f8c7a..7e22839 100644 --- a/src/main/java/malte0811/industrialWires/converter/MechPartFlywheel.java +++ b/src/main/java/malte0811/industrialWires/converter/MechPartFlywheel.java @@ -45,6 +45,11 @@ public class MechPartFlywheel extends MechMBPart { private static final double THICKNESS = 1; private static final double VOLUME = Math.PI*RADIUS*RADIUS*THICKNESS; private Material material; + public MechPartFlywheel() {} + + public MechPartFlywheel(Material m) { + material = m; + } //A flywheel simply adds mass (lots of mass!), it doesn't actively change speeds/energy @Override public void createMEnergy(MechEnergy e) {} diff --git a/src/main/java/malte0811/industrialWires/converter/MechPartSpeedometer.java b/src/main/java/malte0811/industrialWires/converter/MechPartSpeedometer.java index aa9624d..769e189 100644 --- a/src/main/java/malte0811/industrialWires/converter/MechPartSpeedometer.java +++ b/src/main/java/malte0811/industrialWires/converter/MechPartSpeedometer.java @@ -92,11 +92,18 @@ public class MechPartSpeedometer extends MechMBPart implements IPlayerInteractio } private int roundHysteresis(int old, double newExact) { - if (oldTHRESHOLD) { + return floor; + } else if (old>newExact && mod<1-THRESHOLD) { + return floor; + } + return old; } @Override diff --git a/src/main/java/malte0811/industrialWires/util/MultiblockTemplateManual.java b/src/main/java/malte0811/industrialWires/util/MultiblockTemplateManual.java index 8e7b4a5..f5c38e0 100644 --- a/src/main/java/malte0811/industrialWires/util/MultiblockTemplateManual.java +++ b/src/main/java/malte0811/industrialWires/util/MultiblockTemplateManual.java @@ -17,6 +17,7 @@ package malte0811.industrialWires.util; import blusunrize.immersiveengineering.api.MultiblockHandler; import blusunrize.immersiveengineering.api.crafting.IngredientStack; +import malte0811.industrialWires.compat.Compat; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; @@ -72,8 +73,8 @@ public class MultiblockTemplateManual implements MultiblockHandler.IMultiblock { List blocks = template.blocks; Set matsSet = new HashSet<>(); for (Template.BlockInfo info : blocks) { - ItemStack here = new ItemStack(info.blockState.getBlock(), 1, - info.blockState.getBlock().getMetaFromState(info.blockState)); + ItemStack here = Compat.stackFromInfo.apply(new ItemStack(info.blockState.getBlock(), 1, + info.blockState.getBlock().getMetaFromState(info.blockState)), info); if (!here.isEmpty()) { realStructure.put(fakeStructure[info.pos.getY()][info.pos.getX()][info.pos.getZ()], info.blockState); diff --git a/src/main/resources/assets/industrialwires/lang/en_US.lang b/src/main/resources/assets/industrialwires/lang/en_US.lang index 5fd2a77..6b86bfe 100644 --- a/src/main/resources/assets/industrialwires/lang/en_US.lang +++ b/src/main/resources/assets/industrialwires/lang/en_US.lang @@ -63,6 +63,9 @@ industrialwires.desc.input=Input industrialwires.desc.output=Main Output industrialwires.desc.alt=Replacement industrialwires.desc.ideal_e=Ideal Energy +industrialwires.desc.inertia=Inertia +industrialwires.desc.max_speed=Max. speed +industrialwires.desc.material=Material industrialwires.desc.wireLength=Wire length: %s block(s) industrialwires.desc.recipe=Please check the Engineer's manual for recipe details @@ -143,7 +146,18 @@ ie.manual.entry.industrialwires.marx=A Marx Generator is a device use to produce ie.manual.entry.industrialwires.mech_mb.name=Mechanical Multiblocks ie.manual.entry.industrialwires.mech_mb.subtext= -ie.manual.entry.industrialwires.mech_mb=Mechanical multiblocks serve two main purposes: storing large amounts of energy and converting DC (tradename EU) to FE (tradename Flux and many others) and vice versa.
The multiblock is formed by placing the desired parts (see [](TODO link to parts entry)) in a row and adding two heavy engineering blocks stacked on top of each other on either side. <&0>The above plan shows a schematic for an energy storage setup with a single lead flywheel. The multiblock is formed by hitting one of the upper heavy engineering blocks with an Engineer's hammer.
§lMechanical§r: Some components have a maximum speed (specified in radians per second). If this speed is exceeded or the multiblock is broken while turning at more than 10%% of the maximum speed (5%% for the part being broken) the component will fail violently, usually damaging nearby objects in the process. The [speedometer](TODO) can be used to check the speed of a mechanical multiblock. Due to slight friction the multiblock will slow down over time, by 5%% per hour.
§lElectrical§r: Both AC and DC come in two major variants: Single-phase and Four-phase. Four phase electricity is required for most high-power parts. AC power has an additional property: synchronous or asynchronous (relative to the speed of the multiblock). This is only relevant for [rectifying/commutating parts](TODO): Power added from outside sources is asynchronous, AC power produced in the multiblock (by coils or by commutation of DC) is synchronous. Only synchronous AC can be rectified (converted to DC) using mechanical multiblocks, attempting to rectify asynchronous AC will produce an unusable waveform. If the speed of the multiblock is within 10%% of 20 radians/second both types of AC are equal: At this speed mechanical rectification work on asynchronous AC power.
§lEnergy storage§r: As mentioned earlier one of the main uses of mechanical multiblocks is as energy storage. The stored energy (in joules, one joule is Flux) can be calculated as 0.5*I*w*w where w is the speed of the multiblock (in radians/second) and I is the moment of inertia. The former can be obtained using a [speedometer](TODO), the latter is the sum of the inertia of each part of the multiblock (which can be found in the entry on [mechanical multiblock parts](TODO)). +ie.manual.entry.industrialwires.mech_mb=Mechanical multiblocks serve two main purposes: storing large amounts of energy and converting DC (tradename EU) to FE (tradename Flux and many others) and vice versa.
The multiblock is formed by placing the desired parts (see ) in a row and adding two heavy engineering blocks stacked on top of each other on either side. <&0>The above plan shows a schematic for an energy storage setup with a single lead flywheel. The multiblock is formed by hitting one of the upper heavy engineering blocks with an Engineer's hammer.
§lMechanical§r: Some components have a maximum speed (specified in radians per second). If this speed is exceeded or the multiblock is broken while turning at more than 10%% of the maximum speed (5%% for the part being broken) the component will fail violently, usually damaging nearby objects in the process. The can be used to check the speed of a mechanical multiblock. Due to slight friction the multiblock will slow down over time, by 5%% per hour.
§lElectrical§r: Electricity is transfered in contiguous sections of parts that can interact with electricity. Only one type of electricity will be transferred in each section.
Both AC and DC come in two major variants: Single-phase and Four-phase. Four phase electricity is required for most high-power parts. AC power has an additional property: synchronous or asynchronous (relative to the speed of the multiblock). This is only relevant for rectifying/ commutating parts: Power added from outside sources is asynchronous, AC power produced in the multiblock (by coils or by commutation of DC) is synchronous. Only synchronous AC can be rectified (converted to DC) using mechanical multiblocks, attempting to rectify asynchronous AC will produce an unusable waveform. If the speed of the multiblock is within 10%% of 20 radians/second both types of AC are equal: At this speed mechanical rectification work on asynchronous AC power.
§lEnergy storage§r: As mentioned earlier one of the main uses of mechanical multiblocks is as energy storage. The stored energy (in joules, one joule is Flux) can be calculated as 0.5*I*w² where w is the speed of the multiblock (in radians/second) and I is the moment of inertia. The former can be obtained using a , the latter is the sum of the inertia of each part of the multiblock (which can be found in the entry on ). + +ie.manual.entry.industrialwires.mech_mb_parts.name=Mechanical Multiblock Parts +ie.manual.entry.industrialwires.mech_mb_parts.subtext= +ie.manual.entry.industrialwires.mech_mb_parts.shaft=The shaft is the simplest part imaginable: It does not do anything. This can be useful for seperating electrical sections of the multiblock. It consists of a single heavy engineering block in the middle of the multiblock. +ie.manual.entry.industrialwires.mech_mb_parts.flywheel=The flywheel is another very simple part: Its only job is to add inertia to increase energy storage. Various materials can be used instead of the lead blocks in the above schematic. The table on the next page shows all available materials, their inertia and their maximum speed. +ie.manual.entry.industrialwires.mech_mb_parts.coils0=Coils produce synchronous AC power from the multiblocks rotation or convert AC power (both synchronous and asynchronous will work) into multiblock rotation. For a four-phase coil replace the light engineering blocks on the level of the shaft with copper coil blocks. The maximum speed +ie.manual.entry.industrialwires.mech_mb_parts.coils1=is 100 radians/second for a single-phase coil and 500 radians/second for a four-phase coil. +ie.manual.entry.industrialwires.mech_mb_parts.electrodes=Electrodes are the standard way of transferring energy out of or into a mechanical multiblock. The above plan shows the four-phase version, the single phase version if formed from a single generator block in the place of the shaft. Both AC and DC power can be connected to it. +ie.manual.entry.industrialwires.mech_mb_parts.speedometer0=The speedometer does what one would expect it to do: It measures the speed the multiblock is turning at. It consists of a single redstone engineering block in the place of the shaft. Right-clicking with a Voltmeter will give the exact speed, but its most common use is to automatically limit the speed of a multiblock. One side (the one marked with a line) will output a redstone signal proportional to the speed, the other one (marked "ln") will output a signal proportional to the logarithm of the speed plus +ie.manual.entry.industrialwires.mech_mb_parts.speedometer1=one. To change what speed equates to a full strength signal you can (shift-) right-click the speedometer with an engineer's hammer.
Both signals have hysteresis to prevent flickering: For the signal to drop from n to n-1 the exact signal strength has to drop below n-0.1. To rise from n to n+1 the exact strength has to be above n+1.1. +ie.manual.entry.industrialwires.mech_mb_parts.commutator=The commutator converts synchronous AC to DC and vice versa. The above plan shows the four-phase version, the single-phase version consists of a single kinetic generator from IC2 in the place of the shaft. ie.manual.entry.industrialwires.intro.name=Introduction ie.manual.entry.industrialwires.intro.subtext= diff --git a/src/main/resources/assets/industrialwires/structures/comm_four.nbt b/src/main/resources/assets/industrialwires/structures/comm_four.nbt new file mode 100644 index 0000000..fbae8c3 Binary files /dev/null and b/src/main/resources/assets/industrialwires/structures/comm_four.nbt differ diff --git a/src/main/resources/assets/industrialwires/structures/commutator.nbt b/src/main/resources/assets/industrialwires/structures/commutator.nbt new file mode 100644 index 0000000..9cd62ba Binary files /dev/null and b/src/main/resources/assets/industrialwires/structures/commutator.nbt differ