Generate documentation stubs from Javadocs

illuaminate does not handle Java files, for obvious reasons. In order to
get around that, we have a series of stub files within /doc/stub which
mirrored the Java ones. While this works, it has a few problems:

 - The link to source code does not work - it just links to the stub
   file.
 - There's no guarantee that documentation remains consistent with the
   Java code. This change found several methods which were incorrectly
   documented beforehand.

We now replace this with a custom Java doclet[1], which extracts doc
comments from @LuaFunction annotated methods and generates stub-files
from them. These also contain a @source annotation, which allows us to
correctly link them back to the original Java code.

There's some issues with this which have yet to be fixed. However, I
don't think any of them are major blockers right now:

 - The custom doclet relies on Java 9 - I think it's /technically/
   possible to do this on Java 8, but the API is significantly uglier.
   This means that we need to run javadoc on a separate JVM.

   This is possible, and it works locally and on CI, but is definitely
   not a nice approach.

 - illuaminate now requires the doc stubs to be generated in order for
   the linter to pass, which does make running the linter locally much
   harder (especially given the above bullet point).

   We could notionally include the generated stubs (or at least a cut
   down version of them) in the repo, but I'm not 100% sure about that.

[1]: https://docs.oracle.com/javase/9/docs/api/jdk/javadoc/doclet/package-summary.html
This commit is contained in:
SquidDev 2020-07-03 13:31:26 +01:00
parent 36bb8b67c9
commit 9f8774960f
40 changed files with 935 additions and 743 deletions

View File

