From e72877cc72238ef0b79f0852f90dd27a5ca7b853 Mon Sep 17 00:00:00 2001 From: Calclavia Date: Wed, 15 Jan 2014 19:08:11 +0800 Subject: [PATCH] Some more work on gears --- build.gradle | 5 +- .../electrical/generator/TileGenerator.java | 6 +- .../mechanical/belt/BeltNetwork.java | 12 +- .../fluid/prefab/TileFluidNetwork.java | 6 +- .../mechanical/gear/PartGear.java | 396 +++++++++--------- .../mechanical/network/IMechNetwork.java | 18 - .../{IMechMachine.java => IMechanical.java} | 2 +- ...nnector.java => IMechanicalConnector.java} | 2 +- .../network/IMechanicalNetwork.java | 30 ++ .../mechanical/network/MechNetwork.java | 234 ----------- .../mechanical/network/MechanicalNetwork.java | 259 ++++++++++++ .../textures/blocks/MachineBlackOffSide.png | Bin 1815 -> 0 bytes .../textures/blocks/MachineBlackOnSide.png | Bin 1907 -> 0 bytes .../textures/blocks/MachineFarmer.png | Bin 2209 -> 0 bytes .../textures/blocks/MachineMiner.png | Bin 2173 -> 0 bytes .../textures/blocks/MachineRedOffSide.png | Bin 1781 -> 0 bytes .../textures/blocks/MachineRedOnSide.png | Bin 1871 -> 0 bytes .../textures/blocks/firebox_side.png | Bin 0 -> 1441 bytes .../textures/blocks/firebox_top_off.png | Bin 0 -> 1625 bytes .../textures/blocks/firebox_top_on.png | Bin 0 -> 1851 bytes .../textures/blocks/material_steel_shiny.png | Bin 0 -> 2942 bytes .../textures/blocks/material_steel_tint.png | Bin 0 -> 2238 bytes 22 files changed, 516 insertions(+), 454 deletions(-) delete mode 100644 src/main/java/resonantinduction/mechanical/network/IMechNetwork.java rename src/main/java/resonantinduction/mechanical/network/{IMechMachine.java => IMechanical.java} (90%) rename src/main/java/resonantinduction/mechanical/network/{IMechConnector.java => IMechanicalConnector.java} (71%) create mode 100644 src/main/java/resonantinduction/mechanical/network/IMechanicalNetwork.java delete mode 100644 src/main/java/resonantinduction/mechanical/network/MechNetwork.java create mode 100644 src/main/java/resonantinduction/mechanical/network/MechanicalNetwork.java delete mode 100644 src/main/resources/assets/resonantinduction/textures/blocks/MachineBlackOffSide.png delete mode 100644 src/main/resources/assets/resonantinduction/textures/blocks/MachineBlackOnSide.png delete mode 100644 src/main/resources/assets/resonantinduction/textures/blocks/MachineFarmer.png delete mode 100644 src/main/resources/assets/resonantinduction/textures/blocks/MachineMiner.png delete mode 100644 src/main/resources/assets/resonantinduction/textures/blocks/MachineRedOffSide.png delete mode 100644 src/main/resources/assets/resonantinduction/textures/blocks/MachineRedOnSide.png create mode 100644 src/main/resources/assets/resonantinduction/textures/blocks/firebox_side.png create mode 100644 src/main/resources/assets/resonantinduction/textures/blocks/firebox_top_off.png create mode 100644 src/main/resources/assets/resonantinduction/textures/blocks/firebox_top_on.png create mode 100644 src/main/resources/assets/resonantinduction/textures/blocks/material_steel_shiny.png create mode 100644 src/main/resources/assets/resonantinduction/textures/blocks/material_steel_tint.png diff --git a/build.gradle b/build.gradle index a9c8feef4..570d854bb 100644 --- a/build.gradle +++ b/build.gradle @@ -68,7 +68,10 @@ jar { } repositories { - maven { url 'file://var/www/maven/' } + maven { + name 'Calclavia Maven' + url 'http://calclavia.com/maven' + } ivy { name 'CB FS' diff --git a/src/main/java/resonantinduction/electrical/generator/TileGenerator.java b/src/main/java/resonantinduction/electrical/generator/TileGenerator.java index d9238dae1..665ab949b 100644 --- a/src/main/java/resonantinduction/electrical/generator/TileGenerator.java +++ b/src/main/java/resonantinduction/electrical/generator/TileGenerator.java @@ -1,15 +1,15 @@ package resonantinduction.electrical.generator; import net.minecraftforge.common.ForgeDirection; -import resonantinduction.mechanical.network.IMechConnector; -import resonantinduction.mechanical.network.IMechMachine; +import resonantinduction.mechanical.network.IMechanicalConnector; +import resonantinduction.mechanical.network.IMechanical; import universalelectricity.api.energy.EnergyStorageHandler; import calclavia.lib.prefab.tile.TileElectrical; /** A kinetic energy to electrical energy converter. * * @author Calclavia */ -public class TileGenerator extends TileElectrical implements IMechMachine +public class TileGenerator extends TileElectrical implements IMechanical { //P = \tau \times 2 \pi \times \omega private long power; diff --git a/src/main/java/resonantinduction/mechanical/belt/BeltNetwork.java b/src/main/java/resonantinduction/mechanical/belt/BeltNetwork.java index e8ae64296..7f42f08d3 100644 --- a/src/main/java/resonantinduction/mechanical/belt/BeltNetwork.java +++ b/src/main/java/resonantinduction/mechanical/belt/BeltNetwork.java @@ -3,9 +3,9 @@ package resonantinduction.mechanical.belt; import net.minecraft.tileentity.TileEntity; import resonantinduction.api.IBelt; import resonantinduction.api.IBeltNetwork; -import resonantinduction.mechanical.network.IMechConnector; -import resonantinduction.mechanical.network.IMechNetwork; -import resonantinduction.mechanical.network.MechNetwork; +import resonantinduction.mechanical.network.IMechanicalConnector; +import resonantinduction.mechanical.network.IMechanicalNetwork; +import resonantinduction.mechanical.network.MechanicalNetwork; import universalelectricity.api.net.IConnector; import universalelectricity.core.net.ConnectionPathfinder; import universalelectricity.core.net.Network; @@ -122,13 +122,13 @@ public class BeltNetwork extends Network implem { /** The connections A and B are not connected anymore. Give them both a new common * network. */ - IMechNetwork newNetwork = new MechNetwork(); + IMechanicalNetwork newNetwork = new MechanicalNetwork(); for (IConnector node : finder.closedSet) { - if (node instanceof IMechConnector) + if (node instanceof IMechanicalConnector) { - newNetwork.addConnector((IMechConnector) node); + newNetwork.addConnector((IMechanicalConnector) node); } } diff --git a/src/main/java/resonantinduction/mechanical/fluid/prefab/TileFluidNetwork.java b/src/main/java/resonantinduction/mechanical/fluid/prefab/TileFluidNetwork.java index 08ff1adc7..009a52408 100644 --- a/src/main/java/resonantinduction/mechanical/fluid/prefab/TileFluidNetwork.java +++ b/src/main/java/resonantinduction/mechanical/fluid/prefab/TileFluidNetwork.java @@ -290,19 +290,19 @@ public class TileFluidNetwork extends TileEntityFluidDevice implements IFluidPar @Override public Packet getDescriptionPacket() { - return ResonantInduction.PACKET_TILE.getPacket(PACKET_DESCRIPTION, this, this.colorID, this.renderSides, this.getInternalTank().getCapacity(), this.getInternalTank().writeToNBT(new NBTTagCompound())); + return ResonantInduction.PACKET_TILE.getPacketWithID(PACKET_DESCRIPTION, this, this.colorID, this.renderSides, this.getInternalTank().getCapacity(), this.getInternalTank().writeToNBT(new NBTTagCompound())); } public void sendRenderUpdate() { - PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacket(PACKET_RENDER, this, this.colorID, this.renderSides)); + PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacketWithID(PACKET_RENDER, this, this.colorID, this.renderSides)); } public void sendTankUpdate(int index) { if (this.getInternalTank() != null && index == 0) { - PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacket(PACKET_TANK, this, this.getInternalTank().getCapacity(), this.getInternalTank().writeToNBT(new NBTTagCompound())), this.worldObj, new Vector3(this), 60); + PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacketWithID(PACKET_TANK, this, this.getInternalTank().getCapacity(), this.getInternalTank().writeToNBT(new NBTTagCompound())), this.worldObj, new Vector3(this), 60); } } diff --git a/src/main/java/resonantinduction/mechanical/gear/PartGear.java b/src/main/java/resonantinduction/mechanical/gear/PartGear.java index e8c49eb78..81afd3577 100644 --- a/src/main/java/resonantinduction/mechanical/gear/PartGear.java +++ b/src/main/java/resonantinduction/mechanical/gear/PartGear.java @@ -11,9 +11,9 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.MovingObjectPosition; import net.minecraftforge.common.ForgeDirection; import resonantinduction.mechanical.Mechanical; -import resonantinduction.mechanical.network.IMechConnector; -import resonantinduction.mechanical.network.IMechNetwork; -import resonantinduction.mechanical.network.MechNetwork; +import resonantinduction.mechanical.network.IMechanicalConnector; +import resonantinduction.mechanical.network.IMechanicalNetwork; +import resonantinduction.mechanical.network.MechanicalNetwork; import universalelectricity.api.UniversalElectricity; import codechicken.lib.data.MCDataInput; import codechicken.lib.data.MCDataOutput; @@ -30,227 +30,249 @@ import codechicken.multipart.TileMultipart; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart, IMechConnector +/** + * We assume all the force acting on the gear is 90 degrees. + * + * @author Calclavia + * + */ +public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart, IMechanicalConnector { - public static Cuboid6[][] oBoxes = new Cuboid6[6][2]; + public static Cuboid6[][] oBoxes = new Cuboid6[6][2]; - private IMechNetwork network; + private IMechanicalNetwork network; - static - { - oBoxes[0][0] = new Cuboid6(1 / 8D, 0, 0, 7 / 8D, 1 / 8D, 1); - oBoxes[0][1] = new Cuboid6(0, 0, 1 / 8D, 1, 1 / 8D, 7 / 8D); - for (int s = 1; s < 6; s++) - { - Transformation t = Rotation.sideRotations[s].at(Vector3.center); - oBoxes[s][0] = oBoxes[0][0].copy().apply(t); - oBoxes[s][1] = oBoxes[0][1].copy().apply(t); - } - } - /** Side of the block this is placed on */ - private ForgeDirection placementSide; + static + { + oBoxes[0][0] = new Cuboid6(1 / 8D, 0, 0, 7 / 8D, 1 / 8D, 1); + oBoxes[0][1] = new Cuboid6(0, 0, 1 / 8D, 1, 1 / 8D, 7 / 8D); + for (int s = 1; s < 6; s++) + { + Transformation t = Rotation.sideRotations[s].at(Vector3.center); + oBoxes[s][0] = oBoxes[0][0].copy().apply(t); + oBoxes[s][1] = oBoxes[0][1].copy().apply(t); + } + } + /** Side of the block this is placed on */ + private ForgeDirection placementSide; - /** Positive torque means it is spinning clockwise */ - private long torque = 0; + /** Positive torque means it is spinning clockwise */ + private long torque = 0; - public void preparePlacement(int side, int itemDamage) - { - this.placementSide = ForgeDirection.getOrientation((byte) (side ^ 1)); - } + private long force = 0; - @Override - public void update() - { - // TODO: Should we average the torque? - /** Look for gears that are back-to-back with this gear. Equate torque. */ - universalelectricity.api.vector.Vector3 vec = new universalelectricity.api.vector.Vector3(tile()).modifyPositionFromSide(placementSide); + /** The size of the gear */ + private float radius = 0.5f; + + /** The angular velocity, radians per second. */ + private float angularVelocity = 0; + + /** The current angle the gear is on. In radians. */ + private float angle = 0; - TileEntity tile = vec.getTileEntity(world()); + public void preparePlacement(int side, int itemDamage) + { + this.placementSide = ForgeDirection.getOrientation((byte) (side ^ 1)); + } - if (tile instanceof TileMultipart) - { - TMultiPart part = ((TileMultipart) tile).partMap(this.placementSide.getOpposite().ordinal()); + public long getTorque() + { + return (long) (force * radius); + } - if (part instanceof PartGear) - { - torque = (torque + ((PartGear) part).torque) / 2; - ((PartGear) part).torque = torque; - } - } + @Override + public void update() + { + // TODO: Should we average the torque? + /** Look for gears that are back-to-back with this gear. Equate torque. */ + universalelectricity.api.vector.Vector3 vec = new universalelectricity.api.vector.Vector3(tile()).modifyPositionFromSide(placementSide); - /** Look for gears outside this block space, the relative UP, DOWN, LEFT, RIGHT */ - for (int i = 0; i < 4; i++) - { - ForgeDirection checkDir = ForgeDirection.getOrientation(Rotation.rotateSide(this.placementSide.ordinal(), i)); - universalelectricity.api.vector.Vector3 checkVec = new universalelectricity.api.vector.Vector3(tile()).modifyPositionFromSide(checkDir); + TileEntity tile = vec.getTileEntity(world()); - TileEntity checkTile = checkVec.getTileEntity(world()); + if (tile instanceof TileMultipart) + { + TMultiPart part = ((TileMultipart) tile).partMap(this.placementSide.getOpposite().ordinal()); - if (checkTile instanceof TileMultipart) - { - TMultiPart neighbor = ((TileMultipart) checkTile).partMap(this.placementSide.ordinal()); + if (part instanceof PartGear) + { + torque = (torque + ((PartGear) part).torque) / 2; + ((PartGear) part).torque = torque; + } + } - if (neighbor instanceof PartGear) - { - torque = (torque - ((PartGear) neighbor).torque) / 2; - ((PartGear) neighbor).torque = -torque; - } - } - } + /** Look for gears outside this block space, the relative UP, DOWN, LEFT, RIGHT */ + for (int i = 0; i < 4; i++) + { + ForgeDirection checkDir = ForgeDirection.getOrientation(Rotation.rotateSide(this.placementSide.ordinal(), i)); + universalelectricity.api.vector.Vector3 checkVec = new universalelectricity.api.vector.Vector3(tile()).modifyPositionFromSide(checkDir); - /** Look for gears that are internal and adjacent to this gear. (The 2 sides) */ - for (int i = 0; i < 6; i++) - { - // TODO: Make it work with UP-DOWN - if (i < 2) - { - TMultiPart neighbor = tile().partMap(this.placementSide.getRotation(ForgeDirection.getOrientation(i)).ordinal()); + TileEntity checkTile = checkVec.getTileEntity(world()); - if (neighbor instanceof PartGear) - { - torque = (torque - ((PartGear) neighbor).torque) / 2; - ((PartGear) neighbor).torque = -torque; - } - } - } - } + if (checkTile instanceof TileMultipart) + { + TMultiPart neighbor = ((TileMultipart) checkTile).partMap(this.placementSide.ordinal()); - @Override - public boolean activate(EntityPlayer player, MovingObjectPosition hit, ItemStack item) - { - System.out.println("Torque" + this.torque); + if (neighbor instanceof PartGear) + { + torque = (torque - ((PartGear) neighbor).torque) / 2; + ((PartGear) neighbor).torque = -torque; + } + } + } - if (player.isSneaking()) - { - this.torque += 10; - } + /** Look for gears that are internal and adjacent to this gear. (The 2 sides) */ + for (int i = 0; i < 6; i++) + { + // TODO: Make it work with UP-DOWN + if (i < 2) + { + TMultiPart neighbor = tile().partMap(this.placementSide.getRotation(ForgeDirection.getOrientation(i)).ordinal()); - return false; - } + if (neighbor instanceof PartGear) + { + torque = (torque - ((PartGear) neighbor).torque) / 2; + ((PartGear) neighbor).torque = -torque; + } + } + } + } - /** Packet Code. */ - @Override - public void readDesc(MCDataInput packet) - { - this.placementSide = ForgeDirection.getOrientation(packet.readByte()); - } + @Override + public boolean activate(EntityPlayer player, MovingObjectPosition hit, ItemStack item) + { + System.out.println("Torque" + this.torque); - @Override - public void writeDesc(MCDataOutput packet) - { - packet.writeByte(this.placementSide.ordinal()); - } + if (player.isSneaking()) + { + this.torque += 10; + } - @Override - public int getSlotMask() - { - return 1 << this.placementSide.ordinal(); - } + return false; + } - @Override - public Cuboid6 getBounds() - { - return FaceMicroClass.aBounds()[0x10 | this.placementSide.ordinal()]; - } + /** Packet Code. */ + @Override + public void readDesc(MCDataInput packet) + { + this.placementSide = ForgeDirection.getOrientation(packet.readByte()); + } - @Override - public int redstoneConductionMap() - { - return 0; - } + @Override + public void writeDesc(MCDataOutput packet) + { + packet.writeByte(this.placementSide.ordinal()); + } - @Override - public boolean solid(int arg0) - { - return true; - } + @Override + public int getSlotMask() + { + return 1 << this.placementSide.ordinal(); + } - @Override - public Iterable getOcclusionBoxes() - { - return Arrays.asList(oBoxes[this.placementSide.ordinal()]); - } + @Override + public Cuboid6 getBounds() + { + return FaceMicroClass.aBounds()[0x10 | this.placementSide.ordinal()]; + } - protected ItemStack getItem() - { - return new ItemStack(Mechanical.itemGear); - } + @Override + public int redstoneConductionMap() + { + return 0; + } - @Override - public Iterable getDrops() - { - List drops = new ArrayList(); - drops.add(getItem()); - return drops; - } + @Override + public boolean solid(int arg0) + { + return true; + } - @Override - public ItemStack pickItem(MovingObjectPosition hit) - { - return getItem(); - } + @Override + public Iterable getOcclusionBoxes() + { + return Arrays.asList(oBoxes[this.placementSide.ordinal()]); + } - @Override - @SideOnly(Side.CLIENT) - public void renderDynamic(Vector3 pos, float frame, int pass) - { + protected ItemStack getItem() + { + return new ItemStack(Mechanical.itemGear); + } - } + @Override + public Iterable getDrops() + { + List drops = new ArrayList(); + drops.add(getItem()); + return drops; + } - @Override - public void load(NBTTagCompound nbt) - { - super.load(nbt); - this.placementSide = ForgeDirection.getOrientation(nbt.getByte("side")); - } + @Override + public ItemStack pickItem(MovingObjectPosition hit) + { + return getItem(); + } - @Override - public void save(NBTTagCompound nbt) - { - super.save(nbt); - nbt.setByte("side", (byte) this.placementSide.ordinal()); - } + @Override + @SideOnly(Side.CLIENT) + public void renderDynamic(Vector3 pos, float frame, int pass) + { - @Override - public String getType() - { - return "resonant_induction_gear"; - } + } - @Override - public Object[] getConnections() - { - return null; - } + @Override + public void load(NBTTagCompound nbt) + { + super.load(nbt); + this.placementSide = ForgeDirection.getOrientation(nbt.getByte("side")); + } - @Override - public IMechNetwork getNetwork() - { - if (this.network == null) - { - this.network = new MechNetwork(); - this.network.addConnector(this); - } - return this.network; - } + @Override + public void save(NBTTagCompound nbt) + { + super.save(nbt); + nbt.setByte("side", (byte) this.placementSide.ordinal()); + } - @Override - public void setNetwork(IMechNetwork network) - { - this.network = network; - } + @Override + public String getType() + { + return "resonant_induction_gear"; + } - @Override - public boolean canConnect(ForgeDirection direction) - { - return new universalelectricity.api.vector.Vector3(this.x() + direction.offsetX, this.y() + direction.offsetY, this.z() + direction.offsetZ).getTileEntity(this.world()) instanceof IMechConnector; - } + @Override + public Object[] getConnections() + { + return null; + } - @Override - public int getResistance() - { - // TODO Auto-generated method stub - return 0; - } + @Override + public IMechanicalNetwork getNetwork() + { + if (this.network == null) + { + this.network = new MechanicalNetwork(); + this.network.addConnector(this); + } + return this.network; + } + + @Override + public void setNetwork(IMechanicalNetwork network) + { + this.network = network; + } + + @Override + public boolean canConnect(ForgeDirection direction) + { + return new universalelectricity.api.vector.Vector3(this.x() + direction.offsetX, this.y() + direction.offsetY, this.z() + direction.offsetZ).getTileEntity(this.world()) instanceof IMechanicalConnector; + } + + @Override + public int getResistance() + { + // TODO Auto-generated method stub + return 0; + } } \ No newline at end of file diff --git a/src/main/java/resonantinduction/mechanical/network/IMechNetwork.java b/src/main/java/resonantinduction/mechanical/network/IMechNetwork.java deleted file mode 100644 index 2202cc2a9..000000000 --- a/src/main/java/resonantinduction/mechanical/network/IMechNetwork.java +++ /dev/null @@ -1,18 +0,0 @@ -package resonantinduction.mechanical.network; - -import universalelectricity.api.net.INetwork; - -/** Mechanical network in interface form for interaction or extension - * - * @author DarkGuardsman */ -public interface IMechNetwork extends INetwork -{ - /** Power applied by the network at the given speed */ - public int getTorque(); - - /** Rotation of the the network in a single update */ - public int getRotationPerTick(); - - /** Called to rebuild the network */ - public void reconstruct(); -} diff --git a/src/main/java/resonantinduction/mechanical/network/IMechMachine.java b/src/main/java/resonantinduction/mechanical/network/IMechanical.java similarity index 90% rename from src/main/java/resonantinduction/mechanical/network/IMechMachine.java rename to src/main/java/resonantinduction/mechanical/network/IMechanical.java index f144869f9..8dcdf0dba 100644 --- a/src/main/java/resonantinduction/mechanical/network/IMechMachine.java +++ b/src/main/java/resonantinduction/mechanical/network/IMechanical.java @@ -6,7 +6,7 @@ import universalelectricity.api.net.IConnectable; /** Applied to machines that connect to a mech network * * @author Darkguardsman */ -public interface IMechMachine extends IConnectable +public interface IMechanical extends IConnectable { /** Called by the network when its torque value changes. */ public void onTorqueChange(ForgeDirection side, int speed); diff --git a/src/main/java/resonantinduction/mechanical/network/IMechConnector.java b/src/main/java/resonantinduction/mechanical/network/IMechanicalConnector.java similarity index 71% rename from src/main/java/resonantinduction/mechanical/network/IMechConnector.java rename to src/main/java/resonantinduction/mechanical/network/IMechanicalConnector.java index 300d39cc5..30ffa637a 100644 --- a/src/main/java/resonantinduction/mechanical/network/IMechConnector.java +++ b/src/main/java/resonantinduction/mechanical/network/IMechanicalConnector.java @@ -5,7 +5,7 @@ import universalelectricity.api.net.IConnector; /** For the mechanical network. * * @author Calclavia */ -public interface IMechConnector extends IConnector +public interface IMechanicalConnector extends IConnector { public int getResistance(); } diff --git a/src/main/java/resonantinduction/mechanical/network/IMechanicalNetwork.java b/src/main/java/resonantinduction/mechanical/network/IMechanicalNetwork.java new file mode 100644 index 000000000..89bba276f --- /dev/null +++ b/src/main/java/resonantinduction/mechanical/network/IMechanicalNetwork.java @@ -0,0 +1,30 @@ +package resonantinduction.mechanical.network; + +import universalelectricity.api.net.INetwork; + +/** + * Mechanical network in interface form for interaction or extension + * + * @author DarkGuardsman + */ +public interface IMechanicalNetwork extends INetwork +{ + /** + * Gets the power of the network. + * + * @return Power in Watts. + */ + public long getPower(); + + /** Torque applied by the network at the given speed */ + public int getTorque(); + + /** + * Gets the angular velocity of the network. + * @return In radians per second. + */ + public int getAngularVelocity(); + + /** Called to rebuild the network */ + public void reconstruct(); +} diff --git a/src/main/java/resonantinduction/mechanical/network/MechNetwork.java b/src/main/java/resonantinduction/mechanical/network/MechNetwork.java deleted file mode 100644 index a9a7acd90..000000000 --- a/src/main/java/resonantinduction/mechanical/network/MechNetwork.java +++ /dev/null @@ -1,234 +0,0 @@ -package resonantinduction.mechanical.network; - -import java.util.HashMap; -import java.util.Iterator; - -import net.minecraftforge.common.ForgeDirection; -import universalelectricity.api.net.IConnector; -import universalelectricity.core.net.ConnectionPathfinder; -import universalelectricity.core.net.Network; -import universalelectricity.core.net.NetworkTickHandler; - -/** Simple network to translate speed and force using mechanical rotation - * - * @author DarkGuardsman */ -public class MechNetwork extends Network implements IMechNetwork -{ - private int force = 0; - private int speed = 0; - private int resistance = 0; - - private HashMap forceMap = new HashMap(); - - @Override - public void update() - { - - } - - @Override - public void reconstruct() - { - if (this.getConnectors().size() > 0) - { - // Reset all values related to wires - this.getNodes().clear(); - this.forceMap.clear(); - this.resistance = 0; - this.force = 0; - this.speed = 0; - - // Iterate threw list of wires - Iterator it = this.getConnectors().iterator(); - - while (it.hasNext()) - { - IMechConnector conductor = it.next(); - - if (conductor != null) - { - this.reconstructConductor(conductor); - } - else - { - it.remove(); - } - } - - if (this.getNodes().size() > 0) - { - NetworkTickHandler.addNetwork(this); - } - } - } - - /** Segmented out call so overriding can be done when conductors are reconstructed. */ - protected void reconstructConductor(IMechConnector conductor) - { - conductor.setNetwork(this); - - for (int i = 0; i < conductor.getConnections().length; i++) - { - reconstructHandler(conductor.getConnections()[i], ForgeDirection.getOrientation(i).getOpposite()); - } - - this.resistance += conductor.getResistance(); - } - - /** Segmented out call so overriding can be done when machines are reconstructed. */ - protected void reconstructHandler(Object obj, ForgeDirection side) - { - if (obj != null && !(obj instanceof IMechConnector)) - { - if (obj instanceof IMechMachine) - { - ForceWrapper[] set = this.forceMap.get((IMechMachine)obj); - if (set == null) - { - set = new ForceWrapper[6]; - } - this.getNodes().add((IMechMachine) obj); - set[side.ordinal()] = new ForceWrapper(((IMechMachine) obj).getForceSide(side.getOpposite()),((IMechMachine) obj).getForceSide(side.getOpposite())); - this.forceMap.put((IMechMachine) obj, set); - } - } - } - - @Override - public boolean canUpdate() - { - return true; - } - - @Override - public boolean continueUpdate() - { - return true; - } - - @Override - public IMechNetwork merge(IMechNetwork network) - { - if (network.getClass().isAssignableFrom(this.getClass()) && network != this) - { - MechNetwork newNetwork = new MechNetwork(); - newNetwork.getConnectors().addAll(this.getConnectors()); - newNetwork.getConnectors().addAll(network.getConnectors()); - - network.getConnectors().clear(); - network.getNodes().clear(); - this.getConnectors().clear(); - this.getNodes().clear(); - - newNetwork.reconstruct(); - return newNetwork; - } - - return null; - } - - @Override - public void split(IMechConnector splitPoint) - { - this.removeConnector(splitPoint); - this.reconstruct(); - - /** Loop through the connected blocks and attempt to see if there are connections between the - * two points elsewhere. */ - Object[] connectedBlocks = splitPoint.getConnections(); - - for (int i = 0; i < connectedBlocks.length; i++) - { - Object connectedBlockA = connectedBlocks[i]; - - if (connectedBlockA instanceof IMechConnector) - { - for (int ii = 0; ii < connectedBlocks.length; ii++) - { - final Object connectedBlockB = connectedBlocks[ii]; - - if (connectedBlockA != connectedBlockB && connectedBlockB instanceof IMechConnector) - { - ConnectionPathfinder finder = new ConnectionPathfinder((IConnector) connectedBlockB, splitPoint); - finder.findNodes((IConnector) connectedBlockA); - - if (finder.results.size() <= 0) - { - try - { - /** The connections A and B are not connected anymore. Give them both - * a new common network. */ - IMechNetwork newNetwork = new MechNetwork(); - for (IConnector node : finder.closedSet) - { - if (node != splitPoint && node instanceof IMechConnector) - { - newNetwork.addConnector((IMechConnector) node); - } - } - newNetwork.reconstruct(); - } - catch (Exception e) - { - e.printStackTrace(); - } - - } - } - } - } - } - } - - @Override - public void split(IMechConnector connectorA, IMechConnector connectorB) - { - this.reconstruct(); - - /** Check if connectorA connects with connectorB. */ - ConnectionPathfinder finder = new ConnectionPathfinder(connectorB); - finder.findNodes(connectorA); - - if (finder.results.size() <= 0) - { - /** The connections A and B are not connected anymore. Give them both a new common - * network. */ - IMechNetwork newNetwork = new MechNetwork(); - - for (IConnector node : finder.closedSet) - { - if (node instanceof IMechConnector) - { - newNetwork.addConnector((IMechConnector) node); - } - } - - newNetwork.reconstruct(); - } - } - - @Override - public int getTorque() - { - return this.force; - } - - @Override - public int getRotationPerTick() - { - return this.speed; - } - - public static class ForceWrapper - { - public int force = 0; - public int speed = 0; - - public ForceWrapper(int force, int speed) - { - this.force = force; - this.speed = speed; - } - } - -} diff --git a/src/main/java/resonantinduction/mechanical/network/MechanicalNetwork.java b/src/main/java/resonantinduction/mechanical/network/MechanicalNetwork.java new file mode 100644 index 000000000..7b836bb64 --- /dev/null +++ b/src/main/java/resonantinduction/mechanical/network/MechanicalNetwork.java @@ -0,0 +1,259 @@ +package resonantinduction.mechanical.network; + +import java.util.HashMap; +import java.util.Iterator; + +import net.minecraftforge.common.ForgeDirection; +import universalelectricity.api.net.IConnector; +import universalelectricity.core.net.ConnectionPathfinder; +import universalelectricity.core.net.Network; +import universalelectricity.core.net.NetworkTickHandler; + +/** + * A mechanical network for translate speed and force using mechanical rotations. + * + * Useful Formula: + * + * Power is the work per unit time. + * Power (W) = Torque (Strength of the rotation, Newton Meters) x Speed (Angular Velocity, RADIAN + * PER SECOND). + * *OR* + * Power = Torque / Time + * + * Torque = r (Radius) * F (Force) * sin0 (Direction/Angle of the force applied. 90 degrees if + * optimal.) + * + * @author DarkGuardsman + */ +public class MechanicalNetwork extends Network implements IMechanicalNetwork +{ + private int force = 0; + private int speed = 0; + private int resistance = 0; + + private HashMap forceMap = new HashMap(); + + @Override + public void update() + { + + } + + @Override + public void reconstruct() + { + if (this.getConnectors().size() > 0) + { + // Reset all values related to wires + this.getNodes().clear(); + this.forceMap.clear(); + this.resistance = 0; + this.force = 0; + this.speed = 0; + + // Iterate threw list of wires + Iterator it = this.getConnectors().iterator(); + + while (it.hasNext()) + { + IMechanicalConnector conductor = it.next(); + + if (conductor != null) + { + this.reconstructConductor(conductor); + } + else + { + it.remove(); + } + } + + if (this.getNodes().size() > 0) + { + NetworkTickHandler.addNetwork(this); + } + } + } + + /** Segmented out call so overriding can be done when conductors are reconstructed. */ + protected void reconstructConductor(IMechanicalConnector conductor) + { + conductor.setNetwork(this); + + for (int i = 0; i < conductor.getConnections().length; i++) + { + reconstructHandler(conductor.getConnections()[i], ForgeDirection.getOrientation(i).getOpposite()); + } + + this.resistance += conductor.getResistance(); + } + + /** Segmented out call so overriding can be done when machines are reconstructed. */ + protected void reconstructHandler(Object obj, ForgeDirection side) + { + if (obj != null && !(obj instanceof IMechanicalConnector)) + { + if (obj instanceof IMechanical) + { + ForceWrapper[] set = this.forceMap.get((IMechanical) obj); + if (set == null) + { + set = new ForceWrapper[6]; + } + this.getNodes().add((IMechanical) obj); + set[side.ordinal()] = new ForceWrapper(((IMechanical) obj).getForceSide(side.getOpposite()), ((IMechanical) obj).getForceSide(side.getOpposite())); + this.forceMap.put((IMechanical) obj, set); + } + } + } + + @Override + public boolean canUpdate() + { + return true; + } + + @Override + public boolean continueUpdate() + { + return true; + } + + @Override + public IMechanicalNetwork merge(IMechanicalNetwork network) + { + if (network.getClass().isAssignableFrom(this.getClass()) && network != this) + { + MechanicalNetwork newNetwork = new MechanicalNetwork(); + newNetwork.getConnectors().addAll(this.getConnectors()); + newNetwork.getConnectors().addAll(network.getConnectors()); + + network.getConnectors().clear(); + network.getNodes().clear(); + this.getConnectors().clear(); + this.getNodes().clear(); + + newNetwork.reconstruct(); + return newNetwork; + } + + return null; + } + + @Override + public void split(IMechanicalConnector splitPoint) + { + this.removeConnector(splitPoint); + this.reconstruct(); + + /** + * Loop through the connected blocks and attempt to see if there are connections between the + * two points elsewhere. + */ + Object[] connectedBlocks = splitPoint.getConnections(); + + for (int i = 0; i < connectedBlocks.length; i++) + { + Object connectedBlockA = connectedBlocks[i]; + + if (connectedBlockA instanceof IMechanicalConnector) + { + for (int ii = 0; ii < connectedBlocks.length; ii++) + { + final Object connectedBlockB = connectedBlocks[ii]; + + if (connectedBlockA != connectedBlockB && connectedBlockB instanceof IMechanicalConnector) + { + ConnectionPathfinder finder = new ConnectionPathfinder((IConnector) connectedBlockB, splitPoint); + finder.findNodes((IConnector) connectedBlockA); + + if (finder.results.size() <= 0) + { + try + { + /** + * The connections A and B are not connected anymore. Give them both + * a new common network. + */ + IMechanicalNetwork newNetwork = new MechanicalNetwork(); + for (IConnector node : finder.closedSet) + { + if (node != splitPoint && node instanceof IMechanicalConnector) + { + newNetwork.addConnector((IMechanicalConnector) node); + } + } + newNetwork.reconstruct(); + } + catch (Exception e) + { + e.printStackTrace(); + } + + } + } + } + } + } + } + + @Override + public void split(IMechanicalConnector connectorA, IMechanicalConnector connectorB) + { + this.reconstruct(); + + /** Check if connectorA connects with connectorB. */ + ConnectionPathfinder finder = new ConnectionPathfinder(connectorB); + finder.findNodes(connectorA); + + if (finder.results.size() <= 0) + { + /** + * The connections A and B are not connected anymore. Give them both a new common + * network. + */ + IMechanicalNetwork newNetwork = new MechanicalNetwork(); + + for (IConnector node : finder.closedSet) + { + if (node instanceof IMechanicalConnector) + { + newNetwork.addConnector((IMechanicalConnector) node); + } + } + + newNetwork.reconstruct(); + } + } + + @Override + public int getTorque() + { + return this.force; + } + + @Override + public int getAngularVelocity() + { + return this.speed; + } + + public static class ForceWrapper + { + public int force = 0; + public int speed = 0; + + public ForceWrapper(int force, int speed) + { + this.force = force; + this.speed = speed; + } + } + + @Override + public long getPower() + { + return this.getTorque() * this.getAngularVelocity(); + } + +} diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/MachineBlackOffSide.png b/src/main/resources/assets/resonantinduction/textures/blocks/MachineBlackOffSide.png deleted file mode 100644 index 818dae7ac244fff2bb6ca4947d89566cb7e3b06d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1815 zcmV+y2k7{TP)`3IQvNA`Jil03B&m zSad^gZEa<4bN~PV002XBWnpw>WFU8GbZ8()Nlj2>E@cM*00w(WL_t(o!@ZYHZyd)F zhM%hL`PwD9q6N_skl0CVm~)w<*6-a{RYXAMA95}@ zr=*kt@ZK#BOEF3*clLh$)-UUGs!HFtlwu6s3En%*z&8$6CB=;Qj;3iSC6iL2lmrMM zhzgDOs8g(fDtO<}_AO$K$@d>PU-uBVHhyVd`e+8 z444_tIbw{IQph<|iji~1`-Y}*c;8S;q3b$^^*~OA&AkoJ{{0;11f$G>SD)TH{AyUE zDz$dQKtJ^4oY>skAX4|ebHtc%u0ho?g$Y$5XQOTFUeh#~8Kq>pzN2khq6N$pFt*zf z=N-;F%nVgQL@Nk$Dz%2H+`G47b8<}Ec074t?)qtvF8@J??5f%ErC8o5nC8vrdzu)iY^f{Wg<>+Y5Za0Ex1)+B}2ta|&y$#35 zCkvpiUR*7}N;z|Ue1wRSOQvZWFc1V&#d}Xm84;mr>iga~Wj{`p+fB6hGD2E7dU<66kv%u#!S;VtQap|TyuKwbf#OOWFx14rpSJ`~l`Sv7|1{*^ zN^`<{Puq5w*{lh&08m8Gz8@B1g%AQM)plQ}WWnFu+}r_)oN6Jo3v8mpPhx!`jy3nfH^?ahw1_3WpSynkG(8Hnm>k z$cyLC`0TU52OqrmqZzokxZwQ!oJWry-FfCOk00~?`w{0IIc9Ro=sasStw&YrOn9K7 zN|n$U>fC>GGxGH5(^t~{ed~vwnWhN|Qm=F|5<-}L34Pz=Roz0vZ!f=oWf#dW+Flel_lPLN8h)+^Q*W1@0U{mFQR<$<+pdlK~)!H!!Rs89^m=&XNV|G z<9YDljGOJA%gam5sJ))snc!gaFh_JWkC*@e002ovPDHLk FV1oKTV~qd+ diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/MachineBlackOnSide.png b/src/main/resources/assets/resonantinduction/textures/blocks/MachineBlackOnSide.png deleted file mode 100644 index 4a6f62a751254789119da662b6331f42d5dbc57f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1907 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 diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/MachineRedOffSide.png b/src/main/resources/assets/resonantinduction/textures/blocks/MachineRedOffSide.png deleted file mode 100644 index f7dd580692efeae711007bded65b6c4556160907..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1781 zcmV`4>SNz5^Dee03B&m zSad^gZEa<4bN~PV002XBWnpw>WFU8GbZ8()Nlj2>E@cM*00vn}L_t(o!@ZZgj~vGl z#(!1a^V+?;<%#Br2U~()a4rXu040hKurmLJ2AnuQ_z$oGCN`8PFeJc+1W2MpllR!& znSN9|=-D9;qz#h-+`wRGdV9KRs=n{5YI*qZVF6H8R0Xp_eXjR?-!V;r!w{*zZQD|S zVg+@AcOHOJ3gb9ZN}=mIcDp@o+W_F417I8{N-30Lc!1x&_ZwnNG>s>OMB93-6kDsGu}Izrok+el3|tr z0R&N@@g8+bF;E5X8`{1_im==5XxkPLa!!OW@#N`uw5`WEhesgI-aDuC{lG8`6m0%V zVKoetQgF@@W5mqJIb&AHIpcjp(>T0uFf+QYV^|O5WNhwjc>1qrI42ZrcD&m3-r-ln z8da&e8wUEJC+EcG-Ug96@0}yYgmVq5jwwv23ON_rw$3$8Ln#HbOxJg`ZA&bHQWPj` zw%tK;j{fU08~x8#%&75cs1J3i!^TCa~Nr4UnOzuWQLrlC0}V$6s@jEN}(O0gq{yJNT8&1LuXzuc_U_oPyp7xqXglha%a?t(@EVYOP(wk=bbm_mG`(C3_LL_>g5 z5K&@?jQjB}R#Hls*%G*v;u6EvtZdorjhsk1;k~DAJ4z|DCddLn5kdQYAjY^TotdGt z%)S_|*B#EeMTRRKWhvhWaRX2hVYMD+gjR!=GnQ@cZfw3@R|6F197EsNRK!S(;dzg- z9+;*HZ)SukE)B_pvj;Qqj1Z=!-SP*8dyUaFGvb|RoF-H~DerMk2~(^>bjV3<5|plO z2qDn-Jy+M)+`oUHM~@yczVp+W!xhy9a9XMKd=Ee>`im8&DUedF1%lw5LaB6LKzPVk z&XuPzMw+H&yWO&0tr+)vPESvH>;7Bhlu0v?oVukcO*!M8TdHRWaW*WZlyR;~atMKx zYPqjnvfyuTZ|?x7YIj6bDJgMz`R5;14?g+icS~=ePUrJLVH`u%0q@;HL+2fB*O6kP zakW5gHXAHuVSBry zZ9V&GHPehi;IiJiG%TPzWHXM+4c1`AAh)_sFG8rZ95R* zMcomRih%7#2gvt`{y`%42e)aQr|L=!W0576^@#VL7 z#6eY;&4yt>^?7Z0_UtJlO4E2AJUHWayXW!a$CN^?^~kdRu;-x}>AG&&r|UcR`#t{# X3bWpo?S3$a00000NkvXXu0mjfBMMf( diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/MachineRedOnSide.png b/src/main/resources/assets/resonantinduction/textures/blocks/MachineRedOnSide.png deleted file mode 100644 index fe4acacdd7bf012f9ac398e66c0b523418b8f080..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1871 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/firebox_top_off.png b/src/main/resources/assets/resonantinduction/textures/blocks/firebox_top_off.png new file mode 100644 index 0000000000000000000000000000000000000000..1197fd466792ced2f329f1e454b168ac3400273a GIT binary patch literal 1625 zcmV-f2B!ImP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qRNAp5A000HZNkl3_5y|FpHWB|nl3K&4WV z!C)Y{T+XP`XvpE=p{<+ErW_w1%hA!1tq%?kWHOmZr_+&oy)Ly{ODBs#dGF0B|Whk=VCGC`=?0W(;z7@{KiwF*ver z7+Dna8+T(60PH(Z_OV4+ZU8J63;U5uB_m~t?QcR6*eLexcKa3p2?Y;=Y?L4>+zI0{ ztfge!$SP0ES+67){i2-oa&k5(OC_@{!R{Z@4)^8DswKTrQl^cZ%-T6wbW3)2(F0hmsww*aUBc%hKDcokDIQ!uJ$Y#&0=S`9CHc?Anym3b?Wi30flxmB02MgY9xoPQMp>KS*P97V2r@ZfGYa(u_*!F0H!i>Utojy`rr9k(;5@;eqPPnNB=Vuh(p!s)8E;kB8TM zAsLh9aoG})JOIdgSdxEK8FCQrefI2`JbLs@)M z>uOkyX{DeOzPTRbp6M8d zL!Nm3T2}Vn{bm3NAv(!5Z^2&r8%emmy=_!X$2D_{vg%i4sWj6B<2!~u?tWtox^W24 zAlp627=Yck5dd@&ch7;1M&zjW_V%m~6jO0CPW-t&VEB$P-0eo+ym@15yy9NKOUTxX z`;t%oEeFB2Nl3T>a5UtAmmwjbrf1h}mG7@!y)pxSTL;4)9Pc=Q)!bYJuVF0`j&}aC*(FeQ}GAex*001w%Z{`fZLYoOPxZktix!;^MG8f~DR*pVg6abx( z5I6uT4H*x`MiP>x0LZJb=fJp`wYIy`UXP5&{pHJ-1_0xP0B`v1FPItq2mr>p06NJ5 zMl&)SeW2g(+Yit|!QQs^{6m|BN9BY~y+u2at6{_BAl!{%$P*7*XxOgChX&x}+5@9{ z+H}(7s@00gZOj61i##4!Ba8=T*Yf~cbOQN2t!YQpCZof}_nl^HXxCz10{T#C_+_pKTwSYBewgXF6O~+G^<$UrxL7@2aC- zs7Ox%Tr{=+tLHBD&EV%4MpF#~I;l2)3vPtKbHJZu3=RfJZvU-RGw)2vdwl~;bga&m zcn=I}N%?rvlrQU^mRu;^a$HBTzM8b=*P4KrItxDN+ktP^h*T#R^(UD(Bm>|-cn|o4 z>L-1FdDKg<2n2Ed!b5Bp=%?RM?Q_arU?Hvr4!^1J^z-SEJVqb>Ol XH=3N1ltk4*00000NkvXXu0mjfQjz(? literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/firebox_top_on.png b/src/main/resources/assets/resonantinduction/textures/blocks/firebox_top_on.png new file mode 100644 index 0000000000000000000000000000000000000000..eee5ff8d379e29143ad901892f297f9e2f7859b1 GIT binary patch literal 1851 zcmV-B2gLY^P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qRNAp5A000K6Nkl+8dVBn1$Q#ZW93;rIKMQmGWi#>RA? zPNy+BIf;ph3Ehv5j-p&HBb&`4nM@*)NML+?9Fa&w_xx=>pV!|S3 z_xXG()9dx>x!-T8u6R7Y0e~ju>T(V1k0{XPa;Y+sF(>c1Cs7$!@*2hDrC@&3+*C*a zJU2jjPF-}%I)GZOrXL=U+ZN{Pzb9mawSAw-WHtaWptxF=&khh_&PJRlB|Ml;`DFEC zAs@z}LI|^YKNgBn#76pI4Zes>WEdwK4v0;pwzsAa>l2GA@;TYg7b zl*v~|BDM=m+$jL28P{+)C~oiwS{ne*KHs+oS883lpD)JHoQh$-5JxKLPymB{&nke0 zY#ejr7RmyEyuUAX;O1+ab>GO*tu_FYab~^C1ocq)N%+D@fAsgV;?CoRn9LueLkGn3{^qaw?%GHHQiGNI?p zDy|B^_`~FU(Ct8dGOB^dI3SQ_DU72cjC`aY=6iAN^=|z4=_c&myLbJ(S%_jmXucR% zaV9B>MVVv@Wm0)G8d09Pxw#DhrVvp%D_~fdshmVh z)F&foh-t}l?Q|#3cz5G#YZv}{rwxBM+i+`fGgd$7z{;s^##Eo~`ar6BxxN)Qd*Wc>IFS8vucVH*Z4D7kRK(>VT<)Y?Y=L5CE+(llCisniLcA{BitYoOM5r z?~nIlMS$GMwBxIR9r*QFJASP9D$k+mm}HI&E&_m+kuER*m}%rOu4oBDMkxUVgxSQv zblRt7w;{EjJm(i4!zbP+aW1nHmy+A?U9K0OjqSl|wi6$}@RSXJJ)>X)pmIKdG8qGG z&E#pR1BF6CKZuTG4fRXSAJa}a5p`+Tt7R-Kmr}|{Iv?MTONky_eq}4pWp}Qh*Tikh z(_;!?cFh7)Nw3Oek&DM;%Gc5hOj+dcz&)91f$Ca6Al0%KPE-<75v9mTb1~BCyu?FzWlw0l>rOhsiTi9}G)@1?I z5OdSag@gpHtczjCL;x4iUOx01_uL%LkQ1Ix#hk-&S8W--}dXV zY6?r`r0xr`LCncKuvD_6{LY{>LCBJyPTLlsF0Kl|L}WM|(pim-gMJ^__q3jqDv}NC zf>miQ4Joy(5hv$!c)5`kE5wi&0Eg02|HX1kGBcRpu^Cmw4V1}jGqYfe3rq}{k&KOl z4a7gZAMud`Dr81xfU>mJIU&vi#e^G2X45#?%uC8ekc&E{70c8lIp353T#{aJSY`*_ zX(1Ase5e`8OhHlr=7aNq8A$F0-3h?Nf&wsR;aG0s;9igA=Ftkk6om)&$0V1_>Bs#f pK7^|RsMqWF{m*HO1s)vr;eTHd_0Ro8ffoP(002ovPDHLkV1oZYSup?r literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/material_steel_shiny.png b/src/main/resources/assets/resonantinduction/textures/blocks/material_steel_shiny.png new file mode 100644 index 0000000000000000000000000000000000000000..fc5bb2d53c45c597880bccbe05e3056cad7593cf GIT binary patch literal 2942 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 M07*qoM6N<$f_u?qQvd(} literal 0 HcmV?d00001