diff --git a/src/main/java/mods/eln/Eln.java b/src/main/java/mods/eln/Eln.java index 2e54e76a4..e2e6ba953 100644 --- a/src/main/java/mods/eln/Eln.java +++ b/src/main/java/mods/eln/Eln.java @@ -53,6 +53,8 @@ import mods.eln.ore.OreDescriptor; import mods.eln.ore.OreItem; import mods.eln.packets.*; +import mods.eln.railroad.ElectricMinecartItem; +import mods.eln.railroad.EntityElectricMinecart; import mods.eln.server.*; import mods.eln.server.console.ElnConsoleCommands; import mods.eln.signalinductor.SignalInductorDescriptor; @@ -61,9 +63,6 @@ import mods.eln.sim.ThermalLoadInitializerByPowerDrop; import mods.eln.sim.mna.component.Resistor; import mods.eln.sim.nbt.NbtElectricalLoad; -import mods.eln.simplenode.DeviceProbeBlock; -import mods.eln.simplenode.DeviceProbeEntity; -import mods.eln.simplenode.DeviceProbeNode; import mods.eln.simplenode.computerprobe.ComputerProbeBlock; import mods.eln.simplenode.computerprobe.ComputerProbeEntity; import mods.eln.simplenode.computerprobe.ComputerProbeNode; @@ -144,6 +143,7 @@ import mods.eln.transparentnode.heatfurnace.HeatFurnaceDescriptor; import mods.eln.transparentnode.powercapacitor.PowerCapacitorDescriptor; import mods.eln.transparentnode.powerinductor.PowerInductorDescriptor; +import mods.eln.railroad.OverheadLinesDescriptor; import mods.eln.transparentnode.solarpanel.SolarPanelDescriptor; import mods.eln.transparentnode.teleporter.TeleporterDescriptor; import mods.eln.transparentnode.teleporter.TeleporterElement; @@ -688,6 +688,7 @@ public void preInit(FMLPreInitializationEvent event) { //registerFloodlight(68); registerFestive(69); registerFab(70); + registerOverheadWires(71); //ITEM REGISTRATION @@ -719,6 +720,7 @@ public void preInit(FMLPreInitializationEvent event) { registerFuelBurnerItem(124); registerPortableNaN(); // 125 registerBasicItems(126); + registerElectricMinecartItems(127); OreDictionary.registerOre("blockAluminum", arcClayBlock); OreDictionary.registerOre("blockSteel", arcMetalBlock); @@ -773,6 +775,24 @@ private void registerFab(int id) { }*/ } + private void registerOverheadWires(int id) { + int subId; + { + subId = 0; + OverheadLinesDescriptor desc = new OverheadLinesDescriptor("Overhead Lines", + obj.getObj("OverheadGantry")); + transparentNodeItem.addDescriptor(subId + (id << 6), desc); + } + /* + { + subId = 1; + UnderTrackPowerDescriptor desc = new UnderTrackPowerDescriptor("Under Track Power", + obj.getObj("OverheadGantry")); + transparentNodeItem.addDescriptor(subId + (id << 6), desc); + } + */ + } + private void registerGridDevices(int id) { int subId; { @@ -906,6 +926,7 @@ public void load(FMLInitializationEvent event) { // registerReplicator(); + registerElectricMinecart(); // recipeEnergyConverter(); @@ -4690,7 +4711,7 @@ private void registerTransparentNodeMisc(int id) { g.addRectangle(-4, -1, 2, 2, 0, 0); g.addElement(0, 1, 0); //g.addElement(0, 2, 0); - g.addElement(-1, 0, 0, ghostBlock, ghostBlock.tFloor); + g.addElement(-1, 0, 0, ghostBlock, GhostBlock.tFloor); /* g.addElement(1, 0, 0,ghostBlock,ghostBlock.tLadder); g.addElement(1, 1, 0,ghostBlock,ghostBlock.tLadder); g.addElement(1, 2, 0,ghostBlock,ghostBlock.tLadder);*/ @@ -5752,6 +5773,17 @@ private static void registerBasicItems(int id) { } } + private void registerElectricMinecartItems(int id) { + int subId; + String name; + { + subId = 0; + name = TR_NAME(Type.NONE, "Electric Minecart"); + ElectricMinecartItem minecartItem = new ElectricMinecartItem(name); + sharedItem.addElement(subId + (id << 6), minecartItem); + } + } + public DataLogsPrintDescriptor dataLogsPrintDescriptor; private void recipeGround() { @@ -8521,6 +8553,14 @@ private void registerReplicator() { } + private int electricMinecartId = -1; + + private void registerElectricMinecart() { + electricMinecartId = EntityRegistry.findGlobalUniqueEntityId(); + Utils.println("Electric Minecrart registered at " + electricMinecartId); + EntityRegistry.registerGlobalEntityID(EntityElectricMinecart.class, TR_NAME(Type.ENTITY, "ElectricMinecart"), electricMinecartId); + } + // Registers WIP items. private void registerWipItems() { } diff --git a/src/main/java/mods/eln/railroad/ElectricMinecartItem.kt b/src/main/java/mods/eln/railroad/ElectricMinecartItem.kt new file mode 100644 index 000000000..209ba5619 --- /dev/null +++ b/src/main/java/mods/eln/railroad/ElectricMinecartItem.kt @@ -0,0 +1,40 @@ +package mods.eln.railroad + +import mods.eln.generic.GenericItemUsingDamageDescriptor +import net.minecraft.block.BlockRailBase +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.ItemStack +import net.minecraft.world.World + +class ElectricMinecartItem(name: String) : GenericItemUsingDamageDescriptor(name) { + override fun onItemUse( + stack: ItemStack?, + player: EntityPlayer?, + world: World?, + x: Int, + y: Int, + z: Int, + side: Int, + vx: Float, + vy: Float, + vz: Float + ): Boolean { + if (world == null || stack == null) return false + return if (BlockRailBase.func_150051_a(world.getBlock(x, y, z))) { + if (!world.isRemote) { + val minecart = EntityElectricMinecart( + world, + (x.toFloat() + 0.5f).toDouble(), + (y.toFloat() + 0.5f).toDouble(), + (z.toFloat() + 0.5f).toDouble() + ) + if (stack.hasDisplayName()) { + minecart.setMinecartName(stack.displayName) + } + world.spawnEntityInWorld(minecart) + } + --stack.stackSize + true + } else false + } +} diff --git a/src/main/java/mods/eln/railroad/EntityElectricMinecart.kt b/src/main/java/mods/eln/railroad/EntityElectricMinecart.kt new file mode 100644 index 000000000..9b1f9ea0d --- /dev/null +++ b/src/main/java/mods/eln/railroad/EntityElectricMinecart.kt @@ -0,0 +1,149 @@ +package mods.eln.railroad + +import mods.eln.Eln +import mods.eln.misc.Coordinate +import mods.eln.misc.Utils +import mods.eln.node.NodeManager +import mods.eln.sim.mna.misc.MnaConst +import net.minecraft.block.Block +import net.minecraft.entity.item.EntityMinecart +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.init.Blocks +import net.minecraft.server.MinecraftServer +import net.minecraft.world.World +import kotlin.math.abs +import kotlin.math.sign + +class EntityElectricMinecart(world: World, x: Double, y: Double, z: Double): EntityMinecart(world, x, y, z) { + + private var lastPowerElement: RailroadPowerInterface? = null + private val locomotiveMaximumResistance = 200.0 + var energyBufferTargetJoules = 10_000.0 + var energyBufferJoules = 0.0 + + var count = 0 + + override fun onUpdate() { + super.onUpdate() + val cartCoordinate = Coordinate(posX.toInt(), posY.toInt(), posZ.toInt(), worldObj) + val overheadWires = getOverheadWires(cartCoordinate) + val underTrackWires = getUnderTrackWires(cartCoordinate) + + when (val oldPowerElement = lastPowerElement) { + overheadWires, underTrackWires, null -> { + // references existing overhead wires or under track wires, or nothing + } + else -> { + // references old overhead wires or under track wires that are not the current ones + energyBufferJoules += PoweredMinecartSimulationSingleton.cartCollectEnergy(this) + Eln.logger.info("Deregister cart from $oldPowerElement") + oldPowerElement.deregisterCart(this) + } + } + + val currentElement: RailroadPowerInterface? = underTrackWires ?: overheadWires + + if (currentElement != null) { + if (currentElement != lastPowerElement) { + Eln.logger.info("Register cart to $currentElement") + currentElement.registerCart(this) + } + + if (energyBufferJoules < energyBufferTargetJoules) { + val chargeRateInv = energyBufferTargetJoules / (abs(energyBufferTargetJoules - energyBufferJoules) * 2) + PoweredMinecartSimulationSingleton.powerCart(this, chargeRateInv * locomotiveMaximumResistance, 0.1) + } else { + PoweredMinecartSimulationSingleton.powerCart(this, MnaConst.highImpedance, 0.1) + } + energyBufferJoules += PoweredMinecartSimulationSingleton.cartCollectEnergy(this) + } + + if (count > 20) count = 0 + if (count == 0) { + MinecraftServer.getServer().entityWorld.playerEntities.forEach {it -> + val player = it as EntityPlayer + Utils.addChatMessage(player, "Cart Energy: ${Utils.plotEnergy(energyBufferJoules)}") + } + } + count++ + + lastPowerElement = currentElement + } + + var pushX: Double = 0.0 + var pushZ: Double = 0.0 + + override fun func_145821_a( + blockX: Int, + blockY: Int, + blockZ: Int, + speed: Double, + drag: Double, + block: Block?, + direction: Int + ) { + super.func_145821_a(blockX, blockY, blockZ, speed + 1, drag, block, direction) + if (energyBufferJoules > 0) { + val maxEnergy = 40.0 + var energyAvailable = maxEnergy + if (energyBufferJoules < maxEnergy) { + energyAvailable = energyBufferJoules + } + + val startingThreshold = 0.0005 + + if (abs(motionX) >= startingThreshold || abs(motionZ) >= startingThreshold) { + if (abs(motionX) < 0.5 && abs(motionZ) < 0.5) { + pushX = motionX.sign * 0.05 * (energyAvailable / maxEnergy) + pushZ = motionZ.sign * 0.05 * (energyAvailable / maxEnergy) + energyBufferJoules -= energyAvailable + } + } + } + + //Eln.logger.info("Push: ($pushX, $pushZ)") + + motionX += pushX + motionZ += pushZ + + //Eln.logger.info("Speed: ($motionX, $motionZ)") + + pushX = 0.0 + pushZ = 0.0 + } + + private fun getOverheadWires(coordinate: Coordinate): OverheadLinesElement? { + // Pass coordinate of tracks and check vertically the next 3 blocks (4 up looks visually weird) + val originalY = coordinate.y + while (coordinate.y <= (originalY + 3)) { + coordinate.y + val node = NodeManager.instance!!.getTransparentNodeFromCoordinate(coordinate) + if (node is OverheadLinesElement) { + return node + } + coordinate.y++ + } + return null + } + + private fun getUnderTrackWires(coordinate: Coordinate): UnderTrackPowerElement? { + coordinate.y -= 1 // check the block below the cart + val node = NodeManager.instance!!.getTransparentNodeFromCoordinate(coordinate) + if (node is UnderTrackPowerElement) { + return node + } + return null + } + + override fun getMinecartType(): Int { + return -1 + } + + override fun func_145817_o(): Block? { + return Blocks.iron_block + } + + override fun func_145820_n(): Block? { + return Blocks.iron_block + } +} diff --git a/src/main/java/mods/eln/railroad/OverheadLines.kt b/src/main/java/mods/eln/railroad/OverheadLines.kt new file mode 100644 index 000000000..b7911fc26 --- /dev/null +++ b/src/main/java/mods/eln/railroad/OverheadLines.kt @@ -0,0 +1,193 @@ +package mods.eln.railroad + +import mods.eln.Eln +import mods.eln.cable.CableRenderDescriptor +import mods.eln.i18n.I18N +import mods.eln.misc.Coordinate +import mods.eln.misc.Direction +import mods.eln.misc.LRDU +import mods.eln.misc.LRDUMask +import mods.eln.misc.Obj3D +import mods.eln.misc.Utils.getBlock +import mods.eln.misc.Utils.plotPower +import mods.eln.misc.Utils.plotVolt +import mods.eln.node.NodeBase +import mods.eln.node.transparent.* +import mods.eln.sim.ElectricalConnection +import mods.eln.sim.ElectricalLoad +import mods.eln.sim.mna.component.Resistor +import mods.eln.sim.mna.misc.MnaConst +import mods.eln.sim.nbt.NbtElectricalLoad +import mods.eln.railroad.PoweredMinecartSimulationSingleton.poweredMinecartSimulationData +import java.io.DataInputStream +import java.io.DataOutputStream +import java.io.IOException + +class OverheadLinesDescriptor(name: String, private val obj3D: Obj3D?): TransparentNodeDescriptor(name, OverheadLinesElement::class.java, + OverheadLinesRender::class.java +) { + override fun mustHaveFloor() = false + override fun mustHaveWall() = false + override fun mustHaveWallFrontInverse() = false + override fun mustHaveCeiling() = false + + val centenaryCableRender = CableRenderDescriptor("eln", "sprites/cable.png", + 0.95f, 0.95f) + + fun drawBase() { + obj3D?.draw("OverheadGantry") + } +} + +class OverheadLinesElement(node: TransparentNode?, + transparentNodeDescriptor: TransparentNodeDescriptor +): TransparentNodeElement(node, transparentNodeDescriptor), RailroadPowerInterface { + + val electricalLoad = NbtElectricalLoad("electricalLoad") + + init { + Eln.applySmallRs(electricalLoad) + electricalLoad.setCanBeSimplifiedByLine(true) + electricalLoadList.add(electricalLoad) + } + + override fun initialize() { + connect() + } + + private val actualSides = listOf(Direction.XN, Direction.ZN, Direction.XP, Direction.ZP) + + override fun getConnectionMask(side: Direction, lrdu: LRDU): Int { + return if (side in actualSides && (lrdu == LRDU.Down)) { + NodeBase.maskElectricalPower + } else { + 0 + } + } + + override fun getElectricalLoad(side: Direction, lrdu: LRDU): ElectricalLoad? { + return if (side in actualSides && (lrdu == LRDU.Down)) { + electricalLoad + } else { + null + } + } + + override fun networkSerialize(stream: DataOutputStream) { + super.networkSerialize(stream) + try { + node!!.lrduCubeMask.getTranslate(front.down()).serialize(stream) + } catch (e: IOException) { + e.printStackTrace() + } + } + + override fun getWaila(): Map { + val info: MutableMap = HashMap() + info[I18N.tr("Voltage")] = plotVolt("", electricalLoad.u) + if (Eln.wailaEasyMode) { + info[I18N.tr("Power")] = plotPower("", electricalLoad.i * electricalLoad.u) + } + val ss = electricalLoad.subSystem + if (ss != null) { + val subSystemSize = electricalLoad.subSystem.component.size + val textColor: String = if (subSystemSize <= 8) { + "§a" + } else if (subSystemSize <= 15) { + "§6" + } else { + "§c" + } + info[I18N.tr("Subsystem Matrix Size")] = textColor + subSystemSize + } else { + info[I18N.tr("Subsystem Matrix Size")] = "§cnull SubSystem" + } + return info + } + + class MinecartResistor: Resistor() + + override fun registerCart(cart: EntityElectricMinecart) { + if (cart !in poweredMinecartSimulationData.map { it.minecart }) { + val resistor = MinecartResistor() + val resistorLoad = ElectricalLoad() + resistorLoad.setAsPrivate() + val connection = ElectricalConnection(electricalLoad, resistorLoad) + resistor.connectTo(resistorLoad, null) + resistor.r = MnaConst.highImpedance + resistorLoad.rs = MnaConst.noImpedance + connection.r = MnaConst.noImpedance + Eln.simulator.addElectricalLoad(resistorLoad) + Eln.simulator.addElectricalComponent(connection) + Eln.simulator.addElectricalComponent(resistor) + val rrsp = RailroadResistorSlowProcess(this, cart, 0.05) + Eln.simulator.addSlowProcess(rrsp) + poweredMinecartSimulationData.add(PoweredMinecartSimulationData(cart, resistor, resistorLoad, connection, rrsp, this)) + this.needPublish() + } + } + + override fun deregisterCart(cart: EntityElectricMinecart) { + val search = poweredMinecartSimulationData.filter { it.minecart == cart } + if (search.isNotEmpty()) { + search.forEach { + if (it.owningElement == this) { + Eln.simulator.removeElectricalComponent(it.resistor) + Eln.simulator.removeElectricalComponent(it.electricalConnection) + Eln.simulator.removeElectricalLoad(it.resistorElectricalLoad) + it.resistor.breakConnection() + it.electricalConnection.breakConnection() + Eln.simulator.removeSlowProcess(it.slowProcess) + poweredMinecartSimulationData.remove(it) + this.needPublish() + } + } + } + } +} + +class OverheadLinesRender(tileEntity: TransparentNodeEntity, transparentNodeDescriptor: TransparentNodeDescriptor): + TransparentNodeElementRender(tileEntity, transparentNodeDescriptor) { + + val desc = transparentNodeDescriptor as OverheadLinesDescriptor + private val eConn = LRDUMask() + + private val boundedSides = mutableListOf() + + init { + val x = tileEntity.xCoord + val y = tileEntity.yCoord + val z = tileEntity.zCoord + boundedSides.add(Coordinate(x + 1, y, z, 0)) + boundedSides.add(Coordinate(x -1, y, z, 0)) + boundedSides.add(Coordinate(x, y + 1, z, 0)) + boundedSides.add(Coordinate(x, y - 1, z, 0)) + boundedSides.add(Coordinate(x, y, z + 1, 0)) + } + + private fun hasBlockAnySideNotBottom(): Boolean { + return boundedSides.any { + getBlock(tileEntity.worldObj, it.x.toDouble(), it.y.toDouble(),it.z.toDouble()).isOpaqueCube + } + } + + override fun draw() { + val locFront = front + if (locFront != null) { + drawCable(locFront.down(), desc.centenaryCableRender, eConn, null, true) + } + + if (hasBlockAnySideNotBottom()) { + desc.drawBase() + } + } + + override fun networkUnserialize(stream: DataInputStream) { + super.networkUnserialize(stream) + try { + eConn.deserialize(stream) + } catch (e: IOException) { + e.printStackTrace() + } + } +} diff --git a/src/main/java/mods/eln/railroad/PoweredMinecartSimulationData.kt b/src/main/java/mods/eln/railroad/PoweredMinecartSimulationData.kt new file mode 100644 index 000000000..a87f32ec5 --- /dev/null +++ b/src/main/java/mods/eln/railroad/PoweredMinecartSimulationData.kt @@ -0,0 +1,20 @@ +package mods.eln.railroad + +import mods.eln.sim.ElectricalConnection +import mods.eln.sim.ElectricalLoad +import mods.eln.sim.mna.component.Resistor + +/** + * @param minecart the electrical minecart entity instance + * @param resistor the resistor instance used by this minecart + * @param slowProcess the IProcess slow process for processing the resistor removal after the time specified. + * @param owningElement the element this minecart was most recently connected to + */ +data class PoweredMinecartSimulationData( + val minecart: EntityElectricMinecart, + var resistor: Resistor, + var resistorElectricalLoad: ElectricalLoad, + var electricalConnection: ElectricalConnection, + var slowProcess: RailroadResistorSlowProcess, + val owningElement: RailroadPowerInterface + ) diff --git a/src/main/java/mods/eln/railroad/PoweredMinecartSimulationSingleton.kt b/src/main/java/mods/eln/railroad/PoweredMinecartSimulationSingleton.kt new file mode 100644 index 000000000..4f736600c --- /dev/null +++ b/src/main/java/mods/eln/railroad/PoweredMinecartSimulationSingleton.kt @@ -0,0 +1,70 @@ +package mods.eln.railroad + +import mods.eln.Eln +import mods.eln.node.transparent.TransparentNodeElement +import mods.eln.sim.IProcess +import mods.eln.sim.mna.misc.MnaConst + +object PoweredMinecartSimulationSingleton { + val poweredMinecartSimulationData: MutableList = mutableListOf() + val minecartEnergyCache: MutableMap = mutableMapOf() + + init { + val energyMover = IProcess { time -> + poweredMinecartSimulationData.forEach { + moveEnergy(it.minecart, it.resistor.p * time) + } + } + Eln.simulator.addSlowPostProcess(energyMover) + } + + /** + * powerCart - set the power demands of the cart + * @param cart electric minecart entity instance + * @param resistance the resistance of the motor + * @param time time in seconds to request this power for the cart + */ + fun powerCart(cart: EntityElectricMinecart, resistance: Double, time: Double) { + val search = poweredMinecartSimulationData.filter { it.minecart == cart } + if (search.isEmpty()) return + val cartData = search.first() + if (cartData.resistor.r != resistance) + if (cartData.owningElement is TransparentNodeElement) + cartData.owningElement.needPublish() + // Don't draw power from the overhead lines if the voltage is too low + if (cartData.resistorElectricalLoad.u < 700.0) { + cartData.resistor.r = MnaConst.highImpedance + } else { + cartData.resistor.r = resistance + } + cartData.slowProcess.timeLeft = time + } + + /** + * cartCollectEnergy - collect the joules from the wire for the cart + * @param cart electric minecart entity instance + * @return the joules of energy from the cable + */ + fun cartCollectEnergy(cart: EntityElectricMinecart): Double { + return if (cart in minecartEnergyCache) { + val currentEnergy = minecartEnergyCache[cart]!! + minecartEnergyCache.remove(cart) + currentEnergy + } else { + 0.0 + } + } + + /** + * moveEnergy - move energy to the cart's energy cache for collection by the entity + * @param cart electric minecart entity instance + * @param joules the quantity of energy in joules + */ + private fun moveEnergy(cart: EntityElectricMinecart, joules: Double) { + minecartEnergyCache[cart] = if (cart in minecartEnergyCache) { + minecartEnergyCache[cart]!! + joules + } else { + joules + } + } +} diff --git a/src/main/java/mods/eln/railroad/RailroadPowerInterface.kt b/src/main/java/mods/eln/railroad/RailroadPowerInterface.kt new file mode 100644 index 000000000..3c614ae53 --- /dev/null +++ b/src/main/java/mods/eln/railroad/RailroadPowerInterface.kt @@ -0,0 +1,15 @@ +package mods.eln.railroad + +interface RailroadPowerInterface { + /** + * registerCart - register a cart against a power element + * @param cart electric minecart entity instance + */ + fun registerCart(cart: EntityElectricMinecart) + + /** + * deregisterCart - de-register a cart against a power element + * @param cart electric minecart entity instance + */ + fun deregisterCart(cart: EntityElectricMinecart) +} diff --git a/src/main/java/mods/eln/railroad/RailroadResistorSlowProcess.kt b/src/main/java/mods/eln/railroad/RailroadResistorSlowProcess.kt new file mode 100644 index 000000000..24ded1517 --- /dev/null +++ b/src/main/java/mods/eln/railroad/RailroadResistorSlowProcess.kt @@ -0,0 +1,15 @@ +package mods.eln.railroad + +import mods.eln.Eln +import mods.eln.sim.IProcess + +class RailroadResistorSlowProcess(val rpi: RailroadPowerInterface, val cart: EntityElectricMinecart, var timeLeft: Double): IProcess { + + override fun process(time: Double) { + if (timeLeft - time < 0.0) { + Eln.logger.warn("Automatically unregistered minecart after timeout") + rpi.deregisterCart(cart) + } + timeLeft -= time + } +} diff --git a/src/main/java/mods/eln/railroad/UnderTrackPower.kt b/src/main/java/mods/eln/railroad/UnderTrackPower.kt new file mode 100644 index 000000000..4959eec5b --- /dev/null +++ b/src/main/java/mods/eln/railroad/UnderTrackPower.kt @@ -0,0 +1,158 @@ +package mods.eln.railroad + +import mods.eln.Eln +import mods.eln.cable.CableRenderDescriptor +import mods.eln.i18n.I18N +import mods.eln.misc.* +import mods.eln.node.NodeBase +import mods.eln.node.transparent.* +import mods.eln.sim.ElectricalConnection +import mods.eln.sim.ElectricalLoad +import mods.eln.railroad.PoweredMinecartSimulationSingleton.poweredMinecartSimulationData +import mods.eln.sim.mna.component.Resistor +import mods.eln.sim.mna.misc.MnaConst +import mods.eln.sim.nbt.NbtElectricalLoad +import java.io.DataInputStream +import java.io.DataOutputStream +import java.io.IOException + +class UnderTrackPowerDescriptor(name: String, private val obj3D: Obj3D?): TransparentNodeDescriptor(name, UnderTrackPowerElement::class.java, + UnderTrackPowerRender::class.java +) { + override fun checkCanPlace(coord: Coordinate?, front: Direction): String? { + // TODO: Require support from at least one side, except top + return null + } + + val thirdRailRender = CableRenderDescriptor("eln", "sprites/cable.png", + 0.95f, 0.95f) + + fun drawBase() { + obj3D?.draw("OverheadGantry") + } +} + +class UnderTrackPowerElement(node: TransparentNode?, + transparentNodeDescriptor: TransparentNodeDescriptor +): TransparentNodeElement(node, transparentNodeDescriptor), RailroadPowerInterface { + + val electricalLoad = NbtElectricalLoad("electricalLoad") + + init { + Eln.applySmallRs(electricalLoad) + electricalLoad.setCanBeSimplifiedByLine(true) + electricalLoadList.add(electricalLoad) + } + + override fun initialize() { + connect() + } + + override fun getConnectionMask(side: Direction, lrdu: LRDU): Int { + return NodeBase.maskElectricalPower + } + + override fun getElectricalLoad(side: Direction, lrdu: LRDU): ElectricalLoad { + return electricalLoad + } + + override fun networkSerialize(stream: DataOutputStream) { + super.networkSerialize(stream) + try { + node!!.lrduCubeMask.getTranslate(front.down()).serialize(stream) + } catch (e: IOException) { + e.printStackTrace() + } + } + + override fun getWaila(): Map { + val info: MutableMap = HashMap() + info[I18N.tr("Voltage")] = Utils.plotVolt("", electricalLoad.u) + if (Eln.wailaEasyMode) { + info[I18N.tr("Power")] = Utils.plotPower("", electricalLoad.i * electricalLoad.u) + } + val ss = electricalLoad.subSystem + if (ss != null) { + val subSystemSize = electricalLoad.subSystem.component.size + val textColor: String = if (subSystemSize <= 8) { + "§a" + } else if (subSystemSize <= 15) { + "§6" + } else { + "§c" + } + info[I18N.tr("Subsystem Matrix Size")] = textColor + subSystemSize + } else { + info[I18N.tr("Subsystem Matrix Size")] = "§cnull SubSystem" + } + return info + } + + class MinecartResistor: Resistor() + + override fun registerCart(cart: EntityElectricMinecart) { + if (cart !in poweredMinecartSimulationData.map { it.minecart }) { + val resistor = MinecartResistor() + val resistorLoad = ElectricalLoad() + resistorLoad.setAsPrivate() + val connection = ElectricalConnection(electricalLoad, resistorLoad) + resistor.connectTo(resistorLoad, null) + resistor.r = MnaConst.highImpedance + resistorLoad.rs = MnaConst.noImpedance + connection.r = MnaConst.noImpedance + electricalLoadList.add(resistorLoad) + electricalComponentList.add(connection) + electricalComponentList.add(resistor) + val rrsp = RailroadResistorSlowProcess(this, cart, 0.05) + Eln.simulator.addSlowProcess(rrsp) + poweredMinecartSimulationData.add(PoweredMinecartSimulationData(cart, resistor, resistorLoad, connection, rrsp, this)) + this.electricalLoad.subSystem.invalidate() + this.needPublish() + } + } + + override fun deregisterCart(cart: EntityElectricMinecart) { + val search = poweredMinecartSimulationData.filter { it.minecart == cart } + if (search.isNotEmpty()) { + search.forEach { + if (it.owningElement == this) { + electricalComponentList.remove(it.resistor) + electricalComponentList.remove(it.electricalConnection) + electricalLoadList.remove(it.resistorElectricalLoad) + it.resistor.breakConnection() + it.electricalConnection.breakConnection() + this.electricalLoad.subSystem.invalidate() + Eln.simulator.removeSlowProcess(it.slowProcess) + poweredMinecartSimulationData.remove(it) + this.needPublish() + } + } + } + } +} + +class UnderTrackPowerRender(tileEntity: TransparentNodeEntity, transparentNodeDescriptor: TransparentNodeDescriptor): + TransparentNodeElementRender(tileEntity, transparentNodeDescriptor) { + + val desc = transparentNodeDescriptor as UnderTrackPowerDescriptor + private val eConn = LRDUMask() + + init { + val x = tileEntity.xCoord + val y = tileEntity.yCoord + val z = tileEntity.zCoord + } + + override fun draw() { + desc.drawBase() + } + + override fun networkUnserialize(stream: DataInputStream) { + super.networkUnserialize(stream) + try { + eConn.deserialize(stream) + } catch (e: IOException) { + e.printStackTrace() + } + } +} diff --git a/src/main/resources/assets/eln/lang/en_US.lang b/src/main/resources/assets/eln/lang/en_US.lang index 6cdcb8318..3699bb451 100644 --- a/src/main/resources/assets/eln/lang/en_US.lang +++ b/src/main/resources/assets/eln/lang/en_US.lang @@ -1159,3 +1159,5 @@ Fabricator.name=Fabricator Multicolor_LED_vuMeter.name=Multicolor LED vuMeter Grid_Switch.name=Grid Switch Direct_Utility_Pole.name=Direct Utility Pole +Overhead_Lines.name=Overhead Lines +Under_Track_Power.name=Under Track Power diff --git a/src/main/resources/assets/eln/model/OverheadGantry/OverheadGantry.mtl b/src/main/resources/assets/eln/model/OverheadGantry/OverheadGantry.mtl new file mode 100644 index 000000000..59a84a38e --- /dev/null +++ b/src/main/resources/assets/eln/model/OverheadGantry/OverheadGantry.mtl @@ -0,0 +1,13 @@ +# Blender MTL File: 'TestCube.blend' +# Material Count: 1 + +newmtl OverheadGantry +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 +map_Kd OverheadGantry.png diff --git a/src/main/resources/assets/eln/model/OverheadGantry/OverheadGantry.obj b/src/main/resources/assets/eln/model/OverheadGantry/OverheadGantry.obj new file mode 100644 index 000000000..de4c175c9 --- /dev/null +++ b/src/main/resources/assets/eln/model/OverheadGantry/OverheadGantry.obj @@ -0,0 +1,54 @@ +# Blender v2.78 (sub 0) OBJ File: 'TestCube.blend' +# www.blender.org +mtllib OverheadGantry.mtl +o OverheadGantry +v 0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 0.500000 -0.500000 +v 0.500000 0.500000 0.500000 +v -0.500000 0.500000 0.500000 +v -0.500000 0.500000 -0.500000 +vt 1.0000 0.0000 +vt 0.6667 0.3333 +vt 0.6667 0.0000 +vt 0.6667 0.6667 +vt 0.3333 0.3333 +vt 0.6667 0.3333 +vt 0.3333 0.3333 +vt 0.6667 0.0000 +vt 0.6667 0.3333 +vt 0.0000 0.0000 +vt 0.3333 0.3333 +vt 0.0000 0.3333 +vt 0.3333 1.0000 +vt 0.0000 0.6667 +vt 0.3333 0.6667 +vt 0.3333 0.3333 +vt 0.0000 0.3333 +vt 1.0000 0.3333 +vt 0.3333 0.6667 +vt 0.3333 0.0000 +vt 0.3333 0.0000 +vt 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 -0.0000 +vn 1.0000 -0.0000 0.0000 +vn -0.0000 -0.0000 1.0000 +vn -1.0000 -0.0000 -0.0000 +vn 0.0000 0.0000 -1.0000 +usemtl OverheadGantry +s off +f 2/1/1 4/2/1 1/3/1 +f 8/4/2 6/5/2 5/6/2 +f 5/7/3 2/8/3 1/9/3 +f 6/10/4 3/11/4 2/12/4 +f 3/13/5 8/14/5 4/15/5 +f 1/16/6 8/14/6 5/17/6 +f 2/1/1 3/18/1 4/2/1 +f 8/4/2 7/19/2 6/5/2 +f 5/7/3 6/20/3 2/8/3 +f 6/10/4 7/21/4 3/11/4 +f 3/13/5 7/22/5 8/14/5 +f 1/16/6 4/15/6 8/14/6 diff --git a/src/main/resources/assets/eln/model/OverheadGantry/OverheadGantry.png b/src/main/resources/assets/eln/model/OverheadGantry/OverheadGantry.png new file mode 100644 index 000000000..606e2b040 Binary files /dev/null and b/src/main/resources/assets/eln/model/OverheadGantry/OverheadGantry.png differ diff --git a/src/main/resources/assets/eln/textures/blocks/overheadlines.png b/src/main/resources/assets/eln/textures/blocks/overheadlines.png new file mode 100644 index 000000000..d729e4901 Binary files /dev/null and b/src/main/resources/assets/eln/textures/blocks/overheadlines.png differ