1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-11-07 08:52:59 +00:00

Compare commits

...

22 Commits

Author SHA1 Message Date
Jonathan Coates
ee27d8f081 Bump version to 1.95.2 2021-01-16 11:18:59 +00:00
Jonathan Coates
1381325813 Expand CONTRIBUTING a little
Explain our overly-complicated build system. Because of course we need
to.
2021-01-15 23:16:58 +00:00
Jonathan Coates
52b112fae6 Bump several action versions 2021-01-15 19:39:12 +00:00
Wojbie
c83eeb16a8 id.lua now handles more disk types (#677)
Co-authored-by: Lupus590 <lupussolitarius590@gmail.com>
2021-01-15 19:30:21 +00:00
Jonathan Coates
9d1ee6f61d Remove m_ (#658)
IT'S GONE!

Not looking forward to the merge conflicts on this one.
2021-01-15 16:35:49 +00:00
Jonathan Coates
b90611b4b4 Preserve registration order of upgrades
Makes them display in a more reasonable order within JEI. Closes #647
(note, the title is an entirley separate issue)!
2021-01-15 15:32:11 +00:00
Jonathan Coates
e1e7ef59c6 Measure code coverage from in-game tests
More importantly, `./gradlew check' actually runs the in-game tests,
which makes the CI steps look a little more sensible again.

Somewhat depressing that one of the longest files (15th) in CC:T is the
build script.
2021-01-15 09:54:38 +00:00
SquidDev
9ae0f4a993 Add some initial documentation for events
Credit to @BradyFromDiscord for writing these. See #640 and #565.

Co-authored-by: Brady <bradyakent@gmail.com
2021-01-14 18:37:20 +00:00
Jonathan Coates
fd262a7995 Clarify the cc.strings.wrap docs a little
Also make the example a bit more "useful". Hopefully this should clarify
that the function returns a table rather than a single string.

Closes #678.
2021-01-14 09:12:37 +00:00
Jonathan Coates
58054ad2d1 Reformat src/main/java
Removes several pointless imports. And, more importantly, fixes the
build.
2021-01-14 09:09:02 +00:00
Jonathan Coates
1255bd00fd Fix mounts being usable after a disk is ejected
This probably fails "responsible disclosure", but it's not an RCE and
frankly the whole bug is utterly hilarious so here we are...

It's possible to open a file on a disk drive and continue to read/write
to them after the disk has been removed:

    local disk = peripheral.find("drive")
    local input = fs.open(fs.combine(disk.getMountPath(), "stream"), "rb")
    local output = fs.open(fs.combine(disk.getMountPath(), "stream"), "wb")
    disk.ejectDisk()

    -- input/output can still be interacted with.

This is pretty amusing, as now it allows us to move the disk somewhere
else and repeat - we've now got a private tunnel which two computers can
use to communicate.

Fixing this is intuitively quite simple - just close any open files
belonging to this mount. However, this is where things get messy thanks
to the wonderful joy of how CC's streams are handled.

As things stand, the filesystem effectively does the following flow::
 - There is a function `open : String -> Channel' (file modes are
   irrelevant here).

 - Once a file is opened, we transform it into some <T extends
   Closeable>. This is, for instance, a BufferedReader.

 - We generate a "token" (i.e. FileSystemWrapper<T>), which we generate
   a week reference to and map it to a tuple of our Channel and T. If
   this token is ever garbage collected (someone forgot to call close()
   on a file), then we close our T and Channel.

 - This token and T are returned to the calling function, which then
   constructs a Lua object.

The problem here is that if we close the underlying Channel+T before the
Lua object calls .close(), then it won't know the underlying channel is
closed, and you get some pretty ugly errors (e.g. "Stream Closed"). So
we've moved the "is open" state into the FileSystemWrapper<T>.

The whole system is incredibly complex at this point, and I'd really
like to clean it up. Ideally we could treat the HandleGeneric as the
token instead - this way we could potentially also clean up
FileSystemWrapperMount.

BBut something to play with in the future, and not when it's 10:30pm.

---

All this wall of text, and this isn't the only bug I've found with disks
today :/.
2021-01-13 22:10:44 +00:00
Wojbie
1f84480a80 Make rightAlt only close menu, never open it. (#672)
Fixes #669
2021-01-11 21:59:29 +00:00
Jonathan Coates
b838efedd2 Retry the prepare step one time
Hopefully ensures failed assets assets don't entirely break the build.
2021-01-09 20:17:32 +00:00
Jonathan Coates
f78e24f9a0 Use UnsafeHacks to construct the test function info
This has been stripped (only in CI on 1.15, always in 1.16) so blows up
when we try to call it.
2021-01-09 20:12:13 +00:00
Jonathan Coates
88f5b20353 Fix checkstyle and licence checks
Of all the things to fail in this absurdy complex change >_>.
2021-01-09 20:00:15 +00:00
Jonathan Coates
331031be45 Run integration tests in-game
Name a more iconic duo than @SquidDev and over-engineered test
frameworks.

This uses Minecraft's test core[1] plus a home-grown framework to run
tests against computers in-world.

The general idea is:
 - Build a structure in game.
 - Save the structure to a file. This will be spawned in every time the
   test is run.
 - Write some code which asserts the structure behaves in a particular
   way. This is done in Kotlin (shock, horror), as coroutines give us a
   nice way to run asynchronous code while still running on the main
   thread.

As with all my testing efforts, I still haven't actually written any
tests!  It'd be good to go through some of the historic ones and write
some tests though. Turtle block placing and computer redstone
interactions are probably a good place to start.

[1]: https://www.youtube.com/watch?v=vXaWOJTCYNg
2021-01-09 19:50:27 +00:00
Jonathan Coates
34b5ede326 Switch to Mojang mappings
ForgeGradle (probably sensibly) yells at me about doing this. However:
 - There's a reasonable number of mods doing this, which establishes
   some optimistic precedent.
 - The licence update in Aug 2020 now allows you to use them for
   "development purposes". I guess source code counts??
 - I'm fairly sure this is also compatible with the CCPL - there's an
   exception for Minecraft code.

The main motivation for this is to make the Fabric port a little
easier. Hopefully folks (maybe me in the future, we'll see) will no
longer have to deal with mapping hell when merging - only mod loader
hell.
2021-01-09 19:22:58 +00:00
Jonathan Coates
c864576619 Fix impostor recipes for disks
Well, this is embarrassing. See #652
2021-01-09 18:30:07 +00:00
Jonathan Coates
247c05305d Fix problem with RepeatArgumentType
The whole "flatten" thing can probably be dropped TBH. We don't use it
anywhere. Fixes #661
2021-01-08 17:50:26 +00:00
Jonathan Coates
2232f025b8 Make CC:T work as a non-root project 2021-01-08 17:50:25 +00:00
Wojbie
b2e5401486 Added Numpad Enter Support in rom lua programs. (#657) 2021-01-07 21:41:04 +00:00
Lupus590
41226371f3 Add isReadOnly to fs.attributes (#639) 2021-01-07 16:36:25 +00:00
271 changed files with 5669 additions and 3322 deletions

1
.gitattributes vendored
View File

@@ -1,2 +1,3 @@
# Ignore changes in generated files
src/generated/resources/data/** linguist-generated
src/test/server-files/structures linguist-generated

View File

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

View File

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

View File

@@ -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."

View File

@@ -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'
@@ -50,9 +51,10 @@ minecraft {
}
server {
workingDirectory project.file("run/server-${mc_version}")
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP'
workingDirectory project.file("run/server")
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,9 +75,20 @@ minecraft {
}
}
}
testServer {
workingDirectory project.file('test-files/server')
parent runs.server
mods {
cctest {
source sourceSets.test
}
}
}
}
mappings channel: 'snapshot', version: "${mappings_version}".toString()
mappings channel: 'official', version: project.mc_version
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
}
@@ -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
@@ -388,14 +405,14 @@ license {
it.configure {
include("**/*.java")
exclude("dan200/computercraft/api/**")
header rootProject.file('config/license/main.txt')
header file('config/license/main.txt')
}
}
[licenseTest, licenseFormatTest].forEach {
it.configure {
include("**/*.java")
header rootProject.file('config/license/main.txt')
header file('config/license/main.txt')
}
}
@@ -412,10 +429,71 @@ task licenseFormatAPI(type: LicenseFormat);
it.configure {
source = sourceSets.main.java
include("dan200/computercraft/api/**")
header rootProject.file('config/license/api.txt')
header file('config/license/api.txt')
}
}
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 {
@@ -430,7 +508,7 @@ task checkRelease {
def ok = true
// Check we're targetting the current version
def whatsnew = new File("src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt").readLines()
def whatsnew = new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt").readLines()
if (whatsnew[0] != "New features in CC: Tweaked $mod_version") {
ok = false
project.logger.error("Expected `whatsnew.txt' to target $mod_version.")
@@ -447,7 +525,7 @@ task checkRelease {
// Check whatsnew and changelog match.
def versionChangelog = "# " + whatsnew.join("\n")
def changelog = new File("src/main/resources/data/computercraft/lua/rom/help/changelog.txt").getText()
def changelog = new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/changelog.txt").getText()
if (!changelog.startsWith(versionChangelog)) {
ok = false
project.logger.error("whatsnew and changelog are not in sync")
@@ -535,7 +613,7 @@ githubRelease {
tagName "v${mc_version}-${mod_version}"
releaseName "[${mc_version}] ${mod_version}"
body {
"## " + new File("src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt")
"## " + new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt")
.readLines()
.takeWhile { it != 'Type "help changelog" to see the full version history.' }
.join("\n").trim()

View File

@@ -7,7 +7,7 @@
<property name="charset" value="UTF-8" />
<module name="SuppressionFilter">
<property name="file" value="config/checkstyle/suppressions.xml" />
<property name="file" value="${config_loc}/suppressions.xml" />
</module>
<module name="BeforeExecutionExclusionFileFilter">
@@ -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
View 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
View 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
View 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
View 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
View 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
```

View 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
View 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

View File

@@ -1,7 +1,6 @@
# Mod properties
mod_version=1.95.1
mod_version=1.95.2
# Minecraft properties (update mods.toml when changing)
mc_version=1.15.2
forge_version=31.1.41
mappings_version=20200429-1.15.1

View File

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

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:1118481}"
"nbt": "{Color:1118481}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:15905484}"
"nbt": "{Color:15905484}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:8375321}"
"nbt": "{Color:8375321}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:14605932}"
"nbt": "{Color:14605932}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:10072818}"
"nbt": "{Color:10072818}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:15040472}"
"nbt": "{Color:15040472}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:15905331}"
"nbt": "{Color:15905331}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:15790320}"
"nbt": "{Color:15790320}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:13388876}"
"nbt": "{Color:13388876}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:5744206}"
"nbt": "{Color:5744206}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:8349260}"
"nbt": "{Color:8349260}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:3368652}"
"nbt": "{Color:3368652}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:11691749}"
"nbt": "{Color:11691749}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:5020082}"
"nbt": "{Color:5020082}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:10066329}"
"nbt": "{Color:10066329}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:5000268}"
"nbt": "{Color:5000268}"
}
}

View File

@@ -54,7 +54,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
public static InputStream getResourceFile( String domain, String subPath )
{
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResources();
try
{
return manager.getResource( new ResourceLocation( domain, subPath ) ).getInputStream();
@@ -97,7 +97,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
@Override
public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
{
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResources();
ResourceMount mount = ResourceMount.get( domain, subPath, manager );
return mount.exists( "" ) ? mount : null;
}
@@ -162,7 +162,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
@Override
public LazyOptional<IWiredElement> getWiredElementAt( @Nonnull IBlockReader world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
TileEntity tile = world.getTileEntity( pos );
TileEntity tile = world.getBlockEntity( pos );
return tile == null ? LazyOptional.empty() : tile.getCapability( CAPABILITY_WIRED_ELEMENT, side );
}
}

View File

@@ -43,7 +43,7 @@ public final class TransformedModel
public static TransformedModel of( @Nonnull ItemStack item, @Nonnull TransformationMatrix transform )
{
IBakedModel model = Minecraft.getInstance().getItemRenderer().getItemModelMesher().getItemModel( item );
IBakedModel model = Minecraft.getInstance().getItemRenderer().getItemModelShaper().getItemModel( item );
return new TransformedModel( model, transform );
}

View File

@@ -35,7 +35,7 @@ public abstract class AbstractPocketUpgrade implements IPocketUpgrade
protected AbstractPocketUpgrade( ResourceLocation id, NonNullSupplier<ItemStack> item )
{
this( id, Util.makeTranslationKey( "upgrade", id ) + ".adjective", item );
this( id, Util.makeDescriptionId( "upgrade", id ) + ".adjective", item );
}
protected AbstractPocketUpgrade( ResourceLocation id, String adjective, ItemStack stack )

View File

@@ -37,7 +37,7 @@ public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade
protected AbstractTurtleUpgrade( ResourceLocation id, TurtleUpgradeType type, NonNullSupplier<ItemStack> stack )
{
this( id, type, Util.makeTranslationKey( "upgrade", id ) + ".adjective", stack );
this( id, type, Util.makeDescriptionId( "upgrade", id ) + ".adjective", stack );
}
protected AbstractTurtleUpgrade( ResourceLocation id, TurtleUpgradeType type, String adjective, ItemStack stack )

View File

@@ -78,7 +78,7 @@ public final class ClientRegistry
@SubscribeEvent
public static void onTextureStitchEvent( TextureStitchEvent.Pre event )
{
if( !event.getMap().getTextureLocation().equals( PlayerContainer.LOCATION_BLOCKS_TEXTURE ) ) return;
if( !event.getMap().location().equals( PlayerContainer.BLOCK_ATLAS ) ) return;
for( String extra : EXTRA_TEXTURES )
{
@@ -96,10 +96,10 @@ public final class ClientRegistry
for( String modelName : EXTRA_MODELS )
{
ResourceLocation location = new ResourceLocation( ComputerCraft.MOD_ID, "item/" + modelName );
IUnbakedModel model = loader.getUnbakedModel( location );
model.getTextures( loader::getUnbakedModel, new HashSet<>() );
IUnbakedModel model = loader.getModel( location );
model.getMaterials( loader::getModel, new HashSet<>() );
IBakedModel baked = model.bakeModel( loader, ModelLoader.defaultTextureGetter(), SimpleModelTransform.IDENTITY, location );
IBakedModel baked = model.bake( loader, ModelLoader.defaultTextureGetter(), SimpleModelTransform.IDENTITY, location );
if( baked != null )
{
registry.put( new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, modelName ), "inventory" ), baked );

View File

@@ -25,11 +25,11 @@ public class ClientTableFormatter implements TableFormatter
{
public static final ClientTableFormatter INSTANCE = new ClientTableFormatter();
private static Int2IntOpenHashMap lastHeights = new Int2IntOpenHashMap();
private static final Int2IntOpenHashMap lastHeights = new Int2IntOpenHashMap();
private static FontRenderer renderer()
{
return Minecraft.getInstance().fontRenderer;
return Minecraft.getInstance().font;
}
@Override
@@ -41,7 +41,7 @@ public class ClientTableFormatter implements TableFormatter
FontRenderer renderer = renderer();
float spaceWidth = renderer.getStringWidth( " " );
float spaceWidth = renderer.width( " " );
int spaces = MathHelper.floor( extraWidth / spaceWidth );
int extra = extraWidth - (int) (spaces * spaceWidth);
@@ -57,32 +57,32 @@ public class ClientTableFormatter implements TableFormatter
@Override
public int getWidth( ITextComponent component )
{
return renderer().getStringWidth( component.getFormattedText() );
return renderer().width( component.getColoredString() );
}
@Override
public void writeLine( int id, ITextComponent component )
{
Minecraft mc = Minecraft.getInstance();
NewChatGui chat = mc.ingameGUI.getChatGUI();
NewChatGui chat = mc.gui.getChat();
// Trim the text if it goes over the allowed length
int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getScale() );
List<ITextComponent> list = RenderComponentsUtil.splitText( component, maxWidth, mc.fontRenderer, false, false );
if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id );
int maxWidth = MathHelper.floor( chat.getWidth() / chat.getScale() );
List<ITextComponent> list = RenderComponentsUtil.wrapComponents( component, maxWidth, mc.font, false, false );
if( !list.isEmpty() ) chat.addMessage( list.get( 0 ), id );
}
@Override
public int display( TableBuilder table )
{
NewChatGui chat = Minecraft.getInstance().ingameGUI.getChatGUI();
NewChatGui chat = Minecraft.getInstance().gui.getChat();
int lastHeight = lastHeights.get( table.getId() );
int height = TableFormatter.super.display( table );
lastHeights.put( table.getId(), height );
for( int i = height; i < lastHeight; i++ ) chat.deleteChatLine( i + table.getId() );
for( int i = height; i < lastHeight; i++ ) chat.removeById( i + table.getId() );
return height;
}
}

View File

@@ -62,22 +62,22 @@ public final class FixedWidthFontRenderer
int xStart = 1 + column * (FONT_WIDTH + 2);
int yStart = 1 + row * (FONT_HEIGHT + 2);
buffer.pos( transform, x, y, 0f ).color( r, g, b, 1.0f ).tex( xStart / WIDTH, yStart / WIDTH ).endVertex();
buffer.pos( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).tex( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex();
buffer.pos( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).tex( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).endVertex();
buffer.pos( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).tex( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).endVertex();
buffer.pos( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).tex( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex();
buffer.pos( transform, x + FONT_WIDTH, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).tex( (xStart + FONT_WIDTH) / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex();
buffer.vertex( transform, x, y, 0f ).color( r, g, b, 1.0f ).uv( xStart / WIDTH, yStart / WIDTH ).endVertex();
buffer.vertex( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).uv( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex();
buffer.vertex( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).uv( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).endVertex();
buffer.vertex( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).uv( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).endVertex();
buffer.vertex( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).uv( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex();
buffer.vertex( transform, x + FONT_WIDTH, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).uv( (xStart + FONT_WIDTH) / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex();
}
private static void drawQuad( Matrix4f transform, IVertexBuilder buffer, float x, float y, float width, float height, float r, float g, float b )
{
buffer.pos( transform, x, y, 0 ).color( r, g, b, 1.0f ).tex( BACKGROUND_START, BACKGROUND_START ).endVertex();
buffer.pos( transform, x, y + height, 0 ).color( r, g, b, 1.0f ).tex( BACKGROUND_START, BACKGROUND_END ).endVertex();
buffer.pos( transform, x + width, y, 0 ).color( r, g, b, 1.0f ).tex( BACKGROUND_END, BACKGROUND_START ).endVertex();
buffer.pos( transform, x + width, y, 0 ).color( r, g, b, 1.0f ).tex( BACKGROUND_END, BACKGROUND_START ).endVertex();
buffer.pos( transform, x, y + height, 0 ).color( r, g, b, 1.0f ).tex( BACKGROUND_START, BACKGROUND_END ).endVertex();
buffer.pos( transform, x + width, y + height, 0 ).color( r, g, b, 1.0f ).tex( BACKGROUND_END, BACKGROUND_END ).endVertex();
buffer.vertex( transform, x, y, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_START, BACKGROUND_START ).endVertex();
buffer.vertex( transform, x, y + height, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_START, BACKGROUND_END ).endVertex();
buffer.vertex( transform, x + width, y, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_END, BACKGROUND_START ).endVertex();
buffer.vertex( transform, x + width, y, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_END, BACKGROUND_START ).endVertex();
buffer.vertex( transform, x, y + height, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_START, BACKGROUND_END ).endVertex();
buffer.vertex( transform, x + width, y + height, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_END, BACKGROUND_END ).endVertex();
}
private static void drawQuad( Matrix4f transform, IVertexBuilder buffer, float x, float y, float width, float height, Palette palette, boolean greyscale, char colourIndex )
@@ -178,9 +178,9 @@ public final class FixedWidthFontRenderer
{
bindFont();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().getRenderTypeBuffers().getBufferSource();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().renderBuffers().bufferSource();
drawString( IDENTITY, ((IRenderTypeBuffer) renderer).getBuffer( TYPE ), x, y, text, textColour, backgroundColour, palette, greyscale, leftMarginSize, rightMarginSize );
renderer.finish();
renderer.endBatch();
}
public static void drawTerminalWithoutCursor(
@@ -263,10 +263,10 @@ public final class FixedWidthFontRenderer
{
bindFont();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().getRenderTypeBuffers().getBufferSource();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().renderBuffers().bufferSource();
IVertexBuilder buffer = renderer.getBuffer( TYPE );
drawTerminal( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize );
renderer.finish( TYPE );
renderer.endBatch( TYPE );
}
public static void drawTerminal(
@@ -287,9 +287,9 @@ public final class FixedWidthFontRenderer
{
bindFont();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().getRenderTypeBuffers().getBufferSource();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().renderBuffers().bufferSource();
drawEmptyTerminal( transform, renderer, x, y, width, height );
renderer.finish();
renderer.endBatch();
}
public static void drawEmptyTerminal( float x, float y, float width, float height )
@@ -305,7 +305,7 @@ public final class FixedWidthFontRenderer
private static void bindFont()
{
Minecraft.getInstance().getTextureManager().bindTexture( FONT );
Minecraft.getInstance().getTextureManager().bind( FONT );
RenderSystem.texParameter( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
}
@@ -315,26 +315,26 @@ public final class FixedWidthFontRenderer
private static final VertexFormat FORMAT = DefaultVertexFormats.POSITION_COLOR_TEX;
static final RenderType MAIN = RenderType.makeType(
static final RenderType MAIN = RenderType.create(
"terminal_font", FORMAT, GL_MODE, 1024,
false, false, // useDelegate, needsSorting
RenderType.State.getBuilder()
.texture( new RenderState.TextureState( FONT, false, false ) ) // blur, minimap
.alpha( DEFAULT_ALPHA )
.lightmap( LIGHTMAP_DISABLED )
.writeMask( COLOR_WRITE )
.build( false )
RenderType.State.builder()
.setTextureState( new RenderState.TextureState( FONT, false, false ) ) // blur, minimap
.setAlphaState( DEFAULT_ALPHA )
.setLightmapState( NO_LIGHTMAP )
.setWriteMaskState( COLOR_WRITE )
.createCompositeState( false )
);
static final RenderType BLOCKER = RenderType.makeType(
static final RenderType BLOCKER = RenderType.create(
"terminal_blocker", FORMAT, GL_MODE, 256,
false, false, // useDelegate, needsSorting
RenderType.State.getBuilder()
.texture( new RenderState.TextureState( FONT, false, false ) ) // blur, minimap
.alpha( DEFAULT_ALPHA )
.writeMask( DEPTH_WRITE )
.lightmap( LIGHTMAP_DISABLED )
.build( false )
RenderType.State.builder()
.setTextureState( new RenderState.TextureState( FONT, false, false ) ) // blur, minimap
.setAlphaState( DEFAULT_ALPHA )
.setWriteMaskState( DEPTH_WRITE )
.setLightmapState( NO_LIGHTMAP )
.createCompositeState( false )
);
private Type( String name, Runnable setup, Runnable destroy )

View File

@@ -74,18 +74,18 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
@Override
protected void init()
{
minecraft.keyboardListener.enableRepeatEvents( true );
minecraft.keyboardHandler.setSendRepeatsToGui( true );
int termPxWidth = termWidth * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = termHeight * FixedWidthFontRenderer.FONT_HEIGHT;
xSize = termPxWidth + MARGIN * 2 + BORDER * 2;
ySize = termPxHeight + MARGIN * 2 + BORDER * 2;
imageWidth = termPxWidth + MARGIN * 2 + BORDER * 2;
imageHeight = termPxHeight + MARGIN * 2 + BORDER * 2;
super.init();
terminal = new WidgetTerminal( minecraft, () -> computer, termWidth, termHeight, MARGIN, MARGIN, MARGIN, MARGIN );
terminalWrapper = new WidgetWrapper( terminal, MARGIN + BORDER + guiLeft, MARGIN + BORDER + guiTop, termPxWidth, termPxHeight );
terminalWrapper = new WidgetWrapper( terminal, MARGIN + BORDER + leftPos, MARGIN + BORDER + topPos, termPxWidth, termPxHeight );
children.add( terminalWrapper );
setFocused( terminalWrapper );
@@ -97,7 +97,7 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
super.removed();
children.remove( terminal );
terminal = null;
minecraft.keyboardListener.enableRepeatEvents( false );
minecraft.keyboardHandler.setSendRepeatsToGui( false );
}
@Override
@@ -120,14 +120,14 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
}
@Override
public void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
public void renderBg( float partialTicks, int mouseX, int mouseY )
{
// Draw terminal
terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
// Draw a border around the terminal
RenderSystem.color4f( 1, 1, 1, 1 );
minecraft.getTextureManager().bindTexture( ComputerBorderRenderer.getTexture( family ) );
minecraft.getTextureManager().bind( ComputerBorderRenderer.getTexture( family ) );
ComputerBorderRenderer.render(
terminalWrapper.getX() - MARGIN, terminalWrapper.getY() - MARGIN, getBlitOffset(),
terminalWrapper.getWidth() + MARGIN * 2, terminalWrapper.getHeight() + MARGIN * 2
@@ -139,7 +139,7 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
{
renderBackground();
super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY );
renderTooltip( mouseX, mouseY );
}
@Override

View File

@@ -22,19 +22,19 @@ public class GuiDiskDrive extends ContainerScreen<ContainerDiskDrive>
}
@Override
protected void drawGuiContainerForegroundLayer( int mouseX, int mouseY )
protected void renderLabels( int mouseX, int mouseY )
{
String title = this.title.getFormattedText();
font.drawString( title, (xSize - font.getStringWidth( title )) / 2.0f, 6, 0x404040 );
font.drawString( title, 8, ySize - 96 + 2, 0x404040 );
String title = this.title.getColoredString();
font.draw( title, (imageWidth - font.width( title )) / 2.0f, 6, 0x404040 );
font.draw( title, 8, imageHeight - 96 + 2, 0x404040 );
}
@Override
protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
protected void renderBg( float partialTicks, int mouseX, int mouseY )
{
RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTexture( BACKGROUND );
blit( guiLeft, guiTop, 0, 0, xSize, ySize );
minecraft.getTextureManager().bind( BACKGROUND );
blit( leftPos, topPos, 0, 0, imageWidth, imageHeight );
}
@Override
@@ -42,6 +42,6 @@ public class GuiDiskDrive extends ContainerScreen<ContainerDiskDrive>
{
renderBackground();
super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY );
renderTooltip( mouseX, mouseY );
}
}

View File

@@ -23,21 +23,21 @@ public class GuiPrinter extends ContainerScreen<ContainerPrinter>
}
@Override
protected void drawGuiContainerForegroundLayer( int mouseX, int mouseY )
protected void renderLabels( int mouseX, int mouseY )
{
String title = getTitle().getFormattedText();
font.drawString( title, (xSize - font.getStringWidth( title )) / 2.0f, 6, 0x404040 );
font.drawString( I18n.format( "container.inventory" ), 8, ySize - 96 + 2, 0x404040 );
String title = getTitle().getColoredString();
font.draw( title, (imageWidth - font.width( title )) / 2.0f, 6, 0x404040 );
font.draw( I18n.get( "container.inventory" ), 8, imageHeight - 96 + 2, 0x404040 );
}
@Override
protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
protected void renderBg( float partialTicks, int mouseX, int mouseY )
{
RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTexture( BACKGROUND );
blit( guiLeft, guiTop, 0, 0, xSize, ySize );
minecraft.getTextureManager().bind( BACKGROUND );
blit( leftPos, topPos, 0, 0, imageWidth, imageHeight );
if( getContainer().isPrinting() ) blit( guiLeft + 34, guiTop + 21, 176, 0, 25, 45 );
if( getMenu().isPrinting() ) blit( leftPos + 34, topPos + 21, 176, 0, 25, 45 );
}
@Override
@@ -45,6 +45,6 @@ public class GuiPrinter extends ContainerScreen<ContainerPrinter>
{
renderBackground();
super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY );
renderTooltip( mouseX, mouseY );
}
}

View File

@@ -24,29 +24,29 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
{
private static final Matrix4f IDENTITY = TransformationMatrix.identity().getMatrix();
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 )
{
super( container, player, title );
ySize = Y_SIZE;
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;
}
@@ -91,16 +91,16 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
}
@Override
public void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
public void renderBg( float partialTicks, int mouseX, int mouseY )
{
// Draw the printout
RenderSystem.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
RenderSystem.enableDepthTest();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().getRenderTypeBuffers().getBufferSource();
drawBorder( IDENTITY, renderer, guiLeft, guiTop, getBlitOffset(), m_page, m_pages, m_book );
drawText( IDENTITY, renderer, guiLeft + X_TEXT_MARGIN, guiTop + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours );
renderer.finish();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().renderBuffers().bufferSource();
drawBorder( IDENTITY, renderer, leftPos, topPos, getBlitOffset(), page, pages, book );
drawText( IDENTITY, renderer, leftPos + X_TEXT_MARGIN, topPos + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * page, text, colours );
renderer.endBatch();
}
@Override
@@ -112,6 +112,6 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
setBlitOffset( getBlitOffset() + 1 );
super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY );
renderTooltip( mouseX, mouseY );
}
}

View File

@@ -20,13 +20,13 @@ import org.lwjgl.glfw.GLFW;
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;
@@ -35,30 +35,30 @@ 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();
xSize = 254;
ySize = 217;
imageWidth = 254;
imageHeight = 217;
}
@Override
protected void init()
{
super.init();
minecraft.keyboardListener.enableRepeatEvents( true );
minecraft.keyboardHandler.setSendRepeatsToGui( true );
int termPxWidth = ComputerCraft.turtleTermWidth * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = ComputerCraft.turtleTermHeight * FixedWidthFontRenderer.FONT_HEIGHT;
terminal = new WidgetTerminal(
minecraft, () -> m_computer,
minecraft, () -> computer,
ComputerCraft.turtleTermWidth,
ComputerCraft.turtleTermHeight,
2, 2, 2, 2
);
terminalWrapper = new WidgetWrapper( terminal, 2 + 8 + guiLeft, 2 + 8 + guiTop, termPxWidth, termPxHeight );
terminalWrapper = new WidgetWrapper( terminal, 2 + 8 + leftPos, 2 + 8 + topPos, termPxWidth, termPxHeight );
children.add( terminalWrapper );
setFocused( terminalWrapper );
@@ -70,7 +70,7 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
super.removed();
children.remove( terminal );
terminal = null;
minecraft.keyboardListener.enableRepeatEvents( false );
minecraft.keyboardHandler.setSendRepeatsToGui( false );
}
@Override
@@ -95,28 +95,28 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
private void drawSelectionSlot( boolean advanced )
{
// Draw selection slot
int slot = m_container.getSelectedSlot();
int slot = container.getSelectedSlot();
if( slot >= 0 )
{
RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
int slotX = slot % 4;
int slotY = slot / 4;
minecraft.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
blit( guiLeft + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18, guiTop + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18, 0, 217, 24, 24 );
minecraft.getTextureManager().bind( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
blit( leftPos + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18, topPos + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18, 0, 217, 24, 24 );
}
}
@Override
protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
protected void renderBg( float partialTicks, int mouseX, int mouseY )
{
// Draw term
boolean advanced = m_family == ComputerFamily.ADVANCED;
boolean advanced = family == ComputerFamily.ADVANCED;
terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
// Draw border/inventory
RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
blit( guiLeft, guiTop, 0, 0, xSize, ySize );
minecraft.getTextureManager().bind( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
blit( leftPos, topPos, 0, 0, imageWidth, imageHeight );
drawSelectionSlot( advanced );
}
@@ -126,7 +126,7 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
{
renderBackground();
super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY );
renderTooltip( mouseX, mouseY );
}
@Override

View File

@@ -91,7 +91,7 @@ public class WidgetTerminal implements IGuiEventListener
case GLFW.GLFW_KEY_V:
// Ctrl+V for paste
String clipboard = client.keyboardListener.getClipboardString();
String clipboard = client.keyboardHandler.getClipboard();
if( clipboard != null )
{
// Clip to the first occurrence of \r or \n
@@ -111,7 +111,7 @@ public class WidgetTerminal implements IGuiEventListener
}
// Filter the string
clipboard = SharedConstants.filterAllowedCharacters( clipboard );
clipboard = SharedConstants.filterText( clipboard );
if( !clipboard.isEmpty() )
{
// Clip to 512 characters and queue the event

View File

@@ -35,12 +35,12 @@ public final class ComputerCraftProxyClient
registerContainers();
// While turtles themselves are not transparent, their upgrades may be.
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.TURTLE_NORMAL.get(), RenderType.getTranslucent() );
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.TURTLE_ADVANCED.get(), RenderType.getTranslucent() );
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.TURTLE_NORMAL.get(), RenderType.translucent() );
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.TURTLE_ADVANCED.get(), RenderType.translucent() );
// Monitors' textures have transparent fronts and so count as cutouts.
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.MONITOR_NORMAL.get(), RenderType.getCutout() );
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.MONITOR_ADVANCED.get(), RenderType.getCutout() );
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.MONITOR_NORMAL.get(), RenderType.cutout() );
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.MONITOR_ADVANCED.get(), RenderType.cutout() );
// Setup TESRs
ClientRegistry.bindTileEntityRenderer( Registry.ModTiles.MONITOR_NORMAL.get(), TileEntityMonitorRenderer::new );
@@ -55,15 +55,15 @@ public final class ComputerCraftProxyClient
{
// My IDE doesn't think so, but we do actually need these generics.
ScreenManager.<ContainerComputer, GuiComputer<ContainerComputer>>registerFactory( Registry.ModContainers.COMPUTER.get(), GuiComputer::create );
ScreenManager.<ContainerPocketComputer, GuiComputer<ContainerPocketComputer>>registerFactory( Registry.ModContainers.POCKET_COMPUTER.get(), GuiComputer::createPocket );
ScreenManager.registerFactory( Registry.ModContainers.TURTLE.get(), GuiTurtle::new );
ScreenManager.<ContainerComputer, GuiComputer<ContainerComputer>>register( Registry.ModContainers.COMPUTER.get(), GuiComputer::create );
ScreenManager.<ContainerPocketComputer, GuiComputer<ContainerPocketComputer>>register( Registry.ModContainers.POCKET_COMPUTER.get(), GuiComputer::createPocket );
ScreenManager.register( Registry.ModContainers.TURTLE.get(), GuiTurtle::new );
ScreenManager.registerFactory( Registry.ModContainers.PRINTER.get(), GuiPrinter::new );
ScreenManager.registerFactory( Registry.ModContainers.DISK_DRIVE.get(), GuiDiskDrive::new );
ScreenManager.registerFactory( Registry.ModContainers.PRINTOUT.get(), GuiPrintout::new );
ScreenManager.register( Registry.ModContainers.PRINTER.get(), GuiPrinter::new );
ScreenManager.register( Registry.ModContainers.DISK_DRIVE.get(), GuiDiskDrive::new );
ScreenManager.register( Registry.ModContainers.PRINTOUT.get(), GuiPrintout::new );
ScreenManager.<ContainerViewComputer, GuiComputer<ContainerViewComputer>>registerFactory( Registry.ModContainers.VIEW_COMPUTER.get(), GuiComputer::createView );
ScreenManager.<ContainerViewComputer, GuiComputer<ContainerViewComputer>>register( Registry.ModContainers.VIEW_COMPUTER.get(), GuiComputer::createView );
}
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
@@ -72,7 +72,7 @@ public final class ComputerCraftProxyClient
@SubscribeEvent
public static void onWorldUnload( WorldEvent.Unload event )
{
if( event.getWorld().isRemote() )
if( event.getWorld().isClientSide() )
{
ClientMonitor.destroyAll();
}

View File

@@ -45,35 +45,35 @@ public final class CableHighlightRenderer
public static void drawHighlight( DrawHighlightEvent.HighlightBlock event )
{
BlockRayTraceResult hit = event.getTarget();
BlockPos pos = hit.getPos();
World world = event.getInfo().getRenderViewEntity().getEntityWorld();
BlockPos pos = hit.getBlockPos();
World world = event.getInfo().getEntity().getCommandSenderWorld();
ActiveRenderInfo info = event.getInfo();
BlockState state = world.getBlockState( pos );
// We only care about instances with both cable and modem.
if( state.getBlock() != Registry.ModBlocks.CABLE.get() || state.get( BlockCable.MODEM ).getFacing() == null || !state.get( BlockCable.CABLE ) )
if( state.getBlock() != Registry.ModBlocks.CABLE.get() || state.getValue( BlockCable.MODEM ).getFacing() == null || !state.getValue( BlockCable.CABLE ) )
{
return;
}
event.setCanceled( true );
VoxelShape shape = WorldUtil.isVecInside( CableShapes.getModemShape( state ), hit.getHitVec().subtract( pos.getX(), pos.getY(), pos.getZ() ) )
VoxelShape shape = WorldUtil.isVecInside( CableShapes.getModemShape( state ), hit.getLocation().subtract( pos.getX(), pos.getY(), pos.getZ() ) )
? CableShapes.getModemShape( state )
: CableShapes.getCableShape( state );
Vec3d cameraPos = info.getProjectedView();
double xOffset = pos.getX() - cameraPos.getX();
double yOffset = pos.getY() - cameraPos.getY();
double zOffset = pos.getZ() - cameraPos.getZ();
Vec3d cameraPos = info.getPosition();
double xOffset = pos.getX() - cameraPos.x();
double yOffset = pos.getY() - cameraPos.y();
double zOffset = pos.getZ() - cameraPos.z();
IVertexBuilder buffer = event.getBuffers().getBuffer( RenderType.getLines() );
Matrix4f matrix4f = event.getMatrix().getLast().getMatrix();
shape.forEachEdge( ( x1, y1, z1, x2, y2, z2 ) -> {
buffer.pos( matrix4f, (float) (x1 + xOffset), (float) (y1 + yOffset), (float) (z1 + zOffset) )
IVertexBuilder buffer = event.getBuffers().getBuffer( RenderType.lines() );
Matrix4f matrix4f = event.getMatrix().last().pose();
shape.forAllEdges( ( x1, y1, z1, x2, y2, z2 ) -> {
buffer.vertex( matrix4f, (float) (x1 + xOffset), (float) (y1 + yOffset), (float) (z1 + zOffset) )
.color( 0, 0, 0, 0.4f ).endVertex();
buffer.pos( matrix4f, (float) (x2 + xOffset), (float) (y2 + yOffset), (float) (z2 + zOffset) )
buffer.vertex( matrix4f, (float) (x2 + xOffset), (float) (y2 + yOffset), (float) (z2 + zOffset) )
.color( 0, 0, 0, 0.4f ).endVertex();
} );
}

View File

@@ -85,13 +85,13 @@ public class ComputerBorderRenderer
public static void render( int x, int y, int z, int width, int height )
{
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
BufferBuilder buffer = tessellator.getBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR_TEX );
render( IDENTITY, buffer, x, y, z, width, height );
RenderSystem.enableAlphaTest();
tessellator.draw();
tessellator.end();
}
public static void render( Matrix4f transform, IVertexBuilder buffer, int x, int y, int z, int width, int height )
@@ -166,9 +166,9 @@ public class ComputerBorderRenderer
private void renderTexture( int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight )
{
builder.pos( transform, x, y + height, z ).color( r, g, b, 1.0f ).tex( u * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).endVertex();
builder.pos( transform, x + width, y + height, z ).color( r, g, b, 1.0f ).tex( (u + textureWidth) * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).endVertex();
builder.pos( transform, x + width, y, z ).color( r, g, b, 1.0f ).tex( (u + textureWidth) * TEX_SCALE, v * TEX_SCALE ).endVertex();
builder.pos( transform, x, y, z ).color( r, g, b, 1.0f ).tex( u * TEX_SCALE, v * TEX_SCALE ).endVertex();
builder.vertex( transform, x, y + height, z ).color( r, g, b, 1.0f ).uv( u * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).endVertex();
builder.vertex( transform, x + width, y + height, z ).color( r, g, b, 1.0f ).uv( (u + textureWidth) * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).endVertex();
builder.vertex( transform, x + width, y, z ).color( r, g, b, 1.0f ).uv( (u + textureWidth) * TEX_SCALE, v * TEX_SCALE ).endVertex();
builder.vertex( transform, x, y, z ).color( r, g, b, 1.0f ).uv( u * TEX_SCALE, v * TEX_SCALE ).endVertex();
}
}

View File

@@ -33,8 +33,8 @@ public abstract class ItemMapLikeRenderer
{
PlayerEntity player = Minecraft.getInstance().player;
transform.push();
if( hand == Hand.MAIN_HAND && player.getHeldItemOffhand().isEmpty() )
transform.pushPose();
if( hand == Hand.MAIN_HAND && player.getOffhandItem().isEmpty() )
{
renderItemFirstPersonCenter( transform, render, lightTexture, pitch, equipProgress, swingProgress, stack );
}
@@ -42,11 +42,11 @@ public abstract class ItemMapLikeRenderer
{
renderItemFirstPersonSide(
transform, render, lightTexture,
hand == Hand.MAIN_HAND ? player.getPrimaryHand() : player.getPrimaryHand().opposite(),
hand == Hand.MAIN_HAND ? player.getMainArm() : player.getMainArm().getOpposite(),
equipProgress, swingProgress, stack
);
}
transform.pop();
transform.popPose();
}
/**
@@ -70,15 +70,15 @@ public abstract class ItemMapLikeRenderer
// If the player is not invisible then render a single arm
if( !minecraft.player.isInvisible() )
{
transform.push();
transform.rotate( Vector3f.ZP.rotationDegrees( offset * 10f ) );
minecraft.getFirstPersonRenderer().renderArmFirstPerson( transform, render, combinedLight, equipProgress, swingProgress, side );
transform.pop();
transform.pushPose();
transform.mulPose( Vector3f.ZP.rotationDegrees( offset * 10f ) );
minecraft.getItemInHandRenderer().renderPlayerArm( transform, render, combinedLight, equipProgress, swingProgress, side );
transform.popPose();
}
// Setup the appropriate transformations. This is just copied from the
// corresponding method in ItemRenderer.
transform.push();
transform.pushPose();
transform.translate( offset * 0.51f, -0.08f + equipProgress * -1.2f, -0.75f );
float f1 = MathHelper.sqrt( swingProgress );
float f2 = MathHelper.sin( f1 * (float) Math.PI );
@@ -86,12 +86,12 @@ public abstract class ItemMapLikeRenderer
float f4 = 0.4f * MathHelper.sin( f1 * ((float) Math.PI * 2f) );
float f5 = -0.3f * MathHelper.sin( swingProgress * (float) Math.PI );
transform.translate( offset * f3, f4 - 0.3f * f2, f5 );
transform.rotate( Vector3f.XP.rotationDegrees( f2 * -45f ) );
transform.rotate( Vector3f.YP.rotationDegrees( offset * f2 * -30f ) );
transform.mulPose( Vector3f.XP.rotationDegrees( f2 * -45f ) );
transform.mulPose( Vector3f.YP.rotationDegrees( offset * f2 * -30f ) );
renderItem( transform, render, stack );
transform.pop();
transform.popPose();
}
/**
@@ -109,7 +109,7 @@ public abstract class ItemMapLikeRenderer
private void renderItemFirstPersonCenter( MatrixStack transform, IRenderTypeBuffer render, int combinedLight, float pitch, float equipProgress, float swingProgress, ItemStack stack )
{
Minecraft minecraft = Minecraft.getInstance();
FirstPersonRenderer renderer = minecraft.getFirstPersonRenderer();
FirstPersonRenderer renderer = minecraft.getItemInHandRenderer();
// Setup the appropriate transformations. This is just copied from the
// corresponding method in ItemRenderer.
@@ -118,20 +118,20 @@ public abstract class ItemMapLikeRenderer
float tZ = -0.4f * MathHelper.sin( swingRt * (float) Math.PI );
transform.translate( 0, -tX / 2, tZ );
float pitchAngle = renderer.getMapAngleFromPitch( pitch );
float pitchAngle = renderer.calculateMapTilt( pitch );
transform.translate( 0, 0.04F + equipProgress * -1.2f + pitchAngle * -0.5f, -0.72f );
transform.rotate( Vector3f.XP.rotationDegrees( pitchAngle * -85.0f ) );
transform.mulPose( Vector3f.XP.rotationDegrees( pitchAngle * -85.0f ) );
if( !minecraft.player.isInvisible() )
{
transform.push();
transform.rotate( Vector3f.YP.rotationDegrees( 90.0F ) );
renderer.renderArm( transform, render, combinedLight, HandSide.RIGHT );
renderer.renderArm( transform, render, combinedLight, HandSide.LEFT );
transform.pop();
transform.pushPose();
transform.mulPose( Vector3f.YP.rotationDegrees( 90.0F ) );
renderer.renderMapHand( transform, render, combinedLight, HandSide.RIGHT );
renderer.renderMapHand( transform, render, combinedLight, HandSide.LEFT );
transform.popPose();
}
float rX = MathHelper.sin( swingRt * (float) Math.PI );
transform.rotate( Vector3f.XP.rotationDegrees( rX * 20.0F ) );
transform.mulPose( Vector3f.XP.rotationDegrees( rX * 20.0F ) );
transform.scale( 2.0F, 2.0F, 2.0F );
renderItem( transform, render, stack );

View File

@@ -79,9 +79,9 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
// Setup various transformations. Note that these are partially adapted from the corresponding method
// in ItemRenderer
transform.push();
transform.rotate( Vector3f.YP.rotationDegrees( 180f ) );
transform.rotate( Vector3f.ZP.rotationDegrees( 180f ) );
transform.pushPose();
transform.mulPose( Vector3f.YP.rotationDegrees( 180f ) );
transform.mulPose( Vector3f.ZP.rotationDegrees( 180f ) );
transform.scale( 0.5f, 0.5f, 0.5f );
float scale = 0.75f / Math.max( width + BORDER * 2, height + BORDER * 2 + LIGHT_HEIGHT );
@@ -93,7 +93,7 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
ComputerFamily family = item.getFamily();
int frameColour = item.getColour( stack );
Matrix4f matrix = transform.getLast().getMatrix();
Matrix4f matrix = transform.last().pose();
renderFrame( matrix, family, frameColour, width, height );
// Render the light
@@ -110,26 +110,26 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
FixedWidthFontRenderer.drawEmptyTerminal( matrix, 0, 0, width, height );
}
transform.pop();
transform.popPose();
}
private static void renderFrame( Matrix4f transform, ComputerFamily family, int colour, int width, int height )
{
RenderSystem.enableBlend();
Minecraft.getInstance().getTextureManager()
.bindTexture( colour != -1 ? ComputerBorderRenderer.BACKGROUND_COLOUR : ComputerBorderRenderer.getTexture( family ) );
.bind( colour != -1 ? ComputerBorderRenderer.BACKGROUND_COLOUR : ComputerBorderRenderer.getTexture( family ) );
float r = ((colour >>> 16) & 0xFF) / 255.0f;
float g = ((colour >>> 8) & 0xFF) / 255.0f;
float b = (colour & 0xFF) / 255.0f;
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
BufferBuilder buffer = tessellator.getBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR_TEX );
ComputerBorderRenderer.render( transform, buffer, 0, 0, 0, width, height, LIGHT_HEIGHT, r, g, b );
tessellator.draw();
tessellator.end();
}
private static void renderLight( Matrix4f transform, int colour, int width, int height )
@@ -141,14 +141,14 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
float b = (colour & 0xFF) / 255.0f;
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
BufferBuilder buffer = tessellator.getBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR );
buffer.pos( transform, width - LIGHT_HEIGHT * 2, height + LIGHT_HEIGHT + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.pos( transform, width, height + LIGHT_HEIGHT + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.pos( transform, width, height + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.pos( transform, width - LIGHT_HEIGHT * 2, height + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.vertex( transform, width - LIGHT_HEIGHT * 2, height + LIGHT_HEIGHT + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.vertex( transform, width, height + LIGHT_HEIGHT + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.vertex( transform, width, height + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.vertex( transform, width - LIGHT_HEIGHT * 2, height + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
tessellator.draw();
tessellator.end();
RenderSystem.enableTexture();
}
}

View File

@@ -52,7 +52,7 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
@Override
protected void renderItem( MatrixStack transform, IRenderTypeBuffer render, ItemStack stack )
{
transform.rotate( Vector3f.XP.rotationDegrees( 180f ) );
transform.mulPose( Vector3f.XP.rotationDegrees( 180f ) );
transform.scale( 0.42f, 0.42f, -0.42f );
transform.translate( -0.5f, -0.48f, 0.0f );
@@ -70,7 +70,7 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
// Move a little bit forward to ensure we're not clipping with the frame
transform.translate( 0.0f, 0.0f, -0.001f );
transform.rotate( Vector3f.ZP.rotationDegrees( 180f ) );
transform.mulPose( Vector3f.ZP.rotationDegrees( 180f ) );
transform.scale( 0.95f, 0.95f, -0.95f );
transform.translate( -0.5f, -0.5f, 0.0f );
@@ -104,7 +104,7 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
transform.scale( scale, scale, scale );
transform.translate( (max - width) / 2.0, (max - height) / 2.0, 0.0 );
Matrix4f matrix = transform.getLast().getMatrix();
Matrix4f matrix = transform.last().pose();
drawBorder( matrix, render, 0, 0, -0.01f, 0, pages, book );
drawText( matrix, render,
X_TEXT_MARGIN, Y_TEXT_MARGIN, 0, ItemPrintout.getText( stack ), ItemPrintout.getColours( stack )

View File

@@ -40,12 +40,12 @@ public final class MonitorHighlightRenderer
public static void drawHighlight( DrawHighlightEvent.HighlightBlock event )
{
// Preserve normal behaviour when crouching.
if( event.getInfo().getRenderViewEntity().isCrouching() ) return;
if( event.getInfo().getEntity().isCrouching() ) return;
World world = event.getInfo().getRenderViewEntity().getEntityWorld();
BlockPos pos = event.getTarget().getPos();
World world = event.getInfo().getEntity().getCommandSenderWorld();
BlockPos pos = event.getTarget().getBlockPos();
TileEntity tile = world.getTileEntity( pos );
TileEntity tile = world.getBlockEntity( pos );
if( !(tile instanceof TileMonitor) ) return;
TileMonitor monitor = (TileMonitor) tile;
@@ -61,13 +61,13 @@ public final class MonitorHighlightRenderer
if( monitor.getYIndex() != monitor.getHeight() - 1 ) faces.remove( monitor.getDown() );
MatrixStack transformStack = event.getMatrix();
Vec3d cameraPos = event.getInfo().getProjectedView();
transformStack.push();
transformStack.translate( pos.getX() - cameraPos.getX(), pos.getY() - cameraPos.getY(), pos.getZ() - cameraPos.getZ() );
Vec3d cameraPos = event.getInfo().getPosition();
transformStack.pushPose();
transformStack.translate( pos.getX() - cameraPos.x(), pos.getY() - cameraPos.y(), pos.getZ() - cameraPos.z() );
// I wish I could think of a better way to do this
IVertexBuilder buffer = event.getBuffers().getBuffer( RenderType.getLines() );
Matrix4f transform = transformStack.getLast().getMatrix();
IVertexBuilder buffer = event.getBuffers().getBuffer( RenderType.lines() );
Matrix4f transform = transformStack.last().pose();
if( faces.contains( NORTH ) || faces.contains( WEST ) ) line( buffer, transform, 0, 0, 0, UP );
if( faces.contains( SOUTH ) || faces.contains( WEST ) ) line( buffer, transform, 0, 0, 1, UP );
if( faces.contains( NORTH ) || faces.contains( EAST ) ) line( buffer, transform, 1, 0, 0, UP );
@@ -81,16 +81,16 @@ public final class MonitorHighlightRenderer
if( faces.contains( WEST ) || faces.contains( UP ) ) line( buffer, transform, 0, 1, 0, SOUTH );
if( faces.contains( EAST ) || faces.contains( UP ) ) line( buffer, transform, 1, 1, 0, SOUTH );
transformStack.pop();
transformStack.popPose();
}
private static void line( IVertexBuilder buffer, Matrix4f transform, float x, float y, float z, Direction direction )
{
buffer.pos( transform, x, y, z ).color( 0, 0, 0, 0.4f ).endVertex();
buffer.pos( transform,
x + direction.getXOffset(),
y + direction.getYOffset(),
z + direction.getZOffset()
buffer.vertex( transform, x, y, z ).color( 0, 0, 0, 0.4f ).endVertex();
buffer.vertex( transform,
x + direction.getStepX(),
y + direction.getStepY(),
z + direction.getStepZ()
).color( 0, 0, 0, 0.4f ).endVertex();
}
}

View File

@@ -42,7 +42,7 @@ class MonitorTextureBufferShader
static void setupUniform( Matrix4f transform, int width, int height, Palette palette, boolean greyscale )
{
MATRIX_BUFFER.rewind();
transform.write( MATRIX_BUFFER );
transform.store( MATRIX_BUFFER );
MATRIX_BUFFER.rewind();
RenderSystem.glUniformMatrix4( uniformMv, false, MATRIX_BUFFER );
@@ -71,7 +71,7 @@ class MonitorTextureBufferShader
{
if( initialised )
{
if( ok ) GlStateManager.useProgram( program );
if( ok ) GlStateManager._glUseProgram( program );
return ok;
}
@@ -94,14 +94,14 @@ class MonitorTextureBufferShader
int vertexShader = loadShader( GL20.GL_VERTEX_SHADER, "assets/computercraft/shaders/monitor.vert" );
int fragmentShader = loadShader( GL20.GL_FRAGMENT_SHADER, "assets/computercraft/shaders/monitor.frag" );
program = GlStateManager.createProgram();
GlStateManager.attachShader( program, vertexShader );
GlStateManager.attachShader( program, fragmentShader );
program = GlStateManager.glCreateProgram();
GlStateManager.glAttachShader( program, vertexShader );
GlStateManager.glAttachShader( program, fragmentShader );
GL20.glBindAttribLocation( program, 0, "v_pos" );
GlStateManager.linkProgram( program );
boolean ok = GlStateManager.getProgram( program, GL20.GL_LINK_STATUS ) != 0;
String log = GlStateManager.getProgramInfoLog( program, Short.MAX_VALUE ).trim();
GlStateManager.glLinkProgram( program );
boolean ok = GlStateManager.glGetProgrami( program, GL20.GL_LINK_STATUS ) != 0;
String log = GlStateManager.glGetProgramInfoLog( program, Short.MAX_VALUE ).trim();
if( !Strings.isNullOrEmpty( log ) )
{
ComputerCraft.log.warn( "Problems when linking monitor shader: {}", log );
@@ -109,8 +109,8 @@ class MonitorTextureBufferShader
GL20.glDetachShader( program, vertexShader );
GL20.glDetachShader( program, fragmentShader );
GlStateManager.deleteShader( vertexShader );
GlStateManager.deleteShader( fragmentShader );
GlStateManager.glDeleteShader( vertexShader );
GlStateManager.glDeleteShader( fragmentShader );
if( !ok ) return false;
@@ -137,13 +137,13 @@ class MonitorTextureBufferShader
if( stream == null ) throw new IllegalArgumentException( "Cannot find " + path );
String contents = TextureUtil.readResourceAsString( stream );
int shader = GlStateManager.createShader( kind );
int shader = GlStateManager.glCreateShader( kind );
GlStateManager.shaderSource( shader, contents );
GlStateManager.compileShader( shader );
GlStateManager.glShaderSource( shader, contents );
GlStateManager.glCompileShader( shader );
boolean ok = GlStateManager.getShader( shader, GL20.GL_COMPILE_STATUS ) != 0;
String log = GlStateManager.getShaderInfoLog( shader, Short.MAX_VALUE ).trim();
boolean ok = GlStateManager.glGetShaderi( shader, GL20.GL_COMPILE_STATUS ) != 0;
String log = GlStateManager.glGetShaderInfoLog( shader, Short.MAX_VALUE ).trim();
if( !Strings.isNullOrEmpty( log ) )
{
ComputerCraft.log.warn( "Problems when loading monitor shader {}: {}", path, log );
@@ -155,7 +155,7 @@ class MonitorTextureBufferShader
private static int getUniformLocation( int program, String name )
{
int uniform = GlStateManager.getUniformLocation( program, name );
int uniform = GlStateManager._glGetUniformLocation( program, name );
if( uniform == -1 ) throw new IllegalStateException( "Cannot find uniform " + name );
return uniform;
}

View File

@@ -146,18 +146,18 @@ public final class PrintoutRenderer
private static void drawTexture( Matrix4f matrix, IVertexBuilder buffer, float x, float y, float z, float u, float v, float width, float height )
{
buffer.pos( matrix, x, y + height, z ).tex( u / BG_SIZE, (v + height) / BG_SIZE ).endVertex();
buffer.pos( matrix, x + width, y + height, z ).tex( (u + width) / BG_SIZE, (v + height) / BG_SIZE ).endVertex();
buffer.pos( matrix, x + width, y, z ).tex( (u + width) / BG_SIZE, v / BG_SIZE ).endVertex();
buffer.pos( matrix, x, y, z ).tex( u / BG_SIZE, v / BG_SIZE ).endVertex();
buffer.vertex( matrix, x, y + height, z ).uv( u / BG_SIZE, (v + height) / BG_SIZE ).endVertex();
buffer.vertex( matrix, x + width, y + height, z ).uv( (u + width) / BG_SIZE, (v + height) / BG_SIZE ).endVertex();
buffer.vertex( matrix, x + width, y, z ).uv( (u + width) / BG_SIZE, v / BG_SIZE ).endVertex();
buffer.vertex( matrix, x, y, z ).uv( u / BG_SIZE, v / BG_SIZE ).endVertex();
}
private static void drawTexture( Matrix4f matrix, IVertexBuilder buffer, float x, float y, float z, float width, float height, float u, float v, float tWidth, float tHeight )
{
buffer.pos( matrix, x, y + height, z ).tex( u / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex();
buffer.pos( matrix, x + width, y + height, z ).tex( (u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex();
buffer.pos( matrix, x + width, y, z ).tex( (u + tWidth) / BG_SIZE, v / BG_SIZE ).endVertex();
buffer.pos( matrix, x, y, z ).tex( u / BG_SIZE, v / BG_SIZE ).endVertex();
buffer.vertex( matrix, x, y + height, z ).uv( u / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex();
buffer.vertex( matrix, x + width, y + height, z ).uv( (u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex();
buffer.vertex( matrix, x + width, y, z ).uv( (u + tWidth) / BG_SIZE, v / BG_SIZE ).endVertex();
buffer.vertex( matrix, x, y, z ).uv( u / BG_SIZE, v / BG_SIZE ).endVertex();
}
public static float offsetAt( int page )
@@ -167,14 +167,14 @@ public final class PrintoutRenderer
private static final class Type extends RenderState
{
static final RenderType TYPE = RenderType.makeType(
static final RenderType TYPE = RenderType.create(
"printout_background", DefaultVertexFormats.POSITION_TEX, GL11.GL_QUADS, 1024,
false, false, // useDelegate, needsSorting
RenderType.State.getBuilder()
.texture( new RenderState.TextureState( BG, false, false ) ) // blur, minimap
.alpha( DEFAULT_ALPHA )
.lightmap( LIGHTMAP_DISABLED )
.build( false )
RenderType.State.builder()
.setTextureState( new RenderState.TextureState( BG, false, false ) ) // blur, minimap
.setAlphaState( DEFAULT_ALPHA )
.setLightmapState( NO_LIGHTMAP )
.createCompositeState( false )
);
private Type( String name, Runnable setup, Runnable destroy )

View File

@@ -58,7 +58,7 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
if( originTerminal == null ) return;
TileMonitor origin = originTerminal.getOrigin();
BlockPos monitorPos = monitor.getPos();
BlockPos monitorPos = monitor.getBlockPos();
// Ensure each monitor terminal is rendered only once. We allow rendering a specific tile
// multiple times in a single frame to ensure compatibility with shaders which may run a
@@ -72,24 +72,24 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
originTerminal.lastRenderFrame = renderFrame;
originTerminal.lastRenderPos = monitorPos;
BlockPos originPos = origin.getPos();
BlockPos originPos = origin.getBlockPos();
// Determine orientation
Direction dir = origin.getDirection();
Direction front = origin.getFront();
float yaw = dir.getHorizontalAngle();
float yaw = dir.toYRot();
float pitch = DirectionUtil.toPitchAngle( front );
// Setup initial transform
transform.push();
transform.pushPose();
transform.translate(
originPos.getX() - monitorPos.getX() + 0.5,
originPos.getY() - monitorPos.getY() + 0.5,
originPos.getZ() - monitorPos.getZ() + 0.5
);
transform.rotate( Vector3f.YN.rotationDegrees( yaw ) );
transform.rotate( Vector3f.XP.rotationDegrees( pitch ) );
transform.mulPose( Vector3f.YN.rotationDegrees( yaw ) );
transform.mulPose( Vector3f.XP.rotationDegrees( pitch ) );
transform.translate(
-0.5 + TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN,
origin.getHeight() - 0.5 - (TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN) + 0,
@@ -107,10 +107,10 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
int pixelWidth = width * FONT_WIDTH, pixelHeight = height * FONT_HEIGHT;
double xScale = xSize / pixelWidth;
double yScale = ySize / pixelHeight;
transform.push();
transform.pushPose();
transform.scale( (float) xScale, (float) -yScale, 1.0f );
Matrix4f matrix = transform.getLast().getMatrix();
Matrix4f matrix = transform.last().pose();
// Sneaky hack here: we get a buffer now in order to flush existing ones and set up the appropriate
// render state. I've no clue how well this'll work in future versions of Minecraft, but it does the trick
@@ -124,24 +124,24 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
// reasonable.
FixedWidthFontRenderer.drawCursor( matrix, buffer, 0, 0, terminal, !originTerminal.isColour() );
transform.pop();
transform.popPose();
}
else
{
FixedWidthFontRenderer.drawEmptyTerminal(
transform.getLast().getMatrix(), renderer,
transform.last().pose(), renderer,
-MARGIN, MARGIN,
(float) (xSize + 2 * MARGIN), (float) -(ySize + MARGIN * 2)
);
}
FixedWidthFontRenderer.drawBlocker(
transform.getLast().getMatrix(), renderer,
transform.last().pose(), renderer,
(float) -TileMonitor.RENDER_MARGIN, (float) TileMonitor.RENDER_MARGIN,
(float) (xSize + 2 * TileMonitor.RENDER_MARGIN), (float) -(ySize + TileMonitor.RENDER_MARGIN * 2)
);
transform.pop();
transform.popPose();
}
private static void renderTerminal( Matrix4f matrix, ClientMonitor monitor, float xMargin, float yMargin )
@@ -166,7 +166,7 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
int size = width * height * 3;
if( tboContents == null || tboContents.capacity() < size )
{
tboContents = GLAllocation.createDirectByteBuffer( size );
tboContents = GLAllocation.createByteBuffer( size );
}
ByteBuffer monitorBuffer = tboContents;
@@ -183,28 +183,28 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
}
monitorBuffer.flip();
GlStateManager.bindBuffer( GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer );
GlStateManager.bufferData( GL31.GL_TEXTURE_BUFFER, monitorBuffer, GL20.GL_STATIC_DRAW );
GlStateManager.bindBuffer( GL31.GL_TEXTURE_BUFFER, 0 );
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer );
GlStateManager._glBufferData( GL31.GL_TEXTURE_BUFFER, monitorBuffer, GL20.GL_STATIC_DRAW );
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, 0 );
}
// Nobody knows what they're doing!
GlStateManager.activeTexture( MonitorTextureBufferShader.TEXTURE_INDEX );
GlStateManager._activeTexture( MonitorTextureBufferShader.TEXTURE_INDEX );
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, monitor.tboTexture );
GlStateManager.activeTexture( GL13.GL_TEXTURE0 );
GlStateManager._activeTexture( GL13.GL_TEXTURE0 );
MonitorTextureBufferShader.setupUniform( matrix, width, height, terminal.getPalette(), !monitor.isColour() );
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
BufferBuilder buffer = tessellator.getBuilder();
buffer.begin( GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION );
buffer.pos( -xMargin, -yMargin, 0 ).endVertex();
buffer.pos( -xMargin, pixelHeight + yMargin, 0 ).endVertex();
buffer.pos( pixelWidth + xMargin, -yMargin, 0 ).endVertex();
buffer.pos( pixelWidth + xMargin, pixelHeight + yMargin, 0 ).endVertex();
tessellator.draw();
buffer.vertex( -xMargin, -yMargin, 0 ).endVertex();
buffer.vertex( -xMargin, pixelHeight + yMargin, 0 ).endVertex();
buffer.vertex( pixelWidth + xMargin, -yMargin, 0 ).endVertex();
buffer.vertex( pixelWidth + xMargin, pixelHeight + yMargin, 0 ).endVertex();
tessellator.end();
GlStateManager.useProgram( 0 );
GlStateManager._glUseProgram( 0 );
break;
}
@@ -214,22 +214,22 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
if( redraw )
{
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder builder = tessellator.getBuffer();
builder.begin( FixedWidthFontRenderer.TYPE.getDrawMode(), FixedWidthFontRenderer.TYPE.getVertexFormat() );
BufferBuilder builder = tessellator.getBuilder();
builder.begin( FixedWidthFontRenderer.TYPE.mode(), FixedWidthFontRenderer.TYPE.format() );
FixedWidthFontRenderer.drawTerminalWithoutCursor(
IDENTITY, builder, 0, 0,
terminal, !monitor.isColour(), yMargin, yMargin, xMargin, xMargin
);
builder.finishDrawing();
builder.end();
vbo.upload( builder );
}
vbo.bindBuffer();
FixedWidthFontRenderer.TYPE.getVertexFormat().setupBufferState( 0L );
vbo.draw( matrix, FixedWidthFontRenderer.TYPE.getDrawMode() );
VertexBuffer.unbindBuffer();
FixedWidthFontRenderer.TYPE.getVertexFormat().clearBufferState();
vbo.bind();
FixedWidthFontRenderer.TYPE.format().setupBufferState( 0L );
vbo.draw( matrix, FixedWidthFontRenderer.TYPE.mode() );
VertexBuffer.unbind();
FixedWidthFontRenderer.TYPE.format().clearBufferState();
break;
}
}

View File

@@ -72,31 +72,31 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
}
@Override
public void render( @Nonnull TileTurtle turtle, float partialTicks, @Nonnull MatrixStack transform, @Nonnull IRenderTypeBuffer renderer, int lightmapCoord, int overlayLight )
public void render( @Nonnull TileTurtle turtle, float partialTicks, @Nonnull MatrixStack transform, @Nonnull IRenderTypeBuffer buffers, int lightmapCoord, int overlayLight )
{
// Render the label
String label = turtle.createProxy().getLabel();
RayTraceResult hit = renderDispatcher.cameraHitResult;
if( label != null && hit.getType() == RayTraceResult.Type.BLOCK && turtle.getPos().equals( ((BlockRayTraceResult) hit).getPos() ) )
RayTraceResult hit = renderer.cameraHitResult;
if( label != null && hit.getType() == RayTraceResult.Type.BLOCK && turtle.getBlockPos().equals( ((BlockRayTraceResult) hit).getBlockPos() ) )
{
Minecraft mc = Minecraft.getInstance();
FontRenderer font = renderDispatcher.fontRenderer;
FontRenderer font = renderer.font;
transform.push();
transform.pushPose();
transform.translate( 0.5, 1.2, 0.5 );
transform.rotate( mc.getRenderManager().getCameraOrientation() );
transform.mulPose( mc.getEntityRenderDispatcher().cameraOrientation() );
transform.scale( -0.025f, -0.025f, 0.025f );
Matrix4f matrix = transform.getLast().getMatrix();
int opacity = (int) (mc.gameSettings.getTextBackgroundOpacity( 0.25f ) * 255) << 24;
float width = -font.getStringWidth( label ) / 2.0f;
font.renderString( label, width, (float) 0, 0x20ffffff, false, matrix, renderer, true, opacity, lightmapCoord );
font.renderString( label, width, (float) 0, 0xffffffff, false, matrix, renderer, false, 0, lightmapCoord );
Matrix4f matrix = transform.last().pose();
int opacity = (int) (mc.options.getBackgroundOpacity( 0.25f ) * 255) << 24;
float width = -font.width( label ) / 2.0f;
font.drawInBatch( label, width, (float) 0, 0x20ffffff, false, matrix, buffers, true, opacity, lightmapCoord );
font.drawInBatch( label, width, (float) 0, 0xffffffff, false, matrix, buffers, false, 0, lightmapCoord );
transform.pop();
transform.popPose();
}
transform.push();
transform.pushPose();
// Setup the transform.
Vec3d offset = turtle.getRenderOffset( partialTicks );
@@ -104,7 +104,7 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
transform.translate( offset.x, offset.y, offset.z );
transform.translate( 0.5f, 0.5f, 0.5f );
transform.rotate( Vector3f.YP.rotationDegrees( 180.0f - yaw ) );
transform.mulPose( Vector3f.YP.rotationDegrees( 180.0f - yaw ) );
if( label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" )) )
{
// Flip the model
@@ -117,7 +117,7 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
ComputerFamily family = turtle.getFamily();
ResourceLocation overlay = turtle.getOverlay();
IVertexBuilder buffer = renderer.getBuffer( Atlases.getTranslucentCullBlockType() );
IVertexBuilder buffer = buffers.getBuffer( Atlases.translucentCullBlockSheet() );
renderModel( transform, buffer, lightmapCoord, overlayLight, getTurtleModel( family, colour != -1 ), colour == -1 ? null : new int[] { colour } );
// Render the overlay
@@ -131,31 +131,31 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
renderUpgrade( transform, buffer, lightmapCoord, overlayLight, turtle, TurtleSide.LEFT, partialTicks );
renderUpgrade( transform, buffer, lightmapCoord, overlayLight, turtle, TurtleSide.RIGHT, partialTicks );
transform.pop();
transform.popPose();
}
private void renderUpgrade( @Nonnull MatrixStack transform, @Nonnull IVertexBuilder renderer, int lightmapCoord, int overlayLight, TileTurtle turtle, TurtleSide side, float f )
{
ITurtleUpgrade upgrade = turtle.getUpgrade( side );
if( upgrade == null ) return;
transform.push();
transform.pushPose();
float toolAngle = turtle.getToolRenderAngle( side, f );
transform.translate( 0.0f, 0.5f, 0.5f );
transform.rotate( Vector3f.XN.rotationDegrees( toolAngle ) );
transform.mulPose( Vector3f.XN.rotationDegrees( toolAngle ) );
transform.translate( 0.0f, -0.5f, -0.5f );
TransformedModel model = upgrade.getModel( turtle.getAccess(), side );
model.getMatrix().push( transform );
renderModel( transform, renderer, lightmapCoord, overlayLight, model.getModel(), null );
transform.pop();
transform.popPose();
transform.pop();
transform.popPose();
}
private void renderModel( @Nonnull MatrixStack transform, @Nonnull IVertexBuilder renderer, int lightmapCoord, int overlayLight, ModelResourceLocation modelLocation, int[] tints )
{
ModelManager modelManager = Minecraft.getInstance().getItemRenderer().getItemModelMesher().getModelManager();
ModelManager modelManager = Minecraft.getInstance().getItemRenderer().getItemModelShaper().getModelManager();
renderModel( transform, renderer, lightmapCoord, overlayLight, modelManager.getModel( modelLocation ), tints );
}
@@ -171,12 +171,12 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
private static void renderQuads( @Nonnull MatrixStack transform, @Nonnull IVertexBuilder buffer, int lightmapCoord, int overlayLight, List<BakedQuad> quads, int[] tints )
{
MatrixStack.Entry matrix = transform.getLast();
MatrixStack.Entry matrix = transform.last();
for( BakedQuad bakedquad : quads )
{
int tint = -1;
if( tints != null && bakedquad.hasTintIndex() )
if( tints != null && bakedquad.isTinted() )
{
int idx = bakedquad.getTintIndex();
if( idx >= 0 && idx < tints.length ) tint = tints[bakedquad.getTintIndex()];

View File

@@ -43,7 +43,7 @@ public final class TurtleModelLoader implements IModelLoader<TurtleModelLoader.T
@Override
public TurtleModel read( @Nonnull JsonDeserializationContext deserializationContext, @Nonnull JsonObject modelContents )
{
ResourceLocation model = new ResourceLocation( JSONUtils.getString( modelContents, "model" ) );
ResourceLocation model = new ResourceLocation( JSONUtils.getAsString( modelContents, "model" ) );
return new TurtleModel( model );
}
@@ -60,8 +60,8 @@ public final class TurtleModelLoader implements IModelLoader<TurtleModelLoader.T
public Collection<Material> getTextures( IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors )
{
Set<Material> materials = new HashSet<>();
materials.addAll( modelGetter.apply( family ).getTextures( modelGetter, missingTextureErrors ) );
materials.addAll( modelGetter.apply( COLOUR_TURTLE_MODEL ).getTextures( modelGetter, missingTextureErrors ) );
materials.addAll( modelGetter.apply( family ).getMaterials( modelGetter, missingTextureErrors ) );
materials.addAll( modelGetter.apply( COLOUR_TURTLE_MODEL ).getMaterials( modelGetter, missingTextureErrors ) );
return materials;
}

View File

@@ -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,63 +70,63 @@ 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;
}
@Override
public boolean isAmbientOcclusion()
public boolean useAmbientOcclusion()
{
return m_baseModel.isAmbientOcclusion();
return baseModel.useAmbientOcclusion();
}
@Override
public boolean isGui3d()
{
return m_baseModel.isGui3d();
return baseModel.isGui3d();
}
@Override
public boolean isBuiltInRenderer()
public boolean isCustomRenderer()
{
return m_baseModel.isBuiltInRenderer();
return baseModel.isCustomRenderer();
}
@Override
public boolean func_230044_c_()
public boolean usesBlockLight()
{
return m_baseModel.func_230044_c_();
return baseModel.usesBlockLight();
}
@Nonnull
@Override
@Deprecated
public TextureAtlasSprite getParticleTexture()
public TextureAtlasSprite getParticleIcon()
{
return m_baseModel.getParticleTexture();
return baseModel.getParticleIcon();
}
@Nonnull
@Override
@Deprecated
public net.minecraft.client.renderer.model.ItemCameraTransforms getItemCameraTransforms()
public net.minecraft.client.renderer.model.ItemCameraTransforms getTransforms()
{
return m_baseModel.getItemCameraTransforms();
return baseModel.getTransforms();
}
@Nonnull

View File

@@ -23,7 +23,7 @@ public class TurtlePlayerRenderer extends EntityRenderer<TurtlePlayer>
@Nonnull
@Override
public ResourceLocation getEntityTexture( @Nonnull TurtlePlayer entity )
public ResourceLocation getTextureLocation( @Nonnull TurtlePlayer entity )
{
return ComputerBorderRenderer.BACKGROUND_NORMAL;
}

View File

@@ -42,26 +42,26 @@ public class TurtleSmartItemModel implements IBakedModel
stack.translate( 0, 0, 1 );
identity = TransformationMatrix.identity();
flip = new TransformationMatrix( stack.getLast().getMatrix() );
flip = new TransformationMatrix( stack.last().pose() );
}
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,19 +97,19 @@ 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
public IBakedModel getModelWithOverrides( @Nonnull IBakedModel originalModel, @Nonnull ItemStack stack, @Nullable World world, @Nullable LivingEntity entity )
public IBakedModel resolve( @Nonnull IBakedModel originalModel, @Nonnull ItemStack stack, @Nullable World world, @Nullable LivingEntity entity )
{
ItemTurtle turtle = (ItemTurtle) stack.getItem();
int colour = turtle.getColour( stack );
@@ -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().getItemModelMesher().getModelManager();
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.m_overlay, combo.m_christmas );
ModelManager modelManager = mc.getItemRenderer().getItemModelShaper().getModelManager();
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 );
}
@@ -166,9 +166,9 @@ public class TurtleSmartItemModel implements IBakedModel
}
@Override
public boolean isAmbientOcclusion()
public boolean useAmbientOcclusion()
{
return familyModel.isAmbientOcclusion();
return familyModel.useAmbientOcclusion();
}
@Override
@@ -178,31 +178,31 @@ public class TurtleSmartItemModel implements IBakedModel
}
@Override
public boolean isBuiltInRenderer()
public boolean isCustomRenderer()
{
return familyModel.isBuiltInRenderer();
return familyModel.isCustomRenderer();
}
@Override
public boolean func_230044_c_()
public boolean usesBlockLight()
{
return familyModel.func_230044_c_();
return familyModel.usesBlockLight();
}
@Nonnull
@Override
@Deprecated
public TextureAtlasSprite getParticleTexture()
public TextureAtlasSprite getParticleIcon()
{
return familyModel.getParticleTexture();
return familyModel.getParticleIcon();
}
@Nonnull
@Override
@Deprecated
public ItemCameraTransforms getItemCameraTransforms()
public ItemCameraTransforms getTransforms()
{
return familyModel.getItemCameraTransforms();
return familyModel.getTransforms();
}
}

View File

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

View File

@@ -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
@@ -471,8 +471,8 @@ public class FSAPI implements ILuaAPI
/**
* Get attributes about a specific file or folder.
*
* The returned attributes table contains information about the size of the file, whether it is a directory, and
* when it was created and last modified.
* The returned attributes table contains information about the size of the file, whether it is a directory,
* when it was created and last modified, and whether it is read only.
*
* The creation and modification times are given as the number of milliseconds since the UNIX epoch. This may be
* given to {@link OSAPI#date} in order to convert it to more usable form.
@@ -480,7 +480,7 @@ public class FSAPI implements ILuaAPI
* @param path The path to get attributes for.
* @return The resulting attributes.
* @throws LuaException If the path does not exist.
* @cc.treturn { size = number, isDir = boolean, created = number, modified = number } The resulting attributes.
* @cc.treturn { size = number, isDir = boolean, isReadOnly = boolean, created = number, modified = number } The resulting attributes.
* @see #getSize If you only care about the file's size.
* @see #isDir If you only care whether a path is a directory or not.
*/
@@ -496,6 +496,7 @@ public class FSAPI implements ILuaAPI
result.put( "created", getFileTime( attributes.creationTime() ) );
result.put( "size", attributes.isDirectory() ? 0 : attributes.size() );
result.put( "isDir", attributes.isDirectory() );
result.put( "isReadOnly", fileSystem.isReadOnly( path ) );
return result;
}
catch( FileSystemException e )

View File

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

View File

@@ -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;
}
/**
@@ -312,10 +312,10 @@ public class OSAPI implements ILuaAPI
* always be in the range [0.0, 24.0).
*
* * If called with {@code ingame}, the current world time will be returned.
* This is the default if nothing is passed.
* This is the default if nothing is passed.
* * If called with {@code utc}, returns the hour of the day in UTC time.
* * If called with {@code local}, returns the hour of the day in the
* timezone the server is located in.
* timezone the server is located in.
*
* This function can also be called with a table returned from {@link #date},
* which will convert the date fields into a UNIX timestamp (number of
@@ -323,9 +323,9 @@ public class OSAPI implements ILuaAPI
*
* @param args The locale of the time, or a table filled by {@code os.date("*t")} to decode. Defaults to {@code ingame} locale if not specified.
* @return The hour of the selected locale, or a UNIX timestamp from the table, depending on the argument passed in.
* @throws LuaException If an invalid locale is passed.
* @cc.tparam [opt] string|table locale The locale of the time, or a table filled by {@code os.date("*t")} to decode. Defaults to {@code ingame} locale if not specified.
* @see #date To get a date table that can be converted with this function.
* @throws LuaException If an invalid locale is passed.
*/
@LuaFunction
public final Object time( IArguments args ) throws LuaException
@@ -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" );
}
@@ -351,11 +351,11 @@ public class OSAPI implements ILuaAPI
* Returns the day depending on the locale specified.
*
* * If called with {@code ingame}, returns the number of days 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 days since 1 January
* 1970 in the UTC timezone.
* 1970 in the UTC timezone.
* * If called with {@code local}, returns the number of days 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 day for. Defaults to {@code ingame} if not set.
* @return The day depending on the selected locale.
@@ -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" );
@@ -435,7 +435,7 @@ public class OSAPI implements ILuaAPI
* timestamp (days since 1 January 1970) with {@link #date}.
*
* @param formatA The format of the string to return. This defaults to {@code %c}, which expands to a string similar to "Sat Dec 24 16:58:00 2011".
* @param timeA The time to convert to a string. This defaults to the current time.
* @param timeA The time to convert to a string. This defaults to the current time.
* @return The resulting format string.
* @throws LuaException If an invalid format is passed.
*/

View File

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

View File

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

View File

@@ -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 ) );
}
/**

View File

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

View File

@@ -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;
}
/**

View File

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

View File

@@ -42,7 +42,7 @@ class ChannelWrapper<T extends Closeable> implements Closeable
}
}
public T get()
T get()
{
return wrapper;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -104,7 +104,7 @@ public final class ResourceMount implements IMount
{
boolean hasAny = false;
FileEntry newRoot = new FileEntry( new ResourceLocation( namespace, subPath ) );
for( ResourceLocation file : manager.getAllResourceLocations( subPath, s -> true ) )
for( ResourceLocation file : manager.listResources( subPath, s -> true ) )
{
if( !file.getNamespace().equals( namespace ) ) continue;
@@ -297,7 +297,7 @@ public final class ResourceMount implements IMount
synchronized void add( IReloadableResourceManager manager, ResourceMount mount )
{
if( managers.add( manager ) ) manager.addReloadListener( this );
if( managers.add( manager ) ) manager.registerReloadListener( this );
mounts.add( mount );
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -52,7 +52,7 @@ public class BlockModelProvider extends BlockStateProvider
private void registerComputer( BlockComputer block )
{
VariantBlockStateBuilder builder = getVariantBuilder( block );
for( ComputerState state : BlockComputer.STATE.getAllowedValues() )
for( ComputerState state : BlockComputer.STATE.getPossibleValues() )
{
BlockModelBuilder model = models()
.getBuilder( suffix( block, "_" + state ) )
@@ -61,7 +61,7 @@ public class BlockModelProvider extends BlockStateProvider
.texture( "side", suffix( block, "_side" ) )
.texture( "front", suffix( block, "_front" + toSuffix( state ) ) );
for( Direction facing : BlockComputer.FACING.getAllowedValues() )
for( Direction facing : BlockComputer.FACING.getPossibleValues() )
{
builder.partialState()
.with( BlockComputer.STATE, state )
@@ -92,14 +92,14 @@ public class BlockModelProvider extends BlockStateProvider
registerMonitorModel( name, "_ud", 21, 6, 0, 37 );
VariantBlockStateBuilder builder = getVariantBuilder( block );
for( MonitorEdgeState edge : BlockMonitor.STATE.getAllowedValues() )
for( MonitorEdgeState edge : BlockMonitor.STATE.getPossibleValues() )
{
String suffix = edge == MonitorEdgeState.NONE ? "" : "_" + edge.getName();
String suffix = edge == MonitorEdgeState.NONE ? "" : "_" + edge.getSerializedName();
ModelFile model = models().getBuilder( suffix( block, suffix ) );
for( Direction facing : BlockMonitor.FACING.getAllowedValues() )
for( Direction facing : BlockMonitor.FACING.getPossibleValues() )
{
for( Direction orientation : BlockMonitor.ORIENTATION.getAllowedValues() )
for( Direction orientation : BlockMonitor.ORIENTATION.getPossibleValues() )
{
builder.partialState()
.with( BlockMonitor.STATE, edge )
@@ -137,7 +137,7 @@ public class BlockModelProvider extends BlockStateProvider
private static int toYAngle( Direction direction )
{
return ((int) direction.getHorizontalAngle() + 180) % 360;
return ((int) direction.toYRot() + 180) % 360;
}
private static String toSuffix( ComputerState state )

View File

@@ -40,17 +40,17 @@ public abstract class LootTableProvider implements IDataProvider
}
@Override
public void act( @Nonnull DirectoryCache cache )
public void run( @Nonnull DirectoryCache cache )
{
Map<ResourceLocation, LootTable> tables = new HashMap<>();
ValidationTracker validation = new ValidationTracker( LootParameterSets.GENERIC, x -> null, tables::get );
ValidationTracker validation = new ValidationTracker( LootParameterSets.ALL_PARAMS, x -> null, tables::get );
registerLoot( ( id, table ) -> {
if( tables.containsKey( id ) ) validation.addProblem( "Duplicate loot tables for " + id );
if( tables.containsKey( id ) ) validation.reportProblem( "Duplicate loot tables for " + id );
tables.put( id, table );
} );
tables.forEach( ( key, value ) -> LootTableManager.func_227508_a_( validation, key, value ) );
tables.forEach( ( key, value ) -> LootTableManager.validate( validation, key, value ) );
Multimap<String, String> problems = validation.getProblems();
if( !problems.isEmpty() )
@@ -64,7 +64,7 @@ public abstract class LootTableProvider implements IDataProvider
Path path = getPath( key );
try
{
IDataProvider.save( GSON, cache, LootTableManager.toJson( value ), path );
IDataProvider.save( GSON, cache, LootTableManager.serialize( value ), path );
}
catch( IOException e )
{

View File

@@ -47,8 +47,8 @@ public class LootTables extends LootTableProvider
computerDrop( add, Registry.ModBlocks.TURTLE_ADVANCED );
add.accept( ComputerCraftProxyCommon.ForgeHandlers.LOOT_TREASURE_DISK, LootTable
.builder()
.setParameterSet( LootParameterSets.GENERIC )
.lootTable()
.setParamSet( LootParameterSets.ALL_PARAMS )
.build() );
}
@@ -56,13 +56,13 @@ public class LootTables extends LootTableProvider
{
Block block = wrapper.get();
add.accept( block.getLootTable(), LootTable
.builder()
.setParameterSet( LootParameterSets.BLOCK )
.addLootPool( LootPool.builder()
.lootTable()
.setParamSet( LootParameterSets.BLOCK )
.withPool( LootPool.lootPool()
.name( "main" )
.rolls( ConstantRange.of( 1 ) )
.addEntry( ItemLootEntry.builder( block ) )
.acceptCondition( SurvivesExplosion.builder() )
.setRolls( ConstantRange.exactly( 1 ) )
.add( ItemLootEntry.lootTableItem( block ) )
.when( SurvivesExplosion.survivesExplosion() )
).build() );
}
@@ -70,16 +70,16 @@ public class LootTables extends LootTableProvider
{
Block block = wrapper.get();
add.accept( block.getLootTable(), LootTable
.builder()
.setParameterSet( LootParameterSets.BLOCK )
.addLootPool( LootPool.builder()
.lootTable()
.setParamSet( LootParameterSets.BLOCK )
.withPool( LootPool.lootPool()
.name( "main" )
.rolls( ConstantRange.of( 1 ) )
.addEntry( DynamicLootEntry.func_216162_a( new ResourceLocation( ComputerCraft.MOD_ID, "computer" ) ) )
.acceptCondition( Alternative.builder(
.setRolls( ConstantRange.exactly( 1 ) )
.add( DynamicLootEntry.dynamicEntry( new ResourceLocation( ComputerCraft.MOD_ID, "computer" ) ) )
.when( Alternative.alternative(
BlockNamedEntityLootCondition.builder(),
HasComputerIdLootCondition.builder(),
PlayerCreativeLootCondition.builder().inverted()
PlayerCreativeLootCondition.builder().invert()
) )
).build() );
}

View File

@@ -50,42 +50,42 @@ public final class RecipeWrapper implements IFinishedRecipe
}
@Override
public void serialize( @Nonnull JsonObject jsonObject )
public void serializeRecipeData( @Nonnull JsonObject jsonObject )
{
recipe.serialize( jsonObject );
recipe.serializeRecipeData( jsonObject );
if( resultData != null )
{
JsonObject object = JSONUtils.getJsonObject( jsonObject, "result" );
JsonObject object = JSONUtils.getAsJsonObject( jsonObject, "result" );
object.addProperty( "nbt", resultData.toString() );
}
}
@Nonnull
@Override
public ResourceLocation getID()
public ResourceLocation getId()
{
return recipe.getID();
return recipe.getId();
}
@Nonnull
@Override
public IRecipeSerializer<?> getSerializer()
public IRecipeSerializer<?> getType()
{
return serializer;
}
@Nullable
@Override
public JsonObject getAdvancementJson()
public JsonObject serializeAdvancement()
{
return recipe.getAdvancementJson();
return recipe.serializeAdvancement();
}
@Nullable
@Override
public ResourceLocation getAdvancementID()
public ResourceLocation getAdvancementId()
{
return recipe.getAdvancementID();
return recipe.getAdvancementId();
}
}

View File

@@ -10,6 +10,7 @@ import dan200.computercraft.data.Tags.CCTags;
import dan200.computercraft.shared.PocketUpgrades;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.TurtleUpgrades;
import dan200.computercraft.shared.common.IColouredItem;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory;
import dan200.computercraft.shared.turtle.items.TurtleItemFactory;
@@ -38,7 +39,7 @@ public class Recipes extends RecipeProvider
}
@Override
protected void registerRecipes( @Nonnull Consumer<IFinishedRecipe> add )
protected void buildShapelessRecipes( @Nonnull Consumer<IFinishedRecipe> add )
{
basicRecipes( add );
diskColours( add );
@@ -56,15 +57,15 @@ public class Recipes extends RecipeProvider
for( Colour colour : Colour.VALUES )
{
ShapelessRecipeBuilder
.shapelessRecipe( Registry.ModItems.DISK.get() )
.addIngredient( Tags.Items.DUSTS_REDSTONE )
.addIngredient( Items.PAPER )
.addIngredient( DyeItem.getItem( ofColour( colour ) ) )
.setGroup( "computercraft:disk" )
.addCriterion( "has_drive", inventoryChange( Registry.ModBlocks.DISK_DRIVE.get() ) )
.build( RecipeWrapper.wrap(
.shapeless( Registry.ModItems.DISK.get() )
.requires( Tags.Items.DUSTS_REDSTONE )
.requires( Items.PAPER )
.requires( DyeItem.byColor( ofColour( colour ) ) )
.group( "computercraft:disk" )
.unlocks( "has_drive", inventoryChange( Registry.ModBlocks.DISK_DRIVE.get() ) )
.save( RecipeWrapper.wrap(
ImpostorShapelessRecipe.SERIALIZER, add,
x -> x.putInt( "color", colour.getHex() )
x -> x.putInt( IColouredItem.NBT_COLOUR, colour.getHex() )
), new ResourceLocation( ComputerCraft.MOD_ID, "disk_" + (colour.ordinal() + 1) ) );
}
}
@@ -86,14 +87,14 @@ public class Recipes extends RecipeProvider
TurtleUpgrades.getVanillaUpgrades().forEach( upgrade -> {
ItemStack result = TurtleItemFactory.create( -1, null, -1, family, null, upgrade, -1, null );
ShapedRecipeBuilder
.shapedRecipe( result.getItem() )
.setGroup( String.format( "%s:turtle_%s", ComputerCraft.MOD_ID, nameId ) )
.patternLine( "#T" )
.key( '#', base.getItem() )
.key( 'T', upgrade.getCraftingItem().getItem() )
.addCriterion( "has_items",
.shaped( result.getItem() )
.group( String.format( "%s:turtle_%s", ComputerCraft.MOD_ID, nameId ) )
.pattern( "#T" )
.define( '#', base.getItem() )
.define( 'T', upgrade.getCraftingItem().getItem() )
.unlocks( "has_items",
inventoryChange( base.getItem(), upgrade.getCraftingItem().getItem() ) )
.build(
.save(
RecipeWrapper.wrap( ImpostorRecipe.SERIALIZER, add, result.getTag() ),
new ResourceLocation( ComputerCraft.MOD_ID, String.format( "turtle_%s/%s/%s",
nameId, upgrade.getUpgradeID().getNamespace(), upgrade.getUpgradeID().getPath()
@@ -120,15 +121,15 @@ public class Recipes extends RecipeProvider
PocketUpgrades.getVanillaUpgrades().forEach( upgrade -> {
ItemStack result = PocketComputerItemFactory.create( -1, null, -1, family, null );
ShapedRecipeBuilder
.shapedRecipe( result.getItem() )
.setGroup( String.format( "%s:pocket_%s", ComputerCraft.MOD_ID, nameId ) )
.patternLine( "#" )
.patternLine( "P" )
.key( '#', base.getItem() )
.key( 'P', upgrade.getCraftingItem().getItem() )
.addCriterion( "has_items",
.shaped( result.getItem() )
.group( String.format( "%s:pocket_%s", ComputerCraft.MOD_ID, nameId ) )
.pattern( "#" )
.pattern( "P" )
.define( '#', base.getItem() )
.define( 'P', upgrade.getCraftingItem().getItem() )
.unlocks( "has_items",
inventoryChange( base.getItem(), upgrade.getCraftingItem().getItem() ) )
.build(
.save(
RecipeWrapper.wrap( ImpostorRecipe.SERIALIZER, add, result.getTag() ),
new ResourceLocation( ComputerCraft.MOD_ID, String.format( "pocket_%s/%s/%s",
nameId, upgrade.getUpgradeID().getNamespace(), upgrade.getUpgradeID().getPath()
@@ -141,167 +142,167 @@ public class Recipes extends RecipeProvider
private void basicRecipes( @Nonnull Consumer<IFinishedRecipe> add )
{
ShapedRecipeBuilder
.shapedRecipe( Registry.ModItems.CABLE.get(), 6 )
.patternLine( " # " )
.patternLine( "#R#" )
.patternLine( " # " )
.key( '#', Tags.Items.STONE )
.key( 'R', Tags.Items.DUSTS_REDSTONE )
.addCriterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.addCriterion( "has_modem", inventoryChange( CCTags.COMPUTER ) )
.build( add );
.shaped( Registry.ModItems.CABLE.get(), 6 )
.pattern( " # " )
.pattern( "#R#" )
.pattern( " # " )
.define( '#', Tags.Items.STONE )
.define( 'R', Tags.Items.DUSTS_REDSTONE )
.unlocks( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.unlocks( "has_modem", inventoryChange( CCTags.COMPUTER ) )
.save( add );
ShapedRecipeBuilder
.shapedRecipe( Registry.ModBlocks.COMPUTER_NORMAL.get() )
.patternLine( "###" )
.patternLine( "#R#" )
.patternLine( "#G#" )
.key( '#', Tags.Items.STONE )
.key( 'R', Tags.Items.DUSTS_REDSTONE )
.key( 'G', Tags.Items.GLASS_PANES )
.addCriterion( "has_redstone", inventoryChange( Tags.Items.DUSTS_REDSTONE ) )
.build( add );
.shaped( Registry.ModBlocks.COMPUTER_NORMAL.get() )
.pattern( "###" )
.pattern( "#R#" )
.pattern( "#G#" )
.define( '#', Tags.Items.STONE )
.define( 'R', Tags.Items.DUSTS_REDSTONE )
.define( 'G', Tags.Items.GLASS_PANES )
.unlocks( "has_redstone", inventoryChange( Tags.Items.DUSTS_REDSTONE ) )
.save( add );
ShapedRecipeBuilder
.shapedRecipe( Registry.ModBlocks.COMPUTER_ADVANCED.get() )
.patternLine( "###" )
.patternLine( "#R#" )
.patternLine( "#G#" )
.key( '#', Tags.Items.INGOTS_GOLD )
.key( 'R', Tags.Items.DUSTS_REDSTONE )
.key( 'G', Tags.Items.GLASS_PANES )
.addCriterion( "has_components", inventoryChange( Items.REDSTONE, Items.GOLD_INGOT ) )
.build( add );
.shaped( Registry.ModBlocks.COMPUTER_ADVANCED.get() )
.pattern( "###" )
.pattern( "#R#" )
.pattern( "#G#" )
.define( '#', Tags.Items.INGOTS_GOLD )
.define( 'R', Tags.Items.DUSTS_REDSTONE )
.define( 'G', Tags.Items.GLASS_PANES )
.unlocks( "has_components", inventoryChange( Items.REDSTONE, Items.GOLD_INGOT ) )
.save( add );
ShapedRecipeBuilder
.shapedRecipe( Registry.ModBlocks.COMPUTER_COMMAND.get() )
.patternLine( "###" )
.patternLine( "#R#" )
.patternLine( "#G#" )
.key( '#', Tags.Items.INGOTS_GOLD )
.key( 'R', Blocks.COMMAND_BLOCK )
.key( 'G', Tags.Items.GLASS_PANES )
.addCriterion( "has_components", inventoryChange( Blocks.COMMAND_BLOCK ) )
.build( add );
.shaped( Registry.ModBlocks.COMPUTER_COMMAND.get() )
.pattern( "###" )
.pattern( "#R#" )
.pattern( "#G#" )
.define( '#', Tags.Items.INGOTS_GOLD )
.define( 'R', Blocks.COMMAND_BLOCK )
.define( 'G', Tags.Items.GLASS_PANES )
.unlocks( "has_components", inventoryChange( Blocks.COMMAND_BLOCK ) )
.save( add );
ShapedRecipeBuilder
.shapedRecipe( Registry.ModBlocks.DISK_DRIVE.get() )
.patternLine( "###" )
.patternLine( "#R#" )
.patternLine( "#R#" )
.key( '#', Tags.Items.STONE )
.key( 'R', Tags.Items.DUSTS_REDSTONE )
.addCriterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.build( add );
.shaped( Registry.ModBlocks.DISK_DRIVE.get() )
.pattern( "###" )
.pattern( "#R#" )
.pattern( "#R#" )
.define( '#', Tags.Items.STONE )
.define( 'R', Tags.Items.DUSTS_REDSTONE )
.unlocks( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.save( add );
ShapedRecipeBuilder
.shapedRecipe( Registry.ModBlocks.MONITOR_NORMAL.get() )
.patternLine( "###" )
.patternLine( "#G#" )
.patternLine( "###" )
.key( '#', Tags.Items.STONE )
.key( 'G', Tags.Items.GLASS_PANES )
.addCriterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.build( add );
.shaped( Registry.ModBlocks.MONITOR_NORMAL.get() )
.pattern( "###" )
.pattern( "#G#" )
.pattern( "###" )
.define( '#', Tags.Items.STONE )
.define( 'G', Tags.Items.GLASS_PANES )
.unlocks( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.save( add );
ShapedRecipeBuilder
.shapedRecipe( Registry.ModBlocks.MONITOR_ADVANCED.get(), 4 )
.patternLine( "###" )
.patternLine( "#G#" )
.patternLine( "###" )
.key( '#', Tags.Items.INGOTS_GOLD )
.key( 'G', Tags.Items.GLASS_PANES )
.addCriterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.build( add );
.shaped( Registry.ModBlocks.MONITOR_ADVANCED.get(), 4 )
.pattern( "###" )
.pattern( "#G#" )
.pattern( "###" )
.define( '#', Tags.Items.INGOTS_GOLD )
.define( 'G', Tags.Items.GLASS_PANES )
.unlocks( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.save( add );
ShapedRecipeBuilder
.shapedRecipe( Registry.ModItems.POCKET_COMPUTER_NORMAL.get() )
.patternLine( "###" )
.patternLine( "#A#" )
.patternLine( "#G#" )
.key( '#', Tags.Items.STONE )
.key( 'A', Items.GOLDEN_APPLE )
.key( 'G', Tags.Items.GLASS_PANES )
.addCriterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.addCriterion( "has_apple", inventoryChange( Items.GOLDEN_APPLE ) )
.build( add );
.shaped( Registry.ModItems.POCKET_COMPUTER_NORMAL.get() )
.pattern( "###" )
.pattern( "#A#" )
.pattern( "#G#" )
.define( '#', Tags.Items.STONE )
.define( 'A', Items.GOLDEN_APPLE )
.define( 'G', Tags.Items.GLASS_PANES )
.unlocks( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.unlocks( "has_apple", inventoryChange( Items.GOLDEN_APPLE ) )
.save( add );
ShapedRecipeBuilder
.shapedRecipe( Registry.ModItems.POCKET_COMPUTER_ADVANCED.get() )
.patternLine( "###" )
.patternLine( "#A#" )
.patternLine( "#G#" )
.key( '#', Tags.Items.INGOTS_GOLD )
.key( 'A', Items.GOLDEN_APPLE )
.key( 'G', Tags.Items.GLASS_PANES )
.addCriterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.addCriterion( "has_apple", inventoryChange( Items.GOLDEN_APPLE ) )
.build( add );
.shaped( Registry.ModItems.POCKET_COMPUTER_ADVANCED.get() )
.pattern( "###" )
.pattern( "#A#" )
.pattern( "#G#" )
.define( '#', Tags.Items.INGOTS_GOLD )
.define( 'A', Items.GOLDEN_APPLE )
.define( 'G', Tags.Items.GLASS_PANES )
.unlocks( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.unlocks( "has_apple", inventoryChange( Items.GOLDEN_APPLE ) )
.save( add );
ShapedRecipeBuilder
.shapedRecipe( Registry.ModBlocks.PRINTER.get() )
.patternLine( "###" )
.patternLine( "#R#" )
.patternLine( "#D#" )
.key( '#', Tags.Items.STONE )
.key( 'R', Tags.Items.DUSTS_REDSTONE )
.key( 'D', Tags.Items.DYES )
.addCriterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.build( add );
.shaped( Registry.ModBlocks.PRINTER.get() )
.pattern( "###" )
.pattern( "#R#" )
.pattern( "#D#" )
.define( '#', Tags.Items.STONE )
.define( 'R', Tags.Items.DUSTS_REDSTONE )
.define( 'D', Tags.Items.DYES )
.unlocks( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.save( add );
ShapedRecipeBuilder
.shapedRecipe( Registry.ModBlocks.SPEAKER.get() )
.patternLine( "###" )
.patternLine( "#N#" )
.patternLine( "#R#" )
.key( '#', Tags.Items.STONE )
.key( 'N', Blocks.NOTE_BLOCK )
.key( 'R', Tags.Items.DUSTS_REDSTONE )
.addCriterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.build( add );
.shaped( Registry.ModBlocks.SPEAKER.get() )
.pattern( "###" )
.pattern( "#N#" )
.pattern( "#R#" )
.define( '#', Tags.Items.STONE )
.define( 'N', Blocks.NOTE_BLOCK )
.define( 'R', Tags.Items.DUSTS_REDSTONE )
.unlocks( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.save( add );
ShapedRecipeBuilder
.shapedRecipe( Registry.ModItems.WIRED_MODEM.get() )
.patternLine( "###" )
.patternLine( "#R#" )
.patternLine( "###" )
.key( '#', Tags.Items.STONE )
.key( 'R', Tags.Items.DUSTS_REDSTONE )
.addCriterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.addCriterion( "has_cable", inventoryChange( Registry.ModItems.CABLE.get() ) )
.build( add );
.shaped( Registry.ModItems.WIRED_MODEM.get() )
.pattern( "###" )
.pattern( "#R#" )
.pattern( "###" )
.define( '#', Tags.Items.STONE )
.define( 'R', Tags.Items.DUSTS_REDSTONE )
.unlocks( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.unlocks( "has_cable", inventoryChange( Registry.ModItems.CABLE.get() ) )
.save( add );
ShapelessRecipeBuilder
.shapelessRecipe( Registry.ModBlocks.WIRED_MODEM_FULL.get() )
.addIngredient( Registry.ModItems.WIRED_MODEM.get() )
.addCriterion( "has_modem", inventoryChange( CCTags.WIRED_MODEM ) )
.build( add, new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full_from" ) );
.shapeless( Registry.ModBlocks.WIRED_MODEM_FULL.get() )
.requires( Registry.ModItems.WIRED_MODEM.get() )
.unlocks( "has_modem", inventoryChange( CCTags.WIRED_MODEM ) )
.save( add, new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full_from" ) );
ShapelessRecipeBuilder
.shapelessRecipe( Registry.ModItems.WIRED_MODEM.get() )
.addIngredient( Registry.ModBlocks.WIRED_MODEM_FULL.get() )
.addCriterion( "has_modem", inventoryChange( CCTags.WIRED_MODEM ) )
.build( add, new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full_to" ) );
.shapeless( Registry.ModItems.WIRED_MODEM.get() )
.requires( Registry.ModBlocks.WIRED_MODEM_FULL.get() )
.unlocks( "has_modem", inventoryChange( CCTags.WIRED_MODEM ) )
.save( add, new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full_to" ) );
ShapedRecipeBuilder
.shapedRecipe( Registry.ModBlocks.WIRELESS_MODEM_NORMAL.get() )
.patternLine( "###" )
.patternLine( "#E#" )
.patternLine( "###" )
.key( '#', Tags.Items.STONE )
.key( 'E', Tags.Items.ENDER_PEARLS )
.addCriterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.build( add );
.shaped( Registry.ModBlocks.WIRELESS_MODEM_NORMAL.get() )
.pattern( "###" )
.pattern( "#E#" )
.pattern( "###" )
.define( '#', Tags.Items.STONE )
.define( 'E', Tags.Items.ENDER_PEARLS )
.unlocks( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.save( add );
ShapedRecipeBuilder
.shapedRecipe( Registry.ModBlocks.WIRELESS_MODEM_ADVANCED.get() )
.patternLine( "###" )
.patternLine( "#E#" )
.patternLine( "###" )
.key( '#', Tags.Items.INGOTS_GOLD )
.key( 'E', Items.ENDER_EYE )
.addCriterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.addCriterion( "has_wireless", inventoryChange( Registry.ModBlocks.WIRELESS_MODEM_NORMAL.get() ) )
.build( add );
.shaped( Registry.ModBlocks.WIRELESS_MODEM_ADVANCED.get() )
.pattern( "###" )
.pattern( "#E#" )
.pattern( "###" )
.define( '#', Tags.Items.INGOTS_GOLD )
.define( 'E', Items.ENDER_EYE )
.unlocks( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.unlocks( "has_wireless", inventoryChange( Registry.ModBlocks.WIRELESS_MODEM_NORMAL.get() ) )
.save( add );
}
private static DyeColor ofColour( Colour colour )
@@ -311,11 +312,11 @@ public class Recipes extends RecipeProvider
private static InventoryChangeTrigger.Instance inventoryChange( Tag<Item> stack )
{
return InventoryChangeTrigger.Instance.forItems( ItemPredicate.Builder.create().tag( stack ).build() );
return InventoryChangeTrigger.Instance.hasItem( ItemPredicate.Builder.item().of( stack ).build() );
}
private static InventoryChangeTrigger.Instance inventoryChange( IItemProvider... stack )
{
return InventoryChangeTrigger.Instance.forItems( stack );
return InventoryChangeTrigger.Instance.hasItem( stack );
}
}

View File

@@ -32,15 +32,15 @@ public class Tags extends ItemTagsProvider
}
@Override
protected void registerTags()
protected void addTags()
{
getBuilder( COMPUTER )
tag( COMPUTER )
.add( Registry.ModItems.COMPUTER_NORMAL.get() )
.add( Registry.ModItems.COMPUTER_ADVANCED.get() )
.add( Registry.ModItems.COMPUTER_COMMAND.get() );
getBuilder( TURTLE ).add( Registry.ModItems.TURTLE_NORMAL.get(), Registry.ModItems.TURTLE_ADVANCED.get() );
getBuilder( WIRED_MODEM ).add( Registry.ModItems.WIRED_MODEM.get(), Registry.ModItems.WIRED_MODEM_FULL.get() );
getBuilder( MONITOR )
tag( TURTLE ).add( Registry.ModItems.TURTLE_NORMAL.get(), Registry.ModItems.TURTLE_ADVANCED.get() );
tag( WIRED_MODEM ).add( Registry.ModItems.WIRED_MODEM.get(), Registry.ModItems.WIRED_MODEM_FULL.get() );
tag( MONITOR )
.add( Registry.ModItems.MONITOR_NORMAL.get() )
.add( Registry.ModItems.MONITOR_ADVANCED.get() );
}

View File

@@ -31,12 +31,12 @@ public final class BundledRedstone
public static int getDefaultOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
return World.isValid( pos ) ? DefaultBundledRedstoneProvider.getDefaultBundledRedstoneOutput( world, pos, side ) : -1;
return World.isInWorldBounds( pos ) ? DefaultBundledRedstoneProvider.getDefaultBundledRedstoneOutput( world, pos, side ) : -1;
}
private static int getUnmaskedOutput( World world, BlockPos pos, Direction side )
{
if( !World.isValid( pos ) ) return -1;
if( !World.isInWorldBounds( pos ) ) return -1;
// Try the providers in order:
int combinedSignal = -1;

View File

@@ -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,9 +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;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD )
public final class Config
{

View File

@@ -40,13 +40,13 @@ public final class Peripherals
@Nullable
public static IPeripheral getPeripheral( World world, BlockPos pos, Direction side, NonNullConsumer<LazyOptional<IPeripheral>> invalidate )
{
return World.isValid( pos ) && !world.isRemote ? getPeripheralAt( world, pos, side, invalidate ) : null;
return World.isInWorldBounds( pos ) && !world.isClientSide ? getPeripheralAt( world, pos, side, invalidate ) : null;
}
@Nullable
private static IPeripheral getPeripheralAt( World world, BlockPos pos, Direction side, NonNullConsumer<LazyOptional<IPeripheral>> invalidate )
{
TileEntity block = world.getTileEntity( pos );
TileEntity block = world.getBlockEntity( pos );
if( block != null )
{
LazyOptional<IPeripheral> peripheral = block.getCapability( CAPABILITY_PERIPHERAL, side );

View File

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

View File

@@ -96,17 +96,17 @@ public final class Registry
private static Block.Properties properties()
{
return Block.Properties.create( Material.ROCK ).hardnessAndResistance( 2 );
return Block.Properties.of( Material.STONE ).strength( 2 );
}
private static Block.Properties turtleProperties()
{
return Block.Properties.create( Material.ROCK ).hardnessAndResistance( 2.5f );
return Block.Properties.of( Material.STONE ).strength( 2.5f );
}
private static Block.Properties modemProperties()
{
return Block.Properties.create( Material.ROCK ).hardnessAndResistance( 1.5f );
return Block.Properties.of( Material.STONE ).strength( 1.5f );
}
public static final RegistryObject<BlockComputer> COMPUTER_NORMAL = BLOCKS.register( "computer_normal",
@@ -115,7 +115,7 @@ public final class Registry
() -> new BlockComputer( properties(), ComputerFamily.ADVANCED, ModTiles.COMPUTER_ADVANCED ) );
public static final RegistryObject<BlockComputer> COMPUTER_COMMAND = BLOCKS.register( "computer_command", () -> new BlockComputer(
Block.Properties.create( Material.ROCK ).hardnessAndResistance( -1, 6000000.0F ),
Block.Properties.of( Material.STONE ).strength( -1, 6000000.0F ),
ComputerFamily.COMMAND, ModTiles.COMPUTER_COMMAND
) );
@@ -187,7 +187,7 @@ public final class Registry
private static Item.Properties properties()
{
return new Item.Properties().group( mainItemGroup );
return new Item.Properties().tab( mainItemGroup );
}
private static <B extends Block, I extends Item> RegistryObject<I> ofBlock( RegistryObject<B> parent, BiFunction<B, Item.Properties, I> supplier )
@@ -200,24 +200,24 @@ public final class Registry
public static final RegistryObject<ItemComputer> COMPUTER_COMMAND = ofBlock( ModBlocks.COMPUTER_COMMAND, ItemComputer::new );
public static final RegistryObject<ItemPocketComputer> POCKET_COMPUTER_NORMAL = ITEMS.register( "pocket_computer_normal",
() -> new ItemPocketComputer( properties().maxStackSize( 1 ), ComputerFamily.NORMAL ) );
() -> new ItemPocketComputer( properties().stacksTo( 1 ), ComputerFamily.NORMAL ) );
public static final RegistryObject<ItemPocketComputer> POCKET_COMPUTER_ADVANCED = ITEMS.register( "pocket_computer_advanced",
() -> new ItemPocketComputer( properties().maxStackSize( 1 ), ComputerFamily.ADVANCED ) );
() -> new ItemPocketComputer( properties().stacksTo( 1 ), ComputerFamily.ADVANCED ) );
public static final RegistryObject<ItemTurtle> TURTLE_NORMAL = ofBlock( ModBlocks.TURTLE_NORMAL, ItemTurtle::new );
public static final RegistryObject<ItemTurtle> TURTLE_ADVANCED = ofBlock( ModBlocks.TURTLE_ADVANCED, ItemTurtle::new );
public static final RegistryObject<ItemDisk> DISK =
ITEMS.register( "disk", () -> new ItemDisk( properties().maxStackSize( 1 ) ) );
ITEMS.register( "disk", () -> new ItemDisk( properties().stacksTo( 1 ) ) );
public static final RegistryObject<ItemTreasureDisk> TREASURE_DISK =
ITEMS.register( "treasure_disk", () -> new ItemTreasureDisk( properties().maxStackSize( 1 ) ) );
ITEMS.register( "treasure_disk", () -> new ItemTreasureDisk( properties().stacksTo( 1 ) ) );
public static final RegistryObject<ItemPrintout> PRINTED_PAGE = ITEMS.register( "printed_page",
() -> new ItemPrintout( properties().maxStackSize( 1 ), ItemPrintout.Type.PAGE ) );
() -> new ItemPrintout( properties().stacksTo( 1 ), ItemPrintout.Type.PAGE ) );
public static final RegistryObject<ItemPrintout> PRINTED_PAGES = ITEMS.register( "printed_pages",
() -> new ItemPrintout( properties().maxStackSize( 1 ), ItemPrintout.Type.PAGES ) );
() -> new ItemPrintout( properties().stacksTo( 1 ), ItemPrintout.Type.PAGES ) );
public static final RegistryObject<ItemPrintout> PRINTED_BOOK = ITEMS.register( "printed_book",
() -> new ItemPrintout( properties().maxStackSize( 1 ), ItemPrintout.Type.BOOK ) );
() -> new ItemPrintout( properties().stacksTo( 1 ), ItemPrintout.Type.BOOK ) );
public static final RegistryObject<BlockItem> SPEAKER = ofBlock( ModBlocks.SPEAKER, BlockItem::new );
public static final RegistryObject<BlockItem> DISK_DRIVE = ofBlock( ModBlocks.DISK_DRIVE, BlockItem::new );
@@ -284,10 +284,10 @@ public final class Registry
static final DeferredRegister<EntityType<?>> ENTITIES = new DeferredRegister<>( ForgeRegistries.ENTITIES, ComputerCraft.MOD_ID );
public static final RegistryObject<EntityType<TurtlePlayer>> TURTLE_PLAYER = ENTITIES.register( "turtle_player", () ->
EntityType.Builder.<TurtlePlayer>create( EntityClassification.MISC )
.disableSerialization()
.disableSummoning()
.size( 0, 0 )
EntityType.Builder.<TurtlePlayer>createNothing( EntityClassification.MISC )
.noSave()
.noSummon()
.sized( 0, 0 )
.build( ComputerCraft.MOD_ID + ":turtle_player" ) );
}

View File

@@ -20,13 +20,13 @@ public final class TurtlePermissions
public static boolean isBlockEnterable( World world, BlockPos pos, PlayerEntity player )
{
MinecraftServer server = world.getServer();
return server == null || world.isRemote || !server.isBlockProtected( world, pos, player );
return server == null || world.isClientSide || !server.isUnderSpawnProtection( world, pos, player );
}
public static boolean isBlockEditable( World world, BlockPos pos, PlayerEntity player )
{
MinecraftServer server = world.getServer();
return server == null || world.isRemote || !server.isBlockProtected( world, pos, player );
return server == null || world.isClientSide || !server.isUnderSpawnProtection( world, pos, player );
}
@SubscribeEvent

View File

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

View File

@@ -75,13 +75,13 @@ public final class CommandComputerCraft
List<ServerComputer> computers = new ArrayList<>( ComputerCraft.serverComputerRegistry.getComputers() );
// Unless we're on a server, limit the number of rows we can send.
World world = source.getWorld();
BlockPos pos = new BlockPos( source.getPos() );
World world = source.getLevel();
BlockPos pos = new BlockPos( source.getPosition() );
computers.sort( ( a, b ) -> {
if( a.getWorld() == b.getWorld() && a.getWorld() == world )
{
return Double.compare( a.getPosition().distanceSq( pos ), b.getPosition().distanceSq( pos ) );
return Double.compare( a.getPosition().distSqr( pos ), b.getPosition().distSqr( pos ) );
}
else if( a.getWorld() == world )
{
@@ -145,7 +145,7 @@ public final class CommandComputerCraft
if( computer.isOn() ) shutdown++;
computer.shutdown();
}
context.getSource().sendFeedback( translate( "commands.computercraft.shutdown.done", shutdown, computers.size() ), false );
context.getSource().sendSuccess( translate( "commands.computercraft.shutdown.done", shutdown, computers.size() ), false );
return shutdown;
} ) )
@@ -159,7 +159,7 @@ public final class CommandComputerCraft
if( !computer.isOn() ) on++;
computer.turnOn();
}
context.getSource().sendFeedback( translate( "commands.computercraft.turn_on.done", on, computers.size() ), false );
context.getSource().sendSuccess( translate( "commands.computercraft.turn_on.done", on, computers.size() ), false );
return on;
} ) )
@@ -173,20 +173,20 @@ public final class CommandComputerCraft
if( world == null || pos == null ) throw TP_NOT_THERE.create();
Entity entity = context.getSource().assertIsEntity();
Entity entity = context.getSource().getEntityOrException();
if( !(entity instanceof ServerPlayerEntity) ) throw TP_NOT_PLAYER.create();
ServerPlayerEntity player = (ServerPlayerEntity) entity;
if( player.getEntityWorld() == world )
if( player.getCommandSenderWorld() == world )
{
player.connection.setPlayerLocation(
player.connection.teleport(
pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, 0, 0,
EnumSet.noneOf( SPlayerPositionLookPacket.Flags.class )
);
}
else
{
player.teleport( (ServerWorld) world,
player.teleportTo( (ServerWorld) world,
pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, 0, 0
);
}
@@ -219,7 +219,7 @@ public final class CommandComputerCraft
.requires( UserLevel.OP )
.arg( "computer", oneComputer() )
.executes( context -> {
ServerPlayerEntity player = context.getSource().asPlayer();
ServerPlayerEntity player = context.getSource().getPlayerOrException();
ServerComputer computer = getComputerArgument( context, "computer" );
new ViewComputerContainerData( computer ).open( player, new INamedContainerProvider()
{
@@ -247,7 +247,7 @@ public final class CommandComputerCraft
getTimingContext( context.getSource() ).start();
String stopCommand = "/computercraft track stop";
context.getSource().sendFeedback( translate( "commands.computercraft.track.start.stop",
context.getSource().sendSuccess( translate( "commands.computercraft.track.start.stop",
link( text( stopCommand ), stopCommand, translate( "commands.computercraft.track.stop.action" ) ) ), false );
return 1;
} ) )
@@ -288,11 +288,11 @@ public final class CommandComputerCraft
// Append the computer instance
if( serverComputer == null )
{
out.appendSibling( text( "?" ) );
out.append( text( "?" ) );
}
else
{
out.appendSibling( link(
out.append( link(
text( Integer.toString( serverComputer.getInstanceID() ) ),
"/computercraft dump " + serverComputer.getInstanceID(),
translate( "commands.computercraft.dump.action" )
@@ -300,20 +300,20 @@ public final class CommandComputerCraft
}
// And ID
out.appendText( " (id " + computerId + ")" );
out.append( " (id " + computerId + ")" );
// And, if we're a player, some useful links
if( serverComputer != null && UserLevel.OP.test( source ) && isPlayer( source ) )
{
out
.appendText( " " )
.appendSibling( link(
.append( " " )
.append( link(
text( "\u261b" ),
"/computercraft tp " + serverComputer.getInstanceID(),
translate( "commands.computercraft.tp.action" )
) )
.appendText( " " )
.appendSibling( link(
.append( " " )
.append( link(
text( "\u20e2" ),
"/computercraft view " + serverComputer.getInstanceID(),
translate( "commands.computercraft.view.action" )
@@ -343,7 +343,7 @@ public final class CommandComputerCraft
private static TrackingContext getTimingContext( CommandSource source )
{
Entity entity = source.getEntity();
return entity instanceof PlayerEntity ? Tracking.getContext( entity.getUniqueID() ) : Tracking.getContext( SYSTEM_UUID );
return entity instanceof PlayerEntity ? Tracking.getContext( entity.getUUID() ) : Tracking.getContext( SYSTEM_UUID );
}
private static final List<TrackingField> DEFAULT_FIELDS = Arrays.asList( TrackingField.TASKS, TrackingField.TOTAL_TIME, TrackingField.AVERAGE_TIME, TrackingField.MAX_TIME );

View File

@@ -38,7 +38,7 @@ public final class CommandCopy
.then( literal( "copy" ) )
.then( argument( "message", StringArgumentType.greedyString() ) )
.executes( context -> {
Minecraft.getInstance().keyboardListener.setClipboardString( context.getArgument( "message", String.class ) );
Minecraft.getInstance().keyboardHandler.setClipboard( context.getArgument( "message", String.class ) );
return 1;
} )
);
@@ -50,7 +50,7 @@ public final class CommandCopy
// Emulate the command on the client side
if( event.getMessage().startsWith( PREFIX ) )
{
Minecraft.getInstance().keyboardListener.setClipboardString( event.getMessage().substring( PREFIX.length() ) );
Minecraft.getInstance().keyboardHandler.setClipboard( event.getMessage().substring( PREFIX.length() ) );
event.setCanceled( true );
}
}

View File

@@ -45,7 +45,7 @@ public final class CommandUtils
}
else
{
return ((ISuggestionProvider) source).getSuggestionsFromServer( (CommandContext<ISuggestionProvider>) context, builder );
return ((ISuggestionProvider) source).customSuggestion( (CommandContext<ISuggestionProvider>) context, builder );
}
}

View File

@@ -61,12 +61,12 @@ public enum UserLevel implements Predicate<CommandSource>
MinecraftServer server = source.getServer();
Entity sender = source.getEntity();
if( server.isSinglePlayer() && sender instanceof PlayerEntity &&
if( server.isSingleplayer() && sender instanceof PlayerEntity &&
((PlayerEntity) sender).getGameProfile().getName().equalsIgnoreCase( server.getServerModName() ) )
{
if( this == OWNER || this == OWNER_OP ) return true;
}
return source.hasPermissionLevel( toLevel() );
return source.hasPermission( toLevel() );
}
}

View File

@@ -175,20 +175,20 @@ public final class ComputersArgumentType implements ArgumentType<ComputersArgume
{
@Override
public void write( @Nonnull ComputersArgumentType arg, @Nonnull PacketBuffer buf )
public void serializeToNetwork( @Nonnull ComputersArgumentType arg, @Nonnull PacketBuffer buf )
{
buf.writeBoolean( arg.requireSome );
}
@Nonnull
@Override
public ComputersArgumentType read( @Nonnull PacketBuffer buf )
public ComputersArgumentType deserializeFromNetwork( @Nonnull PacketBuffer buf )
{
return buf.readBoolean() ? SOME : MANY;
}
@Override
public void write( @Nonnull ComputersArgumentType arg, @Nonnull JsonObject json )
public void serializeToJson( @Nonnull ComputersArgumentType arg, @Nonnull JsonObject json )
{
json.addProperty( "requireSome", arg.requireSome );
}

View File

@@ -56,7 +56,7 @@ public final class RepeatArgumentType<T, U> implements ArgumentType<List<T>>
public static <T> RepeatArgumentType<T, T> some( ArgumentType<T> appender, SimpleCommandExceptionType missing )
{
return new RepeatArgumentType<>( appender, List::add, true, missing );
return new RepeatArgumentType<>( appender, List::add, false, missing );
}
public static <T> RepeatArgumentType<T, List<T>> someFlat( ArgumentType<List<T>> appender, SimpleCommandExceptionType missing )
@@ -128,27 +128,27 @@ public final class RepeatArgumentType<T, U> implements ArgumentType<List<T>>
public static class Serializer implements IArgumentSerializer<RepeatArgumentType<?, ?>>
{
@Override
public void write( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull PacketBuffer buf )
public void serializeToNetwork( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull PacketBuffer buf )
{
buf.writeBoolean( arg.flatten );
ArgumentTypes.serialize( buf, arg.child );
buf.writeTextComponent( getMessage( arg ) );
buf.writeComponent( getMessage( arg ) );
}
@Nonnull
@Override
@SuppressWarnings( { "unchecked", "rawtypes" } )
public RepeatArgumentType<?, ?> read( @Nonnull PacketBuffer buf )
public RepeatArgumentType<?, ?> deserializeFromNetwork( @Nonnull PacketBuffer buf )
{
boolean isList = buf.readBoolean();
ArgumentType<?> child = ArgumentTypes.deserialize( buf );
ITextComponent message = buf.readTextComponent();
ITextComponent message = buf.readComponent();
BiConsumer<List<Object>, ?> appender = isList ? ( list, x ) -> list.addAll( (Collection) x ) : List::add;
return new RepeatArgumentType( child, appender, isList, new SimpleCommandExceptionType( message ) );
}
@Override
public void write( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull JsonObject json )
public void serializeToJson( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull JsonObject json )
{
json.addProperty( "flatten", arg.flatten );
json.addProperty( "child", "<<cannot serialize>>" ); // TODO: Potentially serialize this using reflection.

Some files were not shown because too many files have changed in this diff Show More