251 lines
8.2 KiB
Scala
251 lines
8.2 KiB
Scala
package edx.mechanical.mech.turbine
|
|
|
|
import java.util.List
|
|
|
|
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
|
import edx.core.{Reference, Settings}
|
|
import net.minecraft.creativetab.CreativeTabs
|
|
import net.minecraft.init.{Blocks, Items}
|
|
import net.minecraft.item.{Item, ItemStack}
|
|
import net.minecraft.nbt.NBTTagCompound
|
|
import net.minecraft.util.ResourceLocation
|
|
import net.minecraft.world.biome.{BiomeGenBase, BiomeGenOcean, BiomeGenPlains}
|
|
import net.minecraftforge.client.model.AdvancedModelLoader
|
|
import net.minecraftforge.common.util.ForgeDirection
|
|
import net.minecraftforge.fluids.{Fluid, FluidStack, FluidTank, FluidTankInfo}
|
|
import org.lwjgl.opengl.GL11
|
|
import resonantengine.api.tile.IBoilHandler
|
|
import resonantengine.lib.render.RenderUtility
|
|
import resonantengine.lib.transform.vector.Vector3
|
|
import resonantengine.lib.utility.MathUtility
|
|
import resonantengine.lib.utility.inventory.InventoryUtility
|
|
import resonantengine.lib.wrapper.CollectionWrapper._
|
|
import resonantengine.lib.wrapper.NBTWrapper._
|
|
import resonantengine.prefab.block.itemblock.ItemBlockMetadata
|
|
|
|
/**
|
|
* The vertical wind turbine collects airflow.
|
|
*
|
|
* The horizontal wind turbine collects steam from steam power plants.
|
|
*
|
|
* @author Calclavia
|
|
*/
|
|
object TileWindTurbine
|
|
{
|
|
@SideOnly(Side.CLIENT)
|
|
val model = AdvancedModelLoader.loadModel(new ResourceLocation(Reference.domain, Reference.modelPath + "windTurbines.obj"))
|
|
}
|
|
|
|
class TileWindTurbine extends TileTurbine with IBoilHandler
|
|
{
|
|
/**
|
|
* Steam simulations
|
|
*/
|
|
private val gasTank = new FluidTank(1000)
|
|
/**
|
|
* Wind simulations
|
|
*/
|
|
private var openBlockCache = new Array[Byte](224)
|
|
private var checkCount = 0
|
|
private var efficiency = 0f
|
|
private var windTorque = 0d
|
|
private var nextWindTorque = 0d
|
|
|
|
//Constructor
|
|
this.itemBlock = classOf[ItemBlockMetadata]
|
|
|
|
override def update()
|
|
{
|
|
super.update()
|
|
|
|
if (!worldObj.isRemote)
|
|
{
|
|
if (tier == 0 && getDirection.offsetY == 0 && worldObj.isRaining && worldObj.isThundering && worldObj.rand.nextFloat < 0.00000008)
|
|
{
|
|
//Break under storm
|
|
InventoryUtility.dropItemStack(worldObj, new Vector3(x, y, z), new ItemStack(Blocks.wool, 1 + worldObj.rand.nextInt(2)))
|
|
InventoryUtility.dropItemStack(worldObj, new Vector3(x, y, z), new ItemStack(Items.stick, 3 + worldObj.rand.nextInt(8)))
|
|
toVectorWorld.setBlockToAir()
|
|
}
|
|
else if (getMultiBlock.isPrimary)
|
|
{
|
|
//Only execute code in the primary block
|
|
if (getDirection.offsetY == 0)
|
|
{
|
|
//This is a vertical wind turbine, generate from airflow
|
|
if (ticks % 20 == 0)
|
|
computePower()
|
|
|
|
windTorque = MathUtility.lerp(windTorque, nextWindTorque, ticks % 20 / 20d)
|
|
getMultiBlock.get.mechanicalNode.accelerate(windTorque * multiBlockRadius)
|
|
}
|
|
|
|
//Generate from steam
|
|
val steamPower = if (gasTank.getFluid != null) gasTank.drain(gasTank.getFluidAmount, true).amount else 0 * 1000 * Settings.steamMultiplier
|
|
getMultiBlock.get.mechanicalNode.accelerate(steamPower * multiBlockRadius)
|
|
}
|
|
}
|
|
}
|
|
|
|
private def computePower()
|
|
{
|
|
val checkSize = 10
|
|
val height = yCoord + checkCount / 28
|
|
val deviation = checkCount % 7
|
|
var checkDir: ForgeDirection = null
|
|
var check: Vector3 = null
|
|
val cc = checkCount / 7 % 4
|
|
|
|
cc match
|
|
{
|
|
case 0 =>
|
|
checkDir = ForgeDirection.NORTH
|
|
check = new Vector3(xCoord - 3 + deviation, height, zCoord - 4)
|
|
case 1 =>
|
|
checkDir = ForgeDirection.WEST
|
|
check = new Vector3(xCoord - 4, height, zCoord - 3 + deviation)
|
|
case 2 =>
|
|
checkDir = ForgeDirection.WEST
|
|
check = new Vector3(xCoord - 4, height, zCoord - 3 + deviation)
|
|
case 3 =>
|
|
checkDir = ForgeDirection.EAST
|
|
check = new Vector3(xCoord + 4, height, zCoord - 3 + deviation)
|
|
}
|
|
|
|
var openAirBlocks = 0
|
|
|
|
while (openAirBlocks < checkSize && world.isAirBlock(check.xi, check.yi, check.zi))
|
|
{
|
|
check.add(checkDir)
|
|
openAirBlocks += 1
|
|
}
|
|
|
|
efficiency = efficiency - openBlockCache(checkCount) + openAirBlocks
|
|
openBlockCache(checkCount) = openAirBlocks.toByte
|
|
checkCount = (checkCount + 1) % (openBlockCache.length - 1)
|
|
val multiblockMultiplier = (multiBlockRadius / 2) * (multiBlockRadius / 2)
|
|
|
|
val materialMultiplier = tier match
|
|
{
|
|
case 0 => 1.1f
|
|
case 1 => 0.9f
|
|
case 2 => 1f
|
|
}
|
|
|
|
val biome = worldObj.getBiomeGenForCoords(xCoord, zCoord)
|
|
val hasBonus = biome.isInstanceOf[BiomeGenOcean] || biome.isInstanceOf[BiomeGenPlains] || biome == BiomeGenBase.river
|
|
val windSpeed = (worldObj.rand.nextFloat / 5) + (yCoord / 256f) * (if (hasBonus) 1.2f else 1) + worldObj.getRainStrength(0.5f)
|
|
|
|
nextWindTorque = 5 * materialMultiplier * multiblockMultiplier * windSpeed * efficiency * Settings.WIND_POWER_RATIO / 20
|
|
}
|
|
|
|
override def getSubBlocks(par1: Item, par2CreativeTabs: CreativeTabs, par3List: List[_])
|
|
{
|
|
for (i <- 0 to 2)
|
|
{
|
|
par3List.add(new ItemStack(par1, 1, i))
|
|
}
|
|
}
|
|
|
|
override def canFill(from: ForgeDirection, fluid: Fluid): Boolean = from == ForgeDirection.DOWN && fluid.getName.contains("steam")
|
|
|
|
override def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int = gasTank.fill(resource, doFill)
|
|
|
|
override def drain(from: ForgeDirection, resource: FluidStack, doDrain: Boolean): FluidStack = null
|
|
|
|
override def drain(from: ForgeDirection, maxDrain: Int, doDrain: Boolean): FluidStack = null
|
|
|
|
override def canDrain(from: ForgeDirection, fluid: Fluid): Boolean = false
|
|
|
|
override def getTankInfo(from: ForgeDirection): Array[FluidTankInfo] = Array(gasTank.getInfo)
|
|
|
|
/** Reads a tile entity from NBT. */
|
|
override def readFromNBT(nbt: NBTTagCompound)
|
|
{
|
|
super.readFromNBT(nbt)
|
|
checkCount = nbt.getInteger("checkCount")
|
|
efficiency = nbt.getFloat("efficiency")
|
|
openBlockCache = nbt.getArray[Byte]("openBlockCache")
|
|
}
|
|
|
|
/** Writes a tile entity to NBT. */
|
|
override def writeToNBT(nbt: NBTTagCompound)
|
|
{
|
|
super.writeToNBT(nbt)
|
|
nbt.setInteger("checkCount", checkCount)
|
|
nbt.setFloat("efficiency", efficiency)
|
|
nbt.setArray("openBlockCache", openBlockCache)
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
override def renderDynamic(pos: Vector3, frame: Float, pass: Int): Unit =
|
|
{
|
|
if (getMultiBlock.isPrimary)
|
|
{
|
|
GL11.glPushMatrix()
|
|
GL11.glTranslated(pos.x + 0.5, pos.y + 0.5, pos.z + 0.5)
|
|
GL11.glPushMatrix()
|
|
RenderUtility.rotateBlockBasedOnDirectionUp(getDirection)
|
|
GL11.glTranslatef(0, 0.35f, 0)
|
|
GL11.glRotatef(180, 1, 0, 0)
|
|
GL11.glRotatef(Math.toDegrees(mechanicalNode.angle).asInstanceOf[Float], 0, 1, 0)
|
|
render(tier, multiBlockRadius, getMultiBlock.isConstructed)
|
|
GL11.glPopMatrix()
|
|
GL11.glPopMatrix()
|
|
}
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
override def renderInventory(itemStack: ItemStack)
|
|
{
|
|
GL11.glPushMatrix()
|
|
GL11.glTranslatef(0.5f, 0.5f, 0.5f)
|
|
render(itemStack.getItemDamage, 1, false)
|
|
GL11.glPopMatrix()
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
def render(tier: Int, size: Int, isConstructed: Boolean)
|
|
{
|
|
if (tier == 0)
|
|
{
|
|
RenderUtility.bind(Reference.blockTextureDirectory + "planks_oak.png")
|
|
}
|
|
else if (tier == 1)
|
|
{
|
|
RenderUtility.bind(Reference.blockTextureDirectory + "cobblestone.png")
|
|
}
|
|
else if (tier == 2)
|
|
{
|
|
RenderUtility.bind(Reference.blockTextureDirectory + "iron_block.png")
|
|
|
|
}
|
|
if (isConstructed)
|
|
{
|
|
GL11.glScalef(0.3f, 1, 0.3f)
|
|
GL11.glScalef(size * 2 + 1, Math.min(size, 2), size * 2 + 1)
|
|
if (tier == 2)
|
|
{
|
|
GL11.glTranslatef(0, -0.11f, 0)
|
|
TileWindTurbine.model.renderOnly("LargeMetalBlade")
|
|
TileWindTurbine.model.renderOnly("LargeMetalHub")
|
|
}
|
|
else
|
|
{
|
|
TileWindTurbine.model.renderOnly("LargeBladeArm")
|
|
GL11.glScalef(1f, 2f, 1f)
|
|
GL11.glTranslatef(0, -0.05f, 0)
|
|
TileWindTurbine.model.renderOnly("LargeHub")
|
|
RenderUtility.bind(Reference.blockTextureDirectory + "wool_colored_white.png")
|
|
TileWindTurbine.model.renderOnly("LargeBlade")
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TileWindTurbine.model.renderOnly("SmallBlade")
|
|
RenderUtility.bind(Reference.blockTextureDirectory + "log_oak.png")
|
|
TileWindTurbine.model.renderOnly("SmallHub")
|
|
}
|
|
}
|
|
}
|