mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-18 11:48:02 -04:00
crafting addon, allows robots to craft in the 3x3 grid in the top left of their inventory; added extended context interface for robot interaction, allowing access to selected slot index and fake player for general stuff and in particular for inventory interaction; todo: maybe a nicer check in component if method is interface compatible (context/robotcontext) each call?
This commit is contained in:
parent
608383bf8a
commit
d23a6534d9
BIN
assets/opencomputers/textures/items/crafting.png
Normal file
BIN
assets/opencomputers/textures/items/crafting.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 372 B |
Binary file not shown.
Before Width: | Height: | Size: 210 B After Width: | Height: | Size: 250 B |
@ -6,16 +6,33 @@ import li.cil.oc.common.item
|
|||||||
object Items {
|
object Items {
|
||||||
var multi: item.Delegator = null
|
var multi: item.Delegator = null
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
// Tools
|
||||||
var analyzer: item.Analyzer = null
|
var analyzer: item.Analyzer = null
|
||||||
var disk: item.Disk = null
|
|
||||||
var generator: item.Generator = null
|
// ----------------------------------------------------------------------- //
|
||||||
var gpu1, gpu2, gpu3: item.GraphicsCard = null
|
// Memory
|
||||||
var hdd1, hdd2, hdd3: item.HardDiskDrive = null
|
|
||||||
var lan: item.NetworkCard = null
|
|
||||||
var ram1, ram2, ram3: item.Memory = null
|
var ram1, ram2, ram3: item.Memory = null
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
// Storage
|
||||||
|
var disk: item.Disk = null
|
||||||
|
var hdd1, hdd2, hdd3: item.HardDiskDrive = null
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
// Cards
|
||||||
|
var gpu1, gpu2, gpu3: item.GraphicsCard = null
|
||||||
|
var lan: item.NetworkCard = null
|
||||||
var rs: item.RedstoneCard = null
|
var rs: item.RedstoneCard = null
|
||||||
var wlan: item.WirelessNetworkCard = null
|
var wlan: item.WirelessNetworkCard = null
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
// Upgrades
|
||||||
|
var crafting: item.Crafting = null
|
||||||
|
var generator: item.Generator = null
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
// Crafting
|
||||||
var card: item.Card = null
|
var card: item.Card = null
|
||||||
var circuitBoardBody: item.PlatineBody = null
|
var circuitBoardBody: item.PlatineBody = null
|
||||||
var circuitBoard: item.Platine = null
|
var circuitBoard: item.Platine = null
|
||||||
@ -41,6 +58,7 @@ object Items {
|
|||||||
ram3 = new item.Memory(multi, 2)
|
ram3 = new item.Memory(multi, 2)
|
||||||
rs = new item.RedstoneCard(multi)
|
rs = new item.RedstoneCard(multi)
|
||||||
wlan = new item.WirelessNetworkCard(multi)
|
wlan = new item.WirelessNetworkCard(multi)
|
||||||
|
crafting = new item.Crafting(multi)
|
||||||
|
|
||||||
card = new item.Card(multi)
|
card = new item.Card(multi)
|
||||||
circuitBoardBody = new item.PlatineBody(multi)
|
circuitBoardBody = new item.PlatineBody(multi)
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package li.cil.oc.api.network;
|
package li.cil.oc.api.network;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is used to provide some context to {@link LuaCallback}s, i.e. the
|
* This is used to provide some context to {@link LuaCallback}s, i.e. the
|
||||||
* computer from which the callback was called.
|
* computer from which the callback was called.
|
||||||
@ -161,37 +159,4 @@ public interface Context {
|
|||||||
* @return <tt>true</tt> if the signal was queued; <tt>false</tt> otherwise.
|
* @return <tt>true</tt> if the signal was queued; <tt>false</tt> otherwise.
|
||||||
*/
|
*/
|
||||||
boolean signal(String name, Object... args);
|
boolean signal(String name, Object... args);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the item stack that is currently in the robot's selected slot.
|
|
||||||
* <p/>
|
|
||||||
* For normal computers this will always return <tt>null</tt>.
|
|
||||||
* <p/>
|
|
||||||
* Note that this returns the actual <tt>ItemStack</tt> instance that is in
|
|
||||||
* the robot's inventory, so if you manipulate the stack's size, make sure
|
|
||||||
* to always call {@link #setStackInSelectedSlot} with the stack itself
|
|
||||||
* afterwards, to trigger an `onInventoryUpdate` in the robot.
|
|
||||||
*
|
|
||||||
* @return the item stack in the robot's currently selected inventory slot.
|
|
||||||
*/
|
|
||||||
ItemStack getStackInSelectedSlot();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the item stack in the robot's selected inventory slot.
|
|
||||||
* <p/>
|
|
||||||
* For computers this will always do nothing and return <tt>false</tt>.
|
|
||||||
* <p/>
|
|
||||||
* This will store a copy / split portion of the passed stack in the robot's
|
|
||||||
* inventory. How many items of the stack were stored can be seen from the
|
|
||||||
* stack size of the passed stack after the function returns (it will be
|
|
||||||
* set to the number of remaining items, or zero if the stack was completely
|
|
||||||
* stored).
|
|
||||||
* <p/>
|
|
||||||
* If the slot is not empty, and the stack cannot be - at least partially -
|
|
||||||
* merged into the existing item stack this will return <tt>false</tt>.
|
|
||||||
*
|
|
||||||
* @param stack the stack to store in the currently selected slot.
|
|
||||||
* @return <tt>true</tt> if the stack was completely or partially stored.
|
|
||||||
*/
|
|
||||||
boolean setStackInSelectedSlot(ItemStack stack);
|
|
||||||
}
|
}
|
||||||
|
25
li/cil/oc/api/network/RobotContext.java
Normal file
25
li/cil/oc/api/network/RobotContext.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package li.cil.oc.api.network;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
|
||||||
|
public interface RobotContext extends Context {
|
||||||
|
/**
|
||||||
|
* Gets the index of the currently selected slot in the robot's inventory.
|
||||||
|
*
|
||||||
|
* @return the index of the currently selected slot.
|
||||||
|
*/
|
||||||
|
int selectedSlot();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the fake player used to represent the robot as an entity for
|
||||||
|
* certain actions that require one.
|
||||||
|
* <p/>
|
||||||
|
* This will automatically be positioned and rotated to represent the
|
||||||
|
* robot's current position and rotation in the world. Use this to trigger
|
||||||
|
* events involving the robot that require a player entity, and for
|
||||||
|
* interacting with the robots' inventory.
|
||||||
|
*
|
||||||
|
* @return the fake player for the robot.
|
||||||
|
*/
|
||||||
|
EntityPlayer player();
|
||||||
|
}
|
@ -119,8 +119,9 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten
|
|||||||
Minecraft.getMinecraft.renderEngine.bindTexture(selection)
|
Minecraft.getMinecraft.renderEngine.bindTexture(selection)
|
||||||
val now = System.currentTimeMillis() / 1000.0
|
val now = System.currentTimeMillis() / 1000.0
|
||||||
val offsetV = ((now - now.toInt) * selectionsStates).toInt * selectionStepV
|
val offsetV = ((now - now.toInt) * selectionsStates).toInt * selectionStepV
|
||||||
val x = guiLeft + inventoryX + (robot.selectedSlot % 4) * (selectionSize - 2)
|
val slot = robot.selectedSlot - robot.actualSlot(0)
|
||||||
val y = guiTop + inventoryY + (robot.selectedSlot / 4) * (selectionSize - 2)
|
val x = guiLeft + inventoryX + (slot % 4) * (selectionSize - 2)
|
||||||
|
val y = guiTop + inventoryY + (slot / 4) * (selectionSize - 2)
|
||||||
|
|
||||||
val t = Tessellator.instance
|
val t = Tessellator.instance
|
||||||
t.startDrawingQuads()
|
t.startDrawingQuads()
|
||||||
|
@ -26,11 +26,12 @@ class Proxy {
|
|||||||
api.Driver.add(driver.block.Carriage)
|
api.Driver.add(driver.block.Carriage)
|
||||||
api.Driver.add(driver.block.CommandBlock)
|
api.Driver.add(driver.block.CommandBlock)
|
||||||
|
|
||||||
|
api.Driver.add(driver.item.Crafting)
|
||||||
api.Driver.add(driver.item.FileSystem)
|
api.Driver.add(driver.item.FileSystem)
|
||||||
|
api.Driver.add(driver.item.Generator)
|
||||||
api.Driver.add(driver.item.GraphicsCard)
|
api.Driver.add(driver.item.GraphicsCard)
|
||||||
api.Driver.add(driver.item.Memory)
|
api.Driver.add(driver.item.Memory)
|
||||||
api.Driver.add(driver.item.NetworkCard)
|
api.Driver.add(driver.item.NetworkCard)
|
||||||
api.Driver.add(driver.item.Generator)
|
|
||||||
api.Driver.add(driver.item.RedstoneCard)
|
api.Driver.add(driver.item.RedstoneCard)
|
||||||
api.Driver.add(driver.item.WirelessNetworkCard)
|
api.Driver.add(driver.item.WirelessNetworkCard)
|
||||||
|
|
||||||
|
23
li/cil/oc/common/item/Crafting.scala
Normal file
23
li/cil/oc/common/item/Crafting.scala
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package li.cil.oc.common.item
|
||||||
|
|
||||||
|
import java.util
|
||||||
|
import li.cil.oc.Settings
|
||||||
|
import li.cil.oc.util.Tooltip
|
||||||
|
import net.minecraft.client.renderer.texture.IconRegister
|
||||||
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
|
||||||
|
class Crafting(val parent: Delegator) extends Delegate {
|
||||||
|
val unlocalizedName = "Crafting"
|
||||||
|
|
||||||
|
override def addInformation(stack: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean) {
|
||||||
|
tooltip.addAll(Tooltip.get(unlocalizedName))
|
||||||
|
super.addInformation(stack, player, tooltip, advanced)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def registerIcons(iconRegister: IconRegister) = {
|
||||||
|
super.registerIcons(iconRegister)
|
||||||
|
|
||||||
|
icon = iconRegister.registerIcon(Settings.resourceDomain + ":crafting")
|
||||||
|
}
|
||||||
|
}
|
@ -33,7 +33,12 @@ trait Inventory extends TileEntity with IInventory with Persistable {
|
|||||||
onItemRemoved(slot, items(slot).get)
|
onItemRemoved(slot, items(slot).get)
|
||||||
}
|
}
|
||||||
|
|
||||||
items(slot) = Option(stack)
|
if (stack == null || stack.stackSize <= 0) {
|
||||||
|
items(slot) = None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
items(slot) = Some(stack)
|
||||||
|
}
|
||||||
if (stack != null && stack.stackSize > getInventoryStackLimit) {
|
if (stack != null && stack.stackSize > getInventoryStackLimit) {
|
||||||
stack.stackSize = getInventoryStackLimit
|
stack.stackSize = getInventoryStackLimit
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import li.cil.oc.util.ExtendedNBT._
|
|||||||
import li.cil.oc.util.{ThreadPoolFactory, GameTimeFormatter, LuaStateFactory}
|
import li.cil.oc.util.{ThreadPoolFactory, GameTimeFormatter, LuaStateFactory}
|
||||||
import li.cil.oc.{OpenComputers, Settings}
|
import li.cil.oc.{OpenComputers, Settings}
|
||||||
import net.minecraft.entity.player.EntityPlayer
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
import net.minecraft.item.ItemStack
|
|
||||||
import net.minecraft.nbt._
|
import net.minecraft.nbt._
|
||||||
import net.minecraft.server.MinecraftServer
|
import net.minecraft.server.MinecraftServer
|
||||||
import scala.Array.canBuildFrom
|
import scala.Array.canBuildFrom
|
||||||
@ -174,10 +173,6 @@ class Computer(val owner: tileentity.Computer) extends ManagedComponent with Con
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
def getStackInSelectedSlot: ItemStack = null
|
|
||||||
|
|
||||||
def setStackInSelectedSlot(stack: ItemStack) = false
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
@LuaCallback("start")
|
@LuaCallback("start")
|
||||||
|
95
li/cil/oc/server/component/Crafting.scala
Normal file
95
li/cil/oc/server/component/Crafting.scala
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
package li.cil.oc.server.component
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.registry.GameRegistry
|
||||||
|
import li.cil.oc.api
|
||||||
|
import li.cil.oc.api.network._
|
||||||
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
import net.minecraft.inventory.{Container, InventoryCrafting}
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.item.crafting.CraftingManager
|
||||||
|
import net.minecraft.tileentity.{TileEntity => MCTileEntity}
|
||||||
|
import net.minecraftforge.common.MinecraftForge
|
||||||
|
import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent
|
||||||
|
import scala.collection.mutable
|
||||||
|
|
||||||
|
class Crafting(owner: MCTileEntity) extends ManagedComponent {
|
||||||
|
val node = api.Network.newNode(this, Visibility.Network).
|
||||||
|
withComponent("crafting").
|
||||||
|
create()
|
||||||
|
|
||||||
|
@LuaCallback("craft")
|
||||||
|
def craft(context: RobotContext, args: Arguments): Array[AnyRef] = {
|
||||||
|
val count = if (args.count > 0) args.checkInteger(0) else 64
|
||||||
|
if (count > 0 && context.player.inventory.getStackInSlot(context.selectedSlot) != null) {
|
||||||
|
throw new IllegalArgumentException("selected result slot is not empty")
|
||||||
|
}
|
||||||
|
result(CraftingInventory.craft(context, count))
|
||||||
|
}
|
||||||
|
|
||||||
|
private object CraftingInventory extends InventoryCrafting(new Container {
|
||||||
|
def canInteractWith(player: EntityPlayer) = true
|
||||||
|
}, 4, 4) {
|
||||||
|
var amountPossible = 0
|
||||||
|
|
||||||
|
def craft(context: RobotContext, wantedCount: Int): Boolean = {
|
||||||
|
CraftingInventory.load(context)
|
||||||
|
val manager = CraftingManager.getInstance
|
||||||
|
val result = manager.findMatchingRecipe(CraftingInventory, owner.getWorldObj)
|
||||||
|
if (result == null) return false
|
||||||
|
val targetStackSize = if (result.isStackable) wantedCount min result.getMaxStackSize else result.stackSize
|
||||||
|
val timesCrafted = targetStackSize / result.stackSize
|
||||||
|
if (timesCrafted <= 0) return true
|
||||||
|
val surplus = mutable.ArrayBuffer.empty[ItemStack]
|
||||||
|
for (row <- 0 until 3) for (col <- 0 until 3) {
|
||||||
|
val slot = row * 3 + col
|
||||||
|
val stack = getStackInSlot(slot)
|
||||||
|
if (stack != null) {
|
||||||
|
decrStackSize(slot, timesCrafted)
|
||||||
|
val item = stack.getItem
|
||||||
|
if (item.hasContainerItem) {
|
||||||
|
val container = item.getContainerItemStack(stack)
|
||||||
|
if (container.isItemStackDamageable && container.getItemDamage > container.getMaxDamage) {
|
||||||
|
MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(context.player, container))
|
||||||
|
}
|
||||||
|
else if (container.getItem.doesContainerItemLeaveCraftingGrid(container) || getStackInSlot(slot) != null) {
|
||||||
|
surplus += container
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
container.stackSize *= timesCrafted
|
||||||
|
setInventorySlotContents(slot, container)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GameRegistry.onItemCrafted(context.player, result, this)
|
||||||
|
CraftingInventory.save(context)
|
||||||
|
result.stackSize *= timesCrafted
|
||||||
|
val inventory = context.player.inventory
|
||||||
|
inventory.addItemStackToInventory(result)
|
||||||
|
for (stack <- surplus) {
|
||||||
|
inventory.addItemStackToInventory(stack)
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
def load(context: RobotContext) {
|
||||||
|
val inventory = context.player.inventory
|
||||||
|
amountPossible = Int.MaxValue
|
||||||
|
for (slot <- 0 until 16) {
|
||||||
|
val stack = inventory.getStackInSlot(slot + 4)
|
||||||
|
setInventorySlotContents(slot, stack)
|
||||||
|
if (stack != null) {
|
||||||
|
amountPossible = amountPossible min stack.stackSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def save(context: RobotContext) {
|
||||||
|
val inventory = context.player.inventory
|
||||||
|
for (slot <- 0 until 16) {
|
||||||
|
inventory.setInventorySlotContents(slot + 4, getStackInSlot(slot))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,11 +1,12 @@
|
|||||||
package li.cil.oc.server.component
|
package li.cil.oc.server.component
|
||||||
|
|
||||||
import li.cil.oc.api.network.{Context, Arguments, LuaCallback, Visibility}
|
import li.cil.oc.api.network._
|
||||||
import li.cil.oc.util.ExtendedNBT._
|
import li.cil.oc.util.ExtendedNBT._
|
||||||
import li.cil.oc.{Settings, api}
|
import li.cil.oc.{Settings, api}
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.nbt.NBTTagCompound
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
import net.minecraft.tileentity.TileEntityFurnace
|
import net.minecraft.tileentity.TileEntityFurnace
|
||||||
|
import scala.Some
|
||||||
|
|
||||||
class Generator extends ManagedComponent {
|
class Generator extends ManagedComponent {
|
||||||
val node = api.Network.newNode(this, Visibility.Network).
|
val node = api.Network.newNode(this, Visibility.Network).
|
||||||
@ -20,14 +21,15 @@ class Generator extends ManagedComponent {
|
|||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
@LuaCallback("insert")
|
@LuaCallback("insert")
|
||||||
def insert(context: Context, args: Arguments): Array[AnyRef] = {
|
def insert(context: RobotContext, args: Arguments): Array[AnyRef] = {
|
||||||
val count = if (args.count > 0) args.checkInteger(0) else 64
|
val count = if (args.count > 0) args.checkInteger(0) else 64
|
||||||
val stack = context.getStackInSelectedSlot
|
val player = context.player
|
||||||
|
val stack = player.inventory.getStackInSlot(context.selectedSlot)
|
||||||
if (stack == null) throw new IllegalArgumentException("selected slot is empty")
|
if (stack == null) throw new IllegalArgumentException("selected slot is empty")
|
||||||
if (!TileEntityFurnace.isItemFuel(stack)) return result(false, "selected slot does not contain fuel")
|
if (!TileEntityFurnace.isItemFuel(stack)) return result(false, "selected slot does not contain fuel")
|
||||||
inventory match {
|
inventory match {
|
||||||
case Some(existingStack) =>
|
case Some(existingStack) =>
|
||||||
if (!ItemStack.areItemStacksEqual(existingStack, stack) ||
|
if (!existingStack.isItemEqual(stack) ||
|
||||||
!ItemStack.areItemStackTagsEqual(existingStack, stack)) {
|
!ItemStack.areItemStackTagsEqual(existingStack, stack)) {
|
||||||
return result(false, "different fuel type already queued")
|
return result(false, "different fuel type already queued")
|
||||||
}
|
}
|
||||||
@ -41,7 +43,7 @@ class Generator extends ManagedComponent {
|
|||||||
case _ =>
|
case _ =>
|
||||||
inventory = Some(stack.splitStack(stack.getMaxStackSize min count))
|
inventory = Some(stack.splitStack(stack.getMaxStackSize min count))
|
||||||
}
|
}
|
||||||
context.setStackInSelectedSlot(stack)
|
player.inventory.setInventorySlotContents(context.selectedSlot, stack)
|
||||||
result(true)
|
result(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,8 +56,19 @@ class Generator extends ManagedComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@LuaCallback("remove")
|
@LuaCallback("remove")
|
||||||
def remove(context: Context, args: Arguments): Array[AnyRef] = {
|
def remove(context: RobotContext, args: Arguments): Array[AnyRef] = {
|
||||||
null
|
val count = if (args.count > 0) args.checkInteger(0) else Int.MaxValue
|
||||||
|
inventory match {
|
||||||
|
case Some(stack) =>
|
||||||
|
val removedStack = stack.splitStack(count min stack.stackSize)
|
||||||
|
val success = context.player.inventory.addItemStackToInventory(removedStack)
|
||||||
|
stack.stackSize += removedStack.stackSize
|
||||||
|
if (success && stack.stackSize <= 0) {
|
||||||
|
inventory = None
|
||||||
|
}
|
||||||
|
result(success)
|
||||||
|
case _ => result(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package li.cil.oc.server.component
|
package li.cil.oc.server.component
|
||||||
|
|
||||||
import li.cil.oc.Settings
|
import li.cil.oc.Settings
|
||||||
import li.cil.oc.api.network.{LuaCallback, Arguments, Context}
|
import li.cil.oc.api.network.{RobotContext, LuaCallback, Arguments, Context}
|
||||||
import li.cil.oc.common.tileentity
|
import li.cil.oc.common.tileentity
|
||||||
import li.cil.oc.server.component.robot.{Player, ActivationType}
|
import li.cil.oc.server.component.robot.{Player, ActivationType}
|
||||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||||
import net.minecraft.block.{BlockFluid, Block}
|
import net.minecraft.block.{BlockFluid, Block}
|
||||||
import net.minecraft.entity.{EntityLivingBase, Entity}
|
|
||||||
import net.minecraft.entity.item.EntityItem
|
import net.minecraft.entity.item.EntityItem
|
||||||
|
import net.minecraft.entity.{EntityLivingBase, Entity}
|
||||||
import net.minecraft.inventory.{IInventory, ISidedInventory}
|
import net.minecraft.inventory.{IInventory, ISidedInventory}
|
||||||
import net.minecraft.item.{ItemStack, ItemBlock}
|
import net.minecraft.item.{ItemStack, ItemBlock}
|
||||||
import net.minecraft.util.{Vec3, MovingObjectPosition, EnumMovingObjectType}
|
import net.minecraft.util.{Vec3, MovingObjectPosition, EnumMovingObjectType}
|
||||||
@ -16,9 +16,7 @@ import net.minecraftforge.fluids.FluidRegistry
|
|||||||
import scala.Some
|
import scala.Some
|
||||||
import scala.collection.convert.WrapAsScala._
|
import scala.collection.convert.WrapAsScala._
|
||||||
|
|
||||||
class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotContext {
|
||||||
|
|
||||||
def selectedSlot = robot.selectedSlot
|
|
||||||
|
|
||||||
def actualSlot(n: Int) = robot.actualSlot(n)
|
def actualSlot(n: Int) = robot.actualSlot(n)
|
||||||
|
|
||||||
@ -34,34 +32,9 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
|
|
||||||
override def isRobot = true
|
override def isRobot = true
|
||||||
|
|
||||||
override def getStackInSelectedSlot = stackInSlot(selectedSlot).orNull
|
def selectedSlot = robot.selectedSlot
|
||||||
|
|
||||||
override def setStackInSelectedSlot(stack: ItemStack): Boolean = {
|
def player = robot.player()
|
||||||
val existingStack = stackInSlot(selectedSlot).orNull
|
|
||||||
if (stack == existingStack) {
|
|
||||||
robot.onInventoryChanged()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (existingStack != null &&
|
|
||||||
!ItemStack.areItemStacksEqual(existingStack, stack) ||
|
|
||||||
!ItemStack.areItemStackTagsEqual(existingStack, stack) ||
|
|
||||||
existingStack.stackSize >= robot.getInventoryStackLimit) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
val maxStackSize = stack.getMaxStackSize min robot.getInventoryStackLimit
|
|
||||||
if (existingStack != null) {
|
|
||||||
val space = maxStackSize - existingStack.stackSize
|
|
||||||
val moveCount = stack.stackSize min space
|
|
||||||
existingStack.stackSize += moveCount
|
|
||||||
stack.stackSize -= moveCount
|
|
||||||
robot.onInventoryChanged()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val moveCount = stack.stackSize min maxStackSize
|
|
||||||
robot.setInventorySlotContents(selectedSlot, stack.splitStack(moveCount))
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
@ -118,19 +91,19 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
to.stackSize += amount
|
to.stackSize += amount
|
||||||
assert(from.stackSize >= 0)
|
assert(from.stackSize >= 0)
|
||||||
if (from.stackSize == 0) {
|
if (from.stackSize == 0) {
|
||||||
robot.setInventorySlotContents(actualSlot(selectedSlot), null)
|
robot.setInventorySlotContents(selectedSlot, null)
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
else false
|
else false
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
robot.setInventorySlotContents(actualSlot(slot), from)
|
robot.setInventorySlotContents(slot, from)
|
||||||
robot.setInventorySlotContents(actualSlot(selectedSlot), to)
|
robot.setInventorySlotContents(selectedSlot, to)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
case (Some(from), None) =>
|
case (Some(from), None) =>
|
||||||
robot.setInventorySlotContents(actualSlot(slot), robot.decrStackSize(actualSlot(selectedSlot), count))
|
robot.setInventorySlotContents(slot, robot.decrStackSize(selectedSlot, count))
|
||||||
true
|
true
|
||||||
case _ => false
|
case _ => false
|
||||||
})
|
})
|
||||||
@ -157,7 +130,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
def drop(context: Context, args: Arguments): Array[AnyRef] = {
|
def drop(context: Context, args: Arguments): Array[AnyRef] = {
|
||||||
val facing = checkSideForAction(args, 0)
|
val facing = checkSideForAction(args, 0)
|
||||||
val count = checkOptionalItemCount(args, 1)
|
val count = checkOptionalItemCount(args, 1)
|
||||||
val dropped = robot.decrStackSize(actualSlot(selectedSlot), count)
|
val dropped = robot.decrStackSize(selectedSlot, count)
|
||||||
if (dropped != null && dropped.stackSize > 0) {
|
if (dropped != null && dropped.stackSize > 0) {
|
||||||
def tryDropIntoInventory(inventory: IInventory, filter: (Int) => Boolean) = {
|
def tryDropIntoInventory(inventory: IInventory, filter: (Int) => Boolean) = {
|
||||||
var success = false
|
var success = false
|
||||||
@ -187,7 +160,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
if (success) {
|
if (success) {
|
||||||
inventory.onInventoryChanged()
|
inventory.onInventoryChanged()
|
||||||
}
|
}
|
||||||
robot.player().inventory.addItemStackToInventory(dropped)
|
player.inventory.addItemStackToInventory(dropped)
|
||||||
result(success)
|
result(success)
|
||||||
}
|
}
|
||||||
world.getBlockTileEntity(x + facing.offsetX, y + facing.offsetY, z + facing.offsetZ) match {
|
world.getBlockTileEntity(x + facing.offsetX, y + facing.offsetY, z + facing.offsetZ) match {
|
||||||
@ -196,7 +169,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
case inventory: IInventory =>
|
case inventory: IInventory =>
|
||||||
tryDropIntoInventory(inventory, (slot) => true)
|
tryDropIntoInventory(inventory, (slot) => true)
|
||||||
case _ =>
|
case _ =>
|
||||||
robot.player().dropPlayerItemWithRandomChoice(dropped, inPlace = false)
|
player.dropPlayerItemWithRandomChoice(dropped, inPlace = false)
|
||||||
context.pause(Settings.get.dropDelay)
|
context.pause(Settings.get.dropDelay)
|
||||||
result(true)
|
result(true)
|
||||||
}
|
}
|
||||||
@ -252,7 +225,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
val maxStackSize = robot.getInventoryStackLimit min stack.getMaxStackSize
|
val maxStackSize = robot.getInventoryStackLimit min stack.getMaxStackSize
|
||||||
val amount = maxStackSize min stack.stackSize min count
|
val amount = maxStackSize min stack.stackSize min count
|
||||||
val sucked = stack.splitStack(amount)
|
val sucked = stack.splitStack(amount)
|
||||||
success = robot.player().inventory.addItemStackToInventory(sucked)
|
success = player.inventory.addItemStackToInventory(sucked)
|
||||||
stack.stackSize += sucked.stackSize
|
stack.stackSize += sucked.stackSize
|
||||||
if (stack.stackSize == 0) {
|
if (stack.stackSize == 0) {
|
||||||
inventory.setInventorySlotContents(slot, null)
|
inventory.setInventorySlotContents(slot, null)
|
||||||
@ -270,10 +243,10 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
case inventory: IInventory =>
|
case inventory: IInventory =>
|
||||||
trySuckFromInventory(inventory, (slot) => true)
|
trySuckFromInventory(inventory, (slot) => true)
|
||||||
case _ =>
|
case _ =>
|
||||||
for (entity <- robot.player().entitiesOnSide[EntityItem](facing) if !entity.isDead && entity.delayBeforeCanPickup <= 0) {
|
for (entity <- player.entitiesOnSide[EntityItem](facing) if !entity.isDead && entity.delayBeforeCanPickup <= 0) {
|
||||||
val stack = entity.getEntityItem
|
val stack = entity.getEntityItem
|
||||||
val size = stack.stackSize
|
val size = stack.stackSize
|
||||||
entity.onCollideWithPlayer(robot.player())
|
entity.onCollideWithPlayer(player)
|
||||||
if (stack.stackSize < size || entity.isDead) {
|
if (stack.stackSize < size || entity.isDead) {
|
||||||
context.pause(Settings.get.suckDelay)
|
context.pause(Settings.get.suckDelay)
|
||||||
return result(true)
|
return result(true)
|
||||||
@ -459,7 +432,6 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def endConsumeDrops(entity: Entity) {
|
private def endConsumeDrops(entity: Entity) {
|
||||||
val player = robot.player()
|
|
||||||
entity.captureDrops = false
|
entity.captureDrops = false
|
||||||
for (drop <- entity.capturedDrops) {
|
for (drop <- entity.capturedDrops) {
|
||||||
val stack = drop.getEntityItem
|
val stack = drop.getEntityItem
|
||||||
@ -478,7 +450,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
val id = world.getBlockId(bx, by, bz)
|
val id = world.getBlockId(bx, by, bz)
|
||||||
val block = Block.blocksList(id)
|
val block = Block.blocksList(id)
|
||||||
if (id == 0 || block == null || block.isAirBlock(world, bx, by, bz)) {
|
if (id == 0 || block == null || block.isAirBlock(world, bx, by, bz)) {
|
||||||
robot.player().closestEntity[Entity]() match {
|
player.closestEntity[Entity]() match {
|
||||||
case Some(entity) => (true, "entity")
|
case Some(entity) => (true, "entity")
|
||||||
case _ => (false, "air")
|
case _ => (false, "air")
|
||||||
}
|
}
|
||||||
@ -526,7 +498,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
stackA.getItem == stackB.getItem &&
|
stackA.getItem == stackB.getItem &&
|
||||||
(!stackA.getHasSubtypes || stackA.getItemDamage == stackB.getItemDamage)
|
(!stackA.getHasSubtypes || stackA.getItemDamage == stackB.getItemDamage)
|
||||||
|
|
||||||
private def stackInSlot(slot: Int) = Option(robot.getStackInSlot(actualSlot(slot)))
|
private def stackInSlot(slot: Int) = Option(robot.getStackInSlot(slot))
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
@ -541,7 +513,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
if (slot < 0 || slot > 15) {
|
if (slot < 0 || slot > 15) {
|
||||||
throw new IllegalArgumentException("invalid slot")
|
throw new IllegalArgumentException("invalid slot")
|
||||||
}
|
}
|
||||||
slot
|
actualSlot(slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
private def checkSideForAction(args: Arguments, n: Int) = checkSide(args, n, ForgeDirection.SOUTH, ForgeDirection.UP, ForgeDirection.DOWN)
|
private def checkSideForAction(args: Arguments, n: Int) = checkSide(args, n, ForgeDirection.SOUTH, ForgeDirection.UP, ForgeDirection.DOWN)
|
||||||
|
@ -9,13 +9,13 @@ import scala.util.control.Breaks._
|
|||||||
class Inventory(player: Player) extends InventoryPlayer(player) {
|
class Inventory(player: Player) extends InventoryPlayer(player) {
|
||||||
val robot = player.robot
|
val robot = player.robot
|
||||||
|
|
||||||
def selectedSlot = robot.actualSlot(robot.selectedSlot)
|
def selectedSlot = robot.selectedSlot
|
||||||
|
|
||||||
def selectedItemStack = robot.getStackInSlot(selectedSlot)
|
def selectedItemStack = robot.getStackInSlot(selectedSlot)
|
||||||
|
|
||||||
def firstInventorySlot = robot.actualSlot(0)
|
def firstInventorySlot = robot.actualSlot(0)
|
||||||
|
|
||||||
def inventorySlots = (robot.actualSlot(robot.selectedSlot) until getSizeInventory) ++ (firstInventorySlot until robot.actualSlot(robot.selectedSlot))
|
def inventorySlots = (robot.selectedSlot until getSizeInventory) ++ (firstInventorySlot until robot.selectedSlot)
|
||||||
|
|
||||||
override def getCurrentItem = getStackInSlot(0)
|
override def getCurrentItem = getStackInSlot(0)
|
||||||
|
|
||||||
|
15
li/cil/oc/server/driver/item/Crafting.scala
Normal file
15
li/cil/oc/server/driver/item/Crafting.scala
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package li.cil.oc.server.driver.item
|
||||||
|
|
||||||
|
import li.cil.oc.Items
|
||||||
|
import li.cil.oc.api.driver.Slot
|
||||||
|
import li.cil.oc.server.component
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.tileentity.{TileEntity => MCTileEntity}
|
||||||
|
|
||||||
|
object Crafting extends Item {
|
||||||
|
override def worksWith(stack: ItemStack) = isOneOf(stack, Items.crafting)
|
||||||
|
|
||||||
|
override def createEnvironment(stack: ItemStack, container: MCTileEntity) = new component.Crafting(container)
|
||||||
|
|
||||||
|
override def slot(stack: ItemStack) = Slot.Upgrade
|
||||||
|
}
|
@ -4,7 +4,7 @@ import cpw.mods.fml.common.FMLCommonHandler
|
|||||||
import cpw.mods.fml.relauncher.Side
|
import cpw.mods.fml.relauncher.Side
|
||||||
import java.lang.reflect.{Method, InvocationTargetException}
|
import java.lang.reflect.{Method, InvocationTargetException}
|
||||||
import li.cil.oc.api
|
import li.cil.oc.api
|
||||||
import li.cil.oc.api.network.{LuaCallback, Arguments, Context, Visibility}
|
import li.cil.oc.api.network._
|
||||||
import li.cil.oc.common.tileentity
|
import li.cil.oc.common.tileentity
|
||||||
import li.cil.oc.util.Persistable
|
import li.cil.oc.util.Persistable
|
||||||
import net.minecraft.nbt.NBTTagCompound
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
@ -117,7 +117,7 @@ object Component {
|
|||||||
|
|
||||||
ms.filter(_.isAnnotationPresent(classOf[LuaCallback])).foreach(m =>
|
ms.filter(_.isAnnotationPresent(classOf[LuaCallback])).foreach(m =>
|
||||||
if (m.getParameterTypes.size != 2 ||
|
if (m.getParameterTypes.size != 2 ||
|
||||||
m.getParameterTypes()(0) != classOf[Context] ||
|
(m.getParameterTypes()(0) != classOf[Context] && m.getParameterTypes()(0) != classOf[RobotContext]) ||
|
||||||
m.getParameterTypes()(1) != classOf[Arguments]) {
|
m.getParameterTypes()(1) != classOf[Arguments]) {
|
||||||
throw new IllegalArgumentException("Invalid use of LuaCallback annotation (invalid signature).")
|
throw new IllegalArgumentException("Invalid use of LuaCallback annotation (invalid signature).")
|
||||||
}
|
}
|
||||||
@ -130,7 +130,6 @@ object Component {
|
|||||||
throw new IllegalArgumentException("Invalid use of LuaCallback annotation (name must not be null or empty).")
|
throw new IllegalArgumentException("Invalid use of LuaCallback annotation (name must not be null or empty).")
|
||||||
}
|
}
|
||||||
else if (!callbacks.contains(a.value)) {
|
else if (!callbacks.contains(a.value)) {
|
||||||
|
|
||||||
callbacks += a.value -> new Callback(m, a.direct, a.limit)
|
callbacks += a.value -> new Callback(m, a.direct, a.limit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user