diff --git a/assets/opencomputers/textures/items/crafting.png b/assets/opencomputers/textures/items/crafting.png new file mode 100644 index 000000000..a1147a490 Binary files /dev/null and b/assets/opencomputers/textures/items/crafting.png differ diff --git a/assets/opencomputers/textures/items/generator.png b/assets/opencomputers/textures/items/generator.png index c8fc8a9d5..2113f35e3 100644 Binary files a/assets/opencomputers/textures/items/generator.png and b/assets/opencomputers/textures/items/generator.png differ diff --git a/li/cil/oc/Items.scala b/li/cil/oc/Items.scala index e7bc212b6..a43ad2677 100644 --- a/li/cil/oc/Items.scala +++ b/li/cil/oc/Items.scala @@ -6,16 +6,33 @@ import li.cil.oc.common.item object Items { var multi: item.Delegator = null + // ----------------------------------------------------------------------- // + // Tools var analyzer: item.Analyzer = null - var disk: item.Disk = null - var generator: item.Generator = null - var gpu1, gpu2, gpu3: item.GraphicsCard = null - var hdd1, hdd2, hdd3: item.HardDiskDrive = null - var lan: item.NetworkCard = null + + // ----------------------------------------------------------------------- // + // Memory 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 wlan: item.WirelessNetworkCard = null + // ----------------------------------------------------------------------- // + // Upgrades + var crafting: item.Crafting = null + var generator: item.Generator = null + + // ----------------------------------------------------------------------- // + // Crafting var card: item.Card = null var circuitBoardBody: item.PlatineBody = null var circuitBoard: item.Platine = null @@ -41,6 +58,7 @@ object Items { ram3 = new item.Memory(multi, 2) rs = new item.RedstoneCard(multi) wlan = new item.WirelessNetworkCard(multi) + crafting = new item.Crafting(multi) card = new item.Card(multi) circuitBoardBody = new item.PlatineBody(multi) diff --git a/li/cil/oc/api/network/Context.java b/li/cil/oc/api/network/Context.java index d19653659..dc9b9d2a0 100644 --- a/li/cil/oc/api/network/Context.java +++ b/li/cil/oc/api/network/Context.java @@ -1,7 +1,5 @@ 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 * computer from which the callback was called. @@ -161,37 +159,4 @@ public interface Context { * @return true if the signal was queued; false otherwise. */ boolean signal(String name, Object... args); - - /** - * Get the item stack that is currently in the robot's selected slot. - *

- * For normal computers this will always return null. - *

- * Note that this returns the actual ItemStack 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. - *

- * For computers this will always do nothing and return false. - *

- * 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). - *

- * If the slot is not empty, and the stack cannot be - at least partially - - * merged into the existing item stack this will return false. - * - * @param stack the stack to store in the currently selected slot. - * @return true if the stack was completely or partially stored. - */ - boolean setStackInSelectedSlot(ItemStack stack); } diff --git a/li/cil/oc/api/network/RobotContext.java b/li/cil/oc/api/network/RobotContext.java new file mode 100644 index 000000000..3d46f1a31 --- /dev/null +++ b/li/cil/oc/api/network/RobotContext.java @@ -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. + *

