From 9245aa45d69c2694415cc094be7fbbae1650bba1 Mon Sep 17 00:00:00 2001 From: repo_alt Date: Tue, 1 Feb 2022 11:56:10 +0300 Subject: [PATCH] Configurator upgrade, currently supports EIO conduits Fixed forestry item converter, adding empty circuit list to all items Added inventory_controller.installUpgrade function for robots, to use upgrade containers at runtime --- dependencies.gradle | 13 +- .../assets/opencomputers/lang/en_US.lang | 1 + .../opencomputers/recipes/default.recipes | 8 + .../textures/items/UpgradeConfigurator.png | Bin 0 -> 585 bytes src/main/scala/li/cil/oc/Constants.scala | 1 + .../scala/li/cil/oc/common/init/Items.scala | 7 +- .../oc/common/item/UpgradeConfigurator.scala | 3 + .../scala/li/cil/oc/integration/Mods.scala | 2 +- .../forestry/ConverterItemStack.scala | 3 +- .../DriverUpgradeConfigurator.scala | 39 +++ .../opencomputers/ModOpenComputers.scala | 6 +- .../component/UpgradeConfigurator.scala | 297 ++++++++++++++++++ .../UpgradeInventoryController.scala | 16 + 13 files changed, 386 insertions(+), 10 deletions(-) create mode 100644 src/main/resources/assets/opencomputers/textures/items/UpgradeConfigurator.png create mode 100644 src/main/scala/li/cil/oc/common/item/UpgradeConfigurator.scala create mode 100644 src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeConfigurator.scala create mode 100644 src/main/scala/li/cil/oc/server/component/UpgradeConfigurator.scala diff --git a/dependencies.gradle b/dependencies.gradle index e1a4d941e..346fc9e9b 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -21,16 +21,16 @@ dependencies { compileOnly("com.github.GTNewHorizons:Railcraft:9.13.5:dev") { transitive = false } - compileOnly("com.github.GTNewHorizons:NotEnoughItems:2.2.3-GTNH:dev") { + compile("com.github.GTNewHorizons:NotEnoughItems:2.2.3-GTNH:dev") { transitive = false } compileOnly("com.github.GTNewHorizons:ForgeMultipart:1.2.7:dev") { transitive = false } - compileOnly("com.github.GTNewHorizons:CodeChickenLib:1.1.5.1:dev") { + compile("com.github.GTNewHorizons:CodeChickenLib:1.1.5.1:dev") { transitive = false } - compileOnly("com.github.GTNewHorizons:CodeChickenCore:1.1.3:dev") { + compile("com.github.GTNewHorizons:CodeChickenCore:1.1.3:dev") { transitive = false } compileOnly("com.github.GTNewHorizons:waila:1.5.18:dev") { @@ -54,7 +54,10 @@ dependencies { compileOnly("com.github.GTNewHorizons:ExtraCells2:2.5.4:dev") { transitive = false } - compileOnly("com.github.GTNewHorizons:EnderIO:2.3.1.27:dev") { + compile("com.github.GTNewHorizons:EnderCore:0.2.6:dev") { + transitive = false + } + compile("com.github.GTNewHorizons:EnderIO:2.3.1.27:dev") { transitive = false } compileOnly("com.github.GTNewHorizons:Avaritiaddons:1.5.2-GTNH:dev") { @@ -66,7 +69,6 @@ dependencies { compileOnly("com.github.GTNewHorizons:WirelessRedstone-CBE:1.4.4:dev") { transitive = false } - compileOnly("appeng:RotaryCraft:V5c:api") { transitive = false } @@ -116,6 +118,7 @@ dependencies { compileOnly files("dependencies/ic2classic-api.zip") //curseforge one does NOT work ... compileOnly(deobf("https://github.com/purpleposeidon/fz_archive/raw/master/old/Factorization-1.7.10-0.8.108.jar")) compileOnly("api:coloredlightscore:1") + compileOnly(deobf("http://immibis.com/mcmoddl/files/immibis-microblocks-59.1.2.jar")) testCompile("org.mockito:mockito-all:1.10.19") testCompile("org.scalactic:scalactic_2.11:2.2.6") diff --git a/src/main/resources/assets/opencomputers/lang/en_US.lang b/src/main/resources/assets/opencomputers/lang/en_US.lang index a9ece72ed..359c68912 100644 --- a/src/main/resources/assets/opencomputers/lang/en_US.lang +++ b/src/main/resources/assets/opencomputers/lang/en_US.lang @@ -166,6 +166,7 @@ item.oc.Server3.name=Server (Tier 4) item.oc.TabletCase3.name=Tablet Case (Tier 3) item.oc.UpgradeBeekeeper.name=Beekeeper Upgrade item.oc.UpgradeRITEG.name=RITEG Upgrade +item.oc.UpgradeConfigurator.name=Configurator Upgrade # Entities entity.oc.Drone.name=Drone diff --git a/src/main/resources/assets/opencomputers/recipes/default.recipes b/src/main/resources/assets/opencomputers/recipes/default.recipes index 2280f7fed..81fe46564 100644 --- a/src/main/resources/assets/opencomputers/recipes/default.recipes +++ b/src/main/resources/assets/opencomputers/recipes/default.recipes @@ -249,6 +249,13 @@ beekeeperUpgrade { ["oc:circuitChip3", {item="Forestry:beealyzer"}, "oc:circuitChip3"] [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] } + +configuratorUpgrade { + input: [[ingotIron, "", ingotIron] + ["oc:circuitChip1", "oc:wrench", "oc:circuitChip1"] + [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] +} + chunkloaderUpgrade { input: [[ingotGold, blockGlass, ingotGold] ["oc:circuitChip3", eyeOfEnder, "oc:circuitChip3"] @@ -710,3 +717,4 @@ appengTunnel { type: shapeless input: [{item="appliedenergistics2:item.ItemMultiPart", subID=460}, "oc:adapter"] } +ritegUpgrade = false diff --git a/src/main/resources/assets/opencomputers/textures/items/UpgradeConfigurator.png b/src/main/resources/assets/opencomputers/textures/items/UpgradeConfigurator.png new file mode 100644 index 0000000000000000000000000000000000000000..931db9e5031938bd107f05b8d971dbad653f7f17 GIT binary patch literal 585 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%Li90X`wFX=lrYxW-LS+cICr|-=FGt0LeoVaX# z>#QY?9&wWwub#7ZtF3e7k#kqqZ#yyb%*?JiOX?=gP0p^}vj24F^qKK#mF+VY&04!{ z-R=|3GZs1fCf|AVU`J)S4IiJQXF}Wb1x?cz*7Qv`F!cx#5y`Q$Hsj^BbPQ0}HrLRx z+F4UM#n(fZo7+QCZf>xzkC0HCt%WHsZ-l0bo1kEWwW%QwPl%f0f?W&sxVin56*eB; zoKu$L;N>)T*MgRbEw=9VlebLHugmui_IB`aa`*QH`p@5F!#g15SrX(I{GUpIfrn#$ zD9}*O0*}aI1_r*vAk26?e?aJDgL5moaJ}LG%1aQvS)N*Lz3Z8_hn4~hBgR&=d^-hM&GMUWEDB_Ty7w@2R zOLf;F#*Hy6ukq}@cVXenEw^N^zy0zopr06T&f)&Kwi literal 0 HcmV?d00001 diff --git a/src/main/scala/li/cil/oc/Constants.scala b/src/main/scala/li/cil/oc/Constants.scala index 226ee5c3e..027814685 100644 --- a/src/main/scala/li/cil/oc/Constants.scala +++ b/src/main/scala/li/cil/oc/Constants.scala @@ -76,6 +76,7 @@ object Constants { final val ComponentBusTier2 = "componentBus2" final val ComponentBusTier3 = "componentBus3" final val ComponentBusCreative = "componentBusCreative" + final val ConfiguratorUpgrade = "configuratorUpgrade" final val CPUTier1 = "cpu1" final val CPUTier2 = "cpu2" final val CPUTier3 = "cpu3" diff --git a/src/main/scala/li/cil/oc/common/init/Items.scala b/src/main/scala/li/cil/oc/common/init/Items.scala index 733e07ee9..5209387d2 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -14,8 +14,7 @@ import li.cil.oc.common.Loot import li.cil.oc.common.Tier import li.cil.oc.common.block.SimpleBlock import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator -import li.cil.oc.common.item.UpgradeLeash +import li.cil.oc.common.item.{Delegator, UpgradeConfigurator, UpgradeLeash} import li.cil.oc.common.item.data.DroneData import li.cil.oc.common.item.data.HoverBootsData import li.cil.oc.common.item.data.MicrocontrollerData @@ -551,6 +550,10 @@ object Items extends ItemAPI { Recipes.addSubItem(new item.WirelessNetworkCard(multi, Tier.One), Constants.ItemName.WirelessNetworkCardTier1, "oc:wlanCard1") registerItem(new item.ComponentBus(multi, Tier.Four), Constants.ItemName.ComponentBusCreative) + + // GTNH + Recipes.addSubItem(new UpgradeConfigurator(multi), Constants.ItemName.ConfiguratorUpgrade, "oc:configuratorUpgrade") + Recipes.addSubItem(new item.UpgradeRITEG(multi), Constants.ItemName.RITEGUpgrade) // Register aliases. diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeConfigurator.scala b/src/main/scala/li/cil/oc/common/item/UpgradeConfigurator.scala new file mode 100644 index 000000000..62990ef02 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/item/UpgradeConfigurator.scala @@ -0,0 +1,3 @@ +package li.cil.oc.common.item + +class UpgradeConfigurator(val parent: Delegator) extends traits.Delegate with traits.ItemTier diff --git a/src/main/scala/li/cil/oc/integration/Mods.scala b/src/main/scala/li/cil/oc/integration/Mods.scala index 3a5c81a04..82e8cf494 100644 --- a/src/main/scala/li/cil/oc/integration/Mods.scala +++ b/src/main/scala/li/cil/oc/integration/Mods.scala @@ -39,7 +39,7 @@ object Mods { val CraftingCosts = new SimpleMod(IDs.CraftingCosts) val DeepStorageUnit = new ClassBasedMod(IDs.DeepStorageUnit, "powercrystals.minefactoryreloaded.api.IDeepStorageUnit") val ElectricalAge = new SimpleMod(IDs.ElectricalAge) - val EnderIO = new SimpleMod(IDs.EnderIO, version = "@[2.2,2.3)") + val EnderIO = new SimpleMod(IDs.EnderIO, version = "@[2.2,)") val EnderStorage = new SimpleMod(IDs.EnderStorage) val ExtraCells = new SimpleMod(IDs.ExtraCells, version = "@[2.2.73,)") val Factorization = new SimpleMod(IDs.Factorization) diff --git a/src/main/scala/li/cil/oc/integration/forestry/ConverterItemStack.scala b/src/main/scala/li/cil/oc/integration/forestry/ConverterItemStack.scala index 14f6f8cce..fa4ca04e3 100644 --- a/src/main/scala/li/cil/oc/integration/forestry/ConverterItemStack.scala +++ b/src/main/scala/li/cil/oc/integration/forestry/ConverterItemStack.scala @@ -16,7 +16,8 @@ object ConverterItemStack extends Converter { case stack: ItemStack if ChipsetManager.circuitRegistry.getCircuitboard(stack) != null => { val cc = ChipsetManager.circuitRegistry.getCircuitboard(stack).getCircuits val names = cc.collect{case c: ICircuit => c.getName} - output += "circuits" -> names + if (names.length > 0) + output += "circuits" -> names } case _ => } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeConfigurator.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeConfigurator.scala new file mode 100644 index 000000000..faa05fcc2 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeConfigurator.scala @@ -0,0 +1,39 @@ +package li.cil.oc.integration.opencomputers + +import li.cil.oc.api.driver.EnvironmentProvider +import li.cil.oc.{Constants, api} +import li.cil.oc.api.driver.item.HostAware +import li.cil.oc.api.internal.Adapter +import li.cil.oc.api.network.{EnvironmentHost, ManagedEnvironment} +import li.cil.oc.common.entity.Drone +import li.cil.oc.common.tileentity.Robot +import li.cil.oc.common.tileentity.Microcontroller +import li.cil.oc.common.{Slot, Tier} +import li.cil.oc.server.component +import net.minecraft.item.ItemStack + +object DriverUpgradeConfigurator extends Item with HostAware { + override def worksWith(stack: ItemStack): Boolean = isOneOf(stack, + api.Items.get(Constants.ItemName.ConfiguratorUpgrade)) + + override def createEnvironment(stack: ItemStack, host: EnvironmentHost) : ManagedEnvironment = + if (host.world != null && host.world.isRemote) null + else host match { + case host: EnvironmentHost with Adapter => new component.UpgradeConfigurator.Adapter(host) + case host: EnvironmentHost with Drone => new component.UpgradeConfigurator.Drone(host) + case host: EnvironmentHost with Robot => new component.UpgradeConfigurator.Robot(host) + case host: EnvironmentHost with Microcontroller => new component.UpgradeConfigurator.Microcontroller(host) + case _ => null + } + + override def slot(stack: ItemStack): String = Slot.Upgrade + + override def tier(stack: ItemStack): Int = Tier.Two + + object Provider extends EnvironmentProvider { + override def getEnvironment(stack: ItemStack): Class[_] = + if (worksWith(stack)) + classOf[component.UpgradeConfigurator.Robot] + else null + } +} diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala index 17e6bb226..f1af772a9 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala @@ -172,6 +172,7 @@ object ModOpenComputers extends ModProxy { api.Driver.add(DriverUpgradeTractorBeam) api.Driver.add(DriverUpgradeTrading) api.Driver.add(DriverUpgradeMF) + api.Driver.add(DriverUpgradeConfigurator) api.Driver.add(DriverAPU.Provider) api.Driver.add(DriverDataCard.Provider) @@ -206,6 +207,7 @@ object ModOpenComputers extends ModProxy { api.Driver.add(InventoryProviderDatabase) api.Driver.add(InventoryProviderServer) + api.Driver.add(DriverUpgradeConfigurator.Provider) blacklistHost(classOf[internal.Adapter], Constants.BlockName.Geolyzer, @@ -313,7 +315,9 @@ object ModOpenComputers extends ModProxy { Constants.ItemName.TankControllerUpgrade, Constants.ItemName.LeashUpgrade, Constants.ItemName.TradingUpgrade, - Constants.ItemName.BeekeeperUpgrade) + Constants.ItemName.BeekeeperUpgrade, + Constants.ItemName.ConfiguratorUpgrade + ) if (!WirelessRedstone.isAvailable) { blacklistHost(classOf[internal.Drone], Constants.ItemName.RedstoneCardTier2) diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeConfigurator.scala b/src/main/scala/li/cil/oc/server/component/UpgradeConfigurator.scala new file mode 100644 index 000000000..cf553ac88 --- /dev/null +++ b/src/main/scala/li/cil/oc/server/component/UpgradeConfigurator.scala @@ -0,0 +1,297 @@ +package li.cil.oc.server.component + +import java.util + +import com.enderio.core.common.util.DyeColor +import crazypants.enderio.conduit.IConduitBundle +import crazypants.enderio.conduit.item.IItemConduit +import crazypants.enderio.conduit.item.filter.{IItemFilter, ItemFilter} +import crazypants.enderio.conduit.liquid.{AbstractEnderLiquidConduit, AbstractTankConduit, FluidFilter, ILiquidConduit} +import li.cil.oc.Constants +import li.cil.oc.api.driver.DeviceInfo +import li.cil.oc.api.driver.DeviceInfo.{DeviceAttribute, DeviceClass} +import li.cil.oc.api.machine.{Arguments, Callback, Context} +import li.cil.oc.api.network.{EnvironmentHost, Node, Visibility} +import li.cil.oc.api.{Network, internal, prefab} +import li.cil.oc.common.tileentity +import li.cil.oc.integration.Mods +import li.cil.oc.server.component.traits.{NetworkAware, SideRestricted, WorldAware} +import li.cil.oc.util.{BlockPosition, DatabaseAccess} +import li.cil.oc.util.ExtendedArguments.extendedArguments +import net.minecraft.inventory.IInventory +import net.minecraft.item.ItemStack +import net.minecraftforge.common.util.ForgeDirection +import net.minecraftforge.fluids.{FluidRegistry, FluidStack} + +import scala.collection.convert.WrapAsJava._ + +object UpgradeConfigurator { + + trait Common extends DeviceInfo { + private final lazy val deviceInfo = Map( + DeviceAttribute.Class -> DeviceClass.Generic, + DeviceAttribute.Description -> "External device configurator", + DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor, + DeviceAttribute.Product -> "Sonic Screwdriver" + ) + + override def getDeviceInfo: util.Map[String, String] = deviceInfo + } + + class Adapter(val host: EnvironmentHost) extends prefab.ManagedEnvironment with Configurator with Common { + override val node: Node = Network.newNode(this, Visibility.Network). + withComponent("configurator", Visibility.Network). + create() + + override def position: BlockPosition = BlockPosition(host) + override protected def checkSideForAction(args: Arguments, n: Int): ForgeDirection = args.checkSideAny(n) + } + + class Drone(val host: EnvironmentHost with internal.Agent) extends prefab.ManagedEnvironment with Configurator with Common { + override val node: Node = Network.newNode(this, Visibility.Network). + withComponent("configurator", Visibility.Neighbors). + create() + + override def position: BlockPosition = BlockPosition(host) + override protected def checkSideForAction(args: Arguments, n: Int): ForgeDirection = args.checkSideAny(n) + } + + class Robot(val host: EnvironmentHost with tileentity.Robot) extends prefab.ManagedEnvironment with Configurator with RobotConfigurator with Common { + override val node: Node = Network.newNode(this, Visibility.Network). + withComponent("configurator", Visibility.Neighbors). + create() + + override def position: BlockPosition = BlockPosition(host) + override def inventory: IInventory = host.mainInventory + override def selectedSlot: Int = host.selectedSlot + override def selectedSlot_=(value: Int): Unit = host.setSelectedSlot(value) + override protected def checkSideForAction(args: Arguments, n: Int): ForgeDirection = host.toGlobal(args.checkSideForAction(n)) + } + + class Microcontroller(val host: EnvironmentHost with tileentity.Microcontroller) extends prefab.ManagedEnvironment with Configurator with Common { + override val node: Node = Network.newNode(this, Visibility.Network). + withComponent("configurator", Visibility.Neighbors). + create() + + override def position: BlockPosition = BlockPosition(host) + override protected def checkSideForAction(args: Arguments, n: Int): ForgeDirection = host.toLocal(args.checkSideForAction(n)) + } + + trait ConfiguratorBase extends WorldAware + { + def conduitAt(position: BlockPosition): Option[IConduitBundle] = + position.world match { + case Some(world) => world.getTileEntity(position.x, position.y, position.z) match { + case conduit: IConduitBundle => Some(conduit) + } + case _ => None + } + def withItemConduit(side: ForgeDirection, f: IItemConduit => Array[AnyRef]): Array[AnyRef] = + conduitAt(position.offset(side)) match { + case Some(conduit) if conduit.hasType(classOf[IItemConduit]) + => f(conduit.getConduit(classOf[IItemConduit])) + case _ => result(Unit, "no item conduit here") + } + + def withEnderFluidConduit(side: ForgeDirection, f: AbstractEnderLiquidConduit => Array[AnyRef]): Array[AnyRef] = + conduitAt(position.offset(side)) match { + case Some(conduit) if conduit.hasType(classOf[AbstractEnderLiquidConduit]) + => f(conduit.getConduit(classOf[AbstractEnderLiquidConduit])) + case _ => result(Unit, "no item conduit here") + } + } + + trait Configurator extends ConfiguratorBase with SideRestricted with NetworkAware { + + //noinspection ScalaUnusedSymbol + @Callback(doc = """function(side:number, direction: number):table -- Get conduit configuration at side facing direction""") + def getConduitConfiguration(context: Context, args: Arguments): Array[AnyRef] = if (Mods.EnderIO.isModAvailable) { + val facing = checkSideForAction(args, 0) + val dir = args.checkSideAny(1) + conduitAt(position.offset(facing)) match { + case Some(conduit) => + var info = Map[AnyRef,AnyRef]("HasFacade" -> conduit.hasFacade.asInstanceOf[AnyRef]) + if (conduit.hasType(classOf[IItemConduit])) + info += "ItemConduit" -> convert(dir, conduit.getConduit(classOf[IItemConduit])) + if (conduit.hasType(classOf[ILiquidConduit])) + info += "LiquidConduit" -> convert(dir, conduit.getConduit(classOf[ILiquidConduit])) + result(info) + + case _ => result(null, "No conduit here") + } + } + else + result(null, "EnderIO not loaded") + + //noinspection ScalaUnusedSymbol + @Callback(doc = """function(side:number, direction: number, color: string):boolean -- Set conduit input color at side facing direction""") + def setItemConduitInputColor(context: Context, args: Arguments): Array[AnyRef] = if (Mods.EnderIO.isModAvailable) { + val facing = checkSideForAction(args, 0) + val dir = args.checkSideAny(1) + withItemConduit(facing, c =>{ + c.setInputColor(dir, DyeColor.valueOf(args.checkString(2))) + result(true) + }) + } + else + result(false, "EnderIO not loaded") + + //noinspection ScalaUnusedSymbol + @Callback(doc = """function(side:number, direction: number, color: string):boolean -- Set conduit output color at side facing direction""") + def setItemConduitOutputColor(context: Context, args: Arguments): Array[AnyRef] = if (Mods.EnderIO.isModAvailable) { + val facing = checkSideForAction(args, 0) + val dir = args.checkSideAny(1) + withItemConduit(facing, c => { + c.setOutputColor(dir, DyeColor.valueOf(args.checkString(2))) + result(true) + }) + } + else + result(false, "EnderIO not loaded") + + //noinspection ScalaUnusedSymbol + @Callback(doc = """function(side:number, direction: number, priority: number):boolean -- Set conduit output priority at side facing direction""") + def setItemConduitOutputPriority(context: Context, args: Arguments): Array[AnyRef] = if (Mods.EnderIO.isModAvailable) { + val facing = checkSideForAction(args, 0) + val dir = args.checkSideAny(1) + withItemConduit(facing, c => { + c.setOutputPriority(dir, args.checkInteger(2)) + result(true) + }) + } + else + result(false, "EnderIO not loaded") + + //noinspection ScalaUnusedSymbol + @Callback(doc = """function(side:number, direction: number, database: string, dbSlot:number, filterIndex:number, isInput:boolean):boolean -- Set conduit input or output filter at side facing direction""") + def setItemConduitFilter(context: Context, args: Arguments): Array[AnyRef] = if (Mods.EnderIO.isModAvailable) { + val facing = checkSideForAction(args, 0) + val dir = args.checkSideAny(1) + val dbAddress = args.checkString(2) + withItemConduit(facing, c => + DatabaseAccess.withDatabase(node, dbAddress, database => { + val dbSlot = args.checkSlot(database.data, 3) + val dbStack = database.getStackInSlot(dbSlot) + val filterSlot = args.checkInteger(4) + val isInput = args.checkBoolean(5) + val f = if (isInput) c.getInputFilter(dir) else c.getOutputFilter(dir) + if (f != null && f.getSlotCount > filterSlot && f.isInstanceOf[ItemFilter]) { + f.asInstanceOf[ItemFilter].setInventorySlotContents(filterSlot, dbStack) + result(true) + } + else result(false, "Wrong or no item filter") + }) + ) + } + else + result(false, "EnderIO not loaded") + + //noinspection ScalaUnusedSymbol + @Callback(doc = """function(side:number, direction:number, fluid:string, blacklist:boolean, isInput:boolean[, filterIndex:number]):boolean -- Set ender liquid conduit filter at side facing direction""") + def setEnderLiquidConduitFilter(context: Context, args: Arguments): Array[AnyRef] = if (Mods.EnderIO.isModAvailable) { + val facing = checkSideForAction(args, 0) + val dir = args.checkSideAny(1) + val fluidName = args.checkString(2) + val filterIndex = args.optInteger(5, 0) + val ff = new FluidFilter + ff.setBlacklist(args.checkBoolean(3)) + ff.setFluid(filterIndex, new FluidStack(FluidRegistry.getFluid(fluidName), 0)) + withEnderFluidConduit(facing, c => { + c.setFilter(dir, ff, args.checkBoolean(4)) + result(true) + }) + } + else + result(false, "EnderIO not loaded") + + //noinspection ScalaUnusedSymbol + @Callback(doc = """function(side:number, direction:number, isInput:boolean, color:string):boolean -- Set fluid conduit priority at side facing direction""") + def setEnderLiquidConduitColor(context: Context, args: Arguments): Array[AnyRef] = if (Mods.EnderIO.isModAvailable) { + val facing = checkSideForAction(args, 0) + val dir = args.checkSideAny(1) + withEnderFluidConduit(facing, c => { + val isInput = args.checkBoolean(2) + val color = DyeColor.valueOf(args.checkString(3)) + if (isInput) c.setInputColor(dir, color) else c.setOutputColor(dir, color) + result(true) + }) + } + else + result(false, "EnderIO not loaded") + + private def convert(dir: ForgeDirection, ic: IItemConduit): Map[AnyRef, AnyRef] = Map( + "OutputColor" -> ic.getOutputColor(dir).getName, + "InputColor" -> ic.getInputColor(dir).getName, + "RoundRobinEnabled" -> ic.isRoundRobinEnabled(dir).asInstanceOf[AnyRef], + "SelfFeedEnabled" -> ic.isSelfFeedEnabled(dir).asInstanceOf[AnyRef], + "ExtractionRedstoneConditionMet" -> ic.isExtractionRedstoneConditionMet(dir).asInstanceOf[AnyRef], + "OutputPriority" -> ic.getOutputPriority(dir).asInstanceOf[AnyRef], + "InputFilter" -> convert(ic.getInputFilter(dir)), + "OutputFilter" -> convert(ic.getOutputFilter(dir)) + ) + + private def convert(dir: ForgeDirection, ic: ILiquidConduit): Map[AnyRef, AnyRef] = ic match { + case c: AbstractEnderLiquidConduit => Map[AnyRef,AnyRef]( + "InputFilter" -> convert(c.getFilter(dir, true)), + "OutputFilter" -> convert(c.getFilter(dir, false)), + "InputColor" -> c.getInputColor(dir).getName, + "OutputColor" -> c.getOutputColor(dir).getName + ) + + case c: AbstractTankConduit => Map[AnyRef,AnyRef]( + "FluidType" -> c.getFluidType.getLocalizedName + ) + case _ => null + } + private def convert(f: FluidFilter): Map[AnyRef, AnyRef] = + Map( + "blacklist"-> f.isBlacklist.asInstanceOf[AnyRef], + "1" -> Option(f.getFluidStackAt(0)).fold("")(_.getLocalizedName), + "2" -> Option(f.getFluidStackAt(1)).fold("")(_.getLocalizedName), + "3" -> Option(f.getFluidStackAt(2)).fold("")(_.getLocalizedName), + "4" -> Option(f.getFluidStackAt(3)).fold("")(_.getLocalizedName), + "5" -> Option(f.getFluidStackAt(4)).fold("")(_.getLocalizedName)) + + + private def convert(f: IItemFilter): Map[AnyRef, AnyRef] = f match { + case f: ItemFilter => + var filterInfo = Map[AnyRef,AnyRef]( + "Advanced" -> f.isAdvanced.asInstanceOf[AnyRef], + "Blacklist" -> f.isBlacklist.asInstanceOf[AnyRef], + "MatchMeta" -> f.isMatchMeta.asInstanceOf[AnyRef], + "MatchNBT" -> f.isMatchNBT.asInstanceOf[AnyRef], + "UseOreDict" -> f.isUseOreDict.asInstanceOf[AnyRef], + "Sticky" -> f.isSticky.asInstanceOf[AnyRef], + "FuzzyMode" -> f.getFuzzyMode.toString + ) + var items = List[ItemStack]() + for (i <- 0 to f.getSizeInventory) { + if (f.getStackInSlot(i) != null) + items = f.getStackInSlot(i) :: items + } + filterInfo += "FilterItems" -> items.toArray + filterInfo + + case _ => Map[AnyRef,AnyRef]() + } + } + trait RobotConfigurator extends ConfiguratorBase with SideRestricted with NetworkAware with traits.InventoryAware { + + //noinspection ScalaUnusedSymbol + @Callback(doc = """function(side:number, direction:number, input:boolean):boolean -- Replace conduit input or output filter at side facing direction with the filter in selected slot""") + def replaceConduitFilter(context: Context, args: Arguments): Array[AnyRef] = if (Mods.EnderIO.isModAvailable) { + val facing = checkSideForAction(args, 0) + val stack = inventory.getStackInSlot(selectedSlot) + val dir = args.checkSideAny(1) + val isInput = args.checkBoolean(2) + withItemConduit(facing, c => { + val old = if (isInput) c.getInputFilterUpgrade(dir) else c.getOutputFilterUpgrade(dir) + if (isInput) c.setInputFilterUpgrade(dir, stack) else c.setOutputFilterUpgrade(dir, stack) + inventory.setInventorySlotContents(selectedSlot, old) + result(true) + }) + } + else + result(false, "EnderIO not loaded") + } +} diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeInventoryController.scala b/src/main/scala/li/cil/oc/server/component/UpgradeInventoryController.scala index f7c7818ab..da4a2b2a1 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeInventoryController.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeInventoryController.scala @@ -91,6 +91,22 @@ object UpgradeInventoryController { } else result(false) } + @Callback(doc = """function([slot:number]):boolean -- Swaps the installed upgrade in the slot (1 by default) with the content of the currently selected inventory slot.""") + def installUpgrade(context: Context, args: Arguments): Array[AnyRef] = { + if (inventory.getSizeInventory > 0) { + val slot = args.optInteger(0, 1) + if (!host.isContainerSlot(slot)) + return result(false, "not a container slot") + val selected = inventory.getStackInSlot(selectedSlot) + if (selected != null && !host.isItemValidForSlot(slot, selected)) + return result(false, "Invalid upgrade") + val equipped = host.getStackInSlot(slot) + host.setInventorySlotContents(slot, selected) + inventory.setInventorySlotContents(selectedSlot, equipped) + result(true) + } + else result(false) + } } }