Make disassembler finish disassembly of added item immediately if added by a player in creative mode. Closes #839.

This commit is contained in:
Florian Nücke 2015-01-21 21:46:29 +01:00
parent 49197c57b1
commit 60c97140d9
3 changed files with 48 additions and 4 deletions

View File

@ -36,6 +36,15 @@ trait ComponentSlot extends Slot {
} }
} }
override def putStack(stack: ItemStack): Unit = {
super.putStack(stack)
inventory match {
case playerAware: common.tileentity.traits.PlayerInputAware =>
playerAware.onSetInventorySlotContents(container.playerInventory.player, getSlotIndex, stack)
case _ =>
}
}
override def onSlotChanged() { override def onSlotChanged() {
super.onSlotChanged() super.onSlotChanged()
for (slot <- container.inventorySlots) slot match { for (slot <- container.inventorySlots) slot match {

View File

@ -13,6 +13,7 @@ import li.cil.oc.util.BlockPosition
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.InventoryUtils import li.cil.oc.util.InventoryUtils
import li.cil.oc.util.ItemUtils import li.cil.oc.util.ItemUtils
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.Constants.NBT import net.minecraftforge.common.util.Constants.NBT
@ -20,7 +21,7 @@ import net.minecraftforge.common.util.ForgeDirection
import scala.collection.mutable import scala.collection.mutable
class Disassembler extends traits.Environment with traits.PowerAcceptor with traits.Inventory with traits.StateAware { class Disassembler extends traits.Environment with traits.PowerAcceptor with traits.Inventory with traits.StateAware with traits.PlayerInputAware {
val node = api.Network.newNode(this, Visibility.None). val node = api.Network.newNode(this, Visibility.None).
withConnector(Settings.get.bufferConverter). withConnector(Settings.get.bufferConverter).
create() create()
@ -33,6 +34,8 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
var buffer = 0.0 var buffer = 0.0
var disassembleNextInstantly = false
def progress = if (queue.isEmpty) 0 else (1 - (queue.size * Settings.get.disassemblerItemCost - buffer) / totalRequiredEnergy) * 100 def progress = if (queue.isEmpty) 0 else (1 - (queue.size * Settings.get.disassemblerItemCost - buffer) / totalRequiredEnergy) * 100
private def setActive(value: Boolean) = if (value != isActive) { private def setActive(value: Boolean) = if (value != isActive) {
@ -64,7 +67,8 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
super.updateEntity() super.updateEntity()
if (world.getTotalWorldTime % Settings.get.tickFrequency == 0) { if (world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
if (queue.isEmpty) { if (queue.isEmpty) {
disassemble(decrStackSize(0, 1)) val instant = disassembleNextInstantly // Is reset via decrStackSize
disassemble(decrStackSize(0, 1), instant)
setActive(queue.nonEmpty) setActive(queue.nonEmpty)
} }
else { else {
@ -76,7 +80,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
buffer += want buffer += want
} }
} }
if (buffer >= Settings.get.disassemblerItemCost) { while (buffer >= Settings.get.disassemblerItemCost && queue.nonEmpty) {
buffer -= Settings.get.disassemblerItemCost buffer -= Settings.get.disassemblerItemCost
val stack = queue.remove(0) val stack = queue.remove(0)
if (world.rand.nextDouble >= Settings.get.disassemblerBreakChance) { if (world.rand.nextDouble >= Settings.get.disassemblerBreakChance) {
@ -87,7 +91,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
} }
} }
def disassemble(stack: ItemStack) { def disassemble(stack: ItemStack, instant: Boolean = false) {
// Validate the item, never trust Minecraft / other Mods on anything! // Validate the item, never trust Minecraft / other Mods on anything!
if (stack != null && isItemValidForSlot(0, stack)) { if (stack != null && isItemValidForSlot(0, stack)) {
val ingredients = ItemUtils.getIngredients(stack) val ingredients = ItemUtils.getIngredients(stack)
@ -99,6 +103,10 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
case _ => queue ++= ingredients case _ => queue ++= ingredients
} }
totalRequiredEnergy = queue.size * Settings.get.disassemblerItemCost totalRequiredEnergy = queue.size * Settings.get.disassemblerItemCost
if (instant) {
buffer = totalRequiredEnergy
disassembleNextInstantly = false // Just to be sure...
}
} }
} }
@ -152,4 +160,17 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
override def isItemValidForSlot(i: Int, stack: ItemStack) = override def isItemValidForSlot(i: Int, stack: ItemStack) =
((Settings.get.disassembleAllTheThings || api.Items.get(stack) != null) && ItemUtils.getIngredients(stack).nonEmpty) || ((Settings.get.disassembleAllTheThings || api.Items.get(stack) != null) && ItemUtils.getIngredients(stack).nonEmpty) ||
DisassemblerTemplates.select(stack) != None DisassemblerTemplates.select(stack) != None
override def setInventorySlotContents(slot: Int, stack: ItemStack): Unit = {
super.setInventorySlotContents(slot, stack)
if (!world.isRemote) {
disassembleNextInstantly = false
}
}
override def onSetInventorySlotContents(player: EntityPlayer, slot: Int, stack: ItemStack): Unit = {
if (!world.isRemote) {
disassembleNextInstantly = stack != null && slot == 0 && player.capabilities.isCreativeMode
}
}
} }

View File

@ -0,0 +1,14 @@
package li.cil.oc.common.tileentity.traits
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.inventory.IInventory
import net.minecraft.item.ItemStack
// Used to get notifications from containers when a player changes a slot in
// this inventory. Normally the player causing a setInventorySlotContents is
// unavailable. Using this we gain access to the causing player, allowing for
// some player-specific logic, such as the disassembler working instantaneously
// when used by a player in creative mode.
trait PlayerInputAware extends IInventory {
def onSetInventorySlotContents(player: EntityPlayer, slot: Int, stack: ItemStack): Unit
}