From b95bd77dbdf927422704001d6ffa2ec075ef6b78 Mon Sep 17 00:00:00 2001 From: hinyb <40139991+hinyb@users.noreply.github.com> Date: Fri, 24 Apr 2026 17:07:31 +0800 Subject: [PATCH 1/8] feat(appeng): enhance updateAE --- .../cil/oc/integration/appeng/UpgradeAE.scala | 212 +++++++----------- 1 file changed, 76 insertions(+), 136 deletions(-) diff --git a/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala b/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala index e3ca377f87..6b7af57024 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala @@ -14,13 +14,14 @@ import li.cil.oc.Constants import li.cil.oc.api.Network import li.cil.oc.api.driver.DeviceInfo import li.cil.oc.api.driver.DeviceInfo.{DeviceAttribute, DeviceClass} -import li.cil.oc.api.internal.{Agent, Database, Drone, Robot} +import li.cil.oc.api.internal.{Agent, Drone, Robot} import li.cil.oc.api.machine.{Arguments, Callback, Context} import li.cil.oc.api.network._ import li.cil.oc.api.prefab.ManagedEnvironment import li.cil.oc.common.item.Delegator import li.cil.oc.integration.appeng -import li.cil.oc.server.network.Component +import li.cil.oc.util.DatabaseAccess +import li.cil.oc.util.ResultWrapper.result import net.minecraft.item.ItemStack import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.fluids.FluidContainerRegistry @@ -73,69 +74,38 @@ class UpgradeAE(val host: EnvironmentHost, val tier: Int) extends ManagedEnviron } def checkRange(stack: ItemStack, sec: IGridHost): Boolean = { - if (sec == null) return false - val gridNode: IGridNode = sec.getGridNode(ForgeDirection.UNKNOWN) - if (gridNode == null) return false - val grid = gridNode.getGrid - if (grid == null) return false - stack.getItemDamage match { - case 0 => - val gridBlock = gridNode.getGridBlock - if (gridBlock == null) return false - val loc = gridBlock.getLocation - if (loc == null) return false - for ( - node <- grid.getMachines( - AEApi.instance.definitions.blocks.wireless.maybeEntity.get - .asInstanceOf[Class[_ <: IGridHost]] - ) - ) { - val accessPoint: IWirelessAccessPoint = - node.getMachine.asInstanceOf[IWirelessAccessPoint] - val distance: WorldCoord = accessPoint.getLocation.subtract( - agent.xPosition.toInt, - agent.yPosition.toInt, - agent.zPosition.toInt - ) - val squaredDistance: Int = - distance.x * distance.x + distance.y * distance.y + distance.z * distance.z - val range = accessPoint.getRange / 2 - if (squaredDistance <= range * range) return true - } - false - case 1 => - val gridBlock = gridNode.getGridBlock - if (gridBlock == null) return false - val loc = gridBlock.getLocation - if (loc == null) return false - for ( - node <- grid.getMachines( - AEApi.instance.definitions.blocks.wireless.maybeEntity.get - .asInstanceOf[Class[_ <: IGridHost]] - ) - ) { - val accessPoint: IWirelessAccessPoint = - node.getMachine.asInstanceOf[IWirelessAccessPoint] - val distance: WorldCoord = accessPoint.getLocation.subtract( - agent.xPosition.toInt, - agent.yPosition.toInt, - agent.zPosition.toInt - ) - val squaredDistance: Int = - distance.x * distance.x + distance.y * distance.y + distance.z * distance.z - val range = accessPoint.getRange - if (squaredDistance <= range * range) return true - } - false - case _ => - grid - .getMachines( - AEApi.instance.definitions.blocks.wireless.maybeEntity.get - .asInstanceOf[Class[_ <: IGridHost]] - ) - .iterator - .hasNext + val result = for { + sec_ <- Option(sec) + gridNode <- Option(sec_.getGridNode(ForgeDirection.UNKNOWN)) + grid <- Option(gridNode.getGrid) + } yield { + val wirelessClass = AEApi.instance.definitions.blocks.wireless.maybeEntity.get + val accessPoints = grid.getMachines(wirelessClass.asInstanceOf[Class[_ <: IGridHost]]) + stack.getItemDamage match { + case 0 | 1 => + val gridBlock = gridNode.getGridBlock + if (gridBlock == null || gridBlock.getLocation == null) + false + else { + val rangeMultiplier = if (stack.getItemDamage == 0) 0.5 else 1 + accessPoints.exists { node => + val accessPoint = node.getMachine.asInstanceOf[IWirelessAccessPoint] + val distance: WorldCoord = accessPoint.getLocation.subtract( + agent.xPosition.toInt, + agent.yPosition.toInt, + agent.zPosition.toInt + ) + val squaredDistance: Int = + distance.x * distance.x + distance.y * distance.y + distance.z * distance.z + val range = accessPoint.getRange * rangeMultiplier + squaredDistance <= range * range + } + } + case _ => + accessPoints.iterator.hasNext + } } + result.getOrElse(false) } def getGrid: IGrid = { @@ -224,60 +194,35 @@ class UpgradeAE(val host: EnvironmentHost, val tier: Int) extends ManagedEnviron } } - @Callback(doc = """function(database:address, entry:number[, number:amount]):number -- Get items from your ae system.""") + @Callback(doc = """function(database:address, entry:number[, number:amount]):number OR function(detail:table):number -- Get items from your ae system.""") def requestItems(context: Context, args: Arguments): Array[AnyRef] = { - - val address = args.checkString(0) - val entry = args.checkInteger(1) - val amount = args.optInteger(2, 64) - val selected = agent.selectedSlot val invRobot = agent.mainInventory - if (invRobot.getSizeInventory <= 0) return Array(0.underlying) + if (invRobot.getSizeInventory <= 0) return result(0) val inv = getItemInventory - if (inv == null) return Array(0.underlying) - val n: Node = node.network.node(address) - if (n == null) throw new IllegalArgumentException("no such component") - if (!n.isInstanceOf[Component]) - throw new IllegalArgumentException("no such component") - val env: Environment = n.host - if (!env.isInstanceOf[Database]) - throw new IllegalArgumentException("not a database") - val database: Database = env.asInstanceOf[Database] - val sel = invRobot.getStackInSlot(selected) - val inSlot = - if (sel == null) - 0 - else - sel.stackSize - val maxSize = - if (sel == null) - 64 - else - sel.getMaxStackSize - val stack = database.getStackInSlot(entry - 1) - if (stack == null) return Array(0.underlying) - stack.stackSize = Math.min(amount, maxSize - inSlot) - val stack2 = stack.copy - stack2.stackSize = 1 - val sel2 = - if (sel != null) { - val sel3 = sel.copy - sel3.stackSize = 1 - sel3 - } else - null - if (sel != null && !ItemStack.areItemStacksEqual(sel2, stack2)) - return Array(0.underlying) + if (inv == null) return result(0) + + val aestack = { + if (args.isTable(0)) AEStackFactory.parse[IAEItemStack](args.checkTable(0)) + else AEApi.instance.storage.createItemStack(DatabaseAccess.getStackFromDatabase(node, args, 0)) + } + if (aestack == null) return result(0) + val set_stack = aestack.getItemStack + val currentStackOpt = Option(invRobot.getStackInSlot(agent.selectedSlot)) + val inSlot = currentStackOpt.map(_.stackSize).getOrElse(0) + val maxSize = currentStackOpt.map(_.getMaxStackSize).getOrElse(64) + aestack.setStackSize(Math.min(set_stack.stackSize, maxSize - inSlot)) + if (currentStackOpt.exists(!aestack.isSameType(_))) + return result(0) val extracted = inv.extractItems( - AEApi.instance.storage.createItemStack(stack), + aestack, Actionable.MODULATE, new MachineSource(tile) ) - if (extracted == null) return Array(0.underlying) + if (extracted == null) return result(0) val ext = extracted.getStackSize.toInt - stack.stackSize = inSlot + ext - invRobot.setInventorySlotContents(selected, stack) - Array(ext.underlying) + set_stack.stackSize = inSlot + ext + invRobot.setInventorySlotContents(agent.selectedSlot, set_stack) + result(ext) } @Callback(doc = """function([number:amount]):number -- Transfer selected fluid to your ae system.""") @@ -308,39 +253,34 @@ class UpgradeAE(val host: EnvironmentHost, val tier: Int) extends ManagedEnviron } } - @Callback(doc = """function(database:address, entry:number[, number:amount]):number -- Get fluid from your ae system.""") + @Callback(doc = """function(database:address, entry:number[, number:amount]):number OR function(detail:table):number -- Get fluid from your ae system.""") def requestFluids(context: Context, args: Arguments): Array[AnyRef] = { - val address = args.checkString(0) - val entry = args.checkInteger(1) - val amount = args.optInteger(2, FluidContainerRegistry.BUCKET_VOLUME) val tanks = agent.tank - val selected = agent.selectedTank - if (tanks.tankCount <= 0) return Array(0.underlying) - val tank = tanks.getFluidTank(selected) + if (tanks.tankCount <= 0) return result(0) + + val tank = tanks.getFluidTank(agent.selectedTank) val inv = getFluidInventory - if (tank == null || inv == null) return Array(0.underlying) - val n: Node = node.network.node(address) - if (n == null) throw new IllegalArgumentException("no such component") - if (!n.isInstanceOf[Component]) - throw new IllegalArgumentException("no such component") - val env: Environment = n.host - if (!env.isInstanceOf[Database]) - throw new IllegalArgumentException("not a database") - val database: Database = env.asInstanceOf[Database] - val fluid = FluidContainerRegistry.getFluidForFilledItem( - database.getStackInSlot(entry - 1) - ) - fluid.amount = amount - val fluid2 = fluid.copy() - fluid2.amount = tank.fill(fluid, false) - if (fluid2.amount == 0) return Array(0.underlying) + if (tank == null || inv == null) return result(0) + + val aefluid = { + if (args.isTable(0)) AEStackFactory.parse[IAEFluidStack](args.checkTable(0)) + else { + val stack = DatabaseAccess.getStackFromDatabase(node, args, 0) + val fluid = FluidContainerRegistry.getFluidForFilledItem(stack) + fluid.amount = args.optInteger(2, FluidContainerRegistry.BUCKET_VOLUME) + AEApi.instance.storage.createFluidStack(fluid) + } + } + val amount = tank.fill(aefluid.getFluidStack, false) + if (amount == 0) return result(0) + aefluid.setStackSize(amount) val extracted = inv.extractItems( - AEApi.instance.storage.createFluidStack(fluid2), + aefluid, Actionable.MODULATE, new MachineSource(tile) ) - if (extracted == null) return Array(0.underlying) - Array(tank.fill(extracted.getFluidStack, true).underlying) + if (extracted == null) return result(0) + result(tank.fill(extracted.getFluidStack, true)) } From 598b4064623b85b66815c6bcf6ec391a0ad453c1 Mon Sep 17 00:00:00 2001 From: hinyb <40139991+hinyb@users.noreply.github.com> Date: Fri, 24 Apr 2026 17:07:47 +0800 Subject: [PATCH 2/8] fix: make size optional --- .../scala/li/cil/oc/integration/appeng/AEStackFactory.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/li/cil/oc/integration/appeng/AEStackFactory.scala b/src/main/scala/li/cil/oc/integration/appeng/AEStackFactory.scala index b22ebba071..bf6fe5652d 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/AEStackFactory.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/AEStackFactory.scala @@ -27,7 +27,7 @@ object AEStackFactory { classRegistry.get(tag.runtimeClass) match { case Some(entry) => val result = entry.parser(map).asInstanceOf[T] - result.setStackSize(map.getLong("size").get) + result.setStackSize(map.getLong("size").getOrElse(1)) result case None => throw new UnregisteredAETypeException(s"Type ${tag.runtimeClass} hasn't been registered"); } @@ -37,7 +37,7 @@ object AEStackFactory { idRegistry.get(key) match { case Some(entry) => val result = entry.parser(map) - result.setStackSize(map.getLong("size").get) + result.setStackSize(map.getLong("size").getOrElse(1)) result case None => throw new UnregisteredAETypeException(s"Type $key hasn't been registered"); } From b62b0f23d9e7c66ffcc7f1a85a3859d652c6d45c Mon Sep 17 00:00:00 2001 From: hinyb <40139991+hinyb@users.noreply.github.com> Date: Fri, 24 Apr 2026 17:07:59 +0800 Subject: [PATCH 3/8] refactor: support long in request --- .../scala/li/cil/oc/integration/appeng/NetworkControl.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala b/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala index 8d6520134e..44316e04bf 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala @@ -344,13 +344,13 @@ object NetworkControl extends AETypes { @Callback(doc = "function():table -- Returns the item stack representation of the crafting result.") def getStack(context: Context, args: Arguments): Array[AnyRef] = result(stack) - @Callback(doc = "function([amount:int[, prioritizePower:boolean[, cpuName:string]]]):userdata -- Requests the item to be crafted, returning an object that allows tracking the crafting status.") + @Callback(doc = "function([amount:number[, prioritizePower:boolean[, cpuName:string]]]):userdata -- Requests the item to be crafted, returning an object that allows tracking the crafting status.") def request(context: Context, args: Arguments): Array[AnyRef] = { if (controller == null || controller.isInvalid) { return result(Unit, "no controller") } - val count = args.optInteger(0, 1) + val count = args.optLong(0, 1) val request = stack.copy request.setStackSize(count) From e750ba6639946ddd41b40ed526fe629e521791af Mon Sep 17 00:00:00 2001 From: hinyb <40139991+hinyb@users.noreply.github.com> Date: Sat, 25 Apr 2026 07:54:34 +0800 Subject: [PATCH 4/8] fix: fix default argument and add null check --- src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala b/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala index 6b7af57024..fd0fcac7a0 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala @@ -21,6 +21,7 @@ import li.cil.oc.api.prefab.ManagedEnvironment import li.cil.oc.common.item.Delegator import li.cil.oc.integration.appeng import li.cil.oc.util.DatabaseAccess +import li.cil.oc.util.ExtendedArguments.extendedArguments import li.cil.oc.util.ResultWrapper.result import net.minecraft.item.ItemStack import net.minecraftforge.common.util.ForgeDirection @@ -206,6 +207,7 @@ class UpgradeAE(val host: EnvironmentHost, val tier: Int) extends ManagedEnviron else AEApi.instance.storage.createItemStack(DatabaseAccess.getStackFromDatabase(node, args, 0)) } if (aestack == null) return result(0) + if (!args.isInteger(2)) aestack.setStackSize(64) val set_stack = aestack.getItemStack val currentStackOpt = Option(invRobot.getStackInSlot(agent.selectedSlot)) val inSlot = currentStackOpt.map(_.stackSize).getOrElse(0) @@ -267,10 +269,11 @@ class UpgradeAE(val host: EnvironmentHost, val tier: Int) extends ManagedEnviron else { val stack = DatabaseAccess.getStackFromDatabase(node, args, 0) val fluid = FluidContainerRegistry.getFluidForFilledItem(stack) - fluid.amount = args.optInteger(2, FluidContainerRegistry.BUCKET_VOLUME) AEApi.instance.storage.createFluidStack(fluid) } } + if (aefluid == null) return result(0) + if (!args.isInteger(2)) aefluid.setStackSize(FluidContainerRegistry.BUCKET_VOLUME) val amount = tank.fill(aefluid.getFluidStack, false) if (amount == 0) return result(0) aefluid.setStackSize(amount) From 99c1214f2d91b548d49268555f145dae1815b2d9 Mon Sep 17 00:00:00 2001 From: hinyb <40139991+hinyb@users.noreply.github.com> Date: Sat, 25 Apr 2026 07:54:45 +0800 Subject: [PATCH 5/8] refactor: improve requestItems logic and variable naming --- .../li/cil/oc/integration/appeng/UpgradeAE.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala b/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala index fd0fcac7a0..fec8a5e08a 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala @@ -208,13 +208,13 @@ class UpgradeAE(val host: EnvironmentHost, val tier: Int) extends ManagedEnviron } if (aestack == null) return result(0) if (!args.isInteger(2)) aestack.setStackSize(64) - val set_stack = aestack.getItemStack + val setStack = aestack.getItemStack val currentStackOpt = Option(invRobot.getStackInSlot(agent.selectedSlot)) - val inSlot = currentStackOpt.map(_.stackSize).getOrElse(0) - val maxSize = currentStackOpt.map(_.getMaxStackSize).getOrElse(64) - aestack.setStackSize(Math.min(set_stack.stackSize, maxSize - inSlot)) if (currentStackOpt.exists(!aestack.isSameType(_))) return result(0) + val inSlot = currentStackOpt.map(_.stackSize).getOrElse(0) + val maxSize = currentStackOpt.map(_.getMaxStackSize).getOrElse(64) + aestack.setStackSize(Math.min(setStack.stackSize, maxSize - inSlot)) val extracted = inv.extractItems( aestack, Actionable.MODULATE, @@ -222,8 +222,8 @@ class UpgradeAE(val host: EnvironmentHost, val tier: Int) extends ManagedEnviron ) if (extracted == null) return result(0) val ext = extracted.getStackSize.toInt - set_stack.stackSize = inSlot + ext - invRobot.setInventorySlotContents(agent.selectedSlot, set_stack) + setStack.stackSize = inSlot + ext + invRobot.setInventorySlotContents(agent.selectedSlot, setStack) result(ext) } From 1a9bb00d1baf964771e1687c653669d9283eeded Mon Sep 17 00:00:00 2001 From: hinyb <40139991+hinyb@users.noreply.github.com> Date: Sat, 25 Apr 2026 08:17:33 +0800 Subject: [PATCH 6/8] docs: imporve documentation for requestItems and requestFluids --- .../cil/oc/integration/appeng/UpgradeAE.scala | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala b/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala index fec8a5e08a..046cc054ef 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala @@ -21,7 +21,6 @@ import li.cil.oc.api.prefab.ManagedEnvironment import li.cil.oc.common.item.Delegator import li.cil.oc.integration.appeng import li.cil.oc.util.DatabaseAccess -import li.cil.oc.util.ExtendedArguments.extendedArguments import li.cil.oc.util.ResultWrapper.result import net.minecraft.item.ItemStack import net.minecraftforge.common.util.ForgeDirection @@ -161,7 +160,8 @@ class UpgradeAE(val host: EnvironmentHost, val tier: Int) extends ManagedEnviron storage.getItemInventory } - @Callback(doc = """function([number:amount]):number -- Transfer selected items to your ae system.""") + @Callback(doc = + """function([number:amount]):number -- Transfer selected items to your ae system.""") def sendItems(context: Context, args: Arguments): Array[AnyRef] = { val selected = agent.selectedSlot val invRobot = agent.mainInventory @@ -195,7 +195,12 @@ class UpgradeAE(val host: EnvironmentHost, val tier: Int) extends ManagedEnviron } } - @Callback(doc = """function(database:address, entry:number[, number:amount]):number OR function(detail:table):number -- Get items from your ae system.""") + @Callback(doc = + """function(database:address, entry:number[, number:amount]):number OR function(detail:table):number +Detail keys: 'name' (string), 'damage' (number), 'size' (number), 'id' (number). +Required: name OR id. Optional: damage, size +Example: {name = "minecraft:bucket", size = 1} OR {id = 1} +-- Get items from your ae system.""") def requestItems(context: Context, args: Arguments): Array[AnyRef] = { val invRobot = agent.mainInventory if (invRobot.getSizeInventory <= 0) return result(0) @@ -255,7 +260,12 @@ class UpgradeAE(val host: EnvironmentHost, val tier: Int) extends ManagedEnviron } } - @Callback(doc = """function(database:address, entry:number[, number:amount]):number OR function(detail:table):number -- Get fluid from your ae system.""") + @Callback(doc = + """function(database:address, entry:number[, number:amount]):number OR function(detail:table):number +Detail keys: 'name' (string), 'size' (number), 'id' (number). +Required: name OR id. Optional: size +Example: {name = "water", size = 1} OR {id = 1} +-- Get fluid from your ae system.""") def requestFluids(context: Context, args: Arguments): Array[AnyRef] = { val tanks = agent.tank if (tanks.tankCount <= 0) return result(0) From fc049d9854a707a40b7ddecb0202d73b6c56cfb0 Mon Sep 17 00:00:00 2001 From: hinyb <40139991+hinyb@users.noreply.github.com> Date: Sat, 25 Apr 2026 11:50:52 +0800 Subject: [PATCH 7/8] fix: correct default argument logic --- .../cil/oc/integration/appeng/UpgradeAE.scala | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala b/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala index 046cc054ef..889c063048 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala @@ -20,6 +20,7 @@ import li.cil.oc.api.network._ import li.cil.oc.api.prefab.ManagedEnvironment import li.cil.oc.common.item.Delegator import li.cil.oc.integration.appeng +import li.cil.oc.integration.util.MapUtils.MapWrapper import li.cil.oc.util.DatabaseAccess import li.cil.oc.util.ResultWrapper.result import net.minecraft.item.ItemStack @@ -208,11 +209,21 @@ Example: {name = "minecraft:bucket", size = 1} OR {id = 1} if (inv == null) return result(0) val aestack = { - if (args.isTable(0)) AEStackFactory.parse[IAEItemStack](args.checkTable(0)) - else AEApi.instance.storage.createItemStack(DatabaseAccess.getStackFromDatabase(node, args, 0)) + if (args.isTable(0)) { + val t = args.checkTable(0) + Option(AEStackFactory.parse[IAEItemStack](t)).map { s => + if (t.getInt("size").isEmpty) s.setStackSize(64) + s + }.orNull + } + else { + Option(DatabaseAccess.getStackFromDatabase(node, args, 0)).map { s => + if (!args.isInteger(2)) s.stackSize = math.min(64, s.getMaxStackSize) + AEApi.instance.storage.createItemStack(s) + }.orNull + } } if (aestack == null) return result(0) - if (!args.isInteger(2)) aestack.setStackSize(64) val setStack = aestack.getItemStack val currentStackOpt = Option(invRobot.getStackInSlot(agent.selectedSlot)) if (currentStackOpt.exists(!aestack.isSameType(_))) @@ -275,15 +286,23 @@ Example: {name = "water", size = 1} OR {id = 1} if (tank == null || inv == null) return result(0) val aefluid = { - if (args.isTable(0)) AEStackFactory.parse[IAEFluidStack](args.checkTable(0)) + if (args.isTable(0)) { + val t = args.checkTable(0) + Option(AEStackFactory.parse[IAEFluidStack](t)).map { s => + if (t.getInt("size").isEmpty) s.setStackSize(FluidContainerRegistry.BUCKET_VOLUME) + s + }.orNull + } else { - val stack = DatabaseAccess.getStackFromDatabase(node, args, 0) - val fluid = FluidContainerRegistry.getFluidForFilledItem(stack) - AEApi.instance.storage.createFluidStack(fluid) + Option(DatabaseAccess.getStackFromDatabase(node, args, 0)).flatMap { s => + Option(FluidContainerRegistry.getFluidForFilledItem(s)) + }.map { fluid => + fluid.amount = args.optInteger(2, FluidContainerRegistry.BUCKET_VOLUME) + AEApi.instance.storage.createFluidStack(fluid) + }.orNull } } if (aefluid == null) return result(0) - if (!args.isInteger(2)) aefluid.setStackSize(FluidContainerRegistry.BUCKET_VOLUME) val amount = tank.fill(aefluid.getFluidStack, false) if (amount == 0) return result(0) aefluid.setStackSize(amount) From 88a37fca58d7ef8cce42af870814fea57ddcfa9a Mon Sep 17 00:00:00 2001 From: hinyb <40139991+hinyb@users.noreply.github.com> Date: Sat, 25 Apr 2026 19:31:06 +0800 Subject: [PATCH 8/8] docs: clarify fluid amount units --- src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala b/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala index 889c063048..21492f5c02 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/UpgradeAE.scala @@ -274,8 +274,8 @@ Example: {name = "minecraft:bucket", size = 1} OR {id = 1} @Callback(doc = """function(database:address, entry:number[, number:amount]):number OR function(detail:table):number Detail keys: 'name' (string), 'size' (number), 'id' (number). -Required: name OR id. Optional: size -Example: {name = "water", size = 1} OR {id = 1} +Required: name OR id. Optional: size (Note: 1000 = 1 bucket) +Example: {name = "water", size = 1000} OR {id = 1} -- Get fluid from your ae system.""") def requestFluids(context: Context, args: Arguments): Array[AnyRef] = { val tanks = agent.tank