electrodynamics/src/main/scala/resonantinduction/mechanical/mech/process/grinder/TileGrindingWheel.scala
2014-11-23 11:59:44 +08:00

200 lines
6.1 KiB
Scala

package resonantinduction.mechanical.mech.process.grinder
import net.minecraft.block.material.Material
import net.minecraft.entity.Entity
import net.minecraft.entity.item.EntityItem
import net.minecraft.item.{ItemBlock, ItemStack}
import net.minecraftforge.common.util.ForgeDirection
import resonant.api.IRotatable
import resonant.api.recipe.{MachineRecipes, RecipeResource}
import resonant.content.factory.resources.RecipeType
import resonant.lib.prefab.damage.CustomDamageSource
import resonant.lib.transform.region.Cuboid
import resonant.lib.transform.vector.Vector3
import resonant.lib.utility.Timer
import resonantinduction.core.{Reference, ResonantInduction}
import resonantinduction.mechanical.mech.TileMechanical
/**
* @author Calclavia
*/
object TileGrindingWheel
{
final val processTime: Int = 20 * 20
/**
* A map of ItemStacks and their remaining grind-time left.
*/
final val grindingTimer: Timer[EntityItem] = new Timer[EntityItem]
}
class TileGrindingWheel extends TileMechanical(Material.rock)
{
private var grindingItem: EntityItem = null
private final val requiredTorque: Long = 250
private var counter = 0d
mechanicalNode = new NodeGrinder(this)
bounds = new Cuboid(0.05f, 0.05f, 0.05f, 0.95f, 0.95f, 0.95f)
isOpaqueCube = false
normalRender = false
textureName = "material_steel_dark"
override def update()
{
super.update()
counter = Math.max(counter + Math.abs(mechanicalNode.torque), 0)
doWork()
if(!world.isRemote)
{
println(mechanicalNode)
sendPacket(1)
}
}
override def collide(entity: Entity)
{
if (entity.isInstanceOf[EntityItem])
{
entity.asInstanceOf[EntityItem].age -= 1
}
if (canWork)
{
if (entity.isInstanceOf[EntityItem])
{
if (canGrind((entity.asInstanceOf[EntityItem]).getEntityItem))
{
if (grindingItem == null)
{
grindingItem = entity.asInstanceOf[EntityItem]
}
if (!TileGrindingWheel.grindingTimer.containsKey(entity.asInstanceOf[EntityItem]))
{
TileGrindingWheel.grindingTimer.put(entity.asInstanceOf[EntityItem], TileGrindingWheel.processTime)
}
}
else
{
entity.setPosition(entity.posX, entity.posY - 1.2, entity.posZ)
}
}
else
{
entity.attackEntityFrom(new CustomDamageSource("grinder", this), 2)
}
}
if (mechanicalNode.angularVelocity != 0)
{
var dir: ForgeDirection = getDirection
dir = ForgeDirection.getOrientation(if (!(dir.ordinal % 2 == 0)) dir.ordinal - 1 else dir.ordinal).getOpposite
val speed: Double = mechanicalNode.angularVelocity / 20
var speedX: Double = dir.offsetX * speed
var speedZ: Double = dir.offsetZ * speed
var speedY: Double = Math.random * speed
if (Math.abs(speedX) > 1)
{
speedX = if (speedX > 0) 1 else -1
}
if (Math.abs(speedZ) > 1)
{
speedZ = if (speedZ > 0) 1 else -1
}
if (Math.abs(speedZ) > 1)
{
speedY = if (speedY > 0) 1 else -1
}
entity.addVelocity(speedX, speedY, speedZ)
}
}
/**
* Can this machine work this tick?
*
* @return
*/
def canWork: Boolean = counter >= requiredTorque
def doWork()
{
if (canWork)
{
var didWork: Boolean = false
if (grindingItem != null)
{
if (TileGrindingWheel.grindingTimer.containsKey(grindingItem) && !grindingItem.isDead && toVector3.add(0.5).distance(new Vector3(grindingItem)) < 1)
{
val timeLeft: Int = TileGrindingWheel.grindingTimer.decrease(grindingItem)
if (timeLeft <= 0)
{
if (this.doGrind(grindingItem))
{
grindingItem.getEntityItem.stackSize -= 1;
if (grindingItem.getEntityItem.stackSize <= 0)
{
grindingItem.setDead()
TileGrindingWheel.grindingTimer.remove(grindingItem)
grindingItem = null
}
else
{
grindingItem.setEntityItemStack(grindingItem.getEntityItem)
TileGrindingWheel.grindingTimer.put(grindingItem, TileGrindingWheel.processTime)
}
}
}
else
{
grindingItem.delayBeforeCanPickup = 20
if (grindingItem.getEntityItem.getItem.isInstanceOf[ItemBlock])
{
ResonantInduction.proxy.renderBlockParticle(worldObj, new Vector3(grindingItem), new Vector3((Math.random - 0.5f) * 3, (Math.random - 0.5f) * 3, (Math.random - 0.5f) * 3), 3, 1)
}
else
{
worldObj.spawnParticle("crit", grindingItem.posX, grindingItem.posY, grindingItem.posZ, (Math.random - 0.5f) * 3, (Math.random - 0.5f) * 3, (Math.random - 0.5f) * 3)
}
}
didWork = true
}
else
{
TileGrindingWheel.grindingTimer.remove(grindingItem)
grindingItem = null
}
}
if (didWork)
{
if (this.ticks % 8 == 0)
{
worldObj.playSoundEffect(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, Reference.prefix + "grinder", 0.5f, 1)
}
counter -= requiredTorque
}
}
}
def canGrind(itemStack: ItemStack): Boolean =
{
return MachineRecipes.INSTANCE.getOutput(RecipeType.GRINDER.name, itemStack).length > 0
}
private def doGrind(entity: EntityItem): Boolean =
{
val itemStack: ItemStack = entity.getEntityItem
val results: Array[RecipeResource] = MachineRecipes.INSTANCE.getOutput(RecipeType.GRINDER.name, itemStack)
for (resource <- results)
{
val outputStack: ItemStack = resource.getItemStack
if (!this.worldObj.isRemote)
{
val entityItem: EntityItem = new EntityItem(this.worldObj, entity.posX, entity.posY - 1.2, entity.posZ, outputStack)
entityItem.delayBeforeCanPickup = 20
entityItem.motionX = 0
entityItem.motionY = 0
entityItem.motionZ = 0
this.worldObj.spawnEntityInWorld(entityItem)
}
}
return results.length > 0
}
}