mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-16 10:51:55 -04:00
sided inventory for robots; drop can now place stuff from the robots inventory into some other inventory, if present
This commit is contained in:
parent
76efda0a7a
commit
b3a5521dc1
@ -79,7 +79,7 @@ trait Inventory extends TileEntity with IInventory with Persistable {
|
||||
}
|
||||
}
|
||||
|
||||
private def spawnStackInWorld(stack: ItemStack, direction: ForgeDirection) {
|
||||
def spawnStackInWorld(stack: ItemStack, direction: ForgeDirection) {
|
||||
val rng = world.rand
|
||||
val (tx, ty, tz) = (
|
||||
0.1 * rng.nextGaussian + direction.offsetX * 0.45,
|
||||
|
@ -12,6 +12,7 @@ import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.{Blocks, Config, api, common}
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory.ISidedInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.ForgeDirection
|
||||
@ -23,7 +24,7 @@ import scala.Some
|
||||
// robot moves we only create a new proxy tile entity, hook the instance of this
|
||||
// class that was held by the old proxy to it and can then safely forget the
|
||||
// old proxy, which will be cleaned up by Minecraft like any other tile entity.
|
||||
class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with PowerInformation {
|
||||
class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory with Buffer with PowerInformation {
|
||||
def this() = this(false)
|
||||
|
||||
var proxy: RobotProxy = _
|
||||
@ -282,40 +283,6 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with Power
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def installedMemory = 64 * 1024
|
||||
|
||||
def tier = 0
|
||||
|
||||
override def hasRedstoneCard = items(1).fold(false)(driver.item.RedstoneCard.worksWith)
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override protected def markForRenderUpdate() {
|
||||
super.markForRenderUpdate()
|
||||
currentGui.foreach(_.recompileDisplayLists())
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def getInvName = Config.namespace + "container.Robot"
|
||||
|
||||
def getSizeInventory = 19
|
||||
|
||||
override def getInventoryStackLimit = 64
|
||||
|
||||
override def isUseableByPlayer(player: EntityPlayer) =
|
||||
world.getBlockTileEntity(x, y, z) match {
|
||||
case t: RobotProxy if t == proxy => player.getDistanceSq(x + 0.5, y + 0.5, z + 0.5) <= 64
|
||||
case _ => false
|
||||
}
|
||||
|
||||
def isItemValidForSlot(slot: Int, item: ItemStack) = (slot, Registry.driverFor(item)) match {
|
||||
case (0, _) => true // Allow anything in the tool slot.
|
||||
case (1, Some(driver)) => driver.slot(item) == Slot.Card
|
||||
case (2, Some(driver)) => driver.slot(item) == Slot.HardDiskDrive
|
||||
case (i, _) if 3 until getSizeInventory contains i => true // Normal inventory.
|
||||
case _ => false // Invalid slot.
|
||||
}
|
||||
|
||||
override def onInventoryChanged() {
|
||||
super.onInventoryChanged()
|
||||
if (isServer) {
|
||||
@ -350,4 +317,57 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with Power
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def installedMemory = 64 * 1024
|
||||
|
||||
def tier = 0
|
||||
|
||||
override def hasRedstoneCard = items(1).fold(false)(driver.item.RedstoneCard.worksWith)
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override protected def markForRenderUpdate() {
|
||||
super.markForRenderUpdate()
|
||||
currentGui.foreach(_.recompileDisplayLists())
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def getInvName = Config.namespace + "container.Robot"
|
||||
|
||||
def getSizeInventory = 19
|
||||
|
||||
override def getInventoryStackLimit = 64
|
||||
|
||||
override def isUseableByPlayer(player: EntityPlayer) =
|
||||
world.getBlockTileEntity(x, y, z) match {
|
||||
case t: RobotProxy if t == proxy => player.getDistanceSq(x + 0.5, y + 0.5, z + 0.5) <= 64
|
||||
case _ => false
|
||||
}
|
||||
|
||||
def isItemValidForSlot(slot: Int, item: ItemStack) = (slot, Registry.driverFor(item)) match {
|
||||
case (0, _) => true // Allow anything in the tool slot.
|
||||
case (1, Some(driver)) => driver.slot(item) == Slot.Card
|
||||
case (2, Some(driver)) => driver.slot(item) == Slot.HardDiskDrive
|
||||
case (i, _) if 3 until getSizeInventory contains i => true // Normal inventory.
|
||||
case _ => false // Invalid slot.
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def canExtractItem(slot: Int, stack: ItemStack, side: Int) =
|
||||
getAccessibleSlotsFromSide(side).contains(slot)
|
||||
|
||||
def canInsertItem(slot: Int, stack: ItemStack, side: Int) =
|
||||
getAccessibleSlotsFromSide(side).contains(slot) &&
|
||||
isItemValidForSlot(slot, stack)
|
||||
|
||||
def getAccessibleSlotsFromSide(side: Int) =
|
||||
toLocal(ForgeDirection.getOrientation(side)) match {
|
||||
case ForgeDirection.WEST => Array(0)
|
||||
case ForgeDirection.EAST => Array(1)
|
||||
case ForgeDirection.NORTH => Array(2)
|
||||
case _ => (3 until getSizeInventory).toArray
|
||||
}
|
||||
}
|
||||
|
@ -8,11 +8,12 @@ import li.cil.oc.client.gui
|
||||
import mods.immibis.redlogic.api.wiring.IWire
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory.ISidedInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.ForgeDirection
|
||||
|
||||
class RobotProxy(val robot: Robot) extends Computer(robot.isClient) with Buffer with PowerInformation {
|
||||
class RobotProxy(val robot: Robot) extends Computer(robot.isClient) with ISidedInventory with Buffer with PowerInformation {
|
||||
def this() = this(new Robot(false))
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
@ -203,6 +204,14 @@ class RobotProxy(val robot: Robot) extends Computer(robot.isClient) with Buffer
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def canExtractItem(slot: Int, stack: ItemStack, side: Int) = robot.canExtractItem(slot, stack, side)
|
||||
|
||||
def canInsertItem(slot: Int, stack: ItemStack, side: Int) = robot.canInsertItem(slot, stack, side)
|
||||
|
||||
def getAccessibleSlotsFromSide(side: Int) = robot.getAccessibleSlotsFromSide(side)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def computer = robot.computer
|
||||
|
||||
override def isOn = robot.isOn
|
||||
|
@ -7,6 +7,7 @@ import li.cil.oc.server.component.robot.ActivationType
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import net.minecraft.block.{BlockFluid, Block}
|
||||
import net.minecraft.entity.item.EntityItem
|
||||
import net.minecraft.inventory.{IInventory, ISidedInventory}
|
||||
import net.minecraft.item.{ItemStack, ItemBlock}
|
||||
import net.minecraft.util.{MovingObjectPosition, EnumMovingObjectType, Vec3}
|
||||
import net.minecraftforge.common.ForgeDirection
|
||||
@ -125,12 +126,51 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
||||
def drop(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val facing = checkSideForAction(args, 0)
|
||||
val count = checkOptionalItemCount(args, 1)
|
||||
// TODO inventory, if available
|
||||
|
||||
// Don't drop using the fake player because he throws too far.
|
||||
if (robot.dropSlot(actualSlot(selectedSlot), count, facing)) {
|
||||
context.pause(Config.dropDelay)
|
||||
result(true)
|
||||
val dropped = robot.decrStackSize(actualSlot(selectedSlot), count)
|
||||
if (dropped != null && dropped.stackSize > 0) {
|
||||
def tryDropIntoInventory(inventory: IInventory, filter: (Int) => Boolean) = {
|
||||
var success = false
|
||||
val maxStackSize = inventory.getInventoryStackLimit min dropped.getMaxStackSize
|
||||
val shouldTryMerge = !dropped.isItemStackDamageable && dropped.getMaxStackSize > 1 && inventory.getInventoryStackLimit > 1
|
||||
if (shouldTryMerge) {
|
||||
for (slot <- 0 until inventory.getSizeInventory if dropped.stackSize > 0 && filter(slot)) {
|
||||
val existing = inventory.getStackInSlot(slot)
|
||||
val shouldMerge = existing != null && existing.stackSize < maxStackSize &&
|
||||
existing.isItemEqual(dropped) && ItemStack.areItemStackTagsEqual(existing, dropped)
|
||||
if (shouldMerge) {
|
||||
val space = maxStackSize - existing.stackSize
|
||||
val amount = space min dropped.stackSize
|
||||
assert(amount > 0)
|
||||
success = true
|
||||
existing.stackSize += amount
|
||||
dropped.stackSize -= amount
|
||||
}
|
||||
}
|
||||
}
|
||||
def canDropIntoSlot(slot: Int) = filter(slot) && inventory.isItemValidForSlot(slot, dropped) && inventory.getStackInSlot(slot) == null
|
||||
for (slot <- 0 until inventory.getSizeInventory if dropped.stackSize > 0 && canDropIntoSlot(slot)) {
|
||||
val amount = maxStackSize min dropped.stackSize
|
||||
inventory.setInventorySlotContents(slot, dropped.splitStack(amount))
|
||||
success = true
|
||||
}
|
||||
if (success) {
|
||||
inventory.onInventoryChanged()
|
||||
}
|
||||
robot.player().inventory.addItemStackToInventory(dropped)
|
||||
result(success)
|
||||
}
|
||||
world.getBlockTileEntity(x + facing.offsetX, y + facing.offsetY, z + facing.offsetZ) match {
|
||||
case inventory: ISidedInventory =>
|
||||
tryDropIntoInventory(inventory, (slot) => inventory.canInsertItem(slot, dropped, facing.getOpposite.ordinal()))
|
||||
case inventory: IInventory =>
|
||||
tryDropIntoInventory(inventory, (slot) => true)
|
||||
case _ =>
|
||||
// Don't drop using the fake player because he throws too far.
|
||||
// TODO make player's drop redirect to our dropSlot
|
||||
robot.spawnStackInWorld(dropped, facing)
|
||||
context.pause(Config.dropDelay)
|
||||
result(true)
|
||||
}
|
||||
}
|
||||
else result(false)
|
||||
}
|
||||
@ -175,15 +215,19 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
||||
def suck(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val facing = checkSideForAction(args, 0)
|
||||
val count = checkOptionalItemCount(args, 1)
|
||||
// TODO inventory, if available
|
||||
for (entity <- robot.player().entitiesOnSide[EntityItem](facing) if !entity.isDead && entity.delayBeforeCanPickup <= 0) {
|
||||
val stack = entity.getEntityItem
|
||||
val size = stack.stackSize
|
||||
entity.onCollideWithPlayer(robot.player())
|
||||
if (stack.stackSize < size || entity.isDead) {
|
||||
context.pause(Config.suckDelay)
|
||||
return result(true)
|
||||
}
|
||||
world.getBlockTileEntity(x + facing.offsetX, y + facing.offsetY, z + facing.offsetZ) match {
|
||||
case inventory: ISidedInventory => // TODO
|
||||
case inventory: IInventory => // TODO
|
||||
case _ =>
|
||||
for (entity <- robot.player().entitiesOnSide[EntityItem](facing) if !entity.isDead && entity.delayBeforeCanPickup <= 0) {
|
||||
val stack = entity.getEntityItem
|
||||
val size = stack.stackSize
|
||||
entity.onCollideWithPlayer(robot.player())
|
||||
if (stack.stackSize < size || entity.isDead) {
|
||||
context.pause(Config.suckDelay)
|
||||
return result(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
result(false)
|
||||
}
|
||||
|
@ -273,9 +273,11 @@ class Player(val robot: Robot) extends FakePlayer(robot.world, "OpenComputers")
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def swingItem() {
|
||||
// TODO animation
|
||||
}
|
||||
override def openGui(mod: AnyRef, modGuiId: Int, world: World, x: Int, y: Int, z: Int) {}
|
||||
|
||||
override def closeScreen() {}
|
||||
|
||||
override def swingItem() {}
|
||||
|
||||
override def canAttackPlayer(player: EntityPlayer) =
|
||||
Config.canAttackPlayers && super.canAttackPlayer(player)
|
||||
@ -290,9 +292,7 @@ class Player(val robot: Robot) extends FakePlayer(robot.world, "OpenComputers")
|
||||
|
||||
override def setItemInUse(stack: ItemStack, maxItemUseDuration: Int) {}
|
||||
|
||||
override def openGui(mod: AnyRef, modGuiId: Int, world: World, x: Int, y: Int, z: Int) {}
|
||||
|
||||
override def closeScreen() {}
|
||||
override def isEntityInvulnerable = true
|
||||
|
||||
override def heal(amount: Float) {}
|
||||
|
||||
@ -302,6 +302,10 @@ class Player(val robot: Robot) extends FakePlayer(robot.world, "OpenComputers")
|
||||
|
||||
override def onDeath(source: DamageSource) {}
|
||||
|
||||
override def onUpdate() {}
|
||||
|
||||
override def onLivingUpdate() {}
|
||||
|
||||
override def setCurrentItemOrArmor(slot: Int, stack: ItemStack) {}
|
||||
|
||||
override def setRevengeTarget(entity: EntityLivingBase) {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user