1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-21 17:07:39 +00:00

Compare commits

..

61 Commits

Author SHA1 Message Date
SquidDev
0f82a4589b Fix complaints 2019-12-24 19:31:14 +00:00
SquidDev
4320a4f851 Update CT integration
Sadly we have to disable -Werror, as the annotation class files are not
available on maven, so this produces a warning.
2019-12-24 19:16:06 +00:00
SquidDev
037cbabb32 Merge branch 'master' into mc-1.14.x
Unfortunately we can't apply the config changes due to backwards
compatibility. This'll be something we may need to PR into Forge.

CraftTweaker support still needs to be added.
2019-12-23 22:34:30 +00:00
SquidDev
0dde859582 Bump version 2019-12-23 22:10:32 +00:00
SquidDev
e59c043fb6 Fix a couple of comments to use the new config names 2019-12-23 21:34:03 +00:00
SquidDev
ae928c4397 Make http domain configuration a little clearer 2019-12-23 18:59:36 +00:00
SquidDev
da41c65128 Update proguard configuration
- Remove redundant preservation of cobalt lib constructors. We use
   lambdas now, so this is no longer needed.
 - Fix Java crypto lib not being included.
2019-12-23 18:54:19 +00:00
SquidDev
4d18234714 Use a fake network handler too
It appears that WB opens containers manually, and thus all of our stubs
network stubs are entirely ignored. Thus the only solution here is to
stub out the whole network handler code.

Thankfully this is simple enough - we do the same for Plethora and 1.14.

