**This is an old revision of the document!**

Robot(机器人) API

此API封装了机器人组件的功能,允许与机器人实现更直观的互动。

使用如下方式在你的 Lua 代码中调用这个 API:

snippet.lua
local robot_api = require("robot")
robot_api.forward()

不推荐直接访问机器人组件API,虽然可以通过组件接口这么做:

snippet.lua
local component = require("component")
local robot_component_api = component.robot -- 如果你使用 OpenOS 可以这么写,否则要写 component.proxy(component.list("robot")())
robot_component_api.move(sides.front)

尽管机器人组件提供了更通用的功能,比如说 move([side: number]) 或者 drop([side: number]),但这个API能提供更直观、更安全的功能,比如说 turnRight, dropDown, forward。使用哪一种由你自己决定,甚至可以混用二者。

请注意机器人本身就是一台开放式电脑,和其它电脑一样,只是多了一个机器人组件,所以一般的API仍然可用。

查看方块:机器人以获取更多有关机器人本身的信息。

槽位排列

内部与外部槽位排列的区别

机器人自带物品栏的内部视图与外部视图槽位索引号不同。

机器人与其自身物品栏交互时使用内部视图。访问其他机器人的物品栏时使用外部视图。

这种区别是为了分开两种物品栏空间:主物品栏和工具带物品栏。在内部视图下,机器人只能选定主物品栏的槽位,不能选定工具带槽位,但是可以装备(equip函数)或卸下工具带中的物品。在外部视图下,观察者只会与单个物品栏交互,其中同时包含了工具带和主物品栏二者。

内部视图槽位排列

机器人的GUI中显示了机器人的物品栏槽位,编号从左上到右下排列。例如,编号为1的槽位显示在左上角,编号为2的槽位紧挨着它在其右侧,第二行的第一个槽位为编号5。

这些槽位编号是机器人与自身交互时使用的(在内部视图下用于自身的主物品栏 )。

机器人有多少可用槽位依其配置而定。若在调用某函数时指定的槽位号超出了机器人的槽位总数,将会报错。

这些槽位编号代表了内部视角下的机器人物品栏,因此机器人可以使用这些槽位编号对其主物品栏中的物品进行select(选定)、place(放置)、drop(丢弃)compare(比较)等操作。

机器人物品栏的外部视图

对外部观察者而言,机器人物品栏的编号会偏移4。对外部观察者,1至4槽位代表机器人工具带的槽位。主物品栏的第一个槽位在机器人内部(内部视图下)为1,但是对外部观察者而言是5。这么做确实感觉有些混乱,但是这么设计是为了:对外部观察者而言,[槽位1]永远代指第一个工具带槽位,[槽位5]永远代指第一个主物品栏槽位,无论机器人的物品栏大小如何。

机器人的物品栏对外界观察者而言是有方向区分的。机器人不会将其全部物品栏开放给全部方向。但是槽位编号不会随方向而变化。因此槽位1永远代指工具带的第一个槽位,哪怕在无法访问的面上也是如此。

  • 机器人的左侧不开放任何槽位。
  • 机器人的右侧仅开放工具带槽位(1-5)。
  • 机器人的其余所有面仅开放主物品栏槽位(5-n)。

移动

机器人能够灵活移动,但你应该了解一点细节。

悬停

机器人有飞行高度限制。机器人移动的基本规则是这样的:

  • 1. 机器人只有在起点和目标点均可用时才会移动(例如用于建桥)。
  • 2. 机器人下方一定可用(一定可以向下移动)。
  • 3. 固体方块上至多flightHeight格是可用的(飞行能力有限,默认为8)
  • 4. 任何紧贴着实心面的位置都是可用的(机器人可以“爬墙”)。
    此处为一张可视化展示上述规则的图片(忽略了第二条规则,这会使图片变得混乱)

违反这些规则会导致机器人返回impossible move错误。

你可以安装悬浮升级以提升(1级)乃至很大程度上规避(2级)这个限制。或者你也可以在模组配置文件中禁用这个限制,只要将limitFlightHeight设置为256或更高即可。

来源(英文)

