686 lines
21 KiB
Scala
686 lines
21 KiB
Scala
package edx.basic.engineering
|
|
|
|
import java.util.ArrayList
|
|
|
|
import codechicken.multipart.ControlKeyModifer
|
|
import cpw.mods.fml.common.network.ByteBufUtils
|
|
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
|
import edx.basic.blocks.ItemImprint
|
|
import edx.basic.process.grinding.ItemHammer
|
|
import edx.core.{Electrodynamics, Reference}
|
|
import io.netty.buffer.ByteBuf
|
|
import net.minecraft.block.Block
|
|
import net.minecraft.block.material.Material
|
|
import net.minecraft.client.renderer.texture.IIconRegister
|
|
import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP, InventoryPlayer}
|
|
import net.minecraft.inventory.{IInventory, ISidedInventory, InventoryCrafting}
|
|
import net.minecraft.item.crafting.CraftingManager
|
|
import net.minecraft.item.{Item, ItemStack}
|
|
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
|
|
import net.minecraft.network.Packet
|
|
import net.minecraft.tileentity.TileEntity
|
|
import net.minecraft.util.{ChatComponentText, IIcon}
|
|
import net.minecraftforge.common.util.ForgeDirection
|
|
import net.minecraftforge.oredict.OreDictionary
|
|
import org.apache.commons.lang3.ArrayUtils
|
|
import org.lwjgl.opengl.GL11
|
|
import resonantengine.api.gui.ISlotPickResult
|
|
import resonantengine.api.edx.recipe.{MachineRecipes, RecipeResource, RecipeType}
|
|
import resonantengine.api.network.IPacketReceiver
|
|
import resonantengine.api.tile.IRotatable
|
|
import resonantengine.core.ResonantEngine
|
|
import resonantengine.lib.collection.Pair
|
|
import resonantengine.lib.network.discriminator.{PacketTile, PacketType}
|
|
import resonantengine.lib.prefab.gui.ContainerDummy
|
|
import resonantengine.lib.prefab.tile.item.ItemBlockSaved
|
|
import resonantengine.lib.prefab.tile.mixed.TileInventory
|
|
import resonantengine.lib.render.RenderItemOverlayUtility
|
|
import resonantengine.lib.transform.region.Cuboid
|
|
import resonantengine.lib.transform.vector.{Vector2, Vector3}
|
|
import resonantengine.lib.utility.LanguageUtility
|
|
import resonantengine.lib.utility.inventory.AutoCraftingManager.IAutoCrafter
|
|
import resonantengine.lib.utility.inventory.{AutoCraftingManager, InventoryUtility}
|
|
|
|
import scala.collection.JavaConversions._
|
|
|
|
/**
|
|
* Advanced crafting table that stores its crafting grid, can craft out of the player's inv, and be
|
|
* configed to auto craft.
|
|
*
|
|
* @author DarkGuardsman, Calclavia
|
|
*/
|
|
object TileEngineeringTable
|
|
{
|
|
val CRAFTING_MATRIX_END: Int = 9
|
|
val CRAFTING_OUTPUT_END: Int = CRAFTING_MATRIX_END + 1
|
|
val PLAYER_OUTPUT_END: Int = CRAFTING_OUTPUT_END + 40
|
|
val CENTER_SLOT: Int = 4
|
|
val CRAFTING_OUTPUT_SLOT: Int = 0
|
|
/**
|
|
* 9 slots for crafting, 1 slot for a output.
|
|
*/
|
|
val CRAFTING_MATRIX_SIZE: Int = 9
|
|
val craftingSlots: Array[Int] = Array(0, 1, 2, 3, 4, 5, 6, 7, 8)
|
|
|
|
@SideOnly(Side.CLIENT) private var iconTop: IIcon = null
|
|
@SideOnly(Side.CLIENT) private var iconFront: IIcon = null
|
|
@SideOnly(Side.CLIENT) private var iconSide: IIcon = null
|
|
}
|
|
|
|
class TileEngineeringTable extends TileInventory(Material.wood) with IPacketReceiver with IRotatable with ISidedInventory with ISlotPickResult with IAutoCrafter
|
|
{
|
|
|
|
var craftingMatrix: Array[ItemStack] = new Array[ItemStack](TileEngineeringTable.CRAFTING_MATRIX_SIZE)
|
|
/**
|
|
* The output inventory containing slots.
|
|
*/
|
|
var outputInventory: Array[ItemStack] = new Array[ItemStack](1)
|
|
/**
|
|
* The ability for the engineering table to search nearby inventories.
|
|
*/
|
|
var searchInventories: Boolean = true
|
|
private var craftManager: AutoCraftingManager = null
|
|
/**
|
|
* Temporary player inventory stored to draw the player's items.
|
|
*/
|
|
private var invPlayer: InventoryPlayer = null
|
|
private var playerSlots: Array[Int] = null
|
|
|
|
//Constructor
|
|
bounds = new Cuboid(0, 0, 0, 1, 0.9f, 1)
|
|
isOpaqueCube = false
|
|
itemBlock(classOf[ItemBlockSaved])
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
override def getIcon(side: Int, meta: Int): IIcon =
|
|
{
|
|
return if (side == 1) TileEngineeringTable.iconTop else (if (side == meta) TileEngineeringTable.iconFront else TileEngineeringTable.iconSide)
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
override def registerIcons(iconRegister: IIconRegister)
|
|
{
|
|
TileEngineeringTable.iconTop = iconRegister.registerIcon(getTextureName + "_top")
|
|
TileEngineeringTable.iconFront = iconRegister.registerIcon(getTextureName + "_front")
|
|
TileEngineeringTable.iconSide = iconRegister.registerIcon(getTextureName + "_side")
|
|
}
|
|
|
|
override def click(player: EntityPlayer)
|
|
{
|
|
if (!world.isRemote && ControlKeyModifer.isControlDown(player))
|
|
{
|
|
{
|
|
var i: Int = 0
|
|
while (i < getSizeInventory - 1)
|
|
{
|
|
{
|
|
if (getStackInSlot(i) != null)
|
|
{
|
|
InventoryUtility.dropItemStack(world, new Vector3(player), getStackInSlot(i))
|
|
setInventorySlotContents(i, null)
|
|
}
|
|
}
|
|
({
|
|
i += 1;
|
|
i
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
override def getSizeInventory: Int =
|
|
{
|
|
return 10 + (if (this.invPlayer != null) this.invPlayer.getSizeInventory else 0)
|
|
}
|
|
|
|
override def setInventorySlotContents(slot: Int, itemStack: ItemStack)
|
|
{
|
|
if (slot < TileEngineeringTable.CRAFTING_MATRIX_END)
|
|
{
|
|
craftingMatrix(slot) = itemStack
|
|
}
|
|
else if (slot < TileEngineeringTable.CRAFTING_OUTPUT_END)
|
|
{
|
|
outputInventory(slot - TileEngineeringTable.CRAFTING_MATRIX_END) = itemStack
|
|
}
|
|
else if (slot < TileEngineeringTable.PLAYER_OUTPUT_END && this.invPlayer != null)
|
|
{
|
|
this.invPlayer.setInventorySlotContents(slot - TileEngineeringTable.CRAFTING_OUTPUT_END, itemStack)
|
|
val player: EntityPlayer = this.invPlayer.player
|
|
if (player.isInstanceOf[EntityPlayerMP])
|
|
{
|
|
(player.asInstanceOf[EntityPlayerMP]).sendContainerToPlayer(player.inventoryContainer)
|
|
}
|
|
}
|
|
else if (searchInventories)
|
|
{
|
|
var idDisplacement: Int = TileEngineeringTable.PLAYER_OUTPUT_END
|
|
for (dir <- ForgeDirection.VALID_DIRECTIONS)
|
|
{
|
|
val tile: TileEntity = toVectorWorld.add(dir).getTileEntity
|
|
if (tile.isInstanceOf[IInventory])
|
|
{
|
|
val inventory: IInventory = tile.asInstanceOf[IInventory]
|
|
val slotID: Int = slot - idDisplacement
|
|
if (slotID >= 0 && slotID < inventory.getSizeInventory)
|
|
{
|
|
inventory.setInventorySlotContents(slotID, itemStack)
|
|
}
|
|
idDisplacement += inventory.getSizeInventory
|
|
}
|
|
}
|
|
}
|
|
onInventoryChanged
|
|
}
|
|
|
|
/**
|
|
* Updates all the output slots. Call this to update the Engineering Table.
|
|
*/
|
|
override def onInventoryChanged
|
|
{
|
|
if (worldObj != null)
|
|
{
|
|
if (!worldObj.isRemote)
|
|
{
|
|
this.outputInventory(TileEngineeringTable.CRAFTING_OUTPUT_SLOT) = null
|
|
var didCraft: Boolean = false
|
|
val inventoryCrafting: InventoryCrafting = this.getCraftingMatrix
|
|
val matrixOutput: ItemStack = CraftingManager.getInstance.findMatchingRecipe(inventoryCrafting, this.worldObj)
|
|
if (matrixOutput != null && this.getCraftingManager.getIdealRecipe(matrixOutput) != null)
|
|
{
|
|
this.outputInventory(TileEngineeringTable.CRAFTING_OUTPUT_SLOT) = matrixOutput
|
|
didCraft = true
|
|
}
|
|
if (!didCraft)
|
|
{
|
|
val filterStack: ItemStack = craftingMatrix(TileEngineeringTable.CENTER_SLOT)
|
|
if (filterStack != null && filterStack.getItem.isInstanceOf[ItemImprint])
|
|
{
|
|
val filters: java.util.List[ItemStack] = ItemImprint.getFilters(filterStack)
|
|
for (o <- filters)
|
|
{
|
|
val outputStack: ItemStack = o
|
|
if (outputStack != null)
|
|
{
|
|
val idealRecipe: Pair[ItemStack, Array[ItemStack]] = this.getCraftingManager.getIdealRecipe(outputStack)
|
|
if (idealRecipe != null)
|
|
{
|
|
val recipeOutput: ItemStack = idealRecipe.left
|
|
if (recipeOutput != null & recipeOutput.stackSize > 0)
|
|
{
|
|
this.outputInventory(TileEngineeringTable.CRAFTING_OUTPUT_SLOT) = recipeOutput
|
|
didCraft = true
|
|
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the AutoCraftingManager that does all the crafting results
|
|
*/
|
|
def getCraftingManager: AutoCraftingManager =
|
|
{
|
|
if (craftManager == null)
|
|
{
|
|
craftManager = new AutoCraftingManager(this)
|
|
}
|
|
return craftManager
|
|
}
|
|
|
|
/**
|
|
* Construct an InventoryCrafting Matrix on the fly.
|
|
*
|
|
* @return
|
|
*/
|
|
def getCraftingMatrix: InventoryCrafting =
|
|
{
|
|
val inventoryCrafting: InventoryCrafting = new InventoryCrafting(new ContainerDummy(this), 3, 3)
|
|
|
|
for (i <- 0 until this.craftingMatrix.length)
|
|
{
|
|
inventoryCrafting.setInventorySlotContents(i, this.craftingMatrix(i))
|
|
}
|
|
return inventoryCrafting
|
|
}
|
|
|
|
/**
|
|
* DO NOT USE THIS INTERNALLY. FOR EXTERNAL USE ONLY!
|
|
*/
|
|
override def getStackInSlot(slot: Int): ItemStack =
|
|
{
|
|
if (slot < TileEngineeringTable.CRAFTING_MATRIX_END)
|
|
{
|
|
return this.craftingMatrix(slot)
|
|
}
|
|
else if (slot < TileEngineeringTable.CRAFTING_OUTPUT_END)
|
|
{
|
|
return outputInventory(slot - TileEngineeringTable.CRAFTING_MATRIX_END)
|
|
}
|
|
else if (slot < TileEngineeringTable.PLAYER_OUTPUT_END && invPlayer != null)
|
|
{
|
|
return this.invPlayer.getStackInSlot(slot - TileEngineeringTable.CRAFTING_OUTPUT_END)
|
|
}
|
|
else if (searchInventories)
|
|
{
|
|
var idDisplacement: Int = TileEngineeringTable.PLAYER_OUTPUT_END
|
|
for (dir <- ForgeDirection.VALID_DIRECTIONS)
|
|
{
|
|
val tile: TileEntity = toVectorWorld.add(dir).getTileEntity
|
|
if (tile.isInstanceOf[IInventory])
|
|
{
|
|
val inventory: IInventory = tile.asInstanceOf[IInventory]
|
|
val slotID: Int = slot - idDisplacement
|
|
if (slotID >= 0 && slotID < inventory.getSizeInventory)
|
|
{
|
|
return inventory.getStackInSlot(slotID)
|
|
}
|
|
idDisplacement += inventory.getSizeInventory
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
override def use(player: EntityPlayer, hitSide: Int, hit: Vector3): Boolean =
|
|
{
|
|
if (player.getCurrentEquippedItem != null && player.getCurrentEquippedItem.getItem.isInstanceOf[ItemHammer])
|
|
{
|
|
for (slot <- 0 to TileEngineeringTable.CRAFTING_OUTPUT_END)
|
|
{
|
|
val inputStack: ItemStack = getStackInSlot(slot)
|
|
if (inputStack != null)
|
|
{
|
|
val oreName: String = OreDictionary.getOreName(OreDictionary.getOreID(inputStack))
|
|
if (oreName != null && !(oreName == "Unknown"))
|
|
{
|
|
val outputs: Array[RecipeResource] = MachineRecipes.instance.getOutput(RecipeType.GRINDER.name, oreName)
|
|
if (outputs != null && outputs.length > 0)
|
|
{
|
|
if (!world.isRemote && world.rand.nextFloat < 0.2)
|
|
{
|
|
for (resource <- outputs)
|
|
{
|
|
val outputStack: ItemStack = resource.getItemStack.copy
|
|
if (outputStack != null)
|
|
{
|
|
InventoryUtility.dropItemStack(world, new Vector3(player), outputStack, 0)
|
|
setInventorySlotContents(slot, if (({
|
|
inputStack.stackSize -= 1;
|
|
inputStack.stackSize
|
|
}) <= 0) null
|
|
else inputStack)
|
|
}
|
|
}
|
|
}
|
|
Electrodynamics.proxy.renderBlockParticle(world, new Vector3(x + 0.5, y + 0.5, z + 0.5), new Vector3((Math.random - 0.5f) * 3, (Math.random - 0.5f) * 3, (Math.random - 0.5f) * 3), Item.getIdFromItem(inputStack.getItem), 1)
|
|
world.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, Reference.prefix + "hammer", 0.5f, 0.8f + (0.2f * world.rand.nextFloat))
|
|
player.addExhaustion(0.1f)
|
|
player.getCurrentEquippedItem.damageItem(1, player)
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
if (hitSide == 1)
|
|
{
|
|
if (!world.isRemote)
|
|
{
|
|
val hitVector: Vector3 = new Vector3(hit.x, 0, hit.z)
|
|
val regionLength: Double = 1d / 3d
|
|
|
|
for (j <- 0 to 3)
|
|
{
|
|
for (k <- 0 to 3)
|
|
{
|
|
val check: Vector2 = new Vector2(j, k).multiply(regionLength)
|
|
if (check.distance(hitVector.toVector2) < regionLength)
|
|
{
|
|
val slotID: Int = j * 3 + k
|
|
interactCurrentItem(this, slotID, player)
|
|
onInventoryChanged
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
onInventoryChanged
|
|
}
|
|
return true
|
|
}
|
|
else if (hitSide != 0)
|
|
{
|
|
if (!world.isRemote)
|
|
{
|
|
setPlayerInventory(player.inventory)
|
|
var output: ItemStack = getStackInSlot(9)
|
|
var firstLoop: Boolean = true
|
|
while (output != null && (firstLoop || ControlKeyModifer.isControlDown(player)))
|
|
{
|
|
onPickUpFromSlot(player, 9, output)
|
|
if (output.stackSize > 0)
|
|
{
|
|
InventoryUtility.dropItemStack(world, new Vector3(player), output, 0)
|
|
}
|
|
setInventorySlotContents(9, null)
|
|
onInventoryChanged
|
|
output = getStackInSlot(9)
|
|
firstLoop = false
|
|
}
|
|
setPlayerInventory(null)
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
/**
|
|
* Creates a "fake inventory" and hook the player up to the crafter to use the player's items.
|
|
*/
|
|
def setPlayerInventory(invPlayer: InventoryPlayer)
|
|
{
|
|
if (searchInventories)
|
|
{
|
|
if (invPlayer != null)
|
|
{
|
|
playerSlots = new Array[Int](invPlayer.getSizeInventory)
|
|
|
|
for (i <- 0 until playerSlots.length)
|
|
{
|
|
playerSlots(i) = i + TileEngineeringTable.CRAFTING_OUTPUT_END
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
playerSlots = null
|
|
}
|
|
this.invPlayer = invPlayer
|
|
}
|
|
}
|
|
|
|
def onPickUpFromSlot(entityPlayer: EntityPlayer, slotID: Int, itemStack: ItemStack)
|
|
{
|
|
if (!worldObj.isRemote)
|
|
{
|
|
if (itemStack != null)
|
|
{
|
|
val idealRecipeItem: Pair[ItemStack, Array[ItemStack]] = getCraftingManager.getIdealRecipe(itemStack)
|
|
if (idealRecipeItem != null)
|
|
{
|
|
getCraftingManager.consumeItems(idealRecipeItem.right.clone: _*)
|
|
}
|
|
else
|
|
{
|
|
itemStack.stackSize = 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
override def configure(player: EntityPlayer, side: Int, hit: Vector3): Boolean =
|
|
{
|
|
if (player.isSneaking)
|
|
{
|
|
searchInventories = !searchInventories
|
|
if (!world.isRemote)
|
|
{
|
|
if (searchInventories)
|
|
{
|
|
player.addChatMessage(new ChatComponentText(LanguageUtility.getLocal("engineerTable.config.inventory.true")))
|
|
}
|
|
else
|
|
{
|
|
player.addChatMessage(new ChatComponentText(LanguageUtility.getLocal("engineerTable.config.inventory.false")))
|
|
}
|
|
}
|
|
markUpdate
|
|
return true
|
|
}
|
|
return super.configure(player, side, hit)
|
|
}
|
|
|
|
override def getDrops(metadata: Int, fortune: Int): ArrayList[ItemStack] = new ArrayList[ItemStack]
|
|
|
|
override def onRemove(block: Block, par6: Int)
|
|
{
|
|
val stack: ItemStack = ItemBlockSaved.getItemStackWithNBT(block, world, xi, yi, zi)
|
|
InventoryUtility.dropItemStack(world, center, stack)
|
|
}
|
|
|
|
override def canUpdate: Boolean =
|
|
{
|
|
return false
|
|
}
|
|
|
|
override def getDescriptionPacket: Packet =
|
|
{
|
|
val nbt: NBTTagCompound = new NBTTagCompound
|
|
this.writeToNBT(nbt)
|
|
return ResonantEngine.packetHandler.toMCPacket(new PacketTile(this, nbt))
|
|
}
|
|
|
|
/**
|
|
* Writes a tile entity to NBT.
|
|
*/
|
|
override def writeToNBT(nbt: NBTTagCompound)
|
|
{
|
|
super.writeToNBT(nbt)
|
|
val nbtList: NBTTagList = new NBTTagList
|
|
|
|
for (i <- 0 to this.getSizeInventory)
|
|
{
|
|
if (this.getStackInSlot(i) != null)
|
|
{
|
|
val var4: NBTTagCompound = new NBTTagCompound
|
|
var4.setByte("Slot", i.asInstanceOf[Byte])
|
|
this.getStackInSlot(i).writeToNBT(var4)
|
|
nbtList.appendTag(var4)
|
|
}
|
|
}
|
|
nbt.setTag("Items", nbtList)
|
|
nbt.setBoolean("searchInventories", this.searchInventories)
|
|
}
|
|
|
|
def read(data: ByteBuf, player: EntityPlayer, `type`: PacketType)
|
|
{
|
|
try
|
|
{
|
|
readFromNBT(ByteBufUtils.readTag(data))
|
|
}
|
|
catch
|
|
{
|
|
case e: Exception =>
|
|
{
|
|
e.printStackTrace
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* NBT Data
|
|
*/
|
|
override def readFromNBT(nbt: NBTTagCompound)
|
|
{
|
|
super.readFromNBT(nbt)
|
|
val nbtList: NBTTagList = nbt.getTagList("Items", 0)
|
|
this.craftingMatrix = new Array[ItemStack](9)
|
|
this.outputInventory = new Array[ItemStack](1)
|
|
|
|
for (i <- 0 to nbtList.tagCount)
|
|
{
|
|
val stackTag: NBTTagCompound = nbtList.getCompoundTagAt(i)
|
|
val id: Byte = stackTag.getByte("Slot")
|
|
if (id >= 0 && id < this.getSizeInventory)
|
|
{
|
|
this.setInventorySlotContents(id, ItemStack.loadItemStackFromNBT(stackTag))
|
|
}
|
|
}
|
|
|
|
this.searchInventories = nbt.getBoolean("searchInventories")
|
|
}
|
|
|
|
override def decrStackSize(i: Int, amount: Int): ItemStack =
|
|
{
|
|
if (getStackInSlot(i) != null)
|
|
{
|
|
var stack: ItemStack = null
|
|
if (getStackInSlot(i).stackSize <= amount)
|
|
{
|
|
stack = getStackInSlot(i)
|
|
setInventorySlotContents(i, null)
|
|
return stack
|
|
}
|
|
else
|
|
{
|
|
stack = getStackInSlot(i).splitStack(amount)
|
|
if (getStackInSlot(i).stackSize == 0)
|
|
{
|
|
setInventorySlotContents(i, null)
|
|
}
|
|
return stack
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return null
|
|
}
|
|
}
|
|
|
|
/**
|
|
* When some containers are closed they call this on each slot, then drop whatever it returns as
|
|
* an EntityItem - like when you close a workbench GUI.
|
|
*/
|
|
override def getStackInSlotOnClosing(slot: Int): ItemStack =
|
|
{
|
|
if (this.getStackInSlot(slot) != null)
|
|
{
|
|
val var2: ItemStack = this.getStackInSlot(slot)
|
|
this.setInventorySlotContents(slot, null)
|
|
return var2
|
|
}
|
|
else
|
|
{
|
|
return null
|
|
}
|
|
}
|
|
|
|
override def isItemValidForSlot(i: Int, itemstack: ItemStack): Boolean =
|
|
{
|
|
return true
|
|
}
|
|
|
|
override def getInventoryStackLimit: Int =
|
|
{
|
|
return 64
|
|
}
|
|
|
|
override def isUseableByPlayer(entityplayer: EntityPlayer): Boolean =
|
|
{
|
|
return if (this.worldObj.getTileEntity(this.xCoord, this.yCoord, this.zCoord) ne this) false else entityplayer.getDistanceSq(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D) <= 64.0D
|
|
}
|
|
|
|
override def getAccessibleSlotsFromSide(side: Int): Array[Int] =
|
|
{
|
|
return new Array[Int](0)
|
|
}
|
|
|
|
/**
|
|
* Auto-crafting methods.
|
|
*/
|
|
override def canInsertItem(slot: Int, itemstack: ItemStack, side: Int): Boolean =
|
|
{
|
|
if (getStackInSlot(4) != null && getStackInSlot(4).getItem.isInstanceOf[ItemImprint])
|
|
{
|
|
return true
|
|
}
|
|
var minSize: Int = 64
|
|
var optimalSlot: Int = -1
|
|
|
|
for (i <- 0 to craftingMatrix.length)
|
|
{
|
|
val checkStack: ItemStack = getStackInSlot(i)
|
|
if (checkStack != null && checkStack.isItemEqual(itemstack))
|
|
{
|
|
if (checkStack.stackSize < minSize || optimalSlot < 0)
|
|
{
|
|
optimalSlot = i
|
|
minSize = checkStack.stackSize
|
|
}
|
|
}
|
|
}
|
|
return slot == optimalSlot
|
|
}
|
|
|
|
override def canExtractItem(slot: Int, itemstack: ItemStack, side: Int): Boolean =
|
|
{
|
|
val outputStack: ItemStack = getStackInSlot(TileEngineeringTable.CRAFTING_MATRIX_END)
|
|
if (outputStack != null)
|
|
{
|
|
val idealRecipeItem: Pair[ItemStack, Array[ItemStack]] = this.getCraftingManager.getIdealRecipe(outputStack)
|
|
val doubleResults: Array[ItemStack] = ArrayUtils.addAll(idealRecipeItem.right, idealRecipeItem.right: _*)
|
|
if (!getCraftingManager.consumeItems(false, doubleResults: _*))
|
|
{
|
|
return false
|
|
}
|
|
}
|
|
return slot == TileEngineeringTable.CRAFTING_MATRIX_END
|
|
}
|
|
|
|
def getCraftingInv: Array[Int] =
|
|
{
|
|
var slots: Array[Int] = TileEngineeringTable.craftingSlots
|
|
if (playerSlots != null)
|
|
{
|
|
slots = ArrayUtils.addAll(playerSlots, slots: _*)
|
|
}
|
|
if (searchInventories)
|
|
{
|
|
var temporaryInvID: Int = TileEngineeringTable.PLAYER_OUTPUT_END
|
|
for (dir <- ForgeDirection.VALID_DIRECTIONS)
|
|
{
|
|
val tile: TileEntity = toVectorWorld.add(dir).getTileEntity(worldObj)
|
|
if (tile.isInstanceOf[IInventory])
|
|
{
|
|
val inventory: IInventory = tile.asInstanceOf[IInventory]
|
|
val nearbySlots: Array[Int] = new Array[Int](inventory.getSizeInventory)
|
|
|
|
for (i <- 0 to inventory.getSizeInventory)
|
|
{
|
|
temporaryInvID = temporaryInvID + 1;
|
|
nearbySlots(i) = temporaryInvID;
|
|
|
|
}
|
|
slots = ArrayUtils.addAll(nearbySlots, slots: _*)
|
|
}
|
|
}
|
|
}
|
|
return slots
|
|
}
|
|
|
|
override def renderDynamic(position: Vector3, frame: Float, pass: Int)
|
|
{
|
|
GL11.glPushMatrix
|
|
RenderItemOverlayUtility.renderItemOnSides(TileEngineeringTable.this, getStackInSlot(9), position.x, position.y, position.z)
|
|
RenderItemOverlayUtility.renderTopOverlay(TileEngineeringTable.this, craftingMatrix, getDirection, position.x, position.y - 0.1, position.z)
|
|
GL11.glPopMatrix
|
|
}
|
|
|
|
override def getDirection: ForgeDirection =
|
|
{
|
|
return null
|
|
}
|
|
|
|
override def setDirection(direction: ForgeDirection)
|
|
{
|
|
}
|
|
} |