electrodynamics/src/main/scala/edx/electrical/circuit/source/battery/TileBattery.scala

282 lines
9.6 KiB
Scala
Raw Normal View History

2015-01-27 10:05:20 +01:00
package edx.electrical.circuit.source.battery
import java.util.ArrayList
2014-11-05 02:10:36 +01:00
import cpw.mods.fml.relauncher.{Side, SideOnly}
2015-01-14 12:06:03 +01:00
import edx.core.Reference
import io.netty.buffer.ByteBuf
import net.minecraft.block.material.Material
import net.minecraft.client.Minecraft
import net.minecraft.entity.EntityLivingBase
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
2014-11-05 02:10:36 +01:00
import net.minecraft.util.ResourceLocation
import net.minecraftforge.client.IItemRenderer.ItemRenderType
import net.minecraftforge.client.model.AdvancedModelLoader
import net.minecraftforge.common.util.ForgeDirection
2014-11-05 02:10:36 +01:00
import org.lwjgl.opengl.GL11._
2015-01-26 13:17:04 +01:00
import resonantengine.api.item.ISimpleItemRenderer
2015-01-26 13:28:38 +01:00
import resonantengine.core.network.discriminator.PacketType
2015-01-26 12:40:32 +01:00
import resonantengine.lib.content.prefab.TIO
import resonantengine.lib.grid.energy.EnergyStorage
import resonantengine.lib.grid.energy.electric.NodeElectricComponent
2015-01-26 13:28:38 +01:00
import resonantengine.lib.modcontent.block.ResonantTile
2015-01-26 12:40:32 +01:00
import resonantengine.lib.render.RenderUtility
import resonantengine.lib.transform.vector.Vector3
import resonantengine.lib.utility.science.UnitDisplay
import resonantengine.lib.wrapper.ByteBufWrapper._
import resonantengine.prefab.block.impl.{TBlockNodeProvider, TEnergyProvider}
2015-01-26 13:28:38 +01:00
import resonantengine.prefab.network.{TPacketReceiver, TPacketSender}
/** A modular battery box that allows shared connections with boxes next to it.
*
* @author Calclavia
*/
object TileBattery
{
2015-01-09 05:10:44 +01:00
/** Tiers: 0, 1, 2 */
final val maxTier = 2
2015-01-09 05:10:44 +01:00
@SideOnly(Side.CLIENT)
val model = AdvancedModelLoader.loadModel(new ResourceLocation(Reference.domain, Reference.modelPath + "battery/battery.tcn"))
/**
* @param tier - 0, 1, 2
* @return
*/
def getEnergyForTier(tier: Int) = Math.round(Math.pow(500000000, (tier / (maxTier + 0.7f)) + 1) / 500000000) * 500000000
}
2015-01-26 11:17:24 +01:00
class TileBattery extends ResonantTile(Material.iron) with TIO with TBlockNodeProvider with TPacketSender with TPacketReceiver with TEnergyProvider with ISimpleItemRenderer
{
2015-01-26 11:13:56 +01:00
private val electricNode = new NodeElectricComponent(this)
var energyRenderLevel = 0
nodes.add(electricNode)
2014-11-02 14:18:55 +01:00
energy = new EnergyStorage
2014-10-25 18:32:05 +02:00
textureName = "material_metal_side"
2014-10-26 15:41:40 +01:00
ioMap = 0
saveIOMap = true
2014-10-25 18:32:05 +02:00
normalRender = false
isOpaqueCube = false
itemBlock = classOf[ItemBlockBattery]
electricNode.resistance = 10
override def start()
{
super.start()
updateConnectionMask()
}
override def update()
{
super.update()
if (!world.isRemote)
{
if (isIndirectlyPowered)
{
2015-01-25 09:58:35 +01:00
//Discharge battery when current is flowing positive direction
//TODO: Allow player to set the power output
electricNode.generatePower(Math.min(energy.max * 0.0001, energy.value))
val dissipatedEnergy = electricNode.power / 20
energy -= dissipatedEnergy
}
2015-01-23 16:06:00 +01:00
else
{
//Recharge battery when current is flowing negative direction
energy += electricNode.power / 20
}
if (energy.prev != energy.value)
2015-01-25 09:58:35 +01:00
{
energyRenderLevel = Math.round((energy.value / TileBattery.getEnergyForTier(getBlockMetadata).toDouble) * 8).toInt
sendDescPacket()
}
2015-01-26 11:13:56 +01:00
/**
* Update packet when energy level changes.
2015-01-23 12:43:08 +01:00
val prevEnergyLevel = energyRenderLevel
2015-01-21 04:12:44 +01:00
energyRenderLevel = Math.round((energy.value / TileBattery.getEnergyForTier(getBlockMetadata).toDouble) * 8).toInt
if (prevEnergyLevel != energyRenderLevel)
{
markUpdate()
2015-01-23 12:43:08 +01:00
}*/
}
}
override def write(buf: ByteBuf, id: Int)
{
super.write(buf, id)
2015-01-21 04:12:44 +01:00
buf <<< energy.value
buf <<< energyRenderLevel.toByte
buf <<< ioMap
}
override def read(buf: ByteBuf, id: Int, packetType: PacketType)
{
super.read(buf, id, packetType)
2015-01-21 04:12:44 +01:00
energy.max = TileBattery.getEnergyForTier(metadata)
energy.value = buf.readDouble()
energyRenderLevel = buf.readByte()
2015-01-17 05:26:14 +01:00
ioMap = buf.readInt()
}
2014-11-02 15:53:45 +01:00
override def setIO(dir: ForgeDirection, packet: Int)
{
2014-11-02 15:53:45 +01:00
super.setIO(dir, packet)
updateConnectionMask()
}
2015-01-27 10:05:20 +01:00
def updateConnectionMask()
{
electricNode.setPositives(getInputDirections())
electricNode.setNegatives(getOutputDirections())
electricNode.reconstruct()
markUpdate()
notifyChange()
}
override def onPlaced(entityLiving: EntityLivingBase, itemStack: ItemStack)
{
if (!world.isRemote && itemStack.getItem.isInstanceOf[ItemBlockBattery])
{
2015-01-21 04:12:44 +01:00
energy.max = (TileBattery.getEnergyForTier(ItemBlockBattery.getTier(itemStack)))
energy.value = itemStack.getItem.asInstanceOf[ItemBlockBattery].getEnergy(itemStack)
2021-04-05 14:41:30 +02:00
world.setBlockMetadataWithNotify(x.toInt, y.toInt, z.toInt, ItemBlockBattery.getTier(itemStack), 3)
}
}
override def getDrops(metadata: Int, fortune: Int): ArrayList[ItemStack] =
{
val ret = new ArrayList[ItemStack]
val itemStack: ItemStack = new ItemStack(getBlockType, 1)
val itemBlock: ItemBlockBattery = itemStack.getItem.asInstanceOf[ItemBlockBattery]
2021-04-05 14:41:30 +02:00
ItemBlockBattery.setTier(itemStack, world.getBlockMetadata(x.toInt, y.toInt, z.toInt).asInstanceOf[Byte])
2015-01-21 04:12:44 +01:00
itemBlock.setEnergy(itemStack, energy.value)
ret.add(itemStack)
return ret
}
2014-11-05 02:10:36 +01:00
@SideOnly(Side.CLIENT)
override def renderInventoryItem(`type`: ItemRenderType, itemStack: ItemStack, data: AnyRef*)
2014-11-05 02:10:36 +01:00
{
glPushMatrix()
val energyLevel = ((itemStack.getItem.asInstanceOf[ItemBlockBattery].getEnergy(itemStack) / itemStack.getItem.asInstanceOf[ItemBlockBattery].getEnergyCapacity(itemStack)) * 8).toInt
RenderUtility.bind(Reference.domain, Reference.modelPath + "battery/battery.png")
var disabledParts = Set.empty[String]
disabledParts ++= Set("connector", "connectorIn", "connectorOut")
disabledParts ++= Set("coil1", "coil2", "coil3", "coil4", "coil5", "coil6", "coil7", "coil8")
disabledParts ++= Set("coil1lit", "coil2lit", "coil3lit", "coil4lit", "coil5lit", "coil6lit", "coil7lit", "coil8lit")
disabledParts ++= Set("frame1con", "frame2con", "frame3con", "frame4con")
TileBattery.model.renderAllExcept(disabledParts.toList: _*)
2014-11-05 02:10:36 +01:00
for (i <- 1 until 8)
{
if (i != 1 || !disabledParts.contains("coil1"))
{
if ((8 - i) <= energyLevel)
TileBattery.model.renderOnly("coil" + i + "lit")
else
TileBattery.model.renderOnly("coil" + i)
2014-11-05 02:10:36 +01:00
}
}
glPopMatrix()
}
@SideOnly(Side.CLIENT)
override def renderDynamic(pos: Vector3, frame: Float, pass: Int)
{
val partToDisable = Array[Array[String]](Array[String]("bottom"), Array[String]("top"), Array[String]("frame1", "frame2"), Array[String]("frame3", "frame4"), Array[String]("frame4", "frame1"), Array[String]("frame2", "frame3"))
val connectionPartToEnable = Array[Array[String]](null, null, Array[String]("frame1con", "frame2con"), Array[String]("frame3con", "frame4con"), Array[String]("frame4con", "frame1con"), Array[String]("frame2con", "frame3con"))
2014-11-05 02:10:36 +01:00
glPushMatrix()
glTranslated(pos.x + 0.5, pos.y + 0.5, pos.z + 0.5)
RenderUtility.bind(Reference.domain, Reference.modelPath + "battery/battery.png")
var disabledParts = Set.empty[String]
var enabledParts = Set.empty[String]
2014-11-05 02:10:36 +01:00
for (check <- ForgeDirection.VALID_DIRECTIONS)
{
2021-04-05 14:41:30 +02:00
if ((toVectorWorld + check).getTileEntity.isInstanceOf[TileBattery])
2014-11-05 02:10:36 +01:00
{
disabledParts ++= partToDisable(check.ordinal)
if (check == ForgeDirection.UP)
2014-11-05 02:10:36 +01:00
{
enabledParts ++= partToDisable(check.ordinal)
enabledParts += "coil1"
2014-11-05 02:10:36 +01:00
}
else if (check == ForgeDirection.DOWN)
2014-11-05 02:10:36 +01:00
{
var connectionParts = Set.empty[String]
val downDirs = ForgeDirection.VALID_DIRECTIONS.filter(_.offsetY == 0)
downDirs.foreach(s => connectionParts ++= connectionPartToEnable(s.ordinal))
2021-04-05 14:41:30 +02:00
downDirs.filter(s => (toVectorWorld + s).getTileEntity.isInstanceOf[TileBattery]).foreach(s => connectionParts --= connectionPartToEnable(s.ordinal))
enabledParts ++= connectionParts
2014-11-05 02:10:36 +01:00
}
}
//Render connectors
2014-11-05 02:10:36 +01:00
if (check.offsetY == 0)
{
glPushMatrix()
2014-11-05 02:10:36 +01:00
RenderUtility.rotateBlockBasedOnDirection(check)
glRotatef(-90, 0, 1, 0)
getIO(check) match
2014-11-05 02:10:36 +01:00
{
case 1 => TileBattery.model.renderOnly("connectorIn")
case 2 => TileBattery.model.renderOnly("connectorOut")
case _ =>
2014-11-05 02:10:36 +01:00
}
glPopMatrix()
2014-11-05 02:10:36 +01:00
}
}
enabledParts --= disabledParts
2014-11-05 02:10:36 +01:00
for (i <- 1 to 8)
{
if (i != 1 || enabledParts.contains("coil1"))
{
if ((8 - i) < energyRenderLevel)
TileBattery.model.renderOnly("coil" + i + "lit")
else
TileBattery.model.renderOnly("coil" + i)
2014-11-05 02:10:36 +01:00
}
}
disabledParts ++= Set("connector", "connectorIn", "connectorOut")
disabledParts ++= Set("coil1", "coil2", "coil3", "coil4", "coil5", "coil6", "coil7", "coil8")
disabledParts ++= Set("coil1lit", "coil2lit", "coil3lit", "coil4lit", "coil5lit", "coil6lit", "coil7lit", "coil8lit")
disabledParts ++= Set("frame1con", "frame2con", "frame3con", "frame4con")
enabledParts --= Set("coil1", "coil2", "coil3", "coil4", "coil5", "coil6", "coil7", "coil8")
TileBattery.model.renderAllExcept(disabledParts.toList: _*)
TileBattery.model.renderOnly(enabledParts.toList: _*)
/**
* Render energy tooltip
*/
if (isPlayerLooking(Minecraft.getMinecraft.thePlayer))
2015-01-21 04:12:44 +01:00
RenderUtility.renderFloatingText(new UnitDisplay(UnitDisplay.Unit.JOULES, energy.value).symbol + " / " + new UnitDisplay(UnitDisplay.Unit.JOULES, energy.max).symbol, new Vector3(0, 0.9, 0))
glPopMatrix()
2014-11-05 02:10:36 +01:00
}
override def readFromNBT(nbt: NBTTagCompound)
2015-01-17 05:26:14 +01:00
{
super.readFromNBT(nbt)
2015-01-21 04:12:44 +01:00
energy.load(nbt)
}
2015-01-17 05:26:14 +01:00
override def writeToNBT(nbt: NBTTagCompound)
{
super.writeToNBT(nbt)
2015-01-21 04:12:44 +01:00
energy.save(nbt)
2015-01-17 05:26:14 +01:00
}
2021-04-05 14:41:30 +02:00
}