Limiting robot flight height, by default to 8 blocks above ground for now.

Movement rules are as follows now:
 1. Robots may only move if the start or target position is valid (e.g. to allow building bridges).
 2. The position below a robot is always valid (can always move down).
 3. Positions up to <flightHeight> above a block are valid (limited flight capabilities).
 4. Any position that has an adjacent block with a solid face towards the position is valid (robots can "climb").
This commit is contained in:
Florian Nücke 2015-02-05 20:02:14 +01:00
parent 29b9a2d007
commit 003463ec4a
5 changed files with 57 additions and 4 deletions

View File

@ -274,6 +274,19 @@ opencomputers {
# in the game.
canAttackPlayers: false
# Limit robot flight height, based on the following rules:
# - Robots may only move if the start or target position is valid (e.g.
# to allow building bridges).
# - The position below a robot is always valid (can always move down).
# - Positions up to <flightHeight> above a block are valid (limited
# flight capabilities).
# - Any position that has an adjacent block with a solid face towards the
# position is valid (robots can "climb").
# Set this to 256 to allow robots to fly whereever, as was the case
# before the 1.5 update. Consider using drones for cases where you need
# unlimited flight capabilities instead!
limitFlightHeight: 8
# Determines whether robots are a pretty cool guy. Ususally cobwebs are
# the bane of anything using a tool other than a sword or shears. This is
# an utter pain in the part you sit on, because it makes robots meant to

View File

@ -95,6 +95,7 @@ class Settings(val config: Config) {
val allowActivateBlocks = config.getBoolean("robot.allowActivateBlocks")
val allowUseItemsWithDuration = config.getBoolean("robot.allowUseItemsWithDuration")
val canAttackPlayers = config.getBoolean("robot.canAttackPlayers")
val limitFlightHeight = config.getInt("robot.limitFlightHeight") max 0
val screwCobwebs = config.getBoolean("robot.notAfraidOfSpiders")
val swingRange = config.getDouble("robot.swingRange")
val useAndPlaceRange = config.getDouble("robot.useAndPlaceRange")

View File

@ -1,7 +1,13 @@
package li.cil.oc.common.event
import cpw.mods.fml.common.eventhandler.SubscribeEvent
import li.cil.oc.Settings
import li.cil.oc.api.event.RobotMoveEvent
import li.cil.oc.api.event.RobotUsedToolEvent
import li.cil.oc.api.internal.Robot
import li.cil.oc.util.BlockPosition
import li.cil.oc.util.ExtendedWorld._
import net.minecraftforge.common.util.ForgeDirection
object RobotCommonHandler {
@SubscribeEvent
@ -15,4 +21,33 @@ object RobotCommonHandler {
}
}
}
@SubscribeEvent
def onRobotMove(e: RobotMoveEvent.Pre): Unit = {
if (Settings.get.limitFlightHeight < 256) e.agent match {
case robot: Robot =>
val world = robot.world
// TODO Allow increasing this via upgrades?
val maxFlyingHeight = Settings.get.limitFlightHeight
def isMovingDown = e.direction == ForgeDirection.DOWN
def hasAdjacentBlock(pos: BlockPosition) = ForgeDirection.VALID_DIRECTIONS.exists(side => world.isSideSolid(pos.offset(side), side.getOpposite))
def isWithinFlyingHeight(pos: BlockPosition) = (1 to maxFlyingHeight).exists(n => !world.isAirBlock(pos.offset(e.direction.getOpposite, n)))
val startPos = BlockPosition(robot)
val targetPos = startPos.offset(e.direction)
// New movement rules as of 1.5:
// 1. Robots may only move if the start or target position is valid (e.g. to allow building bridges).
// 2. The position below a robot is always valid (can always move down).
// 3. Positions up to <flightHeight> above a block are valid (limited flight capabilities).
// 4. Any position that has an adjacent block with a solid face towards the position is valid (robots can "climb").
val validMove = isMovingDown ||
hasAdjacentBlock(startPos) ||
hasAdjacentBlock(targetPos) ||
isWithinFlyingHeight(startPos)
if (!validMove) {
e.setCanceled(true)
}
case _ =>
}
}
}

View File

@ -19,13 +19,15 @@ class BlockPosition(val x: Int, val y: Int, val z: Int, val world: Option[World]
world
)
def offset(direction: ForgeDirection) = new BlockPosition(
x + direction.offsetX,
y + direction.offsetY,
z + direction.offsetZ,
def offset(direction: ForgeDirection, n: Int) = new BlockPosition(
x + direction.offsetX * n,
y + direction.offsetY * n,
z + direction.offsetZ * n,
world
)
def offset(direction: ForgeDirection): BlockPosition = offset(direction, 1)
def offset(x: Double, y: Double, z: Double) = Vec3.createVectorHelper(this.x + x, this.y + y, this.z + z)
def bounds = AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 1, z + 1)

View File

@ -60,6 +60,8 @@ object ExtendedWorld {
def setBlock(position: BlockPosition, block: Block, metadata: Int, flag: Int) = world.setBlock(position.x, position.y, position.z, block, metadata, flag)
def setBlockToAir(position: BlockPosition) = world.setBlockToAir(position.x, position.y, position.z)
def isSideSolid(position: BlockPosition, side: ForgeDirection) = world.isSideSolid(position.x, position.y, position.z, side)
}
}