@ -10,10 +10,10 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
- name: Set up Java 8
uses: actions/setup-java@v1
with:
java-version: 1.8
java-version: 8
- name: Cache gradle dependencies
uses: actions/cache@v1
@ -35,12 +35,8 @@ jobs:
- name: Upload Coverage
run: bash <(curl -s https://codecov.io/bash)
lint-lua:
name: Lint Lua
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Generate Java documentation stubs
run: ./gradlew luaJavadoc --no-daemon
- name: Lint Lua code
run: |

View File

@ -17,6 +17,25 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: Set up Java 8
uses: actions/setup-java@v1
with:
java-version: 8
- name: Cache gradle dependencies
uses: actions/cache@v1
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build with Gradle
run: ./gradlew compileJava --no-daemon || ./gradlew compileJava --no-daemon
- name: Generate Java documentation stubs
run: ./gradlew luaJavadoc --no-daemon
- name: Build documentation
run: |
test -d bin || mkdir bin

1
.gitignore vendored
View File

@ -4,6 +4,7 @@
/build
/out
/doc/**/*.html
/doc/javadoc/
/doc/index.json
# Runtime directories

View File

@ -33,6 +33,8 @@
group = "org.squiddev"
archivesBaseName = "cc-tweaked-${mc_version}"
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
minecraft {
runs {
client {
@ -78,11 +80,14 @@
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
}
sourceSets.main.resources {
srcDir 'src/generated/resources'
sourceSets {
main.resources {
srcDir 'src/generated/resources'
}
}
repositories {
mavenCentral()
maven {
name "SquidDev"
url "https://squiddev.cc/maven"
@ -93,6 +98,7 @@ accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
shade
compile.extendsFrom shade
deployerJars
cctJavadoc
}
dependencies {
@ -115,6 +121,8 @@ accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
testImplementation 'org.hamcrest:hamcrest:2.2'
deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0"
cctJavadoc 'cc.tweaked:cct-javadoc:1.0.0'
}
// Compile tasks
@ -123,6 +131,24 @@ accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
include "dan200/computercraft/api/**/*.java"
}
task luaJavadoc(type: Javadoc) {
description "Generates documentation for Java-side Lua functions."
group "documentation"
source = sourceSets.main.allJava
destinationDir = file("doc/javadoc")
classpath = sourceSets.main.compileClasspath
options.docletpath = configurations.cctJavadoc.files as List
options.doclet = "cc.tweaked.javadoc.LuaDoclet"
// Attempt to run under Java 11 (any Java >= 9 will work though).
if(System.getProperty("java.version").startsWith("1.")
&& (System.getenv("JAVA_HOME_11_X64") != null || project.hasProperty("java11Home"))) {
executable = "${System.getenv("JAVA_HOME_11_X64") ?: project.property("java11Home")}/bin/javadoc"
}
}
jar {
dependsOn javadoc
@ -149,8 +175,6 @@ accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
}
}
import java.nio.charset.StandardCharsets
import java.nio.file.*
import java.util.zip.*

View File

@ -9,4 +9,7 @@
<!-- Do not check for missing package Javadoc. -->
<suppress checks="JavadocStyle" files=".*[\\/]package-info.java" />
<!-- The commands API is documented in Lua. -->
<suppress checks="SummaryJavadocCheck" files=".*[\\/]CommandAPI.java" />
</suppressions>

View File

@ -1,77 +0,0 @@
--- Execute a specific command.
--
-- @tparam string command The command to execute.
-- @treturn boolean Whether the command executed successfully.
-- @treturn { string... } The output of this command, as a list of lines.
-- @treturn number|nil The number of "affected" objects, or `nil` if the command
-- failed. The definition of this varies from command to command.
-- @usage Set the block above the command computer to stone.
--
-- commands.exec("setblock ~ ~1 ~ minecraft:stone")
function exec(command) end
--- Asynchronously execute a command.
--
-- Unlike @{exec}, this will immediately return, instead of waiting for the
-- command to execute. This allows you to run multiple commands at the same
-- time.
--
-- When this command has finished executing, it will queue a `task_complete`
-- event containing the result of executing this command (what @{exec} would
-- return).
--
-- @tparam string command The command to execute.
-- @treturn number The "task id". When this command has been executed, it will
-- queue a `task_complete` event with a matching id.
-- @usage Asynchronously sets the block above the computer to stone.
--
-- commands.execAsync("~ ~1 ~ minecraft:stone")
-- @see parallel One may also use the parallel API to run multiple commands at
-- once.
function execAsync(commad) end
--- List all available commands which the computer has permission to execute.
--
-- @treturn { string... } A list of all available commands
function list() end
--- Get the position of the current command computer.
--
-- @treturn number This computer's x position.
-- @treturn number This computer's y position.
-- @treturn number This computer's z position.
-- @see gps.locate To get the position of a non-command computer.
function getBlockPosition() end
--- Get some basic information about a block.
--
-- The returned table contains the current name, metadata and block state (as
-- with @{turtle.inspect}). If there is a tile entity for that block, its NBT
-- will also be returned.
--
-- @tparam number x The x position of the block to query.
-- @tparam number y The y position of the block to query.
-- @tparam number z The z position of the block to query.
-- @treturn table The given block's information.
-- @throws If the coordinates are not within the world, or are not currently
-- loaded.
function getBlockInfo(x, y, z) end
--- Get information about a range of blocks.
--
-- This returns the same information as @{getBlockInfo}, just for multiple
-- blocks at once.
--
-- Blocks are traversed by ascending y level, followed by z and x - the returned
-- table may be indexed using `x + z*width + y*depth*depth`.
--
-- @tparam number min_x The start x coordinate of the range to query.
-- @tparam number min_y The start y coordinate of the range to query.
-- @tparam number min_z The start z coordinate of the range to query.
-- @tparam number max_x The end x coordinate of the range to query.
-- @tparam number max_y The end y coordinate of the range to query.
-- @tparam number max_z The end z coordinate of the range to query.
-- @treturn { table... } A list of information about each block.
-- @throws If the coordinates are not within the world.
-- @throws If trying to get information about more than 4096 blocks.
function getBlockInfos(min_x, min_y, min_z, max_x, max_y, max_z) end

View File

@ -1,27 +0,0 @@
--- A computer or turtle wrapped as a peripheral.
--
-- This allows for basic interaction with adjacent computers. Computers wrapped
-- as peripherals will have the type `computer` while turtles will be `turtle`.
--
-- @module[kind=peripheral] computer
function turnOn() end --- Turn the other computer on.
function shutdown() end --- Shutdown the other computer.
function reboot() end --- Reboot or turn on the other computer.
--- Get the other computer's ID.
--
-- @treturn number The computer's ID.
-- @see os.getComputerID To get your computer ID.
function getID() end
--- Determine if the other computer is on.
--
-- @treturn boolean If the computer is on.
function isOn() end
--- Get the other computer's label.
--
-- @treturn string|nil The computer's label.
-- @see os.getComputerLabel To get your label.
function getLabel() end

View File

@ -1,12 +0,0 @@
--- @module[kind=peripheral] drive
function isDiskPresent() end
function getDiskLabel() end
function setDiskLabel(label) end
function hasData() end
function getMountPath() end
function hasAudio() end
function getAudioTitle() end
function playAudio() end
function ejectDisk() end
function getDiskID() end

View File

@ -2,23 +2,6 @@
--
-- @module fs
function list(path) end
function combine(base, child) end
function getName(path) end
function getSize(path) end
function exists(path) end
function isDir(path) end
function isReadOnly(path) end
function makeDir(path) end
function move(from, to) end
function copy(from, to) end
function delete(path) end
function open(path, mode) end
function getDrive(path) end
function getFreeSpace(path) end
function find(pattern) end
function getDir(path) end
--- Returns true if a path is mounted to the parent filesystem.
--
-- The root filesystem "/" is considered a mount, along with disk folders and
@ -31,33 +14,6 @@ function getDir(path) end
-- @see getDrive
function isDriveRoot(path) end
--- Get the capacity of the drive at the given path.
--
-- This may be used in conjunction with @{getFreeSpace} to determine what
-- percentage of this drive has been used.
--
-- @tparam string path The path of the drive to get.
-- @treturn number This drive's capacity. This will be 0 for "read-only" drives,
-- such as the ROM or treasure disks.
function getCapacity(path) end
--- Get attributes about a specific file or folder.
--
-- The returned attributes table contains information about the size of the
-- file, whether it is a directory, and when it was created and last modified.
--
-- The creation and modification times are given as the number of milliseconds
-- since the UNIX epoch. This may be given to @{os.date} in order to convert it
-- to more usable form.
--
-- @tparam string path The path to get attributes for.
-- @treturn { size = number, isDir = boolean, created = number, modified = number }
-- The resulting attributes.
-- @throws If the path does not exist.
-- @see getSize If you only care about the file's size.
-- @see isDir If you only care whether a path is a directory or not.
function attributes(path) end
-- Defined in bios.lua
function complete(sPath, sLocation, bIncludeFiles, bIncludeDirs) end

View File

@ -198,32 +198,3 @@ function websocket(url, headers) end
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
-- of the initial websocket connection.
function websocketAsync(url, headers) end
--- A websocket, which can be used to send an receive messages with a web
-- server.
--
-- @type Websocket
-- @see http.websocket On how to open a websocket.
local Websocket = {}
--- Send a websocket message to the connected server.
--
-- @tparam string message The message to send.
-- @tparam[opt] boolean binary Whether this message should be treated as a
-- binary string, rather than encoded text.
-- @throws If the websocket has been closed.
function Websocket.send(message, binary) end
--- Wait for a message from the server.
--
-- @tparam[opt] number timeout The number of seconds to wait if no message is
-- received.
-- @treturn[1] string The received message.
-- @treturn boolean If this was a binary message.
-- @treturn[2] nil If the websocket was closed while waiting, or if we timed out.
-- @throws If the websocket has been closed.
function Websocket.receive(timeout) end
--- Close this websocket. This will terminate the connection, meaning messages
-- can no longer be sent or received along it.
function Websocket.close() end

View File

@ -1,73 +0,0 @@
--- @module[kind=peripheral] modem
function open(channel) end
function isOpen(channel) end
function close(channel) end
--- Close all open channels.
function closeAll() end
function transmit(channel, replyChannel, payload) end
--- Determine if this is a wired or wireless modem.
--
-- Some methods (namely those dealing with wired networks and remote
-- peripherals) are only available on wired modems.
--
-- @treturn boolean @{true} if this is a wireless modem.
function isWireless() end
-- Wired modem only
--- List all remote peripherals on the wired network.
--
-- If this computer is attached to the network, it _will not_ be included in
-- this list.
--
-- > **Important:** This function only appears on wired modems. Check
-- > @{isWireless} returns false before calling it.
--
-- @treturn { string... } Remote peripheral names on the network.
function getNamesRemote(name) end
--- Determine if a peripheral is available on this wired network.
--
-- > **Important:** This function only appears on wired modems. Check
-- > @{isWireless} returns false before calling it.
--
-- @tparam string name The peripheral's name.
-- @treturn boolean If a peripheral is present with the given name.
-- @see peripheral.isPresent
function isPresentRemote(name) end
--- Get the type of a peripheral is available on this wired network.
--
-- > **Important:** This function only appears on wired modems. Check
-- > @{isWireless} returns false before calling it.
--
-- @tparam string name The peripheral's name.
-- @treturn string|nil The peripheral's type, or `nil` if it is not present.
-- @see peripheral.getType
function getTypeRemote(name) end
--- Call a method on a peripheral on this wired network.
--
-- > **Important:** This function only appears on wired modems. Check
-- > @{isWireless} returns false before calling it.
--
-- @tparam string remoteName The name of the peripheral to invoke the method on.
-- @tparam string method The name of the method
-- @param ... Additional arguments to pass to the method
-- @return The return values of the peripheral method.
-- @see peripheral.call
function callRemote(remoteName, method, ...) end
--- Returns the network name of the current computer, if the modem is on. This
-- may be used by other computers on the network to wrap this computer as a
-- peripheral.
--
-- > **Important:** This function only appears on wired modems. Check
-- > @{isWireless} returns false before calling it.
--
-- @treturn string|nil The current computer's name on the wired network.
function getNameLocal() end

View File

@ -1,32 +0,0 @@
--[[- Monitors are a block which act as a terminal, displaying information on
one side. This allows them to be read and interacted with in-world without
opening a GUI.
Monitors act as @{term.Redirect|terminal redirects} and so expose the same
methods, as well as several additional ones, which are documented below.
Like computers, monitors come in both normal (no colour) and advanced (colour)
varieties.
@module[kind=peripheral] monitor
@usage Write "Hello, world!" to an adjacent monitor:
local monitor = peripheral.find("monitor")
monitor.setCursorPos(1, 1)
monitor.write("Hello, world!")
]]
--- Set the scale of this monitor. A larger scale will result in the monitor
-- having a lower resolution, but display text much larger.
--
-- @tparam number scale The monitor's scale. This must be a multiple of 0.5
-- between 0.5 and 5.
-- @throws If the scale is out of range.
-- @see getTextScale
function setTextScale(scale) end
--- Get the monitor's current text scale.
--
-- @treturn number The monitor's current scale.
function getTextScale() end

View File

@ -1,21 +1,3 @@
function queueEvent(event, ...) end
function startTimer(delay) end
function setAlarm(time) end
function shutdown() end
function reboot() end
function getComputerID() end
computerID = getComputerID
function setComputerLabel(label) end
function getComputerLabel() end
computerLabel = getComputerLabel
function clock() end
function time(timezone) end
function day(timezone) end
function cancelTimer(id) end
function cancelAlarm(id) end
function epoch(timezone) end
function date(format, time) end
-- Defined in bios.lua
function loadAPI(path) end
function pullEvent(filter) end

View File

@ -1,28 +0,0 @@
--[[-
Control the current pocket computer, adding or removing upgrades.
This API is only available on pocket computers. As such, you may use its
presence to determine what kind of computer you are using:
```lua
if pocket then
print("On a pocket computer")
else
print("On something else")
end
```
]]
--- Search the player's inventory for another upgrade, replacing the existing
-- one with that item if found.
--
-- This inventory search starts from the player's currently selected slot,
-- allowing you to prioritise upgrades.
--
-- @throws If an upgrade cannot be found.
function equipBack() end
--- Remove the pocket computer's current upgrade.
--
-- @throws If this pocket computer does not currently have an upgrade.
function unequipBack() end

View File

@ -1,11 +0,0 @@
--- @module[kind=peripheral] printer
function write(text) end
function getCursorPos() end
function setCursorPos(x, y) end
function getPageSize() end
function newPage() end
function endPage() end
function setPageTitle(title) end
function getInkLevel() end
function getPaperLevel() end

View File

@ -1,120 +0,0 @@
--[[- Interact with redstone attached to this computer.
The @{redstone} library exposes three "types" of redstone control:
- Binary input/output (@{setOutput}/@{getInput}): These simply check if a
redstone wire has any input or output. A signal strength of 1 and 15 are
treated the same.
- Analogue input/output (@{setAnalogueOutput}/@{getAnalogueInput}): These
work with the actual signal strength of the redstone wired, from 0 to 15.
- Bundled cables (@{setBundledOutput}/@{getBundledInput}): These interact with
"bundled" cables, such as those from Project:Red. These allow you to send
16 separate on/off signals. Each channel corresponds to a colour, with the
first being @{colors.white} and the last @{colors.black}.
Whenever a redstone input changes, a `redstone` event will be fired. This may
be used in or
This module may also be referred to as `rs`. For example, one may call
`rs.getSides()` instead of @{redstone.getSides}.
@module redstone
@usage Toggle the redstone signal above the computer every 0.5 seconds.
while true do
redstone.setOutput("top", not redstone.getOutput("top"))
sleep(0.5)
end
@usage Mimic a redstone comparator in [subtraction mode][comparator].
while true do
local rear = rs.getAnalogueInput("back")
local sides = math.max(rs.getAnalogueInput("left"), rs.getAnalogueInput("right"))
rs.setAnalogueOutput("front", math.max(rear - sides, 0))
os.pullEvent("redstone") -- Wait for a change to inputs.
end
[comparator]: https://minecraft.gamepedia.com/Redstone_Comparator#Subtract_signal_strength "Redstone Comparator on the Minecraft wiki."
]]
--- Returns a table containing the six sides of the computer. Namely, "top",
-- "bottom", "left", "right", "front" and "back".
--
-- @treturn { string... } A table of valid sides.
function getSides() end
--- Turn the redstone signal of a specific side on or off.
--
-- @tparam string side The side to set.
-- @tparam boolean on Whether the redstone signal should be on or off. When on,
-- a signal strength of 15 is emitted.
function setOutput(side, on) end
--- Get the current redstone output of a specific side.
--
-- @tparam string side The side to get.
-- @treturn boolean Whether the redstone output is on or off.
-- @see setOutput
function getOutput(side) end
--- Get the current redstone input of a specific side.
--
-- @tparam string side The side to get.
-- @treturn boolean Whether the redstone input is on or off.
function getInput(side) end
--- Set the redstone signal strength for a specific side.
--
-- @tparam string side The side to set.
-- @tparam number value The signal strength, between 0 and 15.
-- @throws If `value` is not between 0 and 15.
function setAnalogOutput(side, value) end
setAnalogueOutput = setAnalogOutput
--- Get the redstone output signal strength for a specific side.
--
-- @tparam string side The side to get.
-- @treturn number The output signal strength, between 0 and 15.
-- @see setAnalogueOutput
function getAnalogOutput(sid) end
getAnalogueOutput = getAnalogOutput
--- Get the redstone input signal strength for a specific side.
--
-- @tparam string side The side to get.
-- @treturn number The input signal strength, between 0 and 15.
function getAnalogInput(side) end
getAnalogueInput = getAnalogInput
--- Set the bundled cable output for a specific side.
--
-- @tparam string side The side to set.
-- @tparam number The colour bitmask to set.
-- @see colors.subtract For removing a colour from the bitmask.
-- @see colors.combine For adding a colour to the bitmask.
function setBundledOutput(side, output) end
--- Get the bundled cable output for a specific side.
--
-- @tparam string side The side to get.
-- @treturn number The bundled cable's output.
function getBundledOutput(side) end
--- Get the bundled cable input for a specific side.
--
-- @tparam string side The side to get.
-- @treturn number The bundled cable's input.
-- @see testBundledInput To determine if a specific colour is set.
function getBundledInput(side) end
--- Determine if a specific combination of colours are on for the given side.
--
-- @tparam string side The side to test.
-- @tparam number mask The mask to test.
-- @see getBundledInput
-- @see colors.combine For adding a colour to the bitmask.
-- @usage Check if @{colors.white} and @{colors.black} are on for above the
-- computer.
--
-- print(redstone.testBundledInput("top", colors.combine(colors.white, colors.black)))
function testBundledInput(side, mask) end

View File

@ -21,8 +21,6 @@ function setPaletteColour(colour, ...) end
setPaletteColor = setPaletteColour
function getPaletteColour(colour, ...) end
getPaletteColor = getPaletteColour
function nativePaletteColour(colour) end
nativePaletteColor = nativePaletteColour
--- @type Redirect
local Redirect = {}

View File

@ -1,231 +1 @@
--- Move the turtle forward one block.
-- @treturn boolean Whether the turtle could successfully move.
-- @treturn string|nil The reason the turtle could not move.
function forward() end
--- Move the turtle backwards one block.
-- @treturn boolean Whether the turtle could successfully move.
-- @treturn string|nil The reason the turtle could not move.
function back() end
--- Move the turtle up one block.
-- @treturn boolean Whether the turtle could successfully move.
-- @treturn string|nil The reason the turtle could not move.
function up() end
--- Move the turtle down one block.
-- @treturn boolean Whether the turtle could successfully move.
-- @treturn string|nil The reason the turtle could not move.
function down() end
--- Rotate the turtle 90 degress to the left.
function turnLeft() end
--- Rotate the turtle 90 degress to the right.
function turnRight() end
--- Attempt to break the block in front of the turtle.
--
-- This requires a turtle tool capable of breaking the block. Diamond pickaxes
-- (mining turtles) can break any vanilla block, but other tools (such as axes)
-- are more limited.
--
-- @tparam[opt] "left"|"right" side The specific tool to use.
-- @treturn boolean Whether a block was broken.
-- @treturn string|nil The reason no block was broken.
function dig(side) end
--- Attempt to break the block above the turtle. See @{dig} for full details.
--
-- @tparam[opt] "left"|"right" side The specific tool to use.
-- @treturn boolean Whether a block was broken.
-- @treturn string|nil The reason no block was broken.
function digUp(side) end
--- Attempt to break the block below the turtle. See @{dig} for full details.
--
-- @tparam[opt] "left"|"right" side The specific tool to use.
-- @treturn boolean Whether a block was broken.
-- @treturn string|nil The reason no block was broken.
function digDown(side) end
--- Attack the entity in front of the turtle.
--
-- @tparam[opt] "left"|"right" side The specific tool to use.
-- @treturn boolean Whether an entity was attacked.
-- @treturn string|nil The reason nothing was attacked.
function attack(side) end
--- Attack the entity above the turtle.
--
-- @tparam[opt] "left"|"right" side The specific tool to use.
-- @treturn boolean Whether an entity was attacked.
-- @treturn string|nil The reason nothing was attacked.
function attackUp(side) end
--- Attack the entity below the turtle.
--
-- @tparam[opt] "left"|"right" side The specific tool to use.
-- @treturn boolean Whether an entity was attacked.
-- @treturn string|nil The reason nothing was attacked.
function attackDown(side) end
--- Place a block or item into the world in front of the turtle.
--
-- @treturn boolean Whether the block could be placed.
-- @treturn string|nil The reason the block was not placed.
function place() end
--- Place a block or item into the world above the turtle.
--
-- @treturn boolean Whether the block could be placed.
-- @treturn string|nil The reason the block was not placed.
function placeUp() end
--- Place a block or item into the world below the turtle.
--
-- @treturn boolean Whether the block could be placed.
-- @treturn string|nil The reason the block was not placed.
function placeDown() end
--- Drop the currently selected stack into the inventory in front of the turtle,
-- or as an item into the world if there is no inventory.
--
-- @tparam[opt] number count The number of items to drop. If not given, the
-- entire stack will be dropped.
-- @treturn boolean Whether items were dropped.
-- @treturn string|nil The reason the no items were dropped.
-- @see select
function drop(count) end
--- Drop the currently selected stack into the inventory above the turtle, or as
-- an item into the world if there is no inventory.
--
-- @tparam[opt] number count The number of items to drop. If not given, the
-- entire stack will be dropped.
-- @treturn boolean Whether items were dropped.
-- @treturn string|nil The reason the no items were dropped.
-- @see select
function dropUp(count) end
--- Drop the currently selected stack into the inventory below the turtle, or as
-- an item into the world if there is no inventory.
--
-- @tparam[opt] number count The number of items to drop. If not given, the
-- entire stack will be dropped.
-- @treturn boolean Whether items were dropped.
-- @treturn string|nil The reason the no items were dropped.
-- @see select
function dropDown(count) end
--- Suck an item from the inventory in front of the turtle, or from an item
-- floating in the world.
--
-- This will pull items into the first acceptable slot, starting at the
-- @{select|currently selected} one.
--
-- @tparam[opt] number count The number of items to suck. If not given, up to a
-- stack of items will be picked up.
-- @treturn boolean Whether items were picked up.
-- @treturn string|nil The reason the no items were picked up.
function suck(count) end
--- Suck an item from the inventory above the turtle, or from an item floating
-- in the world.
--
-- @tparam[opt] number count The number of items to suck. If not given, up to a
-- stack of items will be picked up.
-- @treturn boolean Whether items were picked up.
-- @treturn string|nil The reason the no items were picked up.
function suckUp(count) end
--- Suck an item from the inventory below the turtle, or from an item floating
-- in the world.
--
-- @tparam[opt] number count The number of items to suck. If not given, up to a
-- stack of items will be picked up.
-- @treturn boolean Whether items were picked up.
-- @treturn string|nil The reason the no items were picked up.
function suckDown(count) end
--- Check if there is a solid block in front of the turtle. In this case, solid
-- refers to any non-air or liquid block.
--
-- @treturn boolean If there is a solid block in front.
function detect() end
--- Check if there is a solid block above the turtle.
--
-- @treturn boolean If there is a solid block above.
function detectUp() end
--- Check if there is a solid block below the turtle.
--
-- @treturn boolean If there is a solid block below.
function detectDown() end
function compare() end
function compareUp() end
function compareDown() end
function inspect() end
function inspectUp() end
function inspectDown() end
--- Change the currently selected slot.
--
-- The selected slot is determines what slot actions like @{drop} or
-- @{getItemCount} act on.
--
-- @tparam number slot The slot to select.
-- @see getSelectedSlot
function select(slot) end
--- Get the currently selected slot.
--
-- @treturn number The current slot.
-- @see select
function getSelectedSlot() end
--- Get the number of items in the given slot.
--
-- @tparam[opt] number slot The slot we wish to check. Defaults to the @{turtle.select|selected slot}.
-- @treturn number The number of items in this slot.
function getItemCount(slot) end
--- Get the remaining number of items which may be stored in this stack.
--
-- For instance, if a slot contains 13 blocks of dirt, it has room for another 51.
--
-- @tparam[opt] number slot The slot we wish to check. Defaults to the @{turtle.select|selected slot}.
-- @treturn number The space left in this slot.
function getItemSpace(slot) end
--- Get detailed information about the items in the given slot.
--
-- @tparam[opt] number slot The slot to get information about. Defaults to the @{turtle.select|selected slot}.
-- @tparam[opt] boolean detailed Whether to include "detailed" information. When @{true} the method will contain
-- much more information about the item at the cost of taking longer to run.
-- @treturn nil|table Information about the given slot, or @{nil} if it is empty.
-- @usage Print the current slot, assuming it contains 13 dirt.
--
-- print(textutils.serialize(turtle.getItemDetail()))
-- -- => {
-- -- name = "minecraft:dirt",
-- -- count = 13,
-- -- }
function getItemDetail(slot, detailed) end
function getFuelLevel() end
function refuel(count) end
function compareTo(slot) end
function transferTo(slot, count) end
function getFuelLimit() end
function equipLeft() end
function equipRight() end
function craft(limit) end

View File

@ -2,6 +2,7 @@
(sources
/doc/stub/
/doc/javadoc/
/src/main/resources/*/computercraft/lua/bios.lua
/src/main/resources/*/computercraft/lua/rom/
/src/test/resources/test-rom)
@ -17,6 +18,7 @@
(library-path
/doc/stub/
/doc/javadoc/
/src/main/resources/*/computercraft/lua/rom/apis
/src/main/resources/*/computercraft/lua/rom/apis/command
@ -67,7 +69,7 @@
(lint (allow-toplevel-global true)))
;; Silence some variable warnings in documentation stubs.
(at /doc/stub
(at (/doc/stub/ /doc/javadoc/)
(linters -var:unused-global)
(lint (allow-toplevel-global true)))
@ -79,15 +81,20 @@
/doc/stub/os.lua
/doc/stub/term.lua
/doc/stub/turtle.lua
; Java generated APIs
/doc/javadoc/fs.lua
/doc/javadoc/http.lua
/doc/javadoc/os.lua
/doc/javadoc/turtle.lua
; Peripherals
/doc/stub/drive.lua
/doc/stub/modem.lua
/doc/stub/printer.lua
/doc/javadoc/drive.lua
/doc/javadoc/speaker.lua
/doc/javadoc/printer.lua
; Lua APIs
/src/main/resources/*/computercraft/lua/rom/apis/io.lua
/src/main/resources/*/computercraft/lua/rom/apis/window.lua)
(linters -doc:undocumented -doc:undocumented-arg))
(linters -doc:undocumented -doc:undocumented-arg -doc:undocumented-return))
;; These currently rely on unknown references.
(at

View File

@ -28,6 +28,11 @@
import java.util.OptionalLong;
import java.util.function.Function;
/**
* The FS API allows you to manipulate files and the filesystem.
*
* @cc.module fs
*/
public class FSAPI implements ILuaAPI
{
private final IAPIEnvironment environment;
@ -291,6 +296,19 @@ public final String[] find( String path ) throws LuaException
}
}
/**
* Returns true if a path is mounted to the parent filesystem.
*
* The root filesystem "/" is considered a mount, along with disk folders and the rom folder. Other programs
* (such as network shares) can extend this to make other mount types by correctly assigning their return value for
* getDrive.
*
* @param path The path of the drive to get.
* @return The drive's capacity.
* @throws LuaException If the capacity cannot be determined.
* @cc.treturn number|nil This drive's capacity. This will be nil for "read-only" drives, such as the ROM or
* treasure disks.
*/
@LuaFunction
public final Object getCapacity( String path ) throws LuaException
{
@ -305,6 +323,22 @@ public final Object getCapacity( String path ) throws LuaException
}
}
/**
* Get attributes about a specific file or folder.
*
* The returned attributes table contains information about the size of the file, whether it is a directory, and
* when it was created and last modified.
*
* The creation and modification times are given as the number of milliseconds since the UNIX epoch. This may be
* given to {@link OSAPI#date} in order to convert it to more usable form.
*
* @param path The path to get attributes for.
* @return The resulting attributes.
* @throws LuaException If the path does not exist.
* @cc.treturn { size = number, isDir = boolean, created = number, modified = number } The resulting attributes.
* @see #getSize If you only care about the file's size.
* @see #isDir If you only care whether a path is a directory or not.
*/
@LuaFunction
public final Map<String, Object> attributes( String path ) throws LuaException
{

View File

@ -26,6 +26,12 @@
import static dan200.computercraft.core.apis.TableHelper.*;
/**
* The http library allows communicating with web servers, sending and receiving data from them.
*
* @cc.module http
* @hidden
*/
public class HTTPAPI implements ILuaAPI
{
private final IAPIEnvironment m_apiEnvironment;

View File

@ -23,6 +23,11 @@
import static dan200.computercraft.api.lua.LuaValues.checkFinite;
/**
* The {@link OSAPI} API allows interacting with the current computer.
*
* @cc.module os
*/
public class OSAPI implements ILuaAPI
{
private final IAPIEnvironment apiEnvironment;
@ -213,6 +218,11 @@ public final Object[] getComputerLabel()
return label == null ? null : new Object[] { label };
}
/**
* Set the label of this computer.
*
* @param label The new label. May be {@code nil} in order to clear it.
*/
@LuaFunction
public final void setComputerLabel( Optional<String> label )
{

View File

@ -22,6 +22,12 @@
import javax.annotation.Nullable;
import java.util.*;
/**
* CC's "native" peripheral API. This is wrapped within CraftOS to provide a version which works with modems.
*
* @cc.module peripheral
* @hidden
*/
public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChangeListener
{
private class PeripheralWrapper extends ComputerAccess

View File

@ -10,6 +10,48 @@
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.computer.ComputerSide;
/**
* Interact with redstone attached to this computer.
*
* The {@link RedstoneAPI} library exposes three "types" of redstone control:
* - Binary input/output ({@link #setOutput}/{@link #getInput}): These simply check if a redstone wire has any input or
* output. A signal strength of 1 and 15 are treated the same.
* - Analogue input/output ({@link #setAnalogOutput}/{@link #getAnalogInput}): These work with the actual signal
* strength of the redstone wired, from 0 to 15.
* - Bundled cables ({@link #setBundledOutput}/{@link #getBundledInput}): These interact with "bundled" cables, such
* as those from Project:Red. These allow you to send 16 separate on/off signals. Each channel corresponds to a
* colour, with the first being @{colors.white} and the last @{colors.black}.
*
* Whenever a redstone input changes, a {@code redstone} event will be fired. This may be used instead of repeativly
* polling.
*
* This module may also be referred to as {@code rs}. For example, one may call {@code rs.getSides()} instead of
* {@link #getSides}.
*
* @cc.usage Toggle the redstone signal above the computer every 0.5 seconds.
*
* <pre>
* while true do
* redstone.setOutput("top", not redstone.getOutput("top"))
* sleep(0.5)
* end
* </pre>
* @cc.usage Mimic a redstone comparator in [subtraction mode][comparator].
*
* <pre>
* while true do
* local rear = rs.getAnalogueInput("back")
* local sides = math.max(rs.getAnalogueInput("left"), rs.getAnalogueInput("right"))
* rs.setAnalogueOutput("front", math.max(rear - sides, 0))
*
* os.pullEvent("redstone") -- Wait for a change to inputs.
* end
* </pre>
*
* [comparator]: https://minecraft.gamepedia.com/Redstone_Comparator#Subtract_signal_strength "Redstone Comparator on
* the Minecraft wiki."
* @cc.module redstone
*/
public class RedstoneAPI implements ILuaAPI
{
private final IAPIEnvironment environment;
@ -25,67 +67,145 @@ public String[] getNames()
return new String[] { "rs", "redstone" };
}
/**
* Returns a table containing the six sides of the computer. Namely, "top", "bottom", "left", "right", "front" and
* "back".
*
* @return A table of valid sides.
*/
@LuaFunction
public final String[] getSides()
{
return ComputerSide.NAMES;
}
/**
* Turn the redstone signal of a specific side on or off.
*
* @param side The side to set.
* @param on Whether the redstone signal should be on or off. When on, a signal strength of 15 is emitted.
*/
@LuaFunction
public final void setOutput( ComputerSide side, boolean output )
public final void setOutput( ComputerSide side, boolean on )
{
environment.setOutput( side, output ? 15 : 0 );
environment.setOutput( side, on ? 15 : 0 );
}
/**
* Get the current redstone output of a specific side.
*
* @param side The side to get.
* @return Whether the redstone output is on or off.
* @see #setOutput
*/
@LuaFunction
public final boolean getOutput( ComputerSide side )
{
return environment.getOutput( side ) > 0;
}
/**
* Get the current redstone input of a specific side.
*
* @param side The side to get.
* @return Whether the redstone input is on or off.
*/
@LuaFunction
public final boolean getInput( ComputerSide side )
{
return environment.getInput( side ) > 0;
}
/**
* Set the redstone signal strength for a specific side.
*
* @param side The side to set.
* @param value The signal strength between 0 and 15.
* @throws LuaException If {@code value} is not betwene 0 and 15.
*/
@LuaFunction( { "setAnalogOutput", "setAnalogueOutput" } )
public final void setAnalogOutput( ComputerSide side, int output ) throws LuaException
public final void setAnalogOutput( ComputerSide side, int value ) throws LuaException
{
if( output < 0 || output > 15 ) throw new LuaException( "Expected number in range 0-15" );
environment.setOutput( side, output );
if( value < 0 || value > 15 ) throw new LuaException( "Expected number in range 0-15" );
environment.setOutput( side, value );
}
/**
* Get the redstone output signal strength for a specific side.
*
* @param side The side to get.
* @return The output signal strength, between 0 and 15.
* @see #setAnalogOutput
*/
@LuaFunction( { "getAnalogOutput", "getAnalogueOutput" } )
public final int getAnalogOutput( ComputerSide side )
{
return environment.getOutput( side );
}
/**
* Get the redstone input signal strength for a specific side.
*
* @param side The side to get.
* @return The input signal strength, between 0 and 15.
*/
@LuaFunction( { "getAnalogInput", "getAnalogueInput" } )
public final int getAnalogInput( ComputerSide side )
{
return environment.getInput( side );
}
/**
* Set the bundled cable output for a specific side.
*
* @param side The side to set.
* @param output The colour bitmask to set.
* @cc.see colors.subtract For removing a colour from the bitmask.
* @cc.see colors.combine For adding a color to the bitmask.
*/
@LuaFunction
public final void setBundledOutput( ComputerSide side, int output )
{
environment.setBundledOutput( side, output );
}
/**
* Get the bundled cable output for a specific side.
*
* @param side The side to get.
* @return The bundle cable's output.
*/
@LuaFunction
public final int getBundledOutput( ComputerSide side )
{
return environment.getBundledOutput( side );
}
/**
* Get the bundled cable input for a specific side.
*
* @param side The side to get.
* @return The bundle cable's input.
* @see #testBundledInput To determine if a specific colour is set.
*/
@LuaFunction
public final int getBundledInput( ComputerSide side )
{
return environment.getBundledOutput( side );
}
/**
* Determine if a specific combination of colours are on for the given side.
*
* @param side The side to test.
* @param mask The mask to test.
* @return If the colours are on.
* @cc.usage Check if @{colors.white} and @{colors.black} are on above the computer.
* <pre>
* print(redstone.testBundledInput("top", colors.combine(colors.white, colors.black)))
* </pre>
* @see #getBundledInput
*/
@LuaFunction
public final boolean testBundledInput( ComputerSide side, int mask )
{

View File

@ -14,6 +14,11 @@
import javax.annotation.Nonnull;
/**
* The Terminal API provides functions for writing text to the terminal and monitors, and drawing ASCII graphics.
*
* @cc.module term
*/
public class TermAPI extends TermMethods implements ILuaAPI
{
private final Terminal terminal;
@ -31,11 +36,21 @@ public String[] getNames()
return new String[] { "term" };
}
/**
* Get the default palette value for a colour.
*
* @param colour The colour whose palette should be fetched.
* @return The RGB values.
* @throws LuaException When given an invalid colour.
* @cc.treturn number The red channel, will be between 0 and 1.
* @cc.treturn number The green channel, will be between 0 and 1.
* @cc.treturn number The blue channel, will be between 0 and 1.
*/
@LuaFunction( { "nativePaletteColour", "nativePaletteColor" } )
public final Object[] nativePaletteColour( int colourArg ) throws LuaException
public final Object[] nativePaletteColour( int colour ) throws LuaException
{
int colour = 15 - parseColour( colourArg );
Colour c = Colour.fromInt( colour );
int actualColour = 15 - parseColour( colour );
Colour c = Colour.fromInt( actualColour );
float[] rgb = c.getRGB();

View File

@ -18,6 +18,9 @@
/**
* A base class for all objects which interact with a terminal. Namely the {@link TermAPI} and monitors.
*
* @cc.module term.Redirect
* @hidden
*/
public abstract class TermMethods
{

View File

@ -25,6 +25,12 @@
import static dan200.computercraft.core.apis.http.websocket.Websocket.CLOSE_EVENT;
import static dan200.computercraft.core.apis.http.websocket.Websocket.MESSAGE_EVENT;
/**
* A websocket, which can be used to send an receive messages with a web server.
*
* @cc.module http.Websocket
* @see dan200.computercraft.core.apis.HTTPAPI#websocket On how to open a websocket.
*/
public class WebsocketHandle implements Closeable
{
private final Websocket websocket;
@ -40,8 +46,18 @@ public WebsocketHandle( Websocket websocket, Options options, Channel channel )
this.channel = channel;
}
/**
* Wait for a message from the server.
*
* @param timeout The number of seconds to wait if no message is received.
* @return The result of receiving.
* @throws LuaException If the websocket has been closed.
* @cc.treturn [1] string The received message.
* @cc.treturn boolean If this was a binary message.
* @cc.treturn [2] nil If the websocket was closed while waiting, or if we timed out.
*/
@LuaFunction
public final MethodResult result( Optional<Double> timeout ) throws LuaException
public final MethodResult receive( Optional<Double> timeout ) throws LuaException
{
checkOpen();
int timeoutId = timeout.isPresent()
@ -51,29 +67,40 @@ public final MethodResult result( Optional<Double> timeout ) throws LuaException
return new ReceiveCallback( timeoutId ).pull;
}
/**
* Send a websocket message to the connected server.
*
* @param message The message to send.
* @param binary Whether this message should be treated as a
* @throws LuaException If the message is too large.
* @throws LuaException If the websocket has been closed.
*/
@LuaFunction
public final void send( IArguments args ) throws LuaException
public final void send( Object message, Optional<Boolean> binary ) throws LuaException
{
checkOpen();
String text = StringUtil.toString( args.get( 0 ) );
String text = StringUtil.toString( message );
if( options.websocketMessage != 0 && text.length() > options.websocketMessage )
{
throw new LuaException( "Message is too large" );
}
boolean binary = args.optBoolean( 1, false );
websocket.environment().addTrackingChange( TrackingField.WEBSOCKET_OUTGOING, text.length() );
Channel channel = this.channel;
if( channel != null )
{
channel.writeAndFlush( binary
channel.writeAndFlush( binary.orElse( false )
? new BinaryWebSocketFrame( Unpooled.wrappedBuffer( LuaValues.encode( text ) ) )
: new TextWebSocketFrame( text ) );
}
}
/**
* Close this websocket. This will terminate the connection, meaning messages can no longer be sent or received
* along it.
*/
@LuaFunction( "close" )
public final void doClose()
{

View File

@ -194,9 +194,9 @@ private Optional<T> build( Method method )
if( bytes == null ) return Optional.empty();
Class<?> klass = DeclaringClassLoader.INSTANCE.define( className, bytes, method.getDeclaringClass().getProtectionDomain() );
return Optional.of( klass.asSubclass( base ).newInstance() );
return Optional.of( klass.asSubclass( base ).getDeclaredConstructor().newInstance() );
}
catch( InstantiationException | IllegalAccessException | ClassFormatError | RuntimeException e )
catch( ReflectiveOperationException | ClassFormatError | RuntimeException e )
{
ComputerCraft.log.error( "Error generating wrapper for {}.", name, e );
return Optional.empty();

View File

@ -23,6 +23,9 @@
import java.util.*;
/**
* @cc.module commands
*/
public class CommandAPI implements ILuaAPI
{
private final TileCommandComputer computer;
@ -78,18 +81,62 @@ private Object[] doCommand( String command )
return table;
}
/**
* Execute a specific command.
*
* @param command The command to execute.
* @return See {@code cc.treturn}.
* @cc.treturn boolean Whether the command executed successfully.
* @cc.treturn { string... } The output of this command, as a list of lines.
* @cc.treturn number|nil The number of "affected" objects, or `nil` if the command failed. The definition of this
* varies from command to command.
* @cc.usage Set the block above the command computer to stone.
* <pre>
* commands.exec("setblock ~ ~1 ~ minecraft:stone")
* </pre>
*/
@LuaFunction( mainThread = true )
public final Object[] exec( String command )
{
return doCommand( command );
}
/**
* Asynchronously execute a command.
*
* Unlike {@link #exec}, this will immediately return, instead of waiting for the
* command to execute. This allows you to run multiple commands at the same
* time.
*
* When this command has finished executing, it will queue a `task_complete`
* event containing the result of executing this command (what {@link #exec} would
* return).
*
* @param context The context this command executes under.
* @param command The command to execute.
* @return The "task id". When this command has been executed, it will queue a `task_complete` event with a matching id.
* @throws LuaException (hidden) If the task cannot be created.
* @cc.tparam string command The command to execute.
* @cc.usage Asynchronously sets the block above the computer to stone.
* <pre>
* commands.execAsync("~ ~1 ~ minecraft:stone")
* </pre>
* @cc.see parallel One may also use the parallel API to run multiple commands at once.
*/
@LuaFunction
public final long execAsync( ILuaContext context, String command ) throws LuaException
{
return context.issueMainThreadTask( () -> doCommand( command ) );
}
/**
* List all available commands which the computer has permission to execute.
*
* @param args Arguments to this function.
* @return A list of all available commands
* @throws LuaException (hidden) On non-string arguments.
* @cc.tparam string ... The sub-command to complete.
*/
@LuaFunction( mainThread = true )
public final List<String> list( IArguments args ) throws LuaException
{
@ -112,6 +159,15 @@ public final List<String> list( IArguments args ) throws LuaException
return result;
}
/**
* Get the position of the current command computer.
*
* @return The block's position.
* @cc.treturn number This computer's x position.
* @cc.treturn number This computer's y position.
* @cc.treturn number This computer's z position.
* @cc.see gps.locate To get the position of a non-command computer.
*/
@LuaFunction
public final Object[] getBlockPosition()
{
@ -120,6 +176,25 @@ public final Object[] getBlockPosition()
return new Object[] { pos.getX(), pos.getY(), pos.getZ() };
}
/**
* Get information about a range of blocks.
*
* This returns the same information as @{getBlockInfo}, just for multiple
* blocks at once.
*
* Blocks are traversed by ascending y level, followed by z and x - the returned
* table may be indexed using `x + z*width + y*depth*depth`.
*
* @param minX The start x coordinate of the range to query.
* @param minY The start y coordinate of the range to query.
* @param minZ The start z coordinate of the range to query.
* @param maxX The end x coordinate of the range to query.
* @param maxY The end y coordinate of the range to query.
* @param maxZ The end z coordinate of the range to query.
* @return A list of information about each block.
* @throws LuaException If the coordinates are not within the world.
* @throws LuaException If trying to get information about more than 4096 blocks.
*/
@LuaFunction( mainThread = true )
public final List<Map<?, ?>> getBlockInfos( int minX, int minY, int minZ, int maxX, int maxY, int maxZ ) throws LuaException
{
@ -159,6 +234,19 @@ public final Object[] getBlockPosition()
return results;
}
/**
* Get some basic information about a block.
*
* The returned table contains the current name, metadata and block state (as
* with @{turtle.inspect}). If there is a tile entity for that block, its NBT
* will also be returned.
*
* @param x The x position of the block to query.
* @param y The y position of the block to query.
* @param z The z position of the block to query.
* @return The given block's information.
* @throws LuaException If the coordinates are not within the world, or are not currently loaded.
*/
@LuaFunction( mainThread = true )
public final Map<?, ?> getBlockInfo( int x, int y, int z ) throws LuaException
{

View File

@ -7,9 +7,19 @@
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.apis.OSAPI;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* A computer or turtle wrapped as a peripheral.
*
* This allows for basic interaction with adjacent computers. Computers wrapped as peripherals will have the type
* {@code computer} while turtles will be {@code turtle}.
*
* @cc.module computer
*/
public class ComputerPeripheral implements IPeripheral
{
private final String type;
@ -28,36 +38,63 @@ public String getType()
return type;
}
/**
* Turn the other computer on.
*/
@LuaFunction
public final void turnOn()
{
computer.turnOn();
}
/**
* Shutdown the other computer.
*/
@LuaFunction
public final void shutdown()
{
computer.shutdown();
}
/**
* Reboot or turn on the other computer.
*/
@LuaFunction
public final void reboot()
{
computer.reboot();
}
/**
* Get the other computer's ID.
*
* @return The computer's ID.
* @see OSAPI#getComputerID() To get your computer's ID.
*/
@LuaFunction
public final int getID()
{
return computer.assignID();
}
/**
* Determine if the other computer is on.
*
* @return If the computer is on.
*/
@LuaFunction
public final boolean isOn()
{
return computer.isOn();
}
/**
* Get the other computer's label.
*
* @return The computer's label.
* @see OSAPI#getComputerLabel() To get your label.
*/
@Nullable
@LuaFunction
public final String getLabel()
{

View File

@ -8,6 +8,7 @@
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.computer.apis.CommandAPI;
import dan200.computercraft.shared.util.CapabilityUtil;
import net.minecraft.tileentity.CommandBlockTileEntity;
import net.minecraft.tileentity.TileEntity;
@ -25,6 +26,16 @@
import static dan200.computercraft.shared.Capabilities.CAPABILITY_PERIPHERAL;
/**
* This peripheral allows you to interact with command blocks.
*
* Command blocks are only wrapped as peripherals if the {@literal enable_command_block} option is true within the
* config.
*
* This API is <em>not</em> the same as the {@link CommandAPI} API, which is exposed on command computers.
*
* @cc.module command
*/
@Mod.EventBusSubscriber
public class CommandBlockPeripheral implements IPeripheral, ICapabilityProvider
{
@ -45,12 +56,22 @@ public String getType()
return "command";
}
/**
* Get the command this command block will run.
*
* @return The current command.
*/
@LuaFunction( mainThread = true )
public final String getCommand()
{
return commandBlock.getCommandBlockLogic().getCommand();
}
/**
* Set the command block's command.
*
* @param command The new command.
*/
@LuaFunction( mainThread = true )
public final void setCommand( String command )
{
@ -58,8 +79,15 @@ public final void setCommand( String command )
commandBlock.getCommandBlockLogic().updateCommand();
}
/**
* Execute the command block once.
*
* @return The result of executing.
* @cc.treturn boolean If the command completed successfully.
* @cc.treturn string|nil A failure message.
*/
@LuaFunction( mainThread = true )
public final Object runCommand()
public final Object[] runCommand()
{
commandBlock.getCommandBlockLogic().trigger( commandBlock.getWorld() );
int result = commandBlock.getCommandBlockLogic().getSuccessCount();

View File

@ -18,6 +18,19 @@
import javax.annotation.Nonnull;
import java.util.Optional;
/**
* Disk drives are a peripheral which allow you to read and write to floppy disks and other "mountable media" (such as
* computers or turtles). They also allow you to {@link #playAudio play records}.
*
* When a disk drive attaches some mount (such as a floppy disk or computer), it attaches a folder called {@code disk},
* {@code disk2}, etc... to the root directory of the computer. This folder can be used to interact with the files on
* that disk.
*
* When a disk is inserted, a {@code disk} event is fired, with the side peripheral is on. Likewise, when the disk is
* detached, a {@code disk_eject} event is fired.
*
* @cc.module drive
*/
public class DiskDrivePeripheral implements IPeripheral
{
private final TileDiskDrive diskDrive;

View File

@ -20,6 +20,11 @@
import java.util.HashSet;
import java.util.Set;
/**
* The modem peripheral allows you to send messages between computers.
*
* @cc.module modem
*/
public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPacketReceiver
{
private IPacketNetwork m_network;
@ -100,30 +105,65 @@ private static int parseChannel( int channel ) throws LuaException
return channel;
}
/**
* Open a channel on a modem. A channel must be open in order to receive messages. Modems can have up to 128
* channels open at one time.
*
* @param channel The channel to open. This must be a number between 0 and 65535.
* @throws LuaException If the channel is out of range.
* @throws LuaException If there are too many open channels.
*/
@LuaFunction
public final void open( int channel ) throws LuaException
{
m_state.open( parseChannel( channel ) );
}
/**
* Check if a channel is open.
*
* @param channel The channel to check.
* @return Whether the channel is open.
* @throws LuaException If the channel is out of range.
*/
@LuaFunction
public final boolean isOpen( int channel ) throws LuaException
{
return m_state.isOpen( parseChannel( channel ) );
}
/**
* Close an open channel, meaning it will no longer receive messages.
*
* @param channel The channel to close.
* @throws LuaException If the channel is out of range.
*/
@LuaFunction
public final void close( int channel ) throws LuaException
{
m_state.close( parseChannel( channel ) );
}
/**
* Close all open channels.
*/
@LuaFunction
public final void closeAll()
{
m_state.closeAll();
}
/**
* Sends a modem message on a certain channel. Modems listening on the channel will queue a {@code modem_message}
* event on adjacent computers.
*
* <blockquote><strong>Note:</strong> The channel does not need be open to send a message.</blockquote>
*
* @param channel The channel to send messages on.
* @param replyChannel The channel that responses to this message should be sent on.
* @param payload The object to send. This can be a string, number, or table.
* @throws LuaException If the channel is out of range.
*/
@LuaFunction
public final void transmit( int channel, int replyChannel, Object payload ) throws LuaException
{
@ -147,6 +187,14 @@ public final void transmit( int channel, int replyChannel, Object payload ) thro
}
}
/**
* Determine if this is a wired or wireless modem.
*
* Some methods (namely those dealing with wired networks and remote peripherals) are only available on wired
* modems.
*
* @return {@code true} if this is a wireless modem.
*/
@LuaFunction
public final boolean isWireless()
{

View File

@ -73,18 +73,54 @@ public World getWorld()
//endregion
//region Peripheral methods
/**
* List all remote peripherals on the wired network.
*
* If this computer is attached to the network, it _will not_ be included in
* this list.
*
* <blockquote><strong>Important:</strong> This function only appears on wired modems. Check {@link #isWireless}
* returns false before calling it.</blockquote>
*
* @param computer The calling computer.
* @return Remote peripheral names on the network.
*/
@LuaFunction
public final Collection<String> getNamesRemote( IComputerAccess computer )
{
return getWrappers( computer ).keySet();
}
/**
* Determine if a peripheral is available on this wired network.
*
* <blockquote><strong>Important:</strong> This function only appears on wired modems. Check {@link #isWireless}
* returns false before calling it.</blockquote>
*
* @param computer The calling computer.
* @param name The peripheral's name.
* @return boolean If a peripheral is present with the given name.
* @see PeripheralAPI#isPresent
*/
@LuaFunction
public final boolean isPresentRemote( IComputerAccess computer, String name )
{
return getWrapper( computer, name ) != null;
}
/**
* Get the type of a peripheral is available on this wired network.
*
* <blockquote><strong>Important:</strong> This function only appears on wired modems. Check {@link #isWireless}
* returns false before calling it.</blockquote>
*
* @param computer The calling computer.
* @param name The peripheral's name.
* @return The peripheral's name.
* @cc.treturn string|nil The peripheral's type, or {@code nil} if it is not present.
* @see PeripheralAPI#getType
*/
@LuaFunction
public final Object[] getTypeRemote( IComputerAccess computer, String name )
{
@ -92,6 +128,17 @@ public final Object[] getTypeRemote( IComputerAccess computer, String name )
return wrapper != null ? new Object[] { wrapper.getType() } : null;
}
/**
* Get all available methods for the remote peripheral with the given name.
*
* <blockquote><strong>Important:</strong> This function only appears on wired modems. Check {@link #isWireless}
* returns false before calling it.</blockquote>
*
* @param computer The calling computer.
* @param name The peripheral's name.
* @return A list of methods provided by this peripheral, or {@code nil} if it is not present.
* @see PeripheralAPI#getMethods
*/
@LuaFunction
public final Object[] getMethodsRemote( IComputerAccess computer, String name )
{
@ -101,6 +148,23 @@ public final Object[] getMethodsRemote( IComputerAccess computer, String name )
return new Object[] { wrapper.getMethodNames() };
}
/**
* Call a method on a peripheral on this wired network.
*
* <blockquote><strong>Important:</strong> This function only appears on wired modems. Check {@link #isWireless}
* returns false before calling it.</blockquote>
*
* @param computer The calling computer.
* @param context The Lua context we're executing in.
* @param arguments Arguments to this computer.
* @return The peripheral's result.
* @throws LuaException (hidden) If the method throws an error.
* @cc.tparam string remoteName The name of the peripheral to invoke the method on.
* @cc.tparam string method The name of the method
* @cc.param ... Additional arguments to pass to the method
* @cc.treturn string The return values of the peripheral method.
* @see PeripheralAPI#call
*/
@LuaFunction
public final MethodResult callRemote( IComputerAccess computer, ILuaContext context, IArguments arguments ) throws LuaException
{
@ -112,6 +176,17 @@ public final MethodResult callRemote( IComputerAccess computer, ILuaContext cont
return wrapper.callMethod( context, methodName, arguments.drop( 2 ) );
}
/**
* Returns the network name of the current computer, if the modem is on. This
* may be used by other computers on the network to wrap this computer as a
* peripheral.
*
* <blockquote><strong>Important:</strong> This function only appears on wired modems. Check {@link #isWireless}
* returns false before calling it.</blockquote>
*
* @return The current computer's name.
* @cc.treturn string|nil The current computer's name on the wired network.
*/
@LuaFunction
public final Object[] getNameLocal()
{

View File

@ -16,6 +16,24 @@
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Monitors are a block which act as a terminal, displaying information on one side. This allows them to be read and
* interacted with in-world without opening a GUI.
*
* Monitors act as @{term.Redirect|terminal redirects} and so expose the same methods, as well as several additional
* ones, which are documented below.
*
* Like computers, monitors come in both normal (no colour) and advanced (colour) varieties.
*
* @cc.module monitor
* @cc.usage Write "Hello, world!" to an adjacent monitor:
*
* <pre>
* local monitor = peripheral.find("monitor")
* monitor.setCursorPos(1, 1)
* monitor.write("Hello, world!")
* </pre>
*/
public class MonitorPeripheral extends TermMethods implements IPeripheral
{
private final TileMonitor monitor;
@ -32,6 +50,14 @@ public String getType()
return "monitor";
}
/**
* Set the scale of this monitor. A larger scale will result in the monitor having a lower resolution, but display
* text much larger.
*
* @param scaleArg The monitor's scale. This must be a multiple of 0.5 between 0.5 and 5.
* @throws LuaException If the scale is out of range.
* @see #getTextScale()
*/
@LuaFunction
public final void setTextScale( double scaleArg ) throws LuaException
{
@ -40,6 +66,12 @@ public final void setTextScale( double scaleArg ) throws LuaException
getMonitor().setTextScale( scale );
}
/**
* Get the monitor's current text scale.
*
* @return The monitor's current scale.
* @throws LuaException If the monitor cannot be found.
*/
@LuaFunction
public final double getTextScale() throws LuaException
{

View File

@ -15,6 +15,11 @@
import javax.annotation.Nonnull;
import java.util.Optional;
/**
* The printer peripheral allows pages and books to be printed.
*
* @cc.module printer
*/
public class PrinterPeripheral implements IPeripheral
{
private final TilePrinter printer;

View File

@ -25,6 +25,11 @@
import static dan200.computercraft.api.lua.LuaValues.checkFinite;
/**
* Speakers allow playing notes and other sounds.
*
* @cc.module speaker
*/
public abstract class SpeakerPeripheral implements IPeripheral
{
private long m_clock = 0;

View File

@ -19,6 +19,22 @@
import net.minecraft.util.NonNullList;
import net.minecraftforge.items.wrapper.PlayerMainInvWrapper;
/**
* Control the current pocket computer, adding or removing upgrades.
*
* This API is only available on pocket computers. As such, you may use its presence to determine what kind of computer
* you are using:
*
* <pre>
* if pocket then
* print("On a pocket computer")
* else
* print("On something else")
* end
* </pre>
*
* @cc.module pocket
*/
public class PocketAPI implements ILuaAPI
{
private final PocketServerComputer computer;
@ -34,6 +50,15 @@ public String[] getNames()
return new String[] { "pocket" };
}
/**
* Search the player's inventory for another upgrade, replacing the existing one with that item if found.
*
* This inventory search starts from the player's currently selected slot, allowing you to prioritise upgrades.
*
* @return The result of equipping.
* @cc.treturn boolean If an item was equipped.
* @cc.treturn string|nil The reason an item was not equipped.
*/
@LuaFunction( mainThread = true )
public final Object[] equipBack()
{
@ -72,6 +97,13 @@ public final Object[] equipBack()
return new Object[] { true };
}
/**
* Remove the pocket computer's current upgrade.
*
* @return The result of unequipping.
* @cc.treturn boolean If the upgrade was unequipped.
* @cc.treturn string|nil The reason an upgrade was not unequipped.
*/
@LuaFunction( mainThread = true )
public final Object[] unequipBack()
{

View File

@ -24,6 +24,11 @@
import java.util.Map;
import java.util.Optional;
/**
* The turtle API allows you to control your turtle.
*
* @cc.module turtle
*/
public class TurtleAPI implements ILuaAPI
{
private final IAPIEnvironment environment;
@ -47,42 +52,92 @@ private MethodResult trackCommand( ITurtleCommand command )
return turtle.executeCommand( command );
}
/**
* Move the turtle forward one block.
*
* @return The turtle command result.
* @cc.treturn boolean Whether the turtle could successfully move.
* @cc.treturn string|nil The reason the turtle could not move.
*/
@LuaFunction
public final MethodResult forward()
{
return trackCommand( new TurtleMoveCommand( MoveDirection.FORWARD ) );
}
/**
* Move the turtle backwards one block.
*
* @return The turtle command result.
* @cc.treturn boolean Whether the turtle could successfully move.
* @cc.treturn string|nil The reason the turtle could not move.
*/
@LuaFunction
public final MethodResult back()
{
return trackCommand( new TurtleMoveCommand( MoveDirection.BACK ) );
}
/**
* Move the turtle up one block.
*
* @return The turtle command result.
* @cc.treturn boolean Whether the turtle could successfully move.
* @cc.treturn string|nil The reason the turtle could not move.
*/
@LuaFunction
public final MethodResult up()
{
return trackCommand( new TurtleMoveCommand( MoveDirection.UP ) );
}
/**
* Move the turtle down one block.
*
* @return The turtle command result.
* @cc.treturn boolean Whether the turtle could successfully move.
* @cc.treturn string|nil The reason the turtle could not move.
*/
@LuaFunction
public final MethodResult down()
{
return trackCommand( new TurtleMoveCommand( MoveDirection.DOWN ) );
}
/**
* Rotate the turtle 90 degress to the left.
*
* @return The turtle command result.
*/
@LuaFunction
public final MethodResult turnLeft()
{
return trackCommand( new TurtleTurnCommand( TurnDirection.LEFT ) );
}
/**
* Rotate the turtle 90 degress to the right.
*
* @return The turtle command result.
*/
@LuaFunction
public final MethodResult turnRight()
{
return trackCommand( new TurtleTurnCommand( TurnDirection.RIGHT ) );
}
/**
* Attempt to break the block in front of the turtle.
*
* This requires a turtle tool capable of breaking the block. Diamond pickaxes
* (mining turtles) can break any vanilla block, but other tools (such as axes)
* are more limited.
*
* @param side The specific tool to use. Should be "left" or "right".
* @return The turtle command result.
* @cc.treturn boolean Whether a block was broken.
* @cc.treturn string|nil The reason no block was broken.
*/
@LuaFunction
public final MethodResult dig( Optional<TurtleSide> side )
{
@ -90,6 +145,14 @@ public final MethodResult dig( Optional<TurtleSide> side )
return trackCommand( TurtleToolCommand.dig( InteractDirection.FORWARD, side.orElse( null ) ) );
}
/**
* Attempt to break the block above the turtle. See {@link #dig} for full details.
*
* @param side The specific tool to use.
* @return The turtle command result.
* @cc.treturn boolean Whether a block was broken.
* @cc.treturn string|nil The reason no block was broken.
*/
@LuaFunction
public final MethodResult digUp( Optional<TurtleSide> side )
{
@ -97,6 +160,14 @@ public final MethodResult digUp( Optional<TurtleSide> side )
return trackCommand( TurtleToolCommand.dig( InteractDirection.UP, side.orElse( null ) ) );
}
/**
* Attempt to break the block below the turtle. See {@link #dig} for full details.
*
* @param side The specific tool to use.
* @return The turtle command result.
* @cc.treturn boolean Whether a block was broken.
* @cc.treturn string|nil The reason no block was broken.
*/
@LuaFunction
public final MethodResult digDown( Optional<TurtleSide> side )
{
@ -104,42 +175,113 @@ public final MethodResult digDown( Optional<TurtleSide> side )
return trackCommand( TurtleToolCommand.dig( InteractDirection.DOWN, side.orElse( null ) ) );
}
/**
* Place a block or item into the world in front of the turtle.
*
* @param args Arguments to place.
* @return The turtle command result.
* @cc.tparam [opt] string text When placing a sign, set its contents to this text.
* @cc.treturn boolean Whether the block could be placed.
* @cc.treturn string|nil The reason the block was not placed.
*/
@LuaFunction
public final MethodResult place( IArguments args )
{
return trackCommand( new TurtlePlaceCommand( InteractDirection.FORWARD, args.getAll() ) );
}
/**
* Place a block or item into the world above the turtle.
*
* @param args Arguments to place.
* @return The turtle command result.
* @cc.tparam [opt] string text When placing a sign, set its contents to this text.
* @cc.treturn boolean Whether the block could be placed.
* @cc.treturn string|nil The reason the block was not placed.
*/
@LuaFunction
public final MethodResult placeUp( IArguments args )
{
return trackCommand( new TurtlePlaceCommand( InteractDirection.UP, args.getAll() ) );
}
/**
* Place a block or item into the world below the turtle.
*
* @param args Arguments to place.
* @return The turtle command result.
* @cc.tparam [opt] string text When placing a sign, set its contents to this text.
* @cc.treturn boolean Whether the block could be placed.
* @cc.treturn string|nil The reason the block was not placed.
*/
@LuaFunction
public final MethodResult placeDown( IArguments args )
{
return trackCommand( new TurtlePlaceCommand( InteractDirection.DOWN, args.getAll() ) );
}
/**
* Drop the currently selected stack into the inventory in front of the turtle, or as an item into the world if
* there is no inventory.
*
* @param count The number of items to drop. If not given, the entire stack will be dropped.
* @return The turtle command result.
* @throws LuaException If dropping an invalid number of items.
* @cc.treturn boolean Whether items were dropped.
* @cc.treturn string|nil The reason the no items were dropped.
* @see #select
*/
@LuaFunction
public final MethodResult drop( Optional<Integer> count ) throws LuaException
{
return trackCommand( new TurtleDropCommand( InteractDirection.FORWARD, checkCount( count ) ) );
}
/**
* Drop the currently selected stack into the inventory above the turtle, or as an item into the world if there is
* no inventory.
*
* @param count The number of items to drop. If not given, the entire stack will be dropped.
* @return The turtle command result.
* @throws LuaException If dropping an invalid number of items.
* @cc.treturn boolean Whether items were dropped.
* @cc.treturn string|nil The reason the no items were dropped.
* @see #select
*/
@LuaFunction
public final MethodResult dropUp( Optional<Integer> count ) throws LuaException
{
return trackCommand( new TurtleDropCommand( InteractDirection.UP, checkCount( count ) ) );
}
/**
* Drop the currently selected stack into the inventory in front of the turtle, or as an item into the world if
* there is no inventory.
*
* @param count The number of items to drop. If not given, the entire stack will be dropped.
* @return The turtle command result.
* @throws LuaException If dropping an invalid number of items.
* @cc.treturn boolean Whether items were dropped.
* @cc.treturn string|nil The reason the no items were dropped.
* @see #select
*/
@LuaFunction
public final MethodResult dropDown( Optional<Integer> count ) throws LuaException
{
return trackCommand( new TurtleDropCommand( InteractDirection.DOWN, checkCount( count ) ) );
}
/**
* Change the currently selected slot.
*
* The selected slot is determines what slot actions like {@link #drop} or {@link #getItemCount} act on.
*
* @param slot The slot to select.
* @return The turtle command result.
* @throws LuaException If the slot is out of range.
* @see #getSelectedSlot
*/
@LuaFunction
public final MethodResult select( int slot ) throws LuaException
{
@ -150,6 +292,13 @@ public final MethodResult select( int slot ) throws LuaException
} );
}
/**
* Get the number of items in the given slot.
*
* @param slot The slot we wish to check. Defaults to the {@link #select selected slot}.
* @return The number of items in this slot.
* @throws LuaException If the slot is out of range.
*/
@LuaFunction
public final int getItemCount( Optional<Integer> slot ) throws LuaException
{
@ -157,6 +306,15 @@ public final int getItemCount( Optional<Integer> slot ) throws LuaException
return turtle.getInventory().getStackInSlot( actualSlot ).getCount();
}
/**
* Get the remaining number of items which may be stored in this stack.
*
* For instance, if a slot contains 13 blocks of dirt, it has room for another 51.
*
* @param slot The slot we wish to check. Defaults to the {@link #select selected slot}.
* @return The space left in in this slot.
* @throws LuaException If the slot is out of range.
*/
@LuaFunction
public final int getItemSpace( Optional<Integer> slot ) throws LuaException
{
@ -165,18 +323,37 @@ public final int getItemSpace( Optional<Integer> slot ) throws LuaException
return stack.isEmpty() ? 64 : Math.min( stack.getMaxStackSize(), 64 ) - stack.getCount();
}
/**
* Check if there is a solid block in front of the turtle. In this case, solid refers to any non-air or liquid
* block.
*
* @return The turtle command result.
* @cc.treturn boolean If there is a solid block in front.
*/
@LuaFunction
public final MethodResult detect()
{
return trackCommand( new TurtleDetectCommand( InteractDirection.FORWARD ) );
}
/**
* Check if there is a solid block above the turtle. In this case, solid refers to any non-air or liquid block.
*
* @return The turtle command result.
* @cc.treturn boolean If there is a solid block in front.
*/
@LuaFunction
public final MethodResult detectUp()
{
return trackCommand( new TurtleDetectCommand( InteractDirection.UP ) );
}
/**
* Check if there is a solid block below the turtle. In this case, solid refers to any non-air or liquid block.
*
* @return The turtle command result.
* @cc.treturn boolean If there is a solid block in front.
*/
@LuaFunction
public final MethodResult detectDown()
{
@ -201,36 +378,89 @@ public final MethodResult compareDown()
return trackCommand( new TurtleCompareCommand( InteractDirection.DOWN ) );
}
/**
* Attack the entity in front of the turtle.
*
* @param side The specific tool to use.
* @return The turtle command result.
* @cc.treturn boolean Whether an entity was attacked.
* @cc.treturn string|nil The reason nothing was attacked.
*/
@LuaFunction
public final MethodResult attack( Optional<TurtleSide> side )
{
return trackCommand( TurtleToolCommand.attack( InteractDirection.FORWARD, side.orElse( null ) ) );
}
/**
* Attack the entity above the turtle.
*
* @param side The specific tool to use.
* @return The turtle command result.
* @cc.treturn boolean Whether an entity was attacked.
* @cc.treturn string|nil The reason nothing was attacked.
*/
@LuaFunction
public final MethodResult attackUp( Optional<TurtleSide> side )
{
return trackCommand( TurtleToolCommand.attack( InteractDirection.UP, side.orElse( null ) ) );
}
/**
* Attack the entity below the turtle.
*
* @param side The specific tool to use.
* @return The turtle command result.
* @cc.treturn boolean Whether an entity was attacked.
* @cc.treturn string|nil The reason nothing was attacked.
*/
@LuaFunction
public final MethodResult attackDown( Optional<TurtleSide> side )
{
return trackCommand( TurtleToolCommand.attack( InteractDirection.DOWN, side.orElse( null ) ) );
}
/**
* Suck an item from the inventory in front of the turtle, or from an item floating in the world.
*
* This will pull items into the first acceptable slot, starting at the {@link #select currently selected} one.
*
* @param count The number of items to suck. If not given, up to a stack of items will be picked up.
* @return The turtle command result.
* @throws LuaException If given an invalid number of items.
* @cc.treturn boolean Whether items were picked up.
* @cc.treturn string|nil The reason the no items were picked up.
*/
@LuaFunction
public final MethodResult suck( Optional<Integer> count ) throws LuaException
{
return trackCommand( new TurtleSuckCommand( InteractDirection.FORWARD, checkCount( count ) ) );
}
/**
* Suck an item from the inventory above the turtle, or from an item floating in the world.
*
* @param count The number of items to suck. If not given, up to a stack of items will be picked up.
* @return The turtle command result.
* @throws LuaException If given an invalid number of items.
* @cc.treturn boolean Whether items were picked up.
* @cc.treturn string|nil The reason the no items were picked up.
*/
@LuaFunction
public final MethodResult suckUp( Optional<Integer> count ) throws LuaException
{
return trackCommand( new TurtleSuckCommand( InteractDirection.UP, checkCount( count ) ) );
}
/**
* Suck an item from the inventory below the turtle, or from an item floating in the world.
*
* @param count The number of items to suck. If not given, up to a stack of items will be picked up.
* @return The turtle command result.
* @throws LuaException If given an invalid number of items.
* @cc.treturn boolean Whether items were picked up.
* @cc.treturn string|nil The reason the no items were picked up.
*/
@LuaFunction
public final MethodResult suckDown( Optional<Integer> count ) throws LuaException
{
@ -265,6 +495,12 @@ public final MethodResult transferTo( int slotArg, Optional<Integer> countArg )
return trackCommand( new TurtleTransferToCommand( slot, count ) );
}
/**
* Get the currently sleected slot.
*
* @return The current slot.
* @see #select
*/
@LuaFunction
public final int getSelectedSlot()
{
@ -307,15 +543,33 @@ public final MethodResult inspectDown()
return trackCommand( new TurtleInspectCommand( InteractDirection.DOWN ) );
}
/**
* Get detailed information about the items in the given slot.
*
* @param context The Lua context
* @param slot The slot to get information about. Defaults to the {@link #select selected slot}.
* @param detailed Whether to include "detailed" information. When {@code true} the method will contain much
* more information about the item at the cost of taking longer to run.
* @return The command result.
* @throws LuaException If the slot is out of range.
* @cc.treturn nil|table Information about the given slot, or {@code nil} if it is empty.
* @cc.usage Print the current slot, assuming it contains 13 dirt.
*
* <pre>{@code
* print(textutils.serialize(turtle.getItemDetail()))
* -- => {
* -- name = "minecraft:dirt",
* -- count = 13,
* -- }
* }</pre>
*/
@LuaFunction
public final MethodResult getItemDetail( ILuaContext context, Optional<Integer> slotArg, Optional<Boolean> detailedArg ) throws LuaException
public final MethodResult getItemDetail( ILuaContext context, Optional<Integer> slot, Optional<Boolean> detailed ) throws LuaException
{
int slot = checkSlot( slotArg ).orElse( turtle.getSelectedSlot() );
boolean detailed = detailedArg.orElse( false );
return detailed
? TaskCallback.make( context, () -> getItemDetail( slot, true ) )
: MethodResult.of( getItemDetail( slot, false ) );
int actualSlot = checkSlot( slot ).orElse( turtle.getSelectedSlot() );
return detailed.orElse( false )
? TaskCallback.make( context, () -> getItemDetail( actualSlot, true ) )
: MethodResult.of( getItemDetail( actualSlot, false ) );
}
private Object[] getItemDetail( int slot, boolean detailed )

View File

@ -15,6 +15,13 @@
import javax.annotation.Nonnull;
import java.util.Optional;
/**
* The workbench peripheral allows you to craft items within the turtle's inventory.
*
* @cc.module workbench
* @hidden
* @cc.see turtle.craft This uses the {@link CraftingTablePeripheral} peripheral to craft items.
*/
public class CraftingTablePeripheral implements IPeripheral
{
private final ITurtleAccess turtle;