Fixes #328
2019-12-23 17:17:32 +00:00
JakobDev
d254c6464b Add more MOTD messages again (#241) 2019-12-23 14:43:48 +00:00
Jonathan Coates
3a5d50e572 Basic Minetweaker support (#327)
This provides the following methods:

 - dan200.computercraft.turtle.removeUpgrade(id: String)
 - dan200.computercraft.turtle.removeUpgrade(stack: IItemStack)
 - dan200.computercraft.turtle.addTool(id: String, craftItem: IItemStack[, toolItem: IItemStack][, kind: string])

While it's pretty minimal, it should allow for a reasonable amount of
functionality.

Closes #327 and #97.
2019-12-18 15:29:24 +00:00
Jonathan Coates
03b6d2f1ab Replace string.len with # 2019-12-10 18:55:11 +00:00
Jared Allard
b0397ed3c5 Add support for HTTP PATCH and TRACE (#324) 2019-12-08 17:10:58 +00:00
Jonathan Coates
fa70ebcac2 Fix spacing on all of the rom (#323) 2019-12-07 10:33:47 +00:00
SquidDev
86e0330100 Lint bios and the rom (#321)
We now use illuaminate[1]'s linting facilities to check the rom and
bios.lua for a couple of common bugs and other problems.

Right now this doesn't detect any especially important bugs, though it
has caught lots of small things (unused variables, some noisy code). In
the future, the linter will grow in scope and features, which should
allow us to be stricter and catch most issues.

As a fun aside, we started off with ~150 bugs, and illuaminate was able
to fix all but 30 of them, which is pretty neat.

[1]: https://github.com/SquidDev/illuaminate
2019-12-03 23:26:13 +00:00
SquidDev
92567b4d7e Merge branch 'master' into mc-1.14.x 2019-11-29 20:23:56 +00:00
SquidDev
0ae70fed13 Correctly implement mouse movement within read
Note to self: if you're going to modify the rom, make sure you test on a
computer which doesn't overwrite the rom with something else.
2019-11-29 20:15:58 +00:00
SquidDev
3b7300543a Correctly invalidate the ROM mount cache
Before it would remain the same across world reloads, and thus would be
out-of-date after leaving the first world. This architecture technically
allows for running multiple servers at once, though that's not going to
matter that soon.
2019-11-26 18:16:49 +00:00
SquidDev
642351af1a Merge branch 'master' into mc-1.14.x 2019-11-25 09:15:20 +00:00
SquidDev
121802a683 Bump version 2019-11-25 08:58:36 +00:00
SquidDev
08cf55e55f Correct implementation of clamp
That's what I get for inlining definitions.
2019-11-23 14:36:43 +00:00
SquidDev
3c8c0d78ef Use correct render type for turtles
This fixes them not rendering particles when broken. Particle rendering
is a little janky right now, as it uses the whole texture - we should
probably split up the texture into smaller images. Fixes #315
2019-11-23 13:24:36 +00:00
SquidDev
c4d18aa9ca Allow navigating read's input using the mouse 2019-11-23 13:21:07 +00:00
SquidDev
2d4a87adc9 Fix the eye height for turtle fake players
This was causing the eye height of the turtle to be above it when
placing down, causing all sorts of funkiness. Fixes #297
2019-11-23 13:05:26 +00:00
SquidDev
bedac71e3d Add a fake network handler to the TurtleFakePlayer
This should fix several issues (see #304, etc...). I'll try to get round
to PRing this into Forge at some point, though on the other hand this is
/super/ ugly.
2019-11-23 12:12:02 +00:00
SquidDev
ee4e42e730 Dont' remove treasure disks from JEI
This shouldn't matter either way - we don't expose it in the creative
menu, and there's no recipes for it. This should shut up a log message
though. Fixes #305.
2019-11-23 11:23:25 +00:00
SquidDev
0de75f05dd Make parameter name a bit nicer
Woops
2019-11-23 11:17:03 +00:00
SquidDev
be6dd21e54 Make monitors "properly" solid blocks
This fixes monitor rendering underwater (closes #314). By default,
isSolid returns true if the render layer is SOLID. As we use CUTOUT due
to our funky TE rendering, we need to override this to return true
anyway.

This will cause some side effects, as monitors now blocking light
propagation, but I don't think that's the end of the world.
2019-11-23 10:31:55 +00:00
SquidDev
927ddb0bde Remove Charset and MCMP integration for now
It's not clear if either of these are coming back soon, and it should be
fairly simple to add them back when needed.
2019-11-23 10:14:32 +00:00
SquidDev
a8fadabaf1 Correct spelling in error message 2019-11-23 09:59:37 +00:00
SquidDev
44d0f78c1b Bump versions 2019-11-23 09:58:54 +00:00
SquidDev
38f9a015ca Wrap all remaining uses of Grgit
This allows you to build from a zip folder of CC:T. Fixes #307. Also fix
the build, woops.
2019-10-30 17:07:29 +00:00
SquidDev
c311cdc6f5 Make our Javadoc validation a little stricter
I'm not sure there's much utility in this, but still feels worth doing.
2019-10-27 15:16:47 +00:00
SquidDev
a93e0f3284 Expose ArgumentHelper in the public API
This is sufficiently useful a class, that it's worthwhile exposing it.
Hopefully we can slowly encourage other mods to migrate to it (well, at
least in 1.14), and so make error messages more consistent.

Also:
 - Add Javadoc for all public methods
 - Clarify the method names a little (getNumber -> getDouble,
   getReal -> getFiniteDouble).
 - Make the *Table methods return a Map<?,?> instead of
   Map<Object, Object>.
2019-10-27 14:29:07 +00:00
SquidDev
14b3065ba4 Check for trailing whitespace
I'd rather assumed one of the existing checkers did this already, but
apparently not.
2019-10-16 09:22:38 +01:00
SquidDev
3ea2d6a0a8 Merge branch 'master' into mc-1.14.x 2019-10-04 19:56:49 +01:00
SquidDev
c802290437 Bump version 2019-10-04 19:52:02 +01:00
SquidDev
f7781defe5 Merge branch 'master' into mc-1.14.x 2019-10-04 19:44:34 +01:00
SquidDev
418420523a Proxy the current turtle's inventory
Previously we were just returning the current tile. However, if someone
was holding a reference to this inventory (such as a GUI), then it'd be
outdated and invalid once the turtle had moved.

This caused a couple of issues:
 - turtle_inventory events would not be fired when moving items in the
   turtle GUI.
 - As of 75e2845c01, turtles would no
   longer share their inventory state after moving. Thus, removing items
   from a GUI using an invalid inventory would move them from an old
   tile, duplicating the items.

Fixes #298, fixes #300
2019-10-04 16:53:48 +01:00
SquidDev
d342a1f368 Prevent wired modems dropping on block change
Fixes #303
2019-10-01 20:06:38 +01:00
SquidDev
81f85361d5 Move Lua files to the correct location
I really need to fix this.
2019-10-01 19:43:03 +01:00
SquidDev
f1621b30ec Remove redundant imports 2019-10-01 19:15:13 +01:00
SquidDev
d4f6a594b6 Merge branch 'master' into mc-1.14.x 2019-10-01 18:58:40 +01:00
SquidDev
ff5ba5c131 Update GUI code to be compatible with 1.14.4
Not quite sure when this changed, but I'm fairly sure isMouseOver wasn't
a thing when I wrote this. Or I'm a plonker. Both are possible.

Also fixes mouse dragging not being handled in turtles.

Fixes #299
2019-10-01 18:53:46 +01:00
SquidDev
4243f30308 Bump Forge version 2019-10-01 18:53:38 +01:00
Jonathan Coates
813e91073d Merge pull request #302 from Wendelstein7/master
Fixed turtle property category
2019-09-30 15:59:55 +01:00
Jonathan Coates
7250f22ff6 Update CI to also run on PRs 2019-09-30 15:37:52 +01:00
Wendelstein7
db31a53bba Fixed turtle property category
Likely was a leftover from copy pasting and a tired programmer.
2019-09-30 15:15:22 +02:00
SquidDev
3023f235a4 Goodbye Travis, I'm with GH Actions now 2019-09-27 08:56:53 +01:00
SquidDev
79cd8b4da5 Also return the number of affected entities
Closes #293. Doesn't really solve anything there aside from exposing the
number, but sadly there's not really anything obvious I can do on my end
- the command API just doesn't expose anything else.
2019-09-15 18:48:51 +01:00
Jonathan Coates
8e4d311cd9 Refactor shell completion into a separate module (#281)
- Adds cc.completions module, with a couple of helper functions for
   working with the more general completion functionality (i.e. that
   provided by read).
 - Adds cc.shell.completions module, which provides shell-specific
   completion functions.
 - Add a "program completion builder", which allows you to write stuff
   like this:

       shell.setCompletionFunction( "rom/programs/redstone.lua", 
         completion.build(
           { completion.choice, { "probe", "set ", "pulse " } },
           completion.side) )

Closes #232
2019-09-15 18:48:40 +01:00
SquidDev
9bd8c86a94 Change event priority to HIGHEST
See the comments in a802f25dd6 -
effectively we want to make sure we arrive before any other thing which
may capture items (some magnet mods, etc...).
2019-09-15 16:42:21 +01:00
Jonathan Coates
cbc0c1d0b6 A little experiment with GitHub actions
Let's give this a go.
2019-09-14 09:16:13 +01:00
SquidDev
49c37857d4 Window.reposition now allow changing the redirect buffer
See #270
2019-09-13 20:55:20 +01:00
SquidDev
b1139a4bf6 Bump to Forge RB 2019-09-12 21:09:57 +01:00
Jonathan Coates
7e8559278e Merge pull request #291 from parly/patch-1.14.x-1
Fix os.time() and os.day() behavior on 1.14
2019-08-19 15:34:20 +01:00
parly
1e7f1c98fc Fix os.time() and os.day() behavior 2019-08-19 23:04:57 +09:00
SquidDev
a802f25dd6 Do not listen to block/entity drop events
It appears several mods inject their own drops on the LOWEST priority,
meaning that we capture the existing drops, and the other mod will clear
the (now empty) drop list and add its own, resulting in dupe bugs.

While I'd argue it's somewhat dubious doing this on the LOWEST priority,
it's not a battle I'm prepared to fight. For now, we just remove the
block/entity drop handlers, and handle all drop logic when entities are
spawned.

Fixes #288
2019-08-19 10:33:53 +01:00
SquidDev
f1d6d21d6d Add back texture registration hook
I totally forgot to do this when Forge re-added this functionality.

Fixes #285
2019-08-18 16:12:16 +01:00
Jonathan Coates
a80302c513 Merge pull request #287 from Lignum/patch-1
The pettiest of spelling fixes
2019-08-15 06:59:59 +01:00
Lignum
1c46949da7 Available 2019-08-15 07:37:02 +02:00
SquidDev
46d78af068 Fix changelog being out-of-sync 2019-08-04 11:05:44 +01:00
215 changed files with 3489 additions and 2340 deletions

View File

@@ -11,5 +11,8 @@ insert_final_newline = true
[*.md] [*.md]
trim_trailing_whitespace = false trim_trailing_whitespace = false
[*.sexp]
indent_size = 2
[*.properties] [*.properties]
insert_final_newline = false insert_final_newline = false

33
.github/workflows/main-ci.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: Build
on: [push, pull_request]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Gradle
run: ./gradlew build --no-daemon
lint-lua:
name: Lint Lua
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Lint Lua code
run: |
test -d bin || mkdir bin
test -f bin/illuaminate || wget -q -Obin/illuaminate https://squiddev.cc/illuaminate/bin/illuaminate
chmod +x bin/illuaminate
bin/illuaminate lint

View File

@@ -1,35 +0,0 @@
std = "max"
ignore = {
-- Allow access to undefined globals or their fields. In the future we'll
-- define all of CC's globals within this file
'113', '143',
-- FIXME: Ignore unused arguments and loop variables
'212', '213',
-- Disable line is too long for now. It would be possible to clean
-- this up in the future.
'631',
}
-- Only run the linter on ROM and bios for now, as the treasure disks
-- are largely unsupported.
include_files = {
'src/main/resources/assets/computercraft/lua/rom',
'src/main/resources/assets/computercraft/lua/bios.lua',
'src/test/resources/test-rom',
}
files['src/main/resources/assets/computercraft/lua/bios.lua'] = {
-- Allow declaring and mutating globals
allow_defined_top = true,
ignore = { '112', '121', '122', '131', '142' },
}
files['src/main/resources/assets/computercraft/lua/rom/apis'] = {
-- APIs may define globals on the top level. We'll ignore unused globals,
-- as obviously they may be used outside that API.
allow_defined_top = true,
ignore = { '131' },
}

View File

@@ -1,14 +0,0 @@
language: java
script: ./gradlew build --no-daemon
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/s
jdk:
- openjdk8

View File

@@ -1,5 +1,5 @@
# ![CC: Tweaked](logo.png) # ![CC: Tweaked](logo.png)
[![Current build status](https://travis-ci.org/SquidDev-CC/CC-Tweaked.svg?branch=master)](https://travis-ci.org/SquidDev-CC/CC-Tweaked "Current build status") [![Download CC: Tweaked on CurseForge](http://cf.way2muchnoise.eu/title/cc-tweaked.svg)](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge") [![Current build status](https://github.com/SquidDev-CC/CC-Tweaked/workflows/Build/badge.svg)](https://github.com/SquidDev-CC/CC-Tweaked/actions "Current build status") [![Download CC: Tweaked on CurseForge](http://cf.way2muchnoise.eu/title/cc-tweaked.svg)](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers, CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
turtles and more to Minecraft. turtles and more to Minecraft.

View File

@@ -9,7 +9,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.google.code.gson:gson:2.8.1' classpath 'com.google.code.gson:gson:2.8.1'
classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.134' classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.154'
classpath 'net.sf.proguard:proguard-gradle:6.1.0beta2' classpath 'net.sf.proguard:proguard-gradle:6.1.0beta2'
classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0' classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0'
} }
@@ -81,6 +81,10 @@ repositories {
name "Amadornes" name "Amadornes"
url "https://maven.amadornes.com/" url "https://maven.amadornes.com/"
} }
maven {
name "CraftTweaker"
url "https://maven.blamejared.com/"
}
} }
configurations { configurations {
@@ -90,15 +94,14 @@ configurations {
} }
dependencies { dependencies {
checkstyle "com.puppycrawl.tools:checkstyle:8.21" checkstyle "com.puppycrawl.tools:checkstyle:8.25"
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}" minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
compileOnly fg.deobf("mezz.jei:jei-1.14.3:6.0.0.7:api") compileOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.25:api")
// deobfProvided "pl.asie:Charset-Lib:0.5.4.6" compileOnly fg.deobf("com.blamejared.crafttweaker:CraftTweaker-1.14.4:5.0.1.150")
// deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
runtimeOnly fg.deobf("mezz.jei:jei-1.14.3:6.0.0.7") runtimeOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.25")
shade 'org.squiddev:Cobalt:0.5.0-SNAPSHOT' shade 'org.squiddev:Cobalt:0.5.0-SNAPSHOT'
@@ -108,15 +111,6 @@ dependencies {
deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0" deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0"
} }
sourceSets {
main {
java {
exclude 'dan200/computercraft/shared/integration/mcmp'
exclude 'dan200/computercraft/shared/integration/charset'
}
}
}
// Compile tasks // Compile tasks
javadoc { javadoc {
@@ -145,7 +139,7 @@ jar {
[compileJava, compileTestJava].forEach { [compileJava, compileTestJava].forEach {
it.configure { it.configure {
options.compilerArgs << "-Xlint" << "-Xlint:-processing" << "-Werror" options.compilerArgs << "-Xlint" << "-Xlint:-processing"
} }
} }
@@ -171,6 +165,7 @@ task proguard(type: ProGuardTask, dependsOn: jar) {
// Add the main runtime jar and all non-shadowed dependencies // Add the main runtime jar and all non-shadowed dependencies
libraryjars "${System.getProperty('java.home')}/lib/rt.jar" libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
libraryjars "${System.getProperty('java.home')}/lib/jce.jar"
doFirst { doFirst {
sourceSets.main.compileClasspath sourceSets.main.compileClasspath
.filter { !it.name.contains("Cobalt") } .filter { !it.name.contains("Cobalt") }
@@ -186,9 +181,6 @@ task proguard(type: ProGuardTask, dependsOn: jar) {
// Preserve ComputerCraft classes - we only want to strip shadowed files. // Preserve ComputerCraft classes - we only want to strip shadowed files.
keep 'class dan200.computercraft.** { *; }' keep 'class dan200.computercraft.** { *; }'
// Preserve the constructors in Cobalt library class, as we init them via reflection
keepclassmembers 'class org.squiddev.cobalt.lib.** { <init>(...); }'
// LWJGL and Apache bundle Java 9 versions, which is great, but rather breaks Proguard // LWJGL and Apache bundle Java 9 versions, which is great, but rather breaks Proguard
dontwarn 'module-info' dontwarn 'module-info'
dontwarn 'org.apache.**,org.lwjgl.**' dontwarn 'org.apache.**,org.lwjgl.**'
@@ -374,6 +366,7 @@ task checkRelease {
if (!ok) throw new IllegalStateException("Could not check release") if (!ok) throw new IllegalStateException("Could not check release")
} }
} }
check.dependsOn checkRelease
curseforge { curseforge {
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : '' apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
@@ -445,7 +438,9 @@ githubRelease {
token project.hasProperty('githubApiKey') ? project.githubApiKey : '' token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
owner 'SquidDev-CC' owner 'SquidDev-CC'
repo 'CC-Tweaked' repo 'CC-Tweaked'
targetCommitish { Grgit.open(dir: '.').branch.current().name } try {
targetCommitish = Grgit.open(dir: '.').branch.current().name
} catch(Exception ignored) { }
tagName "v${mc_version}-${mod_version}" tagName "v${mc_version}-${mod_version}"
releaseName "[${mc_version}] ${mod_version}" releaseName "[${mc_version}] ${mod_version}"

View File

@@ -14,9 +14,7 @@
<!-- Annotations --> <!-- Annotations -->
<module name="AnnotationLocation" /> <module name="AnnotationLocation" />
<module name="AnnotationUseStyle" /> <module name="AnnotationUseStyle" />
<module name="MissingDeprecated"> <module name="MissingDeprecated" />
<property name="skipNoJavadoc" value="true" />
</module>
<module name="MissingOverride" /> <module name="MissingOverride" />
<!-- Blocks --> <!-- Blocks -->
@@ -57,6 +55,9 @@
<module name="SimplifyBooleanReturn" /> <module name="SimplifyBooleanReturn" />
<module name="StringLiteralEquality" /> <module name="StringLiteralEquality" />
<module name="UnnecessaryParentheses" /> <module name="UnnecessaryParentheses" />
<module name="UnnecessarySemicolonAfterTypeMemberDeclaration" />
<module name="UnnecessarySemicolonInTryWithResources" />
<module name="UnnecessarySemicolonInEnumeration" />
<!-- Imports --> <!-- Imports -->
<module name="CustomImportOrder" /> <module name="CustomImportOrder" />
@@ -65,10 +66,16 @@
<module name="UnusedImports" /> <module name="UnusedImports" />
<!-- Javadoc --> <!-- Javadoc -->
<!-- TODO: Missing* checks for the dan200.computercraft.api package? -->
<module name="AtclauseOrder" /> <module name="AtclauseOrder" />
<!-- TODO: Cleanup our documentation before enabling JavadocMethod, JavadocStyle, JavadocType and SummaryJavadoc. --> <module name="InvalidJavadocPosition" />
<module name="JavadocBlockTagLocation" />
<module name="JavadocMethod"/>
<module name="JavadocType"/>
<module name="JavadocStyle" />
<module name="NonEmptyAtclauseDescription" /> <module name="NonEmptyAtclauseDescription" />
<module name="SingleLineJavadoc" /> <module name="SingleLineJavadoc" />
<module name="SummaryJavadocCheck"/>
<!-- Misc --> <!-- Misc -->
<module name="ArrayTypeStyle" /> <module name="ArrayTypeStyle" />
@@ -155,5 +162,8 @@
<module name="FileTabCharacter" /> <module name="FileTabCharacter" />
<module name="NewlineAtEndOfFile" /> <module name="NewlineAtEndOfFile" />
<module name="RegexpSingleline">
<property name="format" value="\s+$"/>
<property name="message" value="Trailing whitespace"/>
</module>
</module> </module>

View File

@@ -6,4 +6,7 @@
<!-- All the config options and method fields. --> <!-- All the config options and method fields. -->
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraft.java" /> <suppress checks="StaticVariableName" files=".*[\\/]ComputerCraft.java" />
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraftAPI.java" /> <suppress checks="StaticVariableName" files=".*[\\/]ComputerCraftAPI.java" />
<!-- Do not check for missing package Javadoc. -->
<suppress checks="JavadocStyle" files=".*[\\/]package-info.java" />
</suppressions> </suppressions>

View File

@@ -1,7 +1,7 @@
# Mod properties # Mod properties
mod_version=1.84.1 mod_version=1.86.0
# Minecraft properties # Minecraft properties (update mods.toml when changing)
mc_version=1.14.4 mc_version=1.14.4
forge_version=28.0.45 forge_version=28.1.71
mappings_version=20190806-1.14.3 mappings_version=20191123-1.14.3

28
illuaminate.sexp Normal file
View File

@@ -0,0 +1,28 @@
; -*- mode: Lisp;-*-
(sources
/src/main/resources/assets/computercraft/lua/bios.lua
/src/main/resources/assets/computercraft/lua/rom/
/src/test/resources/test-rom)
(at /
(linters
;; It'd be nice to avoid this, but right now there's a lot of instances of
;; it.
-var:set-loop
;; It's useful to name arguments for documentation, so we allow this. It'd
;; be good to find a compromise in the future, but this works for now.
-var:unused-arg))
;; We disable the unused global linter in bios.lua and the APIs. In the future
;; hopefully we'll get illuaminate to handle this.
(at
(/src/main/resources/assets/computercraft/lua/bios.lua
/src/main/resources/assets/computercraft/lua/rom/apis/)
(linters -var:unused-global)
(lint
(allow-toplevel-global true)))
;; These warnings are broken right now
(at (bios.lua worm.lua) (linters -control:unreachable))

View File

@@ -6,11 +6,9 @@
package dan200.computercraft; package dan200.computercraft;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.turtle.event.TurtleAction; import dan200.computercraft.api.turtle.event.TurtleAction;
import dan200.computercraft.core.apis.AddressPredicate; import dan200.computercraft.core.apis.AddressPredicate;
import dan200.computercraft.core.apis.http.websocket.Websocket; import dan200.computercraft.core.apis.http.websocket.Websocket;
import dan200.computercraft.core.filesystem.ResourceMount;
import dan200.computercraft.shared.Config; import dan200.computercraft.shared.Config;
import dan200.computercraft.shared.computer.blocks.BlockComputer; import dan200.computercraft.shared.computer.blocks.BlockComputer;
import dan200.computercraft.shared.computer.core.ClientComputerRegistry; import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
@@ -194,13 +192,6 @@ public final class ComputerCraft
return "${version}"; return "${version}";
} }
static IMount createResourceMount( String domain, String subPath )
{
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
ResourceMount mount = new ResourceMount( domain, subPath, manager );
return mount.exists( "" ) ? mount : null;
}
public static InputStream getResourceFile( String domain, String subPath ) public static InputStream getResourceFile( String domain, String subPath )
{ {
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager(); IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();

View File

@@ -6,6 +6,7 @@
package dan200.computercraft; package dan200.computercraft;
import com.google.common.collect.MapMaker;
import dan200.computercraft.api.ComputerCraftAPI.IComputerCraftAPI; import dan200.computercraft.api.ComputerCraftAPI.IComputerCraftAPI;
import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount; import dan200.computercraft.api.filesystem.IWritableMount;
@@ -20,20 +21,26 @@ import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.core.apis.ApiFactories; import dan200.computercraft.core.apis.ApiFactories;
import dan200.computercraft.core.filesystem.FileMount; import dan200.computercraft.core.filesystem.FileMount;
import dan200.computercraft.core.filesystem.ResourceMount;
import dan200.computercraft.shared.*; import dan200.computercraft.shared.*;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork; import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
import dan200.computercraft.shared.util.IDAssigner; import dan200.computercraft.shared.util.IDAssigner;
import dan200.computercraft.shared.wired.CapabilityWiredElement; import dan200.computercraft.shared.wired.CapabilityWiredElement;
import dan200.computercraft.shared.wired.WiredNode; import dan200.computercraft.shared.wired.WiredNode;
import net.minecraft.resources.IReloadableResourceManager;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.io.File; import java.io.File;
import java.lang.ref.WeakReference;
import java.util.Map;
public final class ComputerCraftAPIImpl implements IComputerCraftAPI public final class ComputerCraftAPIImpl implements IComputerCraftAPI
{ {
@@ -43,6 +50,9 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
{ {
} }
private WeakReference<IReloadableResourceManager> currentResources;
private final Map<ResourceLocation, ResourceMount> mountCache = new MapMaker().weakValues().concurrencyLevel( 1 ).makeMap();
@Nonnull @Nonnull
@Override @Override
public String getInstalledVersion() public String getInstalledVersion()
@@ -72,7 +82,9 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
@Override @Override
public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath ) public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
{ {
return ComputerCraft.createResourceMount( domain, subPath ); IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
ResourceMount mount = ResourceMount.get( domain, subPath, manager );
return mount.exists( "" ) ? mount : null;
} }
@Override @Override

View File

@@ -31,8 +31,9 @@ import javax.annotation.Nullable;
/** /**
* The static entry point to the ComputerCraft API. * The static entry point to the ComputerCraft API.
* Members in this class must be called after mod_ComputerCraft has been initialised, *
* but may be called before it is fully loaded. * Members in this class must be called after mod_ComputerCraft has been initialised, but may be called before it is
* fully loaded.
*/ */
public final class ComputerCraftAPI public final class ComputerCraftAPI
{ {
@@ -189,7 +190,7 @@ public final class ComputerCraftAPI
} }
/** /**
* Registers a media provider to provide {@link IMedia} implementations for Items * Registers a media provider to provide {@link IMedia} implementations for Items.
* *
* @param provider The media provider to register. * @param provider The media provider to register.
* @see IMediaProvider * @see IMediaProvider
@@ -220,7 +221,7 @@ public final class ComputerCraftAPI
} }
/** /**
* Construct a new wired node for a given wired element * Construct a new wired node for a given wired element.
* *
* @param element The element to construct it for * @param element The element to construct it for
* @return The element's node * @return The element's node
@@ -233,7 +234,7 @@ public final class ComputerCraftAPI
} }
/** /**
* Get the wired network element for a block in world * Get the wired network element for a block in world.
* *
* @param world The world the block exists in * @param world The world the block exists in
* @param pos The position the block exists in * @param pos The position the block exists in

View File

@@ -19,7 +19,7 @@ import java.util.List;
/** /**
* Represents a read only part of a virtual filesystem that can be mounted onto a computer using * Represents a read only part of a virtual filesystem that can be mounted onto a computer using
* {@link IComputerAccess#mount(String, IMount)} * {@link IComputerAccess#mount(String, IMount)}.
* *
* Ready made implementations of this interface can be created using * Ready made implementations of this interface can be created using
* {@link ComputerCraftAPI#createSaveDirMount(World, String, long)} or * {@link ComputerCraftAPI#createSaveDirMount(World, String, long)} or
@@ -60,7 +60,7 @@ public interface IMount
void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException; void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException;
/** /**
* Returns the size of a file with a given path, in bytes * Returns the size of a file with a given path, in bytes.
* *
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram". * @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
* @return The size of the file, in bytes. * @return The size of the file, in bytes.

View File

@@ -0,0 +1,335 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
/**
* Provides methods for extracting values and validating Lua arguments, such as those provided to
* {@link ILuaObject#callMethod(ILuaContext, int, Object[])} or
* {@link IPeripheral#callMethod(IComputerAccess, ILuaContext, int, Object[])}.
*
* This provides two sets of functions: the {@code get*} methods, which require an argument to be valid, and
* {@code opt*}, which accept a default value and return that if the argument was not present or was {@code null}.
* If the argument is of the wrong type, a suitable error message will be thrown, with a similar format to Lua's own
* error messages.
*
* <h2>Example usage:</h2>
* <pre>
* {@code
* int slot = getInt( args, 0 );
* int amount = optInt( args, 1, 64 );
* }
* </pre>
*/
public final class ArgumentHelper
{
private ArgumentHelper()
{
}
/**
* Get a string representation of the given value's type.
*
* @param value The value whose type we are trying to compute.
* @return A string representation of the given value's type, in a similar format to that provided by Lua's
* {@code type} function.
*/
@Nonnull
public static String getType( @Nullable Object value )
{
if( value == null ) return "nil";
if( value instanceof String ) return "string";
if( value instanceof Boolean ) return "boolean";
if( value instanceof Number ) return "number";
if( value instanceof Map ) return "table";
return "userdata";
}
/**
* Construct a "bad argument" exception, from an expected type and the actual value provided.
*
* @param index The argument number, starting from 0.
* @param expected The expected type for this argument.
* @param actual The actual value provided for this argument.
* @return The constructed exception, which should be thrown immediately.
*/
@Nonnull
public static LuaException badArgumentOf( int index, @Nonnull String expected, @Nullable Object actual )
{
return badArgument( index, expected, getType( actual ) );
}
/**
* Construct a "bad argument" exception, from an expected and actual type.
*
* @param index The argument number, starting from 0.
* @param expected The expected type for this argument.
* @param actual The provided type for this argument.
* @return The constructed exception, which should be thrown immediately.
*/
@Nonnull
public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual )
{
return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" );
}
/**
* Get an argument as a double.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a number.
* @see #getFiniteDouble(Object[], int) if you require this to be finite (i.e. not infinite or NaN).
*/
public static double getDouble( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "nil" );
Object value = args[index];
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return ((Number) value).doubleValue();
}
/**
* Get an argument as an integer.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not an integer.
*/
public static int getInt( @Nonnull Object[] args, int index ) throws LuaException
{
return (int) getLong( args, index );
}
/**
* Get an argument as a long.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a long.
*/
public static long getLong( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "nil" );
Object value = args[index];
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return checkFinite( index, (Number) value ).longValue();
}
/**
* Get an argument as a finite number (not infinite or NaN).
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not finite.
*/
public static double getFiniteDouble( @Nonnull Object[] args, int index ) throws LuaException
{
return checkFinite( index, getDouble( args, index ) );
}
/**
* Get an argument as a boolean.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a boolean.
*/
public static boolean getBoolean( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "boolean", "nil" );
Object value = args[index];
if( !(value instanceof Boolean) ) throw badArgumentOf( index, "boolean", value );
return (Boolean) value;
}
/**
* Get an argument as a string.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a string.
*/
@Nonnull
public static String getString( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "string", "nil" );
Object value = args[index];
if( !(value instanceof String) ) throw badArgumentOf( index, "string", value );
return (String) value;
}
/**
* Get an argument as a table.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a table.
*/
@Nonnull
public static Map<?, ?> getTable( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "table", "nil" );
Object value = args[index];
if( !(value instanceof Map) ) throw badArgumentOf( index, "table", value );
return (Map<?, ?>) value;
}
/**
* Get an argument as a double.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number.
*/
public static double optDouble( @Nonnull Object[] args, int index, double def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return ((Number) value).doubleValue();
}
/**
* Get an argument as an int.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number.
*/
public static int optInt( @Nonnull Object[] args, int index, int def ) throws LuaException
{
return (int) optLong( args, index, def );
}
/**
* Get an argument as a long.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number.
*/
public static long optLong( @Nonnull Object[] args, int index, long def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return checkFinite( index, (Number) value ).longValue();
}
/**
* Get an argument as a finite number (not infinite or NaN).
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not finite.
*/
public static double optFiniteDouble( @Nonnull Object[] args, int index, double def ) throws LuaException
{
return checkFinite( index, optDouble( args, index, def ) );
}
/**
* Get an argument as a boolean.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a boolean.
*/
public static boolean optBoolean( @Nonnull Object[] args, int index, boolean def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Boolean) ) throw badArgumentOf( index, "boolean", value );
return (Boolean) value;
}
/**
* Get an argument as a string.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a string.
*/
public static String optString( @Nonnull Object[] args, int index, String def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof String) ) throw badArgumentOf( index, "string", value );
return (String) value;
}
/**
* Get an argument as a table.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a table.
*/
public static Map<?, ?> optTable( @Nonnull Object[] args, int index, Map<Object, Object> def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Map) ) throw badArgumentOf( index, "table", value );
return (Map<?, ?>) value;
}
private static Number checkFinite( int index, Number value ) throws LuaException
{
checkFinite( index, value.doubleValue() );
return value;
}
private static double checkFinite( int index, double value ) throws LuaException
{
if( !Double.isFinite( value ) ) throw badArgument( index, "number", getNumericType( value ) );
return value;
}
/**
* Returns a more detailed representation of this number's type. If this is finite, it will just return "number",
* otherwise it returns whether it is infinite or NaN.
*
* @param value The value to extract the type for.
* @return This value's numeric type.
*/
@Nonnull
public static String getNumericType( double value )
{
if( Double.isNaN( value ) ) return "nan";
if( value == Double.POSITIVE_INFINITY ) return "inf";
if( value == Double.NEGATIVE_INFINITY ) return "-inf";
return "number";
}
}

View File

@@ -26,7 +26,7 @@ public interface IComputerSystem extends IComputerAccess
IFileSystem getFileSystem(); IFileSystem getFileSystem();
/** /**
* Get the label for this computer * Get the label for this computer.
* *
* @return This computer's label, or {@code null} if it is not set. * @return This computer's label, or {@code null} if it is not set.
*/ */

View File

@@ -6,6 +6,7 @@
package dan200.computercraft.api.peripheral; package dan200.computercraft.api.peripheral;
import dan200.computercraft.api.lua.ArgumentHelper;
import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaException;
@@ -58,9 +59,11 @@ public interface IPeripheral
* Lua values of type "table" will be represented by Object type Map.<br> * Lua values of type "table" will be represented by Object type Map.<br>
* Lua values of any other type will be represented by a null object.<br> * Lua values of any other type will be represented by a null object.<br>
* This array will be empty if no arguments are passed. * This array will be empty if no arguments are passed.
*
* It is recommended you use {@link ArgumentHelper} in order to validate and process arguments.
* @return An array of objects, representing values you wish to return to the lua program. Integers, Doubles, Floats, * @return An array of objects, representing values you wish to return to the lua program. Integers, Doubles, Floats,
* Strings, Booleans, Maps and ILuaObject and null be converted to their corresponding lua type. All other types * Strings, Booleans, Maps, ILuaObject and null be converted to their corresponding lua type. All other types will
* will be converted to nil. * be converted to nil.
* *
* You may return null to indicate no values should be returned. * You may return null to indicate no values should be returned.
* @throws LuaException If you throw any exception from this function, a lua error will be raised with the * @throws LuaException If you throw any exception from this function, a lua error will be raised with the
@@ -70,6 +73,7 @@ public interface IPeripheral
* InterruptedException will be thrown. This exception must not be caught or * InterruptedException will be thrown. This exception must not be caught or
* intercepted, or the computer will leak memory and end up in a broken state. * intercepted, or the computer will leak memory and end up in a broken state.
* @see #getMethodNames * @see #getMethodNames
* @see ArgumentHelper
*/ */
@Nullable @Nullable
Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException; Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException;

View File

@@ -16,7 +16,7 @@ import javax.annotation.Nullable;
import java.util.Map; import java.util.Map;
/** /**
* Wrapper class for pocket computers * Wrapper class for pocket computers.
*/ */
public interface IPocketAccess public interface IPocketAccess
{ {

View File

@@ -12,12 +12,12 @@ package dan200.computercraft.api.turtle;
public enum TurtleSide public enum TurtleSide
{ {
/** /**
* The turtle's left side (where the pickaxe usually is on a Wireless Mining Turtle) * The turtle's left side (where the pickaxe usually is on a Wireless Mining Turtle).
*/ */
Left, Left,
/** /**
* The turtle's right side (where the modem usually is on a Wireless Mining Turtle) * The turtle's right side (where the modem usually is on a Wireless Mining Turtle).
*/ */
Right, Right,
} }

View File

@@ -18,12 +18,12 @@ import net.minecraft.util.Direction;
public enum TurtleVerb public enum TurtleVerb
{ {
/** /**
* The turtle called {@code turtle.dig()}, {@code turtle.digUp()} or {@code turtle.digDown()} * The turtle called {@code turtle.dig()}, {@code turtle.digUp()} or {@code turtle.digDown()}.
*/ */
Dig, Dig,
/** /**
* The turtle called {@code turtle.attack()}, {@code turtle.attackUp()} or {@code turtle.attackDown()} * The turtle called {@code turtle.attack()}, {@code turtle.attackUp()} or {@code turtle.attackDown()}.
*/ */
Attack, Attack,
} }

View File

@@ -71,7 +71,7 @@ public enum TurtleAction
EQUIP, EQUIP,
/** /**
* Inspect a block in world * Inspect a block in world.
* *
* @see TurtleBlockEvent.Inspect * @see TurtleBlockEvent.Inspect
*/ */

View File

@@ -112,7 +112,7 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
} }
/** /**
* Get the upgrade doing the digging * Get the upgrade doing the digging.
* *
* @return The upgrade doing the digging. * @return The upgrade doing the digging.
*/ */

View File

@@ -31,7 +31,7 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent
} }
/** /**
* Get the inventory being interacted with * Get the inventory being interacted with.
* *
* @return The inventory being interacted with, {@code null} if the item will be dropped to/sucked from the world. * @return The inventory being interacted with, {@code null} if the item will be dropped to/sucked from the world.
*/ */