+ * 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(); +} diff --git a/li/cil/oc/client/gui/Robot.scala b/li/cil/oc/client/gui/Robot.scala index 60c513638..66fbf8699 100644 --- a/li/cil/oc/client/gui/Robot.scala +++ b/li/cil/oc/client/gui/Robot.scala @@ -119,8 +119,9 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten Minecraft.getMinecraft.renderEngine.bindTexture(selection) val now = System.currentTimeMillis() / 1000.0 val offsetV = ((now - now.toInt) * selectionsStates).toInt * selectionStepV - val x = guiLeft + inventoryX + (robot.selectedSlot % 4) * (selectionSize - 2) - val y = guiTop + inventoryY + (robot.selectedSlot / 4) * (selectionSize - 2) + val slot = robot.selectedSlot - robot.actualSlot(0) + val x = guiLeft + inventoryX + (slot % 4) * (selectionSize - 2) + val y = guiTop + inventoryY + (slot / 4) * (selectionSize - 2) val t = Tessellator.instance t.startDrawingQuads() diff --git a/li/cil/oc/common/Proxy.scala b/li/cil/oc/common/Proxy.scala index 0c6168db2..1365f8dbe 100644 --- a/li/cil/oc/common/Proxy.scala +++ b/li/cil/oc/common/Proxy.scala @@ -26,11 +26,12 @@ class Proxy { api.Driver.add(driver.block.Carriage) api.Driver.add(driver.block.CommandBlock) + api.Driver.add(driver.item.Crafting) api.Driver.add(driver.item.FileSystem) + api.Driver.add(driver.item.Generator) api.Driver.add(driver.item.GraphicsCard) api.Driver.add(driver.item.Memory) api.Driver.add(driver.item.NetworkCard) - api.Driver.add(driver.item.Generator) api.Driver.add(driver.item.RedstoneCard) api.Driver.add(driver.item.WirelessNetworkCard) diff --git a/li/cil/oc/common/item/Crafting.scala b/li/cil/oc/common/item/Crafting.scala new file mode 100644 index 000000000..4439cd4cb --- /dev/null +++ b/li/cil/oc/common/item/Crafting.scala @@ -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") + } +} diff --git a/li/cil/oc/common/tileentity/Inventory.scala b/li/cil/oc/common/tileentity/Inventory.scala index b54d063d0..f261563db 100644 --- a/li/cil/oc/common/tileentity/Inventory.scala +++ b/li/cil/oc/common/tileentity/Inventory.scala @@ -33,7 +33,12 @@ trait Inventory extends TileEntity with IInventory with Persistable { 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) { stack.stackSize = getInventoryStackLimit } diff --git a/li/cil/oc/server/component/Computer.scala b/li/cil/oc/server/component/Computer.scala index f63299496..fb977fdac 100644 --- a/li/cil/oc/server/component/Computer.scala +++ b/li/cil/oc/server/component/Computer.scala @@ -12,7 +12,6 @@ import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.{ThreadPoolFactory, GameTimeFormatter, LuaStateFactory} import li.cil.oc.{OpenComputers, Settings} import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.ItemStack import net.minecraft.nbt._ import net.minecraft.server.MinecraftServer 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") diff --git a/li/cil/oc/server/component/Crafting.scala b/li/cil/oc/server/component/Crafting.scala new file mode 100644 index 000000000..addc9738d --- /dev/null +++ b/li/cil/oc/server/component/Crafting.scala @@ -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)) + } + } + } + +} diff --git a/li/cil/oc/server/component/Generator.scala b/li/cil/oc/server/component/Generator.scala index 6b14c4f20..00fe82aa2 100644 --- a/li/cil/oc/server/component/Generator.scala +++ b/li/cil/oc/server/component/Generator.scala @@ -1,11 +1,12 @@ 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.{Settings, api} import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound import net.minecraft.tileentity.TileEntityFurnace +import scala.Some class Generator extends ManagedComponent { val node = api.Network.newNode(this, Visibility.Network). @@ -20,14 +21,15 @@ class Generator extends ManagedComponent { // ----------------------------------------------------------------------- // @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 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 (!TileEntityFurnace.isItemFuel(stack)) return result(false, "selected slot does not contain fuel") inventory match { case Some(existingStack) => - if (!ItemStack.areItemStacksEqual(existingStack, stack) || + if (!existingStack.isItemEqual(stack) || !ItemStack.areItemStackTagsEqual(existingStack, stack)) { return result(false, "different fuel type already queued") } @@ -41,7 +43,7 @@ class Generator extends ManagedComponent { case _ => inventory = Some(stack.splitStack(stack.getMaxStackSize min count)) } - context.setStackInSelectedSlot(stack) + player.inventory.setInventorySlotContents(context.selectedSlot, stack) result(true) } @@ -54,8 +56,19 @@ class Generator extends ManagedComponent { } @LuaCallback("remove") - def remove(context: Context, args: Arguments): Array[AnyRef] = { - null + def remove(context: RobotContext, args: Arguments): Array[AnyRef] = { + 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) + } } // ----------------------------------------------------------------------- // diff --git a/li/cil/oc/server/component/Robot.scala b/li/cil/oc/server/component/Robot.scala index 4cd9f294f..1206f152e 100644 --- a/li/cil/oc/server/component/Robot.scala +++ b/li/cil/oc/server/component/Robot.scala @@ -1,13 +1,13 @@ package li.cil.oc.server.component 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.server.component.robot.{Player, ActivationType} import li.cil.oc.server.{PacketSender => ServerPacketSender} import net.minecraft.block.{BlockFluid, Block} -import net.minecraft.entity.{EntityLivingBase, Entity} import net.minecraft.entity.item.EntityItem +import net.minecraft.entity.{EntityLivingBase, Entity} import net.minecraft.inventory.{IInventory, ISidedInventory} import net.minecraft.item.{ItemStack, ItemBlock} import net.minecraft.util.{Vec3, MovingObjectPosition, EnumMovingObjectType} @@ -16,9 +16,7 @@ import net.minecraftforge.fluids.FluidRegistry import scala.Some import scala.collection.convert.WrapAsScala._ -class Robot(val robot: tileentity.Robot) extends Computer(robot) { - - def selectedSlot = robot.selectedSlot +class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotContext { 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 getStackInSelectedSlot = stackInSlot(selectedSlot).orNull + def selectedSlot = robot.selectedSlot - override def setStackInSelectedSlot(stack: ItemStack): Boolean = { - 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 - } + def player = robot.player() // ----------------------------------------------------------------------- // @@ -118,19 +91,19 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) { to.stackSize += amount assert(from.stackSize >= 0) if (from.stackSize == 0) { - robot.setInventorySlotContents(actualSlot(selectedSlot), null) + robot.setInventorySlotContents(selectedSlot, null) } true } else false } else { - robot.setInventorySlotContents(actualSlot(slot), from) - robot.setInventorySlotContents(actualSlot(selectedSlot), to) + robot.setInventorySlotContents(slot, from) + robot.setInventorySlotContents(selectedSlot, to) true } case (Some(from), None) => - robot.setInventorySlotContents(actualSlot(slot), robot.decrStackSize(actualSlot(selectedSlot), count)) + robot.setInventorySlotContents(slot, robot.decrStackSize(selectedSlot, count)) true case _ => false }) @@ -157,7 +130,7 @@ 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) - val dropped = robot.decrStackSize(actualSlot(selectedSlot), count) + val dropped = robot.decrStackSize(selectedSlot, count) if (dropped != null && dropped.stackSize > 0) { def tryDropIntoInventory(inventory: IInventory, filter: (Int) => Boolean) = { var success = false @@ -187,7 +160,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) { if (success) { inventory.onInventoryChanged() } - robot.player().inventory.addItemStackToInventory(dropped) + player.inventory.addItemStackToInventory(dropped) result(success) } 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 => tryDropIntoInventory(inventory, (slot) => true) case _ => - robot.player().dropPlayerItemWithRandomChoice(dropped, inPlace = false) + player.dropPlayerItemWithRandomChoice(dropped, inPlace = false) context.pause(Settings.get.dropDelay) result(true) } @@ -252,7 +225,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) { val maxStackSize = robot.getInventoryStackLimit min stack.getMaxStackSize val amount = maxStackSize min stack.stackSize min count val sucked = stack.splitStack(amount) - success = robot.player().inventory.addItemStackToInventory(sucked) + success = player.inventory.addItemStackToInventory(sucked) stack.stackSize += sucked.stackSize if (stack.stackSize == 0) { inventory.setInventorySlotContents(slot, null) @@ -270,10 +243,10 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) { case inventory: IInventory => trySuckFromInventory(inventory, (slot) => true) 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 size = stack.stackSize - entity.onCollideWithPlayer(robot.player()) + entity.onCollideWithPlayer(player) if (stack.stackSize < size || entity.isDead) { context.pause(Settings.get.suckDelay) return result(true) @@ -459,7 +432,6 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) { } private def endConsumeDrops(entity: Entity) { - val player = robot.player() entity.captureDrops = false for (drop <- entity.capturedDrops) { 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 block = Block.blocksList(id) 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 _ => (false, "air") } @@ -526,7 +498,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) { stackA.getItem == stackB.getItem && (!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) { throw new IllegalArgumentException("invalid slot") } - slot + actualSlot(slot) } private def checkSideForAction(args: Arguments, n: Int) = checkSide(args, n, ForgeDirection.SOUTH, ForgeDirection.UP, ForgeDirection.DOWN) diff --git a/li/cil/oc/server/component/robot/Inventory.scala b/li/cil/oc/server/component/robot/Inventory.scala index 5777f8111..e5ced6ef7 100644 --- a/li/cil/oc/server/component/robot/Inventory.scala +++ b/li/cil/oc/server/component/robot/Inventory.scala @@ -9,13 +9,13 @@ import scala.util.control.Breaks._ class Inventory(player: Player) extends InventoryPlayer(player) { val robot = player.robot - def selectedSlot = robot.actualSlot(robot.selectedSlot) + def selectedSlot = robot.selectedSlot def selectedItemStack = robot.getStackInSlot(selectedSlot) 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) diff --git a/li/cil/oc/server/driver/item/Crafting.scala b/li/cil/oc/server/driver/item/Crafting.scala new file mode 100644 index 000000000..6ffc40ded --- /dev/null +++ b/li/cil/oc/server/driver/item/Crafting.scala @@ -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 +} diff --git a/li/cil/oc/server/network/Component.scala b/li/cil/oc/server/network/Component.scala index d34937454..726c541ae 100644 --- a/li/cil/oc/server/network/Component.scala +++ b/li/cil/oc/server/network/Component.scala @@ -4,7 +4,7 @@ import cpw.mods.fml.common.FMLCommonHandler import cpw.mods.fml.relauncher.Side import java.lang.reflect.{Method, InvocationTargetException} 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.util.Persistable import net.minecraft.nbt.NBTTagCompound @@ -117,7 +117,7 @@ object Component { ms.filter(_.isAnnotationPresent(classOf[LuaCallback])).foreach(m => 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]) { 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).") } else if (!callbacks.contains(a.value)) { - callbacks += a.value -> new Callback(m, a.direct, a.limit) } }