API 特有方法

  • robot.name(): string
    返回机器人的名字。 机器人的名字在它被创造时会自动赋予,并且不能通过程序修改。但如果你想,可以用铁砧修改。

  • robot.detect(): boolean, string
    探测机器人正前方的物体并且返回机器人是否能移动过去,同时返回面前物体的描述。
    返回值:若机器人面前的物体会阻碍其移动(方块或者实体)则返回 true,否则返回 false(注意:即使面前的方块为passable,代表可穿越,无人机也会返回true)。第二个返回值大体描述前面的物体是什么,可能取值为;entitysolidreplaceableliquidpassable或者air

  • robot.detectUp(): boolean, string
    robot.detect()一样,但此函数探测机器人正上方的物体。

  • robot.detectDown(): boolean, string
    robot.detect()一样,但此函数探测机器人正下方的物体。

  • robot.select([slot: number]): number
    选定给定物品栏槽位(若指定),并返回当前选定物品栏槽位。
    slot - 要选定的物品栏槽位。若此参数省略,那么不会改动当前选定槽位。
    返回值:当前选定物品栏槽位。可能是给定物品栏槽位(若选择成功)或先前选定的物品栏槽位。

  • robot.inventorySize(): number
    返回值:可选定的物品栏槽位数量。想要获取安装的物品栏升级个数,可以使用这个公式:x = robot.inventorySize() / 16。

  • robot.count([slot: number]): number
    返回物品栏当前选定槽位或指定槽位里面物品栏的个数。
    slot - 指定要获取物品数的槽位。若省略则会对当前选定槽位的物品计数。
    返回值:指定槽位中物品的数量,或当前选定槽位中物品的数量(若没有指定槽位)。

  • robot.space([slot: number]):number
    返回在给定槽位装满之前还能装入多少物品。 slot - 指定要计算物品数的槽位。若省略则计算当前选定槽位。
    返回值:给定槽位或当前选定槽位在装满前还能装入多少物品。 此函数还能判断某种物品在单个槽位中的堆叠上限。例如圆石在每个槽位中能放64个,但是空桶在每个槽位中只能放16个,而有些方块,比如门,在每个槽位中只能放一个。

  • robot.transferTo(slot: number[, count: number]): boolean
    从当前选定槽位移动所有或是至多count个物品到指定槽位。
    slot - 指定承接物品的槽位。
    count - 若指定此参数,则最多移动此参数个物品,否则移动整个物品堆。
    返回值:若成功交换两个槽位中的物品则返回true,否则返回 false
    若指定槽位中有物品,此函数会尝试交换两个槽位中的物品。只有将当前选定槽位中的所有物品都移走或当前选中槽位本来就是空的才会成功。
    注意,若两个槽位中的物品相同或者两个格子都是空的,返回值一定是true,即使实际上没有移动任何东西。

  • robot.compareTo(slot: number):boolean
    比较物品栏当前选定槽位中的方块与给定槽位中的是否相同。
    slot - 指定要与当前选定槽位比较的槽位。
    返回值:若两个槽位中的物品种类相同则返回true,否则返回false
    若两个物品的种类和元数据相同,那么它们就被认定为“相同”。物品堆大小(物品数量)或其它额外信息(例如容器的物品栏)不会检查。

  • robot.compare(slot: number):boolean
    比较机器人正前方的方块与物品栏当前选定槽位中的方块,并返回它们是否相同。
    若两个方块的种类和元数据相同,那么它们就被认定为“相同”。物品堆大小(物品数量)或其它额外信息(例如容器的物品栏)不会检查。
    请注意,机器人前方如果是空的则会被游戏认为是“空气方块”,这种方块不能被放进物品栏,因此也不能使用一般方法比较。物品栏的空槽位与空气方块不同。你可以先使用robot.detect()来确认机器人前方是否真的有方块。
    还请记住,会掉落其它物品的方块应当和真正出现在世界上的方块比较(而非掉落物)。例如,石头方块掉落圆石,钻石矿石掉落钻石,对于这个函数来说它们并不相同。需要使用精准采集的工具开采实际的方块用于比较。

  • robot.compareUp(): boolean
    robot.compare()一样,但此函数比较机器人正上方的方块。

  • robot.compareDown(): boolean
    robot.compare()一样,但此函数比较机器人正下方的方块。

  • robot.drop([count: number]): boolean
    尝试从内部物品栏的当前选定槽位提取物品,并丢弃在机器人前方。注意,此方法不可用于将物品丢入机器人下方的物品容器,这种情况下需要使用dropDown方法。 此方法会将物品丢在面前
    count - 指定丢出多少物品。若省略此参数或其值超过了物品的数量,则所有物品都会被丢出。
    返回值:若至少丢除了一个物品则返回true,否则返回false
    如果机器人正前方的实体或方块有可访问的物品栏(例如箱子或运输矿车),机器人会尝试将物品放进物品栏中而不是丢弃到世界中。若面前的方块的确有物品栏,但是因为某种原因物品无法被放入其中,则此函数返回false且不会移动任何物品。物品被放置的位置取决于物品容器自身,以及机器人面对容器的哪个面。例如,熔炉从上方接收待烧炼物品。还请注意,其它机器人也会被认为是“带物品栏的方块”,所以物品也能被移入其它机器人的物品栏槽位,就像移入别的物品容器一样。
    此函数不能与非物品类型的容器互动(例如液体储罐),也不会将它们当作物品容器,因此物品会被扔到世界中。你需要使用robot.use函数与这些种类的方块互动。
    请注意若物品栏的当前选定槽位是空的,那么返回值一定为false

  • robot.dropUp(): boolean
    robot.drop()一样,但此函数把物品丢在机器人正上方。

  • robot.dropDown(): boolean
    robot.drop()一样,但此函数把物品丢在机器人正下方。

  • robot.suck([count: number]): boolean
    尝试从正前方拾起掉落物,并将其放入指定物品栏槽位或者(若槽位被占用)第一个可用的物品栏槽位。
    count - 拾起掉落物的数量上限。若省略,则会捡起最多一个物品堆。
    返回值:若捡起了至少一个物品则返回true,否则返回false
    此函数基本就是robot.drop的反向版,而且也会以相同的方式和物品容器互动。但是它只会拿走物品栏中的第一个可用物品。想要实现更精准的物品栏管理,你需要为机器人安装物品栏控制器升级
    若机器人面前有多个掉落物,则会根据距离远近捡起掉落物。此操作会跳过因为任意原因无法捡起的掉落物,并且在返回false之前先尝试捡起其它掉落物。
    若物品栏的当前选定槽位中有和机器人捡起的掉落物不同的物品,机器人会尝试将物品放在这个槽位之后的第一个可用槽位,要么是空槽位,要么是包含相同物品并且尚未达到堆叠上限的槽位。若必要,它会将拾起的物品分配到不同的槽位中。若当前选定槽位后没有可用槽位,此函数会执行失败,即使在选定槽位有能装下这些物品的槽位也是如此。

  • robot.suckUp([count: number]): boolean
    robot.suck()一样,但此函数会尝试捡起正上方的物品。

  • robot.suckDown([count: number]): boolean
    robot.suck()一样,但此函数尝试捡起正下方的物品。

  • robot.place([side: number[, sneaky: boolean]]): boolean[, string]
    尝试将物品栏选定槽位中的方块放置在机器人面前。
    side - 若指定,此参数决定机器人会尝试将方块放到哪个方向。例如,将火把放在特定表面上。若省略,机器人会尝试所有可能的方向。参见sides(方向) API以获取可能的方向列表。
    sneaky - 若设置为 true,机器人会模拟潜行放置方块(和玩家在放置时按住shift的效果相同)。这种操作通常没有必要,只是为了保证和其它模组的兼容性。
    返回值:若物品可以放置则返回 true,否则返回 false。若放置失败,第二个返回值会描述失败原因。
    机器人只能将方块放置到另一个固体方块的某个面上,而不能“放在空气中”,除非有天使升级。此特性可在配置文件中修改。
    请注意若物品栏槽位是空的,那么操作一定会失败。

  • robot.placeUp([side: number[, sneaky: boolean]]): boolean[, string]
    robot.place()一样,但此函数会尝试在正上方放置方块。

  • robot.placeDown([side: number[, sneaky: boolean]]): boolean[, string]
    robot.place()一样,但此函数会尝试在正下方放置方块。

  • robot.durability(): number, number, number or nil, string
    返回工具槽位中物品的耐久度剩余比例(小数)、当前耐久、最大耐久。
    若未装备物品或物品没有耐久值,此函数会返回nil以及一条描述为何不能返回耐久值的信息。报错信息可能为:no tool equipped(未装备物品)或tool cannot be damaged(物品不会损坏)。

  • robot.swing([side: number[, sneaky: boolean]]): boolean[, string]
    让机器人用当前在工具槽位中的物品对正前方的方块或空间交互,与玩家左键单击相同。
    side - 若指定,机器人只会尝试左键单击给定方向处的面,否则机器人会尝试单击所有可能的方向。参见sides(方向) API以获取可能方向的列表。
    返回值:若机器人可以和面前的方块或实体互动,返回true,否则返回false。若执行成功,第二个返回值代表机器人和什么东西互动了,取值可能为entity(实体)、block(方块)或fire(火)。
    此函数可用于开采方块或者攻击实体,就像玩家点击左键一样。请注意工具和武器会像被玩家使用一样减少耐久度,且最终需要被替换掉。如果可能,开采的方块或实体的掉落物会被放进机器人的物品栏中,否则会掉在地上。
    请注意,虽然动作会立刻完成(如方块被摧毁),这个函数还是会适当地等待一会来模拟玩家操作所需的时间。如果你尝试开采黑曜石,这个现象会很明显:它们立即就被破坏并且放入机器人的物品栏中,但函数还会等待几秒。
    如果此函数被用于开采方块,那么装备的工具必须足以开采机器人面前的方块。例如,如果用木镐开采黑曜石,函数会返回false。任何东西(包括空槽位)都能用于与生物战斗,但是伤害会基于所使用的物品。同样所有东西都能被用来灭火,且有耐久的工具也不会减少耐久值。

  • robot.swingUp([side: number[, sneaky: boolean]]): boolean[, string]
    robot.swing()一样,但此函数会将正上方的方块或实体当作目标。

  • robot.swingDown([side: number[, sneaky: boolean]]): boolean[, string]
    robot.swing()一样,但此函数会将正下方的方块或实体当作目标。

  • robot.use([side: number[, sneaky: boolean[, duration: number]]]): boolean[, string]
    尝试以玩家点击右键的方式对着前方使用当前工具栏里的工具。
    side - 如果给定,机器人只会尝试“右键”指定的面,否则机器人会尝试右键所有可能的面。参见 方向控制(sides) API 来获得可能的面的列表。
    sneaky - 如果设置为 true,机器人会模拟潜行点击右键(如同玩家按住 Shift 时点击右键)。某些物品(例如桶)在这时会有不同的行为。 duration - 这个物品被使用多长时间。这在使用例如弓之类的蓄力物品时很有用。
    返回值: 如果机器人可以和它面前的方块或实体互动返回真,否则返回假。如果成功,第二个返回值会描述机器人和什么东西互动了,它会是“方块已激活”、“物品已放置”、“和物品互动”或者“物品已使用”之一。
    这个函数有很广泛的应用,因为机器人能由此模拟右键点击大部分物品。和玩家唯一的不同在于机器人不能使用要求使用者必须是实体的物品,因为机器人是方块。所以喝药水、吃食物或者扔末影珍珠会失败。
    这个函数的第二个返回值可以被用于右键点击造成的结果。有些物品返回的结果并不总是明显的,它们需要事先测试。同样请注意尽管机器人不会被有害的药水伤害,它们仍然可以被爆炸炸毁,所以在你使用这个函数放置、扔出或激活任何爆炸物时,请务必小心。可能的第二个返回值是以下这些:
    • block_activated - 一个方块被激活了(例如拉杆、按钮或门)。
    • item_interacted - 装备的工具与世界互动了,例如用剪刀剪羊毛。
    • item_placed - 某些东西被放置在世界上了。这不仅仅由可放置的方块造成,还会由可以创造方块或实体的物品造成(例如打火石或刷怪蛋)。
    • item_used - 装备的物品被激活了,例如喷溅型药水。
    • air - 装备的物品要求有一个目标但是却没有。请注意,如果你的机器人有一个天使方块升级,这个值永远不会被返回,但是一些动作仍然不会有效果。
  • robot.useUp([side: number[, sneaky: boolean[, duration: number]]]): boolean[, string]
    robot.use() 一样,只是这个会瞄准机器人头顶的位置。
  • robot.useDown([side: number[, sneaky: boolean[, duration: number]]]): boolean[, string]
    robot.use() 一样,只是这个会瞄准机器人脚底的位置。
  • robot.forward(): boolean[, string]
    尝试将机器人向前移动。
    返回值:返回 true,如果机器人成功移动了,否则返回 nil。如果移动失败,第二个返回值会描述为什么失败,它会是“不可能的移动”、“没有足够能量”或者是 robot.detect 返回的障碍描述之一。
    返回值“没有足够能量”是极少见的,因为缺少能量通常会让机器人在那之前就关机了。
    返回值“不可能的移动”是一种回落(fall-back)结果,而且会在诸如机器人试图进入一片未加载区域等场合返回。
  • robot.back(): boolean[, string]
    robot.forward() 一样,只是这个会让机器人尝试向后移动。
  • robot.up(): boolean[, string]
    robot.forward() 一样,只是这个会让机器人尝试向上移动。
  • robot.down(): boolean[, string]
    robot.forward() 一样,只是这个会让机器人尝试向下移动。
  • robot.turnLeft()
    将机器人左转 90°。
    请注意,它只会在机器人没有足够能量左转但还没有关机时失败。
  • robot.turnRight()
    robot.turnLeft() 一样,只是这个会让机器人右转 90°。
  • robot.turnAround
    这和调用两次 robot.turnRight() 是一样的。
  • robot.level(): number
    自 OC 1.3 起已弃用。
    译者注:由于该 API 被弃用且暂无恢复计划,故略过不译,有需要者请自行查看英文文档。
  • robot.tankCount(): number
    机器人安装的液体储罐数量(number)。
  • robot.selectTank(tank)
    选择指定的液体储罐。这决定了大多数操作在哪个液体储罐上进行。
  • robot.tankLevel([tank:number]): number
    返回指定液体储罐的等级,如果没有指定,则返回当前液体储罐的等级。
  • robot.compareFluidTo(tank: number): boolean
    测试当前选定的液体储罐中的液体与给定的液体储罐中的液体是否相同。
  • robot.transferFluidTo(tank: number[, count: number]): boolean
    从当前选定的液体储罐转移指定数量的液体到给定的液体储罐。如果不指定数量,就会尝试转移 1000 mB。
  • robot.compareFluid(): boolean
    测试当前选定的液体储罐中的液体与机器人面前的液体储罐中的液体是否相同。
  • robot.compareFluidUp(): boolean
    robot.compareFluid() 一样,只是这个会比较机器人头顶的液体储罐。
  • robot.compareFluidDown(): boolean
    robot.compareFluid() 一样,只是这个会比较机器人脚底的液体储罐。
  • robot.drain([count: number]): boolean
    从机器人面前的液体储罐抽取指定数量的液体到选定的液体储罐中。当不指定数量时,会尝试转移 1000 mB。当抽取的液体是直接存在于世界上并且不能被完全储存于选定的液体储罐时,操作失败。没有液体会损失。
  • robot.drainUp([count: number]): boolean
    robot.drain() 一样,只是这个会抽取机器人头顶的液体。
  • robot.drainDown([count: number]): boolean
    robot.drain() 一样,只是这个会抽取机器人脚底的液体。
  • robot.fill([count: number]): boolean
    从选定的液体储罐中注入指定数量的液体到机器人面前的液体储罐。当不指定数量时,会尝试转移 1000 mB。当没有足够的液体来填充一个方块。或者目标储罐没有足够的空间,操作失败。没有液体会损失。
  • robot.fillUp([count: number]): boolean
    robot.fill() 一样,只是这个会向机器人头顶注入液体。
  • robot.fillDown([count: number]): boolean
    robot.fill() 一样,只是这个会向机器人脚底注入液体。

目录