212 lines
6.8 KiB
Scala
212 lines
6.8 KiB
Scala
package edx.mechanical.mech.process.grinder
|
|
|
|
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
|
import edx.core.{Electrodynamics, Reference}
|
|
import edx.mechanical.mech.TileMechanical
|
|
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.minecraft.util.{DamageSource, ResourceLocation}
|
|
import net.minecraftforge.client.model.AdvancedModelLoader
|
|
import net.minecraftforge.common.util.ForgeDirection
|
|
import org.lwjgl.opengl.GL11._
|
|
import resonantengine.api.edx.recipe.{MachineRecipes, RecipeType}
|
|
import resonantengine.lib.render.RenderUtility
|
|
import resonantengine.lib.transform.region.Cuboid
|
|
import resonantengine.lib.transform.rotation.AngleAxis
|
|
import resonantengine.lib.transform.vector.Vector3
|
|
import resonantengine.prefab.misc.Timer
|
|
|
|
/**
|
|
* The grinding wheel. This block will face the direction in which it can rotate.
|
|
* @author Calclavia
|
|
*/
|
|
object TileGrindingWheel
|
|
{
|
|
final val processTime = 20 * 20
|
|
/**
|
|
* A map of ItemStacks and their remaining grind-time left.
|
|
*/
|
|
final val grindingTimer = new Timer[EntityItem]
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
final val model = AdvancedModelLoader.loadModel(new ResourceLocation(Reference.domain, Reference.modelPath + "grinder.obj"))
|
|
}
|
|
|
|
class TileGrindingWheel extends TileMechanical(Material.rock)
|
|
{
|
|
private final val requiredTorque: Long = 250
|
|
private var grindingItem: EntityItem = null
|
|
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"
|
|
rotationMask = 0x3F
|
|
|
|
override def update()
|
|
{
|
|
super.update()
|
|
counter = Math.max(counter + Math.abs(mechanicalNode.torque), 0)
|
|
doWork()
|
|
}
|
|
|
|
def doWork()
|
|
{
|
|
if (canWork)
|
|
{
|
|
var didWork = false
|
|
|
|
if (grindingItem != null)
|
|
{
|
|
if (TileGrindingWheel.grindingTimer.containsKey(grindingItem) && !grindingItem.isDead && toVectorWorld.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])
|
|
{
|
|
Electrodynamics.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
|
|
}
|
|
}
|
|
}
|
|
|
|
private def doGrind(entity: EntityItem): Boolean =
|
|
{
|
|
val itemStack: ItemStack = entity.getEntityItem
|
|
val results = MachineRecipes.instance.getOutput(RecipeType.SIFTER.name, itemStack)
|
|
|
|
for (resource <- results)
|
|
{
|
|
val outputStack: ItemStack = resource.getItemStack
|
|
|
|
if (!world.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
|
|
world.spawnEntityInWorld(entityItem)
|
|
}
|
|
}
|
|
return results.length > 0
|
|
}
|
|
|
|
/**
|
|
* Can this machine work this tick?
|
|
*/
|
|
def canWork: Boolean = counter >= requiredTorque
|
|
|
|
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.attackEntityFrom(new DamageSource("grinder"), 2)
|
|
}
|
|
}
|
|
|
|
if (mechanicalNode.angularVelocity != 0)
|
|
{
|
|
//The velocity added should be tangent to the circle
|
|
val deltaVector = new Vector3(entity) - center
|
|
val deltaAngle = Math.toDegrees(mechanicalNode.angularVelocity / 20)
|
|
var dir = getDirection
|
|
dir = ForgeDirection.getOrientation(if (dir.ordinal() % 2 != 0) dir.ordinal() - 1 else dir.ordinal()).getOpposite
|
|
val rotation = new AngleAxis(deltaAngle, new Vector3(dir))
|
|
val deltaPos = deltaVector.transform(rotation) - deltaVector
|
|
val velocity = deltaPos / 20
|
|
entity.addVelocity(velocity.x, velocity.y, velocity.z)
|
|
}
|
|
}
|
|
|
|
def canGrind(itemStack: ItemStack): Boolean = MachineRecipes.instance.getOutput(RecipeType.SIFTER.name, itemStack).length > 0
|
|
|
|
override def renderDynamic(pos: Vector3, frame: Float, pass: Int): Unit =
|
|
{
|
|
glPushMatrix()
|
|
glTranslated(pos.x + 0.5, pos.y + 0.5, pos.z + 0.5)
|
|
glScalef(0.51f, 0.5f, 0.5f)
|
|
|
|
var dir = getDirection
|
|
dir = ForgeDirection.getOrientation(if (dir.ordinal() % 2 != 0) dir.ordinal() - 1 else dir.ordinal())
|
|
|
|
if (dir.offsetY == 0)
|
|
glRotated(90, 0, 1, 0)
|
|
else
|
|
glRotated(90, 0, 1, 0)
|
|
|
|
RenderUtility.rotateBlockBasedOnDirection(dir)
|
|
glRotated(Math.toDegrees(mechanicalNode.angle), 0, 0, 1)
|
|
RenderUtility.bind(Reference.blockTextureDirectory + "planks_oak.png")
|
|
TileGrindingWheel.model.renderAllExcept("teeth")
|
|
RenderUtility.bind(Reference.blockTextureDirectory + "cobblestone.png")
|
|
TileGrindingWheel.model.renderOnly("teeth")
|
|
glPopMatrix()
|
|
}
|
|
}
|