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.
This commit is contained in:
Florian Nücke 2015-08-12 15:07:04 -07:00
parent 8e3eccdbed
commit 6037f7a651
8 changed files with 50 additions and 31 deletions

View File

@ -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)

View File

@ -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)
}

View File

@ -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 => {

View File

@ -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)) {

View File

@ -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)
}

View File

@ -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 =>

View File

@ -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)

View File

@ -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
}
}