View File

@@ -12,6 +12,7 @@ import dan200.computercraft.shared.common.IColouredItem;
import dan200.computercraft.shared.media.items.ItemDisk; import dan200.computercraft.shared.media.items.ItemDisk;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.Colour;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.IUnbakedModel; import net.minecraft.client.renderer.model.IUnbakedModel;
import net.minecraft.client.renderer.model.ModelResourceLocation; import net.minecraft.client.renderer.model.ModelResourceLocation;
@@ -58,8 +59,8 @@ public final class ClientRegistry
}; };
private static final String[] EXTRA_TEXTURES = new String[] { private static final String[] EXTRA_TEXTURES = new String[] {
// TODO: Gather these automatically from the model. I'm unable to get this working with Forge's current // TODO: Gather these automatically from the model. Sadly the model loader isn't available
// model loading code. // when stitching textures.
"block/turtle_colour", "block/turtle_colour",
"block/turtle_elf_overlay", "block/turtle_elf_overlay",
"block/turtle_crafty_face", "block/turtle_crafty_face",
@@ -77,13 +78,12 @@ public final class ClientRegistry
@SubscribeEvent @SubscribeEvent
public static void onTextureStitchEvent( TextureStitchEvent.Pre event ) public static void onTextureStitchEvent( TextureStitchEvent.Pre event )
{ {
/* if( event.getMap() != Minecraft.getInstance().getTextureMap() ) return;
IResourceManager manager = Minecraft.getInstance().getResourceManager();
for( String extra : EXTRA_TEXTURES ) for( String extra : EXTRA_TEXTURES )
{ {
// TODO: event.getMap().registerSprite( manager, new ResourceLocation( ComputerCraft.MOD_ID, extra ) ); event.addSprite( new ResourceLocation( ComputerCraft.MOD_ID, extra ) );
} }
*/
} }
@SubscribeEvent @SubscribeEvent

View File

@@ -176,11 +176,4 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY )) return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|| super.mouseDragged( x, y, button, deltaX, deltaY ); || super.mouseDragged( x, y, button, deltaX, deltaY );
} }
@Override
public boolean mouseReleased( double x, double y, int button )
{
return (getFocused() != null && getFocused().mouseReleased( x, y, button ))
|| super.mouseReleased( x, y, button );
}
} }

View File

@@ -129,4 +129,11 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
super.render( mouseX, mouseY, partialTicks ); super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY ); renderHoveredToolTip( mouseX, mouseY );
} }
@Override
public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
{
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|| super.mouseDragged( x, y, button, deltaX, deltaY );
}
} }

View File

@@ -241,11 +241,12 @@ public class WidgetTerminal implements IGuiEventListener
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 ); charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 ); charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
computer.mouseDrag( button + 1, charX + 1, charY + 1 ); if( button == lastMouseButton && (charX != lastMouseX || charY != lastMouseY) )
{
lastMouseX = charX; computer.mouseDrag( button + 1, charX + 1, charY + 1 );
lastMouseY = charY; lastMouseX = charX;
lastMouseButton = button; lastMouseY = charY;
}
} }
return false; return false;
@@ -427,4 +428,10 @@ public class WidgetTerminal implements IGuiEventListener
ClientComputer computer = this.computer.get(); ClientComputer computer = this.computer.get();
if( computer != null ) computer.queueEvent( event, args ); if( computer != null ) computer.queueEvent( event, args );
} }
@Override
public boolean isMouseOver( double x, double y )
{
return true;
}
} }

View File

@@ -95,4 +95,11 @@ public class WidgetWrapper implements IGuiEventListener
{ {
return height; return height;
} }
@Override
public boolean isMouseOver( double x, double y )
{
double dx = x - this.x, dy = y - this.y;
return dx >= 0 && dx < width && dy >= 0 && dy < height;
}
} }

View File

@@ -18,7 +18,7 @@ import net.minecraft.util.math.MathHelper;
public abstract class ItemMapLikeRenderer public abstract class ItemMapLikeRenderer
{ {
/** /**
* The main rendering method for the item * The main rendering method for the item.
* *
* @param stack The stack to render * @param stack The stack to render
* @see FirstPersonRenderer#renderMapFirstPerson(ItemStack) * @see FirstPersonRenderer#renderMapFirstPerson(ItemStack)
@@ -87,7 +87,7 @@ public abstract class ItemMapLikeRenderer
} }
/** /**
* Render an item in the middle of the screen * Render an item in the middle of the screen.
* *
* @param pitch The pitch of the player * @param pitch The pitch of the player
* @param equipProgress The equip progress of this item * @param equipProgress The equip progress of this item

View File

@@ -32,7 +32,7 @@ import static dan200.computercraft.client.gui.FixedWidthFontRenderer.*;
import static dan200.computercraft.client.gui.GuiComputer.*; import static dan200.computercraft.client.gui.GuiComputer.*;
/** /**
* Emulates map rendering for pocket computers * Emulates map rendering for pocket computers.
*/ */
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT ) @Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class ItemPocketRenderer extends ItemMapLikeRenderer public final class ItemPocketRenderer extends ItemMapLikeRenderer

View File

@@ -23,7 +23,7 @@ import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAG
import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH; import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH;
/** /**
* Emulates map and item-frame rendering for printouts * Emulates map and item-frame rendering for printouts.
*/ */
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT ) @Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class ItemPrintoutRenderer extends ItemMapLikeRenderer public final class ItemPrintoutRenderer extends ItemMapLikeRenderer

View File

@@ -28,32 +28,32 @@ public final class PrintoutRenderer
private static final double BG_SIZE = 256.0; private static final double BG_SIZE = 256.0;
/** /**
* Width of a page * Width of a page.
*/ */
public static final int X_SIZE = 172; public static final int X_SIZE = 172;
/** /**
* Height of a page * Height of a page.
*/ */
public static final int Y_SIZE = 209; public static final int Y_SIZE = 209;
/** /**
* Padding between the left and right of a page and the text * Padding between the left and right of a page and the text.
*/ */
public static final int X_TEXT_MARGIN = 13; public static final int X_TEXT_MARGIN = 13;
/** /**
* Padding between the top and bottom of a page and the text * Padding between the top and bottom of a page and the text.
*/ */
public static final int Y_TEXT_MARGIN = 11; public static final int Y_TEXT_MARGIN = 11;
/** /**
* Width of the extra page texture * Width of the extra page texture.
*/ */
private static final int X_FOLD_SIZE = 12; private static final int X_FOLD_SIZE = 12;
/** /**
* Size of the leather cover * Size of the leather cover.
*/ */
public static final int COVER_SIZE = 12; public static final int COVER_SIZE = 12;

View File

@@ -105,6 +105,8 @@ public class TileEntityCableRenderer extends TileEntityRenderer<TileCable>
} }
/** /**
* Set up the state for rendering block-breaking progress.
*
* @see WorldRenderer#preRenderDamagedBlocks() * @see WorldRenderer#preRenderDamagedBlocks()
*/ */
private void preRenderDamagedBlocks() private void preRenderDamagedBlocks()
@@ -123,6 +125,8 @@ public class TileEntityCableRenderer extends TileEntityRenderer<TileCable>
} }
/** /**
* Tear down the state for rendering block-breaking progress.
*
* @see WorldRenderer#postRenderDamagedBlocks() * @see WorldRenderer#postRenderDamagedBlocks()
*/ */
private void postRenderDamagedBlocks() private void postRenderDamagedBlocks()

