From 6037f7a651163c47a15d663ee29e7211c7b1635d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Wed, 12 Aug 2015 15:07:04 -0700 Subject: [PATCH] Allow passing side to piston upgrade's push() function. Down won't work in tablets held by players because they're holding it too high, but I honestly don't care. Refactored and extended ExtendedArguments a bit to be more in line with normal Arguments' methods. --- .../oc/server/component/UpgradePiston.scala | 8 +-- .../component/traits/InventoryControl.scala | 2 +- .../traits/InventoryWorldControl.scala | 4 +- .../traits/InventoryWorldControlMk2.scala | 4 +- .../server/component/traits/TankControl.scala | 2 +- .../traits/TankInventoryControl.scala | 4 +- .../component/traits/TankWorldControl.scala | 4 +- .../li/cil/oc/util/ExtendedArguments.scala | 53 ++++++++++++------- 8 files changed, 50 insertions(+), 31 deletions(-) diff --git a/src/main/scala/li/cil/oc/server/component/UpgradePiston.scala b/src/main/scala/li/cil/oc/server/component/UpgradePiston.scala index 4512d4414..800fc4b52 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradePiston.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradePiston.scala @@ -11,6 +11,7 @@ import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ +import li.cil.oc.util.ExtendedArguments._ import net.minecraft.init.Blocks class UpgradePiston(val host: Rotatable with EnvironmentHost) extends prefab.ManagedEnvironment { @@ -19,11 +20,12 @@ class UpgradePiston(val host: Rotatable with EnvironmentHost) extends prefab.Man withConnector(). create() - @Callback(doc = """function():boolean -- Tries to push the block in front of the container of the upgrade.""") + @Callback(doc = """function([side:number]):boolean -- Tries to push the block on the specified side of the container of the upgrade. Defaults to front.""") def push(context: Context, args: Arguments): Array[AnyRef] = { val hostPos = BlockPosition(host) - val blockPos = hostPos.offset(host.facing) - if (!host.world.isAirBlock(blockPos) && node.tryChangeBuffer(-Settings.get.pistonCost) && Blocks.piston.tryExtend(host.world, hostPos.x, hostPos.y, hostPos.z, host.facing.ordinal)) { + val facing = args.optSideForAction(0, host.facing) + val blockPos = hostPos.offset(facing) + if (!host.world.isAirBlock(blockPos) && node.tryChangeBuffer(-Settings.get.pistonCost) && Blocks.piston.tryExtend(host.world, hostPos.x, hostPos.y, hostPos.z, facing.ordinal)) { host.world.setBlockToAir(blockPos) host.world.playSoundEffect(host.xPosition, host.yPosition, host.zPosition, "tile.piston.out", 0.5f, host.world.rand.nextFloat() * 0.25f + 0.6f) context.pause(0.5) diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryControl.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryControl.scala index d8273c60e..b4001edec 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryControl.scala @@ -50,7 +50,7 @@ trait InventoryControl extends InventoryAware { @Callback(doc = "function(toSlot:number[, amount:number]):boolean -- Move up to the specified amount of items from the selected slot into the specified slot.") def transferTo(context: Context, args: Arguments): Array[AnyRef] = { val slot = args.checkSlot(inventory, 0) - val count = args.optionalItemCount(1) + val count = args.optItemCount(1) if (slot == selectedSlot || count == 0) { result(true) } diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala index 93367771b..643979f5b 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala @@ -33,7 +33,7 @@ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRest @Callback(doc = "function(side:number[, count:number=64]):boolean -- Drops items from the selected slot towards the specified side.") def drop(context: Context, args: Arguments): Array[AnyRef] = { val facing = checkSideForAction(args, 0) - val count = args.optionalItemCount(1) + val count = args.optItemCount(1) val stack = inventory.getStackInSlot(selectedSlot) if (stack != null && stack.stackSize > 0) { val blockPos = position.offset(facing) @@ -69,7 +69,7 @@ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRest @Callback(doc = "function(side:number[, count:number=64]):boolean -- Suck up items from the specified side.") def suck(context: Context, args: Arguments): Array[AnyRef] = { val facing = checkSideForAction(args, 0) - val count = args.optionalItemCount(1) + val count = args.optItemCount(1) val blockPos = position.offset(facing) if (InventoryUtils.inventoryAt(blockPos).exists(inventory => { diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala index 814ed4706..ad5d40185 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala @@ -14,7 +14,7 @@ trait InventoryWorldControlMk2 extends InventoryAware with WorldAware with SideR @Callback(doc = """function(facing:number, slot:number[, count:number]):boolean -- Drops the selected item stack into the specified slot of an inventory.""") def dropIntoSlot(context: Context, args: Arguments): Array[AnyRef] = { val facing = checkSideForAction(args, 0) - val count = args.optionalItemCount(2) + val count = args.optItemCount(2) val stack = inventory.getStackInSlot(selectedSlot) if (stack != null && stack.stackSize > 0) { withInventory(facing, inventory => { @@ -43,7 +43,7 @@ trait InventoryWorldControlMk2 extends InventoryAware with WorldAware with SideR @Callback(doc = """function(facing:number, slot:number[, count:number]):boolean -- Sucks items from the specified slot of an inventory.""") def suckFromSlot(context: Context, args: Arguments): Array[AnyRef] = { val facing = checkSideForAction(args, 0) - val count = args.optionalItemCount(2) + val count = args.optItemCount(2) withInventory(facing, inventory => { val slot = args.checkSlot(inventory, 1) if (InventoryUtils.extractFromInventorySlot(InventoryUtils.insertIntoInventory(_, this.inventory, slots = Option(insertionSlots)), inventory, facing.getOpposite, slot, count)) { diff --git a/src/main/scala/li/cil/oc/server/component/traits/TankControl.scala b/src/main/scala/li/cil/oc/server/component/traits/TankControl.scala index a57293d32..33815f2e9 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/TankControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/TankControl.scala @@ -53,7 +53,7 @@ trait TankControl extends TankAware { @Callback(doc = "function(index:number[, count:number=1000]):boolean -- Move the specified amount of fluid from the selected tank into the specified tank.") def transferFluidTo(context: Context, args: Arguments): Array[AnyRef] = { val index = args.checkTank(tank, 0) - val count = args.optionalFluidCount(1) + val count = args.optFluidCount(1) if (index == selectedTank || count == 0) { result(true) } diff --git a/src/main/scala/li/cil/oc/server/component/traits/TankInventoryControl.scala b/src/main/scala/li/cil/oc/server/component/traits/TankInventoryControl.scala index 993243f9a..8553bd053 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/TankInventoryControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/TankInventoryControl.scala @@ -35,7 +35,7 @@ trait TankInventoryControl extends WorldAware with InventoryAware with TankAware @Callback(doc = """function([amount:number]):boolean -- Transfers fluid from a tank in the selected inventory slot to the selected tank.""") def drain(context: Context, args: Arguments): Array[AnyRef] = { - val amount = args.optionalFluidCount(0) + val amount = args.optFluidCount(0) Option(tank.getFluidTank(selectedTank)) match { case Some(into) => inventory.getStackInSlot(selectedSlot) match { case stack: ItemStack => @@ -77,7 +77,7 @@ trait TankInventoryControl extends WorldAware with InventoryAware with TankAware @Callback(doc = """function([amount:number]):boolean -- Transfers fluid from the selected tank to a tank in the selected inventory slot.""") def fill(context: Context, args: Arguments): Array[AnyRef] = { - val amount = args.optionalFluidCount(0) + val amount = args.optFluidCount(0) Option(tank.getFluidTank(selectedTank)) match { case Some(from) => inventory.getStackInSlot(selectedSlot) match { case stack: ItemStack => diff --git a/src/main/scala/li/cil/oc/server/component/traits/TankWorldControl.scala b/src/main/scala/li/cil/oc/server/component/traits/TankWorldControl.scala index 282b33036..91a08b8fd 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/TankWorldControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/TankWorldControl.scala @@ -36,7 +36,7 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted { @Callback(doc = "function(side:boolean[, amount:number=1000]):boolean, number or string -- Drains the specified amount of fluid from the specified side. Returns the amount drained, or an error message.") def drain(context: Context, args: Arguments): Array[AnyRef] = { val facing = checkSideForAction(args, 0) - val count = args.optionalFluidCount(1) + val count = args.optFluidCount(1) getTank(selectedTank) match { case Some(tank) => val space = tank.getCapacity - tank.getFluidAmount @@ -97,7 +97,7 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted { @Callback(doc = "function(side:number[, amount:number=1000]):boolean, number of string -- Eject the specified amount of fluid to the specified side. Returns the amount ejected or an error message.") def fill(context: Context, args: Arguments): Array[AnyRef] = { val facing = checkSideForAction(args, 0) - val count = args.optionalFluidCount(1) + val count = args.optFluidCount(1) getTank(selectedTank) match { case Some(tank) => val amount = math.min(count, tank.getFluidAmount) diff --git a/src/main/scala/li/cil/oc/util/ExtendedArguments.scala b/src/main/scala/li/cil/oc/util/ExtendedArguments.scala index a6b682f6d..d6dcc1dbf 100644 --- a/src/main/scala/li/cil/oc/util/ExtendedArguments.scala +++ b/src/main/scala/li/cil/oc/util/ExtendedArguments.scala @@ -12,17 +12,13 @@ object ExtendedArguments { implicit def extendedArguments(args: Arguments): ExtendedArguments = new ExtendedArguments(args) class ExtendedArguments(val args: Arguments) { - def optionalItemCount(n: Int) = - if (args.count > n && args.checkAny(n) != null) { - math.max(0, math.min(64, args.checkInteger(n))) - } - else 64 + def optItemCount(index: Int, default: Int = 64) = + if (!isDefined(index) || !hasValue(index)) default + else math.max(0, math.min(64, args.checkInteger(index))) - def optionalFluidCount(n: Int) = - if (args.count > n && args.checkAny(n) != null) { - math.max(0, args.checkInteger(n)) - } - else 1000 + def optFluidCount(index: Int, default: Int = 1000) = + if (!isDefined(index) || !hasValue(index)) default + else math.max(0, args.checkInteger(index)) def checkSlot(inventory: IInventory, n: Int) = { val slot = args.checkInteger(n) - 1 @@ -32,9 +28,9 @@ object ExtendedArguments { slot } - def optSlot(inventory: IInventory, n: Int, default: Int) = { - if (n >= 0 && n < args.count()) checkSlot(inventory, n) - else default + def optSlot(inventory: IInventory, index: Int, default: Int) = { + if (!isDefined(index)) default + else checkSlot(inventory, index) } def checkTank(multi: MultiTank, n: Int) = { @@ -45,14 +41,26 @@ object ExtendedArguments { tank } - def checkSideForAction(n: Int) = checkSide(n, ForgeDirection.SOUTH, ForgeDirection.UP, ForgeDirection.DOWN) + def checkSideForAction(index: Int) = checkSide(index, ForgeDirection.SOUTH, ForgeDirection.UP, ForgeDirection.DOWN) - def checkSideForMovement(n: Int) = checkSide(n, ForgeDirection.SOUTH, ForgeDirection.NORTH, ForgeDirection.UP, ForgeDirection.DOWN) + def optSideForAction(index: Int, default: ForgeDirection) = + if (!isDefined(index)) default + else checkSideForAction(index) - def checkSideForFace(n: Int, facing: ForgeDirection) = checkSide(n, ForgeDirection.VALID_DIRECTIONS.filter(_ != facing.getOpposite): _*) + def checkSideForMovement(index: Int) = checkSide(index, ForgeDirection.SOUTH, ForgeDirection.NORTH, ForgeDirection.UP, ForgeDirection.DOWN) - def checkSide(n: Int, allowed: ForgeDirection*) = { - val side = args.checkInteger(n) + def optSideForMovement(index: Int, default: ForgeDirection) = + if (!isDefined(index)) default + else checkSideForMovement(index) + + def checkSideForFace(index: Int, facing: ForgeDirection) = checkSide(index, ForgeDirection.VALID_DIRECTIONS.filter(_ != facing.getOpposite): _*) + + def optSideForFace(index: Int, default: ForgeDirection) = + if (!isDefined(index)) default + else checkSideForAction(index) + + def checkSide(index: Int, allowed: ForgeDirection*) = { + val side = args.checkInteger(index) if (side < 0 || side > 5) { throw new IllegalArgumentException("invalid side") } @@ -60,6 +68,15 @@ object ExtendedArguments { if (allowed.isEmpty || (allowed contains direction)) direction else throw new IllegalArgumentException("unsupported side") } + + def optSide(index: Int, default: ForgeDirection, allowed: ForgeDirection*) = { + if (!isDefined(index)) default + else checkSide(index, allowed: _*) + } + + private def isDefined(index: Int) = index >= 0 && index < args.count() + + private def hasValue(index: Int) = args.checkAny(index) != null } }