mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-14 12:10:30 +00:00
Merge branch 'mc-1.15.x' into mc-1.16.x
This commit is contained in:
commit
0be030c497
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1,2 +1,3 @@
|
||||
# Ignore changes in generated files
|
||||
src/generated/resources/data/** linguist-generated
|
||||
src/test/server-files/structures linguist-generated
|
||||
|
9
.github/workflows/main-ci.yml
vendored
9
.github/workflows/main-ci.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
java-version: 8
|
||||
|
||||
- name: Cache gradle dependencies
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
|
||||
@ -24,10 +24,13 @@ jobs:
|
||||
${{ runner.os }}-gradle-
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build --no-daemon || ./gradlew build --no-daemon
|
||||
run: |
|
||||
./gradlew assemble --no-daemon || ./gradlew assemble --no-daemon
|
||||
./gradlew downloadAssets --no-daemon || ./gradlew downloadAssets --no-daemon
|
||||
./gradlew build
|
||||
|
||||
- name: Upload Jar
|
||||
uses: actions/upload-artifact@v1
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: CC-Tweaked
|
||||
path: build/libs
|
||||
|
4
.github/workflows/make-doc.yml
vendored
4
.github/workflows/make-doc.yml
vendored
@ -11,7 +11,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Java 8
|
||||
uses: actions/setup-java@v1
|
||||
@ -19,7 +19,7 @@ jobs:
|
||||
java-version: 8
|
||||
|
||||
- name: Cache gradle dependencies
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
|
||||
|
@ -8,6 +8,10 @@ If you've any other questions, [just ask the community][community] or [open an i
|
||||
If you have a bug, suggestion, or other feedback, the best thing to do is [file an issue][new-issue]. When doing so,
|
||||
do use the issue templates - they provide a useful hint on what information to provide.
|
||||
|
||||
## Translations
|
||||
Translations are managed through [Weblate], an online interface for managing language strings. This is synced
|
||||
automatically with GitHub, so please don't submit PRs adding/changing translations!
|
||||
|
||||
## Developing
|
||||
In order to develop CC: Tweaked, you'll need to download the source code and then run it. This is a pretty simple
|
||||
process. When building on Windows, Use `gradlew.bat` instead of `./gradlew`.
|
||||
@ -20,6 +24,11 @@ If you want to run CC:T in a normal Minecraft instance, run `./gradlew build` an
|
||||
These commands may take a few minutes to run the first time, as the environment is set up, but should be much faster
|
||||
afterwards.
|
||||
|
||||
The following sections describe the more niche sections of CC: Tweaked's build system. Some bits of these are
|
||||
quite-complex, and (dare I say) over-engineered, so you may wish to ignore them. Well tested/documented PRs are always
|
||||
preferred (and I'd definitely recommend setting up the tooling if you're doing serious development work), but for
|
||||
small changes it can be a lot.
|
||||
|
||||
### Code linters
|
||||
CC: Tweaked uses a couple of "linters" on its source code, to enforce a consistent style across the project. While these
|
||||
are run whenever you submit a PR, it's often useful to run this before committing.
|
||||
@ -27,15 +36,83 @@ are run whenever you submit a PR, it's often useful to run this before committin
|
||||
- **[Checkstyle]:** Checks Java code to ensure it is consistently formatted. This can be run with `./gradlew build` or
|
||||
`./gradle check`.
|
||||
- **[illuaminate]:** Checks Lua code for semantic and styleistic issues. See [the usage section][illuaminate-usage] for
|
||||
how to download and run it.
|
||||
how to download and run it. You may need to generate the Java documentation stubs (see "Documentation" below) for all
|
||||
lints to pass.
|
||||
|
||||
## Translations
|
||||
Translations are managed through [Weblate], an online interface for managing language strings. This is synced
|
||||
automatically with GitHub, so please don't submit PRs adding/changing translations!
|
||||
### Documentation
|
||||
When writing documentation for [CC: Tweaked's documentation website][docs], it may be useful to build the documentation
|
||||
and preview it yourself before submitting a PR.
|
||||
|
||||
Building all documentation is, sadly, a multi-stage process (though this is largely hidden by Gradle). First we need to
|
||||
convert Java doc-comments into Lua ones, we also generate some Javascript to embed. All of this is then finally fed into
|
||||
illuaminate, which spits out our HTML.
|
||||
|
||||
#### Setting up the tooling
|
||||
For various reasons, getting the environment set up to build documentation can be pretty complex. I'd quite like to
|
||||
automate this via Docker and/or nix in the future, but this needs to be done manually for now.
|
||||
|
||||
First, you will need JDK 9+ (in addition to JDK 8 which is required to build Minecraft itself). Sadly our version of
|
||||
Gradle doesn't support multiple toolchains, and so you need to install this yourself.
|
||||
|
||||
Gradle needs to be told about this JDK via the `JAVA_HOME_11_X64` environment variable or adding `java11Home` to
|
||||
`~/.gradle/gradle.properties`. On my system this looks like:
|
||||
|
||||
```properties
|
||||
java11Home=/usr/lib/jvm/java-11-openjdk/
|
||||
```
|
||||
|
||||
If you just want to build the documentation stubs for linting, this is enough. However, if you want to build the full
|
||||
website, you will also need to install a few Node packages by running `npm ci`.
|
||||
|
||||
#### Building documentation
|
||||
Gradle should be your entrypoint to building most documentation. There's two tasks which are of interest:
|
||||
|
||||
- `./gradlew luaJavadoc` - Generate documentation stubs for Java methods.
|
||||
- `./gradlew docWebsite` - Generate the whole website (including Javascript pages). The resulting HTML is stored at
|
||||
`./build/docs/lua/`.
|
||||
|
||||
#### Writing documentation
|
||||
illuaminate's documentation system is not currently documented (somewhat ironic), but is _largely_ the same as
|
||||
[ldoc][ldoc]. Documentation comments are written in Markdown,
|
||||
|
||||
Our markdown engine does _not_ support GitHub flavoured markdown, and so does not support all the features one might
|
||||
expect (such as tables). It is very much recommended that you build and preview the docs locally first.
|
||||
|
||||
### Testing
|
||||
Thankfully running tests is much simpler than running the documentation generator! `./gradlew check` will run the
|
||||
entire test suite (and some additional bits of verification).
|
||||
|
||||
Before we get into writing tests, it's worth mentioning the various test suites that CC: Tweaked has:
|
||||
- "Core" Java (`./src/test/java`): These test core bits of the mod which don't require any Minecraft interaction.
|
||||
This includes the `@LuaFunction` system, file system code, etc...
|
||||
|
||||
These tests are run by `./gradlew test`.
|
||||
|
||||
- CraftOS (`./src/test/resources/test-rom/`): These tests are written in Lua, and ensure the Lua environment, libraries
|
||||
and programs work as expected. These are (generally) written to be able to be run on emulators too, to provide some
|
||||
sort of compliance test.
|
||||
|
||||
These tests are run by the '"Core" Java' test suite, and so are also run with `./gradlew test`.
|
||||
|
||||
- In-game (`./src/test/java/dan200/computercraft/ingame/`): These tests are run on an actual Minecraft server, using
|
||||
[the same system Mojang do][mc-test]. The aim of these is to test in-game behaviour of blocks and peripherals.
|
||||
|
||||
These are run by `./gradlew testInGame`.
|
||||
|
||||
## CraftOS tests
|
||||
CraftOS's tests are written using a test system called "mcfly", heavily inspired by [busted] (and thus RSpec). Groups of
|
||||
tests go inside `describe` blocks, and a single test goes inside `it`.
|
||||
|
||||
Assertions are generally written using `expect` (inspired by Hamcrest and the like). For instance, `expect(foo):eq("bar")`
|
||||
asserts that your variable `foo` is equal to the expected value `"bar"`.
|
||||
|
||||
[new-issue]: https://github.com/SquidDev-CC/CC-Tweaked/issues/new/choose "Create a new issue"
|
||||
[community]: README.md#Community "Get in touch with the community."
|
||||
[checkstyle]: https://checkstyle.org/
|
||||
[illuaminate]: https://github.com/SquidDev/illuaminate/
|
||||
[illuaminate-usage]: https://github.com/SquidDev/illuaminate/blob/master/README.md#usage
|
||||
[weblate]: https://i18n.tweaked.cc/projects/cc-tweaked/minecraft/
|
||||
[illuaminate]: https://github.com/SquidDev/illuaminate/ "Illuaminate on GitHub"
|
||||
[illuaminate-usage]: https://github.com/SquidDev/illuaminate/blob/master/README.md#usage "Installing Illuaminate"
|
||||
[weblate]: https://i18n.tweaked.cc/projects/cc-tweaked/minecraft/ "CC: Tweaked weblate instance"
|
||||
[docs]: https://tweaked.cc/ "CC: Tweaked documentation"
|
||||
[ldoc]: http://stevedonovan.github.io/ldoc/ "ldoc, a Lua documentation generator."
|
||||
[mc-test]: https://www.youtube.com/watch?v=vXaWOJTCYNg
|
||||
[busted]: https://github.com/Olivine-Labs/busted "busted: Elegant Lua unit testing."
|
||||
|
82
build.gradle
82
build.gradle
@ -21,6 +21,7 @@ plugins {
|
||||
id "com.github.hierynomus.license" version "0.15.0"
|
||||
id "com.matthewprenger.cursegradle" version "1.3.0"
|
||||
id "com.github.breadmoirai.github-release" version "2.2.4"
|
||||
id "org.jetbrains.kotlin.jvm" version "1.3.72"
|
||||
}
|
||||
|
||||
apply plugin: 'net.minecraftforge.gradle'
|
||||
@ -51,8 +52,9 @@ minecraft {
|
||||
|
||||
server {
|
||||
workingDirectory project.file("run/server")
|
||||
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP'
|
||||
property 'forge.logging.markers', 'REGISTRIES'
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
arg "--nogui"
|
||||
|
||||
mods {
|
||||
computercraft {
|
||||
@ -63,7 +65,7 @@ minecraft {
|
||||
|
||||
data {
|
||||
workingDirectory project.file('run')
|
||||
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP'
|
||||
property 'forge.logging.markers', 'REGISTRIES'
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
|
||||
args '--mod', 'computercraft', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
|
||||
@ -73,6 +75,17 @@ minecraft {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testServer {
|
||||
workingDirectory project.file('test-files/server')
|
||||
parent runs.server
|
||||
|
||||
mods {
|
||||
cctest {
|
||||
source sourceSets.test
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mappings channel: 'official', version: mc_version
|
||||
@ -120,6 +133,9 @@ dependencies {
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
|
||||
testImplementation 'org.hamcrest:hamcrest:2.2'
|
||||
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72'
|
||||
testImplementation 'org.jetbrains.kotlin:kotlin-reflect:1.3.72'
|
||||
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8'
|
||||
|
||||
deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0"
|
||||
|
||||
@ -369,6 +385,7 @@ test {
|
||||
}
|
||||
|
||||
jacocoTestReport {
|
||||
dependsOn('test')
|
||||
reports {
|
||||
xml.enabled true
|
||||
html.enabled true
|
||||
@ -416,6 +433,67 @@ task licenseFormatAPI(type: LicenseFormat);
|
||||
}
|
||||
}
|
||||
|
||||
task setupServer(type: Copy) {
|
||||
group "test server"
|
||||
description "Sets up the environment for the test server."
|
||||
|
||||
from("src/test/server-files") {
|
||||
include "eula.txt"
|
||||
include "server.properties"
|
||||
}
|
||||
into "test-files/server"
|
||||
}
|
||||
|
||||
tasks.register('testInGame', JavaExec.class).configure {
|
||||
it.group('test server')
|
||||
it.description("Runs tests on a temporary Minecraft server.")
|
||||
it.dependsOn(setupServer, 'prepareRunTestServer')
|
||||
|
||||
// Copy from runTestServer. We do it in this slightly odd way as runTestServer
|
||||
// isn't created until the task is configured (which is no good for us).
|
||||
JavaExec exec = tasks.getByName('runTestServer')
|
||||
it.setWorkingDir(exec.getWorkingDir())
|
||||
it.setSystemProperties(exec.getSystemProperties())
|
||||
it.setBootstrapClasspath(exec.getBootstrapClasspath())
|
||||
it.setClasspath(exec.getClasspath())
|
||||
it.setMain(exec.getMain())
|
||||
it.setEnvironment(exec.getEnvironment())
|
||||
it.setArgs(exec.getArgs())
|
||||
it.setJvmArgs(exec.getJvmArgs())
|
||||
|
||||
it.systemProperty('forge.logging.console.level', 'info')
|
||||
it.systemProperty('cctest.run', 'true')
|
||||
|
||||
// Jacoco and modlauncher don't play well together as the classes loaded in-game don't
|
||||
// match up with those written to disk. We get Jacoco to dump all classes to disk, and
|
||||
// use that when generating the report.
|
||||
def coverageOut = new File(buildDir, 'jacocoClassDump/testInGame')
|
||||
jacoco.applyTo(it)
|
||||
it.jacoco.setIncludes(["dan200.computercraft.*"])
|
||||
it.jacoco.setClassDumpDir(coverageOut)
|
||||
it.outputs.dir(coverageOut)
|
||||
// Older versions of modlauncher don't include a protection domain (and thus no code
|
||||
// source). Jacoco skips such classes by default, so we need to explicitly include them.
|
||||
it.jacoco.setIncludeNoLocationClasses(true)
|
||||
}
|
||||
|
||||
tasks.register('jacocoTestInGameReport', JacocoReport.class).configure {
|
||||
it.group('test server')
|
||||
it.description('Generate coverage reports for in-game tests (testInGame)')
|
||||
it.dependsOn('testInGame')
|
||||
|
||||
it.executionData(new File(buildDir, 'jacoco/testInGame.exec'))
|
||||
it.setSourceDirectories(project.files(sourceSets.main.allJava.srcDirs))
|
||||
it.setClassDirectories(project.files(new File(buildDir, 'jacocoClassDump/testInGame')))
|
||||
|
||||
it.reports {
|
||||
xml.enabled true
|
||||
html.enabled true
|
||||
}
|
||||
}
|
||||
check.dependsOn('jacocoTestInGameReport')
|
||||
|
||||
|
||||
// Upload tasks
|
||||
|
||||
task checkRelease {
|
||||
|
@ -97,20 +97,11 @@
|
||||
<module name="LambdaParameterName" />
|
||||
<module name="LocalFinalVariableName" />
|
||||
<module name="LocalVariableName" />
|
||||
<!-- Allow an optional m_ on private members -->
|
||||
<module name="MemberName">
|
||||
<property name="applyToPrivate" value="false" />
|
||||
<property name="applyToPackage" value="false" />
|
||||
</module>
|
||||
<module name="MemberName">
|
||||
<property name="format" value="^(m_)?[a-z][a-zA-Z0-9]*$" />
|
||||
<property name="applyToPrivate" value="true" />
|
||||
<property name="applyToPackage" value="true" />
|
||||
</module>
|
||||
<module name="MemberName" />
|
||||
<module name="MethodName" />
|
||||
<module name="MethodTypeParameterName" />
|
||||
<module name="PackageName">
|
||||
<property name="format" value="^dan200\.computercraf(\.[a-z][a-z0-9]*)*" />
|
||||
<property name="format" value="^dan200\.computercraft(\.[a-z][a-z0-9]*)*" />
|
||||
</module>
|
||||
<module name="ParameterName" />
|
||||
<module name="StaticVariableName">
|
||||
|
24
doc/events/char.md
Normal file
24
doc/events/char.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
module: [kind=event] char
|
||||
see: key To listen to any key press.
|
||||
---
|
||||
|
||||
The @{char} event is fired when a character is _typed_ on the keyboard.
|
||||
|
||||
The @{char} event is different to a key press. Sometimes multiple key presses may result in one character being
|
||||
typed (for instance, on some European keyboards). Similarly, some keys (e.g. <kbd>Ctrl</kbd>) do not have any
|
||||
corresponding character. The @{key} should be used if you want to listen to key presses themselves.
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{string}: The string representing the character that was pressed.
|
||||
|
||||
|
||||
## Example
|
||||
Prints each character the user presses:
|
||||
```lua
|
||||
while true do
|
||||
local event, character = os.pullEvent("char")
|
||||
print(character .. " was pressed.")
|
||||
end
|
||||
```
|
26
doc/events/key.md
Normal file
26
doc/events/key.md
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
module: [kind=event] key
|
||||
---
|
||||
|
||||
This event is fired when any key is pressed while the terminal is focused.
|
||||
|
||||
This event returns a numerical "key code" (for instance, <kbd>F1</kbd> is 290). This value may vary between versions and
|
||||
so it is recommended to use the constants in the @{keys} API rather than hard coding numeric values.
|
||||
|
||||
If the button pressed represented a printable character, then the @{key} event will be followed immediately by a @{char}
|
||||
event. If you are consuming text input, use a @{char} event instead!
|
||||
|
||||
## Return values
|
||||
1. [`string`]: The event name.
|
||||
2. [`number`]: The numerical key value of the key pressed.
|
||||
3. [`boolean`]: Whether the key event was generated while holding the key (@{true}), rather than pressing it the first time (@{false}).
|
||||
|
||||
## Example
|
||||
Prints each key when the user presses it, and if the key is being held.
|
||||
|
||||
```lua
|
||||
while true do
|
||||
local event, key, is_held = os.pullEvent("key")
|
||||
print(("%s held=%s"):format(keys.getName(key), is_held))
|
||||
end
|
||||
```
|
24
doc/events/key_up.md
Normal file
24
doc/events/key_up.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
module: [kind=event] key_up
|
||||
see: keys For a lookup table of the given keys.
|
||||
---
|
||||
|
||||
Fired whenever a key is released (or the terminal is closed while a key was being pressed).
|
||||
|
||||
This event returns a numerical "key code" (for instance, <kbd>F1</kbd> is 290). This value may vary between versions and
|
||||
so it is recommended to use the constants in the @{keys} API rather than hard coding numeric values.
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The numerical key value of the key pressed.
|
||||
|
||||
## Example
|
||||
Prints each key released on the keyboard whenever a @{key_up} event is fired.
|
||||
|
||||
```lua
|
||||
while true do
|
||||
local event, key = os.pullEvent("key_up")
|
||||
local name = keys.getName(key) or "unknown key"
|
||||
print(name .. " was released.")
|
||||
end
|
||||
```
|
34
doc/events/mouse_click.md
Normal file
34
doc/events/mouse_click.md
Normal file
@ -0,0 +1,34 @@
|
||||
---
|
||||
module: [kind=event] mouse_click
|
||||
---
|
||||
|
||||
This event is fired when the terminal is clicked with a mouse. This event is only fired on advanced computers (including
|
||||
advanced turtles and pocket computers).
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The mouse button that was clicked.
|
||||
3. @{number}: The X-coordinate of the click.
|
||||
4. @{number}: The Y-coordinate of the click.
|
||||
|
||||
## Mouse buttons
|
||||
Several mouse events (@{mouse_click}, @{mouse_up}, @{mouse_scroll}) contain a "mouse button" code. This takes a
|
||||
numerical value depending on which button on your mouse was last pressed when this event occurred.
|
||||
|
||||
<table class="pretty-table">
|
||||
<!-- Our markdown parser doesn't work on tables!? Guess I'll have to roll my own soonish :/. -->
|
||||
<tr><th>Button code</th><th>Mouse button</th></tr>
|
||||
<tr><td align="right">1</td><td>Left button</td></tr>
|
||||
<tr><td align="right">2</td><td>Middle button</td></tr>
|
||||
<tr><td align="right">3</td><td>Right button</td></tr>
|
||||
</table>
|
||||
|
||||
## Example
|
||||
Print the button and the coordinates whenever the mouse is clicked.
|
||||
|
||||
```lua
|
||||
while true do
|
||||
local event, button, x, y = os.pullEvent("mouse_click")
|
||||
print(("The mouse button %s was pressed at %d, %d"):format(button, x, y))
|
||||
end
|
||||
```
|
24
doc/events/mouse_drag.md
Normal file
24
doc/events/mouse_drag.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
module: [kind=event] mouse_drag
|
||||
see: mouse_click For when a mouse button is initially pressed.
|
||||
---
|
||||
|
||||
This event is fired every time the mouse is moved while a mouse button is being held.
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The [mouse button](mouse_click.html#Mouse_buttons) that is being pressed.
|
||||
3. @{number}: The X-coordinate of the mouse.
|
||||
4. @{number}: The Y-coordinate of the mouse.
|
||||
|
||||
## Example
|
||||
Print the button and the coordinates whenever the mouse is dragged.
|
||||
|
||||
```lua
|
||||
while true do
|
||||
local event, button, x, y = os.pullEvent("mouse_drag")
|
||||
print(("The mouse button %s was dragged at %d, %d"):format(button, x, y))
|
||||
end
|
||||
```
|
||||
|
||||
|
21
doc/events/mouse_scroll.md
Normal file
21
doc/events/mouse_scroll.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
module: [kind=event] mouse_scroll
|
||||
---
|
||||
|
||||
This event is fired when a mouse wheel is scrolled in the terminal.
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The direction of the scroll. (-1 = up, 1 = down)
|
||||
3. @{number}: The X-coordinate of the mouse when scrolling.
|
||||
4. @{number}: The Y-coordinate of the mouse when scrolling.
|
||||
|
||||
## Example
|
||||
Prints the direction of each scroll, and the position of the mouse at the time.
|
||||
|
||||
```lua
|
||||
while true do
|
||||
local event, dir, x, y = os.pullEvent("mouse_scroll")
|
||||
print(("The mouse was scrolled in direction %s at %d, %d"):format(dir, x, y))
|
||||
end
|
||||
```
|
24
doc/events/mouse_up.md
Normal file
24
doc/events/mouse_up.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
module: [kind=event] mouse_up
|
||||
---
|
||||
|
||||
This event is fired when a mouse button is released or a held mouse leaves the computer's terminal.
|
||||
|
||||
## Return values
|
||||
1. @{string}: The event name.
|
||||
2. @{number}: The [mouse button](mouse_click.html#Mouse_buttons) that was released.
|
||||
3. @{number}: The X-coordinate of the mouse.
|
||||
4. @{number}: The Y-coordinate of the mouse.
|
||||
|
||||
## Example
|
||||
Prints the coordinates and button number whenever the mouse is released.
|
||||
|
||||
```lua
|
||||
while true do
|
||||
local event, button, x, y = os.pullEvent("mouse_up")
|
||||
print(("The mouse button %s was released at %d, %d"):format(button, x, y))
|
||||
end
|
||||
```
|
||||
|
||||
[`string`]: string
|
||||
[`number`]: number
|
@ -1,5 +1,5 @@
|
||||
# Mod properties
|
||||
mod_version=1.95.1
|
||||
mod_version=1.95.2
|
||||
|
||||
# Minecraft properties (update mods.toml when changing)
|
||||
mc_version=1.16.4
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
(sources
|
||||
/doc/stub/
|
||||
/doc/events/
|
||||
/build/docs/luaJavadoc/
|
||||
/src/main/resources/*/computercraft/lua/bios.lua
|
||||
/src/main/resources/*/computercraft/lua/rom/
|
||||
@ -25,7 +26,8 @@
|
||||
|
||||
(module-kinds
|
||||
(peripheral Peripherals)
|
||||
(generic_peripheral "Generic Peripherals"))
|
||||
(generic_peripheral "Generic Peripherals")
|
||||
(event Events))
|
||||
|
||||
(library-path
|
||||
/doc/stub/
|
||||
|
@ -24,11 +24,11 @@ import static dan200.computercraft.client.render.PrintoutRenderer.*;
|
||||
|
||||
public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
|
||||
{
|
||||
private final boolean m_book;
|
||||
private final int m_pages;
|
||||
private final TextBuffer[] m_text;
|
||||
private final TextBuffer[] m_colours;
|
||||
private int m_page;
|
||||
private final boolean book;
|
||||
private final int pages;
|
||||
private final TextBuffer[] text;
|
||||
private final TextBuffer[] colours;
|
||||
private int page;
|
||||
|
||||
public GuiPrintout( ContainerHeldItem container, PlayerInventory player, ITextComponent title )
|
||||
{
|
||||
@ -37,16 +37,16 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
|
||||
imageHeight = Y_SIZE;
|
||||
|
||||
String[] text = ItemPrintout.getText( container.getStack() );
|
||||
m_text = new TextBuffer[text.length];
|
||||
for( int i = 0; i < m_text.length; i++ ) m_text[i] = new TextBuffer( text[i] );
|
||||
this.text = new TextBuffer[text.length];
|
||||
for( int i = 0; i < this.text.length; i++ ) this.text[i] = new TextBuffer( text[i] );
|
||||
|
||||
String[] colours = ItemPrintout.getColours( container.getStack() );
|
||||
m_colours = new TextBuffer[colours.length];
|
||||
for( int i = 0; i < m_colours.length; i++ ) m_colours[i] = new TextBuffer( colours[i] );
|
||||
this.colours = new TextBuffer[colours.length];
|
||||
for( int i = 0; i < this.colours.length; i++ ) this.colours[i] = new TextBuffer( colours[i] );
|
||||
|
||||
m_page = 0;
|
||||
m_pages = Math.max( m_text.length / ItemPrintout.LINES_PER_PAGE, 1 );
|
||||
m_book = ((ItemPrintout) container.getStack().getItem()).getType() == ItemPrintout.Type.BOOK;
|
||||
page = 0;
|
||||
pages = Math.max( this.text.length / ItemPrintout.LINES_PER_PAGE, 1 );
|
||||
book = ((ItemPrintout) container.getStack().getItem()).getType() == ItemPrintout.Type.BOOK;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -56,13 +56,13 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
|
||||
|
||||
if( key == GLFW.GLFW_KEY_RIGHT )
|
||||
{
|
||||
if( m_page < m_pages - 1 ) m_page++;
|
||||
if( page < pages - 1 ) page++;
|
||||
return true;
|
||||
}
|
||||
|
||||
if( key == GLFW.GLFW_KEY_LEFT )
|
||||
{
|
||||
if( m_page > 0 ) m_page--;
|
||||
if( page > 0 ) page--;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -76,14 +76,14 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
|
||||
if( delta < 0 )
|
||||
{
|
||||
// Scroll up goes to the next page
|
||||
if( m_page < m_pages - 1 ) m_page++;
|
||||
if( page < pages - 1 ) page++;
|
||||
return true;
|
||||
}
|
||||
|
||||
if( delta > 0 )
|
||||
{
|
||||
// Scroll down goes to the previous page
|
||||
if( m_page > 0 ) m_page--;
|
||||
if( page > 0 ) page--;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -99,8 +99,8 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
|
||||
|
||||
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().renderBuffers().bufferSource();
|
||||
Matrix4f matrix = transform.last().pose();
|
||||
drawBorder( matrix, renderer, leftPos, topPos, getBlitOffset(), m_page, m_pages, m_book );
|
||||
drawText( matrix, renderer, leftPos + X_TEXT_MARGIN, topPos + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours );
|
||||
drawBorder( matrix, renderer, leftPos, topPos, getBlitOffset(), page, pages, book );
|
||||
drawText( matrix, renderer, leftPos + X_TEXT_MARGIN, topPos + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * page, text, colours );
|
||||
renderer.endBatch();
|
||||
}
|
||||
|
||||
|
@ -23,13 +23,13 @@ import javax.annotation.Nonnull;
|
||||
|
||||
public class GuiTurtle extends ContainerScreen<ContainerTurtle>
|
||||
{
|
||||
private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( "computercraft", "textures/gui/turtle_normal.png" );
|
||||
private static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation( "computercraft", "textures/gui/turtle_advanced.png" );
|
||||
private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/turtle_normal.png" );
|
||||
private static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/turtle_advanced.png" );
|
||||
|
||||
private ContainerTurtle m_container;
|
||||
private final ContainerTurtle container;
|
||||
|
||||
private final ComputerFamily m_family;
|
||||
private final ClientComputer m_computer;
|
||||
private final ComputerFamily family;
|
||||
private final ClientComputer computer;
|
||||
|
||||
private WidgetTerminal terminal;
|
||||
private WidgetWrapper terminalWrapper;
|
||||
@ -38,9 +38,9 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
|
||||
{
|
||||
super( container, player, title );
|
||||
|
||||
m_container = container;
|
||||
m_family = container.getFamily();
|
||||
m_computer = (ClientComputer) container.getComputer();
|
||||
this.container = container;
|
||||
family = container.getFamily();
|
||||
computer = (ClientComputer) container.getComputer();
|
||||
|
||||
imageWidth = 254;
|
||||
imageHeight = 217;
|
||||
@ -56,7 +56,7 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
|
||||
int termPxHeight = ComputerCraft.turtleTermHeight * FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
|
||||
terminal = new WidgetTerminal(
|
||||
minecraft, () -> m_computer,
|
||||
minecraft, () -> computer,
|
||||
ComputerCraft.turtleTermWidth,
|
||||
ComputerCraft.turtleTermHeight,
|
||||
2, 2, 2, 2
|
||||
@ -99,7 +99,7 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
|
||||
protected void renderBg( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
|
||||
{
|
||||
// Draw term
|
||||
ResourceLocation texture = m_family == ComputerFamily.ADVANCED ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL;
|
||||
ResourceLocation texture = family == ComputerFamily.ADVANCED ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL;
|
||||
terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
|
||||
|
||||
// Draw border/inventory
|
||||
@ -108,7 +108,7 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
|
||||
blit( transform, leftPos, topPos, 0, 0, imageWidth, imageHeight );
|
||||
|
||||
// Draw selection slot
|
||||
int slot = m_container.getSelectedSlot();
|
||||
int slot = container.getSelectedSlot();
|
||||
if( slot >= 0 )
|
||||
{
|
||||
int slotX = slot % 4;
|
||||
|
@ -23,22 +23,22 @@ import java.util.*;
|
||||
|
||||
public class TurtleMultiModel implements IBakedModel
|
||||
{
|
||||
private final IBakedModel m_baseModel;
|
||||
private final IBakedModel m_overlayModel;
|
||||
private final TransformationMatrix m_generalTransform;
|
||||
private final TransformedModel m_leftUpgradeModel;
|
||||
private final TransformedModel m_rightUpgradeModel;
|
||||
private List<BakedQuad> m_generalQuads = null;
|
||||
private Map<Direction, List<BakedQuad>> m_faceQuads = new EnumMap<>( Direction.class );
|
||||
private final IBakedModel baseModel;
|
||||
private final IBakedModel overlayModel;
|
||||
private final TransformationMatrix generalTransform;
|
||||
private final TransformedModel leftUpgradeModel;
|
||||
private final TransformedModel rightUpgradeModel;
|
||||
private List<BakedQuad> generalQuads = null;
|
||||
private final Map<Direction, List<BakedQuad>> faceQuads = new EnumMap<>( Direction.class );
|
||||
|
||||
public TurtleMultiModel( IBakedModel baseModel, IBakedModel overlayModel, TransformationMatrix generalTransform, TransformedModel leftUpgradeModel, TransformedModel rightUpgradeModel )
|
||||
{
|
||||
// Get the models
|
||||
m_baseModel = baseModel;
|
||||
m_overlayModel = overlayModel;
|
||||
m_leftUpgradeModel = leftUpgradeModel;
|
||||
m_rightUpgradeModel = rightUpgradeModel;
|
||||
m_generalTransform = generalTransform;
|
||||
this.baseModel = baseModel;
|
||||
this.overlayModel = overlayModel;
|
||||
this.leftUpgradeModel = leftUpgradeModel;
|
||||
this.rightUpgradeModel = rightUpgradeModel;
|
||||
this.generalTransform = generalTransform;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -55,13 +55,13 @@ public class TurtleMultiModel implements IBakedModel
|
||||
{
|
||||
if( side != null )
|
||||
{
|
||||
if( !m_faceQuads.containsKey( side ) ) m_faceQuads.put( side, buildQuads( state, side, rand ) );
|
||||
return m_faceQuads.get( side );
|
||||
if( !faceQuads.containsKey( side ) ) faceQuads.put( side, buildQuads( state, side, rand ) );
|
||||
return faceQuads.get( side );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_generalQuads == null ) m_generalQuads = buildQuads( state, side, rand );
|
||||
return m_generalQuads;
|
||||
if( generalQuads == null ) generalQuads = buildQuads( state, side, rand );
|
||||
return generalQuads;
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,20 +70,20 @@ public class TurtleMultiModel implements IBakedModel
|
||||
ArrayList<BakedQuad> quads = new ArrayList<>();
|
||||
|
||||
|
||||
transformQuadsTo( quads, m_baseModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), m_generalTransform );
|
||||
if( m_overlayModel != null )
|
||||
transformQuadsTo( quads, baseModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), generalTransform );
|
||||
if( overlayModel != null )
|
||||
{
|
||||
transformQuadsTo( quads, m_overlayModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), m_generalTransform );
|
||||
transformQuadsTo( quads, overlayModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), generalTransform );
|
||||
}
|
||||
if( m_leftUpgradeModel != null )
|
||||
if( leftUpgradeModel != null )
|
||||
{
|
||||
TransformationMatrix upgradeTransform = m_generalTransform.compose( m_leftUpgradeModel.getMatrix() );
|
||||
transformQuadsTo( quads, m_leftUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
|
||||
TransformationMatrix upgradeTransform = generalTransform.compose( leftUpgradeModel.getMatrix() );
|
||||
transformQuadsTo( quads, leftUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
|
||||
}
|
||||
if( m_rightUpgradeModel != null )
|
||||
if( rightUpgradeModel != null )
|
||||
{
|
||||
TransformationMatrix upgradeTransform = m_generalTransform.compose( m_rightUpgradeModel.getMatrix() );
|
||||
transformQuadsTo( quads, m_rightUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
|
||||
TransformationMatrix upgradeTransform = generalTransform.compose( rightUpgradeModel.getMatrix() );
|
||||
transformQuadsTo( quads, rightUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
|
||||
}
|
||||
quads.trimToSize();
|
||||
return quads;
|
||||
@ -92,25 +92,25 @@ public class TurtleMultiModel implements IBakedModel
|
||||
@Override
|
||||
public boolean useAmbientOcclusion()
|
||||
{
|
||||
return m_baseModel.useAmbientOcclusion();
|
||||
return baseModel.useAmbientOcclusion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d()
|
||||
{
|
||||
return m_baseModel.isGui3d();
|
||||
return baseModel.isGui3d();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCustomRenderer()
|
||||
{
|
||||
return m_baseModel.isCustomRenderer();
|
||||
return baseModel.isCustomRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesBlockLight()
|
||||
{
|
||||
return m_baseModel.usesBlockLight();
|
||||
return baseModel.usesBlockLight();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -118,7 +118,7 @@ public class TurtleMultiModel implements IBakedModel
|
||||
@Deprecated
|
||||
public TextureAtlasSprite getParticleIcon()
|
||||
{
|
||||
return m_baseModel.getParticleIcon();
|
||||
return baseModel.getParticleIcon();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -126,7 +126,7 @@ public class TurtleMultiModel implements IBakedModel
|
||||
@Deprecated
|
||||
public net.minecraft.client.renderer.model.ItemCameraTransforms getTransforms()
|
||||
{
|
||||
return m_baseModel.getTransforms();
|
||||
return baseModel.getTransforms();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@ -47,21 +47,21 @@ public class TurtleSmartItemModel implements IBakedModel
|
||||
|
||||
private static class TurtleModelCombination
|
||||
{
|
||||
final boolean m_colour;
|
||||
final ITurtleUpgrade m_leftUpgrade;
|
||||
final ITurtleUpgrade m_rightUpgrade;
|
||||
final ResourceLocation m_overlay;
|
||||
final boolean m_christmas;
|
||||
final boolean m_flip;
|
||||
final boolean colour;
|
||||
final ITurtleUpgrade leftUpgrade;
|
||||
final ITurtleUpgrade rightUpgrade;
|
||||
final ResourceLocation overlay;
|
||||
final boolean christmas;
|
||||
final boolean flip;
|
||||
|
||||
TurtleModelCombination( boolean colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, ResourceLocation overlay, boolean christmas, boolean flip )
|
||||
{
|
||||
m_colour = colour;
|
||||
m_leftUpgrade = leftUpgrade;
|
||||
m_rightUpgrade = rightUpgrade;
|
||||
m_overlay = overlay;
|
||||
m_christmas = christmas;
|
||||
m_flip = flip;
|
||||
this.colour = colour;
|
||||
this.leftUpgrade = leftUpgrade;
|
||||
this.rightUpgrade = rightUpgrade;
|
||||
this.overlay = overlay;
|
||||
this.christmas = christmas;
|
||||
this.flip = flip;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,12 +71,12 @@ public class TurtleSmartItemModel implements IBakedModel
|
||||
if( !(other instanceof TurtleModelCombination) ) return false;
|
||||
|
||||
TurtleModelCombination otherCombo = (TurtleModelCombination) other;
|
||||
return otherCombo.m_colour == m_colour &&
|
||||
otherCombo.m_leftUpgrade == m_leftUpgrade &&
|
||||
otherCombo.m_rightUpgrade == m_rightUpgrade &&
|
||||
Objects.equal( otherCombo.m_overlay, m_overlay ) &&
|
||||
otherCombo.m_christmas == m_christmas &&
|
||||
otherCombo.m_flip == m_flip;
|
||||
return otherCombo.colour == colour &&
|
||||
otherCombo.leftUpgrade == leftUpgrade &&
|
||||
otherCombo.rightUpgrade == rightUpgrade &&
|
||||
Objects.equal( otherCombo.overlay, overlay ) &&
|
||||
otherCombo.christmas == christmas &&
|
||||
otherCombo.flip == flip;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -84,12 +84,12 @@ public class TurtleSmartItemModel implements IBakedModel
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 0;
|
||||
result = prime * result + (m_colour ? 1 : 0);
|
||||
result = prime * result + (m_leftUpgrade != null ? m_leftUpgrade.hashCode() : 0);
|
||||
result = prime * result + (m_rightUpgrade != null ? m_rightUpgrade.hashCode() : 0);
|
||||
result = prime * result + (m_overlay != null ? m_overlay.hashCode() : 0);
|
||||
result = prime * result + (m_christmas ? 1 : 0);
|
||||
result = prime * result + (m_flip ? 1 : 0);
|
||||
result = prime * result + (colour ? 1 : 0);
|
||||
result = prime * result + (leftUpgrade != null ? leftUpgrade.hashCode() : 0);
|
||||
result = prime * result + (rightUpgrade != null ? rightUpgrade.hashCode() : 0);
|
||||
result = prime * result + (overlay != null ? overlay.hashCode() : 0);
|
||||
result = prime * result + (christmas ? 1 : 0);
|
||||
result = prime * result + (flip ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -97,15 +97,15 @@ public class TurtleSmartItemModel implements IBakedModel
|
||||
private final IBakedModel familyModel;
|
||||
private final IBakedModel colourModel;
|
||||
|
||||
private final HashMap<TurtleModelCombination, IBakedModel> m_cachedModels = new HashMap<>();
|
||||
private final ItemOverrideList m_overrides;
|
||||
private final HashMap<TurtleModelCombination, IBakedModel> cachedModels = new HashMap<>();
|
||||
private final ItemOverrideList overrides;
|
||||
|
||||
public TurtleSmartItemModel( IBakedModel familyModel, IBakedModel colourModel )
|
||||
{
|
||||
this.familyModel = familyModel;
|
||||
this.colourModel = colourModel;
|
||||
|
||||
m_overrides = new ItemOverrideList()
|
||||
overrides = new ItemOverrideList()
|
||||
{
|
||||
@Nonnull
|
||||
@Override
|
||||
@ -121,8 +121,8 @@ public class TurtleSmartItemModel implements IBakedModel
|
||||
boolean flip = label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" ));
|
||||
TurtleModelCombination combo = new TurtleModelCombination( colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip );
|
||||
|
||||
IBakedModel model = m_cachedModels.get( combo );
|
||||
if( model == null ) m_cachedModels.put( combo, model = buildModel( combo ) );
|
||||
IBakedModel model = cachedModels.get( combo );
|
||||
if( model == null ) cachedModels.put( combo, model = buildModel( combo ) );
|
||||
return model;
|
||||
}
|
||||
};
|
||||
@ -132,20 +132,20 @@ public class TurtleSmartItemModel implements IBakedModel
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
return m_overrides;
|
||||
return overrides;
|
||||
}
|
||||
|
||||
private IBakedModel buildModel( TurtleModelCombination combo )
|
||||
{
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
ModelManager modelManager = mc.getItemRenderer().getItemModelShaper().getModelManager();
|
||||
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.m_overlay, combo.m_christmas );
|
||||
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.overlay, combo.christmas );
|
||||
|
||||
IBakedModel baseModel = combo.m_colour ? colourModel : familyModel;
|
||||
IBakedModel baseModel = combo.colour ? colourModel : familyModel;
|
||||
IBakedModel overlayModel = overlayModelLocation != null ? modelManager.getModel( overlayModelLocation ) : null;
|
||||
TransformationMatrix transform = combo.m_flip ? flip : identity;
|
||||
TransformedModel leftModel = combo.m_leftUpgrade != null ? combo.m_leftUpgrade.getModel( null, TurtleSide.LEFT ) : null;
|
||||
TransformedModel rightModel = combo.m_rightUpgrade != null ? combo.m_rightUpgrade.getModel( null, TurtleSide.RIGHT ) : null;
|
||||
TransformationMatrix transform = combo.flip ? flip : identity;
|
||||
TransformedModel leftModel = combo.leftUpgrade != null ? combo.leftUpgrade.getModel( null, TurtleSide.LEFT ) : null;
|
||||
TransformedModel rightModel = combo.rightUpgrade != null ? combo.rightUpgrade.getModel( null, TurtleSide.RIGHT ) : null;
|
||||
return new TurtleMultiModel( baseModel, overlayModel, transform, leftModel, rightModel );
|
||||
}
|
||||
|
||||
|
@ -19,22 +19,22 @@ import java.util.Set;
|
||||
|
||||
public abstract class ComputerAccess implements IComputerAccess
|
||||
{
|
||||
private final IAPIEnvironment m_environment;
|
||||
private final Set<String> m_mounts = new HashSet<>();
|
||||
private final IAPIEnvironment environment;
|
||||
private final Set<String> mounts = new HashSet<>();
|
||||
|
||||
protected ComputerAccess( IAPIEnvironment environment )
|
||||
{
|
||||
this.m_environment = environment;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public void unmountAll()
|
||||
{
|
||||
FileSystem fileSystem = m_environment.getFileSystem();
|
||||
for( String mount : m_mounts )
|
||||
FileSystem fileSystem = environment.getFileSystem();
|
||||
for( String mount : mounts )
|
||||
{
|
||||
fileSystem.unmount( mount );
|
||||
}
|
||||
m_mounts.clear();
|
||||
mounts.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -46,7 +46,7 @@ public abstract class ComputerAccess implements IComputerAccess
|
||||
|
||||
// Mount the location
|
||||
String location;
|
||||
FileSystem fileSystem = m_environment.getFileSystem();
|
||||
FileSystem fileSystem = environment.getFileSystem();
|
||||
if( fileSystem == null ) throw new IllegalStateException( "File system has not been created" );
|
||||
|
||||
synchronized( fileSystem )
|
||||
@ -64,7 +64,7 @@ public abstract class ComputerAccess implements IComputerAccess
|
||||
}
|
||||
}
|
||||
|
||||
if( location != null ) m_mounts.add( location );
|
||||
if( location != null ) mounts.add( location );
|
||||
return location;
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ public abstract class ComputerAccess implements IComputerAccess
|
||||
|
||||
// Mount the location
|
||||
String location;
|
||||
FileSystem fileSystem = m_environment.getFileSystem();
|
||||
FileSystem fileSystem = environment.getFileSystem();
|
||||
if( fileSystem == null ) throw new IllegalStateException( "File system has not been created" );
|
||||
|
||||
synchronized( fileSystem )
|
||||
@ -95,7 +95,7 @@ public abstract class ComputerAccess implements IComputerAccess
|
||||
}
|
||||
}
|
||||
|
||||
if( location != null ) m_mounts.add( location );
|
||||
if( location != null ) mounts.add( location );
|
||||
return location;
|
||||
}
|
||||
|
||||
@ -103,37 +103,37 @@ public abstract class ComputerAccess implements IComputerAccess
|
||||
public void unmount( String location )
|
||||
{
|
||||
if( location == null ) return;
|
||||
if( !m_mounts.contains( location ) ) throw new IllegalStateException( "You didn't mount this location" );
|
||||
if( !mounts.contains( location ) ) throw new IllegalStateException( "You didn't mount this location" );
|
||||
|
||||
m_environment.getFileSystem().unmount( location );
|
||||
m_mounts.remove( location );
|
||||
environment.getFileSystem().unmount( location );
|
||||
mounts.remove( location );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getID()
|
||||
{
|
||||
return m_environment.getComputerID();
|
||||
return environment.getComputerID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queueEvent( @Nonnull String event, Object... arguments )
|
||||
{
|
||||
Objects.requireNonNull( event, "event cannot be null" );
|
||||
m_environment.queueEvent( event, arguments );
|
||||
environment.queueEvent( event, arguments );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IWorkMonitor getMainThreadMonitor()
|
||||
{
|
||||
return m_environment.getMainThreadMonitor();
|
||||
return environment.getMainThreadMonitor();
|
||||
}
|
||||
|
||||
private String findFreeLocation( String desiredLoc )
|
||||
{
|
||||
try
|
||||
{
|
||||
FileSystem fileSystem = m_environment.getFileSystem();
|
||||
FileSystem fileSystem = environment.getFileSystem();
|
||||
if( !fileSystem.exists( desiredLoc ) ) return desiredLoc;
|
||||
|
||||
// We used to check foo2, foo3, foo4, etc here but the disk drive does this itself now
|
||||
|
@ -89,9 +89,9 @@ public class FSAPI implements ILuaAPI
|
||||
*
|
||||
* @param arguments The paths to combine.
|
||||
* @return The new path, with separators added between parts as needed.
|
||||
* @throws LuaException On argument errors.
|
||||
* @cc.tparam string path The first part of the path. For example, a parent directory path.
|
||||
* @cc.tparam string ... Additional parts of the path to combine.
|
||||
* @throws LuaException On argument errors.
|
||||
*/
|
||||
@LuaFunction
|
||||
public final String combine( IArguments arguments ) throws LuaException
|
||||
|
@ -34,7 +34,7 @@ import static dan200.computercraft.core.apis.TableHelper.*;
|
||||
*/
|
||||
public class HTTPAPI implements ILuaAPI
|
||||
{
|
||||
private final IAPIEnvironment m_apiEnvironment;
|
||||
private final IAPIEnvironment apiEnvironment;
|
||||
|
||||
private final ResourceGroup<CheckUrl> checkUrls = new ResourceGroup<>();
|
||||
private final ResourceGroup<HttpRequest> requests = new ResourceQueue<>( () -> ComputerCraft.httpMaxRequests );
|
||||
@ -42,7 +42,7 @@ public class HTTPAPI implements ILuaAPI
|
||||
|
||||
public HTTPAPI( IAPIEnvironment environment )
|
||||
{
|
||||
m_apiEnvironment = environment;
|
||||
apiEnvironment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -123,7 +123,7 @@ public class HTTPAPI implements ILuaAPI
|
||||
try
|
||||
{
|
||||
URI uri = HttpRequest.checkUri( address );
|
||||
HttpRequest request = new HttpRequest( requests, m_apiEnvironment, address, postString, headers, binary, redirect );
|
||||
HttpRequest request = new HttpRequest( requests, apiEnvironment, address, postString, headers, binary, redirect );
|
||||
|
||||
// Make the request
|
||||
request.queue( r -> r.request( uri, httpMethod ) );
|
||||
@ -142,7 +142,7 @@ public class HTTPAPI implements ILuaAPI
|
||||
try
|
||||
{
|
||||
URI uri = HttpRequest.checkUri( address );
|
||||
new CheckUrl( checkUrls, m_apiEnvironment, address, uri ).queue( CheckUrl::run );
|
||||
new CheckUrl( checkUrls, apiEnvironment, address, uri ).queue( CheckUrl::run );
|
||||
|
||||
return new Object[] { true };
|
||||
}
|
||||
@ -165,7 +165,7 @@ public class HTTPAPI implements ILuaAPI
|
||||
try
|
||||
{
|
||||
URI uri = Websocket.checkUri( address );
|
||||
if( !new Websocket( websockets, m_apiEnvironment, uri, address, headers ).queue( Websocket::connect ) )
|
||||
if( !new Websocket( websockets, apiEnvironment, uri, address, headers ).queue( Websocket::connect ) )
|
||||
{
|
||||
throw new LuaException( "Too many websockets already open" );
|
||||
}
|
||||
|
@ -32,29 +32,29 @@ public class OSAPI implements ILuaAPI
|
||||
{
|
||||
private final IAPIEnvironment apiEnvironment;
|
||||
|
||||
private final Int2ObjectMap<Alarm> m_alarms = new Int2ObjectOpenHashMap<>();
|
||||
private int m_clock;
|
||||
private double m_time;
|
||||
private int m_day;
|
||||
private final Int2ObjectMap<Alarm> alarms = new Int2ObjectOpenHashMap<>();
|
||||
private int clock;
|
||||
private double time;
|
||||
private int day;
|
||||
|
||||
private int m_nextAlarmToken = 0;
|
||||
private int nextAlarmToken = 0;
|
||||
|
||||
private static class Alarm implements Comparable<Alarm>
|
||||
{
|
||||
final double m_time;
|
||||
final int m_day;
|
||||
final double time;
|
||||
final int day;
|
||||
|
||||
Alarm( double time, int day )
|
||||
{
|
||||
m_time = time;
|
||||
m_day = day;
|
||||
this.time = time;
|
||||
this.day = day;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo( @Nonnull Alarm o )
|
||||
{
|
||||
double t = m_day * 24.0 + m_time;
|
||||
double ot = m_day * 24.0 + m_time;
|
||||
double t = day * 24.0 + time;
|
||||
double ot = day * 24.0 + time;
|
||||
return Double.compare( t, ot );
|
||||
}
|
||||
}
|
||||
@ -73,38 +73,38 @@ public class OSAPI implements ILuaAPI
|
||||
@Override
|
||||
public void startup()
|
||||
{
|
||||
m_time = apiEnvironment.getComputerEnvironment().getTimeOfDay();
|
||||
m_day = apiEnvironment.getComputerEnvironment().getDay();
|
||||
m_clock = 0;
|
||||
time = apiEnvironment.getComputerEnvironment().getTimeOfDay();
|
||||
day = apiEnvironment.getComputerEnvironment().getDay();
|
||||
clock = 0;
|
||||
|
||||
synchronized( m_alarms )
|
||||
synchronized( alarms )
|
||||
{
|
||||
m_alarms.clear();
|
||||
alarms.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
m_clock++;
|
||||
clock++;
|
||||
|
||||
// Wait for all of our alarms
|
||||
synchronized( m_alarms )
|
||||
synchronized( alarms )
|
||||
{
|
||||
double previousTime = m_time;
|
||||
int previousDay = m_day;
|
||||
double previousTime = time;
|
||||
int previousDay = day;
|
||||
double time = apiEnvironment.getComputerEnvironment().getTimeOfDay();
|
||||
int day = apiEnvironment.getComputerEnvironment().getDay();
|
||||
|
||||
if( time > previousTime || day > previousDay )
|
||||
{
|
||||
double now = m_day * 24.0 + m_time;
|
||||
Iterator<Int2ObjectMap.Entry<Alarm>> it = m_alarms.int2ObjectEntrySet().iterator();
|
||||
double now = this.day * 24.0 + this.time;
|
||||
Iterator<Int2ObjectMap.Entry<Alarm>> it = alarms.int2ObjectEntrySet().iterator();
|
||||
while( it.hasNext() )
|
||||
{
|
||||
Int2ObjectMap.Entry<Alarm> entry = it.next();
|
||||
Alarm alarm = entry.getValue();
|
||||
double t = alarm.m_day * 24.0 + alarm.m_time;
|
||||
double t = alarm.day * 24.0 + alarm.time;
|
||||
if( now >= t )
|
||||
{
|
||||
apiEnvironment.queueEvent( "alarm", entry.getIntKey() );
|
||||
@ -113,17 +113,17 @@ public class OSAPI implements ILuaAPI
|
||||
}
|
||||
}
|
||||
|
||||
m_time = time;
|
||||
m_day = day;
|
||||
this.time = time;
|
||||
this.day = day;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown()
|
||||
{
|
||||
synchronized( m_alarms )
|
||||
synchronized( alarms )
|
||||
{
|
||||
m_alarms.clear();
|
||||
alarms.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,7 +180,7 @@ public class OSAPI implements ILuaAPI
|
||||
*
|
||||
* @param timer The number of seconds until the timer fires.
|
||||
* @return The ID of the new timer. This can be used to filter the
|
||||
* {@code timer} event, or {@link #cancelTimer cancel the timer}.
|
||||
* {@code timer} event, or {@link #cancelTimer cancel the timer}.
|
||||
* @throws LuaException If the time is below zero.
|
||||
* @see #cancelTimer To cancel a timer.
|
||||
*/
|
||||
@ -210,7 +210,7 @@ public class OSAPI implements ILuaAPI
|
||||
*
|
||||
* @param time The time at which to fire the alarm, in the range [0.0, 24.0).
|
||||
* @return The ID of the new alarm. This can be used to filter the
|
||||
* {@code alarm} event, or {@link #cancelAlarm cancel the alarm}.
|
||||
* {@code alarm} event, or {@link #cancelAlarm cancel the alarm}.
|
||||
* @throws LuaException If the time is out of range.
|
||||
* @see #cancelAlarm To cancel an alarm.
|
||||
*/
|
||||
@ -219,11 +219,11 @@ public class OSAPI implements ILuaAPI
|
||||
{
|
||||
checkFinite( 0, time );
|
||||
if( time < 0.0 || time >= 24.0 ) throw new LuaException( "Number out of range" );
|
||||
synchronized( m_alarms )
|
||||
synchronized( alarms )
|
||||
{
|
||||
int day = time > m_time ? m_day : m_day + 1;
|
||||
m_alarms.put( m_nextAlarmToken, new Alarm( time, day ) );
|
||||
return m_nextAlarmToken++;
|
||||
int day = time > this.time ? this.day : this.day + 1;
|
||||
alarms.put( nextAlarmToken, new Alarm( time, day ) );
|
||||
return nextAlarmToken++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,9 +237,9 @@ public class OSAPI implements ILuaAPI
|
||||
@LuaFunction
|
||||
public final void cancelAlarm( int token )
|
||||
{
|
||||
synchronized( m_alarms )
|
||||
synchronized( alarms )
|
||||
{
|
||||
m_alarms.remove( token );
|
||||
alarms.remove( token );
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,7 +304,7 @@ public class OSAPI implements ILuaAPI
|
||||
@LuaFunction
|
||||
public final double clock()
|
||||
{
|
||||
return m_clock * 0.05;
|
||||
return clock * 0.05;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -341,7 +341,7 @@ public class OSAPI implements ILuaAPI
|
||||
case "local": // Get Hour of day (local time)
|
||||
return getTimeForCalendar( Calendar.getInstance() );
|
||||
case "ingame": // Get in-game hour
|
||||
return m_time;
|
||||
return time;
|
||||
default:
|
||||
throw new LuaException( "Unsupported operation" );
|
||||
}
|
||||
@ -371,7 +371,7 @@ public class OSAPI implements ILuaAPI
|
||||
case "local": // Get numbers of days since 1970-01-01 (local time)
|
||||
return getDayForCalendar( Calendar.getInstance() );
|
||||
case "ingame":// Get game day
|
||||
return m_day;
|
||||
return day;
|
||||
default:
|
||||
throw new LuaException( "Unsupported operation" );
|
||||
}
|
||||
@ -381,11 +381,11 @@ public class OSAPI implements ILuaAPI
|
||||
* Returns the number of milliseconds since an epoch depending on the locale.
|
||||
*
|
||||
* * If called with {@code ingame}, returns the number of milliseconds since the
|
||||
* world was created. This is the default.
|
||||
* world was created. This is the default.
|
||||
* * If called with {@code utc}, returns the number of milliseconds since 1
|
||||
* January 1970 in the UTC timezone.
|
||||
* January 1970 in the UTC timezone.
|
||||
* * If called with {@code local}, returns the number of milliseconds since 1
|
||||
* January 1970 in the server's local timezone.
|
||||
* January 1970 in the server's local timezone.
|
||||
*
|
||||
* @param args The locale to get the milliseconds for. Defaults to {@code ingame} if not set.
|
||||
* @return The milliseconds since the epoch depending on the selected locale.
|
||||
@ -410,9 +410,9 @@ public class OSAPI implements ILuaAPI
|
||||
}
|
||||
case "ingame":
|
||||
// Get in-game epoch
|
||||
synchronized( m_alarms )
|
||||
synchronized( alarms )
|
||||
{
|
||||
return m_day * 86400000L + (long) (m_time * 3600000.0);
|
||||
return day * 86400000L + (long) (time * 3600000.0);
|
||||
}
|
||||
default:
|
||||
throw new LuaException( "Unsupported operation" );
|
||||
|
@ -7,9 +7,9 @@ package dan200.computercraft.core.apis.handles;
|
||||
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.core.filesystem.TrackingCloseable;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
@ -32,14 +32,14 @@ public class BinaryReadableHandle extends HandleGeneric
|
||||
final SeekableByteChannel seekable;
|
||||
private final ByteBuffer single = ByteBuffer.allocate( 1 );
|
||||
|
||||
BinaryReadableHandle( ReadableByteChannel reader, SeekableByteChannel seekable, Closeable closeable )
|
||||
BinaryReadableHandle( ReadableByteChannel reader, SeekableByteChannel seekable, TrackingCloseable closeable )
|
||||
{
|
||||
super( closeable );
|
||||
this.reader = reader;
|
||||
this.seekable = seekable;
|
||||
}
|
||||
|
||||
public static BinaryReadableHandle of( ReadableByteChannel channel, Closeable closeable )
|
||||
public static BinaryReadableHandle of( ReadableByteChannel channel, TrackingCloseable closeable )
|
||||
{
|
||||
SeekableByteChannel seekable = asSeekable( channel );
|
||||
return seekable == null ? new BinaryReadableHandle( channel, null, closeable ) : new Seekable( seekable, closeable );
|
||||
@ -47,7 +47,7 @@ public class BinaryReadableHandle extends HandleGeneric
|
||||
|
||||
public static BinaryReadableHandle of( ReadableByteChannel channel )
|
||||
{
|
||||
return of( channel, channel );
|
||||
return of( channel, new TrackingCloseable.Impl( channel ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -237,7 +237,7 @@ public class BinaryReadableHandle extends HandleGeneric
|
||||
|
||||
public static class Seekable extends BinaryReadableHandle
|
||||
{
|
||||
Seekable( SeekableByteChannel seekable, Closeable closeable )
|
||||
Seekable( SeekableByteChannel seekable, TrackingCloseable closeable )
|
||||
{
|
||||
super( seekable, seekable, closeable );
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ import dan200.computercraft.api.lua.IArguments;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.api.lua.LuaValues;
|
||||
import dan200.computercraft.core.filesystem.TrackingCloseable;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
@ -30,14 +30,14 @@ public class BinaryWritableHandle extends HandleGeneric
|
||||
final SeekableByteChannel seekable;
|
||||
private final ByteBuffer single = ByteBuffer.allocate( 1 );
|
||||
|
||||
protected BinaryWritableHandle( WritableByteChannel writer, SeekableByteChannel seekable, Closeable closeable )
|
||||
protected BinaryWritableHandle( WritableByteChannel writer, SeekableByteChannel seekable, TrackingCloseable closeable )
|
||||
{
|
||||
super( closeable );
|
||||
this.writer = writer;
|
||||
this.seekable = seekable;
|
||||
}
|
||||
|
||||
public static BinaryWritableHandle of( WritableByteChannel channel, Closeable closeable )
|
||||
public static BinaryWritableHandle of( WritableByteChannel channel, TrackingCloseable closeable )
|
||||
{
|
||||
SeekableByteChannel seekable = asSeekable( channel );
|
||||
return seekable == null ? new BinaryWritableHandle( channel, null, closeable ) : new Seekable( seekable, closeable );
|
||||
@ -45,7 +45,7 @@ public class BinaryWritableHandle extends HandleGeneric
|
||||
|
||||
public static BinaryWritableHandle of( WritableByteChannel channel )
|
||||
{
|
||||
return of( channel, channel );
|
||||
return of( channel, new TrackingCloseable.Impl( channel ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,7 +108,7 @@ public class BinaryWritableHandle extends HandleGeneric
|
||||
|
||||
public static class Seekable extends BinaryWritableHandle
|
||||
{
|
||||
public Seekable( SeekableByteChannel seekable, Closeable closeable )
|
||||
public Seekable( SeekableByteChannel seekable, TrackingCloseable closeable )
|
||||
{
|
||||
super( seekable, seekable, closeable );
|
||||
}
|
||||
|
@ -7,10 +7,10 @@ package dan200.computercraft.core.apis.handles;
|
||||
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.core.filesystem.TrackingCloseable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
@ -32,7 +32,7 @@ public class EncodedReadableHandle extends HandleGeneric
|
||||
|
||||
private final BufferedReader reader;
|
||||
|
||||
public EncodedReadableHandle( @Nonnull BufferedReader reader, @Nonnull Closeable closable )
|
||||
public EncodedReadableHandle( @Nonnull BufferedReader reader, @Nonnull TrackingCloseable closable )
|
||||
{
|
||||
super( closable );
|
||||
this.reader = reader;
|
||||
@ -40,7 +40,7 @@ public class EncodedReadableHandle extends HandleGeneric
|
||||
|
||||
public EncodedReadableHandle( @Nonnull BufferedReader reader )
|
||||
{
|
||||
this( reader, reader );
|
||||
this( reader, new TrackingCloseable.Impl( reader ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8,11 +8,11 @@ package dan200.computercraft.core.apis.handles;
|
||||
import dan200.computercraft.api.lua.IArguments;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.core.filesystem.TrackingCloseable;
|
||||
import dan200.computercraft.shared.util.StringUtil;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
@ -30,7 +30,7 @@ public class EncodedWritableHandle extends HandleGeneric
|
||||
{
|
||||
private final BufferedWriter writer;
|
||||
|
||||
public EncodedWritableHandle( @Nonnull BufferedWriter writer, @Nonnull Closeable closable )
|
||||
public EncodedWritableHandle( @Nonnull BufferedWriter writer, @Nonnull TrackingCloseable closable )
|
||||
{
|
||||
super( closable );
|
||||
this.writer = writer;
|
||||
|
@ -7,10 +7,10 @@ package dan200.computercraft.core.apis.handles;
|
||||
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.core.filesystem.TrackingCloseable;
|
||||
import dan200.computercraft.shared.util.IoUtil;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.Channel;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
@ -18,25 +18,23 @@ import java.util.Optional;
|
||||
|
||||
public abstract class HandleGeneric
|
||||
{
|
||||
private Closeable closable;
|
||||
private boolean open = true;
|
||||
private TrackingCloseable closeable;
|
||||
|
||||
protected HandleGeneric( @Nonnull Closeable closable )
|
||||
protected HandleGeneric( @Nonnull TrackingCloseable closeable )
|
||||
{
|
||||
this.closable = closable;
|
||||
this.closeable = closeable;
|
||||
}
|
||||
|
||||
protected void checkOpen() throws LuaException
|
||||
{
|
||||
if( !open ) throw new LuaException( "attempt to use a closed file" );
|
||||
TrackingCloseable closeable = this.closeable;
|
||||
if( closeable == null || !closeable.isOpen() ) throw new LuaException( "attempt to use a closed file" );
|
||||
}
|
||||
|
||||
protected final void close()
|
||||
{
|
||||
open = false;
|
||||
|
||||
IoUtil.closeQuietly( closable );
|
||||
closable = null;
|
||||
IoUtil.closeQuietly( closeable );
|
||||
closeable = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,28 +32,28 @@ public class Computer
|
||||
private static final int START_DELAY = 50;
|
||||
|
||||
// Various properties of the computer
|
||||
private int m_id;
|
||||
private String m_label = null;
|
||||
private int id;
|
||||
private String label = null;
|
||||
|
||||
// Read-only fields about the computer
|
||||
private final IComputerEnvironment m_environment;
|
||||
private final Terminal m_terminal;
|
||||
private final IComputerEnvironment environment;
|
||||
private final Terminal terminal;
|
||||
private final ComputerExecutor executor;
|
||||
private final MainThreadExecutor serverExecutor;
|
||||
|
||||
// Additional state about the computer and its environment.
|
||||
private boolean m_blinking = false;
|
||||
private boolean blinking = false;
|
||||
private final Environment internalEnvironment = new Environment( this );
|
||||
private final AtomicBoolean externalOutputChanged = new AtomicBoolean();
|
||||
|
||||
private boolean startRequested;
|
||||
private int m_ticksSinceStart = -1;
|
||||
private int ticksSinceStart = -1;
|
||||
|
||||
public Computer( IComputerEnvironment environment, Terminal terminal, int id )
|
||||
{
|
||||
m_id = id;
|
||||
m_environment = environment;
|
||||
m_terminal = terminal;
|
||||
this.id = id;
|
||||
this.environment = environment;
|
||||
this.terminal = terminal;
|
||||
|
||||
executor = new ComputerExecutor( this );
|
||||
serverExecutor = new MainThreadExecutor( this );
|
||||
@ -61,7 +61,7 @@ public class Computer
|
||||
|
||||
IComputerEnvironment getComputerEnvironment()
|
||||
{
|
||||
return m_environment;
|
||||
return environment;
|
||||
}
|
||||
|
||||
FileSystem getFileSystem()
|
||||
@ -71,7 +71,7 @@ public class Computer
|
||||
|
||||
Terminal getTerminal()
|
||||
{
|
||||
return m_terminal;
|
||||
return terminal;
|
||||
}
|
||||
|
||||
public Environment getEnvironment()
|
||||
@ -132,33 +132,33 @@ public class Computer
|
||||
|
||||
public int getID()
|
||||
{
|
||||
return m_id;
|
||||
return id;
|
||||
}
|
||||
|
||||
public int assignID()
|
||||
{
|
||||
if( m_id < 0 )
|
||||
if( id < 0 )
|
||||
{
|
||||
m_id = m_environment.assignNewID();
|
||||
id = environment.assignNewID();
|
||||
}
|
||||
return m_id;
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setID( int id )
|
||||
{
|
||||
m_id = id;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getLabel()
|
||||
{
|
||||
return m_label;
|
||||
return label;
|
||||
}
|
||||
|
||||
public void setLabel( String label )
|
||||
{
|
||||
if( !Objects.equal( label, m_label ) )
|
||||
if( !Objects.equal( label, this.label ) )
|
||||
{
|
||||
m_label = label;
|
||||
this.label = label;
|
||||
externalOutputChanged.set( true );
|
||||
}
|
||||
}
|
||||
@ -166,14 +166,14 @@ public class Computer
|
||||
public void tick()
|
||||
{
|
||||
// We keep track of the number of ticks since the last start, only
|
||||
if( m_ticksSinceStart >= 0 && m_ticksSinceStart <= START_DELAY ) m_ticksSinceStart++;
|
||||
if( ticksSinceStart >= 0 && ticksSinceStart <= START_DELAY ) ticksSinceStart++;
|
||||
|
||||
if( startRequested && (m_ticksSinceStart < 0 || m_ticksSinceStart > START_DELAY) )
|
||||
if( startRequested && (ticksSinceStart < 0 || ticksSinceStart > START_DELAY) )
|
||||
{
|
||||
startRequested = false;
|
||||
if( !executor.isOn() )
|
||||
{
|
||||
m_ticksSinceStart = 0;
|
||||
ticksSinceStart = 0;
|
||||
executor.queueStart();
|
||||
}
|
||||
}
|
||||
@ -187,12 +187,12 @@ public class Computer
|
||||
if( internalEnvironment.updateOutput() ) externalOutputChanged.set( true );
|
||||
|
||||
// Set output changed if the terminal has changed from blinking to not
|
||||
boolean blinking = m_terminal.getCursorBlink() &&
|
||||
m_terminal.getCursorX() >= 0 && m_terminal.getCursorX() < m_terminal.getWidth() &&
|
||||
m_terminal.getCursorY() >= 0 && m_terminal.getCursorY() < m_terminal.getHeight();
|
||||
if( blinking != m_blinking )
|
||||
boolean blinking = terminal.getCursorBlink() &&
|
||||
terminal.getCursorX() >= 0 && terminal.getCursorX() < terminal.getWidth() &&
|
||||
terminal.getCursorY() >= 0 && terminal.getCursorY() < terminal.getHeight();
|
||||
if( blinking != this.blinking )
|
||||
{
|
||||
m_blinking = blinking;
|
||||
this.blinking = blinking;
|
||||
externalOutputChanged.set( true );
|
||||
}
|
||||
}
|
||||
@ -209,7 +209,7 @@ public class Computer
|
||||
|
||||
public boolean isBlinking()
|
||||
{
|
||||
return isOn() && m_blinking;
|
||||
return isOn() && blinking;
|
||||
}
|
||||
|
||||
public void addApi( ILuaAPI api )
|
||||
|
@ -20,8 +20,6 @@ import javax.annotation.Nonnull;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import dan200.computercraft.core.apis.IAPIEnvironment.IPeripheralChangeListener;
|
||||
|
||||
/**
|
||||
* Represents the "environment" that a {@link Computer} exists in.
|
||||
*
|
||||
|
@ -42,7 +42,7 @@ class ChannelWrapper<T extends Closeable> implements Closeable
|
||||
}
|
||||
}
|
||||
|
||||
public T get()
|
||||
T get()
|
||||
{
|
||||
return wrapper;
|
||||
}
|
||||
|
@ -19,11 +19,11 @@ import java.util.Set;
|
||||
|
||||
public class ComboMount implements IMount
|
||||
{
|
||||
private IMount[] m_parts;
|
||||
private final IMount[] parts;
|
||||
|
||||
public ComboMount( IMount[] parts )
|
||||
{
|
||||
m_parts = parts;
|
||||
this.parts = parts;
|
||||
}
|
||||
|
||||
// IMount implementation
|
||||
@ -31,9 +31,9 @@ public class ComboMount implements IMount
|
||||
@Override
|
||||
public boolean exists( @Nonnull String path ) throws IOException
|
||||
{
|
||||
for( int i = m_parts.length - 1; i >= 0; --i )
|
||||
for( int i = parts.length - 1; i >= 0; --i )
|
||||
{
|
||||
IMount part = m_parts[i];
|
||||
IMount part = parts[i];
|
||||
if( part.exists( path ) )
|
||||
{
|
||||
return true;
|
||||
@ -45,9 +45,9 @@ public class ComboMount implements IMount
|
||||
@Override
|
||||
public boolean isDirectory( @Nonnull String path ) throws IOException
|
||||
{
|
||||
for( int i = m_parts.length - 1; i >= 0; --i )
|
||||
for( int i = parts.length - 1; i >= 0; --i )
|
||||
{
|
||||
IMount part = m_parts[i];
|
||||
IMount part = parts[i];
|
||||
if( part.isDirectory( path ) )
|
||||
{
|
||||
return true;
|
||||
@ -62,9 +62,9 @@ public class ComboMount implements IMount
|
||||
// Combine the lists from all the mounts
|
||||
List<String> foundFiles = null;
|
||||
int foundDirs = 0;
|
||||
for( int i = m_parts.length - 1; i >= 0; --i )
|
||||
for( int i = parts.length - 1; i >= 0; --i )
|
||||
{
|
||||
IMount part = m_parts[i];
|
||||
IMount part = parts[i];
|
||||
if( part.exists( path ) && part.isDirectory( path ) )
|
||||
{
|
||||
if( foundFiles == null )
|
||||
@ -102,9 +102,9 @@ public class ComboMount implements IMount
|
||||
@Override
|
||||
public long getSize( @Nonnull String path ) throws IOException
|
||||
{
|
||||
for( int i = m_parts.length - 1; i >= 0; --i )
|
||||
for( int i = parts.length - 1; i >= 0; --i )
|
||||
{
|
||||
IMount part = m_parts[i];
|
||||
IMount part = parts[i];
|
||||
if( part.exists( path ) )
|
||||
{
|
||||
return part.getSize( path );
|
||||
@ -117,9 +117,9 @@ public class ComboMount implements IMount
|
||||
@Override
|
||||
public ReadableByteChannel openForRead( @Nonnull String path ) throws IOException
|
||||
{
|
||||
for( int i = m_parts.length - 1; i >= 0; --i )
|
||||
for( int i = parts.length - 1; i >= 0; --i )
|
||||
{
|
||||
IMount part = m_parts[i];
|
||||
IMount part = parts[i];
|
||||
if( part.exists( path ) && !part.isDirectory( path ) )
|
||||
{
|
||||
return part.openForRead( path );
|
||||
@ -132,9 +132,9 @@ public class ComboMount implements IMount
|
||||
@Override
|
||||
public BasicFileAttributes getAttributes( @Nonnull String path ) throws IOException
|
||||
{
|
||||
for( int i = m_parts.length - 1; i >= 0; --i )
|
||||
for( int i = parts.length - 1; i >= 0; --i )
|
||||
{
|
||||
IMount part = m_parts[i];
|
||||
IMount part = parts[i];
|
||||
if( part.exists( path ) && !part.isDirectory( path ) )
|
||||
{
|
||||
return part.getAttributes( path );
|
||||
|
@ -32,57 +32,57 @@ public class FileMount implements IWritableMount
|
||||
private class WritableCountingChannel implements WritableByteChannel
|
||||
{
|
||||
|
||||
private final WritableByteChannel m_inner;
|
||||
long m_ignoredBytesLeft;
|
||||
private final WritableByteChannel inner;
|
||||
long ignoredBytesLeft;
|
||||
|
||||
WritableCountingChannel( WritableByteChannel inner, long bytesToIgnore )
|
||||
{
|
||||
m_inner = inner;
|
||||
m_ignoredBytesLeft = bytesToIgnore;
|
||||
this.inner = inner;
|
||||
ignoredBytesLeft = bytesToIgnore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int write( @Nonnull ByteBuffer b ) throws IOException
|
||||
{
|
||||
count( b.remaining() );
|
||||
return m_inner.write( b );
|
||||
return inner.write( b );
|
||||
}
|
||||
|
||||
void count( long n ) throws IOException
|
||||
{
|
||||
m_ignoredBytesLeft -= n;
|
||||
if( m_ignoredBytesLeft < 0 )
|
||||
ignoredBytesLeft -= n;
|
||||
if( ignoredBytesLeft < 0 )
|
||||
{
|
||||
long newBytes = -m_ignoredBytesLeft;
|
||||
m_ignoredBytesLeft = 0;
|
||||
long newBytes = -ignoredBytesLeft;
|
||||
ignoredBytesLeft = 0;
|
||||
|
||||
long bytesLeft = m_capacity - m_usedSpace;
|
||||
long bytesLeft = capacity - usedSpace;
|
||||
if( newBytes > bytesLeft ) throw new IOException( "Out of space" );
|
||||
m_usedSpace += newBytes;
|
||||
usedSpace += newBytes;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen()
|
||||
{
|
||||
return m_inner.isOpen();
|
||||
return inner.isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
m_inner.close();
|
||||
inner.close();
|
||||
}
|
||||
}
|
||||
|
||||
private class SeekableCountingChannel extends WritableCountingChannel implements SeekableByteChannel
|
||||
{
|
||||
private final SeekableByteChannel m_inner;
|
||||
private final SeekableByteChannel inner;
|
||||
|
||||
SeekableCountingChannel( SeekableByteChannel inner, long bytesToIgnore )
|
||||
{
|
||||
super( inner, bytesToIgnore );
|
||||
m_inner = inner;
|
||||
this.inner = inner;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -94,17 +94,17 @@ public class FileMount implements IWritableMount
|
||||
throw new IllegalArgumentException( "Cannot seek before the beginning of the stream" );
|
||||
}
|
||||
|
||||
long delta = newPosition - m_inner.position();
|
||||
long delta = newPosition - inner.position();
|
||||
if( delta < 0 )
|
||||
{
|
||||
m_ignoredBytesLeft -= delta;
|
||||
ignoredBytesLeft -= delta;
|
||||
}
|
||||
else
|
||||
{
|
||||
count( delta );
|
||||
}
|
||||
|
||||
return m_inner.position( newPosition );
|
||||
return inner.position( newPosition );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -116,32 +116,32 @@ public class FileMount implements IWritableMount
|
||||
@Override
|
||||
public int read( ByteBuffer dst ) throws ClosedChannelException
|
||||
{
|
||||
if( !m_inner.isOpen() ) throw new ClosedChannelException();
|
||||
if( !inner.isOpen() ) throw new ClosedChannelException();
|
||||
throw new NonReadableChannelException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long position() throws IOException
|
||||
{
|
||||
return m_inner.position();
|
||||
return inner.position();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long size() throws IOException
|
||||
{
|
||||
return m_inner.size();
|
||||
return inner.size();
|
||||
}
|
||||
}
|
||||
|
||||
private File m_rootPath;
|
||||
private long m_capacity;
|
||||
private long m_usedSpace;
|
||||
private final File rootPath;
|
||||
private final long capacity;
|
||||
private long usedSpace;
|
||||
|
||||
public FileMount( File rootPath, long capacity )
|
||||
{
|
||||
m_rootPath = rootPath;
|
||||
m_capacity = capacity + MINIMUM_FILE_SIZE;
|
||||
m_usedSpace = created() ? measureUsedSpace( m_rootPath ) : MINIMUM_FILE_SIZE;
|
||||
this.rootPath = rootPath;
|
||||
this.capacity = capacity + MINIMUM_FILE_SIZE;
|
||||
usedSpace = created() ? measureUsedSpace( this.rootPath ) : MINIMUM_FILE_SIZE;
|
||||
}
|
||||
|
||||
// IMount implementation
|
||||
@ -253,7 +253,7 @@ public class FileMount implements IWritableMount
|
||||
|
||||
if( file.mkdirs() )
|
||||
{
|
||||
m_usedSpace += dirsToCreate * MINIMUM_FILE_SIZE;
|
||||
usedSpace += dirsToCreate * MINIMUM_FILE_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -290,7 +290,7 @@ public class FileMount implements IWritableMount
|
||||
boolean success = file.delete();
|
||||
if( success )
|
||||
{
|
||||
m_usedSpace -= Math.max( MINIMUM_FILE_SIZE, fileSize );
|
||||
usedSpace -= Math.max( MINIMUM_FILE_SIZE, fileSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -308,13 +308,13 @@ public class FileMount implements IWritableMount
|
||||
|
||||
if( file.exists() )
|
||||
{
|
||||
m_usedSpace -= Math.max( file.length(), MINIMUM_FILE_SIZE );
|
||||
usedSpace -= Math.max( file.length(), MINIMUM_FILE_SIZE );
|
||||
}
|
||||
else if( getRemainingSpace() < MINIMUM_FILE_SIZE )
|
||||
{
|
||||
throw new FileOperationException( path, "Out of space" );
|
||||
}
|
||||
m_usedSpace += MINIMUM_FILE_SIZE;
|
||||
usedSpace += MINIMUM_FILE_SIZE;
|
||||
|
||||
return new SeekableCountingChannel( Files.newByteChannel( file.toPath(), WRITE_OPTIONS ), MINIMUM_FILE_SIZE );
|
||||
}
|
||||
@ -342,31 +342,31 @@ public class FileMount implements IWritableMount
|
||||
@Override
|
||||
public long getRemainingSpace()
|
||||
{
|
||||
return Math.max( m_capacity - m_usedSpace, 0 );
|
||||
return Math.max( capacity - usedSpace, 0 );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public OptionalLong getCapacity()
|
||||
{
|
||||
return OptionalLong.of( m_capacity - MINIMUM_FILE_SIZE );
|
||||
return OptionalLong.of( capacity - MINIMUM_FILE_SIZE );
|
||||
}
|
||||
|
||||
private File getRealPath( String path )
|
||||
{
|
||||
return new File( m_rootPath, path );
|
||||
return new File( rootPath, path );
|
||||
}
|
||||
|
||||
private boolean created()
|
||||
{
|
||||
return m_rootPath.exists();
|
||||
return rootPath.exists();
|
||||
}
|
||||
|
||||
private void create() throws IOException
|
||||
{
|
||||
if( !m_rootPath.exists() )
|
||||
if( !rootPath.exists() )
|
||||
{
|
||||
boolean success = m_rootPath.mkdirs();
|
||||
boolean success = rootPath.mkdirs();
|
||||
if( !success )
|
||||
{
|
||||
throw new IOException( "Access denied" );
|
||||
|
@ -37,11 +37,11 @@ public class FileSystem
|
||||
*/
|
||||
private static final int MAX_COPY_DEPTH = 128;
|
||||
|
||||
private final FileSystemWrapperMount m_wrapper = new FileSystemWrapperMount( this );
|
||||
private final FileSystemWrapperMount wrapper = new FileSystemWrapperMount( this );
|
||||
private final Map<String, MountWrapper> mounts = new HashMap<>();
|
||||
|
||||
private final HashMap<WeakReference<FileSystemWrapper<?>>, ChannelWrapper<?>> m_openFiles = new HashMap<>();
|
||||
private final ReferenceQueue<FileSystemWrapper<?>> m_openFileQueue = new ReferenceQueue<>();
|
||||
private final HashMap<WeakReference<FileSystemWrapper<?>>, ChannelWrapper<?>> openFiles = new HashMap<>();
|
||||
private final ReferenceQueue<FileSystemWrapper<?>> openFileQueue = new ReferenceQueue<>();
|
||||
|
||||
public FileSystem( String rootLabel, IMount rootMount ) throws FileSystemException
|
||||
{
|
||||
@ -56,11 +56,11 @@ public class FileSystem
|
||||
public void close()
|
||||
{
|
||||
// Close all dangling open files
|
||||
synchronized( m_openFiles )
|
||||
synchronized( openFiles )
|
||||
{
|
||||
for( Closeable file : m_openFiles.values() ) IoUtil.closeQuietly( file );
|
||||
m_openFiles.clear();
|
||||
while( m_openFileQueue.poll() != null ) ;
|
||||
for( Closeable file : openFiles.values() ) IoUtil.closeQuietly( file );
|
||||
openFiles.clear();
|
||||
while( openFileQueue.poll() != null ) ;
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +95,29 @@ public class FileSystem
|
||||
|
||||
public synchronized void unmount( String path )
|
||||
{
|
||||
mounts.remove( sanitizePath( path ) );
|
||||
MountWrapper mount = mounts.remove( sanitizePath( path ) );
|
||||
if( mount == null ) return;
|
||||
|
||||
cleanup();
|
||||
|
||||
// Close any files which belong to this mount - don't want people writing to a disk after it's been ejected!
|
||||
// There's no point storing a Mount -> Wrapper[] map, as openFiles is small and unmount isn't called very
|
||||
// often.
|
||||
synchronized( openFiles )
|
||||
{
|
||||
for( Iterator<WeakReference<FileSystemWrapper<?>>> iterator = openFiles.keySet().iterator(); iterator.hasNext(); )
|
||||
{
|
||||
WeakReference<FileSystemWrapper<?>> reference = iterator.next();
|
||||
FileSystemWrapper<?> wrapper = reference.get();
|
||||
if( wrapper == null ) continue;
|
||||
|
||||
if( wrapper.mount == mount )
|
||||
{
|
||||
wrapper.closeExternally();
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String combine( String path, String childPath )
|
||||
@ -361,22 +383,22 @@ public class FileSystem
|
||||
|
||||
private void cleanup()
|
||||
{
|
||||
synchronized( m_openFiles )
|
||||
synchronized( openFiles )
|
||||
{
|
||||
Reference<?> ref;
|
||||
while( (ref = m_openFileQueue.poll()) != null )
|
||||
while( (ref = openFileQueue.poll()) != null )
|
||||
{
|
||||
IoUtil.closeQuietly( m_openFiles.remove( ref ) );
|
||||
IoUtil.closeQuietly( openFiles.remove( ref ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized <T extends Closeable> FileSystemWrapper<T> openFile( @Nonnull Channel channel, @Nonnull T file ) throws FileSystemException
|
||||
private synchronized <T extends Closeable> FileSystemWrapper<T> openFile( @Nonnull MountWrapper mount, @Nonnull Channel channel, @Nonnull T file ) throws FileSystemException
|
||||
{
|
||||
synchronized( m_openFiles )
|
||||
synchronized( openFiles )
|
||||
{
|
||||
if( ComputerCraft.maximumFilesOpen > 0 &&
|
||||
m_openFiles.size() >= ComputerCraft.maximumFilesOpen )
|
||||
openFiles.size() >= ComputerCraft.maximumFilesOpen )
|
||||
{
|
||||
IoUtil.closeQuietly( file );
|
||||
IoUtil.closeQuietly( channel );
|
||||
@ -384,17 +406,17 @@ public class FileSystem
|
||||
}
|
||||
|
||||
ChannelWrapper<T> channelWrapper = new ChannelWrapper<>( file, channel );
|
||||
FileSystemWrapper<T> fsWrapper = new FileSystemWrapper<>( this, channelWrapper, m_openFileQueue );
|
||||
m_openFiles.put( fsWrapper.self, channelWrapper );
|
||||
FileSystemWrapper<T> fsWrapper = new FileSystemWrapper<>( this, mount, channelWrapper, openFileQueue );
|
||||
openFiles.put( fsWrapper.self, channelWrapper );
|
||||
return fsWrapper;
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void removeFile( FileSystemWrapper<?> handle )
|
||||
void removeFile( FileSystemWrapper<?> handle )
|
||||
{
|
||||
synchronized( m_openFiles )
|
||||
synchronized( openFiles )
|
||||
{
|
||||
m_openFiles.remove( handle.self );
|
||||
openFiles.remove( handle.self );
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,11 +427,7 @@ public class FileSystem
|
||||
path = sanitizePath( path );
|
||||
MountWrapper mount = getMount( path );
|
||||
ReadableByteChannel channel = mount.openForRead( path );
|
||||
if( channel != null )
|
||||
{
|
||||
return openFile( channel, open.apply( channel ) );
|
||||
}
|
||||
return null;
|
||||
return channel != null ? openFile( mount, channel, open.apply( channel ) ) : null;
|
||||
}
|
||||
|
||||
public synchronized <T extends Closeable> FileSystemWrapper<T> openForWrite( String path, boolean append, Function<WritableByteChannel, T> open ) throws FileSystemException
|
||||
@ -419,11 +437,7 @@ public class FileSystem
|
||||
path = sanitizePath( path );
|
||||
MountWrapper mount = getMount( path );
|
||||
WritableByteChannel channel = append ? mount.openForAppend( path ) : mount.openForWrite( path );
|
||||
if( channel != null )
|
||||
{
|
||||
return openFile( channel, open.apply( channel ) );
|
||||
}
|
||||
return null;
|
||||
return channel != null ? openFile( mount, channel, open.apply( channel ) ) : null;
|
||||
}
|
||||
|
||||
public synchronized long getFreeSpace( String path ) throws FileSystemException
|
||||
@ -469,7 +483,7 @@ public class FileSystem
|
||||
|
||||
public IFileSystem getMountWrapper()
|
||||
{
|
||||
return m_wrapper;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
private static String sanitizePath( String path )
|
||||
|
@ -5,6 +5,8 @@
|
||||
*/
|
||||
package dan200.computercraft.core.filesystem;
|
||||
|
||||
import dan200.computercraft.shared.util.IoUtil;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
@ -24,15 +26,18 @@ import java.lang.ref.WeakReference;
|
||||
*
|
||||
* @param <T> The type of writer or channel to wrap.
|
||||
*/
|
||||
public class FileSystemWrapper<T extends Closeable> implements Closeable
|
||||
public class FileSystemWrapper<T extends Closeable> implements TrackingCloseable
|
||||
{
|
||||
private final FileSystem fileSystem;
|
||||
final MountWrapper mount;
|
||||
private final ChannelWrapper<T> closeable;
|
||||
final WeakReference<FileSystemWrapper<?>> self;
|
||||
private boolean isOpen = true;
|
||||
|
||||
FileSystemWrapper( FileSystem fileSystem, ChannelWrapper<T> closeable, ReferenceQueue<FileSystemWrapper<?>> queue )
|
||||
FileSystemWrapper( FileSystem fileSystem, MountWrapper mount, ChannelWrapper<T> closeable, ReferenceQueue<FileSystemWrapper<?>> queue )
|
||||
{
|
||||
this.fileSystem = fileSystem;
|
||||
this.mount = mount;
|
||||
this.closeable = closeable;
|
||||
self = new WeakReference<>( this, queue );
|
||||
}
|
||||
@ -40,10 +45,23 @@ public class FileSystemWrapper<T extends Closeable> implements Closeable
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
isOpen = false;
|
||||
fileSystem.removeFile( this );
|
||||
closeable.close();
|
||||
}
|
||||
|
||||
void closeExternally()
|
||||
{
|
||||
isOpen = false;
|
||||
IoUtil.closeQuietly( closeable );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen()
|
||||
{
|
||||
return isOpen;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public T get()
|
||||
{
|
||||
|
@ -17,11 +17,11 @@ import java.util.function.Function;
|
||||
|
||||
public class FileSystemWrapperMount implements IFileSystem
|
||||
{
|
||||
private final FileSystem m_filesystem;
|
||||
private final FileSystem filesystem;
|
||||
|
||||
public FileSystemWrapperMount( FileSystem filesystem )
|
||||
{
|
||||
this.m_filesystem = filesystem;
|
||||
this.filesystem = filesystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -29,7 +29,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
||||
{
|
||||
try
|
||||
{
|
||||
m_filesystem.makeDir( path );
|
||||
filesystem.makeDir( path );
|
||||
}
|
||||
catch( FileSystemException e )
|
||||
{
|
||||
@ -42,7 +42,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
||||
{
|
||||
try
|
||||
{
|
||||
m_filesystem.delete( path );
|
||||
filesystem.delete( path );
|
||||
}
|
||||
catch( FileSystemException e )
|
||||
{
|
||||
@ -57,7 +57,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
||||
try
|
||||
{
|
||||
// FIXME: Think of a better way of implementing this, so closing this will close on the computer.
|
||||
return m_filesystem.openForRead( path, Function.identity() ).get();
|
||||
return filesystem.openForRead( path, Function.identity() ).get();
|
||||
}
|
||||
catch( FileSystemException e )
|
||||
{
|
||||
@ -71,7 +71,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_filesystem.openForWrite( path, false, Function.identity() ).get();
|
||||
return filesystem.openForWrite( path, false, Function.identity() ).get();
|
||||
}
|
||||
catch( FileSystemException e )
|
||||
{
|
||||
@ -85,7 +85,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_filesystem.openForWrite( path, true, Function.identity() ).get();
|
||||
return filesystem.openForWrite( path, true, Function.identity() ).get();
|
||||
}
|
||||
catch( FileSystemException e )
|
||||
{
|
||||
@ -98,7 +98,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_filesystem.getFreeSpace( "/" );
|
||||
return filesystem.getFreeSpace( "/" );
|
||||
}
|
||||
catch( FileSystemException e )
|
||||
{
|
||||
@ -111,7 +111,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_filesystem.exists( path );
|
||||
return filesystem.exists( path );
|
||||
}
|
||||
catch( FileSystemException e )
|
||||
{
|
||||
@ -124,7 +124,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_filesystem.isDir( path );
|
||||
return filesystem.isDir( path );
|
||||
}
|
||||
catch( FileSystemException e )
|
||||
{
|
||||
@ -137,7 +137,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
||||
{
|
||||
try
|
||||
{
|
||||
Collections.addAll( contents, m_filesystem.list( path ) );
|
||||
Collections.addAll( contents, filesystem.list( path ) );
|
||||
}
|
||||
catch( FileSystemException e )
|
||||
{
|
||||
@ -150,7 +150,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_filesystem.getSize( path );
|
||||
return filesystem.getSize( path );
|
||||
}
|
||||
catch( FileSystemException e )
|
||||
{
|
||||
@ -161,7 +161,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
||||
@Override
|
||||
public String combine( String path, String child )
|
||||
{
|
||||
return m_filesystem.combine( path, child );
|
||||
return filesystem.combine( path, child );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -169,7 +169,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
||||
{
|
||||
try
|
||||
{
|
||||
m_filesystem.copy( from, to );
|
||||
filesystem.copy( from, to );
|
||||
}
|
||||
catch( FileSystemException e )
|
||||
{
|
||||
@ -182,7 +182,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
||||
{
|
||||
try
|
||||
{
|
||||
m_filesystem.move( from, to );
|
||||
filesystem.move( from, to );
|
||||
}
|
||||
catch( FileSystemException e )
|
||||
{
|
||||
|
@ -15,8 +15,8 @@ import java.util.List;
|
||||
|
||||
public class SubMount implements IMount
|
||||
{
|
||||
private IMount parent;
|
||||
private String subPath;
|
||||
private final IMount parent;
|
||||
private final String subPath;
|
||||
|
||||
public SubMount( IMount parent, String subPath )
|
||||
{
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.core.filesystem;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A {@link Closeable} which knows when it has been closed.
|
||||
*
|
||||
* This is a quick (though racey) way of providing more friendly (and more similar to Lua)
|
||||
* error messages to the user.
|
||||
*/
|
||||
public interface TrackingCloseable extends Closeable
|
||||
{
|
||||
boolean isOpen();
|
||||
|
||||
class Impl implements TrackingCloseable
|
||||
{
|
||||
private final Closeable object;
|
||||
private boolean isOpen = true;
|
||||
|
||||
public Impl( Closeable object )
|
||||
{
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen()
|
||||
{
|
||||
return isOpen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
isOpen = false;
|
||||
object.close();
|
||||
}
|
||||
}
|
||||
}
|
@ -50,29 +50,29 @@ public class CobaltLuaMachine implements ILuaMachine
|
||||
|
||||
private static final LuaMethod FUNCTION_METHOD = ( target, context, args ) -> ((ILuaFunction) target).call( args );
|
||||
|
||||
private final Computer m_computer;
|
||||
private final Computer computer;
|
||||
private final TimeoutState timeout;
|
||||
private final TimeoutDebugHandler debug;
|
||||
private final ILuaContext context = new CobaltLuaContext();
|
||||
|
||||
private LuaState m_state;
|
||||
private LuaTable m_globals;
|
||||
private LuaState state;
|
||||
private LuaTable globals;
|
||||
|
||||
private LuaThread m_mainRoutine = null;
|
||||
private String m_eventFilter = null;
|
||||
private LuaThread mainRoutine = null;
|
||||
private String eventFilter = null;
|
||||
|
||||
public CobaltLuaMachine( Computer computer, TimeoutState timeout )
|
||||
{
|
||||
m_computer = computer;
|
||||
this.computer = computer;
|
||||
this.timeout = timeout;
|
||||
debug = new TimeoutDebugHandler();
|
||||
|
||||
// Create an environment to run in
|
||||
LuaState state = m_state = LuaState.builder()
|
||||
LuaState state = this.state = LuaState.builder()
|
||||
.resourceManipulator( new VoidResourceManipulator() )
|
||||
.debug( debug )
|
||||
.coroutineExecutor( command -> {
|
||||
Tracking.addValue( m_computer, TrackingField.COROUTINES_CREATED, 1 );
|
||||
Tracking.addValue( this.computer, TrackingField.COROUTINES_CREATED, 1 );
|
||||
COROUTINES.execute( () -> {
|
||||
try
|
||||
{
|
||||
@ -80,38 +80,38 @@ public class CobaltLuaMachine implements ILuaMachine
|
||||
}
|
||||
finally
|
||||
{
|
||||
Tracking.addValue( m_computer, TrackingField.COROUTINES_DISPOSED, 1 );
|
||||
Tracking.addValue( this.computer, TrackingField.COROUTINES_DISPOSED, 1 );
|
||||
}
|
||||
} );
|
||||
} )
|
||||
.build();
|
||||
|
||||
m_globals = new LuaTable();
|
||||
state.setupThread( m_globals );
|
||||
globals = new LuaTable();
|
||||
state.setupThread( globals );
|
||||
|
||||
// Add basic libraries
|
||||
m_globals.load( state, new BaseLib() );
|
||||
m_globals.load( state, new TableLib() );
|
||||
m_globals.load( state, new StringLib() );
|
||||
m_globals.load( state, new MathLib() );
|
||||
m_globals.load( state, new CoroutineLib() );
|
||||
m_globals.load( state, new Bit32Lib() );
|
||||
m_globals.load( state, new Utf8Lib() );
|
||||
if( ComputerCraft.debugEnable ) m_globals.load( state, new DebugLib() );
|
||||
globals.load( state, new BaseLib() );
|
||||
globals.load( state, new TableLib() );
|
||||
globals.load( state, new StringLib() );
|
||||
globals.load( state, new MathLib() );
|
||||
globals.load( state, new CoroutineLib() );
|
||||
globals.load( state, new Bit32Lib() );
|
||||
globals.load( state, new Utf8Lib() );
|
||||
if( ComputerCraft.debugEnable ) globals.load( state, new DebugLib() );
|
||||
|
||||
// Remove globals we don't want to expose
|
||||
m_globals.rawset( "collectgarbage", Constants.NIL );
|
||||
m_globals.rawset( "dofile", Constants.NIL );
|
||||
m_globals.rawset( "loadfile", Constants.NIL );
|
||||
m_globals.rawset( "print", Constants.NIL );
|
||||
globals.rawset( "collectgarbage", Constants.NIL );
|
||||
globals.rawset( "dofile", Constants.NIL );
|
||||
globals.rawset( "loadfile", Constants.NIL );
|
||||
globals.rawset( "print", Constants.NIL );
|
||||
|
||||
// Add version globals
|
||||
m_globals.rawset( "_VERSION", valueOf( "Lua 5.1" ) );
|
||||
m_globals.rawset( "_HOST", valueOf( computer.getAPIEnvironment().getComputerEnvironment().getHostString() ) );
|
||||
m_globals.rawset( "_CC_DEFAULT_SETTINGS", valueOf( ComputerCraft.defaultComputerSettings ) );
|
||||
globals.rawset( "_VERSION", valueOf( "Lua 5.1" ) );
|
||||
globals.rawset( "_HOST", valueOf( computer.getAPIEnvironment().getComputerEnvironment().getHostString() ) );
|
||||
globals.rawset( "_CC_DEFAULT_SETTINGS", valueOf( ComputerCraft.defaultComputerSettings ) );
|
||||
if( ComputerCraft.disableLua51Features )
|
||||
{
|
||||
m_globals.rawset( "_CC_DISABLE_LUA51_FEATURES", Constants.TRUE );
|
||||
globals.rawset( "_CC_DISABLE_LUA51_FEATURES", Constants.TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,19 +127,19 @@ public class CobaltLuaMachine implements ILuaMachine
|
||||
}
|
||||
|
||||
String[] names = api.getNames();
|
||||
for( String name : names ) m_globals.rawset( name, table );
|
||||
for( String name : names ) globals.rawset( name, table );
|
||||
}
|
||||
|
||||
@Override
|
||||
public MachineResult loadBios( @Nonnull InputStream bios )
|
||||
{
|
||||
// Begin executing a file (ie, the bios)
|
||||
if( m_mainRoutine != null ) return MachineResult.OK;
|
||||
if( mainRoutine != null ) return MachineResult.OK;
|
||||
|
||||
try
|
||||
{
|
||||
LuaFunction value = LoadState.load( m_state, bios, "@bios.lua", m_globals );
|
||||
m_mainRoutine = new LuaThread( m_state, value, m_globals );
|
||||
LuaFunction value = LoadState.load( state, bios, "@bios.lua", globals );
|
||||
mainRoutine = new LuaThread( state, value, globals );
|
||||
return MachineResult.OK;
|
||||
}
|
||||
catch( CompileException e )
|
||||
@ -158,9 +158,9 @@ public class CobaltLuaMachine implements ILuaMachine
|
||||
@Override
|
||||
public MachineResult handleEvent( String eventName, Object[] arguments )
|
||||
{
|
||||
if( m_mainRoutine == null ) return MachineResult.OK;
|
||||
if( mainRoutine == null ) return MachineResult.OK;
|
||||
|
||||
if( m_eventFilter != null && eventName != null && !eventName.equals( m_eventFilter ) && !eventName.equals( "terminate" ) )
|
||||
if( eventFilter != null && eventName != null && !eventName.equals( eventFilter ) && !eventName.equals( "terminate" ) )
|
||||
{
|
||||
return MachineResult.OK;
|
||||
}
|
||||
@ -178,17 +178,17 @@ public class CobaltLuaMachine implements ILuaMachine
|
||||
}
|
||||
|
||||
// Resume the current thread, or the main one when first starting off.
|
||||
LuaThread thread = m_state.getCurrentThread();
|
||||
if( thread == null || thread == m_state.getMainThread() ) thread = m_mainRoutine;
|
||||
LuaThread thread = state.getCurrentThread();
|
||||
if( thread == null || thread == state.getMainThread() ) thread = mainRoutine;
|
||||
|
||||
Varargs results = LuaThread.run( thread, resumeArgs );
|
||||
if( timeout.isHardAborted() ) throw HardAbortError.INSTANCE;
|
||||
if( results == null ) return MachineResult.PAUSE;
|
||||
|
||||
LuaValue filter = results.first();
|
||||
m_eventFilter = filter.isString() ? filter.toString() : null;
|
||||
eventFilter = filter.isString() ? filter.toString() : null;
|
||||
|
||||
if( m_mainRoutine.getStatus().equals( "dead" ) )
|
||||
if( mainRoutine.getStatus().equals( "dead" ) )
|
||||
{
|
||||
close();
|
||||
return MachineResult.GENERIC_ERROR;
|
||||
@ -214,13 +214,13 @@ public class CobaltLuaMachine implements ILuaMachine
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
LuaState state = m_state;
|
||||
LuaState state = this.state;
|
||||
if( state == null ) return;
|
||||
|
||||
state.abandon();
|
||||
m_mainRoutine = null;
|
||||
m_state = null;
|
||||
m_globals = null;
|
||||
mainRoutine = null;
|
||||
this.state = null;
|
||||
globals = null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -457,7 +457,7 @@ public class CobaltLuaMachine implements ILuaMachine
|
||||
if( (count = (count + 1) & 127) == 0 )
|
||||
{
|
||||
// If we've been hard aborted or closed then abort.
|
||||
if( timeout.isHardAborted() || m_state == null ) throw HardAbortError.INSTANCE;
|
||||
if( timeout.isHardAborted() || state == null ) throw HardAbortError.INSTANCE;
|
||||
|
||||
timeout.refresh();
|
||||
if( timeout.isPaused() )
|
||||
@ -483,7 +483,7 @@ public class CobaltLuaMachine implements ILuaMachine
|
||||
public void poll() throws LuaError
|
||||
{
|
||||
// If we've been hard aborted or closed then abort.
|
||||
LuaState state = m_state;
|
||||
LuaState state = CobaltLuaMachine.this.state;
|
||||
if( timeout.isHardAborted() || state == null ) throw HardAbortError.INSTANCE;
|
||||
|
||||
timeout.refresh();
|
||||
@ -526,26 +526,26 @@ public class CobaltLuaMachine implements ILuaMachine
|
||||
eventArguments[0] = taskID;
|
||||
eventArguments[1] = true;
|
||||
System.arraycopy( results, 0, eventArguments, 2, results.length );
|
||||
m_computer.queueEvent( "task_complete", eventArguments );
|
||||
computer.queueEvent( "task_complete", eventArguments );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_computer.queueEvent( "task_complete", new Object[] { taskID, true } );
|
||||
computer.queueEvent( "task_complete", new Object[] { taskID, true } );
|
||||
}
|
||||
}
|
||||
catch( LuaException e )
|
||||
{
|
||||
m_computer.queueEvent( "task_complete", new Object[] { taskID, false, e.getMessage() } );
|
||||
computer.queueEvent( "task_complete", new Object[] { taskID, false, e.getMessage() } );
|
||||
}
|
||||
catch( Throwable t )
|
||||
{
|
||||
if( ComputerCraft.logComputerErrors ) ComputerCraft.log.error( "Error running task", t );
|
||||
m_computer.queueEvent( "task_complete", new Object[] {
|
||||
computer.queueEvent( "task_complete", new Object[] {
|
||||
taskID, false, "Java Exception Thrown: " + t,
|
||||
} );
|
||||
}
|
||||
};
|
||||
if( m_computer.queueMainThread( iTask ) )
|
||||
if( computer.queueMainThread( iTask ) )
|
||||
{
|
||||
return taskID;
|
||||
}
|
||||
|
@ -16,20 +16,20 @@ public class Terminal
|
||||
{
|
||||
private static final String base16 = "0123456789abcdef";
|
||||
|
||||
private int m_cursorX = 0;
|
||||
private int m_cursorY = 0;
|
||||
private boolean m_cursorBlink = false;
|
||||
private int m_cursorColour = 0;
|
||||
private int m_cursorBackgroundColour = 15;
|
||||
private int cursorX = 0;
|
||||
private int cursorY = 0;
|
||||
private boolean cursorBlink = false;
|
||||
private int cursorColour = 0;
|
||||
private int cursorBackgroundColour = 15;
|
||||
|
||||
private int m_width;
|
||||
private int m_height;
|
||||
private int width;
|
||||
private int height;
|
||||
|
||||
private TextBuffer[] m_text;
|
||||
private TextBuffer[] m_textColour;
|
||||
private TextBuffer[] m_backgroundColour;
|
||||
private TextBuffer[] text;
|
||||
private TextBuffer[] textColour;
|
||||
private TextBuffer[] backgroundColour;
|
||||
|
||||
private final Palette m_palette = new Palette();
|
||||
private final Palette palette = new Palette();
|
||||
|
||||
private final Runnable onChanged;
|
||||
|
||||
@ -40,84 +40,84 @@ public class Terminal
|
||||
|
||||
public Terminal( int width, int height, Runnable changedCallback )
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
onChanged = changedCallback;
|
||||
|
||||
m_text = new TextBuffer[m_height];
|
||||
m_textColour = new TextBuffer[m_height];
|
||||
m_backgroundColour = new TextBuffer[m_height];
|
||||
for( int i = 0; i < m_height; i++ )
|
||||
text = new TextBuffer[this.height];
|
||||
textColour = new TextBuffer[this.height];
|
||||
backgroundColour = new TextBuffer[this.height];
|
||||
for( int i = 0; i < this.height; i++ )
|
||||
{
|
||||
m_text[i] = new TextBuffer( ' ', m_width );
|
||||
m_textColour[i] = new TextBuffer( base16.charAt( m_cursorColour ), m_width );
|
||||
m_backgroundColour[i] = new TextBuffer( base16.charAt( m_cursorBackgroundColour ), m_width );
|
||||
text[i] = new TextBuffer( ' ', this.width );
|
||||
textColour[i] = new TextBuffer( base16.charAt( cursorColour ), this.width );
|
||||
backgroundColour[i] = new TextBuffer( base16.charAt( cursorBackgroundColour ), this.width );
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void reset()
|
||||
{
|
||||
m_cursorColour = 0;
|
||||
m_cursorBackgroundColour = 15;
|
||||
m_cursorX = 0;
|
||||
m_cursorY = 0;
|
||||
m_cursorBlink = false;
|
||||
cursorColour = 0;
|
||||
cursorBackgroundColour = 15;
|
||||
cursorX = 0;
|
||||
cursorY = 0;
|
||||
cursorBlink = false;
|
||||
clear();
|
||||
setChanged();
|
||||
m_palette.resetColours();
|
||||
palette.resetColours();
|
||||
}
|
||||
|
||||
public int getWidth()
|
||||
{
|
||||
return m_width;
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
return m_height;
|
||||
return height;
|
||||
}
|
||||
|
||||
public synchronized void resize( int width, int height )
|
||||
{
|
||||
if( width == m_width && height == m_height )
|
||||
if( width == this.width && height == this.height )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int oldHeight = m_height;
|
||||
int oldWidth = m_width;
|
||||
TextBuffer[] oldText = m_text;
|
||||
TextBuffer[] oldTextColour = m_textColour;
|
||||
TextBuffer[] oldBackgroundColour = m_backgroundColour;
|
||||
int oldHeight = this.height;
|
||||
int oldWidth = this.width;
|
||||
TextBuffer[] oldText = text;
|
||||
TextBuffer[] oldTextColour = textColour;
|
||||
TextBuffer[] oldBackgroundColour = backgroundColour;
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
m_text = new TextBuffer[m_height];
|
||||
m_textColour = new TextBuffer[m_height];
|
||||
m_backgroundColour = new TextBuffer[m_height];
|
||||
for( int i = 0; i < m_height; i++ )
|
||||
text = new TextBuffer[this.height];
|
||||
textColour = new TextBuffer[this.height];
|
||||
backgroundColour = new TextBuffer[this.height];
|
||||
for( int i = 0; i < this.height; i++ )
|
||||
{
|
||||
if( i >= oldHeight )
|
||||
{
|
||||
m_text[i] = new TextBuffer( ' ', m_width );
|
||||
m_textColour[i] = new TextBuffer( base16.charAt( m_cursorColour ), m_width );
|
||||
m_backgroundColour[i] = new TextBuffer( base16.charAt( m_cursorBackgroundColour ), m_width );
|
||||
text[i] = new TextBuffer( ' ', this.width );
|
||||
textColour[i] = new TextBuffer( base16.charAt( cursorColour ), this.width );
|
||||
backgroundColour[i] = new TextBuffer( base16.charAt( cursorBackgroundColour ), this.width );
|
||||
}
|
||||
else if( m_width == oldWidth )
|
||||
else if( this.width == oldWidth )
|
||||
{
|
||||
m_text[i] = oldText[i];
|
||||
m_textColour[i] = oldTextColour[i];
|
||||
m_backgroundColour[i] = oldBackgroundColour[i];
|
||||
text[i] = oldText[i];
|
||||
textColour[i] = oldTextColour[i];
|
||||
backgroundColour[i] = oldBackgroundColour[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_text[i] = new TextBuffer( ' ', m_width );
|
||||
m_textColour[i] = new TextBuffer( base16.charAt( m_cursorColour ), m_width );
|
||||
m_backgroundColour[i] = new TextBuffer( base16.charAt( m_cursorBackgroundColour ), m_width );
|
||||
m_text[i].write( oldText[i] );
|
||||
m_textColour[i].write( oldTextColour[i] );
|
||||
m_backgroundColour[i].write( oldBackgroundColour[i] );
|
||||
text[i] = new TextBuffer( ' ', this.width );
|
||||
textColour[i] = new TextBuffer( base16.charAt( cursorColour ), this.width );
|
||||
backgroundColour[i] = new TextBuffer( base16.charAt( cursorBackgroundColour ), this.width );
|
||||
text[i].write( oldText[i] );
|
||||
textColour[i].write( oldTextColour[i] );
|
||||
backgroundColour[i].write( oldBackgroundColour[i] );
|
||||
}
|
||||
}
|
||||
setChanged();
|
||||
@ -125,94 +125,94 @@ public class Terminal
|
||||
|
||||
public void setCursorPos( int x, int y )
|
||||
{
|
||||
if( m_cursorX != x || m_cursorY != y )
|
||||
if( cursorX != x || cursorY != y )
|
||||
{
|
||||
m_cursorX = x;
|
||||
m_cursorY = y;
|
||||
cursorX = x;
|
||||
cursorY = y;
|
||||
setChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void setCursorBlink( boolean blink )
|
||||
{
|
||||
if( m_cursorBlink != blink )
|
||||
if( cursorBlink != blink )
|
||||
{
|
||||
m_cursorBlink = blink;
|
||||
cursorBlink = blink;
|
||||
setChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void setTextColour( int colour )
|
||||
{
|
||||
if( m_cursorColour != colour )
|
||||
if( cursorColour != colour )
|
||||
{
|
||||
m_cursorColour = colour;
|
||||
cursorColour = colour;
|
||||
setChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void setBackgroundColour( int colour )
|
||||
{
|
||||
if( m_cursorBackgroundColour != colour )
|
||||
if( cursorBackgroundColour != colour )
|
||||
{
|
||||
m_cursorBackgroundColour = colour;
|
||||
cursorBackgroundColour = colour;
|
||||
setChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public int getCursorX()
|
||||
{
|
||||
return m_cursorX;
|
||||
return cursorX;
|
||||
}
|
||||
|
||||
public int getCursorY()
|
||||
{
|
||||
return m_cursorY;
|
||||
return cursorY;
|
||||
}
|
||||
|
||||
public boolean getCursorBlink()
|
||||
{
|
||||
return m_cursorBlink;
|
||||
return cursorBlink;
|
||||
}
|
||||
|
||||
public int getTextColour()
|
||||
{
|
||||
return m_cursorColour;
|
||||
return cursorColour;
|
||||
}
|
||||
|
||||
public int getBackgroundColour()
|
||||
{
|
||||
return m_cursorBackgroundColour;
|
||||
return cursorBackgroundColour;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Palette getPalette()
|
||||
{
|
||||
return m_palette;
|
||||
return palette;
|
||||
}
|
||||
|
||||
public synchronized void blit( String text, String textColour, String backgroundColour )
|
||||
{
|
||||
int x = m_cursorX;
|
||||
int y = m_cursorY;
|
||||
if( y >= 0 && y < m_height )
|
||||
int x = cursorX;
|
||||
int y = cursorY;
|
||||
if( y >= 0 && y < height )
|
||||
{
|
||||
m_text[y].write( text, x );
|
||||
m_textColour[y].write( textColour, x );
|
||||
m_backgroundColour[y].write( backgroundColour, x );
|
||||
this.text[y].write( text, x );
|
||||
this.textColour[y].write( textColour, x );
|
||||
this.backgroundColour[y].write( backgroundColour, x );
|
||||
setChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void write( String text )
|
||||
{
|
||||
int x = m_cursorX;
|
||||
int y = m_cursorY;
|
||||
if( y >= 0 && y < m_height )
|
||||
int x = cursorX;
|
||||
int y = cursorY;
|
||||
if( y >= 0 && y < height )
|
||||
{
|
||||
m_text[y].write( text, x );
|
||||
m_textColour[y].fill( base16.charAt( m_cursorColour ), x, x + text.length() );
|
||||
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ), x, x + text.length() );
|
||||
this.text[y].write( text, x );
|
||||
textColour[y].fill( base16.charAt( cursorColour ), x, x + text.length() );
|
||||
backgroundColour[y].fill( base16.charAt( cursorBackgroundColour ), x, x + text.length() );
|
||||
setChanged();
|
||||
}
|
||||
}
|
||||
@ -221,86 +221,86 @@ public class Terminal
|
||||
{
|
||||
if( yDiff != 0 )
|
||||
{
|
||||
TextBuffer[] newText = new TextBuffer[m_height];
|
||||
TextBuffer[] newTextColour = new TextBuffer[m_height];
|
||||
TextBuffer[] newBackgroundColour = new TextBuffer[m_height];
|
||||
for( int y = 0; y < m_height; y++ )
|
||||
TextBuffer[] newText = new TextBuffer[height];
|
||||
TextBuffer[] newTextColour = new TextBuffer[height];
|
||||
TextBuffer[] newBackgroundColour = new TextBuffer[height];
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
int oldY = y + yDiff;
|
||||
if( oldY >= 0 && oldY < m_height )
|
||||
if( oldY >= 0 && oldY < height )
|
||||
{
|
||||
newText[y] = m_text[oldY];
|
||||
newTextColour[y] = m_textColour[oldY];
|
||||
newBackgroundColour[y] = m_backgroundColour[oldY];
|
||||
newText[y] = text[oldY];
|
||||
newTextColour[y] = textColour[oldY];
|
||||
newBackgroundColour[y] = backgroundColour[oldY];
|
||||
}
|
||||
else
|
||||
{
|
||||
newText[y] = new TextBuffer( ' ', m_width );
|
||||
newTextColour[y] = new TextBuffer( base16.charAt( m_cursorColour ), m_width );
|
||||
newBackgroundColour[y] = new TextBuffer( base16.charAt( m_cursorBackgroundColour ), m_width );
|
||||
newText[y] = new TextBuffer( ' ', width );
|
||||
newTextColour[y] = new TextBuffer( base16.charAt( cursorColour ), width );
|
||||
newBackgroundColour[y] = new TextBuffer( base16.charAt( cursorBackgroundColour ), width );
|
||||
}
|
||||
}
|
||||
m_text = newText;
|
||||
m_textColour = newTextColour;
|
||||
m_backgroundColour = newBackgroundColour;
|
||||
text = newText;
|
||||
textColour = newTextColour;
|
||||
backgroundColour = newBackgroundColour;
|
||||
setChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void clear()
|
||||
{
|
||||
for( int y = 0; y < m_height; y++ )
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
m_text[y].fill( ' ' );
|
||||
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
|
||||
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
|
||||
text[y].fill( ' ' );
|
||||
textColour[y].fill( base16.charAt( cursorColour ) );
|
||||
backgroundColour[y].fill( base16.charAt( cursorBackgroundColour ) );
|
||||
}
|
||||
setChanged();
|
||||
}
|
||||
|
||||
public synchronized void clearLine()
|
||||
{
|
||||
int y = m_cursorY;
|
||||
if( y >= 0 && y < m_height )
|
||||
int y = cursorY;
|
||||
if( y >= 0 && y < height )
|
||||
{
|
||||
m_text[y].fill( ' ' );
|
||||
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
|
||||
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
|
||||
text[y].fill( ' ' );
|
||||
textColour[y].fill( base16.charAt( cursorColour ) );
|
||||
backgroundColour[y].fill( base16.charAt( cursorBackgroundColour ) );
|
||||
setChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized TextBuffer getLine( int y )
|
||||
{
|
||||
if( y >= 0 && y < m_height )
|
||||
if( y >= 0 && y < height )
|
||||
{
|
||||
return m_text[y];
|
||||
return text[y];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized void setLine( int y, String text, String textColour, String backgroundColour )
|
||||
{
|
||||
m_text[y].write( text );
|
||||
m_textColour[y].write( textColour );
|
||||
m_backgroundColour[y].write( backgroundColour );
|
||||
this.text[y].write( text );
|
||||
this.textColour[y].write( textColour );
|
||||
this.backgroundColour[y].write( backgroundColour );
|
||||
setChanged();
|
||||
}
|
||||
|
||||
public synchronized TextBuffer getTextColourLine( int y )
|
||||
{
|
||||
if( y >= 0 && y < m_height )
|
||||
if( y >= 0 && y < height )
|
||||
{
|
||||
return m_textColour[y];
|
||||
return textColour[y];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized TextBuffer getBackgroundColourLine( int y )
|
||||
{
|
||||
if( y >= 0 && y < m_height )
|
||||
if( y >= 0 && y < height )
|
||||
{
|
||||
return m_backgroundColour[y];
|
||||
return backgroundColour[y];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -312,18 +312,18 @@ public class Terminal
|
||||
|
||||
public synchronized void write( PacketBuffer buffer )
|
||||
{
|
||||
buffer.writeInt( m_cursorX );
|
||||
buffer.writeInt( m_cursorY );
|
||||
buffer.writeBoolean( m_cursorBlink );
|
||||
buffer.writeByte( m_cursorBackgroundColour << 4 | m_cursorColour );
|
||||
buffer.writeInt( cursorX );
|
||||
buffer.writeInt( cursorY );
|
||||
buffer.writeBoolean( cursorBlink );
|
||||
buffer.writeByte( cursorBackgroundColour << 4 | cursorColour );
|
||||
|
||||
for( int y = 0; y < m_height; y++ )
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
TextBuffer text = m_text[y];
|
||||
TextBuffer textColour = m_textColour[y];
|
||||
TextBuffer backColour = m_backgroundColour[y];
|
||||
TextBuffer text = this.text[y];
|
||||
TextBuffer textColour = this.textColour[y];
|
||||
TextBuffer backColour = backgroundColour[y];
|
||||
|
||||
for( int x = 0; x < m_width; x++ )
|
||||
for( int x = 0; x < width; x++ )
|
||||
{
|
||||
buffer.writeByte( text.charAt( x ) & 0xFF );
|
||||
buffer.writeByte( getColour(
|
||||
@ -333,26 +333,26 @@ public class Terminal
|
||||
}
|
||||
}
|
||||
|
||||
m_palette.write( buffer );
|
||||
palette.write( buffer );
|
||||
}
|
||||
|
||||
public synchronized void read( PacketBuffer buffer )
|
||||
{
|
||||
m_cursorX = buffer.readInt();
|
||||
m_cursorY = buffer.readInt();
|
||||
m_cursorBlink = buffer.readBoolean();
|
||||
cursorX = buffer.readInt();
|
||||
cursorY = buffer.readInt();
|
||||
cursorBlink = buffer.readBoolean();
|
||||
|
||||
byte cursorColour = buffer.readByte();
|
||||
m_cursorBackgroundColour = (cursorColour >> 4) & 0xF;
|
||||
m_cursorColour = cursorColour & 0xF;
|
||||
cursorBackgroundColour = (cursorColour >> 4) & 0xF;
|
||||
this.cursorColour = cursorColour & 0xF;
|
||||
|
||||
for( int y = 0; y < m_height; y++ )
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
TextBuffer text = m_text[y];
|
||||
TextBuffer textColour = m_textColour[y];
|
||||
TextBuffer backColour = m_backgroundColour[y];
|
||||
TextBuffer text = this.text[y];
|
||||
TextBuffer textColour = this.textColour[y];
|
||||
TextBuffer backColour = backgroundColour[y];
|
||||
|
||||
for( int x = 0; x < m_width; x++ )
|
||||
for( int x = 0; x < width; x++ )
|
||||
{
|
||||
text.setChar( x, (char) (buffer.readByte() & 0xFF) );
|
||||
|
||||
@ -362,56 +362,56 @@ public class Terminal
|
||||
}
|
||||
}
|
||||
|
||||
m_palette.read( buffer );
|
||||
palette.read( buffer );
|
||||
setChanged();
|
||||
}
|
||||
|
||||
public synchronized CompoundNBT writeToNBT( CompoundNBT nbt )
|
||||
{
|
||||
nbt.putInt( "term_cursorX", m_cursorX );
|
||||
nbt.putInt( "term_cursorY", m_cursorY );
|
||||
nbt.putBoolean( "term_cursorBlink", m_cursorBlink );
|
||||
nbt.putInt( "term_textColour", m_cursorColour );
|
||||
nbt.putInt( "term_bgColour", m_cursorBackgroundColour );
|
||||
for( int n = 0; n < m_height; n++ )
|
||||
nbt.putInt( "term_cursorX", cursorX );
|
||||
nbt.putInt( "term_cursorY", cursorY );
|
||||
nbt.putBoolean( "term_cursorBlink", cursorBlink );
|
||||
nbt.putInt( "term_textColour", cursorColour );
|
||||
nbt.putInt( "term_bgColour", cursorBackgroundColour );
|
||||
for( int n = 0; n < height; n++ )
|
||||
{
|
||||
nbt.putString( "term_text_" + n, m_text[n].toString() );
|
||||
nbt.putString( "term_textColour_" + n, m_textColour[n].toString() );
|
||||
nbt.putString( "term_textBgColour_" + n, m_backgroundColour[n].toString() );
|
||||
nbt.putString( "term_text_" + n, text[n].toString() );
|
||||
nbt.putString( "term_textColour_" + n, textColour[n].toString() );
|
||||
nbt.putString( "term_textBgColour_" + n, backgroundColour[n].toString() );
|
||||
}
|
||||
|
||||
m_palette.writeToNBT( nbt );
|
||||
palette.writeToNBT( nbt );
|
||||
return nbt;
|
||||
}
|
||||
|
||||
public synchronized void readFromNBT( CompoundNBT nbt )
|
||||
{
|
||||
m_cursorX = nbt.getInt( "term_cursorX" );
|
||||
m_cursorY = nbt.getInt( "term_cursorY" );
|
||||
m_cursorBlink = nbt.getBoolean( "term_cursorBlink" );
|
||||
m_cursorColour = nbt.getInt( "term_textColour" );
|
||||
m_cursorBackgroundColour = nbt.getInt( "term_bgColour" );
|
||||
cursorX = nbt.getInt( "term_cursorX" );
|
||||
cursorY = nbt.getInt( "term_cursorY" );
|
||||
cursorBlink = nbt.getBoolean( "term_cursorBlink" );
|
||||
cursorColour = nbt.getInt( "term_textColour" );
|
||||
cursorBackgroundColour = nbt.getInt( "term_bgColour" );
|
||||
|
||||
for( int n = 0; n < m_height; n++ )
|
||||
for( int n = 0; n < height; n++ )
|
||||
{
|
||||
m_text[n].fill( ' ' );
|
||||
text[n].fill( ' ' );
|
||||
if( nbt.contains( "term_text_" + n ) )
|
||||
{
|
||||
m_text[n].write( nbt.getString( "term_text_" + n ) );
|
||||
text[n].write( nbt.getString( "term_text_" + n ) );
|
||||
}
|
||||
m_textColour[n].fill( base16.charAt( m_cursorColour ) );
|
||||
textColour[n].fill( base16.charAt( cursorColour ) );
|
||||
if( nbt.contains( "term_textColour_" + n ) )
|
||||
{
|
||||
m_textColour[n].write( nbt.getString( "term_textColour_" + n ) );
|
||||
textColour[n].write( nbt.getString( "term_textColour_" + n ) );
|
||||
}
|
||||
m_backgroundColour[n].fill( base16.charAt( m_cursorBackgroundColour ) );
|
||||
backgroundColour[n].fill( base16.charAt( cursorBackgroundColour ) );
|
||||
if( nbt.contains( "term_textBgColour_" + n ) )
|
||||
{
|
||||
m_backgroundColour[n].write( nbt.getString( "term_textBgColour_" + n ) );
|
||||
backgroundColour[n].write( nbt.getString( "term_textBgColour_" + n ) );
|
||||
}
|
||||
}
|
||||
|
||||
m_palette.readFromNBT( nbt );
|
||||
palette.readFromNBT( nbt );
|
||||
setChanged();
|
||||
}
|
||||
|
||||
|
@ -7,14 +7,14 @@ package dan200.computercraft.core.terminal;
|
||||
|
||||
public class TextBuffer
|
||||
{
|
||||
private final char[] m_text;
|
||||
private final char[] text;
|
||||
|
||||
public TextBuffer( char c, int length )
|
||||
{
|
||||
m_text = new char[length];
|
||||
text = new char[length];
|
||||
for( int i = 0; i < length; i++ )
|
||||
{
|
||||
m_text[i] = c;
|
||||
text[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,12 +26,12 @@ public class TextBuffer
|
||||
public TextBuffer( String text, int repetitions )
|
||||
{
|
||||
int textLength = text.length();
|
||||
m_text = new char[textLength * repetitions];
|
||||
this.text = new char[textLength * repetitions];
|
||||
for( int i = 0; i < repetitions; i++ )
|
||||
{
|
||||
for( int j = 0; j < textLength; j++ )
|
||||
{
|
||||
m_text[j + i * textLength] = text.charAt( j );
|
||||
this.text[j + i * textLength] = text.charAt( j );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -44,37 +44,37 @@ public class TextBuffer
|
||||
public TextBuffer( TextBuffer text, int repetitions )
|
||||
{
|
||||
int textLength = text.length();
|
||||
m_text = new char[textLength * repetitions];
|
||||
this.text = new char[textLength * repetitions];
|
||||
for( int i = 0; i < repetitions; i++ )
|
||||
{
|
||||
for( int j = 0; j < textLength; j++ )
|
||||
{
|
||||
m_text[j + i * textLength] = text.charAt( j );
|
||||
this.text[j + i * textLength] = text.charAt( j );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int length()
|
||||
{
|
||||
return m_text.length;
|
||||
return text.length;
|
||||
}
|
||||
|
||||
public String read()
|
||||
{
|
||||
return read( 0, m_text.length );
|
||||
return read( 0, text.length );
|
||||
}
|
||||
|
||||
public String read( int start )
|
||||
{
|
||||
return read( start, m_text.length );
|
||||
return read( start, text.length );
|
||||
}
|
||||
|
||||
public String read( int start, int end )
|
||||
{
|
||||
start = Math.max( start, 0 );
|
||||
end = Math.min( end, m_text.length );
|
||||
end = Math.min( end, text.length );
|
||||
int textLength = Math.max( end - start, 0 );
|
||||
return new String( m_text, start, textLength );
|
||||
return new String( text, start, textLength );
|
||||
}
|
||||
|
||||
public void write( String text )
|
||||
@ -92,10 +92,10 @@ public class TextBuffer
|
||||
int pos = start;
|
||||
start = Math.max( start, 0 );
|
||||
end = Math.min( end, pos + text.length() );
|
||||
end = Math.min( end, m_text.length );
|
||||
end = Math.min( end, this.text.length );
|
||||
for( int i = start; i < end; i++ )
|
||||
{
|
||||
m_text[i] = text.charAt( i - pos );
|
||||
this.text[i] = text.charAt( i - pos );
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,94 +114,94 @@ public class TextBuffer
|
||||
int pos = start;
|
||||
start = Math.max( start, 0 );
|
||||
end = Math.min( end, pos + text.length() );
|
||||
end = Math.min( end, m_text.length );
|
||||
end = Math.min( end, this.text.length );
|
||||
for( int i = start; i < end; i++ )
|
||||
{
|
||||
m_text[i] = text.charAt( i - pos );
|
||||
this.text[i] = text.charAt( i - pos );
|
||||
}
|
||||
}
|
||||
|
||||
public void fill( char c )
|
||||
{
|
||||
fill( c, 0, m_text.length );
|
||||
fill( c, 0, text.length );
|
||||
}
|
||||
|
||||
public void fill( char c, int start )
|
||||
{
|
||||
fill( c, start, m_text.length );
|
||||
fill( c, start, text.length );
|
||||
}
|
||||
|
||||
public void fill( char c, int start, int end )
|
||||
{
|
||||
start = Math.max( start, 0 );
|
||||
end = Math.min( end, m_text.length );
|
||||
end = Math.min( end, text.length );
|
||||
for( int i = start; i < end; i++ )
|
||||
{
|
||||
m_text[i] = c;
|
||||
text[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
public void fill( String text )
|
||||
{
|
||||
fill( text, 0, m_text.length );
|
||||
fill( text, 0, this.text.length );
|
||||
}
|
||||
|
||||
public void fill( String text, int start )
|
||||
{
|
||||
fill( text, start, m_text.length );
|
||||
fill( text, start, this.text.length );
|
||||
}
|
||||
|
||||
public void fill( String text, int start, int end )
|
||||
{
|
||||
int pos = start;
|
||||
start = Math.max( start, 0 );
|
||||
end = Math.min( end, m_text.length );
|
||||
end = Math.min( end, this.text.length );
|
||||
|
||||
int textLength = text.length();
|
||||
for( int i = start; i < end; i++ )
|
||||
{
|
||||
m_text[i] = text.charAt( (i - pos) % textLength );
|
||||
this.text[i] = text.charAt( (i - pos) % textLength );
|
||||
}
|
||||
}
|
||||
|
||||
public void fill( TextBuffer text )
|
||||
{
|
||||
fill( text, 0, m_text.length );
|
||||
fill( text, 0, this.text.length );
|
||||
}
|
||||
|
||||
public void fill( TextBuffer text, int start )
|
||||
{
|
||||
fill( text, start, m_text.length );
|
||||
fill( text, start, this.text.length );
|
||||
}
|
||||
|
||||
public void fill( TextBuffer text, int start, int end )
|
||||
{
|
||||
int pos = start;
|
||||
start = Math.max( start, 0 );
|
||||
end = Math.min( end, m_text.length );
|
||||
end = Math.min( end, this.text.length );
|
||||
|
||||
int textLength = text.length();
|
||||
for( int i = start; i < end; i++ )
|
||||
{
|
||||
m_text[i] = text.charAt( (i - pos) % textLength );
|
||||
this.text[i] = text.charAt( (i - pos) % textLength );
|
||||
}
|
||||
}
|
||||
|
||||
public char charAt( int i )
|
||||
{
|
||||
return m_text[i];
|
||||
return text[i];
|
||||
}
|
||||
|
||||
public void setChar( int i, char c )
|
||||
{
|
||||
if( i >= 0 && i < m_text.length )
|
||||
if( i >= 0 && i < text.length )
|
||||
{
|
||||
m_text[i] = c;
|
||||
text[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return new String( m_text );
|
||||
return new String( text );
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ import dan200.computercraft.core.apis.http.options.Action;
|
||||
import dan200.computercraft.core.apis.http.options.AddressRuleConfig;
|
||||
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.Builder;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
@ -28,12 +30,6 @@ import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.minecraftforge.common.ForgeConfigSpec.Builder;
|
||||
import static net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
||||
|
||||
import net.minecraftforge.common.ForgeConfigSpec.Builder;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
||||
|
||||
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD )
|
||||
public final class Config
|
||||
{
|
||||
|
@ -7,7 +7,9 @@ package dan200.computercraft.shared;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenCustomHashMap;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
|
||||
@ -18,7 +20,7 @@ import java.util.*;
|
||||
public final class PocketUpgrades
|
||||
{
|
||||
private static final Map<String, IPocketUpgrade> upgrades = new HashMap<>();
|
||||
private static final IdentityHashMap<IPocketUpgrade, String> upgradeOwners = new IdentityHashMap<>();
|
||||
private static final Map<IPocketUpgrade, String> upgradeOwners = new Object2ObjectLinkedOpenCustomHashMap<>( Util.identityStrategy() );
|
||||
|
||||
private PocketUpgrades() {}
|
||||
|
||||
|
@ -56,6 +56,7 @@ import dan200.computercraft.shared.util.CreativeTabMain;
|
||||
import dan200.computercraft.shared.util.FixedPointTileEntityType;
|
||||
import dan200.computercraft.shared.util.ImpostorRecipe;
|
||||
import dan200.computercraft.shared.util.ImpostorShapelessRecipe;
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.EntityClassification;
|
||||
@ -81,8 +82,6 @@ import net.minecraftforge.registries.ForgeRegistries;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
|
||||
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD )
|
||||
public final class Registry
|
||||
{
|
||||
|
@ -8,12 +8,17 @@ package dan200.computercraft.shared;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenCustomHashMap;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public final class TurtleUpgrades
|
||||
@ -37,7 +42,7 @@ public final class TurtleUpgrades
|
||||
private static ITurtleUpgrade[] vanilla;
|
||||
|
||||
private static final Map<String, ITurtleUpgrade> upgrades = new HashMap<>();
|
||||
private static final IdentityHashMap<ITurtleUpgrade, Wrapper> wrappers = new IdentityHashMap<>();
|
||||
private static final Map<ITurtleUpgrade, Wrapper> wrappers = new Object2ObjectLinkedOpenCustomHashMap<>( Util.identityStrategy() );
|
||||
private static boolean needsRebuild;
|
||||
|
||||
private TurtleUpgrades() {}
|
||||
|
@ -31,7 +31,7 @@ import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder
|
||||
*/
|
||||
public class CommandBuilder<S> implements CommandNodeBuilder<S, Command<S>>
|
||||
{
|
||||
private List<ArgumentBuilder<S, ?>> args = new ArrayList<>();
|
||||
private final List<ArgumentBuilder<S, ?>> args = new ArrayList<>();
|
||||
private Predicate<S> requires;
|
||||
|
||||
public static CommandBuilder<CommandSource> args()
|
||||
|
@ -24,8 +24,6 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.block.AbstractBlock.Properties;
|
||||
|
||||
public abstract class BlockGeneric extends Block
|
||||
{
|
||||
private final RegistryObject<? extends TileEntityType<? extends TileGeneric>> type;
|
||||
|
@ -10,21 +10,21 @@ import dan200.computercraft.shared.network.client.TerminalState;
|
||||
|
||||
public class ClientTerminal implements ITerminal
|
||||
{
|
||||
private boolean m_colour;
|
||||
private Terminal m_terminal;
|
||||
private boolean m_terminalChanged;
|
||||
private boolean colour;
|
||||
private Terminal terminal;
|
||||
private boolean terminalChanged;
|
||||
|
||||
public ClientTerminal( boolean colour )
|
||||
{
|
||||
m_colour = colour;
|
||||
m_terminal = null;
|
||||
m_terminalChanged = false;
|
||||
this.colour = colour;
|
||||
terminal = null;
|
||||
terminalChanged = false;
|
||||
}
|
||||
|
||||
public boolean pollTerminalChanged()
|
||||
{
|
||||
boolean changed = m_terminalChanged;
|
||||
m_terminalChanged = false;
|
||||
boolean changed = terminalChanged;
|
||||
terminalChanged = false;
|
||||
return changed;
|
||||
}
|
||||
|
||||
@ -33,22 +33,22 @@ public class ClientTerminal implements ITerminal
|
||||
@Override
|
||||
public Terminal getTerminal()
|
||||
{
|
||||
return m_terminal;
|
||||
return terminal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isColour()
|
||||
{
|
||||
return m_colour;
|
||||
return colour;
|
||||
}
|
||||
|
||||
public void read( TerminalState state )
|
||||
{
|
||||
m_colour = state.colour;
|
||||
colour = state.colour;
|
||||
if( state.hasTerminal() )
|
||||
{
|
||||
resizeTerminal( state.width, state.height );
|
||||
state.apply( m_terminal );
|
||||
state.apply( terminal );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -58,23 +58,23 @@ public class ClientTerminal implements ITerminal
|
||||
|
||||
private void resizeTerminal( int width, int height )
|
||||
{
|
||||
if( m_terminal == null )
|
||||
if( terminal == null )
|
||||
{
|
||||
m_terminal = new Terminal( width, height, () -> m_terminalChanged = true );
|
||||
m_terminalChanged = true;
|
||||
terminal = new Terminal( width, height, () -> terminalChanged = true );
|
||||
terminalChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminal.resize( width, height );
|
||||
terminal.resize( width, height );
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteTerminal()
|
||||
{
|
||||
if( m_terminal != null )
|
||||
if( terminal != null )
|
||||
{
|
||||
m_terminal = null;
|
||||
m_terminalChanged = true;
|
||||
terminal = null;
|
||||
terminalChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,74 +12,74 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class ServerTerminal implements ITerminal
|
||||
{
|
||||
private final boolean m_colour;
|
||||
private Terminal m_terminal;
|
||||
private final AtomicBoolean m_terminalChanged = new AtomicBoolean( false );
|
||||
private boolean m_terminalChangedLastFrame = false;
|
||||
private final boolean colour;
|
||||
private Terminal terminal;
|
||||
private final AtomicBoolean terminalChanged = new AtomicBoolean( false );
|
||||
private boolean terminalChangedLastFrame = false;
|
||||
|
||||
public ServerTerminal( boolean colour )
|
||||
{
|
||||
m_colour = colour;
|
||||
m_terminal = null;
|
||||
this.colour = colour;
|
||||
terminal = null;
|
||||
}
|
||||
|
||||
public ServerTerminal( boolean colour, int terminalWidth, int terminalHeight )
|
||||
{
|
||||
m_colour = colour;
|
||||
m_terminal = new Terminal( terminalWidth, terminalHeight, this::markTerminalChanged );
|
||||
this.colour = colour;
|
||||
terminal = new Terminal( terminalWidth, terminalHeight, this::markTerminalChanged );
|
||||
}
|
||||
|
||||
protected void resize( int width, int height )
|
||||
{
|
||||
if( m_terminal == null )
|
||||
if( terminal == null )
|
||||
{
|
||||
m_terminal = new Terminal( width, height, this::markTerminalChanged );
|
||||
terminal = new Terminal( width, height, this::markTerminalChanged );
|
||||
markTerminalChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminal.resize( width, height );
|
||||
terminal.resize( width, height );
|
||||
}
|
||||
}
|
||||
|
||||
public void delete()
|
||||
{
|
||||
if( m_terminal != null )
|
||||
if( terminal != null )
|
||||
{
|
||||
m_terminal = null;
|
||||
terminal = null;
|
||||
markTerminalChanged();
|
||||
}
|
||||
}
|
||||
|
||||
protected void markTerminalChanged()
|
||||
{
|
||||
m_terminalChanged.set( true );
|
||||
terminalChanged.set( true );
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
m_terminalChangedLastFrame = m_terminalChanged.getAndSet( false );
|
||||
terminalChangedLastFrame = terminalChanged.getAndSet( false );
|
||||
}
|
||||
|
||||
public boolean hasTerminalChanged()
|
||||
{
|
||||
return m_terminalChangedLastFrame;
|
||||
return terminalChangedLastFrame;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Terminal getTerminal()
|
||||
{
|
||||
return m_terminal;
|
||||
return terminal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isColour()
|
||||
{
|
||||
return m_colour;
|
||||
return colour;
|
||||
}
|
||||
|
||||
public TerminalState write()
|
||||
{
|
||||
return new TerminalState( m_colour, m_terminal );
|
||||
return new TerminalState( colour, terminal );
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,6 @@ import net.minecraftforge.fml.RegistryObject;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.AbstractBlock.Properties;
|
||||
|
||||
public class BlockComputer extends BlockComputerBase<TileComputer>
|
||||
{
|
||||
public static final EnumProperty<ComputerState> STATE = EnumProperty.create( "state", ComputerState.class );
|
||||
|
@ -35,8 +35,6 @@ import net.minecraftforge.fml.RegistryObject;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.AbstractBlock.Properties;
|
||||
|
||||
public abstract class BlockComputerBase<T extends TileComputerBase> extends BlockGeneric implements IBundledRedstoneBlock
|
||||
{
|
||||
private static final ResourceLocation DROP = new ResourceLocation( ComputerCraft.MOD_ID, "computer" );
|
||||
|
@ -33,7 +33,7 @@ public final class ComputerProxy
|
||||
ServerComputer computer = tile.getServerComputer();
|
||||
if( computer == null )
|
||||
{
|
||||
tile.m_startOn = true;
|
||||
tile.startOn = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -47,7 +47,7 @@ public final class ComputerProxy
|
||||
ServerComputer computer = tile.getServerComputer();
|
||||
if( computer == null )
|
||||
{
|
||||
tile.m_startOn = false;
|
||||
tile.startOn = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -61,7 +61,7 @@ public final class ComputerProxy
|
||||
ServerComputer computer = tile.getServerComputer();
|
||||
if( computer == null )
|
||||
{
|
||||
tile.m_startOn = true;
|
||||
tile.startOn = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -52,12 +52,12 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
private static final String NBT_LABEL = "Label";
|
||||
private static final String NBT_ON = "On";
|
||||
|
||||
private int m_instanceID = -1;
|
||||
private int m_computerID = -1;
|
||||
private int instanceID = -1;
|
||||
private int computerID = -1;
|
||||
protected String label = null;
|
||||
private boolean m_on = false;
|
||||
boolean m_startOn = false;
|
||||
private boolean m_fresh = false;
|
||||
private boolean on = false;
|
||||
boolean startOn = false;
|
||||
private boolean fresh = false;
|
||||
private final NonNullConsumer<LazyOptional<IPeripheral>>[] invalidate;
|
||||
|
||||
private final ComputerFamily family;
|
||||
@ -78,10 +78,10 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
|
||||
protected void unload()
|
||||
{
|
||||
if( m_instanceID >= 0 )
|
||||
if( instanceID >= 0 )
|
||||
{
|
||||
if( !getLevel().isClientSide ) ComputerCraft.serverComputerRegistry.remove( m_instanceID );
|
||||
m_instanceID = -1;
|
||||
if( !getLevel().isClientSide ) ComputerCraft.serverComputerRegistry.remove( instanceID );
|
||||
instanceID = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,18 +162,18 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
if( computer == null ) return;
|
||||
|
||||
// If the computer isn't on and should be, then turn it on
|
||||
if( m_startOn || (m_fresh && m_on) )
|
||||
if( startOn || (fresh && on) )
|
||||
{
|
||||
computer.turnOn();
|
||||
m_startOn = false;
|
||||
startOn = false;
|
||||
}
|
||||
|
||||
computer.keepAlive();
|
||||
|
||||
m_fresh = false;
|
||||
m_computerID = computer.getID();
|
||||
fresh = false;
|
||||
computerID = computer.getID();
|
||||
label = computer.getLabel();
|
||||
m_on = computer.isOn();
|
||||
on = computer.isOn();
|
||||
|
||||
if( computer.hasOutputChanged() ) updateOutput();
|
||||
|
||||
@ -192,9 +192,9 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
public CompoundNBT save( @Nonnull CompoundNBT nbt )
|
||||
{
|
||||
// Save ID, label and power state
|
||||
if( m_computerID >= 0 ) nbt.putInt( NBT_ID, m_computerID );
|
||||
if( computerID >= 0 ) nbt.putInt( NBT_ID, computerID );
|
||||
if( label != null ) nbt.putString( NBT_LABEL, label );
|
||||
nbt.putBoolean( NBT_ON, m_on );
|
||||
nbt.putBoolean( NBT_ON, on );
|
||||
|
||||
return super.save( nbt );
|
||||
}
|
||||
@ -205,9 +205,9 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
super.load( state, nbt );
|
||||
|
||||
// Load ID, label and power state
|
||||
m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
|
||||
computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
|
||||
label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null;
|
||||
m_on = m_startOn = nbt.getBoolean( NBT_ON );
|
||||
on = startOn = nbt.getBoolean( NBT_ON );
|
||||
}
|
||||
|
||||
protected boolean isPeripheralBlockedOnSide( ComputerSide localSide )
|
||||
@ -322,7 +322,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
@Override
|
||||
public final int getComputerID()
|
||||
{
|
||||
return m_computerID;
|
||||
return computerID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -334,11 +334,11 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
@Override
|
||||
public final void setComputerID( int id )
|
||||
{
|
||||
if( getLevel().isClientSide || m_computerID == id ) return;
|
||||
if( getLevel().isClientSide || computerID == id ) return;
|
||||
|
||||
m_computerID = id;
|
||||
computerID = id;
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer != null ) computer.setID( m_computerID );
|
||||
if( computer != null ) computer.setID( computerID );
|
||||
setChanged();
|
||||
}
|
||||
|
||||
@ -364,16 +364,16 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
if( getLevel().isClientSide ) return null;
|
||||
|
||||
boolean changed = false;
|
||||
if( m_instanceID < 0 )
|
||||
if( instanceID < 0 )
|
||||
{
|
||||
m_instanceID = ComputerCraft.serverComputerRegistry.getUnusedInstanceID();
|
||||
instanceID = ComputerCraft.serverComputerRegistry.getUnusedInstanceID();
|
||||
changed = true;
|
||||
}
|
||||
if( !ComputerCraft.serverComputerRegistry.contains( m_instanceID ) )
|
||||
if( !ComputerCraft.serverComputerRegistry.contains( instanceID ) )
|
||||
{
|
||||
ServerComputer computer = createComputer( m_instanceID, m_computerID );
|
||||
ComputerCraft.serverComputerRegistry.add( m_instanceID, computer );
|
||||
m_fresh = true;
|
||||
ServerComputer computer = createComputer( instanceID, computerID );
|
||||
ComputerCraft.serverComputerRegistry.add( instanceID, computer );
|
||||
fresh = true;
|
||||
changed = true;
|
||||
}
|
||||
if( changed )
|
||||
@ -381,12 +381,12 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
updateBlock();
|
||||
updateInput();
|
||||
}
|
||||
return ComputerCraft.serverComputerRegistry.get( m_instanceID );
|
||||
return ComputerCraft.serverComputerRegistry.get( instanceID );
|
||||
}
|
||||
|
||||
public ServerComputer getServerComputer()
|
||||
{
|
||||
return getLevel().isClientSide ? null : ComputerCraft.serverComputerRegistry.get( m_instanceID );
|
||||
return getLevel().isClientSide ? null : ComputerCraft.serverComputerRegistry.get( instanceID );
|
||||
}
|
||||
|
||||
// Networking stuff
|
||||
@ -396,7 +396,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
{
|
||||
super.writeDescription( nbt );
|
||||
if( label != null ) nbt.putString( NBT_LABEL, label );
|
||||
if( m_computerID >= 0 ) nbt.putInt( NBT_ID, m_computerID );
|
||||
if( computerID >= 0 ) nbt.putInt( NBT_ID, computerID );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -404,22 +404,22 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
{
|
||||
super.readDescription( nbt );
|
||||
label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null;
|
||||
m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
|
||||
computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
|
||||
}
|
||||
|
||||
protected void transferStateFrom( TileComputerBase copy )
|
||||
{
|
||||
if( copy.m_computerID != m_computerID || copy.m_instanceID != m_instanceID )
|
||||
if( copy.computerID != computerID || copy.instanceID != instanceID )
|
||||
{
|
||||
unload();
|
||||
m_instanceID = copy.m_instanceID;
|
||||
m_computerID = copy.m_computerID;
|
||||
instanceID = copy.instanceID;
|
||||
computerID = copy.computerID;
|
||||
label = copy.label;
|
||||
m_on = copy.m_on;
|
||||
m_startOn = copy.m_startOn;
|
||||
on = copy.on;
|
||||
startOn = copy.startOn;
|
||||
updateBlock();
|
||||
}
|
||||
copy.m_instanceID = -1;
|
||||
copy.instanceID = -1;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@ -12,22 +12,21 @@ import net.minecraft.nbt.CompoundNBT;
|
||||
|
||||
public class ClientComputer extends ClientTerminal implements IComputer
|
||||
{
|
||||
private final int m_instanceID;
|
||||
|
||||
private boolean m_on = false;
|
||||
private boolean m_blinking = false;
|
||||
private CompoundNBT m_userData = null;
|
||||
private final int instanceID;
|
||||
|
||||
private boolean on = false;
|
||||
private boolean blinking = false;
|
||||
private CompoundNBT userData = null;
|
||||
|
||||
public ClientComputer( int instanceID )
|
||||
{
|
||||
super( false );
|
||||
m_instanceID = instanceID;
|
||||
this.instanceID = instanceID;
|
||||
}
|
||||
|
||||
public CompoundNBT getUserData()
|
||||
{
|
||||
return m_userData;
|
||||
return userData;
|
||||
}
|
||||
|
||||
public void requestState()
|
||||
@ -41,89 +40,89 @@ public class ClientComputer extends ClientTerminal implements IComputer
|
||||
@Override
|
||||
public int getInstanceID()
|
||||
{
|
||||
return m_instanceID;
|
||||
return instanceID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOn()
|
||||
{
|
||||
return m_on;
|
||||
return on;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCursorDisplayed()
|
||||
{
|
||||
return m_on && m_blinking;
|
||||
return on && blinking;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void turnOn()
|
||||
{
|
||||
// Send turnOn to server
|
||||
NetworkHandler.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.TURN_ON ) );
|
||||
NetworkHandler.sendToServer( new ComputerActionServerMessage( instanceID, ComputerActionServerMessage.Action.TURN_ON ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown()
|
||||
{
|
||||
// Send shutdown to server
|
||||
NetworkHandler.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.SHUTDOWN ) );
|
||||
NetworkHandler.sendToServer( new ComputerActionServerMessage( instanceID, ComputerActionServerMessage.Action.SHUTDOWN ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reboot()
|
||||
{
|
||||
// Send reboot to server
|
||||
NetworkHandler.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.REBOOT ) );
|
||||
NetworkHandler.sendToServer( new ComputerActionServerMessage( instanceID, ComputerActionServerMessage.Action.REBOOT ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queueEvent( String event, Object[] arguments )
|
||||
{
|
||||
// Send event to server
|
||||
NetworkHandler.sendToServer( new QueueEventServerMessage( m_instanceID, event, arguments ) );
|
||||
NetworkHandler.sendToServer( new QueueEventServerMessage( instanceID, event, arguments ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyDown( int key, boolean repeat )
|
||||
{
|
||||
NetworkHandler.sendToServer( new KeyEventServerMessage( m_instanceID, repeat ? KeyEventServerMessage.TYPE_REPEAT : KeyEventServerMessage.TYPE_DOWN, key ) );
|
||||
NetworkHandler.sendToServer( new KeyEventServerMessage( instanceID, repeat ? KeyEventServerMessage.TYPE_REPEAT : KeyEventServerMessage.TYPE_DOWN, key ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyUp( int key )
|
||||
{
|
||||
NetworkHandler.sendToServer( new KeyEventServerMessage( m_instanceID, KeyEventServerMessage.TYPE_UP, key ) );
|
||||
NetworkHandler.sendToServer( new KeyEventServerMessage( instanceID, KeyEventServerMessage.TYPE_UP, key ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClick( int button, int x, int y )
|
||||
{
|
||||
NetworkHandler.sendToServer( new MouseEventServerMessage( m_instanceID, MouseEventServerMessage.TYPE_CLICK, button, x, y ) );
|
||||
NetworkHandler.sendToServer( new MouseEventServerMessage( instanceID, MouseEventServerMessage.TYPE_CLICK, button, x, y ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseUp( int button, int x, int y )
|
||||
{
|
||||
NetworkHandler.sendToServer( new MouseEventServerMessage( m_instanceID, MouseEventServerMessage.TYPE_UP, button, x, y ) );
|
||||
NetworkHandler.sendToServer( new MouseEventServerMessage( instanceID, MouseEventServerMessage.TYPE_UP, button, x, y ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDrag( int button, int x, int y )
|
||||
{
|
||||
NetworkHandler.sendToServer( new MouseEventServerMessage( m_instanceID, MouseEventServerMessage.TYPE_DRAG, button, x, y ) );
|
||||
NetworkHandler.sendToServer( new MouseEventServerMessage( instanceID, MouseEventServerMessage.TYPE_DRAG, button, x, y ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseScroll( int direction, int x, int y )
|
||||
{
|
||||
NetworkHandler.sendToServer( new MouseEventServerMessage( m_instanceID, MouseEventServerMessage.TYPE_SCROLL, direction, x, y ) );
|
||||
NetworkHandler.sendToServer( new MouseEventServerMessage( instanceID, MouseEventServerMessage.TYPE_SCROLL, direction, x, y ) );
|
||||
}
|
||||
|
||||
public void setState( ComputerState state, CompoundNBT userData )
|
||||
{
|
||||
m_on = state != ComputerState.OFF;
|
||||
m_blinking = state == ComputerState.BLINKING;
|
||||
m_userData = userData;
|
||||
on = state != ComputerState.OFF;
|
||||
blinking = state == ComputerState.BLINKING;
|
||||
this.userData = userData;
|
||||
}
|
||||
}
|
||||
|
@ -12,38 +12,37 @@ import java.util.Random;
|
||||
|
||||
public class ComputerRegistry<T extends IComputer>
|
||||
{
|
||||
private Map<Integer, T> m_computers;
|
||||
private int m_nextUnusedInstanceID;
|
||||
private int m_sessionID;
|
||||
private final Map<Integer, T> computers = new HashMap<>();
|
||||
private int nextUnusedInstanceID;
|
||||
private int sessionID;
|
||||
|
||||
protected ComputerRegistry()
|
||||
{
|
||||
m_computers = new HashMap<>();
|
||||
reset();
|
||||
}
|
||||
|
||||
public int getSessionID()
|
||||
{
|
||||
return m_sessionID;
|
||||
return sessionID;
|
||||
}
|
||||
|
||||
public int getUnusedInstanceID()
|
||||
{
|
||||
return m_nextUnusedInstanceID++;
|
||||
return nextUnusedInstanceID++;
|
||||
}
|
||||
|
||||
public Collection<T> getComputers()
|
||||
{
|
||||
return m_computers.values();
|
||||
return computers.values();
|
||||
}
|
||||
|
||||
public T get( int instanceID )
|
||||
{
|
||||
if( instanceID >= 0 )
|
||||
{
|
||||
if( m_computers.containsKey( instanceID ) )
|
||||
if( computers.containsKey( instanceID ) )
|
||||
{
|
||||
return m_computers.get( instanceID );
|
||||
return computers.get( instanceID );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -51,28 +50,28 @@ public class ComputerRegistry<T extends IComputer>
|
||||
|
||||
public boolean contains( int instanceID )
|
||||
{
|
||||
return m_computers.containsKey( instanceID );
|
||||
return computers.containsKey( instanceID );
|
||||
}
|
||||
|
||||
public void add( int instanceID, T computer )
|
||||
{
|
||||
if( m_computers.containsKey( instanceID ) )
|
||||
if( computers.containsKey( instanceID ) )
|
||||
{
|
||||
remove( instanceID );
|
||||
}
|
||||
m_computers.put( instanceID, computer );
|
||||
m_nextUnusedInstanceID = Math.max( m_nextUnusedInstanceID, instanceID + 1 );
|
||||
computers.put( instanceID, computer );
|
||||
nextUnusedInstanceID = Math.max( nextUnusedInstanceID, instanceID + 1 );
|
||||
}
|
||||
|
||||
public void remove( int instanceID )
|
||||
{
|
||||
m_computers.remove( instanceID );
|
||||
computers.remove( instanceID );
|
||||
}
|
||||
|
||||
public void reset()
|
||||
{
|
||||
m_computers.clear();
|
||||
m_nextUnusedInstanceID = 0;
|
||||
m_sessionID = new Random().nextInt();
|
||||
computers.clear();
|
||||
nextUnusedInstanceID = 0;
|
||||
sessionID = new Random().nextInt();
|
||||
}
|
||||
}
|
||||
|
@ -37,116 +37,109 @@ import java.io.InputStream;
|
||||
|
||||
public class ServerComputer extends ServerTerminal implements IComputer, IComputerEnvironment
|
||||
{
|
||||
private final int m_instanceID;
|
||||
private final int instanceID;
|
||||
|
||||
private World m_world;
|
||||
private BlockPos m_position;
|
||||
private World world;
|
||||
private BlockPos position;
|
||||
|
||||
private final ComputerFamily m_family;
|
||||
private final Computer m_computer;
|
||||
private CompoundNBT m_userData;
|
||||
private boolean m_changed;
|
||||
private final ComputerFamily family;
|
||||
private final Computer computer;
|
||||
private CompoundNBT userData;
|
||||
private boolean changed;
|
||||
|
||||
private boolean m_changedLastFrame;
|
||||
private int m_ticksSincePing;
|
||||
private boolean changedLastFrame;
|
||||
private int ticksSincePing;
|
||||
|
||||
public ServerComputer( World world, int computerID, String label, int instanceID, ComputerFamily family, int terminalWidth, int terminalHeight )
|
||||
{
|
||||
super( family != ComputerFamily.NORMAL, terminalWidth, terminalHeight );
|
||||
m_instanceID = instanceID;
|
||||
this.instanceID = instanceID;
|
||||
|
||||
m_world = world;
|
||||
m_position = null;
|
||||
|
||||
m_family = family;
|
||||
m_computer = new Computer( this, getTerminal(), computerID );
|
||||
m_computer.setLabel( label );
|
||||
m_userData = null;
|
||||
m_changed = false;
|
||||
|
||||
m_changedLastFrame = false;
|
||||
m_ticksSincePing = 0;
|
||||
this.world = world;
|
||||
this.family = family;
|
||||
computer = new Computer( this, getTerminal(), computerID );
|
||||
computer.setLabel( label );
|
||||
}
|
||||
|
||||
public ComputerFamily getFamily()
|
||||
{
|
||||
return m_family;
|
||||
return family;
|
||||
}
|
||||
|
||||
public World getWorld()
|
||||
{
|
||||
return m_world;
|
||||
return world;
|
||||
}
|
||||
|
||||
public void setWorld( World world )
|
||||
{
|
||||
m_world = world;
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public BlockPos getPosition()
|
||||
{
|
||||
return m_position;
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition( BlockPos pos )
|
||||
{
|
||||
m_position = new BlockPos( pos );
|
||||
position = new BlockPos( pos );
|
||||
}
|
||||
|
||||
public IAPIEnvironment getAPIEnvironment()
|
||||
{
|
||||
return m_computer.getAPIEnvironment();
|
||||
return computer.getAPIEnvironment();
|
||||
}
|
||||
|
||||
public Computer getComputer()
|
||||
{
|
||||
return m_computer;
|
||||
return computer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
super.update();
|
||||
m_computer.tick();
|
||||
computer.tick();
|
||||
|
||||
m_changedLastFrame = m_computer.pollAndResetChanged() || m_changed;
|
||||
m_changed = false;
|
||||
changedLastFrame = computer.pollAndResetChanged() || changed;
|
||||
changed = false;
|
||||
|
||||
m_ticksSincePing++;
|
||||
ticksSincePing++;
|
||||
}
|
||||
|
||||
public void keepAlive()
|
||||
{
|
||||
m_ticksSincePing = 0;
|
||||
ticksSincePing = 0;
|
||||
}
|
||||
|
||||
public boolean hasTimedOut()
|
||||
{
|
||||
return m_ticksSincePing > 100;
|
||||
return ticksSincePing > 100;
|
||||
}
|
||||
|
||||
public boolean hasOutputChanged()
|
||||
{
|
||||
return m_changedLastFrame;
|
||||
return changedLastFrame;
|
||||
}
|
||||
|
||||
public void unload()
|
||||
{
|
||||
m_computer.unload();
|
||||
computer.unload();
|
||||
}
|
||||
|
||||
public CompoundNBT getUserData()
|
||||
{
|
||||
if( m_userData == null )
|
||||
if( userData == null )
|
||||
{
|
||||
m_userData = new CompoundNBT();
|
||||
userData = new CompoundNBT();
|
||||
}
|
||||
return m_userData;
|
||||
return userData;
|
||||
}
|
||||
|
||||
public void updateUserData()
|
||||
{
|
||||
m_changed = true;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
private NetworkMessage createComputerPacket()
|
||||
@ -204,7 +197,7 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
||||
|
||||
public void setID( int id )
|
||||
{
|
||||
m_computer.setID( id );
|
||||
computer.setID( id );
|
||||
}
|
||||
|
||||
// IComputer
|
||||
@ -212,97 +205,97 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
||||
@Override
|
||||
public int getInstanceID()
|
||||
{
|
||||
return m_instanceID;
|
||||
return instanceID;
|
||||
}
|
||||
|
||||
public int getID()
|
||||
{
|
||||
return m_computer.getID();
|
||||
return computer.getID();
|
||||
}
|
||||
|
||||
public String getLabel()
|
||||
{
|
||||
return m_computer.getLabel();
|
||||
return computer.getLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOn()
|
||||
{
|
||||
return m_computer.isOn();
|
||||
return computer.isOn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCursorDisplayed()
|
||||
{
|
||||
return m_computer.isOn() && m_computer.isBlinking();
|
||||
return computer.isOn() && computer.isBlinking();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void turnOn()
|
||||
{
|
||||
// Turn on
|
||||
m_computer.turnOn();
|
||||
computer.turnOn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown()
|
||||
{
|
||||
// Shutdown
|
||||
m_computer.shutdown();
|
||||
computer.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reboot()
|
||||
{
|
||||
// Reboot
|
||||
m_computer.reboot();
|
||||
computer.reboot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queueEvent( String event, Object[] arguments )
|
||||
{
|
||||
// Queue event
|
||||
m_computer.queueEvent( event, arguments );
|
||||
computer.queueEvent( event, arguments );
|
||||
}
|
||||
|
||||
public int getRedstoneOutput( ComputerSide side )
|
||||
{
|
||||
return m_computer.getEnvironment().getExternalRedstoneOutput( side );
|
||||
return computer.getEnvironment().getExternalRedstoneOutput( side );
|
||||
}
|
||||
|
||||
public void setRedstoneInput( ComputerSide side, int level )
|
||||
{
|
||||
m_computer.getEnvironment().setRedstoneInput( side, level );
|
||||
computer.getEnvironment().setRedstoneInput( side, level );
|
||||
}
|
||||
|
||||
public int getBundledRedstoneOutput( ComputerSide side )
|
||||
{
|
||||
return m_computer.getEnvironment().getExternalBundledRedstoneOutput( side );
|
||||
return computer.getEnvironment().getExternalBundledRedstoneOutput( side );
|
||||
}
|
||||
|
||||
public void setBundledRedstoneInput( ComputerSide side, int combination )
|
||||
{
|
||||
m_computer.getEnvironment().setBundledRedstoneInput( side, combination );
|
||||
computer.getEnvironment().setBundledRedstoneInput( side, combination );
|
||||
}
|
||||
|
||||
public void addAPI( ILuaAPI api )
|
||||
{
|
||||
m_computer.addApi( api );
|
||||
computer.addApi( api );
|
||||
}
|
||||
|
||||
public void setPeripheral( ComputerSide side, IPeripheral peripheral )
|
||||
{
|
||||
m_computer.getEnvironment().setPeripheral( side, peripheral );
|
||||
computer.getEnvironment().setPeripheral( side, peripheral );
|
||||
}
|
||||
|
||||
public IPeripheral getPeripheral( ComputerSide side )
|
||||
{
|
||||
return m_computer.getEnvironment().getPeripheral( side );
|
||||
return computer.getEnvironment().getPeripheral( side );
|
||||
}
|
||||
|
||||
public void setLabel( String label )
|
||||
{
|
||||
m_computer.setLabel( label );
|
||||
computer.setLabel( label );
|
||||
}
|
||||
|
||||
// IComputerEnvironment implementation
|
||||
@ -310,19 +303,19 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
||||
@Override
|
||||
public double getTimeOfDay()
|
||||
{
|
||||
return (m_world.getDayTime() + 6000) % 24000 / 1000.0;
|
||||
return (world.getDayTime() + 6000) % 24000 / 1000.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDay()
|
||||
{
|
||||
return (int) ((m_world.getDayTime() + 6000) / 24000) + 1;
|
||||
return (int) ((world.getDayTime() + 6000) / 24000) + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWritableMount createSaveDirMount( String subPath, long capacity )
|
||||
{
|
||||
return ComputerCraftAPI.createSaveDirMount( m_world, subPath, capacity );
|
||||
return ComputerCraftAPI.createSaveDirMount( world, subPath, capacity );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -360,7 +353,7 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
||||
@Override
|
||||
public int assignNewID()
|
||||
{
|
||||
return ComputerCraftAPI.createUniqueNumberedSaveDir( m_world, "computer" );
|
||||
return ComputerCraftAPI.createUniqueNumberedSaveDir( world, "computer" );
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -12,8 +12,6 @@ import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.item.Item.Properties;
|
||||
|
||||
public class ItemComputer extends ItemComputerBase
|
||||
{
|
||||
public ItemComputer( BlockComputer block, Properties settings )
|
||||
|
@ -24,8 +24,6 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.item.Item.Properties;
|
||||
|
||||
public abstract class ItemComputerBase extends BlockItem implements IComputerItem, IMedia
|
||||
{
|
||||
private final ComputerFamily family;
|
||||
|
@ -15,8 +15,6 @@ import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import dan200.computercraft.shared.computer.recipe.ComputerFamilyRecipe.Serializer;
|
||||
|
||||
public class ComputerUpgradeRecipe extends ComputerFamilyRecipe
|
||||
{
|
||||
public ComputerUpgradeRecipe( ResourceLocation identifier, String group, int width, int height, NonNullList<Ingredient> ingredients, ItemStack result, ComputerFamily family )
|
||||
|
@ -17,8 +17,6 @@ import javax.annotation.Nonnull;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.loot.conditions.ILootCondition.IBuilder;
|
||||
|
||||
/**
|
||||
* A loot condition which checks if the tile entity has a name.
|
||||
*/
|
||||
|
@ -17,8 +17,6 @@ import javax.annotation.Nonnull;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.loot.conditions.ILootCondition.IBuilder;
|
||||
|
||||
/**
|
||||
* A loot condition which checks if the tile entity has has a non-0 ID.
|
||||
*/
|
||||
|
@ -17,8 +17,6 @@ import javax.annotation.Nonnull;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.loot.conditions.ILootCondition.IBuilder;
|
||||
|
||||
/**
|
||||
* A loot condition which checks if the entity is in creative mode.
|
||||
*/
|
||||
|
@ -31,8 +31,6 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.item.Item.Properties;
|
||||
|
||||
public class ItemDisk extends Item implements IMedia, IColouredItem
|
||||
{
|
||||
private static final String NBT_ID = "DiskId";
|
||||
|
@ -23,8 +23,6 @@ import net.minecraft.world.World;
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.item.Item.Properties;
|
||||
|
||||
public class ItemPrintout extends Item
|
||||
{
|
||||
private static final String NBT_TITLE = "Title";
|
||||
|
@ -29,8 +29,6 @@ import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.item.Item.Properties;
|
||||
|
||||
public class ItemTreasureDisk extends Item implements IMedia
|
||||
{
|
||||
private static final String NBT_TITLE = "Title";
|
||||
|
@ -10,8 +10,6 @@ import dan200.computercraft.shared.command.text.TableBuilder;
|
||||
import dan200.computercraft.shared.network.NetworkMessage;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@ -80,7 +78,6 @@ public class ChatTableClientMessage implements NetworkMessage
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn( Dist.CLIENT )
|
||||
public void handle( NetworkEvent.Context context )
|
||||
{
|
||||
ClientTableFormatter.INSTANCE.display( table );
|
||||
|
@ -27,8 +27,6 @@ import net.minecraft.world.World;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.AbstractBlock.Properties;
|
||||
|
||||
public class BlockDiskDrive extends BlockGeneric
|
||||
{
|
||||
static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
@ -59,18 +59,18 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
|
||||
ITextComponent customName;
|
||||
|
||||
private final Map<IComputerAccess, MountInfo> m_computers = new HashMap<>();
|
||||
private final Map<IComputerAccess, MountInfo> computers = new HashMap<>();
|
||||
|
||||
@Nonnull
|
||||
private ItemStack m_diskStack = ItemStack.EMPTY;
|
||||
private ItemStack diskStack = ItemStack.EMPTY;
|
||||
private LazyOptional<IItemHandlerModifiable> itemHandlerCap;
|
||||
private LazyOptional<IPeripheral> peripheralCap;
|
||||
private IMount m_diskMount = null;
|
||||
private IMount diskMount = null;
|
||||
|
||||
private boolean m_recordQueued = false;
|
||||
private boolean m_recordPlaying = false;
|
||||
private boolean m_restartRecord = false;
|
||||
private boolean m_ejectQueued;
|
||||
private boolean recordQueued = false;
|
||||
private boolean recordPlaying = false;
|
||||
private boolean restartRecord = false;
|
||||
private boolean ejectQueued;
|
||||
|
||||
public TileDiskDrive( TileEntityType<TileDiskDrive> type )
|
||||
{
|
||||
@ -81,7 +81,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
public void destroy()
|
||||
{
|
||||
ejectContents( true );
|
||||
if( m_recordPlaying ) stopRecord();
|
||||
if( recordPlaying ) stopRecord();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -129,8 +129,8 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
if( nbt.contains( NBT_ITEM ) )
|
||||
{
|
||||
CompoundNBT item = nbt.getCompound( NBT_ITEM );
|
||||
m_diskStack = ItemStack.of( item );
|
||||
m_diskMount = null;
|
||||
diskStack = ItemStack.of( item );
|
||||
diskMount = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,10 +140,10 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
{
|
||||
if( customName != null ) nbt.putString( NBT_NAME, ITextComponent.Serializer.toJson( customName ) );
|
||||
|
||||
if( !m_diskStack.isEmpty() )
|
||||
if( !diskStack.isEmpty() )
|
||||
{
|
||||
CompoundNBT item = new CompoundNBT();
|
||||
m_diskStack.save( item );
|
||||
diskStack.save( item );
|
||||
nbt.put( NBT_ITEM, item );
|
||||
}
|
||||
return super.save( nbt );
|
||||
@ -153,36 +153,36 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
public void tick()
|
||||
{
|
||||
// Ejection
|
||||
if( m_ejectQueued )
|
||||
if( ejectQueued )
|
||||
{
|
||||
ejectContents( false );
|
||||
m_ejectQueued = false;
|
||||
ejectQueued = false;
|
||||
}
|
||||
|
||||
// Music
|
||||
synchronized( this )
|
||||
{
|
||||
if( !level.isClientSide && m_recordPlaying != m_recordQueued || m_restartRecord )
|
||||
if( !level.isClientSide && recordPlaying != recordQueued || restartRecord )
|
||||
{
|
||||
m_restartRecord = false;
|
||||
if( m_recordQueued )
|
||||
restartRecord = false;
|
||||
if( recordQueued )
|
||||
{
|
||||
IMedia contents = getDiskMedia();
|
||||
SoundEvent record = contents != null ? contents.getAudio( m_diskStack ) : null;
|
||||
SoundEvent record = contents != null ? contents.getAudio( diskStack ) : null;
|
||||
if( record != null )
|
||||
{
|
||||
m_recordPlaying = true;
|
||||
recordPlaying = true;
|
||||
playRecord();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_recordQueued = false;
|
||||
recordQueued = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stopRecord();
|
||||
m_recordPlaying = false;
|
||||
recordPlaying = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -199,23 +199,23 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
@Override
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return m_diskStack.isEmpty();
|
||||
return diskStack.isEmpty();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack getItem( int slot )
|
||||
{
|
||||
return m_diskStack;
|
||||
return diskStack;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack removeItemNoUpdate( int slot )
|
||||
{
|
||||
ItemStack result = m_diskStack;
|
||||
m_diskStack = ItemStack.EMPTY;
|
||||
m_diskMount = null;
|
||||
ItemStack result = diskStack;
|
||||
diskStack = ItemStack.EMPTY;
|
||||
diskMount = null;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -224,17 +224,17 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
@Override
|
||||
public ItemStack removeItem( int slot, int count )
|
||||
{
|
||||
if( m_diskStack.isEmpty() ) return ItemStack.EMPTY;
|
||||
if( diskStack.isEmpty() ) return ItemStack.EMPTY;
|
||||
|
||||
if( m_diskStack.getCount() <= count )
|
||||
if( diskStack.getCount() <= count )
|
||||
{
|
||||
ItemStack disk = m_diskStack;
|
||||
ItemStack disk = diskStack;
|
||||
setItem( slot, ItemStack.EMPTY );
|
||||
return disk;
|
||||
}
|
||||
|
||||
ItemStack part = m_diskStack.split( count );
|
||||
setItem( slot, m_diskStack.isEmpty() ? ItemStack.EMPTY : m_diskStack );
|
||||
ItemStack part = diskStack.split( count );
|
||||
setItem( slot, diskStack.isEmpty() ? ItemStack.EMPTY : diskStack );
|
||||
return part;
|
||||
}
|
||||
|
||||
@ -243,45 +243,45 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
{
|
||||
if( getLevel().isClientSide )
|
||||
{
|
||||
m_diskStack = stack;
|
||||
m_diskMount = null;
|
||||
diskStack = stack;
|
||||
diskMount = null;
|
||||
setChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized( this )
|
||||
{
|
||||
if( InventoryUtil.areItemsStackable( stack, m_diskStack ) )
|
||||
if( InventoryUtil.areItemsStackable( stack, diskStack ) )
|
||||
{
|
||||
m_diskStack = stack;
|
||||
diskStack = stack;
|
||||
return;
|
||||
}
|
||||
|
||||
// Unmount old disk
|
||||
if( !m_diskStack.isEmpty() )
|
||||
if( !diskStack.isEmpty() )
|
||||
{
|
||||
// TODO: Is this iteration thread safe?
|
||||
Set<IComputerAccess> computers = m_computers.keySet();
|
||||
Set<IComputerAccess> computers = this.computers.keySet();
|
||||
for( IComputerAccess computer : computers ) unmountDisk( computer );
|
||||
}
|
||||
|
||||
// Stop music
|
||||
if( m_recordPlaying )
|
||||
if( recordPlaying )
|
||||
{
|
||||
stopRecord();
|
||||
m_recordPlaying = false;
|
||||
m_recordQueued = false;
|
||||
recordPlaying = false;
|
||||
recordQueued = false;
|
||||
}
|
||||
|
||||
// Swap disk over
|
||||
m_diskStack = stack;
|
||||
m_diskMount = null;
|
||||
diskStack = stack;
|
||||
diskMount = null;
|
||||
setChanged();
|
||||
|
||||
// Mount new disk
|
||||
if( !m_diskStack.isEmpty() )
|
||||
if( !diskStack.isEmpty() )
|
||||
{
|
||||
Set<IComputerAccess> computers = m_computers.keySet();
|
||||
Set<IComputerAccess> computers = this.computers.keySet();
|
||||
for( IComputerAccess computer : computers ) mountDisk( computer );
|
||||
}
|
||||
}
|
||||
@ -326,7 +326,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
MountInfo info = m_computers.get( computer );
|
||||
MountInfo info = computers.get( computer );
|
||||
return info != null ? info.mountPath : null;
|
||||
}
|
||||
}
|
||||
@ -335,7 +335,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
m_computers.put( computer, new MountInfo() );
|
||||
computers.put( computer, new MountInfo() );
|
||||
mountDisk( computer );
|
||||
}
|
||||
}
|
||||
@ -345,7 +345,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
synchronized( this )
|
||||
{
|
||||
unmountDisk( computer );
|
||||
m_computers.remove( computer );
|
||||
computers.remove( computer );
|
||||
}
|
||||
}
|
||||
|
||||
@ -354,10 +354,10 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
synchronized( this )
|
||||
{
|
||||
IMedia media = getDiskMedia();
|
||||
if( media != null && media.getAudioTitle( m_diskStack ) != null )
|
||||
if( media != null && media.getAudioTitle( diskStack ) != null )
|
||||
{
|
||||
m_recordQueued = true;
|
||||
m_restartRecord = m_recordPlaying;
|
||||
recordQueued = true;
|
||||
restartRecord = recordPlaying;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -366,8 +366,8 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
m_recordQueued = false;
|
||||
m_restartRecord = false;
|
||||
recordQueued = false;
|
||||
restartRecord = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,7 +375,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
m_ejectQueued = true;
|
||||
ejectQueued = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,25 +383,25 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
|
||||
private synchronized void mountDisk( IComputerAccess computer )
|
||||
{
|
||||
if( !m_diskStack.isEmpty() )
|
||||
if( !diskStack.isEmpty() )
|
||||
{
|
||||
MountInfo info = m_computers.get( computer );
|
||||
MountInfo info = computers.get( computer );
|
||||
IMedia contents = getDiskMedia();
|
||||
if( contents != null )
|
||||
{
|
||||
if( m_diskMount == null )
|
||||
if( diskMount == null )
|
||||
{
|
||||
m_diskMount = contents.createDataMount( m_diskStack, getLevel() );
|
||||
diskMount = contents.createDataMount( diskStack, getLevel() );
|
||||
}
|
||||
if( m_diskMount != null )
|
||||
if( diskMount != null )
|
||||
{
|
||||
if( m_diskMount instanceof IWritableMount )
|
||||
if( diskMount instanceof IWritableMount )
|
||||
{
|
||||
// Try mounting at the lowest numbered "disk" name we can
|
||||
int n = 1;
|
||||
while( info.mountPath == null )
|
||||
{
|
||||
info.mountPath = computer.mountWritable( n == 1 ? "disk" : "disk" + n, (IWritableMount) m_diskMount );
|
||||
info.mountPath = computer.mountWritable( n == 1 ? "disk" : "disk" + n, (IWritableMount) diskMount );
|
||||
n++;
|
||||
}
|
||||
}
|
||||
@ -411,7 +411,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
int n = 1;
|
||||
while( info.mountPath == null )
|
||||
{
|
||||
info.mountPath = computer.mount( n == 1 ? "disk" : "disk" + n, m_diskMount );
|
||||
info.mountPath = computer.mount( n == 1 ? "disk" : "disk" + n, diskMount );
|
||||
n++;
|
||||
}
|
||||
}
|
||||
@ -427,9 +427,9 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
|
||||
private synchronized void unmountDisk( IComputerAccess computer )
|
||||
{
|
||||
if( !m_diskStack.isEmpty() )
|
||||
if( !diskStack.isEmpty() )
|
||||
{
|
||||
MountInfo info = m_computers.get( computer );
|
||||
MountInfo info = computers.get( computer );
|
||||
assert info != null;
|
||||
if( info.mountPath != null )
|
||||
{
|
||||
@ -444,7 +444,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
{
|
||||
if( remove ) return;
|
||||
|
||||
if( !m_diskStack.isEmpty() )
|
||||
if( !diskStack.isEmpty() )
|
||||
{
|
||||
IMedia contents = getDiskMedia();
|
||||
updateBlockState( contents != null ? DiskDriveState.FULL : DiskDriveState.INVALID );
|
||||
@ -465,10 +465,10 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
|
||||
private synchronized void ejectContents( boolean destroyed )
|
||||
{
|
||||
if( getLevel().isClientSide || m_diskStack.isEmpty() ) return;
|
||||
if( getLevel().isClientSide || diskStack.isEmpty() ) return;
|
||||
|
||||
// Remove the disks from the inventory
|
||||
ItemStack disks = m_diskStack;
|
||||
ItemStack disks = diskStack;
|
||||
setDiskStack( ItemStack.EMPTY );
|
||||
|
||||
// Spawn the item in the world
|
||||
@ -497,10 +497,10 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
private void playRecord()
|
||||
{
|
||||
IMedia contents = getDiskMedia();
|
||||
SoundEvent record = contents != null ? contents.getAudio( m_diskStack ) : null;
|
||||
SoundEvent record = contents != null ? contents.getAudio( diskStack ) : null;
|
||||
if( record != null )
|
||||
{
|
||||
RecordUtil.playRecord( record, contents.getAudioTitle( m_diskStack ), getLevel(), getBlockPos() );
|
||||
RecordUtil.playRecord( record, contents.getAudioTitle( diskStack ), getLevel(), getBlockPos() );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -90,7 +90,7 @@ public class InventoryMethods implements GenericSource
|
||||
* Get detailed information about an item.
|
||||
*
|
||||
* @param inventory The current inventory.
|
||||
* @param slot The slot to get information about.
|
||||
* @param slot The slot to get information about.
|
||||
* @return Information about the item in this slot, or {@code nil} if not present.
|
||||
* @throws LuaException If the slot is out of range.
|
||||
* @cc.treturn table Information about the item in this slot, or {@code nil} if not present.
|
||||
@ -111,17 +111,16 @@ public class InventoryMethods implements GenericSource
|
||||
* This allows you to push an item in an inventory to another inventory <em>on the same wired network</em>. Both
|
||||
* inventories must attached to wired modems which are connected via a cable.
|
||||
*
|
||||
* @param from Inventory to move items from.
|
||||
* @param from Inventory to move items from.
|
||||
* @param computer The current computer.
|
||||
* @param toName The name of the peripheral/inventory to push to. This is the string given to @{peripheral.wrap},
|
||||
* and displayed by the wired modem.
|
||||
* @param toName The name of the peripheral/inventory to push to. This is the string given to @{peripheral.wrap},
|
||||
* and displayed by the wired modem.
|
||||
* @param fromSlot The slot in the current inventory to move items to.
|
||||
* @param limit The maximum number of items to move. Defaults to the current stack limit.
|
||||
* @param toSlot The slot in the target inventory to move to. If not given, the item will be inserted into any slot.
|
||||
* @param limit The maximum number of items to move. Defaults to the current stack limit.
|
||||
* @param toSlot The slot in the target inventory to move to. If not given, the item will be inserted into any slot.
|
||||
* @return The number of transferred items.
|
||||
* @throws LuaException If the peripheral to transfer to doesn't exist or isn't an inventory.
|
||||
* @throws LuaException If either source or destination slot is out of range.
|
||||
*
|
||||
* @cc.see peripheral.getName Allows you to get the name of a @{peripheral.wrap|wrapped} peripheral.
|
||||
* @cc.usage Wrap two chests, and push an item from one to another.
|
||||
* <pre>{@code
|
||||
@ -159,17 +158,16 @@ public class InventoryMethods implements GenericSource
|
||||
* This allows you to transfer items between inventories <em>on the same wired network</em>. Both this and the source
|
||||
* inventory must attached to wired modems which are connected via a cable.
|
||||
*
|
||||
* @param to Inventory to move items to.
|
||||
* @param to Inventory to move items to.
|
||||
* @param computer The current computer.
|
||||
* @param fromName The name of the peripheral/inventory to pull from. This is the string given to @{peripheral.wrap},
|
||||
* and displayed by the wired modem.
|
||||
* and displayed by the wired modem.
|
||||
* @param fromSlot The slot in the source inventory to move items from.
|
||||
* @param limit The maximum number of items to move. Defaults to the current stack limit.
|
||||
* @param toSlot The slot in current inventory to move to. If not given, the item will be inserted into any slot.
|
||||
* @param limit The maximum number of items to move. Defaults to the current stack limit.
|
||||
* @param toSlot The slot in current inventory to move to. If not given, the item will be inserted into any slot.
|
||||
* @return The number of transferred items.
|
||||
* @throws LuaException If the peripheral to transfer to doesn't exist or isn't an inventory.
|
||||
* @throws LuaException If either source or destination slot is out of range.
|
||||
*
|
||||
* @cc.see peripheral.getName Allows you to get the name of a @{peripheral.wrap|wrapped} peripheral.
|
||||
* @cc.usage Wrap two chests, and push an item from one to another.
|
||||
* <pre>{@code
|
||||
|
@ -27,32 +27,32 @@ import java.util.Set;
|
||||
*/
|
||||
public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPacketReceiver
|
||||
{
|
||||
private IPacketNetwork m_network;
|
||||
private final Set<IComputerAccess> m_computers = new HashSet<>( 1 );
|
||||
private final ModemState m_state;
|
||||
private IPacketNetwork network;
|
||||
private final Set<IComputerAccess> computers = new HashSet<>( 1 );
|
||||
private final ModemState state;
|
||||
|
||||
protected ModemPeripheral( ModemState state )
|
||||
{
|
||||
m_state = state;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public ModemState getModemState()
|
||||
{
|
||||
return m_state;
|
||||
return state;
|
||||
}
|
||||
|
||||
private synchronized void setNetwork( IPacketNetwork network )
|
||||
{
|
||||
if( m_network == network ) return;
|
||||
if( this.network == network ) return;
|
||||
|
||||
// Leave old network
|
||||
if( m_network != null ) m_network.removeReceiver( this );
|
||||
if( this.network != null ) this.network.removeReceiver( this );
|
||||
|
||||
// Set new network
|
||||
m_network = network;
|
||||
this.network = network;
|
||||
|
||||
// Join new network
|
||||
if( m_network != null ) m_network.addReceiver( this );
|
||||
if( this.network != null ) this.network.addReceiver( this );
|
||||
}
|
||||
|
||||
public void destroy()
|
||||
@ -63,11 +63,11 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
||||
@Override
|
||||
public void receiveSameDimension( @Nonnull Packet packet, double distance )
|
||||
{
|
||||
if( packet.getSender() == this || !m_state.isOpen( packet.getChannel() ) ) return;
|
||||
if( packet.getSender() == this || !state.isOpen( packet.getChannel() ) ) return;
|
||||
|
||||
synchronized( m_computers )
|
||||
synchronized( computers )
|
||||
{
|
||||
for( IComputerAccess computer : m_computers )
|
||||
for( IComputerAccess computer : computers )
|
||||
{
|
||||
computer.queueEvent( "modem_message",
|
||||
computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload(), distance );
|
||||
@ -78,11 +78,11 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
||||
@Override
|
||||
public void receiveDifferentDimension( @Nonnull Packet packet )
|
||||
{
|
||||
if( packet.getSender() == this || !m_state.isOpen( packet.getChannel() ) ) return;
|
||||
if( packet.getSender() == this || !state.isOpen( packet.getChannel() ) ) return;
|
||||
|
||||
synchronized( m_computers )
|
||||
synchronized( computers )
|
||||
{
|
||||
for( IComputerAccess computer : m_computers )
|
||||
for( IComputerAccess computer : computers )
|
||||
{
|
||||
computer.queueEvent( "modem_message",
|
||||
computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload() );
|
||||
@ -116,7 +116,7 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
||||
@LuaFunction
|
||||
public final void open( int channel ) throws LuaException
|
||||
{
|
||||
m_state.open( parseChannel( channel ) );
|
||||
state.open( parseChannel( channel ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,7 +129,7 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
||||
@LuaFunction
|
||||
public final boolean isOpen( int channel ) throws LuaException
|
||||
{
|
||||
return m_state.isOpen( parseChannel( channel ) );
|
||||
return state.isOpen( parseChannel( channel ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -141,7 +141,7 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
||||
@LuaFunction
|
||||
public final void close( int channel ) throws LuaException
|
||||
{
|
||||
m_state.close( parseChannel( channel ) );
|
||||
state.close( parseChannel( channel ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,7 +150,7 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
||||
@LuaFunction
|
||||
public final void closeAll()
|
||||
{
|
||||
m_state.closeAll();
|
||||
state.closeAll();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,7 +172,7 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
||||
|
||||
World world = getWorld();
|
||||
Vector3d position = getPosition();
|
||||
IPacketNetwork network = m_network;
|
||||
IPacketNetwork network = this.network;
|
||||
|
||||
if( world == null || position == null || network == null ) return;
|
||||
|
||||
@ -198,16 +198,16 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
||||
@LuaFunction
|
||||
public final boolean isWireless()
|
||||
{
|
||||
IPacketNetwork network = m_network;
|
||||
IPacketNetwork network = this.network;
|
||||
return network != null && network.isWireless();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void attach( @Nonnull IComputerAccess computer )
|
||||
{
|
||||
synchronized( m_computers )
|
||||
synchronized( computers )
|
||||
{
|
||||
m_computers.add( computer );
|
||||
computers.add( computer );
|
||||
}
|
||||
|
||||
setNetwork( getNetwork() );
|
||||
@ -217,10 +217,10 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
||||
public synchronized void detach( @Nonnull IComputerAccess computer )
|
||||
{
|
||||
boolean empty;
|
||||
synchronized( m_computers )
|
||||
synchronized( computers )
|
||||
{
|
||||
m_computers.remove( computer );
|
||||
empty = m_computers.isEmpty();
|
||||
computers.remove( computer );
|
||||
empty = computers.isEmpty();
|
||||
}
|
||||
|
||||
if( empty ) setNetwork( null );
|
||||
@ -230,15 +230,15 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
||||
@Override
|
||||
public String getSenderID()
|
||||
{
|
||||
synchronized( m_computers )
|
||||
synchronized( computers )
|
||||
{
|
||||
if( m_computers.size() != 1 )
|
||||
if( computers.size() != 1 )
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
else
|
||||
{
|
||||
IComputerAccess computer = m_computers.iterator().next();
|
||||
IComputerAccess computer = computers.iterator().next();
|
||||
return computer.getID() + "_" + computer.getAttachmentName();
|
||||
}
|
||||
}
|
||||
|
@ -40,8 +40,6 @@ import java.util.EnumMap;
|
||||
|
||||
import static dan200.computercraft.shared.util.WaterloggableHelpers.*;
|
||||
|
||||
import net.minecraft.block.AbstractBlock.Properties;
|
||||
|
||||
public class BlockCable extends BlockGeneric implements IWaterLoggable
|
||||
{
|
||||
public static final EnumProperty<CableModemVariant> MODEM = EnumProperty.create( "modem", CableModemVariant.class );
|
||||
|
@ -12,8 +12,6 @@ import net.minecraft.block.BlockState;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.StateContainer;
|
||||
|
||||
import net.minecraft.block.AbstractBlock.Properties;
|
||||
|
||||
public class BlockWiredModemFull extends BlockGeneric
|
||||
{
|
||||
public static final BooleanProperty MODEM_ON = BooleanProperty.create( "modem" );
|
||||
|
@ -23,8 +23,6 @@ import javax.annotation.Nonnull;
|
||||
|
||||
import static dan200.computercraft.shared.peripheral.modem.wired.BlockCable.*;
|
||||
|
||||
import net.minecraft.item.Item.Properties;
|
||||
|
||||
public abstract class ItemBlockCable extends BlockItem
|
||||
{
|
||||
private String translationKey;
|
||||
|
@ -67,38 +67,38 @@ public class TileCable extends TileGeneric
|
||||
@Override
|
||||
protected void attachPeripheral( String name, IPeripheral peripheral )
|
||||
{
|
||||
m_modem.attachPeripheral( name, peripheral );
|
||||
modem.attachPeripheral( name, peripheral );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void detachPeripheral( String name )
|
||||
{
|
||||
m_modem.detachPeripheral( name );
|
||||
modem.detachPeripheral( name );
|
||||
}
|
||||
}
|
||||
|
||||
private boolean m_peripheralAccessAllowed;
|
||||
private final WiredModemLocalPeripheral m_peripheral = new WiredModemLocalPeripheral( this::refreshPeripheral );
|
||||
private boolean peripheralAccessAllowed;
|
||||
private final WiredModemLocalPeripheral peripheral = new WiredModemLocalPeripheral( this::refreshPeripheral );
|
||||
|
||||
private boolean m_destroyed = false;
|
||||
private boolean destroyed = false;
|
||||
|
||||
private Direction modemDirection = Direction.NORTH;
|
||||
private boolean hasModemDirection = false;
|
||||
private boolean m_connectionsFormed = false;
|
||||
private boolean connectionsFormed = false;
|
||||
|
||||
private final WiredModemElement m_cable = new CableElement();
|
||||
private final WiredModemElement cable = new CableElement();
|
||||
private LazyOptional<IWiredElement> elementCap;
|
||||
private final IWiredNode m_node = m_cable.getNode();
|
||||
private final WiredModemPeripheral m_modem = new WiredModemPeripheral(
|
||||
private final IWiredNode node = cable.getNode();
|
||||
private final WiredModemPeripheral modem = new WiredModemPeripheral(
|
||||
new ModemState( () -> TickScheduler.schedule( this ) ),
|
||||
m_cable
|
||||
cable
|
||||
)
|
||||
{
|
||||
@Nonnull
|
||||
@Override
|
||||
protected WiredModemLocalPeripheral getLocalPeripheral()
|
||||
{
|
||||
return m_peripheral;
|
||||
return peripheral;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -129,18 +129,18 @@ public class TileCable extends TileGeneric
|
||||
{
|
||||
if( level == null || !level.isClientSide )
|
||||
{
|
||||
m_node.remove();
|
||||
m_connectionsFormed = false;
|
||||
node.remove();
|
||||
connectionsFormed = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
if( !m_destroyed )
|
||||
if( !destroyed )
|
||||
{
|
||||
m_destroyed = true;
|
||||
m_modem.destroy();
|
||||
destroyed = true;
|
||||
modem.destroy();
|
||||
onRemove();
|
||||
}
|
||||
}
|
||||
@ -236,7 +236,7 @@ public class TileCable extends TileGeneric
|
||||
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
|
||||
{
|
||||
super.onNeighbourTileEntityChange( neighbour );
|
||||
if( !level.isClientSide && m_peripheralAccessAllowed )
|
||||
if( !level.isClientSide && peripheralAccessAllowed )
|
||||
{
|
||||
Direction facing = getDirection();
|
||||
if( getBlockPos().relative( facing ).equals( neighbour ) ) refreshPeripheral();
|
||||
@ -245,7 +245,7 @@ public class TileCable extends TileGeneric
|
||||
|
||||
private void refreshPeripheral()
|
||||
{
|
||||
if( level != null && !isRemoved() && m_peripheral.attach( level, getBlockPos(), getDirection() ) )
|
||||
if( level != null && !isRemoved() && peripheral.attach( level, getBlockPos(), getDirection() ) )
|
||||
{
|
||||
updateConnectedPeripherals();
|
||||
}
|
||||
@ -260,9 +260,9 @@ public class TileCable extends TileGeneric
|
||||
|
||||
if( getLevel().isClientSide ) return ActionResultType.SUCCESS;
|
||||
|
||||
String oldName = m_peripheral.getConnectedName();
|
||||
String oldName = peripheral.getConnectedName();
|
||||
togglePeripheralAccess();
|
||||
String newName = m_peripheral.getConnectedName();
|
||||
String newName = peripheral.getConnectedName();
|
||||
if( !Objects.equal( newName, oldName ) )
|
||||
{
|
||||
if( oldName != null )
|
||||
@ -284,16 +284,16 @@ public class TileCable extends TileGeneric
|
||||
public void load( @Nonnull BlockState state, @Nonnull CompoundNBT nbt )
|
||||
{
|
||||
super.load( state, nbt );
|
||||
m_peripheralAccessAllowed = nbt.getBoolean( NBT_PERIPHERAL_ENABLED );
|
||||
m_peripheral.read( nbt, "" );
|
||||
peripheralAccessAllowed = nbt.getBoolean( NBT_PERIPHERAL_ENABLED );
|
||||
peripheral.read( nbt, "" );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public CompoundNBT save( CompoundNBT nbt )
|
||||
{
|
||||
nbt.putBoolean( NBT_PERIPHERAL_ENABLED, m_peripheralAccessAllowed );
|
||||
m_peripheral.write( nbt, "" );
|
||||
nbt.putBoolean( NBT_PERIPHERAL_ENABLED, peripheralAccessAllowed );
|
||||
peripheral.write( nbt, "" );
|
||||
return super.save( nbt );
|
||||
}
|
||||
|
||||
@ -302,7 +302,7 @@ public class TileCable extends TileGeneric
|
||||
BlockState state = getBlockState();
|
||||
CableModemVariant oldVariant = state.getValue( BlockCable.MODEM );
|
||||
CableModemVariant newVariant = CableModemVariant
|
||||
.from( oldVariant.getFacing(), m_modem.getModemState().isOpen(), m_peripheralAccessAllowed );
|
||||
.from( oldVariant.getFacing(), modem.getModemState().isOpen(), peripheralAccessAllowed );
|
||||
|
||||
if( oldVariant != newVariant )
|
||||
{
|
||||
@ -324,16 +324,16 @@ public class TileCable extends TileGeneric
|
||||
elementCap = CapabilityUtil.invalidate( elementCap );
|
||||
}
|
||||
|
||||
if( m_modem.getModemState().pollChanged() ) updateBlockState();
|
||||
if( modem.getModemState().pollChanged() ) updateBlockState();
|
||||
|
||||
if( !m_connectionsFormed )
|
||||
if( !connectionsFormed )
|
||||
{
|
||||
m_connectionsFormed = true;
|
||||
connectionsFormed = true;
|
||||
|
||||
connectionsChanged();
|
||||
if( m_peripheralAccessAllowed )
|
||||
if( peripheralAccessAllowed )
|
||||
{
|
||||
m_peripheral.attach( level, worldPosition, modemDirection );
|
||||
peripheral.attach( level, worldPosition, modemDirection );
|
||||
updateConnectedPeripherals();
|
||||
}
|
||||
}
|
||||
@ -359,12 +359,12 @@ public class TileCable extends TileGeneric
|
||||
if( BlockCable.canConnectIn( state, facing ) )
|
||||
{
|
||||
// If we can connect to it then do so
|
||||
m_node.connectTo( node );
|
||||
this.node.connectTo( node );
|
||||
}
|
||||
else if( m_node.getNetwork() == node.getNetwork() )
|
||||
else if( this.node.getNetwork() == node.getNetwork() )
|
||||
{
|
||||
// Otherwise if we're on the same network then attempt to void it.
|
||||
m_node.disconnectFrom( node );
|
||||
this.node.disconnectFrom( node );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -378,11 +378,11 @@ public class TileCable extends TileGeneric
|
||||
|
||||
// If we can no longer attach peripherals, then detach any
|
||||
// which may have existed
|
||||
if( !canAttachPeripheral() && m_peripheralAccessAllowed )
|
||||
if( !canAttachPeripheral() && peripheralAccessAllowed )
|
||||
{
|
||||
m_peripheralAccessAllowed = false;
|
||||
m_peripheral.detach();
|
||||
m_node.updatePeripherals( Collections.emptyMap() );
|
||||
peripheralAccessAllowed = false;
|
||||
peripheral.detach();
|
||||
node.updatePeripherals( Collections.emptyMap() );
|
||||
setChanged();
|
||||
updateBlockState();
|
||||
}
|
||||
@ -390,20 +390,20 @@ public class TileCable extends TileGeneric
|
||||
|
||||
private void togglePeripheralAccess()
|
||||
{
|
||||
if( !m_peripheralAccessAllowed )
|
||||
if( !peripheralAccessAllowed )
|
||||
{
|
||||
m_peripheral.attach( level, getBlockPos(), getDirection() );
|
||||
if( !m_peripheral.hasPeripheral() ) return;
|
||||
peripheral.attach( level, getBlockPos(), getDirection() );
|
||||
if( !peripheral.hasPeripheral() ) return;
|
||||
|
||||
m_peripheralAccessAllowed = true;
|
||||
m_node.updatePeripherals( m_peripheral.toMap() );
|
||||
peripheralAccessAllowed = true;
|
||||
node.updatePeripherals( peripheral.toMap() );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_peripheral.detach();
|
||||
peripheral.detach();
|
||||
|
||||
m_peripheralAccessAllowed = false;
|
||||
m_node.updatePeripherals( Collections.emptyMap() );
|
||||
peripheralAccessAllowed = false;
|
||||
node.updatePeripherals( Collections.emptyMap() );
|
||||
}
|
||||
|
||||
updateBlockState();
|
||||
@ -411,15 +411,15 @@ public class TileCable extends TileGeneric
|
||||
|
||||
private void updateConnectedPeripherals()
|
||||
{
|
||||
Map<String, IPeripheral> peripherals = m_peripheral.toMap();
|
||||
Map<String, IPeripheral> peripherals = peripheral.toMap();
|
||||
if( peripherals.isEmpty() )
|
||||
{
|
||||
// If there are no peripherals then disable access and update the display state.
|
||||
m_peripheralAccessAllowed = false;
|
||||
peripheralAccessAllowed = false;
|
||||
updateBlockState();
|
||||
}
|
||||
|
||||
m_node.updatePeripherals( peripherals );
|
||||
node.updatePeripherals( peripherals );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -428,8 +428,8 @@ public class TileCable extends TileGeneric
|
||||
{
|
||||
if( capability == CAPABILITY_WIRED_ELEMENT )
|
||||
{
|
||||
if( m_destroyed || !BlockCable.canConnectIn( getBlockState(), side ) ) return LazyOptional.empty();
|
||||
if( elementCap == null ) elementCap = LazyOptional.of( () -> m_cable );
|
||||
if( destroyed || !BlockCable.canConnectIn( getBlockState(), side ) ) return LazyOptional.empty();
|
||||
if( elementCap == null ) elementCap = LazyOptional.of( () -> cable );
|
||||
return elementCap.cast();
|
||||
}
|
||||
|
||||
@ -437,7 +437,7 @@ public class TileCable extends TileGeneric
|
||||
{
|
||||
refreshDirection();
|
||||
if( side != null && getMaybeDirection() != side ) return LazyOptional.empty();
|
||||
if( modemCap == null ) modemCap = LazyOptional.of( () -> m_modem );
|
||||
if( modemCap == null ) modemCap = LazyOptional.of( () -> modem );
|
||||
return modemCap.cast();
|
||||
}
|
||||
|
||||
|
@ -49,11 +49,11 @@ public class TileWiredModemFull extends TileGeneric
|
||||
|
||||
private static final class FullElement extends WiredModemElement
|
||||
{
|
||||
private final TileWiredModemFull m_entity;
|
||||
private final TileWiredModemFull entity;
|
||||
|
||||
private FullElement( TileWiredModemFull entity )
|
||||
{
|
||||
m_entity = entity;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -61,7 +61,7 @@ public class TileWiredModemFull extends TileGeneric
|
||||
{
|
||||
for( int i = 0; i < 6; i++ )
|
||||
{
|
||||
WiredModemPeripheral modem = m_entity.modems[i];
|
||||
WiredModemPeripheral modem = entity.modems[i];
|
||||
if( modem != null ) modem.attachPeripheral( name, peripheral );
|
||||
}
|
||||
}
|
||||
@ -71,7 +71,7 @@ public class TileWiredModemFull extends TileGeneric
|
||||
{
|
||||
for( int i = 0; i < 6; i++ )
|
||||
{
|
||||
WiredModemPeripheral modem = m_entity.modems[i];
|
||||
WiredModemPeripheral modem = entity.modems[i];
|
||||
if( modem != null ) modem.detachPeripheral( name );
|
||||
}
|
||||
}
|
||||
@ -80,14 +80,14 @@ public class TileWiredModemFull extends TileGeneric
|
||||
@Override
|
||||
public World getWorld()
|
||||
{
|
||||
return m_entity.getLevel();
|
||||
return entity.getLevel();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Vector3d getPosition()
|
||||
{
|
||||
BlockPos pos = m_entity.getBlockPos();
|
||||
BlockPos pos = entity.getBlockPos();
|
||||
return new Vector3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
|
||||
}
|
||||
}
|
||||
@ -95,26 +95,26 @@ public class TileWiredModemFull extends TileGeneric
|
||||
private final WiredModemPeripheral[] modems = new WiredModemPeripheral[6];
|
||||
private final SidedCaps<IPeripheral> modemCaps = SidedCaps.ofNonNull( this::getPeripheral );
|
||||
|
||||
private boolean m_peripheralAccessAllowed = false;
|
||||
private final WiredModemLocalPeripheral[] m_peripherals = new WiredModemLocalPeripheral[6];
|
||||
private boolean peripheralAccessAllowed = false;
|
||||
private final WiredModemLocalPeripheral[] peripherals = new WiredModemLocalPeripheral[6];
|
||||
|
||||
private boolean m_destroyed = false;
|
||||
private boolean m_connectionsFormed = false;
|
||||
private boolean destroyed = false;
|
||||
private boolean connectionsFormed = false;
|
||||
|
||||
private final ModemState m_modemState = new ModemState( () -> TickScheduler.schedule( this ) );
|
||||
private final WiredModemElement m_element = new FullElement( this );
|
||||
private final ModemState modemState = new ModemState( () -> TickScheduler.schedule( this ) );
|
||||
private final WiredModemElement element = new FullElement( this );
|
||||
private LazyOptional<IWiredElement> elementCap;
|
||||
private final IWiredNode m_node = m_element.getNode();
|
||||
private final IWiredNode node = element.getNode();
|
||||
|
||||
private final NonNullConsumer<LazyOptional<IWiredElement>> connectedNodeChanged = x -> connectionsChanged();
|
||||
|
||||
public TileWiredModemFull( TileEntityType<TileWiredModemFull> type )
|
||||
{
|
||||
super( type );
|
||||
for( int i = 0; i < m_peripherals.length; i++ )
|
||||
for( int i = 0; i < peripherals.length; i++ )
|
||||
{
|
||||
Direction facing = Direction.from3DDataValue( i );
|
||||
m_peripherals[i] = new WiredModemLocalPeripheral( () -> refreshPeripheral( facing ) );
|
||||
peripherals[i] = new WiredModemLocalPeripheral( () -> refreshPeripheral( facing ) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,17 +122,17 @@ public class TileWiredModemFull extends TileGeneric
|
||||
{
|
||||
if( level == null || !level.isClientSide )
|
||||
{
|
||||
m_node.remove();
|
||||
m_connectionsFormed = false;
|
||||
node.remove();
|
||||
connectionsFormed = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
if( !m_destroyed )
|
||||
if( !destroyed )
|
||||
{
|
||||
m_destroyed = true;
|
||||
destroyed = true;
|
||||
doRemove();
|
||||
}
|
||||
super.destroy();
|
||||
@ -169,7 +169,7 @@ public class TileWiredModemFull extends TileGeneric
|
||||
@Override
|
||||
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
|
||||
{
|
||||
if( !level.isClientSide && m_peripheralAccessAllowed )
|
||||
if( !level.isClientSide && peripheralAccessAllowed )
|
||||
{
|
||||
for( Direction facing : DirectionUtil.FACINGS )
|
||||
{
|
||||
@ -180,7 +180,7 @@ public class TileWiredModemFull extends TileGeneric
|
||||
|
||||
private void refreshPeripheral( @Nonnull Direction facing )
|
||||
{
|
||||
WiredModemLocalPeripheral peripheral = m_peripherals[facing.ordinal()];
|
||||
WiredModemLocalPeripheral peripheral = peripherals[facing.ordinal()];
|
||||
if( level != null && !isRemoved() && peripheral.attach( level, getBlockPos(), facing ) )
|
||||
{
|
||||
updateConnectedPeripherals();
|
||||
@ -228,23 +228,23 @@ public class TileWiredModemFull extends TileGeneric
|
||||
public void load( @Nonnull BlockState state, @Nonnull CompoundNBT nbt )
|
||||
{
|
||||
super.load( state, nbt );
|
||||
m_peripheralAccessAllowed = nbt.getBoolean( NBT_PERIPHERAL_ENABLED );
|
||||
for( int i = 0; i < m_peripherals.length; i++ ) m_peripherals[i].read( nbt, Integer.toString( i ) );
|
||||
peripheralAccessAllowed = nbt.getBoolean( NBT_PERIPHERAL_ENABLED );
|
||||
for( int i = 0; i < peripherals.length; i++ ) peripherals[i].read( nbt, Integer.toString( i ) );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public CompoundNBT save( CompoundNBT nbt )
|
||||
{
|
||||
nbt.putBoolean( NBT_PERIPHERAL_ENABLED, m_peripheralAccessAllowed );
|
||||
for( int i = 0; i < m_peripherals.length; i++ ) m_peripherals[i].write( nbt, Integer.toString( i ) );
|
||||
nbt.putBoolean( NBT_PERIPHERAL_ENABLED, peripheralAccessAllowed );
|
||||
for( int i = 0; i < peripherals.length; i++ ) peripherals[i].write( nbt, Integer.toString( i ) );
|
||||
return super.save( nbt );
|
||||
}
|
||||
|
||||
private void updateBlockState()
|
||||
{
|
||||
BlockState state = getBlockState();
|
||||
boolean modemOn = m_modemState.isOpen(), peripheralOn = m_peripheralAccessAllowed;
|
||||
boolean modemOn = modemState.isOpen(), peripheralOn = peripheralAccessAllowed;
|
||||
if( state.getValue( MODEM_ON ) == modemOn && state.getValue( PERIPHERAL_ON ) == peripheralOn ) return;
|
||||
|
||||
getLevel().setBlockAndUpdate( getBlockPos(), state.setValue( MODEM_ON, modemOn ).setValue( PERIPHERAL_ON, peripheralOn ) );
|
||||
@ -262,18 +262,18 @@ public class TileWiredModemFull extends TileGeneric
|
||||
{
|
||||
if( getLevel().isClientSide ) return;
|
||||
|
||||
if( m_modemState.pollChanged() ) updateBlockState();
|
||||
if( modemState.pollChanged() ) updateBlockState();
|
||||
|
||||
if( !m_connectionsFormed )
|
||||
if( !connectionsFormed )
|
||||
{
|
||||
m_connectionsFormed = true;
|
||||
connectionsFormed = true;
|
||||
|
||||
connectionsChanged();
|
||||
if( m_peripheralAccessAllowed )
|
||||
if( peripheralAccessAllowed )
|
||||
{
|
||||
for( Direction facing : DirectionUtil.FACINGS )
|
||||
{
|
||||
m_peripherals[facing.ordinal()].attach( level, getBlockPos(), facing );
|
||||
peripherals[facing.ordinal()].attach( level, getBlockPos(), facing );
|
||||
}
|
||||
updateConnectedPeripherals();
|
||||
}
|
||||
@ -295,33 +295,33 @@ public class TileWiredModemFull extends TileGeneric
|
||||
if( !element.isPresent() ) continue;
|
||||
|
||||
element.addListener( connectedNodeChanged );
|
||||
m_node.connectTo( element.orElseThrow( NullPointerException::new ).getNode() );
|
||||
node.connectTo( element.orElseThrow( NullPointerException::new ).getNode() );
|
||||
}
|
||||
}
|
||||
|
||||
private void togglePeripheralAccess()
|
||||
{
|
||||
if( !m_peripheralAccessAllowed )
|
||||
if( !peripheralAccessAllowed )
|
||||
{
|
||||
boolean hasAny = false;
|
||||
for( Direction facing : DirectionUtil.FACINGS )
|
||||
{
|
||||
WiredModemLocalPeripheral peripheral = m_peripherals[facing.ordinal()];
|
||||
WiredModemLocalPeripheral peripheral = peripherals[facing.ordinal()];
|
||||
peripheral.attach( level, getBlockPos(), facing );
|
||||
hasAny |= peripheral.hasPeripheral();
|
||||
}
|
||||
|
||||
if( !hasAny ) return;
|
||||
|
||||
m_peripheralAccessAllowed = true;
|
||||
m_node.updatePeripherals( getConnectedPeripherals() );
|
||||
peripheralAccessAllowed = true;
|
||||
node.updatePeripherals( getConnectedPeripherals() );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_peripheralAccessAllowed = false;
|
||||
peripheralAccessAllowed = false;
|
||||
|
||||
for( WiredModemLocalPeripheral peripheral : m_peripherals ) peripheral.detach();
|
||||
m_node.updatePeripherals( Collections.emptyMap() );
|
||||
for( WiredModemLocalPeripheral peripheral : peripherals ) peripheral.detach();
|
||||
node.updatePeripherals( Collections.emptyMap() );
|
||||
}
|
||||
|
||||
updateBlockState();
|
||||
@ -329,10 +329,10 @@ public class TileWiredModemFull extends TileGeneric
|
||||
|
||||
private Set<String> getConnectedPeripheralNames()
|
||||
{
|
||||
if( !m_peripheralAccessAllowed ) return Collections.emptySet();
|
||||
if( !peripheralAccessAllowed ) return Collections.emptySet();
|
||||
|
||||
Set<String> peripherals = new HashSet<>( 6 );
|
||||
for( WiredModemLocalPeripheral peripheral : m_peripherals )
|
||||
for( WiredModemLocalPeripheral peripheral : this.peripherals )
|
||||
{
|
||||
String name = peripheral.getConnectedName();
|
||||
if( name != null ) peripherals.add( name );
|
||||
@ -342,10 +342,10 @@ public class TileWiredModemFull extends TileGeneric
|
||||
|
||||
private Map<String, IPeripheral> getConnectedPeripherals()
|
||||
{
|
||||
if( !m_peripheralAccessAllowed ) return Collections.emptyMap();
|
||||
if( !peripheralAccessAllowed ) return Collections.emptyMap();
|
||||
|
||||
Map<String, IPeripheral> peripherals = new HashMap<>( 6 );
|
||||
for( WiredModemLocalPeripheral peripheral : m_peripherals ) peripheral.extendMap( peripherals );
|
||||
for( WiredModemLocalPeripheral peripheral : this.peripherals ) peripheral.extendMap( peripherals );
|
||||
return peripherals;
|
||||
}
|
||||
|
||||
@ -355,11 +355,11 @@ public class TileWiredModemFull extends TileGeneric
|
||||
if( peripherals.isEmpty() )
|
||||
{
|
||||
// If there are no peripherals then disable access and update the display state.
|
||||
m_peripheralAccessAllowed = false;
|
||||
peripheralAccessAllowed = false;
|
||||
updateBlockState();
|
||||
}
|
||||
|
||||
m_node.updatePeripherals( peripherals );
|
||||
node.updatePeripherals( peripherals );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -368,7 +368,7 @@ public class TileWiredModemFull extends TileGeneric
|
||||
{
|
||||
if( capability == CAPABILITY_WIRED_ELEMENT )
|
||||
{
|
||||
if( elementCap == null ) elementCap = LazyOptional.of( () -> m_element );
|
||||
if( elementCap == null ) elementCap = LazyOptional.of( () -> element );
|
||||
return elementCap.cast();
|
||||
}
|
||||
|
||||
@ -379,7 +379,7 @@ public class TileWiredModemFull extends TileGeneric
|
||||
|
||||
public IWiredElement getElement()
|
||||
{
|
||||
return m_element;
|
||||
return element;
|
||||
}
|
||||
|
||||
private WiredModemPeripheral getPeripheral( @Nonnull Direction side )
|
||||
@ -387,8 +387,8 @@ public class TileWiredModemFull extends TileGeneric
|
||||
WiredModemPeripheral peripheral = modems[side.ordinal()];
|
||||
if( peripheral != null ) return peripheral;
|
||||
|
||||
WiredModemLocalPeripheral localPeripheral = m_peripherals[side.ordinal()];
|
||||
return modems[side.ordinal()] = new WiredModemPeripheral( m_modemState, m_element )
|
||||
WiredModemLocalPeripheral localPeripheral = peripherals[side.ordinal()];
|
||||
return modems[side.ordinal()] = new WiredModemPeripheral( modemState, element )
|
||||
{
|
||||
@Nonnull
|
||||
@Override
|
||||
|
@ -31,8 +31,6 @@ import javax.annotation.Nullable;
|
||||
|
||||
import static dan200.computercraft.shared.util.WaterloggableHelpers.*;
|
||||
|
||||
import net.minecraft.block.AbstractBlock.Properties;
|
||||
|
||||
public class BlockWirelessModem extends BlockGeneric implements IWaterLoggable
|
||||
{
|
||||
public static final DirectionProperty FACING = BlockStateProperties.FACING;
|
||||
|
@ -14,24 +14,24 @@ import net.minecraft.world.World;
|
||||
|
||||
public abstract class WirelessModemPeripheral extends ModemPeripheral
|
||||
{
|
||||
private final boolean m_advanced;
|
||||
private final boolean advanced;
|
||||
|
||||
public WirelessModemPeripheral( ModemState state, boolean advanced )
|
||||
{
|
||||
super( state );
|
||||
m_advanced = advanced;
|
||||
this.advanced = advanced;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInterdimensional()
|
||||
{
|
||||
return m_advanced;
|
||||
return advanced;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRange()
|
||||
{
|
||||
if( m_advanced )
|
||||
if( advanced )
|
||||
{
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
@ -18,50 +18,47 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class WirelessNetwork implements IPacketNetwork
|
||||
{
|
||||
private static WirelessNetwork s_universalNetwork = null;
|
||||
private static WirelessNetwork universalNetwork = null;
|
||||
|
||||
public static WirelessNetwork getUniversal()
|
||||
{
|
||||
if( s_universalNetwork == null )
|
||||
{
|
||||
s_universalNetwork = new WirelessNetwork();
|
||||
}
|
||||
return s_universalNetwork;
|
||||
if( universalNetwork == null ) universalNetwork = new WirelessNetwork();
|
||||
return universalNetwork;
|
||||
}
|
||||
|
||||
public static void resetNetworks()
|
||||
{
|
||||
s_universalNetwork = null;
|
||||
universalNetwork = null;
|
||||
}
|
||||
|
||||
private final Set<IPacketReceiver> m_receivers = Collections.newSetFromMap( new ConcurrentHashMap<>() );
|
||||
private final Set<IPacketReceiver> receivers = Collections.newSetFromMap( new ConcurrentHashMap<>() );
|
||||
|
||||
@Override
|
||||
public void addReceiver( @Nonnull IPacketReceiver receiver )
|
||||
{
|
||||
Objects.requireNonNull( receiver, "device cannot be null" );
|
||||
m_receivers.add( receiver );
|
||||
receivers.add( receiver );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeReceiver( @Nonnull IPacketReceiver receiver )
|
||||
{
|
||||
Objects.requireNonNull( receiver, "device cannot be null" );
|
||||
m_receivers.remove( receiver );
|
||||
receivers.remove( receiver );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transmitSameDimension( @Nonnull Packet packet, double range )
|
||||
{
|
||||
Objects.requireNonNull( packet, "packet cannot be null" );
|
||||
for( IPacketReceiver device : m_receivers ) tryTransmit( device, packet, range, false );
|
||||
for( IPacketReceiver device : receivers ) tryTransmit( device, packet, range, false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transmitInterdimensional( @Nonnull Packet packet )
|
||||
{
|
||||
Objects.requireNonNull( packet, "packet cannot be null" );
|
||||
for( IPacketReceiver device : m_receivers ) tryTransmit( device, packet, 0, true );
|
||||
for( IPacketReceiver device : receivers ) tryTransmit( device, packet, 0, true );
|
||||
}
|
||||
|
||||
private static void tryTransmit( IPacketReceiver receiver, Packet packet, double range, boolean interdimensional )
|
||||
|
@ -25,8 +25,6 @@ import net.minecraftforge.fml.RegistryObject;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.AbstractBlock.Properties;
|
||||
|
||||
public class BlockMonitor extends BlockGeneric
|
||||
{
|
||||
public static final DirectionProperty ORIENTATION = DirectionProperty.create( "orientation",
|
||||
|
@ -49,23 +49,23 @@ public class TileMonitor extends TileGeneric
|
||||
|
||||
private final boolean advanced;
|
||||
|
||||
private ServerMonitor m_serverMonitor;
|
||||
private ClientMonitor m_clientMonitor;
|
||||
private ServerMonitor serverMonitor;
|
||||
private ClientMonitor clientMonitor;
|
||||
private MonitorPeripheral peripheral;
|
||||
private LazyOptional<IPeripheral> peripheralCap;
|
||||
private final Set<IComputerAccess> m_computers = new HashSet<>();
|
||||
private final Set<IComputerAccess> computers = new HashSet<>();
|
||||
|
||||
private boolean m_destroyed = false;
|
||||
private boolean destroyed = false;
|
||||
private boolean visiting = false;
|
||||
|
||||
// MonitorWatcher state.
|
||||
boolean enqueued;
|
||||
TerminalState cached;
|
||||
|
||||
private int m_width = 1;
|
||||
private int m_height = 1;
|
||||
private int m_xIndex = 0;
|
||||
private int m_yIndex = 0;
|
||||
private int width = 1;
|
||||
private int height = 1;
|
||||
private int xIndex = 0;
|
||||
private int yIndex = 0;
|
||||
|
||||
public TileMonitor( TileEntityType<? extends TileMonitor> type, boolean advanced )
|
||||
{
|
||||
@ -84,8 +84,8 @@ public class TileMonitor extends TileGeneric
|
||||
public void destroy()
|
||||
{
|
||||
// TODO: Call this before using the block
|
||||
if( m_destroyed ) return;
|
||||
m_destroyed = true;
|
||||
if( destroyed ) return;
|
||||
destroyed = true;
|
||||
if( !getLevel().isClientSide ) contractNeighbours();
|
||||
}
|
||||
|
||||
@ -93,14 +93,14 @@ public class TileMonitor extends TileGeneric
|
||||
public void setRemoved()
|
||||
{
|
||||
super.setRemoved();
|
||||
if( m_clientMonitor != null && m_xIndex == 0 && m_yIndex == 0 ) m_clientMonitor.destroy();
|
||||
if( clientMonitor != null && xIndex == 0 && yIndex == 0 ) clientMonitor.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkUnloaded()
|
||||
{
|
||||
super.onChunkUnloaded();
|
||||
if( m_clientMonitor != null && m_xIndex == 0 && m_yIndex == 0 ) m_clientMonitor.destroy();
|
||||
if( clientMonitor != null && xIndex == 0 && yIndex == 0 ) clientMonitor.destroy();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -127,10 +127,10 @@ public class TileMonitor extends TileGeneric
|
||||
@Override
|
||||
public CompoundNBT save( CompoundNBT tag )
|
||||
{
|
||||
tag.putInt( NBT_X, m_xIndex );
|
||||
tag.putInt( NBT_Y, m_yIndex );
|
||||
tag.putInt( NBT_WIDTH, m_width );
|
||||
tag.putInt( NBT_HEIGHT, m_height );
|
||||
tag.putInt( NBT_X, xIndex );
|
||||
tag.putInt( NBT_Y, yIndex );
|
||||
tag.putInt( NBT_WIDTH, width );
|
||||
tag.putInt( NBT_HEIGHT, height );
|
||||
return super.save( tag );
|
||||
}
|
||||
|
||||
@ -139,29 +139,29 @@ public class TileMonitor extends TileGeneric
|
||||
{
|
||||
super.load( state, nbt );
|
||||
|
||||
m_xIndex = nbt.getInt( NBT_X );
|
||||
m_yIndex = nbt.getInt( NBT_Y );
|
||||
m_width = nbt.getInt( NBT_WIDTH );
|
||||
m_height = nbt.getInt( NBT_HEIGHT );
|
||||
xIndex = nbt.getInt( NBT_X );
|
||||
yIndex = nbt.getInt( NBT_Y );
|
||||
width = nbt.getInt( NBT_WIDTH );
|
||||
height = nbt.getInt( NBT_HEIGHT );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void blockTick()
|
||||
{
|
||||
if( m_xIndex != 0 || m_yIndex != 0 || m_serverMonitor == null ) return;
|
||||
if( xIndex != 0 || yIndex != 0 || serverMonitor == null ) return;
|
||||
|
||||
m_serverMonitor.clearChanged();
|
||||
serverMonitor.clearChanged();
|
||||
|
||||
if( m_serverMonitor.pollResized() )
|
||||
if( serverMonitor.pollResized() )
|
||||
{
|
||||
for( int x = 0; x < m_width; x++ )
|
||||
for( int x = 0; x < width; x++ )
|
||||
{
|
||||
for( int y = 0; y < m_height; y++ )
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
TileMonitor monitor = getNeighbour( x, y );
|
||||
if( monitor == null ) continue;
|
||||
|
||||
for( IComputerAccess computer : monitor.m_computers )
|
||||
for( IComputerAccess computer : monitor.computers )
|
||||
{
|
||||
computer.queueEvent( "monitor_resize", computer.getAttachmentName() );
|
||||
}
|
||||
@ -169,7 +169,7 @@ public class TileMonitor extends TileGeneric
|
||||
}
|
||||
}
|
||||
|
||||
if( m_serverMonitor.pollTerminalChanged() ) MonitorWatcher.enqueue( this );
|
||||
if( serverMonitor.pollTerminalChanged() ) MonitorWatcher.enqueue( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -195,62 +195,62 @@ public class TileMonitor extends TileGeneric
|
||||
|
||||
public ServerMonitor getCachedServerMonitor()
|
||||
{
|
||||
return m_serverMonitor;
|
||||
return serverMonitor;
|
||||
}
|
||||
|
||||
private ServerMonitor getServerMonitor()
|
||||
{
|
||||
if( m_serverMonitor != null ) return m_serverMonitor;
|
||||
if( serverMonitor != null ) return serverMonitor;
|
||||
|
||||
TileMonitor origin = getOrigin();
|
||||
if( origin == null ) return null;
|
||||
|
||||
return m_serverMonitor = origin.m_serverMonitor;
|
||||
return serverMonitor = origin.serverMonitor;
|
||||
}
|
||||
|
||||
private ServerMonitor createServerMonitor()
|
||||
{
|
||||
if( m_serverMonitor != null ) return m_serverMonitor;
|
||||
if( serverMonitor != null ) return serverMonitor;
|
||||
|
||||
if( m_xIndex == 0 && m_yIndex == 0 )
|
||||
if( xIndex == 0 && yIndex == 0 )
|
||||
{
|
||||
// If we're the origin, set up the new monitor
|
||||
m_serverMonitor = new ServerMonitor( advanced, this );
|
||||
m_serverMonitor.rebuild();
|
||||
serverMonitor = new ServerMonitor( advanced, this );
|
||||
serverMonitor.rebuild();
|
||||
|
||||
// And propagate it to child monitors
|
||||
for( int x = 0; x < m_width; x++ )
|
||||
for( int x = 0; x < width; x++ )
|
||||
{
|
||||
for( int y = 0; y < m_height; y++ )
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
TileMonitor monitor = getNeighbour( x, y );
|
||||
if( monitor != null ) monitor.m_serverMonitor = m_serverMonitor;
|
||||
if( monitor != null ) monitor.serverMonitor = serverMonitor;
|
||||
}
|
||||
}
|
||||
|
||||
return m_serverMonitor;
|
||||
return serverMonitor;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise fetch the origin and attempt to get its monitor
|
||||
// Note this may load chunks, but we don't really have a choice here.
|
||||
BlockPos pos = getBlockPos();
|
||||
TileEntity te = level.getBlockEntity( pos.relative( getRight(), -m_xIndex ).relative( getDown(), -m_yIndex ) );
|
||||
TileEntity te = level.getBlockEntity( pos.relative( getRight(), -xIndex ).relative( getDown(), -yIndex ) );
|
||||
if( !(te instanceof TileMonitor) ) return null;
|
||||
|
||||
return m_serverMonitor = ((TileMonitor) te).createServerMonitor();
|
||||
return serverMonitor = ((TileMonitor) te).createServerMonitor();
|
||||
}
|
||||
}
|
||||
|
||||
public ClientMonitor getClientMonitor()
|
||||
{
|
||||
if( m_clientMonitor != null ) return m_clientMonitor;
|
||||
if( clientMonitor != null ) return clientMonitor;
|
||||
|
||||
BlockPos pos = getBlockPos();
|
||||
TileEntity te = level.getBlockEntity( pos.relative( getRight(), -m_xIndex ).relative( getDown(), -m_yIndex ) );
|
||||
TileEntity te = level.getBlockEntity( pos.relative( getRight(), -xIndex ).relative( getDown(), -yIndex ) );
|
||||
if( !(te instanceof TileMonitor) ) return null;
|
||||
|
||||
return m_clientMonitor = ((TileMonitor) te).m_clientMonitor;
|
||||
return clientMonitor = ((TileMonitor) te).clientMonitor;
|
||||
}
|
||||
|
||||
// Networking stuff
|
||||
@ -259,10 +259,10 @@ public class TileMonitor extends TileGeneric
|
||||
protected void writeDescription( @Nonnull CompoundNBT nbt )
|
||||
{
|
||||
super.writeDescription( nbt );
|
||||
nbt.putInt( NBT_X, m_xIndex );
|
||||
nbt.putInt( NBT_Y, m_yIndex );
|
||||
nbt.putInt( NBT_WIDTH, m_width );
|
||||
nbt.putInt( NBT_HEIGHT, m_height );
|
||||
nbt.putInt( NBT_X, xIndex );
|
||||
nbt.putInt( NBT_Y, yIndex );
|
||||
nbt.putInt( NBT_WIDTH, width );
|
||||
nbt.putInt( NBT_HEIGHT, height );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -270,32 +270,32 @@ public class TileMonitor extends TileGeneric
|
||||
{
|
||||
super.readDescription( nbt );
|
||||
|
||||
int oldXIndex = m_xIndex;
|
||||
int oldYIndex = m_yIndex;
|
||||
int oldWidth = m_width;
|
||||
int oldHeight = m_height;
|
||||
int oldXIndex = xIndex;
|
||||
int oldYIndex = yIndex;
|
||||
int oldWidth = width;
|
||||
int oldHeight = height;
|
||||
|
||||
m_xIndex = nbt.getInt( NBT_X );
|
||||
m_yIndex = nbt.getInt( NBT_Y );
|
||||
m_width = nbt.getInt( NBT_WIDTH );
|
||||
m_height = nbt.getInt( NBT_HEIGHT );
|
||||
xIndex = nbt.getInt( NBT_X );
|
||||
yIndex = nbt.getInt( NBT_Y );
|
||||
width = nbt.getInt( NBT_WIDTH );
|
||||
height = nbt.getInt( NBT_HEIGHT );
|
||||
|
||||
if( oldXIndex != m_xIndex || oldYIndex != m_yIndex )
|
||||
if( oldXIndex != xIndex || oldYIndex != yIndex )
|
||||
{
|
||||
// If our index has changed then it's possible the origin monitor has changed. Thus
|
||||
// we'll clear our cache. If we're the origin then we'll need to remove the glList as well.
|
||||
if( oldXIndex == 0 && oldYIndex == 0 && m_clientMonitor != null ) m_clientMonitor.destroy();
|
||||
m_clientMonitor = null;
|
||||
if( oldXIndex == 0 && oldYIndex == 0 && clientMonitor != null ) clientMonitor.destroy();
|
||||
clientMonitor = null;
|
||||
}
|
||||
|
||||
if( m_xIndex == 0 && m_yIndex == 0 )
|
||||
if( xIndex == 0 && yIndex == 0 )
|
||||
{
|
||||
// If we're the origin terminal then create it.
|
||||
if( m_clientMonitor == null ) m_clientMonitor = new ClientMonitor( advanced, this );
|
||||
if( clientMonitor == null ) clientMonitor = new ClientMonitor( advanced, this );
|
||||
}
|
||||
|
||||
if( oldXIndex != m_xIndex || oldYIndex != m_yIndex ||
|
||||
oldWidth != m_width || oldHeight != m_height )
|
||||
if( oldXIndex != xIndex || oldYIndex != yIndex ||
|
||||
oldWidth != width || oldHeight != height )
|
||||
{
|
||||
// One of our properties has changed, so ensure we redraw the block
|
||||
updateBlock();
|
||||
@ -304,14 +304,14 @@ public class TileMonitor extends TileGeneric
|
||||
|
||||
public final void read( TerminalState state )
|
||||
{
|
||||
if( m_xIndex != 0 || m_yIndex != 0 )
|
||||
if( xIndex != 0 || yIndex != 0 )
|
||||
{
|
||||
ComputerCraft.log.warn( "Receiving monitor state for non-origin terminal at {}", getBlockPos() );
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_clientMonitor == null ) m_clientMonitor = new ClientMonitor( advanced, this );
|
||||
m_clientMonitor.read( state );
|
||||
if( clientMonitor == null ) clientMonitor = new ClientMonitor( advanced, this );
|
||||
clientMonitor.read( state );
|
||||
}
|
||||
|
||||
// Sizing and placement stuff
|
||||
@ -320,8 +320,8 @@ public class TileMonitor extends TileGeneric
|
||||
{
|
||||
getLevel().setBlock( getBlockPos(), getBlockState()
|
||||
.setValue( BlockMonitor.STATE, MonitorEdgeState.fromConnections(
|
||||
m_yIndex < m_height - 1, m_yIndex > 0,
|
||||
m_xIndex > 0, m_xIndex < m_width - 1 ) ), 2 );
|
||||
yIndex < height - 1, yIndex > 0,
|
||||
xIndex > 0, xIndex < width - 1 ) ), 2 );
|
||||
}
|
||||
|
||||
// region Sizing and placement stuff
|
||||
@ -359,22 +359,22 @@ public class TileMonitor extends TileGeneric
|
||||
|
||||
public int getWidth()
|
||||
{
|
||||
return m_width;
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
return m_height;
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getXIndex()
|
||||
{
|
||||
return m_xIndex;
|
||||
return xIndex;
|
||||
}
|
||||
|
||||
public int getYIndex()
|
||||
{
|
||||
return m_yIndex;
|
||||
return yIndex;
|
||||
}
|
||||
|
||||
private TileMonitor getSimilarMonitorAt( BlockPos pos )
|
||||
@ -389,7 +389,7 @@ public class TileMonitor extends TileGeneric
|
||||
if( !(tile instanceof TileMonitor) ) return null;
|
||||
|
||||
TileMonitor monitor = (TileMonitor) tile;
|
||||
return !monitor.visiting && !monitor.m_destroyed && advanced == monitor.advanced
|
||||
return !monitor.visiting && !monitor.destroyed && advanced == monitor.advanced
|
||||
&& getDirection() == monitor.getDirection() && getOrientation() == monitor.getOrientation()
|
||||
? monitor : null;
|
||||
}
|
||||
@ -399,8 +399,8 @@ public class TileMonitor extends TileGeneric
|
||||
BlockPos pos = getBlockPos();
|
||||
Direction right = getRight();
|
||||
Direction down = getDown();
|
||||
int xOffset = -m_xIndex + x;
|
||||
int yOffset = -m_yIndex + y;
|
||||
int xOffset = -xIndex + x;
|
||||
int yOffset = -yIndex + y;
|
||||
return getSimilarMonitorAt( pos.relative( right, xOffset ).relative( down, yOffset ) );
|
||||
}
|
||||
|
||||
@ -412,12 +412,12 @@ public class TileMonitor extends TileGeneric
|
||||
private void resize( int width, int height )
|
||||
{
|
||||
// If we're not already the origin then we'll need to generate a new terminal.
|
||||
if( m_xIndex != 0 || m_yIndex != 0 ) m_serverMonitor = null;
|
||||
if( xIndex != 0 || yIndex != 0 ) serverMonitor = null;
|
||||
|
||||
m_xIndex = 0;
|
||||
m_yIndex = 0;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
xIndex = 0;
|
||||
yIndex = 0;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
// Determine if we actually need a monitor. In order to do this, simply check if
|
||||
// any component monitor been wrapped as a peripheral. Whilst this flag may be
|
||||
@ -440,16 +440,16 @@ public class TileMonitor extends TileGeneric
|
||||
// Either delete the current monitor or sync a new one.
|
||||
if( needsTerminal )
|
||||
{
|
||||
if( m_serverMonitor == null ) m_serverMonitor = new ServerMonitor( advanced, this );
|
||||
if( serverMonitor == null ) serverMonitor = new ServerMonitor( advanced, this );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_serverMonitor = null;
|
||||
serverMonitor = null;
|
||||
}
|
||||
|
||||
// Update the terminal's width and height and rebuild it. This ensures the monitor
|
||||
// is consistent when syncing it to other monitors.
|
||||
if( m_serverMonitor != null ) m_serverMonitor.rebuild();
|
||||
if( serverMonitor != null ) serverMonitor.rebuild();
|
||||
|
||||
// Update the other monitors, setting coordinates, dimensions and the server terminal
|
||||
for( int x = 0; x < width; x++ )
|
||||
@ -459,11 +459,11 @@ public class TileMonitor extends TileGeneric
|
||||
TileMonitor monitor = getNeighbour( x, y );
|
||||
if( monitor == null ) continue;
|
||||
|
||||
monitor.m_xIndex = x;
|
||||
monitor.m_yIndex = y;
|
||||
monitor.m_width = width;
|
||||
monitor.m_height = height;
|
||||
monitor.m_serverMonitor = m_serverMonitor;
|
||||
monitor.xIndex = x;
|
||||
monitor.yIndex = y;
|
||||
monitor.width = width;
|
||||
monitor.height = height;
|
||||
monitor.serverMonitor = serverMonitor;
|
||||
monitor.updateBlockState();
|
||||
monitor.updateBlock();
|
||||
}
|
||||
@ -473,41 +473,41 @@ public class TileMonitor extends TileGeneric
|
||||
private boolean mergeLeft()
|
||||
{
|
||||
TileMonitor left = getNeighbour( -1, 0 );
|
||||
if( left == null || left.m_yIndex != 0 || left.m_height != m_height ) return false;
|
||||
if( left == null || left.yIndex != 0 || left.height != height ) return false;
|
||||
|
||||
int width = left.m_width + m_width;
|
||||
int width = left.width + this.width;
|
||||
if( width > ComputerCraft.monitorWidth ) return false;
|
||||
|
||||
TileMonitor origin = left.getOrigin();
|
||||
if( origin != null ) origin.resize( width, m_height );
|
||||
if( origin != null ) origin.resize( width, height );
|
||||
left.expand();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean mergeRight()
|
||||
{
|
||||
TileMonitor right = getNeighbour( m_width, 0 );
|
||||
if( right == null || right.m_yIndex != 0 || right.m_height != m_height ) return false;
|
||||
TileMonitor right = getNeighbour( width, 0 );
|
||||
if( right == null || right.yIndex != 0 || right.height != height ) return false;
|
||||
|
||||
int width = m_width + right.m_width;
|
||||
int width = this.width + right.width;
|
||||
if( width > ComputerCraft.monitorWidth ) return false;
|
||||
|
||||
TileMonitor origin = getOrigin();
|
||||
if( origin != null ) origin.resize( width, m_height );
|
||||
if( origin != null ) origin.resize( width, height );
|
||||
expand();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean mergeUp()
|
||||
{
|
||||
TileMonitor above = getNeighbour( 0, m_height );
|
||||
if( above == null || above.m_xIndex != 0 || above.m_width != m_width ) return false;
|
||||
TileMonitor above = getNeighbour( 0, height );
|
||||
if( above == null || above.xIndex != 0 || above.width != width ) return false;
|
||||
|
||||
int height = above.m_height + m_height;
|
||||
int height = above.height + this.height;
|
||||
if( height > ComputerCraft.monitorHeight ) return false;
|
||||
|
||||
TileMonitor origin = getOrigin();
|
||||
if( origin != null ) origin.resize( m_width, height );
|
||||
if( origin != null ) origin.resize( width, height );
|
||||
expand();
|
||||
return true;
|
||||
}
|
||||
@ -515,13 +515,13 @@ public class TileMonitor extends TileGeneric
|
||||
private boolean mergeDown()
|
||||
{
|
||||
TileMonitor below = getNeighbour( 0, -1 );
|
||||
if( below == null || below.m_xIndex != 0 || below.m_width != m_width ) return false;
|
||||
if( below == null || below.xIndex != 0 || below.width != width ) return false;
|
||||
|
||||
int height = m_height + below.m_height;
|
||||
int height = this.height + below.height;
|
||||
if( height > ComputerCraft.monitorHeight ) return false;
|
||||
|
||||
TileMonitor origin = below.getOrigin();
|
||||
if( origin != null ) origin.resize( m_width, height );
|
||||
if( origin != null ) origin.resize( width, height );
|
||||
below.expand();
|
||||
return true;
|
||||
}
|
||||
@ -535,24 +535,24 @@ public class TileMonitor extends TileGeneric
|
||||
void contractNeighbours()
|
||||
{
|
||||
visiting = true;
|
||||
if( m_xIndex > 0 )
|
||||
if( xIndex > 0 )
|
||||
{
|
||||
TileMonitor left = getNeighbour( m_xIndex - 1, m_yIndex );
|
||||
TileMonitor left = getNeighbour( xIndex - 1, yIndex );
|
||||
if( left != null ) left.contract();
|
||||
}
|
||||
if( m_xIndex + 1 < m_width )
|
||||
if( xIndex + 1 < width )
|
||||
{
|
||||
TileMonitor right = getNeighbour( m_xIndex + 1, m_yIndex );
|
||||
TileMonitor right = getNeighbour( xIndex + 1, yIndex );
|
||||
if( right != null ) right.contract();
|
||||
}
|
||||
if( m_yIndex > 0 )
|
||||
if( yIndex > 0 )
|
||||
{
|
||||
TileMonitor below = getNeighbour( m_xIndex, m_yIndex - 1 );
|
||||
TileMonitor below = getNeighbour( xIndex, yIndex - 1 );
|
||||
if( below != null ) below.contract();
|
||||
}
|
||||
if( m_yIndex + 1 < m_height )
|
||||
if( yIndex + 1 < height )
|
||||
{
|
||||
TileMonitor above = getNeighbour( m_xIndex, m_yIndex + 1 );
|
||||
TileMonitor above = getNeighbour( xIndex, yIndex + 1 );
|
||||
if( above != null ) above.contract();
|
||||
}
|
||||
visiting = false;
|
||||
@ -560,8 +560,8 @@ public class TileMonitor extends TileGeneric
|
||||
|
||||
void contract()
|
||||
{
|
||||
int height = m_height;
|
||||
int width = m_width;
|
||||
int height = this.height;
|
||||
int width = this.width;
|
||||
|
||||
TileMonitor origin = getOrigin();
|
||||
if( origin == null )
|
||||
@ -625,9 +625,9 @@ public class TileMonitor extends TileGeneric
|
||||
{
|
||||
XYPair pair = XYPair
|
||||
.of( xPos, yPos, zPos, getDirection(), getOrientation() )
|
||||
.add( m_xIndex, m_height - m_yIndex - 1 );
|
||||
.add( xIndex, height - yIndex - 1 );
|
||||
|
||||
if( pair.x > m_width - RENDER_BORDER || pair.y > m_height - RENDER_BORDER || pair.x < RENDER_BORDER || pair.y < RENDER_BORDER )
|
||||
if( pair.x > width - RENDER_BORDER || pair.y > height - RENDER_BORDER || pair.x < RENDER_BORDER || pair.y < RENDER_BORDER )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -638,20 +638,20 @@ public class TileMonitor extends TileGeneric
|
||||
Terminal originTerminal = serverTerminal.getTerminal();
|
||||
if( originTerminal == null ) return;
|
||||
|
||||
double xCharWidth = (m_width - (RENDER_BORDER + RENDER_MARGIN) * 2.0) / originTerminal.getWidth();
|
||||
double yCharHeight = (m_height - (RENDER_BORDER + RENDER_MARGIN) * 2.0) / originTerminal.getHeight();
|
||||
double xCharWidth = (width - (RENDER_BORDER + RENDER_MARGIN) * 2.0) / originTerminal.getWidth();
|
||||
double yCharHeight = (height - (RENDER_BORDER + RENDER_MARGIN) * 2.0) / originTerminal.getHeight();
|
||||
|
||||
int xCharPos = (int) Math.min( originTerminal.getWidth(), Math.max( (pair.x - RENDER_BORDER - RENDER_MARGIN) / xCharWidth + 1.0, 1.0 ) );
|
||||
int yCharPos = (int) Math.min( originTerminal.getHeight(), Math.max( (pair.y - RENDER_BORDER - RENDER_MARGIN) / yCharHeight + 1.0, 1.0 ) );
|
||||
|
||||
for( int y = 0; y < m_height; y++ )
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
for( int x = 0; x < m_width; x++ )
|
||||
for( int x = 0; x < width; x++ )
|
||||
{
|
||||
TileMonitor monitor = getNeighbour( x, y );
|
||||
if( monitor == null ) continue;
|
||||
|
||||
for( IComputerAccess computer : monitor.m_computers )
|
||||
for( IComputerAccess computer : monitor.computers )
|
||||
{
|
||||
computer.queueEvent( "monitor_touch", computer.getAttachmentName(), xCharPos, yCharPos );
|
||||
}
|
||||
@ -662,12 +662,12 @@ public class TileMonitor extends TileGeneric
|
||||
|
||||
void addComputer( IComputerAccess computer )
|
||||
{
|
||||
m_computers.add( computer );
|
||||
computers.add( computer );
|
||||
}
|
||||
|
||||
void removeComputer( IComputerAccess computer )
|
||||
{
|
||||
m_computers.remove( computer );
|
||||
computers.remove( computer );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -675,7 +675,7 @@ public class TileMonitor extends TileGeneric
|
||||
public AxisAlignedBB getRenderBoundingBox()
|
||||
{
|
||||
TileMonitor start = getNeighbour( 0, 0 );
|
||||
TileMonitor end = getNeighbour( m_width - 1, m_height - 1 );
|
||||
TileMonitor end = getNeighbour( width - 1, height - 1 );
|
||||
if( start != null && end != null )
|
||||
{
|
||||
BlockPos startPos = start.getBlockPos();
|
||||
|
@ -27,8 +27,6 @@ import net.minecraft.world.World;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.AbstractBlock.Properties;
|
||||
|
||||
public class BlockPrinter extends BlockGeneric
|
||||
{
|
||||
private static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
@ -17,7 +17,10 @@ import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.inventory.ItemStackHelper;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||
import net.minecraft.item.*;
|
||||
import net.minecraft.item.DyeColor;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.*;
|
||||
@ -52,14 +55,14 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
|
||||
ITextComponent customName;
|
||||
|
||||
private final NonNullList<ItemStack> m_inventory = NonNullList.withSize( SLOTS, ItemStack.EMPTY );
|
||||
private final NonNullList<ItemStack> inventory = NonNullList.withSize( SLOTS, ItemStack.EMPTY );
|
||||
private final SidedCaps<IItemHandler> itemHandlerCaps =
|
||||
SidedCaps.ofNullable( facing -> facing == null ? new InvWrapper( this ) : new SidedInvWrapper( this, facing ) );
|
||||
private LazyOptional<IPeripheral> peripheralCap;
|
||||
|
||||
private final Terminal m_page = new Terminal( ItemPrintout.LINE_MAX_LENGTH, ItemPrintout.LINES_PER_PAGE );
|
||||
private String m_pageTitle = "";
|
||||
private boolean m_printing = false;
|
||||
private final Terminal page = new Terminal( ItemPrintout.LINE_MAX_LENGTH, ItemPrintout.LINES_PER_PAGE );
|
||||
private String pageTitle = "";
|
||||
private boolean printing = false;
|
||||
|
||||
public TilePrinter( TileEntityType<TilePrinter> type )
|
||||
{
|
||||
@ -98,15 +101,15 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
customName = nbt.contains( NBT_NAME ) ? ITextComponent.Serializer.fromJson( nbt.getString( NBT_NAME ) ) : null;
|
||||
|
||||
// Read page
|
||||
synchronized( m_page )
|
||||
synchronized( page )
|
||||
{
|
||||
m_printing = nbt.getBoolean( NBT_PRINTING );
|
||||
m_pageTitle = nbt.getString( NBT_PAGE_TITLE );
|
||||
m_page.readFromNBT( nbt );
|
||||
printing = nbt.getBoolean( NBT_PRINTING );
|
||||
pageTitle = nbt.getString( NBT_PAGE_TITLE );
|
||||
page.readFromNBT( nbt );
|
||||
}
|
||||
|
||||
// Read inventory
|
||||
ItemStackHelper.loadAllItems( nbt, m_inventory );
|
||||
ItemStackHelper.loadAllItems( nbt, inventory );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -116,35 +119,35 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
if( customName != null ) nbt.putString( NBT_NAME, ITextComponent.Serializer.toJson( customName ) );
|
||||
|
||||
// Write page
|
||||
synchronized( m_page )
|
||||
synchronized( page )
|
||||
{
|
||||
nbt.putBoolean( NBT_PRINTING, m_printing );
|
||||
nbt.putString( NBT_PAGE_TITLE, m_pageTitle );
|
||||
m_page.writeToNBT( nbt );
|
||||
nbt.putBoolean( NBT_PRINTING, printing );
|
||||
nbt.putString( NBT_PAGE_TITLE, pageTitle );
|
||||
page.writeToNBT( nbt );
|
||||
}
|
||||
|
||||
// Write inventory
|
||||
ItemStackHelper.saveAllItems( nbt, m_inventory );
|
||||
ItemStackHelper.saveAllItems( nbt, inventory );
|
||||
|
||||
return super.save( nbt );
|
||||
}
|
||||
|
||||
boolean isPrinting()
|
||||
{
|
||||
return m_printing;
|
||||
return printing;
|
||||
}
|
||||
|
||||
// IInventory implementation
|
||||
@Override
|
||||
public int getContainerSize()
|
||||
{
|
||||
return m_inventory.size();
|
||||
return inventory.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty()
|
||||
{
|
||||
for( ItemStack stack : m_inventory )
|
||||
for( ItemStack stack : inventory )
|
||||
{
|
||||
if( !stack.isEmpty() ) return false;
|
||||
}
|
||||
@ -155,15 +158,15 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
@Override
|
||||
public ItemStack getItem( int slot )
|
||||
{
|
||||
return m_inventory.get( slot );
|
||||
return inventory.get( slot );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack removeItemNoUpdate( int slot )
|
||||
{
|
||||
ItemStack result = m_inventory.get( slot );
|
||||
m_inventory.set( slot, ItemStack.EMPTY );
|
||||
ItemStack result = inventory.get( slot );
|
||||
inventory.set( slot, ItemStack.EMPTY );
|
||||
setChanged();
|
||||
updateBlockState();
|
||||
return result;
|
||||
@ -173,7 +176,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
@Override
|
||||
public ItemStack removeItem( int slot, int count )
|
||||
{
|
||||
ItemStack stack = m_inventory.get( slot );
|
||||
ItemStack stack = inventory.get( slot );
|
||||
if( stack.isEmpty() ) return ItemStack.EMPTY;
|
||||
|
||||
if( stack.getCount() <= count )
|
||||
@ -183,9 +186,9 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
}
|
||||
|
||||
ItemStack part = stack.split( count );
|
||||
if( m_inventory.get( slot ).isEmpty() )
|
||||
if( inventory.get( slot ).isEmpty() )
|
||||
{
|
||||
m_inventory.set( slot, ItemStack.EMPTY );
|
||||
inventory.set( slot, ItemStack.EMPTY );
|
||||
updateBlockState();
|
||||
}
|
||||
setChanged();
|
||||
@ -195,7 +198,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
@Override
|
||||
public void setItem( int slot, @Nonnull ItemStack stack )
|
||||
{
|
||||
m_inventory.set( slot, stack );
|
||||
inventory.set( slot, stack );
|
||||
setChanged();
|
||||
updateBlockState();
|
||||
}
|
||||
@ -203,7 +206,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
@Override
|
||||
public void clearContent()
|
||||
{
|
||||
for( int i = 0; i < m_inventory.size(); i++ ) m_inventory.set( i, ItemStack.EMPTY );
|
||||
for( int i = 0; i < inventory.size(); i++ ) inventory.set( i, ItemStack.EMPTY );
|
||||
setChanged();
|
||||
updateBlockState();
|
||||
}
|
||||
@ -251,33 +254,33 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
@Nullable
|
||||
Terminal getCurrentPage()
|
||||
{
|
||||
synchronized( m_page )
|
||||
synchronized( page )
|
||||
{
|
||||
return m_printing ? m_page : null;
|
||||
return printing ? page : null;
|
||||
}
|
||||
}
|
||||
|
||||
boolean startNewPage()
|
||||
{
|
||||
synchronized( m_page )
|
||||
synchronized( page )
|
||||
{
|
||||
if( !canInputPage() ) return false;
|
||||
if( m_printing && !outputPage() ) return false;
|
||||
if( printing && !outputPage() ) return false;
|
||||
return inputPage();
|
||||
}
|
||||
}
|
||||
|
||||
boolean endCurrentPage()
|
||||
{
|
||||
synchronized( m_page )
|
||||
synchronized( page )
|
||||
{
|
||||
return m_printing && outputPage();
|
||||
return printing && outputPage();
|
||||
}
|
||||
}
|
||||
|
||||
int getInkLevel()
|
||||
{
|
||||
ItemStack inkStack = m_inventory.get( 0 );
|
||||
ItemStack inkStack = inventory.get( 0 );
|
||||
return isInk( inkStack ) ? inkStack.getCount() : 0;
|
||||
}
|
||||
|
||||
@ -286,7 +289,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
int count = 0;
|
||||
for( int i = 1; i < 7; i++ )
|
||||
{
|
||||
ItemStack paperStack = m_inventory.get( i );
|
||||
ItemStack paperStack = inventory.get( i );
|
||||
if( isPaper( paperStack ) ) count += paperStack.getCount();
|
||||
}
|
||||
return count;
|
||||
@ -294,9 +297,9 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
|
||||
void setPageTitle( String title )
|
||||
{
|
||||
synchronized( m_page )
|
||||
synchronized( page )
|
||||
{
|
||||
if( m_printing ) m_pageTitle = title;
|
||||
if( printing ) pageTitle = title;
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,55 +317,55 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
|
||||
private boolean canInputPage()
|
||||
{
|
||||
ItemStack inkStack = m_inventory.get( 0 );
|
||||
ItemStack inkStack = inventory.get( 0 );
|
||||
return !inkStack.isEmpty() && isInk( inkStack ) && getPaperLevel() > 0;
|
||||
}
|
||||
|
||||
private boolean inputPage()
|
||||
{
|
||||
ItemStack inkStack = m_inventory.get( 0 );
|
||||
ItemStack inkStack = inventory.get( 0 );
|
||||
DyeColor dye = ColourUtils.getStackColour( inkStack );
|
||||
if( dye == null ) return false;
|
||||
|
||||
for( int i = 1; i < 7; i++ )
|
||||
{
|
||||
ItemStack paperStack = m_inventory.get( i );
|
||||
ItemStack paperStack = inventory.get( i );
|
||||
if( paperStack.isEmpty() || !isPaper( paperStack ) ) continue;
|
||||
|
||||
// Setup the new page
|
||||
m_page.setTextColour( dye.getId() );
|
||||
page.setTextColour( dye.getId() );
|
||||
|
||||
m_page.clear();
|
||||
page.clear();
|
||||
if( paperStack.getItem() instanceof ItemPrintout )
|
||||
{
|
||||
m_pageTitle = ItemPrintout.getTitle( paperStack );
|
||||
pageTitle = ItemPrintout.getTitle( paperStack );
|
||||
String[] text = ItemPrintout.getText( paperStack );
|
||||
String[] textColour = ItemPrintout.getColours( paperStack );
|
||||
for( int y = 0; y < m_page.getHeight(); y++ )
|
||||
for( int y = 0; y < page.getHeight(); y++ )
|
||||
{
|
||||
m_page.setLine( y, text[y], textColour[y], "" );
|
||||
page.setLine( y, text[y], textColour[y], "" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pageTitle = "";
|
||||
pageTitle = "";
|
||||
}
|
||||
m_page.setCursorPos( 0, 0 );
|
||||
page.setCursorPos( 0, 0 );
|
||||
|
||||
// Decrement ink
|
||||
inkStack.shrink( 1 );
|
||||
if( inkStack.isEmpty() ) m_inventory.set( 0, ItemStack.EMPTY );
|
||||
if( inkStack.isEmpty() ) inventory.set( 0, ItemStack.EMPTY );
|
||||
|
||||
// Decrement paper
|
||||
paperStack.shrink( 1 );
|
||||
if( paperStack.isEmpty() )
|
||||
{
|
||||
m_inventory.set( i, ItemStack.EMPTY );
|
||||
inventory.set( i, ItemStack.EMPTY );
|
||||
updateBlockState();
|
||||
}
|
||||
|
||||
setChanged();
|
||||
m_printing = true;
|
||||
printing = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -370,22 +373,22 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
|
||||
private boolean outputPage()
|
||||
{
|
||||
int height = m_page.getHeight();
|
||||
int height = page.getHeight();
|
||||
String[] lines = new String[height];
|
||||
String[] colours = new String[height];
|
||||
for( int i = 0; i < height; i++ )
|
||||
{
|
||||
lines[i] = m_page.getLine( i ).toString();
|
||||
colours[i] = m_page.getTextColourLine( i ).toString();
|
||||
lines[i] = page.getLine( i ).toString();
|
||||
colours[i] = page.getTextColourLine( i ).toString();
|
||||
}
|
||||
|
||||
ItemStack stack = ItemPrintout.createSingleFromTitleAndText( m_pageTitle, lines, colours );
|
||||
ItemStack stack = ItemPrintout.createSingleFromTitleAndText( pageTitle, lines, colours );
|
||||
for( int slot : BOTTOM_SLOTS )
|
||||
{
|
||||
if( m_inventory.get( slot ).isEmpty() )
|
||||
if( inventory.get( slot ).isEmpty() )
|
||||
{
|
||||
setItem( slot, stack );
|
||||
m_printing = false;
|
||||
printing = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -396,7 +399,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
{
|
||||
for( int i = 0; i < 13; i++ )
|
||||
{
|
||||
ItemStack stack = m_inventory.get( i );
|
||||
ItemStack stack = inventory.get( i );
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
// Remove the stack from the inventory
|
||||
@ -413,7 +416,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
boolean top = false, bottom = false;
|
||||
for( int i = 1; i < 7; i++ )
|
||||
{
|
||||
ItemStack stack = m_inventory.get( i );
|
||||
ItemStack stack = inventory.get( i );
|
||||
if( !stack.isEmpty() && isPaper( stack ) )
|
||||
{
|
||||
top = true;
|
||||
@ -422,7 +425,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
}
|
||||
for( int i = 7; i < 13; i++ )
|
||||
{
|
||||
ItemStack stack = m_inventory.get( i );
|
||||
ItemStack stack = inventory.get( i );
|
||||
if( !stack.isEmpty() && isPaper( stack ) )
|
||||
{
|
||||
bottom = true;
|
||||
|
@ -17,8 +17,6 @@ import net.minecraft.util.Direction;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.AbstractBlock.Properties;
|
||||
|
||||
public class BlockSpeaker extends BlockGeneric
|
||||
{
|
||||
private static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
@ -32,14 +32,14 @@ import static dan200.computercraft.api.lua.LuaValues.checkFinite;
|
||||
*/
|
||||
public abstract class SpeakerPeripheral implements IPeripheral
|
||||
{
|
||||
private long m_clock = 0;
|
||||
private long m_lastPlayTime = 0;
|
||||
private final AtomicInteger m_notesThisTick = new AtomicInteger();
|
||||
private long clock = 0;
|
||||
private long lastPlayTime = 0;
|
||||
private final AtomicInteger notesThisTick = new AtomicInteger();
|
||||
|
||||
public void update()
|
||||
{
|
||||
m_clock++;
|
||||
m_notesThisTick.set( 0 );
|
||||
clock++;
|
||||
notesThisTick.set( 0 );
|
||||
}
|
||||
|
||||
public abstract World getWorld();
|
||||
@ -48,7 +48,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
|
||||
|
||||
public boolean madeSound( long ticks )
|
||||
{
|
||||
return m_clock - m_lastPlayTime <= ticks;
|
||||
return clock - lastPlayTime <= ticks;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -129,14 +129,14 @@ public abstract class SpeakerPeripheral implements IPeripheral
|
||||
|
||||
// If the resource location for note block notes changes, this method call will need to be updated
|
||||
boolean success = playSound( context, instrument.getSoundEvent().getRegistryName(), volume, (float) Math.pow( 2.0, (pitch - 12.0) / 12.0 ), true );
|
||||
if( success ) m_notesThisTick.incrementAndGet();
|
||||
if( success ) notesThisTick.incrementAndGet();
|
||||
return success;
|
||||
}
|
||||
|
||||
private synchronized boolean playSound( ILuaContext context, ResourceLocation name, float volume, float pitch, boolean isNote ) throws LuaException
|
||||
{
|
||||
if( m_clock - m_lastPlayTime < TileSpeaker.MIN_TICKS_BETWEEN_SOUNDS &&
|
||||
(!isNote || m_clock - m_lastPlayTime != 0 || m_notesThisTick.get() >= ComputerCraft.maxNotesPerTick) )
|
||||
if( clock - lastPlayTime < TileSpeaker.MIN_TICKS_BETWEEN_SOUNDS &&
|
||||
(!isNote || clock - lastPlayTime != 0 || notesThisTick.get() >= ComputerCraft.maxNotesPerTick) )
|
||||
{
|
||||
// Rate limiting occurs when we've already played a sound within the last tick, or we've
|
||||
// played more notes than allowable within the current tick.
|
||||
@ -158,7 +158,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
|
||||
return null;
|
||||
} );
|
||||
|
||||
m_lastPlayTime = m_clock;
|
||||
lastPlayTime = clock;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +35,9 @@ import static dan200.computercraft.shared.pocket.items.ItemPocketComputer.NBT_LI
|
||||
|
||||
public class PocketServerComputer extends ServerComputer implements IPocketAccess
|
||||
{
|
||||
private IPocketUpgrade m_upgrade;
|
||||
private Entity m_entity;
|
||||
private ItemStack m_stack;
|
||||
private IPocketUpgrade upgrade;
|
||||
private Entity entity;
|
||||
private ItemStack stack;
|
||||
|
||||
public PocketServerComputer( World world, int computerID, String label, int instanceID, ComputerFamily family )
|
||||
{
|
||||
@ -48,18 +48,18 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
||||
@Override
|
||||
public Entity getEntity()
|
||||
{
|
||||
Entity entity = m_entity;
|
||||
if( entity == null || m_stack == null || !entity.isAlive() ) return null;
|
||||
Entity entity = this.entity;
|
||||
if( entity == null || stack == null || !entity.isAlive() ) return null;
|
||||
|
||||
if( entity instanceof PlayerEntity )
|
||||
{
|
||||
PlayerInventory inventory = ((PlayerEntity) entity).inventory;
|
||||
return inventory.items.contains( m_stack ) || inventory.offhand.contains( m_stack ) ? entity : null;
|
||||
return inventory.items.contains( stack ) || inventory.offhand.contains( stack ) ? entity : null;
|
||||
}
|
||||
else if( entity instanceof LivingEntity )
|
||||
{
|
||||
LivingEntity living = (LivingEntity) entity;
|
||||
return living.getMainHandItem() == m_stack || living.getOffhandItem() == m_stack ? entity : null;
|
||||
return living.getMainHandItem() == stack || living.getOffhandItem() == stack ? entity : null;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -70,13 +70,13 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
||||
@Override
|
||||
public int getColour()
|
||||
{
|
||||
return IColouredItem.getColourBasic( m_stack );
|
||||
return IColouredItem.getColourBasic( stack );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColour( int colour )
|
||||
{
|
||||
IColouredItem.setColourBasic( m_stack, colour );
|
||||
IColouredItem.setColourBasic( stack, colour );
|
||||
updateUpgradeNBTData();
|
||||
}
|
||||
|
||||
@ -110,19 +110,19 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
||||
@Override
|
||||
public CompoundNBT getUpgradeNBTData()
|
||||
{
|
||||
return ItemPocketComputer.getUpgradeInfo( m_stack );
|
||||
return ItemPocketComputer.getUpgradeInfo( stack );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUpgradeNBTData()
|
||||
{
|
||||
if( m_entity instanceof PlayerEntity ) ((PlayerEntity) m_entity).inventory.setChanged();
|
||||
if( entity instanceof PlayerEntity ) ((PlayerEntity) entity).inventory.setChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidatePeripheral()
|
||||
{
|
||||
IPeripheral peripheral = m_upgrade == null ? null : m_upgrade.createPeripheral( this );
|
||||
IPeripheral peripheral = upgrade == null ? null : upgrade.createPeripheral( this );
|
||||
setPeripheral( ComputerSide.BACK, peripheral );
|
||||
}
|
||||
|
||||
@ -130,12 +130,12 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
||||
@Override
|
||||
public Map<ResourceLocation, IPeripheral> getUpgrades()
|
||||
{
|
||||
return m_upgrade == null ? Collections.emptyMap() : Collections.singletonMap( m_upgrade.getUpgradeID(), getPeripheral( ComputerSide.BACK ) );
|
||||
return upgrade == null ? Collections.emptyMap() : Collections.singletonMap( upgrade.getUpgradeID(), getPeripheral( ComputerSide.BACK ) );
|
||||
}
|
||||
|
||||
public IPocketUpgrade getUpgrade()
|
||||
{
|
||||
return m_upgrade;
|
||||
return upgrade;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -147,13 +147,13 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
||||
*/
|
||||
public void setUpgrade( IPocketUpgrade upgrade )
|
||||
{
|
||||
if( m_upgrade == upgrade ) return;
|
||||
if( this.upgrade == upgrade ) return;
|
||||
|
||||
synchronized( this )
|
||||
{
|
||||
ItemPocketComputer.setUpgrade( m_stack, upgrade );
|
||||
ItemPocketComputer.setUpgrade( stack, upgrade );
|
||||
updateUpgradeNBTData();
|
||||
m_upgrade = upgrade;
|
||||
this.upgrade = upgrade;
|
||||
invalidatePeripheral();
|
||||
}
|
||||
}
|
||||
@ -167,14 +167,14 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
||||
}
|
||||
|
||||
// If a new entity has picked it up then rebroadcast the terminal to them
|
||||
if( entity != m_entity && entity instanceof ServerPlayerEntity ) markTerminalChanged();
|
||||
if( entity != this.entity && entity instanceof ServerPlayerEntity ) markTerminalChanged();
|
||||
|
||||
m_entity = entity;
|
||||
m_stack = stack;
|
||||
this.entity = entity;
|
||||
this.stack = stack;
|
||||
|
||||
if( m_upgrade != upgrade )
|
||||
if( this.upgrade != upgrade )
|
||||
{
|
||||
m_upgrade = upgrade;
|
||||
this.upgrade = upgrade;
|
||||
invalidatePeripheral();
|
||||
}
|
||||
}
|
||||
@ -184,10 +184,10 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
||||
{
|
||||
super.broadcastState( force );
|
||||
|
||||
if( (hasTerminalChanged() || force) && m_entity instanceof ServerPlayerEntity )
|
||||
if( (hasTerminalChanged() || force) && entity instanceof ServerPlayerEntity )
|
||||
{
|
||||
// Broadcast the state to the current entity if they're not already interacting with it.
|
||||
ServerPlayerEntity player = (ServerPlayerEntity) m_entity;
|
||||
ServerPlayerEntity player = (ServerPlayerEntity) entity;
|
||||
if( player.connection != null && !isInteracting( player ) )
|
||||
{
|
||||
NetworkHandler.sendToPlayer( player, createTerminalPacket() );
|
||||
|
@ -40,15 +40,11 @@ import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.item.Item.Properties;
|
||||
|
||||
public class ItemPocketComputer extends Item implements IComputerItem, IMedia, IColouredItem
|
||||
{
|
||||
private static final String NBT_UPGRADE = "Upgrade";
|
||||
@ -363,14 +359,12 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
|
||||
stack.getOrCreateTag().putInt( NBT_SESSION, sessionID );
|
||||
}
|
||||
|
||||
@OnlyIn( Dist.CLIENT )
|
||||
public static ComputerState getState( @Nonnull ItemStack stack )
|
||||
{
|
||||
ClientComputer computer = getClientComputer( stack );
|
||||
return computer == null ? ComputerState.OFF : computer.getState();
|
||||
}
|
||||
|
||||
@OnlyIn( Dist.CLIENT )
|
||||
public static int getLightState( @Nonnull ItemStack stack )
|
||||
{
|
||||
ClientComputer computer = getClientComputer( stack );
|
||||
|
@ -47,8 +47,6 @@ import javax.annotation.Nullable;
|
||||
import static dan200.computercraft.shared.util.WaterloggableHelpers.*;
|
||||
import static net.minecraft.state.properties.BlockStateProperties.WATERLOGGED;
|
||||
|
||||
import net.minecraft.block.AbstractBlock.Properties;
|
||||
|
||||
public class BlockTurtle extends BlockComputerBase<TileTurtle> implements IWaterLoggable
|
||||
{
|
||||
public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
@ -64,13 +64,13 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
MOVED
|
||||
}
|
||||
|
||||
private final NonNullList<ItemStack> m_inventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||
private final NonNullList<ItemStack> m_previousInventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||
private final IItemHandlerModifiable m_itemHandler = new InvWrapper( this );
|
||||
private final NonNullList<ItemStack> inventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||
private final NonNullList<ItemStack> previousInventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||
private final IItemHandlerModifiable itemHandler = new InvWrapper( this );
|
||||
private LazyOptional<IItemHandlerModifiable> itemHandlerCap;
|
||||
private boolean m_inventoryChanged = false;
|
||||
private TurtleBrain m_brain = new TurtleBrain( this );
|
||||
private MoveState m_moveState = MoveState.NOT_MOVED;
|
||||
private boolean inventoryChanged = false;
|
||||
private TurtleBrain brain = new TurtleBrain( this );
|
||||
private MoveState moveState = MoveState.NOT_MOVED;
|
||||
private LazyOptional<IPeripheral> peripheral;
|
||||
|
||||
public TileTurtle( TileEntityType<? extends TileGeneric> type, ComputerFamily family )
|
||||
@ -80,7 +80,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
|
||||
private boolean hasMoved()
|
||||
{
|
||||
return m_moveState == MoveState.MOVED;
|
||||
return moveState == MoveState.MOVED;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -92,13 +92,13 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
);
|
||||
computer.setPosition( getBlockPos() );
|
||||
computer.addAPI( new TurtleAPI( computer.getAPIEnvironment(), getAccess() ) );
|
||||
m_brain.setupComputer( computer );
|
||||
brain.setupComputer( computer );
|
||||
return computer;
|
||||
}
|
||||
|
||||
public ComputerProxy createProxy()
|
||||
{
|
||||
return m_brain.getProxy();
|
||||
return brain.getProxy();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -164,9 +164,9 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
if( !getLevel().isClientSide )
|
||||
{
|
||||
DyeColor dye = ((DyeItem) currentItem.getItem()).getDyeColor();
|
||||
if( m_brain.getDyeColour() != dye )
|
||||
if( brain.getDyeColour() != dye )
|
||||
{
|
||||
m_brain.setDyeColour( dye );
|
||||
brain.setDyeColour( dye );
|
||||
if( !player.isCreative() )
|
||||
{
|
||||
currentItem.shrink( 1 );
|
||||
@ -175,14 +175,14 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
}
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
else if( currentItem.getItem() == Items.WATER_BUCKET && m_brain.getColour() != -1 )
|
||||
else if( currentItem.getItem() == Items.WATER_BUCKET && brain.getColour() != -1 )
|
||||
{
|
||||
// Water to remove turtle colour
|
||||
if( !getLevel().isClientSide )
|
||||
{
|
||||
if( m_brain.getColour() != -1 )
|
||||
if( brain.getColour() != -1 )
|
||||
{
|
||||
m_brain.setColour( -1 );
|
||||
brain.setColour( -1 );
|
||||
if( !player.isCreative() )
|
||||
{
|
||||
player.setItemInHand( hand, new ItemStack( Items.BUCKET ) );
|
||||
@ -214,16 +214,16 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
public void tick()
|
||||
{
|
||||
super.tick();
|
||||
m_brain.update();
|
||||
if( !getLevel().isClientSide && m_inventoryChanged )
|
||||
brain.update();
|
||||
if( !getLevel().isClientSide && inventoryChanged )
|
||||
{
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer != null ) computer.queueEvent( "turtle_inventory" );
|
||||
|
||||
m_inventoryChanged = false;
|
||||
inventoryChanged = false;
|
||||
for( int n = 0; n < getContainerSize(); n++ )
|
||||
{
|
||||
m_previousInventory.set( n, getItem( n ).copy() );
|
||||
previousInventory.set( n, getItem( n ).copy() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,24 +236,24 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
@Override
|
||||
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
||||
{
|
||||
if( m_moveState == MoveState.NOT_MOVED ) super.onNeighbourChange( neighbour );
|
||||
if( moveState == MoveState.NOT_MOVED ) super.onNeighbourChange( neighbour );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
|
||||
{
|
||||
if( m_moveState == MoveState.NOT_MOVED ) super.onNeighbourTileEntityChange( neighbour );
|
||||
if( moveState == MoveState.NOT_MOVED ) super.onNeighbourTileEntityChange( neighbour );
|
||||
}
|
||||
|
||||
public void notifyMoveStart()
|
||||
{
|
||||
if( m_moveState == MoveState.NOT_MOVED ) m_moveState = MoveState.IN_PROGRESS;
|
||||
if( moveState == MoveState.NOT_MOVED ) moveState = MoveState.IN_PROGRESS;
|
||||
}
|
||||
|
||||
public void notifyMoveEnd()
|
||||
{
|
||||
// MoveState.MOVED is final
|
||||
if( m_moveState == MoveState.IN_PROGRESS ) m_moveState = MoveState.NOT_MOVED;
|
||||
if( moveState == MoveState.IN_PROGRESS ) moveState = MoveState.NOT_MOVED;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -263,21 +263,21 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
|
||||
// Read inventory
|
||||
ListNBT nbttaglist = nbt.getList( "Items", Constants.NBT.TAG_COMPOUND );
|
||||
m_inventory.clear();
|
||||
m_previousInventory.clear();
|
||||
inventory.clear();
|
||||
previousInventory.clear();
|
||||
for( int i = 0; i < nbttaglist.size(); i++ )
|
||||
{
|
||||
CompoundNBT tag = nbttaglist.getCompound( i );
|
||||
int slot = tag.getByte( "Slot" ) & 0xff;
|
||||
if( slot < getContainerSize() )
|
||||
{
|
||||
m_inventory.set( slot, ItemStack.of( tag ) );
|
||||
m_previousInventory.set( slot, m_inventory.get( slot ).copy() );
|
||||
inventory.set( slot, ItemStack.of( tag ) );
|
||||
previousInventory.set( slot, inventory.get( slot ).copy() );
|
||||
}
|
||||
}
|
||||
|
||||
// Read state
|
||||
m_brain.readFromNBT( nbt );
|
||||
brain.readFromNBT( nbt );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -288,18 +288,18 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
ListNBT nbttaglist = new ListNBT();
|
||||
for( int i = 0; i < INVENTORY_SIZE; i++ )
|
||||
{
|
||||
if( !m_inventory.get( i ).isEmpty() )
|
||||
if( !inventory.get( i ).isEmpty() )
|
||||
{
|
||||
CompoundNBT tag = new CompoundNBT();
|
||||
tag.putByte( "Slot", (byte) i );
|
||||
m_inventory.get( i ).save( tag );
|
||||
inventory.get( i ).save( tag );
|
||||
nbttaglist.add( tag );
|
||||
}
|
||||
}
|
||||
nbt.put( "Items", nbttaglist );
|
||||
|
||||
// Write brain
|
||||
nbt = m_brain.writeToNBT( nbt );
|
||||
nbt = brain.writeToNBT( nbt );
|
||||
|
||||
return super.save( nbt );
|
||||
}
|
||||
@ -332,48 +332,48 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
@Override
|
||||
public ITurtleUpgrade getUpgrade( TurtleSide side )
|
||||
{
|
||||
return m_brain.getUpgrade( side );
|
||||
return brain.getUpgrade( side );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColour()
|
||||
{
|
||||
return m_brain.getColour();
|
||||
return brain.getColour();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getOverlay()
|
||||
{
|
||||
return m_brain.getOverlay();
|
||||
return brain.getOverlay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITurtleAccess getAccess()
|
||||
{
|
||||
return m_brain;
|
||||
return brain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3d getRenderOffset( float f )
|
||||
{
|
||||
return m_brain.getRenderOffset( f );
|
||||
return brain.getRenderOffset( f );
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRenderYaw( float f )
|
||||
{
|
||||
return m_brain.getVisualYaw( f );
|
||||
return brain.getVisualYaw( f );
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getToolRenderAngle( TurtleSide side, float f )
|
||||
{
|
||||
return m_brain.getToolRenderAngle( side, f );
|
||||
return brain.getToolRenderAngle( side, f );
|
||||
}
|
||||
|
||||
void setOwningPlayer( GameProfile player )
|
||||
{
|
||||
m_brain.setOwningPlayer( player );
|
||||
brain.setOwningPlayer( player );
|
||||
setChanged();
|
||||
}
|
||||
|
||||
@ -388,7 +388,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
@Override
|
||||
public boolean isEmpty()
|
||||
{
|
||||
for( ItemStack stack : m_inventory )
|
||||
for( ItemStack stack : inventory )
|
||||
{
|
||||
if( !stack.isEmpty() ) return false;
|
||||
}
|
||||
@ -399,7 +399,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
@Override
|
||||
public ItemStack getItem( int slot )
|
||||
{
|
||||
return slot >= 0 && slot < INVENTORY_SIZE ? m_inventory.get( slot ) : ItemStack.EMPTY;
|
||||
return slot >= 0 && slot < INVENTORY_SIZE ? inventory.get( slot ) : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -434,9 +434,9 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
@Override
|
||||
public void setItem( int i, @Nonnull ItemStack stack )
|
||||
{
|
||||
if( i >= 0 && i < INVENTORY_SIZE && !InventoryUtil.areItemsEqual( stack, m_inventory.get( i ) ) )
|
||||
if( i >= 0 && i < INVENTORY_SIZE && !InventoryUtil.areItemsEqual( stack, inventory.get( i ) ) )
|
||||
{
|
||||
m_inventory.set( i, stack );
|
||||
inventory.set( i, stack );
|
||||
onInventoryDefinitelyChanged();
|
||||
}
|
||||
}
|
||||
@ -447,9 +447,9 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
boolean changed = false;
|
||||
for( int i = 0; i < INVENTORY_SIZE; i++ )
|
||||
{
|
||||
if( !m_inventory.get( i ).isEmpty() )
|
||||
if( !inventory.get( i ).isEmpty() )
|
||||
{
|
||||
m_inventory.set( i, ItemStack.EMPTY );
|
||||
inventory.set( i, ItemStack.EMPTY );
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
@ -461,13 +461,13 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
public void setChanged()
|
||||
{
|
||||
super.setChanged();
|
||||
if( !m_inventoryChanged )
|
||||
if( !inventoryChanged )
|
||||
{
|
||||
for( int n = 0; n < getContainerSize(); n++ )
|
||||
{
|
||||
if( !ItemStack.matches( getItem( n ), m_previousInventory.get( n ) ) )
|
||||
if( !ItemStack.matches( getItem( n ), previousInventory.get( n ) ) )
|
||||
{
|
||||
m_inventoryChanged = true;
|
||||
inventoryChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -483,7 +483,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
private void onInventoryDefinitelyChanged()
|
||||
{
|
||||
super.setChanged();
|
||||
m_inventoryChanged = true;
|
||||
inventoryChanged = true;
|
||||
}
|
||||
|
||||
public void onTileEntityChange()
|
||||
@ -497,14 +497,14 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
protected void writeDescription( @Nonnull CompoundNBT nbt )
|
||||
{
|
||||
super.writeDescription( nbt );
|
||||
m_brain.writeDescription( nbt );
|
||||
brain.writeDescription( nbt );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readDescription( @Nonnull CompoundNBT nbt )
|
||||
{
|
||||
super.readDescription( nbt );
|
||||
m_brain.readDescription( nbt );
|
||||
brain.readDescription( nbt );
|
||||
}
|
||||
|
||||
// Privates
|
||||
@ -529,20 +529,20 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
public void transferStateFrom( TileTurtle copy )
|
||||
{
|
||||
super.transferStateFrom( copy );
|
||||
Collections.copy( m_inventory, copy.m_inventory );
|
||||
Collections.copy( m_previousInventory, copy.m_previousInventory );
|
||||
m_inventoryChanged = copy.m_inventoryChanged;
|
||||
m_brain = copy.m_brain;
|
||||
m_brain.setOwner( this );
|
||||
Collections.copy( inventory, copy.inventory );
|
||||
Collections.copy( previousInventory, copy.previousInventory );
|
||||
inventoryChanged = copy.inventoryChanged;
|
||||
brain = copy.brain;
|
||||
brain.setOwner( this );
|
||||
|
||||
// Mark the other turtle as having moved, and so its peripheral is dead.
|
||||
copy.m_moveState = MoveState.MOVED;
|
||||
copy.moveState = MoveState.MOVED;
|
||||
copy.peripheral = CapabilityUtil.invalidate( copy.peripheral );
|
||||
}
|
||||
|
||||
public IItemHandlerModifiable getItemHandler()
|
||||
{
|
||||
return m_itemHandler;
|
||||
return itemHandler;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -572,6 +572,6 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
@Override
|
||||
public Container createMenu( int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player )
|
||||
{
|
||||
return new ContainerTurtle( id, inventory, m_brain );
|
||||
return new ContainerTurtle( id, inventory, brain );
|
||||
}
|
||||
}
|
||||
|
@ -65,55 +65,55 @@ public class TurtleBrain implements ITurtleAccess
|
||||
|
||||
private static final int ANIM_DURATION = 8;
|
||||
|
||||
private TileTurtle m_owner;
|
||||
private ComputerProxy m_proxy;
|
||||
private GameProfile m_owningPlayer;
|
||||
private TileTurtle owner;
|
||||
private ComputerProxy proxy;
|
||||
private GameProfile owningPlayer;
|
||||
|
||||
private final IInventory m_inventory = (InventoryDelegate) () -> m_owner;
|
||||
private final IItemHandlerModifiable m_inventoryWrapper = new InvWrapper( m_inventory );
|
||||
private final IInventory inventory = (InventoryDelegate) () -> owner;
|
||||
private final IItemHandlerModifiable inventoryWrapper = new InvWrapper( inventory );
|
||||
|
||||
private final Queue<TurtleCommandQueueEntry> m_commandQueue = new ArrayDeque<>();
|
||||
private int m_commandsIssued = 0;
|
||||
private final Queue<TurtleCommandQueueEntry> commandQueue = new ArrayDeque<>();
|
||||
private int commandsIssued = 0;
|
||||
|
||||
private final Map<TurtleSide, ITurtleUpgrade> m_upgrades = new EnumMap<>( TurtleSide.class );
|
||||
private final Map<TurtleSide, ITurtleUpgrade> upgrades = new EnumMap<>( TurtleSide.class );
|
||||
private final Map<TurtleSide, IPeripheral> peripherals = new EnumMap<>( TurtleSide.class );
|
||||
private final Map<TurtleSide, CompoundNBT> m_upgradeNBTData = new EnumMap<>( TurtleSide.class );
|
||||
private final Map<TurtleSide, CompoundNBT> upgradeNBTData = new EnumMap<>( TurtleSide.class );
|
||||
|
||||
private int m_selectedSlot = 0;
|
||||
private int m_fuelLevel = 0;
|
||||
private int m_colourHex = -1;
|
||||
private ResourceLocation m_overlay = null;
|
||||
private int selectedSlot = 0;
|
||||
private int fuelLevel = 0;
|
||||
private int colourHex = -1;
|
||||
private ResourceLocation overlay = null;
|
||||
|
||||
private TurtleAnimation m_animation = TurtleAnimation.NONE;
|
||||
private int m_animationProgress = 0;
|
||||
private int m_lastAnimationProgress = 0;
|
||||
private TurtleAnimation animation = TurtleAnimation.NONE;
|
||||
private int animationProgress = 0;
|
||||
private int lastAnimationProgress = 0;
|
||||
|
||||
TurtlePlayer m_cachedPlayer;
|
||||
TurtlePlayer cachedPlayer;
|
||||
|
||||
public TurtleBrain( TileTurtle turtle )
|
||||
{
|
||||
m_owner = turtle;
|
||||
owner = turtle;
|
||||
}
|
||||
|
||||
public void setOwner( TileTurtle owner )
|
||||
{
|
||||
m_owner = owner;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public TileTurtle getOwner()
|
||||
{
|
||||
return m_owner;
|
||||
return owner;
|
||||
}
|
||||
|
||||
public ComputerProxy getProxy()
|
||||
{
|
||||
if( m_proxy == null ) m_proxy = new ComputerProxy( () -> m_owner );
|
||||
return m_proxy;
|
||||
if( proxy == null ) proxy = new ComputerProxy( () -> owner );
|
||||
return proxy;
|
||||
}
|
||||
|
||||
public ComputerFamily getFamily()
|
||||
{
|
||||
return m_owner.getFamily();
|
||||
return owner.getFamily();
|
||||
}
|
||||
|
||||
public void setupComputer( ServerComputer computer )
|
||||
@ -131,16 +131,16 @@ public class TurtleBrain implements ITurtleAccess
|
||||
|
||||
// The block may have been broken while the command was executing (for instance, if a block explodes
|
||||
// when being mined). If so, abort.
|
||||
if( m_owner.isRemoved() ) return;
|
||||
if( owner.isRemoved() ) return;
|
||||
}
|
||||
|
||||
// Advance animation
|
||||
updateAnimation();
|
||||
|
||||
// Advance upgrades
|
||||
if( !m_upgrades.isEmpty() )
|
||||
if( !upgrades.isEmpty() )
|
||||
{
|
||||
for( Map.Entry<TurtleSide, ITurtleUpgrade> entry : m_upgrades.entrySet() )
|
||||
for( Map.Entry<TurtleSide, ITurtleUpgrade> entry : upgrades.entrySet() )
|
||||
{
|
||||
entry.getValue().update( this, entry.getKey() );
|
||||
}
|
||||
@ -155,31 +155,31 @@ public class TurtleBrain implements ITurtleAccess
|
||||
private void readCommon( CompoundNBT nbt )
|
||||
{
|
||||
// Read fields
|
||||
m_colourHex = nbt.contains( NBT_COLOUR ) ? nbt.getInt( NBT_COLOUR ) : -1;
|
||||
m_fuelLevel = nbt.contains( NBT_FUEL ) ? nbt.getInt( NBT_FUEL ) : 0;
|
||||
m_overlay = nbt.contains( NBT_OVERLAY ) ? new ResourceLocation( nbt.getString( NBT_OVERLAY ) ) : null;
|
||||
colourHex = nbt.contains( NBT_COLOUR ) ? nbt.getInt( NBT_COLOUR ) : -1;
|
||||
fuelLevel = nbt.contains( NBT_FUEL ) ? nbt.getInt( NBT_FUEL ) : 0;
|
||||
overlay = nbt.contains( NBT_OVERLAY ) ? new ResourceLocation( nbt.getString( NBT_OVERLAY ) ) : null;
|
||||
|
||||
// Read upgrades
|
||||
setUpgrade( TurtleSide.LEFT, nbt.contains( NBT_LEFT_UPGRADE ) ? TurtleUpgrades.get( nbt.getString( NBT_LEFT_UPGRADE ) ) : null );
|
||||
setUpgrade( TurtleSide.RIGHT, nbt.contains( NBT_RIGHT_UPGRADE ) ? TurtleUpgrades.get( nbt.getString( NBT_RIGHT_UPGRADE ) ) : null );
|
||||
|
||||
// NBT
|
||||
m_upgradeNBTData.clear();
|
||||
upgradeNBTData.clear();
|
||||
if( nbt.contains( NBT_LEFT_UPGRADE_DATA ) )
|
||||
{
|
||||
m_upgradeNBTData.put( TurtleSide.LEFT, nbt.getCompound( NBT_LEFT_UPGRADE_DATA ).copy() );
|
||||
upgradeNBTData.put( TurtleSide.LEFT, nbt.getCompound( NBT_LEFT_UPGRADE_DATA ).copy() );
|
||||
}
|
||||
if( nbt.contains( NBT_RIGHT_UPGRADE_DATA ) )
|
||||
{
|
||||
m_upgradeNBTData.put( TurtleSide.RIGHT, nbt.getCompound( NBT_RIGHT_UPGRADE_DATA ).copy() );
|
||||
upgradeNBTData.put( TurtleSide.RIGHT, nbt.getCompound( NBT_RIGHT_UPGRADE_DATA ).copy() );
|
||||
}
|
||||
}
|
||||
|
||||
private void writeCommon( CompoundNBT nbt )
|
||||
{
|
||||
nbt.putInt( NBT_FUEL, m_fuelLevel );
|
||||
if( m_colourHex != -1 ) nbt.putInt( NBT_COLOUR, m_colourHex );
|
||||
if( m_overlay != null ) nbt.putString( NBT_OVERLAY, m_overlay.toString() );
|
||||
nbt.putInt( NBT_FUEL, fuelLevel );
|
||||
if( colourHex != -1 ) nbt.putInt( NBT_COLOUR, colourHex );
|
||||
if( overlay != null ) nbt.putString( NBT_OVERLAY, overlay.toString() );
|
||||
|
||||
// Write upgrades
|
||||
String leftUpgradeId = getUpgradeId( getUpgrade( TurtleSide.LEFT ) );
|
||||
@ -188,11 +188,11 @@ public class TurtleBrain implements ITurtleAccess
|
||||
if( rightUpgradeId != null ) nbt.putString( NBT_RIGHT_UPGRADE, rightUpgradeId );
|
||||
|
||||
// Write upgrade NBT
|
||||
if( m_upgradeNBTData.containsKey( TurtleSide.LEFT ) )
|
||||
if( upgradeNBTData.containsKey( TurtleSide.LEFT ) )
|
||||
{
|
||||
nbt.put( NBT_LEFT_UPGRADE_DATA, getUpgradeNBTData( TurtleSide.LEFT ).copy() );
|
||||
}
|
||||
if( m_upgradeNBTData.containsKey( TurtleSide.RIGHT ) )
|
||||
if( upgradeNBTData.containsKey( TurtleSide.RIGHT ) )
|
||||
{
|
||||
nbt.put( NBT_RIGHT_UPGRADE_DATA, getUpgradeNBTData( TurtleSide.RIGHT ).copy() );
|
||||
}
|
||||
@ -203,20 +203,20 @@ public class TurtleBrain implements ITurtleAccess
|
||||
readCommon( nbt );
|
||||
|
||||
// Read state
|
||||
m_selectedSlot = nbt.getInt( NBT_SLOT );
|
||||
selectedSlot = nbt.getInt( NBT_SLOT );
|
||||
|
||||
// Read owner
|
||||
if( nbt.contains( "Owner", Constants.NBT.TAG_COMPOUND ) )
|
||||
{
|
||||
CompoundNBT owner = nbt.getCompound( "Owner" );
|
||||
m_owningPlayer = new GameProfile(
|
||||
owningPlayer = new GameProfile(
|
||||
new UUID( owner.getLong( "UpperId" ), owner.getLong( "LowerId" ) ),
|
||||
owner.getString( "Name" )
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_owningPlayer = null;
|
||||
owningPlayer = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,17 +225,17 @@ public class TurtleBrain implements ITurtleAccess
|
||||
writeCommon( nbt );
|
||||
|
||||
// Write state
|
||||
nbt.putInt( NBT_SLOT, m_selectedSlot );
|
||||
nbt.putInt( NBT_SLOT, selectedSlot );
|
||||
|
||||
// Write owner
|
||||
if( m_owningPlayer != null )
|
||||
if( owningPlayer != null )
|
||||
{
|
||||
CompoundNBT owner = new CompoundNBT();
|
||||
nbt.put( "Owner", owner );
|
||||
|
||||
owner.putLong( "UpperId", m_owningPlayer.getId().getMostSignificantBits() );
|
||||
owner.putLong( "LowerId", m_owningPlayer.getId().getLeastSignificantBits() );
|
||||
owner.putString( "Name", m_owningPlayer.getName() );
|
||||
owner.putLong( "UpperId", owningPlayer.getId().getMostSignificantBits() );
|
||||
owner.putLong( "LowerId", owningPlayer.getId().getLeastSignificantBits() );
|
||||
owner.putString( "Name", owningPlayer.getName() );
|
||||
}
|
||||
|
||||
return nbt;
|
||||
@ -252,35 +252,35 @@ public class TurtleBrain implements ITurtleAccess
|
||||
|
||||
// Animation
|
||||
TurtleAnimation anim = TurtleAnimation.values()[nbt.getInt( "Animation" )];
|
||||
if( anim != m_animation &&
|
||||
if( anim != animation &&
|
||||
anim != TurtleAnimation.WAIT &&
|
||||
anim != TurtleAnimation.SHORT_WAIT &&
|
||||
anim != TurtleAnimation.NONE )
|
||||
{
|
||||
m_animation = anim;
|
||||
m_animationProgress = 0;
|
||||
m_lastAnimationProgress = 0;
|
||||
animation = anim;
|
||||
animationProgress = 0;
|
||||
lastAnimationProgress = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void writeDescription( CompoundNBT nbt )
|
||||
{
|
||||
writeCommon( nbt );
|
||||
nbt.putInt( "Animation", m_animation.ordinal() );
|
||||
nbt.putInt( "Animation", animation.ordinal() );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public World getWorld()
|
||||
{
|
||||
return m_owner.getLevel();
|
||||
return owner.getLevel();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public BlockPos getPosition()
|
||||
{
|
||||
return m_owner.getBlockPos();
|
||||
return owner.getBlockPos();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -293,9 +293,9 @@ public class TurtleBrain implements ITurtleAccess
|
||||
|
||||
// Cache info about the old turtle (so we don't access this after we delete ourselves)
|
||||
World oldWorld = getWorld();
|
||||
TileTurtle oldOwner = m_owner;
|
||||
BlockPos oldPos = m_owner.getBlockPos();
|
||||
BlockState oldBlock = m_owner.getBlockState();
|
||||
TileTurtle oldOwner = owner;
|
||||
BlockPos oldPos = owner.getBlockPos();
|
||||
BlockState oldBlock = owner.getBlockState();
|
||||
|
||||
if( oldWorld == world && oldPos.equals( pos ) )
|
||||
{
|
||||
@ -365,7 +365,7 @@ public class TurtleBrain implements ITurtleAccess
|
||||
public Vector3d getVisualPosition( float f )
|
||||
{
|
||||
Vector3d offset = getRenderOffset( f );
|
||||
BlockPos pos = m_owner.getBlockPos();
|
||||
BlockPos pos = owner.getBlockPos();
|
||||
return new Vector3d(
|
||||
pos.getX() + 0.5 + offset.x,
|
||||
pos.getY() + 0.5 + offset.y,
|
||||
@ -377,7 +377,7 @@ public class TurtleBrain implements ITurtleAccess
|
||||
public float getVisualYaw( float f )
|
||||
{
|
||||
float yaw = getDirection().toYRot();
|
||||
switch( m_animation )
|
||||
switch( animation )
|
||||
{
|
||||
case TURN_LEFT:
|
||||
{
|
||||
@ -405,19 +405,19 @@ public class TurtleBrain implements ITurtleAccess
|
||||
@Override
|
||||
public Direction getDirection()
|
||||
{
|
||||
return m_owner.getDirection();
|
||||
return owner.getDirection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirection( @Nonnull Direction dir )
|
||||
{
|
||||
m_owner.setDirection( dir );
|
||||
owner.setDirection( dir );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelectedSlot()
|
||||
{
|
||||
return m_selectedSlot;
|
||||
return selectedSlot;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -425,10 +425,10 @@ public class TurtleBrain implements ITurtleAccess
|
||||
{
|
||||
if( getWorld().isClientSide ) throw new UnsupportedOperationException( "Cannot set the slot on the client" );
|
||||
|
||||
if( slot >= 0 && slot < m_owner.getContainerSize() )
|
||||
if( slot >= 0 && slot < owner.getContainerSize() )
|
||||
{
|
||||
m_selectedSlot = slot;
|
||||
m_owner.onTileEntityChange();
|
||||
selectedSlot = slot;
|
||||
owner.onTileEntityChange();
|
||||
}
|
||||
}
|
||||
|
||||
@ -436,14 +436,14 @@ public class TurtleBrain implements ITurtleAccess
|
||||
@Override
|
||||
public IInventory getInventory()
|
||||
{
|
||||
return m_inventory;
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IItemHandlerModifiable getItemHandler()
|
||||
{
|
||||
return m_inventoryWrapper;
|
||||
return inventoryWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -455,20 +455,20 @@ public class TurtleBrain implements ITurtleAccess
|
||||
@Override
|
||||
public int getFuelLevel()
|
||||
{
|
||||
return Math.min( m_fuelLevel, getFuelLimit() );
|
||||
return Math.min( fuelLevel, getFuelLimit() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFuelLevel( int level )
|
||||
{
|
||||
m_fuelLevel = Math.min( level, getFuelLimit() );
|
||||
m_owner.onTileEntityChange();
|
||||
fuelLevel = Math.min( level, getFuelLimit() );
|
||||
owner.onTileEntityChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFuelLimit()
|
||||
{
|
||||
if( m_owner.getFamily() == ComputerFamily.ADVANCED )
|
||||
if( owner.getFamily() == ComputerFamily.ADVANCED )
|
||||
{
|
||||
return ComputerCraft.advancedTurtleFuelLimit;
|
||||
}
|
||||
@ -505,8 +505,8 @@ public class TurtleBrain implements ITurtleAccess
|
||||
|
||||
private int issueCommand( ITurtleCommand command )
|
||||
{
|
||||
m_commandQueue.offer( new TurtleCommandQueueEntry( ++m_commandsIssued, command ) );
|
||||
return m_commandsIssued;
|
||||
commandQueue.offer( new TurtleCommandQueueEntry( ++commandsIssued, command ) );
|
||||
return commandsIssued;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -525,38 +525,38 @@ public class TurtleBrain implements ITurtleAccess
|
||||
{
|
||||
if( getWorld().isClientSide ) throw new UnsupportedOperationException( "Cannot play animations on the client" );
|
||||
|
||||
m_animation = animation;
|
||||
if( m_animation == TurtleAnimation.SHORT_WAIT )
|
||||
this.animation = animation;
|
||||
if( this.animation == TurtleAnimation.SHORT_WAIT )
|
||||
{
|
||||
m_animationProgress = ANIM_DURATION / 2;
|
||||
m_lastAnimationProgress = ANIM_DURATION / 2;
|
||||
animationProgress = ANIM_DURATION / 2;
|
||||
lastAnimationProgress = ANIM_DURATION / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_animationProgress = 0;
|
||||
m_lastAnimationProgress = 0;
|
||||
animationProgress = 0;
|
||||
lastAnimationProgress = 0;
|
||||
}
|
||||
m_owner.updateBlock();
|
||||
owner.updateBlock();
|
||||
}
|
||||
|
||||
public ResourceLocation getOverlay()
|
||||
{
|
||||
return m_overlay;
|
||||
return overlay;
|
||||
}
|
||||
|
||||
public void setOverlay( ResourceLocation overlay )
|
||||
{
|
||||
if( !Objects.equal( m_overlay, overlay ) )
|
||||
if( !Objects.equal( this.overlay, overlay ) )
|
||||
{
|
||||
m_overlay = overlay;
|
||||
m_owner.updateBlock();
|
||||
this.overlay = overlay;
|
||||
owner.updateBlock();
|
||||
}
|
||||
}
|
||||
|
||||
public DyeColor getDyeColour()
|
||||
{
|
||||
if( m_colourHex == -1 ) return null;
|
||||
Colour colour = Colour.fromHex( m_colourHex );
|
||||
if( colourHex == -1 ) return null;
|
||||
Colour colour = Colour.fromHex( colourHex );
|
||||
return colour == null ? null : DyeColor.byId( 15 - colour.ordinal() );
|
||||
}
|
||||
|
||||
@ -567,10 +567,10 @@ public class TurtleBrain implements ITurtleAccess
|
||||
{
|
||||
newColour = Colour.values()[15 - dyeColour.getId()].getHex();
|
||||
}
|
||||
if( m_colourHex != newColour )
|
||||
if( colourHex != newColour )
|
||||
{
|
||||
m_colourHex = newColour;
|
||||
m_owner.updateBlock();
|
||||
colourHex = newColour;
|
||||
owner.updateBlock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -579,67 +579,67 @@ public class TurtleBrain implements ITurtleAccess
|
||||
{
|
||||
if( colour >= 0 && colour <= 0xFFFFFF )
|
||||
{
|
||||
if( m_colourHex != colour )
|
||||
if( colourHex != colour )
|
||||
{
|
||||
m_colourHex = colour;
|
||||
m_owner.updateBlock();
|
||||
colourHex = colour;
|
||||
owner.updateBlock();
|
||||
}
|
||||
}
|
||||
else if( m_colourHex != -1 )
|
||||
else if( colourHex != -1 )
|
||||
{
|
||||
m_colourHex = -1;
|
||||
m_owner.updateBlock();
|
||||
colourHex = -1;
|
||||
owner.updateBlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColour()
|
||||
{
|
||||
return m_colourHex;
|
||||
return colourHex;
|
||||
}
|
||||
|
||||
public void setOwningPlayer( GameProfile profile )
|
||||
{
|
||||
m_owningPlayer = profile;
|
||||
owningPlayer = profile;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public GameProfile getOwningPlayer()
|
||||
{
|
||||
return m_owningPlayer;
|
||||
return owningPlayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITurtleUpgrade getUpgrade( @Nonnull TurtleSide side )
|
||||
{
|
||||
return m_upgrades.get( side );
|
||||
return upgrades.get( side );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUpgrade( @Nonnull TurtleSide side, ITurtleUpgrade upgrade )
|
||||
{
|
||||
// Remove old upgrade
|
||||
if( m_upgrades.containsKey( side ) )
|
||||
if( upgrades.containsKey( side ) )
|
||||
{
|
||||
if( m_upgrades.get( side ) == upgrade ) return;
|
||||
m_upgrades.remove( side );
|
||||
if( upgrades.get( side ) == upgrade ) return;
|
||||
upgrades.remove( side );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( upgrade == null ) return;
|
||||
}
|
||||
|
||||
m_upgradeNBTData.remove( side );
|
||||
upgradeNBTData.remove( side );
|
||||
|
||||
// Set new upgrade
|
||||
if( upgrade != null ) m_upgrades.put( side, upgrade );
|
||||
if( upgrade != null ) upgrades.put( side, upgrade );
|
||||
|
||||
// Notify clients and create peripherals
|
||||
if( m_owner.getLevel() != null )
|
||||
if( owner.getLevel() != null )
|
||||
{
|
||||
updatePeripherals( m_owner.createServerComputer() );
|
||||
m_owner.updateBlock();
|
||||
updatePeripherals( owner.createServerComputer() );
|
||||
owner.updateBlock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -653,20 +653,20 @@ public class TurtleBrain implements ITurtleAccess
|
||||
@Override
|
||||
public CompoundNBT getUpgradeNBTData( TurtleSide side )
|
||||
{
|
||||
CompoundNBT nbt = m_upgradeNBTData.get( side );
|
||||
if( nbt == null ) m_upgradeNBTData.put( side, nbt = new CompoundNBT() );
|
||||
CompoundNBT nbt = upgradeNBTData.get( side );
|
||||
if( nbt == null ) upgradeNBTData.put( side, nbt = new CompoundNBT() );
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUpgradeNBTData( @Nonnull TurtleSide side )
|
||||
{
|
||||
m_owner.updateBlock();
|
||||
owner.updateBlock();
|
||||
}
|
||||
|
||||
public Vector3d getRenderOffset( float f )
|
||||
{
|
||||
switch( m_animation )
|
||||
switch( animation )
|
||||
{
|
||||
case MOVE_FORWARD:
|
||||
case MOVE_BACK:
|
||||
@ -675,7 +675,7 @@ public class TurtleBrain implements ITurtleAccess
|
||||
{
|
||||
// Get direction
|
||||
Direction dir;
|
||||
switch( m_animation )
|
||||
switch( animation )
|
||||
{
|
||||
case MOVE_FORWARD:
|
||||
default:
|
||||
@ -708,8 +708,8 @@ public class TurtleBrain implements ITurtleAccess
|
||||
|
||||
public float getToolRenderAngle( TurtleSide side, float f )
|
||||
{
|
||||
return (side == TurtleSide.LEFT && m_animation == TurtleAnimation.SWING_LEFT_TOOL) ||
|
||||
(side == TurtleSide.RIGHT && m_animation == TurtleAnimation.SWING_RIGHT_TOOL)
|
||||
return (side == TurtleSide.LEFT && animation == TurtleAnimation.SWING_LEFT_TOOL) ||
|
||||
(side == TurtleSide.RIGHT && animation == TurtleAnimation.SWING_RIGHT_TOOL)
|
||||
? 45.0f * (float) Math.sin( getAnimationFraction( f ) * Math.PI )
|
||||
: 0.0f;
|
||||
}
|
||||
@ -759,14 +759,14 @@ public class TurtleBrain implements ITurtleAccess
|
||||
|
||||
private void updateCommands()
|
||||
{
|
||||
if( m_animation != TurtleAnimation.NONE || m_commandQueue.isEmpty() ) return;
|
||||
if( animation != TurtleAnimation.NONE || commandQueue.isEmpty() ) return;
|
||||
|
||||
// If we've got a computer, ensure that we're allowed to perform work.
|
||||
ServerComputer computer = m_owner.getServerComputer();
|
||||
ServerComputer computer = owner.getServerComputer();
|
||||
if( computer != null && !computer.getComputer().getMainThreadMonitor().canWork() ) return;
|
||||
|
||||
// Pull a new command
|
||||
TurtleCommandQueueEntry nextCommand = m_commandQueue.poll();
|
||||
TurtleCommandQueueEntry nextCommand = commandQueue.poll();
|
||||
if( nextCommand == null ) return;
|
||||
|
||||
// Execute the command
|
||||
@ -808,21 +808,21 @@ public class TurtleBrain implements ITurtleAccess
|
||||
|
||||
private void updateAnimation()
|
||||
{
|
||||
if( m_animation != TurtleAnimation.NONE )
|
||||
if( animation != TurtleAnimation.NONE )
|
||||
{
|
||||
World world = getWorld();
|
||||
|
||||
if( ComputerCraft.turtlesCanPush )
|
||||
{
|
||||
// Advance entity pushing
|
||||
if( m_animation == TurtleAnimation.MOVE_FORWARD ||
|
||||
m_animation == TurtleAnimation.MOVE_BACK ||
|
||||
m_animation == TurtleAnimation.MOVE_UP ||
|
||||
m_animation == TurtleAnimation.MOVE_DOWN )
|
||||
if( animation == TurtleAnimation.MOVE_FORWARD ||
|
||||
animation == TurtleAnimation.MOVE_BACK ||
|
||||
animation == TurtleAnimation.MOVE_UP ||
|
||||
animation == TurtleAnimation.MOVE_DOWN )
|
||||
{
|
||||
BlockPos pos = getPosition();
|
||||
Direction moveDir;
|
||||
switch( m_animation )
|
||||
switch( animation )
|
||||
{
|
||||
case MOVE_FORWARD:
|
||||
default:
|
||||
@ -846,7 +846,7 @@ public class TurtleBrain implements ITurtleAccess
|
||||
double maxY = minY + 1.0;
|
||||
double maxZ = minZ + 1.0;
|
||||
|
||||
float pushFrac = 1.0f - (float) (m_animationProgress + 1) / ANIM_DURATION;
|
||||
float pushFrac = 1.0f - (float) (animationProgress + 1) / ANIM_DURATION;
|
||||
float push = Math.max( pushFrac + 0.0125f, 0.0f );
|
||||
if( moveDir.getStepX() < 0 )
|
||||
{
|
||||
@ -892,7 +892,7 @@ public class TurtleBrain implements ITurtleAccess
|
||||
}
|
||||
|
||||
// Advance valentines day easter egg
|
||||
if( world.isClientSide && m_animation == TurtleAnimation.MOVE_FORWARD && m_animationProgress == 4 )
|
||||
if( world.isClientSide && animation == TurtleAnimation.MOVE_FORWARD && animationProgress == 4 )
|
||||
{
|
||||
// Spawn love pfx if valentines day
|
||||
Holiday currentHoliday = HolidayUtil.getCurrentHoliday();
|
||||
@ -915,20 +915,20 @@ public class TurtleBrain implements ITurtleAccess
|
||||
}
|
||||
|
||||
// Wait for anim completion
|
||||
m_lastAnimationProgress = m_animationProgress;
|
||||
if( ++m_animationProgress >= ANIM_DURATION )
|
||||
lastAnimationProgress = animationProgress;
|
||||
if( ++animationProgress >= ANIM_DURATION )
|
||||
{
|
||||
m_animation = TurtleAnimation.NONE;
|
||||
m_animationProgress = 0;
|
||||
m_lastAnimationProgress = 0;
|
||||
animation = TurtleAnimation.NONE;
|
||||
animationProgress = 0;
|
||||
lastAnimationProgress = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float getAnimationFraction( float f )
|
||||
{
|
||||
float next = (float) m_animationProgress / ANIM_DURATION;
|
||||
float previous = (float) m_lastAnimationProgress / ANIM_DURATION;
|
||||
float next = (float) animationProgress / ANIM_DURATION;
|
||||
float previous = (float) lastAnimationProgress / ANIM_DURATION;
|
||||
return previous + (next - previous) * f;
|
||||
}
|
||||
|
||||
|
@ -23,11 +23,11 @@ import java.util.List;
|
||||
|
||||
public class TurtleCompareCommand implements ITurtleCommand
|
||||
{
|
||||
private final InteractDirection m_direction;
|
||||
private final InteractDirection direction;
|
||||
|
||||
public TurtleCompareCommand( InteractDirection direction )
|
||||
{
|
||||
m_direction = direction;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -35,7 +35,7 @@ public class TurtleCompareCommand implements ITurtleCommand
|
||||
public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
|
||||
{
|
||||
// Get world direction from direction
|
||||
Direction direction = m_direction.toWorldDir( turtle );
|
||||
Direction direction = this.direction.toWorldDir( turtle );
|
||||
|
||||
// Get currently selected stack
|
||||
ItemStack selectedStack = turtle.getInventory().getItem( turtle.getSelectedSlot() );
|
||||
|
@ -15,11 +15,11 @@ import javax.annotation.Nonnull;
|
||||
|
||||
public class TurtleCompareToCommand implements ITurtleCommand
|
||||
{
|
||||
private final int m_slot;
|
||||
private final int slot;
|
||||
|
||||
public TurtleCompareToCommand( int slot )
|
||||
{
|
||||
m_slot = slot;
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -27,14 +27,9 @@ public class TurtleCompareToCommand implements ITurtleCommand
|
||||
public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
|
||||
{
|
||||
ItemStack selectedStack = turtle.getInventory().getItem( turtle.getSelectedSlot() );
|
||||
ItemStack stack = turtle.getInventory().getItem( m_slot );
|
||||
if( InventoryUtil.areItemsStackable( selectedStack, stack ) )
|
||||
{
|
||||
return TurtleCommandResult.success();
|
||||
}
|
||||
else
|
||||
{
|
||||
return TurtleCommandResult.failure();
|
||||
}
|
||||
ItemStack stack = turtle.getInventory().getItem( slot );
|
||||
return InventoryUtil.areItemsStackable( selectedStack, stack )
|
||||
? TurtleCommandResult.success()
|
||||
: TurtleCommandResult.failure();
|
||||
}
|
||||
}
|
||||
|
@ -17,11 +17,11 @@ import javax.annotation.Nonnull;
|
||||
|
||||
public class TurtleDetectCommand implements ITurtleCommand
|
||||
{
|
||||
private final InteractDirection m_direction;
|
||||
private final InteractDirection direction;
|
||||
|
||||
public TurtleDetectCommand( InteractDirection direction )
|
||||
{
|
||||
m_direction = direction;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -29,7 +29,7 @@ public class TurtleDetectCommand implements ITurtleCommand
|
||||
public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
|
||||
{
|
||||
// Get world direction from direction
|
||||
Direction direction = m_direction.toWorldDir( turtle );
|
||||
Direction direction = this.direction.toWorldDir( turtle );
|
||||
|
||||
// Check if thing in front is air or not
|
||||
World world = turtle.getWorld();
|
||||
|
@ -23,13 +23,13 @@ import javax.annotation.Nonnull;
|
||||
|
||||
public class TurtleDropCommand implements ITurtleCommand
|
||||
{
|
||||
private final InteractDirection m_direction;
|
||||
private final int m_quantity;
|
||||
private final InteractDirection direction;
|
||||
private final int quantity;
|
||||
|
||||
public TurtleDropCommand( InteractDirection direction, int quantity )
|
||||
{
|
||||
m_direction = direction;
|
||||
m_quantity = quantity;
|
||||
this.direction = direction;
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -37,17 +37,17 @@ public class TurtleDropCommand implements ITurtleCommand
|
||||
public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
|
||||
{
|
||||
// Dropping nothing is easy
|
||||
if( m_quantity == 0 )
|
||||
if( quantity == 0 )
|
||||
{
|
||||
turtle.playAnimation( TurtleAnimation.WAIT );
|
||||
return TurtleCommandResult.success();
|
||||
}
|
||||
|
||||
// Get world direction from direction
|
||||
Direction direction = m_direction.toWorldDir( turtle );
|
||||
Direction direction = this.direction.toWorldDir( turtle );
|
||||
|
||||
// Get things to drop
|
||||
ItemStack stack = InventoryUtil.takeItems( m_quantity, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
|
||||
ItemStack stack = InventoryUtil.takeItems( quantity, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
|
||||
if( stack.isEmpty() )
|
||||
{
|
||||
return TurtleCommandResult.failure( "No items to drop" );
|
||||
|
@ -20,11 +20,11 @@ import javax.annotation.Nonnull;
|
||||
|
||||
public class TurtleEquipCommand implements ITurtleCommand
|
||||
{
|
||||
private final TurtleSide m_side;
|
||||
private final TurtleSide side;
|
||||
|
||||
public TurtleEquipCommand( TurtleSide side )
|
||||
{
|
||||
m_side = side;
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -53,7 +53,7 @@ public class TurtleEquipCommand implements ITurtleCommand
|
||||
|
||||
// Determine the upgrade to replace
|
||||
ItemStack oldUpgradeStack;
|
||||
ITurtleUpgrade oldUpgrade = turtle.getUpgrade( m_side );
|
||||
ITurtleUpgrade oldUpgrade = turtle.getUpgrade( side );
|
||||
if( oldUpgrade != null )
|
||||
{
|
||||
ItemStack craftingItem = oldUpgrade.getCraftingItem();
|
||||
@ -87,7 +87,7 @@ public class TurtleEquipCommand implements ITurtleCommand
|
||||
WorldUtil.dropItemStack( remainder, turtle.getWorld(), position, turtle.getDirection() );
|
||||
}
|
||||
}
|
||||
turtle.setUpgrade( m_side, newUpgrade );
|
||||
turtle.setUpgrade( side, newUpgrade );
|
||||
|
||||
// Animate
|
||||
if( newUpgrade != null || oldUpgrade != null )
|
||||
|
@ -28,11 +28,11 @@ import java.util.List;
|
||||
|
||||
public class TurtleMoveCommand implements ITurtleCommand
|
||||
{
|
||||
private final MoveDirection m_direction;
|
||||
private final MoveDirection direction;
|
||||
|
||||
public TurtleMoveCommand( MoveDirection direction )
|
||||
{
|
||||
m_direction = direction;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -40,7 +40,7 @@ public class TurtleMoveCommand implements ITurtleCommand
|
||||
public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
|
||||
{
|
||||
// Get world direction from direction
|
||||
Direction direction = m_direction.toWorldDir( turtle );
|
||||
Direction direction = this.direction.toWorldDir( turtle );
|
||||
|
||||
// Check if we can move
|
||||
World oldWorld = turtle.getWorld();
|
||||
@ -72,7 +72,7 @@ public class TurtleMoveCommand implements ITurtleCommand
|
||||
|
||||
if( !oldWorld.isUnobstructed( null, collision ) )
|
||||
{
|
||||
if( !ComputerCraft.turtlesCanPush || m_direction == MoveDirection.UP || m_direction == MoveDirection.DOWN )
|
||||
if( !ComputerCraft.turtlesCanPush || this.direction == MoveDirection.UP || this.direction == MoveDirection.DOWN )
|
||||
{
|
||||
return TurtleCommandResult.failure( "Movement obstructed" );
|
||||
}
|
||||
@ -112,7 +112,7 @@ public class TurtleMoveCommand implements ITurtleCommand
|
||||
turtle.consumeFuel( 1 );
|
||||
|
||||
// Animate
|
||||
switch( m_direction )
|
||||
switch( this.direction )
|
||||
{
|
||||
case FORWARD:
|
||||
default:
|
||||
|
@ -42,13 +42,13 @@ import java.util.List;
|
||||
|
||||
public class TurtlePlaceCommand implements ITurtleCommand
|
||||
{
|
||||
private final InteractDirection m_direction;
|
||||
private final Object[] m_extraArguments;
|
||||
private final InteractDirection direction;
|
||||
private final Object[] extraArguments;
|
||||
|
||||
public TurtlePlaceCommand( InteractDirection direction, Object[] arguments )
|
||||
{
|
||||
m_direction = direction;
|
||||
m_extraArguments = arguments;
|
||||
this.direction = direction;
|
||||
extraArguments = arguments;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -63,7 +63,7 @@ public class TurtlePlaceCommand implements ITurtleCommand
|
||||
}
|
||||
|
||||
// Remember old block
|
||||
Direction direction = m_direction.toWorldDir( turtle );
|
||||
Direction direction = this.direction.toWorldDir( turtle );
|
||||
BlockPos coordinates = turtle.getPosition().relative( direction );
|
||||
|
||||
// Create a fake player, and orient it appropriately
|
||||
@ -78,7 +78,7 @@ public class TurtlePlaceCommand implements ITurtleCommand
|
||||
|
||||
// Do the deploying
|
||||
String[] errorMessage = new String[1];
|
||||
ItemStack remainder = deploy( stack, turtle, turtlePlayer, direction, m_extraArguments, errorMessage );
|
||||
ItemStack remainder = deploy( stack, turtle, turtlePlayer, direction, extraArguments, errorMessage );
|
||||
if( remainder != stack )
|
||||
{
|
||||
// Put the remaining items back
|
||||
|
@ -95,11 +95,11 @@ public final class TurtlePlayer extends FakePlayer
|
||||
if( !(access instanceof TurtleBrain) ) return create( access );
|
||||
|
||||
TurtleBrain brain = (TurtleBrain) access;
|
||||
TurtlePlayer player = brain.m_cachedPlayer;
|
||||
TurtlePlayer player = brain.cachedPlayer;
|
||||
if( player == null || player.getGameProfile() != getProfile( access.getOwningPlayer() )
|
||||
|| player.getCommandSenderWorld() != access.getWorld() )
|
||||
{
|
||||
player = brain.m_cachedPlayer = create( brain );
|
||||
player = brain.cachedPlayer = create( brain );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -26,13 +26,13 @@ import java.util.List;
|
||||
|
||||
public class TurtleSuckCommand implements ITurtleCommand
|
||||
{
|
||||
private final InteractDirection m_direction;
|
||||
private final int m_quantity;
|
||||
private final InteractDirection direction;
|
||||
private final int quantity;
|
||||
|
||||
public TurtleSuckCommand( InteractDirection direction, int quantity )
|
||||
{
|
||||
m_direction = direction;
|
||||
m_quantity = quantity;
|
||||
this.direction = direction;
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -40,14 +40,14 @@ public class TurtleSuckCommand implements ITurtleCommand
|
||||
public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
|
||||
{
|
||||
// Sucking nothing is easy
|
||||
if( m_quantity == 0 )
|
||||
if( quantity == 0 )
|
||||
{
|
||||
turtle.playAnimation( TurtleAnimation.WAIT );
|
||||
return TurtleCommandResult.success();
|
||||
}
|
||||
|
||||
// Get world direction from direction
|
||||
Direction direction = m_direction.toWorldDir( turtle );
|
||||
Direction direction = this.direction.toWorldDir( turtle );
|
||||
|
||||
// Get inventory for thing in front
|
||||
World world = turtle.getWorld();
|
||||
@ -68,7 +68,7 @@ public class TurtleSuckCommand implements ITurtleCommand
|
||||
if( inventory != null )
|
||||
{
|
||||
// Take from inventory of thing in front
|
||||
ItemStack stack = InventoryUtil.takeItems( m_quantity, inventory );
|
||||
ItemStack stack = InventoryUtil.takeItems( quantity, inventory );
|
||||
if( stack.isEmpty() ) return TurtleCommandResult.failure( "No items to take" );
|
||||
|
||||
// Try to place into the turtle
|
||||
@ -107,9 +107,9 @@ public class TurtleSuckCommand implements ITurtleCommand
|
||||
|
||||
ItemStack storeStack;
|
||||
ItemStack leaveStack;
|
||||
if( stack.getCount() > m_quantity )
|
||||
if( stack.getCount() > quantity )
|
||||
{
|
||||
storeStack = stack.split( m_quantity );
|
||||
storeStack = stack.split( quantity );
|
||||
leaveStack = stack;
|
||||
}
|
||||
else
|
||||
|
@ -16,13 +16,13 @@ import javax.annotation.Nonnull;
|
||||
|
||||
public class TurtleTransferToCommand implements ITurtleCommand
|
||||
{
|
||||
private final int m_slot;
|
||||
private final int m_quantity;
|
||||
private final int slot;
|
||||
private final int quantity;
|
||||
|
||||
public TurtleTransferToCommand( int slot, int limit )
|
||||
{
|
||||
m_slot = slot;
|
||||
m_quantity = limit;
|
||||
this.slot = slot;
|
||||
quantity = limit;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -30,7 +30,7 @@ public class TurtleTransferToCommand implements ITurtleCommand
|
||||
public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
|
||||
{
|
||||
// Take stack
|
||||
ItemStack stack = InventoryUtil.takeItems( m_quantity, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
|
||||
ItemStack stack = InventoryUtil.takeItems( quantity, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
|
||||
if( stack.isEmpty() )
|
||||
{
|
||||
turtle.playAnimation( TurtleAnimation.WAIT );
|
||||
@ -38,7 +38,7 @@ public class TurtleTransferToCommand implements ITurtleCommand
|
||||
}
|
||||
|
||||
// Store stack
|
||||
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), m_slot, 1, m_slot );
|
||||
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), slot, 1, slot );
|
||||
if( !remainder.isEmpty() )
|
||||
{
|
||||
// Put the remainder back
|
||||
|
@ -17,11 +17,11 @@ import javax.annotation.Nonnull;
|
||||
|
||||
public class TurtleTurnCommand implements ITurtleCommand
|
||||
{
|
||||
private final TurnDirection m_direction;
|
||||
private final TurnDirection direction;
|
||||
|
||||
public TurtleTurnCommand( TurnDirection direction )
|
||||
{
|
||||
m_direction = direction;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -34,7 +34,7 @@ public class TurtleTurnCommand implements ITurtleCommand
|
||||
return TurtleCommandResult.failure( event.getFailureMessage() );
|
||||
}
|
||||
|
||||
switch( m_direction )
|
||||
switch( direction )
|
||||
{
|
||||
case LEFT:
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user