mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-17 03:05:30 -04:00
I don't trust ItemStack Options. Let's get rid of them.
This commit is contained in:
parent
5c3b5634c4
commit
30e3e129c8
@ -9,13 +9,14 @@ import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.jei.ModJEI
|
||||
import li.cil.oc.integration.util.ItemSearch
|
||||
import li.cil.oc.util.RenderState
|
||||
import li.cil.oc.util.StackOption
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.client.gui.Gui
|
||||
import net.minecraft.client.renderer.GlStateManager
|
||||
import net.minecraft.client.renderer.Tessellator
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats
|
||||
import net.minecraft.inventory.Container
|
||||
import net.minecraft.inventory.Slot
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraftforge.fml.common.Optional
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
@ -25,7 +26,7 @@ import scala.collection.convert.WrapAsScala._
|
||||
abstract class DynamicGuiContainer[C <: Container](container: C) extends CustomGuiContainer(container) {
|
||||
protected var hoveredSlot: Option[Slot] = None
|
||||
|
||||
protected var hoveredStackNEI: Option[ItemStack] = None
|
||||
protected var hoveredStackNEI: StackOption = EmptyStack
|
||||
|
||||
protected def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) {
|
||||
fontRenderer.drawString(
|
||||
@ -127,7 +128,7 @@ abstract class DynamicGuiContainer[C <: Container](container: C) extends CustomG
|
||||
((currentIsInPlayerInventory && slot.getHasStack && isSelectiveSlot(hovered) && hovered.isItemValid(slot.getStack)) ||
|
||||
(hoveredIsInPlayerInventory && hovered.getHasStack && isSelectiveSlot(slot) && slot.isItemValid(hovered.getStack)))
|
||||
case _ => hoveredStackNEI match {
|
||||
case Some(stack) => !currentIsInPlayerInventory && isSelectiveSlot(slot) && slot.isItemValid(stack)
|
||||
case SomeStack(stack) => !currentIsInPlayerInventory && isSelectiveSlot(slot) && slot.isItemValid(stack)
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import li.cil.oc.Constants
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.api.detail.ItemInfo
|
||||
import li.cil.oc.common.init.Items
|
||||
import li.cil.oc.util.StackOption
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.stats.StatBase
|
||||
@ -241,7 +242,7 @@ object Achievement {
|
||||
private class AchievementBuilder(val name: String) {
|
||||
var x = 0
|
||||
var y = 0
|
||||
var stack: Option[ItemStack] = stackFromName(name)
|
||||
var stack: StackOption = stackFromName(name)
|
||||
var parent: Option[MCAchievement] = None
|
||||
var crafting = mutable.Set.empty[String]
|
||||
var customCrafting = mutable.Set.empty[ItemStack]
|
||||
@ -254,7 +255,7 @@ object Achievement {
|
||||
}
|
||||
|
||||
def withIconOf(stack: ItemStack): AchievementBuilder = {
|
||||
this.stack = Option(stack)
|
||||
this.stack = StackOption(stack)
|
||||
this
|
||||
}
|
||||
|
||||
@ -271,7 +272,7 @@ object Achievement {
|
||||
|
||||
def whenCrafting(stack: ItemStack): AchievementBuilder = {
|
||||
customCrafting += stack
|
||||
if (this.stack.isEmpty) this.stack = Option(stack)
|
||||
if (this.stack.isEmpty) this.stack = StackOption(stack)
|
||||
this
|
||||
}
|
||||
|
||||
@ -282,7 +283,7 @@ object Achievement {
|
||||
}
|
||||
|
||||
def add(): MCAchievement = {
|
||||
val achievement = new MCAchievement("oc." + name, "oc." + name, x, y, stack.orNull, parent.orNull)
|
||||
val achievement = new MCAchievement("oc." + name, "oc." + name, x, y, stack.orEmpty, parent.orNull)
|
||||
|
||||
if (parent.isEmpty) {
|
||||
achievement.asInstanceOf[StatBase].initIndependentStat()
|
||||
@ -312,7 +313,7 @@ object Achievement {
|
||||
achievement
|
||||
}
|
||||
|
||||
private def stackFromName(name: String) = Option(Items.get(name)).map(_.createItemStack(1))
|
||||
private def stackFromName(name: String): StackOption = StackOption(Option(Items.get(name)).map(_.createItemStack(1)))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import li.cil.oc.server.machine.Machine
|
||||
import li.cil.oc.server.machine.luac.LuaStateFactory
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import li.cil.oc.util.StackOption._
|
||||
import li.cil.oc.util._
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.entity.player.EntityPlayerMP
|
||||
@ -293,29 +294,29 @@ object EventHandler {
|
||||
didRecraft = recraft(e, navigationUpgrade, stack => {
|
||||
// Restore the map currently used in the upgrade.
|
||||
Option(api.Driver.driverFor(e.crafting)) match {
|
||||
case Some(driver) => Option(new ItemStack(driver.dataTag(stack).getCompoundTag(Settings.namespace + "map")))
|
||||
case _ => None
|
||||
case Some(driver) => StackOption(new ItemStack(driver.dataTag(stack).getCompoundTag(Settings.namespace + "map")))
|
||||
case _ => EmptyStack
|
||||
}
|
||||
}) || didRecraft
|
||||
|
||||
didRecraft = recraft(e, mcu, stack => {
|
||||
// Restore EEPROM currently used in microcontroller.
|
||||
new MicrocontrollerData(stack).components.find(api.Items.get(_) == eeprom)
|
||||
new MicrocontrollerData(stack).components.find(api.Items.get(_) == eeprom).asStackOption
|
||||
}) || didRecraft
|
||||
|
||||
didRecraft = recraft(e, drone, stack => {
|
||||
// Restore EEPROM currently used in drone.
|
||||
new MicrocontrollerData(stack).components.find(api.Items.get(_) == eeprom)
|
||||
new MicrocontrollerData(stack).components.find(api.Items.get(_) == eeprom).asStackOption
|
||||
}) || didRecraft
|
||||
|
||||
didRecraft = recraft(e, robot, stack => {
|
||||
// Restore EEPROM currently used in robot.
|
||||
new RobotData(stack).components.find(api.Items.get(_) == eeprom)
|
||||
new RobotData(stack).components.find(api.Items.get(_) == eeprom).asStackOption
|
||||
}) || didRecraft
|
||||
|
||||
didRecraft = recraft(e, tablet, stack => {
|
||||
// Restore EEPROM currently used in tablet.
|
||||
new TabletData(stack).items.collect { case item if !item.isEmpty => item }.find(api.Items.get(_) == eeprom)
|
||||
new TabletData(stack).items.collect { case item if !item.isEmpty => item }.find(api.Items.get(_) == eeprom).asStackOption
|
||||
}) || didRecraft
|
||||
|
||||
// Presents?
|
||||
@ -367,7 +368,7 @@ object EventHandler {
|
||||
month == Calendar.APRIL && dayOfMonth == 1
|
||||
}
|
||||
|
||||
private def recraft(e: ItemCraftedEvent, item: ItemInfo, callback: ItemStack => Option[ItemStack]): Boolean = {
|
||||
private def recraft(e: ItemCraftedEvent, item: ItemInfo, callback: ItemStack => StackOption): Boolean = {
|
||||
if (api.Items.get(e.crafting) == item) {
|
||||
for (slot <- 0 until e.craftMatrix.getSizeInventory) {
|
||||
val stack = e.craftMatrix.getStackInSlot(slot)
|
||||
|
@ -14,6 +14,7 @@ import li.cil.oc.integration.util.ItemBlacklist
|
||||
import li.cil.oc.integration.util.Wrench
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.Rarity
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.state.BlockStateContainer
|
||||
import net.minecraft.block.state.IBlockState
|
||||
@ -91,7 +92,7 @@ class Microcontroller(protected implicit val tileTag: ClassTag[tileentity.Microc
|
||||
case mcu: tileentity.Microcontroller =>
|
||||
val newEeprom = player.inventory.decrStackSize(player.inventory.currentItem, 1)
|
||||
mcu.changeEEPROM(newEeprom) match {
|
||||
case Some(oldEeprom) => InventoryUtils.addToPlayerInventory(oldEeprom, player)
|
||||
case SomeStack(oldEeprom) => InventoryUtils.addToPlayerInventory(oldEeprom, player)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.SideTracker
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory.IInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.ResourceLocation
|
||||
|
||||
class DynamicComponentSlot(val container: Player, inventory: IInventory, index: Int, x: Int, y: Int, val info: DynamicComponentSlot => InventorySlot, val containerTierGetter: () => Int) extends ComponentSlot(inventory, index, x, y) {
|
||||
@ -38,7 +39,7 @@ class DynamicComponentSlot(val container: Player, inventory: IInventory, index:
|
||||
override protected def clearIfInvalid(player: EntityPlayer) {
|
||||
if (SideTracker.isServer && getHasStack && !isItemValid(getStack)) {
|
||||
val stack = getStack
|
||||
putStack(null)
|
||||
putStack(ItemStack.EMPTY)
|
||||
InventoryUtils.addToPlayerInventory(stack, player)
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package li.cil.oc.common.inventory
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.StackOption
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.util.Constants.NBT
|
||||
@ -9,7 +10,7 @@ import net.minecraftforge.common.util.Constants.NBT
|
||||
trait Inventory extends SimpleInventory {
|
||||
def items: Array[ItemStack]
|
||||
|
||||
def updateItems(slot: Int, stack: ItemStack): Unit = items(slot) = stack
|
||||
def updateItems(slot: Int, stack: ItemStack): Unit = items(slot) = StackOption(stack).orEmpty
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
|
@ -6,6 +6,8 @@ import li.cil.oc.api.nanomachines.DisableReason
|
||||
import li.cil.oc.api.prefab.AbstractBehavior
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import li.cil.oc.util.StackOption
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
@ -66,7 +68,7 @@ object DisintegrationProvider extends ScalaProvider("c4e7e3c2-8069-4fbb-b08e-74b
|
||||
if (hardness > 0) {
|
||||
val timeToBreak = (1 / hardness).toInt
|
||||
if (timeToBreak < 20 * 30) {
|
||||
val info = new SlowBreakInfo(now, now + timeToBreak, pos, Option(player.getHeldItemMainhand).map(_.copy()), blockState)
|
||||
val info = new SlowBreakInfo(now, now + timeToBreak, pos, StackOption(player.getHeldItemMainhand).map(_.copy()), blockState)
|
||||
world.destroyBlockInWorldPartially(pos.hashCode(), pos, 0)
|
||||
breakingMapNew += pos -> info
|
||||
}
|
||||
@ -98,14 +100,14 @@ object DisintegrationProvider extends ScalaProvider("c4e7e3c2-8069-4fbb-b08e-74b
|
||||
}
|
||||
}
|
||||
|
||||
class SlowBreakInfo(val timeStarted: Long, val timeBroken: Long, val pos: BlockPosition, val originalTool: Option[ItemStack], val blockState: IBlockState) {
|
||||
class SlowBreakInfo(val timeStarted: Long, val timeBroken: Long, val pos: BlockPosition, val originalTool: StackOption, val blockState: IBlockState) {
|
||||
var lastDamageSent = 0
|
||||
|
||||
def checkTool(player: EntityPlayer): Boolean = {
|
||||
val currentTool = Option(player.getHeldItemMainhand).map(_.copy())
|
||||
val currentTool = StackOption(player.getHeldItemMainhand).map(_.copy())
|
||||
(currentTool, originalTool) match {
|
||||
case (Some(stackA), Some(stackB)) => stackA.getItem == stackB.getItem && (stackA.isItemStackDamageable || stackA.getItemDamage == stackB.getItemDamage)
|
||||
case (None, None) => true
|
||||
case (SomeStack(stackA), SomeStack(stackB)) => stackA.getItem == stackB.getItem && (stackA.isItemStackDamageable || stackA.getItemDamage == stackB.getItemDamage)
|
||||
case (EmptyStack, EmptyStack) => true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package li.cil.oc.common.recipe
|
||||
|
||||
import li.cil.oc.util.Color
|
||||
import li.cil.oc.util.ItemColorizer
|
||||
import li.cil.oc.util.StackOption
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.entity.passive.EntitySheep
|
||||
import net.minecraft.inventory.InventoryCrafting
|
||||
@ -20,9 +21,9 @@ class ColorizeRecipe(target: Item, source: Array[Item] = null) extends Container
|
||||
val sourceItems: Array[Item] = if (source != null) source else Array(targetItem)
|
||||
|
||||
override def matches(crafting: InventoryCrafting, world: World): Boolean = {
|
||||
val stacks = (0 until crafting.getSizeInventory).flatMap(i => Option(crafting.getStackInSlot(i)))
|
||||
val stacks = (0 until crafting.getSizeInventory).flatMap(i => StackOption(crafting.getStackInSlot(i)))
|
||||
val targets = stacks.filter(stack => sourceItems.contains(stack.getItem) || stack.getItem == targetItem)
|
||||
val other = stacks.filterNot(stack => stack.isEmpty || targets.contains(stack))
|
||||
val other = stacks.filterNot(targets.contains(_))
|
||||
targets.size == 1 && other.nonEmpty && other.forall(Color.isDye)
|
||||
}
|
||||
|
||||
@ -32,12 +33,12 @@ class ColorizeRecipe(target: Item, source: Array[Item] = null) extends Container
|
||||
var colorCount = 0
|
||||
var maximum = 0
|
||||
|
||||
(0 until crafting.getSizeInventory).flatMap(i => Option(crafting.getStackInSlot(i))).foreach { stack =>
|
||||
(0 until crafting.getSizeInventory).flatMap(i => StackOption(crafting.getStackInSlot(i))).foreach { stack =>
|
||||
if (sourceItems.contains(stack.getItem)
|
||||
|| stack.getItem == targetItem) {
|
||||
targetStack = stack.copy()
|
||||
targetStack.setCount(1)
|
||||
} else if(!stack.isEmpty) {
|
||||
} else {
|
||||
val dye = Color.findDye(stack)
|
||||
if (dye.isEmpty)
|
||||
return ItemStack.EMPTY
|
||||
|
@ -1,6 +1,7 @@
|
||||
package li.cil.oc.common.recipe
|
||||
|
||||
import li.cil.oc.util.ItemColorizer
|
||||
import li.cil.oc.util.StackOption
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.init.Items
|
||||
import net.minecraft.inventory.InventoryCrafting
|
||||
@ -17,20 +18,20 @@ class DecolorizeRecipe(target: Item) extends ContainerItemAwareRecipe {
|
||||
val targetItem: Item = target
|
||||
|
||||
override def matches(crafting: InventoryCrafting, world: World): Boolean = {
|
||||
val stacks = (0 until crafting.getSizeInventory).flatMap(i => Option(crafting.getStackInSlot(i)))
|
||||
val stacks = (0 until crafting.getSizeInventory).flatMap(i => StackOption(crafting.getStackInSlot(i)))
|
||||
val targets = stacks.filter(stack => stack.getItem == targetItem)
|
||||
val other = stacks.filterNot(stack => stack.isEmpty || targets.contains(stack))
|
||||
val other = stacks.filterNot(targets.contains)
|
||||
targets.size == 1 && other.size == 1 && other.forall(_.getItem == Items.WATER_BUCKET)
|
||||
}
|
||||
|
||||
override def getCraftingResult(crafting: InventoryCrafting): ItemStack = {
|
||||
var targetStack: ItemStack = ItemStack.EMPTY
|
||||
|
||||
(0 until crafting.getSizeInventory).flatMap(i => Option(crafting.getStackInSlot(i))).foreach { stack =>
|
||||
(0 until crafting.getSizeInventory).flatMap(i => StackOption(crafting.getStackInSlot(i))).foreach { stack =>
|
||||
if (stack.getItem == targetItem) {
|
||||
targetStack = stack.copy()
|
||||
targetStack.setCount(1)
|
||||
} else if (!stack.isEmpty && stack.getItem != Items.WATER_BUCKET) {
|
||||
} else if (stack.getItem != Items.WATER_BUCKET) {
|
||||
return ItemStack.EMPTY
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package li.cil.oc.common.recipe
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.common.Loot
|
||||
import li.cil.oc.integration.util.Wrench
|
||||
import li.cil.oc.util.StackOption
|
||||
import net.minecraft.inventory.InventoryCrafting
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.crafting.IRecipe
|
||||
@ -14,7 +15,7 @@ import scala.collection.immutable
|
||||
class LootDiskCyclingRecipe extends IRecipe {
|
||||
override def matches(crafting: InventoryCrafting, world: World): Boolean = {
|
||||
val stacks = collectStacks(crafting).toArray
|
||||
stacks.count(!_.isEmpty) == 2 && stacks.exists(Loot.isLootDisk) && stacks.exists(Wrench.isWrench)
|
||||
stacks.length == 2 && stacks.exists(Loot.isLootDisk) && stacks.exists(Wrench.isWrench)
|
||||
}
|
||||
|
||||
override def getCraftingResult(crafting: InventoryCrafting): ItemStack = {
|
||||
@ -31,7 +32,7 @@ class LootDiskCyclingRecipe extends IRecipe {
|
||||
|
||||
def getLootFactoryName(stack: ItemStack): String = stack.getTagCompound.getString(Settings.namespace + "lootFactory")
|
||||
|
||||
def collectStacks(crafting: InventoryCrafting): immutable.IndexedSeq[ItemStack] = (0 until crafting.getSizeInventory).flatMap(i => Option(crafting.getStackInSlot(i)))
|
||||
def collectStacks(crafting: InventoryCrafting): immutable.IndexedSeq[ItemStack] = (0 until crafting.getSizeInventory).flatMap(i => StackOption(crafting.getStackInSlot(i)))
|
||||
|
||||
override def getRecipeSize: Int = 2
|
||||
|
||||
|
@ -15,6 +15,8 @@ import li.cil.oc.api.network._
|
||||
import li.cil.oc.common.template.AssemblerTemplates
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.StackOption
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.EnumFacing
|
||||
@ -29,7 +31,7 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits
|
||||
withConnector(Settings.get.bufferConverter).
|
||||
create()
|
||||
|
||||
var output: Option[ItemStack] = None
|
||||
var output: StackOption = EmptyStack
|
||||
|
||||
var totalRequiredEnergy = 0.0
|
||||
|
||||
@ -87,7 +89,7 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits
|
||||
if (!stack.isEmpty && !isItemValidForSlot(slot, stack)) return false
|
||||
}
|
||||
val (stack, energy) = template.assemble(this)
|
||||
output = Some(stack)
|
||||
output = StackOption(stack)
|
||||
if (finishImmediately) {
|
||||
totalRequiredEnergy = 0
|
||||
}
|
||||
@ -123,16 +125,16 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits
|
||||
|
||||
override def updateEntity() {
|
||||
super.updateEntity()
|
||||
if (output.isDefined && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) {
|
||||
if (!output.isEmpty && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) {
|
||||
val want = math.max(1, math.min(requiredEnergy, Settings.get.assemblerTickAmount * Settings.get.tickFrequency))
|
||||
val have = want + (if (Settings.get.ignorePower) 0 else node.changeBuffer(-want))
|
||||
requiredEnergy -= have
|
||||
if (requiredEnergy <= 0) {
|
||||
setInventorySlotContents(0, output.get)
|
||||
output = None
|
||||
output = EmptyStack
|
||||
requiredEnergy = 0
|
||||
}
|
||||
ServerPacketSender.sendRobotAssembling(this, have > 0.5 && output.isDefined)
|
||||
ServerPacketSender.sendRobotAssembling(this, have > 0.5 && !output.isEmpty)
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,10 +148,10 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits
|
||||
override def readFromNBTForServer(nbt: NBTTagCompound) {
|
||||
super.readFromNBTForServer(nbt)
|
||||
if (nbt.hasKey(OutputTag)) {
|
||||
output = Option(new ItemStack(nbt.getCompoundTag(OutputTag)))
|
||||
output = StackOption(new ItemStack(nbt.getCompoundTag(OutputTag)))
|
||||
}
|
||||
else if (nbt.hasKey(OutputTagCompat)) {
|
||||
output = Option(new ItemStack(nbt.getCompoundTag(OutputTagCompat)))
|
||||
output = StackOption(new ItemStack(nbt.getCompoundTag(OutputTagCompat)))
|
||||
}
|
||||
totalRequiredEnergy = nbt.getDouble(TotalTag)
|
||||
requiredEnergy = nbt.getDouble(RemainingTag)
|
||||
@ -157,7 +159,7 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits
|
||||
|
||||
override def writeToNBTForServer(nbt: NBTTagCompound) {
|
||||
super.writeToNBTForServer(nbt)
|
||||
output.foreach(stack => nbt.setNewCompoundTag(OutputTag, stack.writeToNBT))
|
||||
nbt.setNewCompoundTag(OutputTag, output.get.writeToNBT)
|
||||
nbt.setDouble(TotalTag, totalRequiredEnergy)
|
||||
nbt.setDouble(RemainingTag, requiredEnergy)
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.item.data.MicrocontrollerData
|
||||
import li.cil.oc.util.ExtendedArguments._
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.StackOption
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
@ -260,17 +262,17 @@ class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.C
|
||||
override def removeStackFromSlot(slot: Int) = ItemStack.EMPTY
|
||||
|
||||
// For hotswapping EEPROMs.
|
||||
def changeEEPROM(newEeprom: ItemStack): Option[ItemStack] = {
|
||||
def changeEEPROM(newEeprom: ItemStack): StackOption = {
|
||||
val oldEepromIndex = info.components.indexWhere(api.Items.get(_) == api.Items.get(Constants.ItemName.EEPROM))
|
||||
if (oldEepromIndex >= 0) {
|
||||
val oldEeprom = info.components(oldEepromIndex)
|
||||
super.setInventorySlotContents(oldEepromIndex, newEeprom)
|
||||
Some(oldEeprom)
|
||||
SomeStack(oldEeprom)
|
||||
}
|
||||
else {
|
||||
assert(info.components(getSizeInventory - 1).isEmpty)
|
||||
super.setInventorySlotContents(getSizeInventory - 1, newEeprom)
|
||||
None
|
||||
EmptyStack
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ import li.cil.oc.api.util.StateAware
|
||||
import li.cil.oc.common.item.data.PrintData
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.StackOption
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.inventory.ISidedInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
@ -40,7 +42,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
|
||||
var data = new PrintData()
|
||||
var isActive = false
|
||||
var limit = 0
|
||||
var output: Option[ItemStack] = None
|
||||
var output: StackOption = EmptyStack
|
||||
var totalRequiredEnergy = 0.0
|
||||
var requiredEnergy = 0.0
|
||||
|
||||
@ -248,7 +250,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
|
||||
amountMaterial -= materialRequired
|
||||
amountInk -= inkRequired
|
||||
limit -= 1
|
||||
output = Option(data.createItemStack())
|
||||
output = StackOption(data.createItemStack())
|
||||
if (limit < 1) isActive = false
|
||||
ServerPacketSender.sendPrinting(this, printing = true)
|
||||
}
|
||||
@ -275,7 +277,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
|
||||
return
|
||||
}
|
||||
requiredEnergy = 0
|
||||
output = None
|
||||
output = EmptyStack
|
||||
}
|
||||
ServerPacketSender.sendPrinting(this, have > 0.5 && output.isDefined)
|
||||
}
|
||||
@ -319,10 +321,10 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
|
||||
isActive = nbt.getBoolean(IsActiveTag)
|
||||
limit = nbt.getInteger(LimitTag)
|
||||
if (nbt.hasKey(OutputTag)) {
|
||||
output = Option(new ItemStack(nbt.getCompoundTag(OutputTag)))
|
||||
output = StackOption(new ItemStack(nbt.getCompoundTag(OutputTag)))
|
||||
}
|
||||
else {
|
||||
output = None
|
||||
output = EmptyStack
|
||||
}
|
||||
totalRequiredEnergy = nbt.getDouble(TotalTag)
|
||||
requiredEnergy = nbt.getDouble(RemainingTag)
|
||||
|
@ -6,6 +6,8 @@ import li.cil.oc.api.network.Node
|
||||
import li.cil.oc.common.EventHandler
|
||||
import li.cil.oc.common.inventory
|
||||
import li.cil.oc.util.ExtendedInventory._
|
||||
import li.cil.oc.util.StackOption
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.EnumFacing
|
||||
@ -24,8 +26,8 @@ trait ComponentInventory extends Environment with Inventory with inventory.Compo
|
||||
// Cache changes to inventory slots on the client side to avoid recreating
|
||||
// components when we don't have to and the slots are just cleared by MC
|
||||
// temporarily.
|
||||
private lazy val pendingRemovalsActual = mutable.ArrayBuffer.fill(getSizeInventory)(None: Option[ItemStack])
|
||||
private lazy val pendingAddsActual = mutable.ArrayBuffer.fill(getSizeInventory)(None: Option[ItemStack])
|
||||
private lazy val pendingRemovalsActual = mutable.ArrayBuffer.fill(getSizeInventory)(EmptyStack: StackOption)
|
||||
private lazy val pendingAddsActual = mutable.ArrayBuffer.fill(getSizeInventory)(EmptyStack: StackOption)
|
||||
private var updateScheduled = false
|
||||
def pendingRemovals = {
|
||||
adjustSize(pendingRemovalsActual)
|
||||
@ -36,7 +38,7 @@ trait ComponentInventory extends Environment with Inventory with inventory.Compo
|
||||
pendingAddsActual
|
||||
}
|
||||
|
||||
private def adjustSize[T](buffer: mutable.ArrayBuffer[Option[T]]): Unit = {
|
||||
private def adjustSize(buffer: mutable.ArrayBuffer[StackOption]): Unit = {
|
||||
val delta = buffer.length - getSizeInventory
|
||||
if (delta > 0) {
|
||||
buffer.remove(buffer.length - delta, delta)
|
||||
@ -44,7 +46,7 @@ trait ComponentInventory extends Environment with Inventory with inventory.Compo
|
||||
else if (delta < 0) {
|
||||
buffer.sizeHint(getSizeInventory)
|
||||
for (i <- 0 until -delta) {
|
||||
buffer += None
|
||||
buffer += EmptyStack
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -53,23 +55,23 @@ trait ComponentInventory extends Environment with Inventory with inventory.Compo
|
||||
updateScheduled = false
|
||||
for (slot <- this.indices) {
|
||||
(pendingRemovals(slot), pendingAdds(slot)) match {
|
||||
case (Some(removed), Some(added)) =>
|
||||
case (SomeStack(removed), SomeStack(added)) =>
|
||||
if (!removed.isItemEqual(added) || !ItemStack.areItemStackTagsEqual(removed, added)) {
|
||||
super.onItemRemoved(slot, removed)
|
||||
super.onItemAdded(slot, added)
|
||||
markDirty()
|
||||
} // else: No change, ignore.
|
||||
case (Some(removed), None) =>
|
||||
case (SomeStack(removed), EmptyStack) =>
|
||||
super.onItemRemoved(slot, removed)
|
||||
markDirty()
|
||||
case (None, Some(added)) =>
|
||||
case (EmptyStack, SomeStack(added)) =>
|
||||
super.onItemAdded(slot, added)
|
||||
markDirty()
|
||||
case _ => // No change.
|
||||
}
|
||||
|
||||
pendingRemovals(slot) = None
|
||||
pendingAdds(slot) = None
|
||||
pendingRemovals(slot) = EmptyStack
|
||||
pendingAdds(slot) = EmptyStack
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,13 +86,13 @@ trait ComponentInventory extends Environment with Inventory with inventory.Compo
|
||||
if (isServer) super.onItemAdded(slot, stack)
|
||||
else {
|
||||
pendingRemovals(slot) match {
|
||||
case Some(removed) if removed.isItemEqual(stack) && ItemStack.areItemStackTagsEqual(removed, stack) =>
|
||||
case SomeStack(removed) if removed.isItemEqual(stack) && ItemStack.areItemStackTagsEqual(removed, stack) =>
|
||||
// Reverted to original state.
|
||||
pendingAdds(slot) = None
|
||||
pendingRemovals(slot) = None
|
||||
pendingAdds(slot) = EmptyStack
|
||||
pendingRemovals(slot) = EmptyStack
|
||||
case _ =>
|
||||
// Got a removal and an add of *something else* in the same tick.
|
||||
pendingAdds(slot) = Option(stack)
|
||||
pendingAdds(slot) = StackOption(stack)
|
||||
scheduleInventoryChange()
|
||||
}
|
||||
}
|
||||
@ -100,15 +102,15 @@ trait ComponentInventory extends Environment with Inventory with inventory.Compo
|
||||
if (isServer) super.onItemRemoved(slot, stack)
|
||||
else {
|
||||
pendingAdds(slot) match {
|
||||
case Some(added) =>
|
||||
case SomeStack(added) =>
|
||||
// If we have a pending add and get a remove on a slot it is
|
||||
// now either empty, or the previous remove is valid again.
|
||||
pendingAdds(slot) = None
|
||||
pendingAdds(slot) = EmptyStack
|
||||
case _ =>
|
||||
// If we have no pending add, only the first removal can be
|
||||
// relevant (further ones should in fact be impossible).
|
||||
if (pendingRemovals(slot).isEmpty) {
|
||||
pendingRemovals(slot) = Option(stack)
|
||||
pendingRemovals(slot) = StackOption(stack)
|
||||
scheduleInventoryChange()
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import li.cil.oc.Settings
|
||||
import li.cil.oc.api.Items
|
||||
import li.cil.oc.integration.util.ItemBlacklist
|
||||
import li.cil.oc.integration.util.ItemSearch
|
||||
import li.cil.oc.util.StackOption
|
||||
import mezz.jei.api.IJeiRuntime
|
||||
import mezz.jei.api.IModPlugin
|
||||
import mezz.jei.api.IModRegistry
|
||||
@ -42,13 +43,13 @@ class ModPluginOpenComputers extends IModPlugin {
|
||||
ModJEI.ingredientRegistry = Option(registry.getIngredientRegistry)
|
||||
}
|
||||
|
||||
private var stackUnderMouse: (GuiContainer, Int, Int) => Option[ItemStack] = _
|
||||
private var stackUnderMouse: (GuiContainer, Int, Int) => StackOption = _
|
||||
|
||||
override def onRuntimeAvailable(jeiRuntime: IJeiRuntime) {
|
||||
if (stackUnderMouse == null) {
|
||||
ItemSearch.stackFocusing += ((container, mouseX, mouseY) => stackUnderMouse(container, mouseX, mouseY))
|
||||
}
|
||||
stackUnderMouse = (container, mouseX, mouseY) => Option(jeiRuntime.getItemListOverlay.getStackUnderMouse)
|
||||
stackUnderMouse = (container, mouseX, mouseY) => StackOption(jeiRuntime.getItemListOverlay.getStackUnderMouse)
|
||||
|
||||
ModJEI.runtime = Option(jeiRuntime)
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
package li.cil.oc.integration.util
|
||||
|
||||
import li.cil.oc.util.StackOption
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.client.gui.inventory.GuiContainer
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
object ItemSearch {
|
||||
|
||||
val focusedInput = mutable.Set.empty[() => Boolean]
|
||||
val stackFocusing = mutable.Set.empty[(GuiContainer, Int, Int) => Option[ItemStack]]
|
||||
val stackFocusing = mutable.Set.empty[(GuiContainer, Int, Int) => StackOption]
|
||||
|
||||
def isInputFocused: Boolean = {
|
||||
for (f <- focusedInput) {
|
||||
@ -17,10 +18,10 @@ object ItemSearch {
|
||||
false
|
||||
}
|
||||
|
||||
def hoveredStack(container: GuiContainer, mouseX: Int, mouseY: Int): Option[ItemStack] = {
|
||||
def hoveredStack(container: GuiContainer, mouseX: Int, mouseY: Int): StackOption = {
|
||||
for (f <- stackFocusing) {
|
||||
f(container, mouseX, mouseY).foreach(stack => return Option(stack))
|
||||
f(container, mouseX, mouseY).foreach(stack => return StackOption(stack))
|
||||
}
|
||||
None
|
||||
EmptyStack
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ import li.cil.oc.server.PacketSender
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedArguments._
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.StackOption
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.util.EnumParticleTypes
|
||||
@ -71,8 +73,8 @@ class Robot(val agent: tileentity.Robot) extends AbstractManagedEnvironment with
|
||||
|
||||
@Callback(doc = "function():number -- Get the durability of the currently equipped tool.")
|
||||
def durability(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
Option(agent.equipmentInventory.getStackInSlot(0)) match {
|
||||
case Some(item) =>
|
||||
StackOption(agent.equipmentInventory.getStackInSlot(0)) match {
|
||||
case SomeStack(item) =>
|
||||
ToolDurabilityProviders.getDurability(item) match {
|
||||
case Some(durability) => result(durability)
|
||||
case _ => result(Unit, "tool cannot be damaged")
|
||||
|
@ -18,6 +18,7 @@ import li.cil.oc.api.prefab.AbstractManagedEnvironment
|
||||
import li.cil.oc.util.DatabaseAccess
|
||||
import li.cil.oc.util.ExtendedArguments._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import li.cil.oc.util.StackOption
|
||||
import net.minecraft.inventory.IInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
@ -40,7 +41,7 @@ class UpgradeDatabase(val data: IInventory) extends AbstractManagedEnvironment w
|
||||
|
||||
override def size = data.getSizeInventory
|
||||
|
||||
override def getStackInSlot(slot: Int) = Option(data.getStackInSlot(slot)).map(_.copy()).orNull
|
||||
override def getStackInSlot(slot: Int) = StackOption(data.getStackInSlot(slot)).map(_.copy()).orEmpty
|
||||
|
||||
override def setStackInSlot(slot: Int, stack: ItemStack) = data.setInventorySlotContents(slot, stack)
|
||||
|
||||
|
@ -17,6 +17,8 @@ import li.cil.oc.api.network._
|
||||
import li.cil.oc.api.prefab
|
||||
import li.cil.oc.api.prefab.AbstractManagedEnvironment
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.StackOption
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.entity.item.EntityItem
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
@ -30,7 +32,7 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab
|
||||
withConnector().
|
||||
create()
|
||||
|
||||
var inventory: Option[ItemStack] = None
|
||||
var inventory: StackOption = EmptyStack
|
||||
|
||||
var remainingTicks = 0
|
||||
|
||||
@ -55,7 +57,7 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab
|
||||
return result(Unit, "selected slot does not contain fuel")
|
||||
}
|
||||
inventory match {
|
||||
case Some(existingStack) =>
|
||||
case SomeStack(existingStack) =>
|
||||
if (!existingStack.isItemEqual(stack) ||
|
||||
!ItemStack.areItemStackTagsEqual(existingStack, stack)) {
|
||||
return result(Unit, "different fuel type already queued")
|
||||
@ -68,7 +70,7 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab
|
||||
existingStack.grow(moveCount)
|
||||
stack.shrink(moveCount)
|
||||
case _ =>
|
||||
inventory = Some(stack.splitStack(math.min(stack.getCount, count)))
|
||||
inventory = StackOption(stack.splitStack(math.min(stack.getCount, count)))
|
||||
}
|
||||
if (stack.getCount > 0) host.mainInventory.setInventorySlotContents(host.selectedSlot, stack)
|
||||
else host.mainInventory.setInventorySlotContents(host.selectedSlot, ItemStack.EMPTY)
|
||||
@ -78,7 +80,7 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab
|
||||
@Callback(doc = """function():number -- Get the size of the item stack in the generator's queue.""")
|
||||
def count(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
inventory match {
|
||||
case Some(stack) => result(stack.getCount)
|
||||
case SomeStack(stack) => result(stack.getCount)
|
||||
case _ => result(0)
|
||||
}
|
||||
}
|
||||
@ -87,12 +89,12 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab
|
||||
def remove(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val count = args.optInteger(0, Int.MaxValue)
|
||||
inventory match {
|
||||
case Some(stack) =>
|
||||
case SomeStack(stack) =>
|
||||
val removedStack = stack.splitStack(math.min(count, stack.getCount))
|
||||
val success = host.player.inventory.addItemStackToInventory(removedStack)
|
||||
stack.grow(removedStack.getCount)
|
||||
if (success && stack.getCount <= 0) {
|
||||
inventory = None
|
||||
inventory = EmptyStack
|
||||
}
|
||||
result(success)
|
||||
case _ => result(false)
|
||||
@ -114,9 +116,9 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab
|
||||
stack.shrink(1)
|
||||
if (stack.getCount <= 0) {
|
||||
if (stack.getItem.hasContainerItem(stack))
|
||||
inventory = Option(stack.getItem.getContainerItem(stack))
|
||||
inventory = StackOption(stack.getItem.getContainerItem(stack))
|
||||
else
|
||||
inventory = None
|
||||
inventory = EmptyStack
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -140,13 +142,13 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab
|
||||
super.onDisconnect(node)
|
||||
if (node == this.node) {
|
||||
inventory match {
|
||||
case Some(stack) =>
|
||||
case SomeStack(stack) =>
|
||||
val world = host.world
|
||||
val entity = new EntityItem(world, host.xPosition, host.yPosition, host.zPosition, stack.copy())
|
||||
entity.motionY = 0.04
|
||||
entity.setPickupDelay(5)
|
||||
world.spawnEntity(entity)
|
||||
inventory = None
|
||||
inventory = EmptyStack
|
||||
case _ =>
|
||||
}
|
||||
remainingTicks = 0
|
||||
@ -158,9 +160,9 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab
|
||||
|
||||
override def load(nbt: NBTTagCompound) {
|
||||
super.load(nbt)
|
||||
inventory = Option(new ItemStack(nbt.getCompoundTag("inventory")))
|
||||
inventory = StackOption(new ItemStack(nbt.getCompoundTag("inventory")))
|
||||
if (nbt.hasKey(InventoryTag)) {
|
||||
inventory = Option(new ItemStack(nbt.getCompoundTag(InventoryTag)))
|
||||
inventory = StackOption(new ItemStack(nbt.getCompoundTag(InventoryTag)))
|
||||
}
|
||||
remainingTicks = nbt.getInteger(RemainingTicksTag)
|
||||
}
|
||||
@ -168,7 +170,7 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
super.save(nbt)
|
||||
inventory match {
|
||||
case Some(stack) => nbt.setNewCompoundTag(InventoryTag, stack.writeToNBT)
|
||||
case SomeStack(stack) => nbt.setNewCompoundTag(InventoryTag, stack.writeToNBT)
|
||||
case _ =>
|
||||
}
|
||||
if (remainingTicks > 0) {
|
||||
|
@ -8,6 +8,7 @@ import li.cil.oc.server.component.result
|
||||
import li.cil.oc.util.DatabaseAccess
|
||||
import li.cil.oc.util.ExtendedArguments._
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraftforge.oredict.OreDictionary
|
||||
|
||||
@ -23,8 +24,8 @@ trait InventoryAnalytics extends InventoryAware with NetworkAware {
|
||||
def isEquivalentTo(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val slot = args.checkSlot(inventory, 0)
|
||||
result((stackInSlot(selectedSlot), stackInSlot(slot)) match {
|
||||
case (Some(stackA), Some(stackB)) => OreDictionary.getOreIDs(stackA).intersect(OreDictionary.getOreIDs(stackB)).nonEmpty
|
||||
case (None, None) => true
|
||||
case (SomeStack(stackA), SomeStack(stackB)) => OreDictionary.getOreIDs(stackA).intersect(OreDictionary.getOreIDs(stackB)).nonEmpty
|
||||
case (EmptyStack, EmptyStack) => true
|
||||
case _ => false
|
||||
})
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package li.cil.oc.server.component.traits
|
||||
|
||||
import li.cil.oc.api.machine.Arguments
|
||||
import li.cil.oc.util.ExtendedArguments._
|
||||
import li.cil.oc.util.StackOption
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory.IInventory
|
||||
|
||||
@ -24,5 +25,5 @@ trait InventoryAware {
|
||||
if (args.count > 0 && args.checkAny(0) != null) args.checkSlot(inventory, 0)
|
||||
else selectedSlot
|
||||
|
||||
protected def stackInSlot(slot: Int) = Option(inventory.getStackInSlot(slot))
|
||||
protected def stackInSlot(slot: Int): StackOption = StackOption(inventory.getStackInSlot(slot))
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import li.cil.oc.api.machine.Context
|
||||
import li.cil.oc.util.ExtendedArguments._
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.ResultWrapper.result
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
trait InventoryControl extends InventoryAware {
|
||||
@ -25,7 +26,7 @@ trait InventoryControl extends InventoryAware {
|
||||
def count(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val slot = optSlot(args, 0)
|
||||
result(stackInSlot(slot) match {
|
||||
case Some(stack) => stack.getCount
|
||||
case SomeStack(stack) => stack.getCount
|
||||
case _ => 0
|
||||
})
|
||||
}
|
||||
@ -34,7 +35,7 @@ trait InventoryControl extends InventoryAware {
|
||||
def space(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val slot = optSlot(args, 0)
|
||||
result(stackInSlot(slot) match {
|
||||
case Some(stack) => math.min(inventory.getInventoryStackLimit, stack.getMaxStackSize) - stack.getCount
|
||||
case SomeStack(stack) => math.min(inventory.getInventoryStackLimit, stack.getMaxStackSize) - stack.getCount
|
||||
case _ => inventory.getInventoryStackLimit
|
||||
})
|
||||
}
|
||||
@ -43,8 +44,8 @@ trait InventoryControl extends InventoryAware {
|
||||
def compareTo(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val slot = args.checkSlot(inventory, 0)
|
||||
result((stackInSlot(selectedSlot), stackInSlot(slot)) match {
|
||||
case (Some(stackA), Some(stackB)) => InventoryUtils.haveSameItemType(stackA, stackB, args.optBoolean(1, false))
|
||||
case (None, None) => true
|
||||
case (SomeStack(stackA), SomeStack(stackB)) => InventoryUtils.haveSameItemType(stackA, stackB, args.optBoolean(1, false))
|
||||
case (EmptyStack, EmptyStack) => true
|
||||
case _ => false
|
||||
})
|
||||
}
|
||||
@ -57,7 +58,7 @@ trait InventoryControl extends InventoryAware {
|
||||
result(true)
|
||||
}
|
||||
else result((stackInSlot(selectedSlot), stackInSlot(slot)) match {
|
||||
case (Some(from), Some(to)) =>
|
||||
case (SomeStack(from), SomeStack(to)) =>
|
||||
if (InventoryUtils.haveSameItemType(from, to, checkNBT = true)) {
|
||||
val space = math.min(inventory.getInventoryStackLimit, to.getMaxStackSize) - to.getCount
|
||||
val amount = math.min(count, math.min(space, from.getCount))
|
||||
@ -79,7 +80,7 @@ trait InventoryControl extends InventoryAware {
|
||||
true
|
||||
}
|
||||
else false
|
||||
case (Some(from), None) =>
|
||||
case (SomeStack(from), EmptyStack) =>
|
||||
inventory.setInventorySlotContents(slot, inventory.decrStackSize(selectedSlot, count))
|
||||
true
|
||||
case _ => false
|
||||
|
@ -7,6 +7,7 @@ import li.cil.oc.api.machine.Context
|
||||
import li.cil.oc.util.ExtendedArguments._
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.ResultWrapper.result
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.entity.item.EntityItem
|
||||
import net.minecraft.item.ItemBlock
|
||||
import net.minecraft.item.ItemStack
|
||||
@ -22,7 +23,7 @@ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRest
|
||||
def compare(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val side = checkSideForAction(args, 0)
|
||||
stackInSlot(selectedSlot) match {
|
||||
case Some(stack) => Option(stack.getItem) match {
|
||||
case SomeStack(stack) => Option(stack.getItem) match {
|
||||
case Some(item: ItemBlock) =>
|
||||
val blockPos = position.offset(side).toBlockPos
|
||||
val state = world.getBlockState(blockPos)
|
||||
|
@ -8,6 +8,7 @@ import li.cil.oc.server.component.result
|
||||
import li.cil.oc.util.DatabaseAccess
|
||||
import li.cil.oc.util.ExtendedArguments._
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.StackOption
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraftforge.items.IItemHandler
|
||||
@ -23,13 +24,13 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ
|
||||
@Callback(doc = """function(side:number, slot:number):number -- Get number of items in the specified slot of the inventory on the specified side of the device.""")
|
||||
def getSlotStackSize(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val facing = checkSideForAction(args, 0)
|
||||
withInventory(facing, inventory => result(Option(inventory.getStackInSlot(args.checkSlot(inventory, 1))).fold(0)(_.getCount)))
|
||||
withInventory(facing, inventory => result(StackOption(inventory.getStackInSlot(args.checkSlot(inventory, 1))).fold(0)(_.getCount)))
|
||||
}
|
||||
|
||||
@Callback(doc = """function(side:number, slot:number):number -- Get the maximum number of items in the specified slot of the inventory on the specified side of the device.""")
|
||||
def getSlotMaxStackSize(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val facing = checkSideForAction(args, 0)
|
||||
withInventory(facing, inventory => result(Option(inventory.getStackInSlot(args.checkSlot(inventory, 1))).fold(0)(_.getMaxStackSize)))
|
||||
withInventory(facing, inventory => result(StackOption(inventory.getStackInSlot(args.checkSlot(inventory, 1))).fold(0)(_.getMaxStackSize)))
|
||||
}
|
||||
|
||||
@Callback(doc = """function(side:number, slotA:number, slotB:number[, checkNBT:boolean=false]):boolean -- Get whether the items in the two specified slots of the inventory on the specified side of the device are of the same type.""")
|
||||
|
@ -2,6 +2,7 @@ package li.cil.oc.util
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.entity.item.EntityItem
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
@ -328,8 +329,8 @@ object InventoryUtils {
|
||||
* the world.
|
||||
*/
|
||||
def dropSlot(position: BlockPosition, inventory: IInventory, slot: Int, count: Int, direction: Option[EnumFacing] = None): Boolean = {
|
||||
Option(inventory.decrStackSize(slot, count)) match {
|
||||
case Some(stack) if stack.getCount > 0 => spawnStackInWorld(position, stack, direction); true
|
||||
StackOption(inventory.decrStackSize(slot, count)) match {
|
||||
case SomeStack(stack) if stack.getCount > 0 => spawnStackInWorld(position, stack, direction); true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
@ -339,8 +340,8 @@ object InventoryUtils {
|
||||
*/
|
||||
def dropAllSlots(position: BlockPosition, inventory: IInventory): Unit = {
|
||||
for (slot <- 0 until inventory.getSizeInventory) {
|
||||
Option(inventory.getStackInSlot(slot)) match {
|
||||
case Some(stack) if stack.getCount > 0 =>
|
||||
StackOption(inventory.getStackInSlot(slot)) match {
|
||||
case SomeStack(stack) if stack.getCount > 0 =>
|
||||
inventory.setInventorySlotContents(slot, ItemStack.EMPTY)
|
||||
spawnStackInWorld(position, stack)
|
||||
case _ => // Nothing.
|
||||
|
97
src/main/scala/li/cil/oc/util/StackOption.scala
Normal file
97
src/main/scala/li/cil/oc/util/StackOption.scala
Normal file
@ -0,0 +1,97 @@
|
||||
package li.cil.oc.util
|
||||
|
||||
import li.cil.oc.util.StackOption._
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
object StackOption {
|
||||
|
||||
//implicit def extendedStack(stack: ItemStack): StackOption = if (stack.isEmpty) Empty else new StackOption(stack)
|
||||
|
||||
implicit def extendedOption(opt: Option[ItemStack]): ExtendedOption = ExtendedOption(opt)
|
||||
|
||||
// Mostly stolen from Option
|
||||
implicit def stack2Iterable(so: StackOption): Iterable[ItemStack] = so.toList
|
||||
|
||||
def apply(stack: ItemStack): StackOption = if (stack == null || stack.isEmpty) EmptyStack else SomeStack(stack)
|
||||
|
||||
def apply(stack: Option[ItemStack]): StackOption = if (stack == null || stack.isEmpty || stack.get.isEmpty) EmptyStack else SomeStack(stack.get)
|
||||
|
||||
def empty: StackOption = EmptyStack
|
||||
|
||||
case object EmptyStack extends StackOption(ItemStack.EMPTY)
|
||||
|
||||
final case class SomeStack(stack: ItemStack) extends StackOption(stack)
|
||||
}
|
||||
|
||||
final case class ExtendedOption(opt : Option[ItemStack]) {
|
||||
def asStackOption = StackOption(opt)
|
||||
}
|
||||
|
||||
sealed abstract class StackOption(stack: ItemStack) extends Product with Serializable {
|
||||
self =>
|
||||
|
||||
def isEmpty: Boolean = stack == null || stack.isEmpty
|
||||
|
||||
def get: ItemStack = stack
|
||||
|
||||
def isDefined: Boolean = !isEmpty
|
||||
|
||||
def getOrElse(default: ItemStack): ItemStack = if (isEmpty) default else this.get
|
||||
|
||||
def orEmpty: ItemStack = if(isEmpty) EmptyStack.get else this.get
|
||||
|
||||
def map(f: ItemStack => ItemStack): StackOption = if (isEmpty) EmptyStack else SomeStack(f(this.get))
|
||||
|
||||
//def map[B](f: ItemStack => B): Option[B] = if (isEmpty) None else Some(f(this.get))
|
||||
|
||||
def fold[B](ifEmpty: => B)(f: ItemStack => B): B = if (isEmpty) ifEmpty else f(this.get)
|
||||
|
||||
def flatMap[B](f: ItemStack => Option[B]): Option[B] = if (isEmpty) None else f(this.get)
|
||||
|
||||
def flatten[B](implicit ev: ItemStack <:< Option[B]): Option[B] = if (isEmpty) None else ev(this.get)
|
||||
|
||||
def filter(p: ItemStack => Boolean): StackOption = if (isEmpty || p(this.get)) this else EmptyStack
|
||||
|
||||
def filterNot(p: ItemStack => Boolean): StackOption = if (isEmpty || !p(this.get)) this else EmptyStack
|
||||
|
||||
def nonEmpty: Boolean = isDefined
|
||||
|
||||
def withFilter(p: ItemStack => Boolean): WithFilter = new WithFilter(p)
|
||||
|
||||
class WithFilter(p: ItemStack => Boolean) {
|
||||
//def map[B](f: ItemStack => B): Option[B] = self filter p map f
|
||||
|
||||
//def flatMap[B](f: ItemStack => Option[B]): Option[B] = self filter p flatMap f
|
||||
|
||||
def foreach[U](f: ItemStack => U): Unit = self filter p foreach f
|
||||
|
||||
def withFilter(q: ItemStack => Boolean): WithFilter = new WithFilter(x => p(x) && q(x))
|
||||
}
|
||||
|
||||
def contains[A1 >: ItemStack](elem: A1): Boolean = !isEmpty && this.get == elem
|
||||
|
||||
def exists(p: ItemStack => Boolean): Boolean = !isEmpty && p(this.get)
|
||||
|
||||
def forall(p: ItemStack => Boolean): Boolean = isEmpty || p(this.get)
|
||||
|
||||
def foreach[U](f: ItemStack => U) {
|
||||
if (!isEmpty) f(this.get)
|
||||
}
|
||||
|
||||
def collect[B](pf: PartialFunction[ItemStack, B]): Option[B] = if (!isEmpty) pf.lift(this.get) else None
|
||||
|
||||
def orElse[B >: ItemStack](alternative: => StackOption): StackOption =
|
||||
if (isEmpty) alternative else this
|
||||
|
||||
def iterator: Iterator[ItemStack] =
|
||||
if (isEmpty) collection.Iterator.empty else collection.Iterator.single(this.get)
|
||||
|
||||
def toList: List[ItemStack] =
|
||||
if (isEmpty) List() else new ::(this.get, Nil)
|
||||
|
||||
def toRight[X](left: => X): Either[X, ItemStack] =
|
||||
if (isEmpty) Left(left) else Right(this.get)
|
||||
|
||||
def toLeft[X](right: => X): Either[ItemStack, X] =
|
||||
if (isEmpty) Right(right) else Left(this.get)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user