View File

@@ -160,7 +160,7 @@ public class AddressPredicate
} }
/** /**
* Determine whether the given address matches a series of patterns * Determine whether the given address matches a series of patterns.
* *
* @param address The address to check. * @param address The address to check.
* @return Whether it matches any of these patterns. * @return Whether it matches any of these patterns.

View File

@@ -13,256 +13,106 @@ import javax.annotation.Nullable;
import java.util.Map; import java.util.Map;
/** /**
* Various helpers for arguments * A stub for any mods which depended on this version of the argument helper.
*
* @deprecated Use {@link dan200.computercraft.api.lua.ArgumentHelper}.
*/ */
@Deprecated
public final class ArgumentHelper public final class ArgumentHelper
{ {
private ArgumentHelper() private ArgumentHelper()
{ {
throw new IllegalStateException( "Cannot instantiate singleton " + getClass().getName() );
} }
@Nonnull @Nonnull
public static String getType( @Nullable Object type ) public static String getType( @Nullable Object type )
{ {
if( type == null ) return "nil"; return dan200.computercraft.api.lua.ArgumentHelper.getType( type );
if( type instanceof String ) return "string";
if( type instanceof Boolean ) return "boolean";
if( type instanceof Number ) return "number";
if( type instanceof Map ) return "table";
Class<?> klass = type.getClass();
if( klass.isArray() )
{
StringBuilder name = new StringBuilder();
while( klass.isArray() )
{
name.append( "[]" );
klass = klass.getComponentType();
}
name.insert( 0, klass.getName() );
return name.toString();
}
else
{
return klass.getName();
}
} }
@Nonnull @Nonnull
public static LuaException badArgument( int index, @Nonnull String expected, @Nullable Object actual ) public static LuaException badArgument( int index, @Nonnull String expected, @Nullable Object actual )
{ {
return badArgument( index, expected, getType( actual ) ); return dan200.computercraft.api.lua.ArgumentHelper.badArgumentOf( index, expected, actual );
} }
@Nonnull @Nonnull
public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual ) public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual )
{ {
return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" ); return dan200.computercraft.api.lua.ArgumentHelper.badArgument( index, expected, actual );
} }
public static double getNumber( @Nonnull Object[] args, int index ) throws LuaException public static double getNumber( @Nonnull Object[] args, int index ) throws LuaException
{ {
if( index >= args.length ) throw badArgument( index, "number", "nil" ); return dan200.computercraft.api.lua.ArgumentHelper.getDouble( args, index );
Object value = args[index];
if( value instanceof Number )
{
return ((Number) value).doubleValue();
}
else
{
throw badArgument( index, "number", value );
}
} }
public static int getInt( @Nonnull Object[] args, int index ) throws LuaException public static int getInt( @Nonnull Object[] args, int index ) throws LuaException
{ {
return (int) getLong( args, index ); return dan200.computercraft.api.lua.ArgumentHelper.getInt( args, index );
} }
public static long getLong( @Nonnull Object[] args, int index ) throws LuaException public static long getLong( @Nonnull Object[] args, int index ) throws LuaException
{ {
if( index >= args.length ) throw badArgument( index, "number", "nil" ); return dan200.computercraft.api.lua.ArgumentHelper.getLong( args, index );
Object value = args[index];
if( value instanceof Number )
{
return checkReal( index, (Number) value ).longValue();
}
else
{
throw badArgument( index, "number", value );
}
} }
public static double getReal( @Nonnull Object[] args, int index ) throws LuaException public static double getReal( @Nonnull Object[] args, int index ) throws LuaException
{ {
return checkReal( index, getNumber( args, index ) ); return dan200.computercraft.api.lua.ArgumentHelper.getFiniteDouble( args, index );
} }
public static boolean getBoolean( @Nonnull Object[] args, int index ) throws LuaException public static boolean getBoolean( @Nonnull Object[] args, int index ) throws LuaException
{ {
if( index >= args.length ) throw badArgument( index, "boolean", "nil" ); return dan200.computercraft.api.lua.ArgumentHelper.getBoolean( args, index );
Object value = args[index];
if( value instanceof Boolean )
{
return (Boolean) value;
}
else
{
throw badArgument( index, "boolean", value );
}
} }
@Nonnull @Nonnull
public static String getString( @Nonnull Object[] args, int index ) throws LuaException public static String getString( @Nonnull Object[] args, int index ) throws LuaException
{ {
if( index >= args.length ) throw badArgument( index, "string", "nil" ); return dan200.computercraft.api.lua.ArgumentHelper.getString( args, index );
Object value = args[index];
if( value instanceof String )
{
return (String) value;
}
else
{
throw badArgument( index, "string", value );
}
} }
@SuppressWarnings( "unchecked" )
@Nonnull @Nonnull
@SuppressWarnings( "unchecked" )
public static Map<Object, Object> getTable( @Nonnull Object[] args, int index ) throws LuaException public static Map<Object, Object> getTable( @Nonnull Object[] args, int index ) throws LuaException
{ {
if( index >= args.length ) throw badArgument( index, "table", "nil" ); return (Map<Object, Object>) dan200.computercraft.api.lua.ArgumentHelper.getTable( args, index );
Object value = args[index];
if( value instanceof Map )
{
return (Map<Object, Object>) value;
}
else
{
throw badArgument( index, "table", value );
}
} }
public static double optNumber( @Nonnull Object[] args, int index, double def ) throws LuaException public static double optNumber( @Nonnull Object[] args, int index, double def ) throws LuaException
{ {
Object value = index < args.length ? args[index] : null; return dan200.computercraft.api.lua.ArgumentHelper.optDouble( args, index, def );
if( value == null )
{
return def;
}
else if( value instanceof Number )
{
return ((Number) value).doubleValue();
}
else
{
throw badArgument( index, "number", value );
}
} }
public static int optInt( @Nonnull Object[] args, int index, int def ) throws LuaException public static int optInt( @Nonnull Object[] args, int index, int def ) throws LuaException
{ {
return (int) optLong( args, index, def ); return dan200.computercraft.api.lua.ArgumentHelper.optInt( args, index, def );
} }
public static long optLong( @Nonnull Object[] args, int index, long def ) throws LuaException public static long optLong( @Nonnull Object[] args, int index, long def ) throws LuaException
{ {
Object value = index < args.length ? args[index] : null; return dan200.computercraft.api.lua.ArgumentHelper.optLong( args, index, def );
if( value == null )
{
return def;
}
else if( value instanceof Number )
{
return checkReal( index, (Number) value ).longValue();
}
else
{
throw badArgument( index, "number", value );
}
} }
public static double optReal( @Nonnull Object[] args, int index, double def ) throws LuaException public static double optReal( @Nonnull Object[] args, int index, double def ) throws LuaException
{ {
return checkReal( index, optNumber( args, index, def ) ); return dan200.computercraft.api.lua.ArgumentHelper.optFiniteDouble( args, index, def );
} }
public static boolean optBoolean( @Nonnull Object[] args, int index, boolean def ) throws LuaException public static boolean optBoolean( @Nonnull Object[] args, int index, boolean def ) throws LuaException
{ {
Object value = index < args.length ? args[index] : null; return dan200.computercraft.api.lua.ArgumentHelper.optBoolean( args, index, def );
if( value == null )
{
return def;
}
else if( value instanceof Boolean )
{
return (Boolean) value;
}
else
{
throw badArgument( index, "boolean", value );
}
} }
public static String optString( @Nonnull Object[] args, int index, String def ) throws LuaException public static String optString( @Nonnull Object[] args, int index, String def ) throws LuaException
{ {
Object value = index < args.length ? args[index] : null; return dan200.computercraft.api.lua.ArgumentHelper.optString( args, index, def );
if( value == null )
{
return def;
}
else if( value instanceof String )
{
return (String) value;
}
else
{
throw badArgument( index, "string", value );
}
} }
@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" )
public static Map<Object, Object> optTable( @Nonnull Object[] args, int index, Map<Object, Object> def ) throws LuaException public static Map<Object, Object> optTable( @Nonnull Object[] args, int index, Map<Object, Object> def ) throws LuaException
{ {
Object value = index < args.length ? args[index] : null; return (Map<Object, Object>) dan200.computercraft.api.lua.ArgumentHelper.optTable( args, index, def );
if( value == null )
{
return def;
}
else if( value instanceof Map )
{
return (Map<Object, Object>) value;
}
else
{
throw badArgument( index, "table", value );
}
}
private static Number checkReal( int index, Number value ) throws LuaException
{
checkReal( index, value.doubleValue() );
return value;
}
private static double checkReal( int index, double value ) throws LuaException
{
if( Double.isNaN( value ) )
{
throw badArgument( index, "number", "nan" );
}
else if( value == Double.POSITIVE_INFINITY )
{
throw badArgument( index, "number", "inf" );
}
else if( value == Double.NEGATIVE_INFINITY )
{
throw badArgument( index, "number", "-inf" );
}
else
{
return value;
}
} }
} }

View File

@@ -27,7 +27,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import static dan200.computercraft.core.apis.ArgumentHelper.getString; import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public class FSAPI implements ILuaAPI public class FSAPI implements ILuaAPI
{ {

View File

@@ -23,7 +23,7 @@ import java.util.Collections;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.*; import static dan200.computercraft.api.lua.ArgumentHelper.*;
import static dan200.computercraft.core.apis.TableHelper.*; import static dan200.computercraft.core.apis.TableHelper.*;
public class HTTPAPI implements ILuaAPI public class HTTPAPI implements ILuaAPI
@@ -89,7 +89,7 @@ public class HTTPAPI implements ILuaAPI
case 0: // request case 0: // request
{ {
String address, postString, requestMethod; String address, postString, requestMethod;
Map<Object, Object> headerTable; Map<?, ?> headerTable;
boolean binary, redirect; boolean binary, redirect;
if( args.length >= 1 && args[0] instanceof Map ) if( args.length >= 1 && args[0] instanceof Map )
@@ -172,7 +172,7 @@ public class HTTPAPI implements ILuaAPI
case 2: // websocket case 2: // websocket
{ {
String address = getString( args, 0 ); String address = getString( args, 0 );
Map<Object, Object> headerTbl = optTable( args, 1, Collections.emptyMap() ); Map<?, ?> headerTbl = optTable( args, 1, Collections.emptyMap() );
if( !ComputerCraft.http_websocket_enable ) if( !ComputerCraft.http_websocket_enable )
{ {

View File

@@ -19,7 +19,7 @@ import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeFormatterBuilder;
import java.util.*; import java.util.*;
import static dan200.computercraft.core.apis.ArgumentHelper.*; import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class OSAPI implements ILuaAPI public class OSAPI implements ILuaAPI
{ {
@@ -229,7 +229,7 @@ public class OSAPI implements ILuaAPI
case 1: case 1:
{ {
// startTimer // startTimer
double timer = getReal( args, 0 ); double timer = getFiniteDouble( args, 0 );
synchronized( m_timers ) synchronized( m_timers )
{ {
m_timers.put( m_nextTimerToken, new Timer( (int) Math.round( timer / 0.05 ) ) ); m_timers.put( m_nextTimerToken, new Timer( (int) Math.round( timer / 0.05 ) ) );
@@ -239,7 +239,7 @@ public class OSAPI implements ILuaAPI
case 2: case 2:
{ {
// setAlarm // setAlarm
double time = getReal( args, 0 ); double time = getFiniteDouble( args, 0 );
if( time < 0.0 || time >= 24.0 ) if( time < 0.0 || time >= 24.0 )
{ {
throw new LuaException( "Number out of range" ); throw new LuaException( "Number out of range" );

View File

@@ -22,7 +22,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.getString; import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChangeListener public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChangeListener
{ {

View File

@@ -15,7 +15,7 @@ import javax.annotation.Nonnull;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.*; import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class RedstoneAPI implements ILuaAPI public class RedstoneAPI implements ILuaAPI
{ {

View File

@@ -6,14 +6,17 @@
package dan200.computercraft.core.apis; package dan200.computercraft.core.apis;
import dan200.computercraft.api.lua.ArgumentHelper;
import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaException;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Map; import java.util.Map;
import static dan200.computercraft.api.lua.ArgumentHelper.getNumericType;
/** /**
* Various helpers for tables * Various helpers for tables.
*/ */
public final class TableHelper public final class TableHelper
{ {
@@ -200,21 +203,7 @@ public final class TableHelper
private static double checkReal( @Nonnull String key, double value ) throws LuaException private static double checkReal( @Nonnull String key, double value ) throws LuaException
{ {
if( Double.isNaN( value ) ) if( !Double.isFinite( value ) ) throw badKey( key, "number", getNumericType( value ) );
{ return value;
throw badKey( key, "number", "nan" );
}
else if( value == Double.POSITIVE_INFINITY )
{
throw badKey( key, "number", "inf" );
}
else if( value == Double.NEGATIVE_INFINITY )
{
throw badKey( key, "number", "-inf" );
}
else
{
return value;
}
} }
} }

View File

@@ -17,7 +17,7 @@ import org.apache.commons.lang3.ArrayUtils;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.*; import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class TermAPI implements ILuaAPI public class TermAPI implements ILuaAPI
{ {
@@ -242,9 +242,9 @@ public class TermAPI implements ILuaAPI
} }
else else
{ {
double r = getReal( args, 1 ); double r = getFiniteDouble( args, 1 );
double g = getReal( args, 2 ); double g = getFiniteDouble( args, 2 );
double b = getReal( args, 3 ); double b = getFiniteDouble( args, 3 );
setColour( m_terminal, colour, r, g, b ); setColour( m_terminal, colour, r, g, b );
} }
return null; return null;

View File

@@ -21,8 +21,8 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt; import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
import static dan200.computercraft.core.apis.ArgumentHelper.optBoolean; import static dan200.computercraft.api.lua.ArgumentHelper.optBoolean;
public class BinaryReadableHandle extends HandleGeneric public class BinaryReadableHandle extends HandleGeneric
{ {

View File

@@ -7,9 +7,9 @@
package dan200.computercraft.core.apis.handles; package dan200.computercraft.core.apis.handles;
import com.google.common.collect.ObjectArrays; import com.google.common.collect.ObjectArrays;
import dan200.computercraft.api.lua.ArgumentHelper;
import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.core.apis.ArgumentHelper;
import dan200.computercraft.shared.util.StringUtil; import dan200.computercraft.shared.util.StringUtil;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -73,7 +73,7 @@ public class BinaryWritableHandle extends HandleGeneric
} }
else else
{ {
throw ArgumentHelper.badArgument( 0, "string or number", args.length > 0 ? args[0] : null ); throw ArgumentHelper.badArgumentOf( 0, "string or number", args.length > 0 ? args[0] : null );
} }
return null; return null;
} }

View File

@@ -20,8 +20,8 @@ import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction; import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static dan200.computercraft.core.apis.ArgumentHelper.optBoolean; import static dan200.computercraft.api.lua.ArgumentHelper.optBoolean;
import static dan200.computercraft.core.apis.ArgumentHelper.optInt; import static dan200.computercraft.api.lua.ArgumentHelper.optInt;
public class EncodedReadableHandle extends HandleGeneric public class EncodedReadableHandle extends HandleGeneric
{ {

View File

@@ -16,8 +16,8 @@ import java.io.IOException;
import java.nio.channels.Channel; import java.nio.channels.Channel;
import java.nio.channels.SeekableByteChannel; import java.nio.channels.SeekableByteChannel;
import static dan200.computercraft.core.apis.ArgumentHelper.optLong; import static dan200.computercraft.api.lua.ArgumentHelper.optLong;
import static dan200.computercraft.core.apis.ArgumentHelper.optString; import static dan200.computercraft.api.lua.ArgumentHelper.optString;
public abstract class HandleGeneric implements ILuaObject public abstract class HandleGeneric implements ILuaObject
{ {
@@ -47,7 +47,7 @@ public abstract class HandleGeneric implements ILuaObject
} }
/** /**
* Shared implementation for various file handle types * Shared implementation for various file handle types.
* *
* @param channel The channel to seek in * @param channel The channel to seek in
* @param args The Lua arguments to process, like Lua's {@code file:seek}. * @param args The Lua arguments to process, like Lua's {@code file:seek}.

View File

@@ -99,7 +99,7 @@ public final class NetworkUtils
} }
/** /**
* Checks a host is allowed * Checks a host is allowed.
* *
* @param host The domain to check against * @param host The domain to check against
* @throws HTTPRequestException If the host is not permitted. * @throws HTTPRequestException If the host is not permitted.

View File

@@ -20,6 +20,8 @@ import java.util.function.Consumer;
/** /**
* A holder for one or more resources, with a lifetime. * A holder for one or more resources, with a lifetime.
*
* @param <T> The type of this resource. Should be the class extending from {@link Resource}.
*/ */
public abstract class Resource<T extends Resource<T>> implements Closeable public abstract class Resource<T extends Resource<T>> implements Closeable
{ {
@@ -42,8 +44,9 @@ public abstract class Resource<T extends Resource<T>> implements Closeable
} }
/** /**
* Checks if this has been cancelled. If so, it'll clean up any * Checks if this has been cancelled. If so, it'll clean up any existing resources and cancel any pending futures.
* existing resources and cancel any pending futures. *
* @return Whether this resource has been closed.
*/ */
public final boolean checkClosed() public final boolean checkClosed()
{ {
@@ -80,6 +83,7 @@ public abstract class Resource<T extends Resource<T>> implements Closeable
/** /**
* Create a {@link WeakReference} which will close {@code this} when collected. * Create a {@link WeakReference} which will close {@code this} when collected.
* *
* @param <R> The object we are wrapping in a reference.
* @param object The object to reference to * @param object The object to reference to
* @return The weak reference. * @return The weak reference.
*/ */

View File

@@ -14,6 +14,8 @@ import java.util.function.Supplier;
/** /**
* A collection of {@link Resource}s, with an upper bound on capacity. * A collection of {@link Resource}s, with an upper bound on capacity.
*
* @param <T> The type of the resource this group manages.
*/ */
public class ResourceGroup<T extends Resource<T>> public class ResourceGroup<T extends Resource<T>>
{ {

View File

@@ -12,6 +12,8 @@ import java.util.function.Supplier;
/** /**
* A {@link ResourceGroup} which will queue items when the group at capacity. * A {@link ResourceGroup} which will queue items when the group at capacity.
*
* @param <T> The type of the resource this queue manages.
*/ */
public class ResourceQueue<T extends Resource<T>> extends ResourceGroup<T> public class ResourceQueue<T extends Resource<T>> extends ResourceGroup<T>
{ {

View File

@@ -40,7 +40,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Represents one or more * Represents an in-progress HTTP request.
*/ */
public class HttpRequest extends Resource<HttpRequest> public class HttpRequest extends Resource<HttpRequest>
{ {

View File

@@ -226,7 +226,11 @@ public final class HttpRequestHandler extends SimpleChannelInboundHandler<HttpOb
} }
/** /**
* Determine the redirect from this response * Determine the redirect from this response.
*
* @param status The status of the HTTP response.
* @param headers The headers of the HTTP response.
* @return The URI to redirect to, or {@code null} if no redirect should occur.
*/ */
private URI getRedirect( HttpResponseStatus status, HttpHeaders headers ) private URI getRedirect( HttpResponseStatus status, HttpHeaders headers )
{ {

View File

@@ -23,7 +23,7 @@ import javax.annotation.Nullable;
import java.io.Closeable; import java.io.Closeable;
import java.util.Arrays; import java.util.Arrays;
import static dan200.computercraft.core.apis.ArgumentHelper.optBoolean; import static dan200.computercraft.api.lua.ArgumentHelper.optBoolean;
import static dan200.computercraft.core.apis.http.websocket.Websocket.CLOSE_EVENT; import static dan200.computercraft.core.apis.http.websocket.Websocket.CLOSE_EVENT;
import static dan200.computercraft.core.apis.http.websocket.Websocket.MESSAGE_EVENT; import static dan200.computercraft.core.apis.http.websocket.Websocket.MESSAGE_EVENT;

View File

@@ -56,9 +56,6 @@ final class ComputerExecutor
{ {
private static final int QUEUE_LIMIT = 256; private static final int QUEUE_LIMIT = 256;
private static IMount romMount;
private static final Object romMountLock = new Object();
private final Computer computer; private final Computer computer;
private final List<ILuaAPI> apis = new ArrayList<>(); private final List<ILuaAPI> apis = new ArrayList<>();
final TimeoutState timeout = new TimeoutState(); final TimeoutState timeout = new TimeoutState();
@@ -268,7 +265,7 @@ final class ComputerExecutor
} }
/** /**
* Queue an event if the computer is on * Queue an event if the computer is on.
* *
* @param event The event's name * @param event The event's name
* @param args The event's arguments * @param args The event's arguments
@@ -329,16 +326,10 @@ final class ComputerExecutor
private IMount getRomMount() private IMount getRomMount()
{ {
if( romMount != null ) return romMount; return computer.getComputerEnvironment().createResourceMount( "computercraft", "lua/rom" );
synchronized( romMountLock )
{
if( romMount != null ) return romMount;
return romMount = computer.getComputerEnvironment().createResourceMount( "computercraft", "lua/rom" );
}
} }
IWritableMount getRootMount() private IWritableMount getRootMount()
{ {
if( rootMount == null ) if( rootMount == null )
{ {

View File

@@ -50,7 +50,7 @@ import static dan200.computercraft.core.computer.TimeoutState.TIMEOUT;
public final class ComputerThread public final class ComputerThread
{ {
/** /**
* How often the computer thread monitor should run, in milliseconds * How often the computer thread monitor should run, in milliseconds.
* *
* @see Monitor * @see Monitor
*/ */
@@ -83,7 +83,7 @@ public final class ComputerThread
private static final Object threadLock = new Object(); private static final Object threadLock = new Object();
/** /**
* Whether the computer thread system is currently running * Whether the computer thread system is currently running.
*/ */
private static volatile boolean running = false; private static volatile boolean running = false;
@@ -105,7 +105,7 @@ public final class ComputerThread
private static final Condition hasWork = computerLock.newCondition(); private static final Condition hasWork = computerLock.newCondition();
/** /**
* Active queues to execute * Active queues to execute.
*/ */
private static final TreeSet<ComputerExecutor> computerQueue = new TreeSet<>( ( a, b ) -> { private static final TreeSet<ComputerExecutor> computerQueue = new TreeSet<>( ( a, b ) -> {
if( a == b ) return 0; // Should never happen, but let's be consistent here if( a == b ) return 0; // Should never happen, but let's be consistent here
@@ -126,7 +126,7 @@ public final class ComputerThread
private ComputerThread() {} private ComputerThread() {}
/** /**
* Start the computer thread * Start the computer thread.
*/ */
static void start() static void start()
{ {
@@ -194,7 +194,7 @@ public final class ComputerThread
} }
/** /**
* Mark a computer as having work, enqueuing it on the thread * Mark a computer as having work, enqueuing it on the thread.
* *
* You must be holding {@link ComputerExecutor}'s {@code queueLock} when calling this method - it should only * You must be holding {@link ComputerExecutor}'s {@code queueLock} when calling this method - it should only
* be called from {@code enqueue}. * be called from {@code enqueue}.
@@ -244,6 +244,8 @@ public final class ComputerThread
* {@link #minimumVirtualRuntime} based on the current tasks. * {@link #minimumVirtualRuntime} based on the current tasks.
* *
* This is called before queueing tasks, to ensure that {@link #minimumVirtualRuntime} is up-to-date. * This is called before queueing tasks, to ensure that {@link #minimumVirtualRuntime} is up-to-date.
*
* @param current The machine which we updating runtimes from.
*/ */
private static void updateRuntimes( @Nullable ComputerExecutor current ) private static void updateRuntimes( @Nullable ComputerExecutor current )
{ {
@@ -321,7 +323,7 @@ public final class ComputerThread
} }
/** /**
* The scaled period for a single task * The scaled period for a single task.
* *
* @return The scaled period for the task * @return The scaled period for the task
* @see #DEFAULT_LATENCY * @see #DEFAULT_LATENCY
@@ -336,7 +338,7 @@ public final class ComputerThread
} }
/** /**
* Determine if the thread has computers queued up * Determine if the thread has computers queued up.
* *
* @return If we have work queued up. * @return If we have work queued up.
*/ */

View File

@@ -36,12 +36,12 @@ import java.util.concurrent.TimeUnit;
public final class TimeoutState public final class TimeoutState
{ {
/** /**
* The total time a task is allowed to run before aborting in nanoseconds * The total time a task is allowed to run before aborting in nanoseconds.
*/ */
static final long TIMEOUT = TimeUnit.MILLISECONDS.toNanos( 7000 ); static final long TIMEOUT = TimeUnit.MILLISECONDS.toNanos( 7000 );
/** /**
* The time the task is allowed to run after each abort in nanoseconds * The time the task is allowed to run after each abort in nanoseconds.
*/ */
static final long ABORT_TIMEOUT = TimeUnit.MILLISECONDS.toNanos( 1500 ); static final long ABORT_TIMEOUT = TimeUnit.MILLISECONDS.toNanos( 1500 );
@@ -111,6 +111,8 @@ public final class TimeoutState
/** /**
* If the machine should be passively aborted. * If the machine should be passively aborted.
*
* @return {@code true} if we should throw a timeout error.
*/ */
public boolean isSoftAborted() public boolean isSoftAborted()
{ {
@@ -118,7 +120,9 @@ public final class TimeoutState
} }
/** /**
* If the machine should be forcibly aborted. * Determine if the machine should be forcibly aborted.
*
* @return {@code true} if the machine should be forcibly shut down.
*/ */
public boolean isHardAborted() public boolean isHardAborted()
{ {
@@ -146,7 +150,7 @@ public final class TimeoutState
} }
/** /**
* Pauses the cumulative time, to be resumed by {@link #startTimer()} * Pauses the cumulative time, to be resumed by {@link #startTimer()}.
* *
* @see #nanoCumulative() * @see #nanoCumulative()
*/ */

View File

@@ -8,13 +8,16 @@ package dan200.computercraft.core.filesystem;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.collect.MapMaker;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.core.apis.handles.ArrayByteChannel; import dan200.computercraft.core.apis.handles.ArrayByteChannel;
import net.minecraft.resources.IReloadableResourceManager; import net.minecraft.resources.IReloadableResourceManager;
import net.minecraft.resources.IResource; import net.minecraft.resources.IResource;
import net.minecraft.resources.IResourceManager; import net.minecraft.resources.IResourceManager;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.ResourceLocationException;
import net.minecraftforge.resource.IResourceType; import net.minecraftforge.resource.IResourceType;
import net.minecraftforge.resource.ISelectiveResourceReloadListener; import net.minecraftforge.resource.ISelectiveResourceReloadListener;
@@ -29,7 +32,7 @@ import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Predicate; import java.util.function.Predicate;
public class ResourceMount implements IMount public final class ResourceMount implements IMount
{ {
/** /**
* Only cache files smaller than 1MiB. * Only cache files smaller than 1MiB.
@@ -55,6 +58,13 @@ public class ResourceMount implements IMount
.<FileEntry, byte[]>weigher( ( k, v ) -> v.length ) .<FileEntry, byte[]>weigher( ( k, v ) -> v.length )
.build(); .build();
private static final MapMaker CACHE_TEMPLATE = new MapMaker().weakValues().concurrencyLevel( 1 );
/**
* Maintain a cache of currently loaded resource mounts. This cache is invalidated when currentManager changes.
*/
private static final Map<IReloadableResourceManager, Map<ResourceLocation, ResourceMount>> MOUNT_CACHE = new WeakHashMap<>( 2 );
private final String namespace; private final String namespace;
private final String subPath; private final String subPath;
private final IReloadableResourceManager manager; private final IReloadableResourceManager manager;
@@ -62,7 +72,26 @@ public class ResourceMount implements IMount
@Nullable @Nullable
private FileEntry root; private FileEntry root;
public ResourceMount( String namespace, String subPath, IReloadableResourceManager manager ) public static ResourceMount get( String namespace, String subPath, IReloadableResourceManager manager )
{
Map<ResourceLocation, ResourceMount> cache;
synchronized( MOUNT_CACHE )
{
cache = MOUNT_CACHE.get( manager );
if( cache == null ) MOUNT_CACHE.put( manager, cache = CACHE_TEMPLATE.makeMap() );
}
ResourceLocation path = new ResourceLocation( namespace, subPath );
synchronized( cache )
{
ResourceMount mount = cache.get( path );
if( mount == null ) cache.put( path, mount = new ResourceMount( namespace, subPath, manager ) );
return mount;
}
}
private ResourceMount( String namespace, String subPath, IReloadableResourceManager manager )
{ {
this.namespace = namespace; this.namespace = namespace;
this.subPath = subPath; this.subPath = subPath;
@@ -119,7 +148,17 @@ public class ResourceMount implements IMount
FileEntry nextEntry = lastEntry.children.get( part ); FileEntry nextEntry = lastEntry.children.get( part );
if( nextEntry == null ) if( nextEntry == null )
{ {
lastEntry.children.put( part, nextEntry = new FileEntry( new ResourceLocation( namespace, subPath + "/" + path ) ) ); ResourceLocation childPath;
try
{
childPath = new ResourceLocation( namespace, subPath + "/" + path );
}
catch( ResourceLocationException e )
{
ComputerCraft.log.warn( "Cannot create resource location for {} ({})", part, e.getMessage() );
return;
}
lastEntry.children.put( part, nextEntry = new FileEntry( childPath ) );
} }
lastEntry = nextEntry; lastEntry = nextEntry;

View File

@@ -38,7 +38,7 @@ public final class MachineResult
public static final MachineResult TIMEOUT = new MachineResult( true, false, TimeoutState.ABORT_MESSAGE ); public static final MachineResult TIMEOUT = new MachineResult( true, false, TimeoutState.ABORT_MESSAGE );
/** /**
* An error with no user-friendly error message * An error with no user-friendly error message.
*/ */
public static final MachineResult GENERIC_ERROR = new MachineResult( true, false, null ); public static final MachineResult GENERIC_ERROR = new MachineResult( true, false, null );

View File

@@ -314,6 +314,9 @@ public class Terminal
} }
/** /**
* Determine whether this terminal has changed.
*
* @return If this terminal is dirty.
* @deprecated All {@code *Changed()} methods are deprecated: one should pass in a callback * @deprecated All {@code *Changed()} methods are deprecated: one should pass in a callback
* instead. * instead.
*/ */

View File

@@ -11,92 +11,168 @@ import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.InventoryUtil;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.ModLoadingContext;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.*; import java.util.*;
import java.util.stream.Stream;
public final class TurtleUpgrades public final class TurtleUpgrades
{ {
private static class Wrapper
{
final ITurtleUpgrade upgrade;
final String id;
final String modId;
boolean enabled;
Wrapper( ITurtleUpgrade upgrade )
{
this.upgrade = upgrade;
this.id = upgrade.getUpgradeID().toString();
this.modId = ModLoadingContext.get().getActiveNamespace();
this.enabled = true;
}
}
private static ITurtleUpgrade[] vanilla;
private static final Map<String, ITurtleUpgrade> upgrades = new HashMap<>(); private static final Map<String, ITurtleUpgrade> upgrades = new HashMap<>();
private static final IdentityHashMap<ITurtleUpgrade, String> upgradeOwners = new IdentityHashMap<>(); private static final IdentityHashMap<ITurtleUpgrade, Wrapper> wrappers = new IdentityHashMap<>();
private static boolean needsRebuild;
private TurtleUpgrades() {} private TurtleUpgrades() {}
public static void register( @Nonnull ITurtleUpgrade upgrade ) public static void register( @Nonnull ITurtleUpgrade upgrade )
{ {
Objects.requireNonNull( upgrade, "upgrade cannot be null" ); Objects.requireNonNull( upgrade, "upgrade cannot be null" );
rebuild();
String id = upgrade.getUpgradeID().toString(); Wrapper wrapper = new Wrapper( upgrade );
String id = wrapper.id;
ITurtleUpgrade existing = upgrades.get( id ); ITurtleUpgrade existing = upgrades.get( id );
if( existing != null ) if( existing != null )
{ {
throw new IllegalStateException( "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turle'. UpgradeID '" + id + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" ); throw new IllegalStateException( "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turtle'. Upgrade ID '" + id + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" );
} }
upgrades.put( id, upgrade ); upgrades.put( id, upgrade );
wrappers.put( upgrade, wrapper );
ModContainer mc = ModLoadingContext.get().getActiveContainer();
if( mc != null && mc.getModId() != null ) upgradeOwners.put( upgrade, mc.getModId() );
} }
@Nullable
public static ITurtleUpgrade get( String id ) public static ITurtleUpgrade get( String id )
{ {
rebuild();
return upgrades.get( id ); return upgrades.get( id );
} }
@Nullable
public static String getOwner( @Nonnull ITurtleUpgrade upgrade )
{
Wrapper wrapper = wrappers.get( upgrade );
return wrapper != null ? wrapper.modId : null;
}
public static ITurtleUpgrade get( @Nonnull ItemStack stack ) public static ITurtleUpgrade get( @Nonnull ItemStack stack )
{ {
if( stack.isEmpty() ) return null; if( stack.isEmpty() ) return null;
for( ITurtleUpgrade upgrade : upgrades.values() ) for( Wrapper wrapper : wrappers.values() )
{ {
ItemStack craftingStack = upgrade.getCraftingItem(); if( !wrapper.enabled ) continue;
ItemStack craftingStack = wrapper.upgrade.getCraftingItem();
if( !craftingStack.isEmpty() && InventoryUtil.areItemsSimilar( stack, craftingStack ) ) if( !craftingStack.isEmpty() && InventoryUtil.areItemsSimilar( stack, craftingStack ) )
{ {
return upgrade; return wrapper.upgrade;
} }
} }
return null; return null;
} }
public static Iterable<ITurtleUpgrade> getVanillaUpgrades() public static Stream<ITurtleUpgrade> getVanillaUpgrades()
{ {
List<ITurtleUpgrade> vanilla = new ArrayList<>(); if( vanilla == null )
{
vanilla = new ITurtleUpgrade[] {
// ComputerCraft upgrades
ComputerCraft.TurtleUpgrades.wirelessModemNormal,
ComputerCraft.TurtleUpgrades.wirelessModemAdvanced,
ComputerCraft.TurtleUpgrades.speaker,
// Vanilla Minecraft upgrades
ComputerCraft.TurtleUpgrades.diamondPickaxe,
ComputerCraft.TurtleUpgrades.diamondAxe,
ComputerCraft.TurtleUpgrades.diamondSword,
ComputerCraft.TurtleUpgrades.diamondShovel,
ComputerCraft.TurtleUpgrades.diamondHoe,
ComputerCraft.TurtleUpgrades.craftingTable,
};
}
// ComputerCraft upgrades return Arrays.stream( vanilla ).filter( x -> x != null && wrappers.get( x ).enabled );
vanilla.add( ComputerCraft.TurtleUpgrades.wirelessModemNormal );
vanilla.add( ComputerCraft.TurtleUpgrades.wirelessModemAdvanced );
vanilla.add( ComputerCraft.TurtleUpgrades.speaker );
// Vanilla Minecraft upgrades
vanilla.add( ComputerCraft.TurtleUpgrades.diamondPickaxe );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondAxe );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondSword );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondShovel );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondHoe );
vanilla.add( ComputerCraft.TurtleUpgrades.craftingTable );
return vanilla;
} }
@Nullable public static Stream<ITurtleUpgrade> getUpgrades()
public static String getOwner( @Nonnull ITurtleUpgrade upgrade )
{ {
return upgradeOwners.get( upgrade ); return wrappers.values().stream().filter( x -> x.enabled ).map( x -> x.upgrade );
}
public static Iterable<ITurtleUpgrade> getUpgrades()
{
return Collections.unmodifiableCollection( upgrades.values() );
} }
public static boolean suitableForFamily( ComputerFamily family, ITurtleUpgrade upgrade ) public static boolean suitableForFamily( ComputerFamily family, ITurtleUpgrade upgrade )
{ {
return true; return true;
} }
/**
* Rebuild the cache of turtle upgrades. This is done before querying the cache or registering new upgrades.
*/
private static void rebuild()
{
if( !needsRebuild ) return;
upgrades.clear();
for( Wrapper wrapper : wrappers.values() )
{
if( !wrapper.enabled ) continue;
ITurtleUpgrade existing = upgrades.get( wrapper.id );
if( existing != null )
{
ComputerCraft.log.error( "Error registering '" + wrapper.upgrade.getUnlocalisedAdjective() + " Turtle'." +
" Upgrade ID '" + wrapper.id + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" );
continue;
}
upgrades.put( wrapper.id, wrapper.upgrade );
}
needsRebuild = false;
}
public static void enable( ITurtleUpgrade upgrade )
{
Wrapper wrapper = wrappers.get( upgrade );
if( wrapper.enabled ) return;
wrapper.enabled = true;
needsRebuild = true;
}
public static void disable( ITurtleUpgrade upgrade )
{
Wrapper wrapper = wrappers.get( upgrade );
if( !wrapper.enabled ) return;
wrapper.enabled = false;
upgrades.remove( wrapper.id );
}
public static void remove( ITurtleUpgrade upgrade )
{
wrappers.remove( upgrade );
needsRebuild = true;
}
} }

View File

@@ -11,7 +11,10 @@ import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
/** /**
* A {@link Command} which accepts an argument * A {@link Command} which accepts an argument.
*
* @param <S> The command source we consume.
* @param <T> The argument given to this command when executed.
*/ */
@FunctionalInterface @FunctionalInterface
public interface ArgCommand<S, T> public interface ArgCommand<S, T>

View File

@@ -25,8 +25,10 @@ import static dan200.computercraft.shared.command.Exceptions.ARGUMENT_EXPECTED;
import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder.literal; import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder.literal;
/** /**
* An alternative way of building command nodes, so one does not have to nest * An alternative way of building command nodes, so one does not have to nest.
* {@link ArgumentBuilder#then(CommandNode)}s. * {@link ArgumentBuilder#then(CommandNode)}s.
*
* @param <S> The command source we consume.
*/ */
public class CommandBuilder<S> implements CommandNodeBuilder<S, Command<S>> public class CommandBuilder<S> implements CommandNodeBuilder<S, Command<S>>
{ {

View File

@@ -10,6 +10,9 @@ import com.mojang.brigadier.tree.CommandNode;
/** /**
* A builder which generates a {@link CommandNode} from the provided action. * A builder which generates a {@link CommandNode} from the provided action.
*
* @param <S> The command source we consume.
* @param <T> The type of action to execute when this command is run.
*/ */
@FunctionalInterface @FunctionalInterface
public interface CommandNodeBuilder<S, T> public interface CommandNodeBuilder<S, T>

View File

@@ -12,7 +12,7 @@ import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.util.text.event.HoverEvent; import net.minecraft.util.text.event.HoverEvent;
/** /**
* Various helpers for building chat messages * Various helpers for building chat messages.
*/ */
public final class ChatHelpers public final class ChatHelpers
{ {

View File

@@ -107,7 +107,7 @@ public class TableBuilder
} }
/** /**
* Trim this table to a given height * Trim this table to a given height.
* *
* @param height The desired height. * @param height The desired height.
*/ */

View File

@@ -22,7 +22,7 @@ public interface TableFormatter
ITextComponent HEADER = coloured( "=", TextFormatting.GRAY ); ITextComponent HEADER = coloured( "=", TextFormatting.GRAY );
/** /**
* Get additional padding for the component * Get additional padding for the component.
* *
* @param component The component to pad * @param component The component to pad
* @param width The desired width for the component * @param width The desired width for the component
@@ -32,7 +32,7 @@ public interface TableFormatter
ITextComponent getPadding( ITextComponent component, int width ); ITextComponent getPadding( ITextComponent component, int width );
/** /**
* Get the minimum padding between each column * Get the minimum padding between each column.
* *
* @return The minimum padding. * @return The minimum padding.
*/ */

View File

@@ -8,7 +8,6 @@ package dan200.computercraft.shared.common;
import dan200.computercraft.shared.network.container.ContainerData; import dan200.computercraft.shared.network.container.ContainerData;
import dan200.computercraft.shared.network.container.HeldItemContainerData; import dan200.computercraft.shared.network.container.HeldItemContainerData;
import dan200.computercraft.shared.util.InventoryUtil;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.Container;
@@ -33,7 +32,7 @@ public class ContainerHeldItem extends Container
super( type, id ); super( type, id );
this.hand = hand; this.hand = hand;
stack = InventoryUtil.copyItem( player.getHeldItem( hand ) ); stack = player.getHeldItem( hand ).copy();
} }
private static ContainerHeldItem createPrintout( int id, PlayerInventory inventory, HeldItemContainerData data ) private static ContainerHeldItem createPrintout( int id, PlayerInventory inventory, HeldItemContainerData data )

View File

@@ -32,8 +32,8 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt; import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
import static dan200.computercraft.core.apis.ArgumentHelper.getString; import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public class CommandAPI implements ILuaAPI public class CommandAPI implements ILuaAPI
{ {
@@ -85,7 +85,7 @@ public class CommandAPI implements ILuaAPI
{ {
receiver.clearOutput(); receiver.clearOutput();
int result = commandManager.handleCommand( m_computer.getSource(), command ); int result = commandManager.handleCommand( m_computer.getSource(), command );
return new Object[] { result > 0, receiver.copyOutput() }; return new Object[] { result > 0, receiver.copyOutput(), result };
} }
catch( Throwable t ) catch( Throwable t )
{ {
@@ -194,7 +194,7 @@ public class CommandAPI implements ILuaAPI
); );
if( !World.isValid( min ) || !World.isValid( max ) ) if( !World.isValid( min ) || !World.isValid( max ) )
{ {
throw new LuaException( "Co-ordinates out or range" ); throw new LuaException( "Co-ordinates out of range" );
} }
if( (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1) * (max.getZ() - min.getZ() + 1) > 4096 ) if( (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1) * (max.getZ() - min.getZ() + 1) > 4096 )
{ {
@@ -233,7 +233,7 @@ public class CommandAPI implements ILuaAPI
} }
else else
{ {
throw new LuaException( "co-ordinates out or range" ); throw new LuaException( "Co-ordinates out of range" );
} }
} ); } );
} }

View File

@@ -230,7 +230,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
} }
/** /**
* Gets the redstone input for an adjacent block * Gets the redstone input for an adjacent block.
* *
* @param world The world we exist in * @param world The world we exist in
* @param pos The position of the neighbour * @param pos The position of the neighbour

View File

@@ -7,7 +7,7 @@
package dan200.computercraft.shared.computer.core; package dan200.computercraft.shared.computer.core;
/** /**
* Receives some input and forwards it to a computer * Receives some input and forwards it to a computer.
* *
* @see InputState * @see InputState
* @see IComputer * @see IComputer

View File

@@ -311,13 +311,13 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
@Override @Override
public double getTimeOfDay() public double getTimeOfDay()
{ {
return (m_world.getGameTime() + 6000) % 24000 / 1000.0; return (m_world.getDayTime() + 6000) % 24000 / 1000.0;
} }
@Override @Override
public int getDay() public int getDay()
{ {
return (int) ((m_world.getGameTime() + 6000) / 24000) + 1; return (int) ((m_world.getDayTime() + 6000) / 24000) + 1;
} }
@Override @Override

View File

@@ -1,89 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.charset;
import dan200.computercraft.shared.common.TileGeneric;
import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import pl.asie.charset.api.wires.IBundledEmitter;
import pl.asie.charset.api.wires.IBundledReceiver;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import static dan200.computercraft.shared.integration.charset.IntegrationCharset.CAPABILITY_EMITTER;
import static dan200.computercraft.shared.integration.charset.IntegrationCharset.CAPABILITY_RECEIVER;
final class BundledCapabilityProvider implements ICapabilityProvider
{
private final TileGeneric tile;
private IBundledReceiver receiver;
private IBundledEmitter[] emitters;
BundledCapabilityProvider( TileGeneric tile )
{
this.tile = tile;
}
@Override
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable Direction side )
{
return capability == CAPABILITY_EMITTER || capability == CAPABILITY_RECEIVER;
}
@Nullable
@Override
public <T> T getCapability( @Nonnull Capability<T> capability, @Nullable Direction side )
{
if( capability == CAPABILITY_RECEIVER )
{
IBundledReceiver receiver = this.receiver;
if( receiver == null )
{
receiver = this.receiver = () -> tile.onNeighbourChange( tile.getPos().offset( side ) );
}
return CAPABILITY_RECEIVER.cast( receiver );
}
else if( capability == CAPABILITY_EMITTER )
{
IBundledEmitter[] emitters = this.emitters;
if( emitters == null ) emitters = this.emitters = new IBundledEmitter[7];
int index = side == null ? 6 : side.getIndex();
IBundledEmitter emitter = emitters[index];
if( emitter == null )
{
if( side == null )
{
emitter = emitters[index] = () -> {
int flags = 0;
for( Direction facing : Direction.VALUES ) flags |= tile.getBundledRedstoneOutput( facing );
return toBytes( flags );
};
}
else
{
emitter = emitters[index] = () -> toBytes( tile.getBundledRedstoneOutput( side ) );
}
}
return CAPABILITY_EMITTER.cast( emitter );
}
else
{
return null;
}
}
private static byte[] toBytes( int flag )
{
byte[] channels = new byte[16];
for( int i = 0; i < 16; i++ ) channels[i] = (flag & (1 << i)) == 0 ? (byte) 0 : 15;
return channels;
}
}

View File

@@ -1,33 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.charset;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import static dan200.computercraft.shared.integration.charset.IntegrationCharset.CAPABILITY_EMITTER;
public class BundledRedstoneProvider implements IBundledRedstoneProvider
{
@Override
public int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
TileEntity tile = world.getTileEntity( pos );
if( tile == null || !tile.hasCapability( CAPABILITY_EMITTER, side ) ) return -1;
byte[] signal = tile.getCapability( CAPABILITY_EMITTER, side ).getBundledSignal();
if( signal == null ) return -1;
int flag = 0;
for( int i = 0; i < signal.length; i++ ) flag |= signal[i] > 0 ? 1 << i : 0;
return flag;
}
}

View File

@@ -1,52 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.charset;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.shared.common.TileGeneric;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import pl.asie.charset.api.wires.IBundledEmitter;
import pl.asie.charset.api.wires.IBundledReceiver;
public final class IntegrationCharset
{
private static final ResourceLocation CAPABILITY_KEY = new ResourceLocation( ComputerCraft.MOD_ID, "charset" );
@CapabilityInject( IBundledEmitter.class )
static Capability<IBundledEmitter> CAPABILITY_EMITTER = null;
@CapabilityInject( IBundledReceiver.class )
static Capability<IBundledReceiver> CAPABILITY_RECEIVER = null;
private IntegrationCharset()
{
}
public static void register()
{
if( CAPABILITY_EMITTER == null || CAPABILITY_RECEIVER == null ) return;
MinecraftForge.EVENT_BUS.register( IntegrationCharset.class );
ComputerCraftAPI.registerBundledRedstoneProvider( new BundledRedstoneProvider() );
}
@SubscribeEvent
public static void attachGenericCapabilities( AttachCapabilitiesEvent<TileEntity> event )
{
TileEntity tile = event.getObject();
if( tile instanceof TileGeneric )
{
event.addCapability( CAPABILITY_KEY, new BundledCapabilityProvider( (TileGeneric) tile ) );
}
}
}

View File

@@ -0,0 +1,40 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker;
import com.blamejared.crafttweaker.api.logger.ILogger;
/**
* Logger which tracks if it has any messages.
*/
public final class TrackingLogger
{
private final ILogger logger;
private boolean ok = true;
public TrackingLogger( ILogger logger )
{
this.logger = logger;
}
public boolean isOk()
{
return ok;
}
public void warning( String message )
{
ok = false;
logger.warning( message );
}
public void error( String message )
{
ok = false;
logger.error( message );
}
}

View File

@@ -0,0 +1,72 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker;
import com.blamejared.crafttweaker.api.CraftTweakerAPI;
import com.blamejared.crafttweaker.api.annotations.ZenRegister;
import com.blamejared.crafttweaker.api.item.IItemStack;
import dan200.computercraft.shared.integration.crafttweaker.actions.AddTurtleTool;
import dan200.computercraft.shared.integration.crafttweaker.actions.RemoveTurtleUpgradeByItem;
import dan200.computercraft.shared.integration.crafttweaker.actions.RemoveTurtleUpgradeByName;
import org.openzen.zencode.java.ZenCodeType;
@ZenRegister
@ZenCodeType.Name( "dan200.computercraft.turtle" )
public class TurtleTweaker
{
/**
* Remove a turtle upgrade with the given id.
*
* @param upgrade The ID of the to remove
*/
@ZenCodeType.Method
public static void removeUpgrade( String upgrade )
{
CraftTweakerAPI.apply( new RemoveTurtleUpgradeByName( upgrade ) );
}
/**
* Remove a turtle upgrade crafted with the given item stack".
*
* @param stack The stack with which the upgrade is crafted.
*/
@ZenCodeType.Method
public static void removeUpgrade( IItemStack stack )
{
CraftTweakerAPI.apply( new RemoveTurtleUpgradeByItem( stack.getInternal() ) );
}
/**
* Add a new turtle tool with the given id, which crafts and acts using the given stack.
*
* @param id The new upgrade's ID
* @param stack The stack used for crafting the upgrade and used by the turtle as a tool.
*/
@ZenCodeType.Method
public static void addTool( String id, IItemStack stack )
{
addTool( id, stack, stack, "tool" );
}
@ZenCodeType.Method
public static void addTool( String id, IItemStack craftingStack, IItemStack toolStack )
{
addTool( id, craftingStack, toolStack, "tool" );
}
@ZenCodeType.Method
public static void addTool( String id, IItemStack stack, String kind )
{
addTool( id, stack, stack, kind );
}
@ZenCodeType.Method
public static void addTool( String id, IItemStack craftingStack, IItemStack toolStack, String kind )
{
CraftTweakerAPI.apply( new AddTurtleTool( id, craftingStack.getInternal(), toolStack.getInternal(), kind ) );
}
}

View File

@@ -0,0 +1,127 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker.actions;
import com.blamejared.crafttweaker.api.actions.IUndoableAction;
import com.blamejared.crafttweaker.api.logger.ILogger;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.shared.TurtleUpgrades;
import dan200.computercraft.shared.integration.crafttweaker.TrackingLogger;
import dan200.computercraft.shared.turtle.upgrades.*;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.LogicalSide;
import java.util.HashMap;
import java.util.Map;
/**
* Register a new turtle tool.
*/
public class AddTurtleTool implements IUndoableAction
{
private interface Factory
{
TurtleTool create( ResourceLocation location, ItemStack craftItem, ItemStack toolItem );
}
private static final Map<String, Factory> kinds = new HashMap<>();
static
{
kinds.put( "tool", TurtleTool::new );
kinds.put( "axe", TurtleAxe::new );
kinds.put( "hoe", TurtleHoe::new );
kinds.put( "shovel", TurtleShovel::new );
kinds.put( "sword", TurtleSword::new );
}
private final String id;
private final ItemStack craftItem;
private final ItemStack toolItem;
private final String kind;
private ITurtleUpgrade upgrade;
public AddTurtleTool( String id, ItemStack craftItem, ItemStack toolItem, String kind )
{
this.id = id;
this.craftItem = craftItem;
this.toolItem = toolItem;
this.kind = kind;
}
@Override
public void apply()
{
ITurtleUpgrade upgrade = this.upgrade;
if( upgrade == null )
{
Factory factory = kinds.get( kind );
if( factory == null )
{
ComputerCraft.log.error( "Unknown turtle upgrade kind '{}' (this should have been rejected by verify!)", kind );
return;
}
upgrade = this.upgrade = factory.create( new ResourceLocation( id ), craftItem, toolItem );
}
try
{
TurtleUpgrades.register( upgrade );
}
catch( RuntimeException e )
{
ComputerCraft.log.error( "Registration of turtle tool failed", e );
}
}
@Override
public String describe()
{
return String.format( "Add new turtle %s '%s' (crafted with '%s', uses a '%s')", kind, id, craftItem, toolItem );
}
@Override
public void undo()
{
if( upgrade != null ) TurtleUpgrades.remove( upgrade );
}
@Override
public String describeUndo()
{
return String.format( "Removing turtle upgrade %s.", id );
}
public boolean validate( ILogger logger )
{
TrackingLogger trackLog = new TrackingLogger( logger );
if( craftItem.isEmpty() ) trackLog.warning( "Crafting item stack is empty." );
if( craftItem.hasTag() && !craftItem.getTag().isEmpty() ) trackLog.warning( "Crafting item has NBT." );
if( toolItem.isEmpty() ) trackLog.error( "Tool item stack is empty." );
if( !kinds.containsKey( kind ) ) trackLog.error( String.format( "Unknown kind '%s'.", kind ) );
if( TurtleUpgrades.get( id ) != null )
{
trackLog.error( String.format( "An upgrade with the same name ('%s') has already been registered.", id ) );
}
return trackLog.isOk();
}
@Override
public boolean shouldApplyOn( LogicalSide side )
{
return true;
}
}

View File

@@ -0,0 +1,71 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker.actions;
import com.blamejared.crafttweaker.api.actions.IUndoableAction;
import com.blamejared.crafttweaker.api.logger.ILogger;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.shared.TurtleUpgrades;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.LogicalSide;
/**
* Removes a turtle upgrade crafted with the given stack.
*/
public class RemoveTurtleUpgradeByItem implements IUndoableAction
{
private final ItemStack stack;
private ITurtleUpgrade upgrade;
public RemoveTurtleUpgradeByItem( ItemStack stack )
{
this.stack = stack;
}
@Override
public void apply()
{
ITurtleUpgrade upgrade = this.upgrade = TurtleUpgrades.get( stack );
if( upgrade != null ) TurtleUpgrades.disable( upgrade );
}
@Override
public String describe()
{
return String.format( "Remove turtle upgrades crafted with '%s'", stack );
}
@Override
public void undo()
{
if( this.upgrade != null ) TurtleUpgrades.enable( upgrade );
}
@Override
public String describeUndo()
{
return String.format( "Adding back turtle upgrades crafted with '%s'", stack );
}
@Override
public boolean validate( ILogger logger )
{
if( TurtleUpgrades.get( stack ) == null )
{
logger.error( String.format( "Unknown turtle upgrade crafted with '%s'.", stack ) );
return false;
}
return true;
}
@Override
public boolean shouldApplyOn( LogicalSide side )
{
return true;
}
}

View File

@@ -0,0 +1,70 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker.actions;
import com.blamejared.crafttweaker.api.actions.IUndoableAction;
import com.blamejared.crafttweaker.api.logger.ILogger;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.shared.TurtleUpgrades;
import net.minecraftforge.fml.LogicalSide;
/**
* Removes a turtle upgrade with the given id.
*/
public class RemoveTurtleUpgradeByName implements IUndoableAction
{
private final String id;
private ITurtleUpgrade upgrade;
public RemoveTurtleUpgradeByName( String id )
{
this.id = id;
}
@Override
public void apply()
{
ITurtleUpgrade upgrade = this.upgrade = TurtleUpgrades.get( id );
if( upgrade != null ) TurtleUpgrades.disable( upgrade );
}
@Override
public String describe()
{
return String.format( "Remove turtle upgrade '%s'", id );
}
@Override
public void undo()
{
if( this.upgrade != null ) TurtleUpgrades.enable( upgrade );
}
@Override
public String describeUndo()
{
return String.format( "Adding back turtle upgrade '%s'", id );
}
@Override
public boolean validate( ILogger logger )
{
if( TurtleUpgrades.get( id ) == null )
{
logger.error( String.format( "Unknown turtle upgrade '%s'.", id ) );
return false;
}
return true;
}
@Override
public boolean shouldApplyOn( LogicalSide side )
{
return true;
}
}

View File

@@ -35,7 +35,6 @@ import net.minecraft.util.ResourceLocation;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import static dan200.computercraft.shared.integration.jei.RecipeResolver.MAIN_FAMILIES; import static dan200.computercraft.shared.integration.jei.RecipeResolver.MAIN_FAMILIES;
@@ -77,12 +76,10 @@ public class JEIComputerCraft implements IModPlugin
List<ItemStack> upgradeItems = new ArrayList<>(); List<ItemStack> upgradeItems = new ArrayList<>();
for( ComputerFamily family : MAIN_FAMILIES ) for( ComputerFamily family : MAIN_FAMILIES )
{ {
for( ITurtleUpgrade upgrade : TurtleUpgrades.getUpgrades() ) TurtleUpgrades.getUpgrades()
{ .filter( x -> TurtleUpgrades.suitableForFamily( family, x ) )
if( !TurtleUpgrades.suitableForFamily( family, upgrade ) ) continue; .map( x -> TurtleItemFactory.create( -1, null, -1, family, null, x, 0, null ) )
.forEach( upgradeItems::add );
upgradeItems.add( TurtleItemFactory.create( -1, null, -1, family, null, upgrade, 0, null ) );
}
for( IPocketUpgrade upgrade : PocketUpgrades.getUpgrades() ) for( IPocketUpgrade upgrade : PocketUpgrades.getUpgrades() )
{ {
@@ -92,10 +89,6 @@ public class JEIComputerCraft implements IModPlugin
runtime.getIngredientManager().addIngredientsAtRuntime( VanillaTypes.ITEM, upgradeItems ); runtime.getIngredientManager().addIngredientsAtRuntime( VanillaTypes.ITEM, upgradeItems );
// Hide treasure disks
runtime.getIngredientManager().removeIngredientsAtRuntime( VanillaTypes.ITEM,
Collections.singletonList( new ItemStack( ComputerCraft.Items.treasureDisk ) ) );
// Hide all upgrade recipes // Hide all upgrade recipes
IRecipeCategory<?> category = (IRecipeCategory<?>) registry.getRecipeCategory( VanillaRecipeCategoryUid.CRAFTING ); IRecipeCategory<?> category = (IRecipeCategory<?>) registry.getRecipeCategory( VanillaRecipeCategoryUid.CRAFTING );
if( category != null ) if( category != null )
@@ -114,7 +107,7 @@ public class JEIComputerCraft implements IModPlugin
} }
/** /**
* Distinguishes turtles by upgrades and family * Distinguishes turtles by upgrades and family.
*/ */
private static final ISubtypeInterpreter turtleSubtype = stack -> { private static final ISubtypeInterpreter turtleSubtype = stack -> {
Item item = stack.getItem(); Item item = stack.getItem();
@@ -134,7 +127,7 @@ public class JEIComputerCraft implements IModPlugin
}; };
/** /**
* Distinguishes pocket computers by upgrade and family * Distinguishes pocket computers by upgrade and family.
*/ */
private static final ISubtypeInterpreter pocketSubtype = stack -> { private static final ISubtypeInterpreter pocketSubtype = stack -> {
Item item = stack.getItem(); Item item = stack.getItem();
@@ -150,7 +143,7 @@ public class JEIComputerCraft implements IModPlugin
}; };
/** /**
* Distinguishes disks by colour * Distinguishes disks by colour.
*/ */
private static final ISubtypeInterpreter diskSubtype = stack -> { private static final ISubtypeInterpreter diskSubtype = stack -> {
Item item = stack.getItem(); Item item = stack.getItem();

View File

@@ -53,15 +53,14 @@ class RecipeResolver implements IRecipeManagerPlugin
if( initialised ) return; if( initialised ) return;
initialised = true; initialised = true;
for( ITurtleUpgrade upgrade : TurtleUpgrades.getUpgrades() ) TurtleUpgrades.getUpgrades().forEach( upgrade -> {
{
ItemStack stack = upgrade.getCraftingItem(); ItemStack stack = upgrade.getCraftingItem();
if( stack.isEmpty() ) continue; if( stack.isEmpty() ) return;
UpgradeInfo info = new UpgradeInfo( stack, upgrade ); UpgradeInfo info = new UpgradeInfo( stack, upgrade );
upgradeItemLookup.computeIfAbsent( stack.getItem(), k -> new ArrayList<>( 1 ) ).add( info ); upgradeItemLookup.computeIfAbsent( stack.getItem(), k -> new ArrayList<>( 1 ) ).add( info );
turtleUpgrades.add( info ); turtleUpgrades.add( info );
} } );
for( IPocketUpgrade upgrade : PocketUpgrades.getUpgrades() ) for( IPocketUpgrade upgrade : PocketUpgrades.getUpgrades() )
{ {

View File

@@ -1,49 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.mcmp;
import mcmultipart.MCMultiPart;
import mcmultipart.api.item.ItemBlockMultipart;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Loader;
import javax.annotation.Nonnull;
public final class MCMPHooks
{
private MCMPHooks()
{
}
public static ActionResultType onItemUse( BlockItem itemBlock, PlayerEntity player, World world, @Nonnull BlockPos pos, @Nonnull Hand hand, @Nonnull Direction facing, float hitX, float hitY, float hitZ )
{
if( !Loader.isModLoaded( MCMultiPart.MODID ) ) return ActionResultType.PASS;
return ItemBlockMultipart.place(
player, world, pos, hand, facing, hitX, hitY, hitZ, itemBlock,
itemBlock.getBlock()::getStateForPlacement,
MCMPIntegration.multipartMap.get( itemBlock.getBlock() ),
(
ItemStack stack, PlayerEntity thisPlayer, World thisWorld, BlockPos thisPos, Direction thisFacing,
float thisX, float thisY, float thisZ, BlockState thisState
) ->
thisPlayer.canPlayerEdit( thisPos, thisFacing, stack ) &&
thisWorld.getBlockState( thisPos ).getBlock().isReplaceable( thisWorld, thisPos ) &&
itemBlock.getBlock().canPlaceBlockAt( thisWorld, thisPos ) &&
itemBlock.getBlock().canPlaceBlockOnSide( thisWorld, thisPos, thisFacing ) &&
itemBlock.placeBlockAt( stack, thisPlayer, thisWorld, thisPos, thisFacing, thisX, thisY, thisZ, thisState ),
ItemBlockMultipart::placePartAt
);
}
}

View File

@@ -1,127 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.mcmp;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralTile;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import dan200.computercraft.shared.peripheral.modem.wireless.TileAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.TileWirelessModem;
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
import mcmultipart.api.addon.IMCMPAddon;
import mcmultipart.api.addon.MCMPAddon;
import mcmultipart.api.container.IMultipartContainer;
import mcmultipart.api.multipart.IMultipart;
import mcmultipart.api.multipart.IMultipartRegistry;
import mcmultipart.api.multipart.IMultipartTile;
import mcmultipart.api.ref.MCMPCapabilities;
import mcmultipart.api.slot.EnumFaceSlot;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
@MCMPAddon
public class MCMPIntegration implements IMCMPAddon
{
private static final ResourceLocation CAPABILITY_KEY = new ResourceLocation( ComputerCraft.MOD_ID, "mcmultipart" );
static final Map<Block, IMultipart> multipartMap = new HashMap<>();
private static void register( IMultipartRegistry registry, Block block, IMultipart multipart )
{
registry.registerPartWrapper( block, multipart );
multipartMap.put( block, multipart );
}
@Override
public void registerParts( IMultipartRegistry registry )
{
// Setup all parts
register( registry, ComputerCraft.Blocks.peripheral, new PartPeripheral() );
register( registry, ComputerCraft.Blocks.advancedModem, new PartAdvancedModem() );
// Subscribe to capability events
MinecraftForge.EVENT_BUS.register( MCMPIntegration.class );
// Register a peripheral provider
ComputerCraftAPI.registerPeripheralProvider( ( world, pos, side ) ->
{
TileEntity tile = world.getTileEntity( pos );
if( tile == null || !tile.hasCapability( MCMPCapabilities.MULTIPART_CONTAINER, null ) ) return null;
IMultipartContainer container = tile.getCapability( MCMPCapabilities.MULTIPART_CONTAINER, null );
if( container == null ) return null;
IMultipartTile multipart = container.getPartTile( EnumFaceSlot.fromFace( side ) ).orElse( null );
if( multipart == null ) return null;
if( multipart instanceof IPeripheral ) return (IPeripheral) multipart;
if( multipart instanceof IPeripheralTile ) return ((IPeripheralTile) multipart).getPeripheral( side );
TileEntity underlying = multipart.getTileEntity();
if( underlying instanceof IPeripheral ) return (IPeripheral) underlying;
if( underlying instanceof IPeripheralTile ) return ((IPeripheralTile) underlying).getPeripheral( side );
return null;
} );
}
@SubscribeEvent
public static void attach( AttachCapabilitiesEvent<TileEntity> event )
{
TileEntity tile = event.getObject();
if( tile instanceof TileAdvancedModem || tile instanceof TileWirelessModem
|| tile instanceof TilePeripheralBase || tile instanceof TileMonitor )
{
// We need to attach to modems (obviously), but also any other tile created by BlockPeripheral. Otherwise
// IMultipart.convertToMultipartTile will error.
event.addCapability( CAPABILITY_KEY, new BasicMultipart( tile ) );
}
}
private static final class BasicMultipart implements ICapabilityProvider
{
private final TileEntity tile;
private IMultipartTile wrapped;
private BasicMultipart( TileEntity tile )
{
this.tile = tile;
}
@Override
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable Direction facing )
{
return capability == MCMPCapabilities.MULTIPART_TILE;
}
@Nullable
@Override
public <T> T getCapability( @Nonnull Capability<T> capability, @Nullable Direction facing )
{
if( capability == MCMPCapabilities.MULTIPART_TILE )
{
IMultipartTile wrapped = this.wrapped;
if( wrapped == null ) wrapped = this.wrapped = IMultipartTile.wrap( tile );
return MCMPCapabilities.MULTIPART_TILE.cast( wrapped );
}
return null;
}
}
}

View File

@@ -1,41 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.mcmp;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.modem.wireless.BlockAdvancedModem;
import mcmultipart.api.multipart.IMultipart;
import mcmultipart.api.slot.EnumFaceSlot;
import mcmultipart.api.slot.IPartSlot;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public class PartAdvancedModem implements IMultipart
{
@Override
public IPartSlot getSlotForPlacement( World world, BlockPos pos, BlockState state, Direction facing, float hitX, float hitY, float hitZ, LivingEntity placer )
{
return EnumFaceSlot.fromFace( state.getValue( BlockAdvancedModem.FACING ) );
}
@Override
public IPartSlot getSlotFromWorld( IBlockAccess world, BlockPos pos, BlockState state )
{
return EnumFaceSlot.fromFace( state.getValue( BlockAdvancedModem.FACING ) );
}
@Override
public Block getBlock()
{
return ComputerCraft.Blocks.advancedModem;
}
}

View File

@@ -1,67 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.mcmp;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
import dan200.computercraft.shared.peripheral.common.BlockPeripheralVariant;
import mcmultipart.api.multipart.IMultipart;
import mcmultipart.api.slot.EnumCenterSlot;
import mcmultipart.api.slot.EnumFaceSlot;
import mcmultipart.api.slot.IPartSlot;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
public class PartPeripheral implements IMultipart
{
@Override
public IPartSlot getSlotForPlacement( World world, BlockPos pos, BlockState state, Direction facing, float hitX, float hitY, float hitZ, LivingEntity placer )
{
return getSlot( state );
}
@Override
public IPartSlot getSlotFromWorld( IBlockAccess world, BlockPos pos, BlockState state )
{
return getSlot( state );
}
@Nonnull
private static IPartSlot getSlot( BlockState state )
{
BlockPeripheralVariant type = state.getValue( BlockPeripheral.VARIANT );
if( type == BlockPeripheralVariant.WirelessModemUpOn || type == BlockPeripheralVariant.WirelessModemUpOff )
{
return EnumFaceSlot.UP;
}
else if( type == BlockPeripheralVariant.WirelessModemDownOn || type == BlockPeripheralVariant.WirelessModemDownOff )
{
return EnumFaceSlot.DOWN;
}
else if( type == BlockPeripheralVariant.WirelessModemOff || type == BlockPeripheralVariant.WirelessModemOn )
{
return EnumFaceSlot.fromFace( state.getValue( BlockPeripheral.FACING ) );
}
else
{
return EnumCenterSlot.CENTER;
}
}
@Override
public Block getBlock()
{
return ComputerCraft.Blocks.peripheral;
}
}

View File

@@ -20,7 +20,7 @@ import net.minecraftforge.fml.common.ObfuscationReflectionHelper.UnableToFindFie
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
/** /**
* An implementation of IMedia for ItemRecord's * An implementation of IMedia for ItemRecords.
*/ */
public final class RecordMedia implements IMedia public final class RecordMedia implements IMedia
{ {

View File

@@ -90,6 +90,7 @@ public final class NetworkHandler
* /** * /**
* Register packet, and a thread-unsafe handler for it. * Register packet, and a thread-unsafe handler for it.
* *
* @param <T> The type of the packet to send.
* @param id The identifier for this packet type * @param id The identifier for this packet type
* @param factory The factory for this type of packet. * @param factory The factory for this type of packet.
*/ */
@@ -106,6 +107,8 @@ public final class NetworkHandler
* /** * /**
* Register packet, and a thread-unsafe handler for it. * Register packet, and a thread-unsafe handler for it.
* *
* @param <T> The type of the packet to send.
* @param type The class of the type of packet to send.
* @param id The identifier for this packet type * @param id The identifier for this packet type
* @param decoder The factory for this type of packet. * @param decoder The factory for this type of packet.
*/ */

View File

@@ -13,7 +13,7 @@ import net.minecraft.util.Hand;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
/** /**
* Opens a printout GUI based on the currently held item * Opens a printout GUI based on the currently held item.
* *
* @see ContainerHeldItem * @see ContainerHeldItem
* @see dan200.computercraft.shared.media.items.ItemPrintout * @see dan200.computercraft.shared.media.items.ItemPrintout

View File

@@ -14,7 +14,7 @@ import net.minecraft.tileentity.CommandBlockTileEntity;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.getString; import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public class CommandBlockPeripheral implements IPeripheral public class CommandBlockPeripheral implements IPeripheral
{ {

View File

@@ -18,7 +18,7 @@ import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.optString; import static dan200.computercraft.api.lua.ArgumentHelper.optString;
class DiskDrivePeripheral implements IPeripheral class DiskDrivePeripheral implements IPeripheral
{ {

View File

@@ -21,7 +21,7 @@ import javax.annotation.Nonnull;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt; import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPacketReceiver public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPacketReceiver
{ {

View File

@@ -210,7 +210,7 @@ public class BlockCable extends BlockGeneric implements IWaterLoggable
BlockPos offsetPos = pos.offset( facing ); BlockPos offsetPos = pos.offset( facing );
BlockState offsetState = world.getBlockState( offsetPos ); BlockState offsetState = world.getBlockState( offsetPos );
return Block.hasSolidSide( offsetState, world, offsetPos, facing.getOpposite() ); return hasSolidSide( offsetState, world, offsetPos, facing.getOpposite() );
} }
@Nullable @Nullable

View File

@@ -201,8 +201,7 @@ public class TileCable extends TileGeneric implements IPeripheralTile
public void onNeighbourChange( @Nonnull BlockPos neighbour ) public void onNeighbourChange( @Nonnull BlockPos neighbour )
{ {
Direction dir = getDirection(); Direction dir = getDirection();
if( neighbour.equals( getPos().offset( dir ) ) && hasModem() if( neighbour.equals( getPos().offset( dir ) ) && hasModem() && !getBlockState().isValidPosition( getWorld(), getPos() ) )
&& getBlockState().isValidPosition( world, pos ) )
{ {
if( hasCable() ) if( hasCable() )
{ {

View File

@@ -23,7 +23,7 @@ import java.util.Collections;
import java.util.Map; import java.util.Map;
/** /**
* Represents a local peripheral exposed on the wired network * Represents a local peripheral exposed on the wired network.
* *
* This is responsible for getting the peripheral in world, tracking id and type and determining whether * This is responsible for getting the peripheral in world, tracking id and type and determining whether
* it has changed. * it has changed.
@@ -39,7 +39,7 @@ public final class WiredModemLocalPeripheral
private IPeripheral peripheral; private IPeripheral peripheral;
/** /**
* Attach a new peripheral from the world * Attach a new peripheral from the world.
* *
* @param world The world to search in * @param world The world to search in
* @param origin The position to search from * @param origin The position to search from
@@ -76,7 +76,7 @@ public final class WiredModemLocalPeripheral
} }
/** /**
* Detach the current peripheral * Detach the current peripheral.
* *
* @return Whether the peripheral changed * @return Whether the peripheral changed
*/ */

View File

@@ -28,7 +28,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import static dan200.computercraft.core.apis.ArgumentHelper.getString; import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public abstract class WiredModemPeripheral extends ModemPeripheral implements IWiredSender public abstract class WiredModemPeripheral extends ModemPeripheral implements IWiredSender
{ {

View File

@@ -49,9 +49,18 @@ public class BlockMonitor extends BlockGeneric
@Override @Override
public BlockRenderLayer getRenderLayer() public BlockRenderLayer getRenderLayer()
{ {
// We use the CUTOUT layer, as otherwise monitor rendering will cause flickering.
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@Override
@Deprecated
public boolean isSolid( BlockState state )
{
// We override isSolid, as our overriding of getRenderLayer means that it would otherwise return false.
return true;
}
@Override @Override
protected void fillStateContainer( StateContainer.Builder<Block, BlockState> builder ) protected void fillStateContainer( StateContainer.Builder<Block, BlockState> builder )
{ {

View File

@@ -17,7 +17,7 @@ import org.apache.commons.lang3.ArrayUtils;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.*; import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class MonitorPeripheral implements IPeripheral public class MonitorPeripheral implements IPeripheral
{ {
@@ -123,7 +123,7 @@ public class MonitorPeripheral implements IPeripheral
case 8: case 8:
{ {
// setTextScale // setTextScale
int scale = (int) (getReal( args, 0 ) * 2.0); int scale = (int) (getFiniteDouble( args, 0 ) * 2.0);
if( scale < 1 || scale > 10 ) if( scale < 1 || scale > 10 )
{ {
throw new LuaException( "Expected number in range 0.5-5" ); throw new LuaException( "Expected number in range 0.5-5" );
@@ -184,9 +184,9 @@ public class MonitorPeripheral implements IPeripheral
} }
else else
{ {
double r = getReal( args, 1 ); double r = getFiniteDouble( args, 1 );
double g = getReal( args, 2 ); double g = getFiniteDouble( args, 2 );
double b = getReal( args, 3 ); double b = getFiniteDouble( args, 3 );
TermAPI.setColour( terminal, colour, r, g, b ); TermAPI.setColour( terminal, colour, r, g, b );
} }
return null; return null;

View File

@@ -15,8 +15,8 @@ import dan200.computercraft.shared.util.StringUtil;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt; import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
import static dan200.computercraft.core.apis.ArgumentHelper.optString; import static dan200.computercraft.api.lua.ArgumentHelper.optString;
public class PrinterPeripheral implements IPeripheral public class PrinterPeripheral implements IPeripheral
{ {

View File

@@ -23,8 +23,8 @@ import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import static dan200.computercraft.core.apis.ArgumentHelper.getString; import static dan200.computercraft.api.lua.ArgumentHelper.getString;
import static dan200.computercraft.core.apis.ArgumentHelper.optReal; import static dan200.computercraft.api.lua.ArgumentHelper.optFiniteDouble;
public abstract class SpeakerPeripheral implements IPeripheral public abstract class SpeakerPeripheral implements IPeripheral
{ {
@@ -72,8 +72,8 @@ public abstract class SpeakerPeripheral implements IPeripheral
case 0: // playSound case 0: // playSound
{ {
String name = getString( args, 0 ); String name = getString( args, 0 );
float volume = (float) optReal( args, 1, 1.0 ); float volume = (float) optFiniteDouble( args, 1, 1.0 );
float pitch = (float) optReal( args, 2, 1.0 ); float pitch = (float) optFiniteDouble( args, 2, 1.0 );
ResourceLocation identifier; ResourceLocation identifier;
try try
@@ -100,8 +100,8 @@ public abstract class SpeakerPeripheral implements IPeripheral
private synchronized Object[] playNote( Object[] arguments, ILuaContext context ) throws LuaException private synchronized Object[] playNote( Object[] arguments, ILuaContext context ) throws LuaException
{ {
String name = getString( arguments, 0 ); String name = getString( arguments, 0 );
float volume = (float) optReal( arguments, 1, 1.0 ); float volume = (float) optFiniteDouble( arguments, 1, 1.0 );
float pitch = (float) optReal( arguments, 2, 1.0 ); float pitch = (float) optFiniteDouble( arguments, 2, 1.0 );
NoteBlockInstrument instrument = null; NoteBlockInstrument instrument = null;
for( NoteBlockInstrument testInstrument : NoteBlockInstrument.values() ) for( NoteBlockInstrument testInstrument : NoteBlockInstrument.values() )

View File

@@ -67,8 +67,6 @@ public final class ComputerCraftProxyCommon
PlayerCreativeLootCondition.class, PlayerCreativeLootCondition.class,
PlayerCreativeLootCondition.INSTANCE PlayerCreativeLootCondition.INSTANCE
) ); ) );
// if( Loader.isModLoaded( ModCharset.MODID ) ) IntegrationCharset.register();
} }
private static void registerProviders() private static void registerProviders()

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