1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-23 01:47:38 +00:00

Compare commits

..

51 Commits

Author SHA1 Message Date
SquidDev
08d22fd3df Fix changelog being out-of-sync 2019-08-04 11:05:14 +01:00
SquidDev
e6c691a8f8 Fix rom's location
This isn't going to get annoying or anything
2019-08-04 11:02:07 +01:00
SquidDev
4b0e5c445c Merge branch 'master' into mc-1.14.x 2019-08-04 10:57:20 +01:00
SquidDev
cef2657048 Fix turtles being replaced by leaves
And logs. Well, hopefully at least.

Fixes #278
2019-07-21 10:28:22 +01:00
SquidDev
ccd85eb055 Bump Forge version 2019-07-21 09:41:58 +01:00
SquidDev
acfb72246c Bump JEI version 2019-07-07 15:52:52 +01:00
SquidDev
9d51c4c340 Use world-specific collider entity
This is equally an ugly hack, but means we're at least not constructing
entities with null worlds any more.

Ideally we could always use the turtle entity, but this will require a
bit more of a refactor.

Fixes #265
2019-07-05 22:09:42 +01:00
SquidDev
18068effec Use reflection to get the record's sound
getSound is client side only - I could have sworn it became shared at
some point, but that may have been reverted again (or I imagined it).

Fixes #263
2019-07-05 21:51:54 +01:00
SquidDev
6ea8ca991b Bump Forge to 1.14.3
Guess it's time for another release?
2019-06-26 08:25:32 +01:00
SquidDev
f1e551b960 Bump Forge version
Turtle models now work (though texture registration is still broken).
2019-06-23 15:30:29 +01:00
SquidDev
772c54ec74 Copy the item stack before merging
Otherwise we would mutate the stack, and so the current mount was
considered empty. Closes #240 (though would be nice to improve this).
2019-06-21 22:00:21 +01:00
SquidDev
13cb789c18 Fix "can deploy" check being entirely incorrect
Closes #258
2019-06-21 21:51:22 +01:00
SquidDev
42220c4268 Fix several other client-only methods 2019-06-21 21:32:15 +01:00
SquidDev
3052506e2e Reload configs from the file 2019-06-21 21:32:02 +01:00
SquidDev
0741daa7eb Fix usage of a client-only method
Should probably run forge-lint on this at some point, but it's a good
start.

Fixes #255
2019-06-21 21:02:09 +01:00
SquidDev
b4aa554279 Do not fetch the current block within onLoad
The chunk has not been fully loaded when onLoad is called, which means
we try to load it again, and so the server deadlocks.
2019-06-21 20:57:38 +01:00
SquidDev
8fe2abe0ae Forward tab key directly to the terminal
Fixes #256
2019-06-21 20:31:28 +01:00
SquidDev
5af789ae11 Bump Forge version 2019-06-21 20:31:17 +01:00
SquidDev
68542aca3a Fix cable breaking rendering
Texture locations have changed a little
2019-06-15 09:19:41 +01:00
SquidDev
594bc4203c Fix block drops for computers and turtles 2019-06-15 09:07:31 +01:00
SquidDev
57318b022d Merge branch 'master' into mc-1.14.x 2019-06-15 08:00:20 +01:00
SquidDev
761159aa93 Bump Forge version 2019-06-15 07:40:27 +01:00
SquidDev
8dd1c2a6cc Finish off containers, somewhat fix block drops
- Add Forge's "name" field to the loot tables. This doesn't resolve all
   our missing loot providers, but it's a start.
 - Add back GUIs for pocket computers, printouts, view computer, etc...
2019-06-12 08:40:20 +01:00
SquidDev
d10b657a54 Initial work on GUIs
Needs a bit of a cleanup, but it's a start!
2019-06-11 21:03:40 +01:00
SquidDev
f90da739eb And bump Forge again 2019-06-09 10:15:53 +01:00
SquidDev
d9cadf64e8 Get the build working I guess? 2019-06-09 09:07:31 +01:00
SquidDev
15d4a55cd8 Bump mappings and Forge versions
Things are shaping up nicely!
2019-06-09 08:58:49 +01:00
SquidDev
39a9ad0ce7 Initial update to 1.14
So very little works, but it compiles and runs.

Things to resolve over the next few days:
 - Horrible mappings (should largely be resolved by tomorrow).
 - Cannot send extra data over containers - we'll have to see what Forge
   does here.
 - Turtle models are broken
 - No block drops yet - this will largely be cherry-picking whatever I
   did on Fabric.
 - Weird inventory desyncs (items don't show up initially when
   interacting with a CC inventory).
 - Probably lots of other things.
2019-06-08 13:36:31 +01:00
SquidDev
0f3c44c926 Merge branch 'master' into mc-1.13.x 2019-06-08 08:21:08 +01:00
SquidDev
b6715bd812 Fix a couple of build failures 2019-06-02 18:36:34 +01:00
SquidDev
18aee02221 Mark CurseForge builds as release
They're almost definitely not, but I've had no bug reports so they must
work!
2019-06-02 17:28:13 +01:00
SquidDev
401bbf2e6a Fix turtle block placing failing 2019-06-02 17:25:49 +01:00
SquidDev
7467b7f88a Fix several deprecated warnings 2019-06-02 17:23:33 +01:00
SquidDev
c82d8a7c2a Merge branch 'master' into mc-1.13.x 2019-06-02 16:46:45 +01:00
SquidDev
3d67421d98 Bump Forge version 2019-06-02 16:18:44 +01:00
SquidDev
bb138326df Use correct model for blinking pocket computers
Fixes #211211211211211211211211211211211211211211211211211211211211211
2019-05-25 09:28:15 +01:00
xuyu0v0
e0660b1dab Create zh_cn.json 2019-05-06 21:47:43 +01:00
SquidDev
2182cfbeb7 Merge branch 'master' into mc-1.13.x 2019-05-06 21:32:56 +01:00
SquidDev
2c027adb68 Fix advancements
Looks like these were never properly updated. Woops.
2019-04-24 12:15:03 +01:00
SquidDev
4a25e7a178 Fix GH release uploading 2019-04-24 10:40:44 +01:00
SquidDev
55d54fec63 Bump versions 2019-04-24 10:33:50 +01:00
SquidDev
220e4bd660 Merge branch 'master' into mc-1.13.x 2019-04-24 10:15:33 +01:00
SquidDev
362dbd97ac Correctly handle capability creation & invalidation
Also make cable part detection more consistent.
2019-04-09 17:29:23 +01:00
SquidDev
aa0e1883d1 Add check for if item/block registration has failed
If mod loading fails, we'll continue to load colour handlers. As
blocks/items have not been registered, then we'll throw an NPE.

See MinecraftForge/MinecraftForge#5682. Somewhat fixes #168.
2019-04-09 16:32:20 +01:00
SquidDev
9cdbcb4332 Use int instead of long for configs
Forge's config system will read the default values as integers, meaning
it fails to validate against the config spec. Ideally this'd be fixed in
forge, but this is a suitable work around.
2019-04-09 16:31:00 +01:00
SquidDev
23ddd4feb5 Fix several deprecation warnings 2019-04-09 16:30:44 +01:00
SquidDev
fcaa777c95 Merge branch 'master' into mc-1.13.x 2019-04-09 11:11:12 +01:00
SquidDev
7afc3e5260 And fix the build failing 2019-04-02 21:33:55 +01:00
SquidDev
f9e13ca67a Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.

Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:

 - Flatten everything. For instance, there are now three instances of
   BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
   more BlockPeripheral (thank heavens) - there's separate block classes
   for each peripheral type.

 - Remove pretty much all legacy code. As we're breaking world
   compatibility anyway, we can remove all the code to load worlds from
   1.4 days.
 - The command system is largely rewriten to take advantage of 1.13's
   new system. It's very fancy!

 - WidgetTerminal now uses Minecraft's "GUI listener" system.

 - BREAKING CHANGE: All the codes in keys.lua are different, due to the
   move to LWJGL 3. Hopefully this won't have too much of an impact.

   I don't want to map to the old key codes on the Java side, as there
   always ends up being small but slight inconsistencies. IMO it's
   better to make a clean break - people should be using keys rather
   than hard coding the constants anyway.

 - commands.list now allows fetching sub-commands. The ROM has already
   been updated to allow fancy usage such as commands.time.set("noon").

 - Turtles, modems and cables can be waterlogged.
2019-04-02 20:59:48 +01:00
SquidDev
810258e9b8 Update and rename all resources
- Languages are converted to JSON
 - Rename most *(_advanced) blocks to *_{advanced,normal}. It's more
   verbose, but means they're sorted together.
 - A couple of changes to the ROM to work with some Java changes.
 - Update recipes and advancements to not use damage values.
2019-04-02 13:18:43 +01:00
SquidDev
5e462adc5c Relocate all resource files
- textures/{block,item}s -> textures/{block,item}
 - assets/*/{advancements,lua,recipes} -> data/*/...
2019-04-02 13:18:43 +01:00
1135 changed files with 13950 additions and 16927 deletions

View File

@@ -1,18 +0,0 @@
name: Build
on: [push, pull_request]
jobs:
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

14
.travis.yml Normal file
View File

@@ -0,0 +1,14 @@
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)
[![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")
[![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")
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
turtles and more to Minecraft.
@@ -41,7 +41,7 @@ Any contribution is welcome, be that using the mod, reporting bugs or contributi
develop CC:T, you'll need to follow these steps:
- **Clone the repository:** `git clone https://github.com/SquidDev-CC/CC-Tweaked.git && cd CC-Tweaked`
- **Setup Forge:** `./gradlew setupDecompWorkspace`
- **Setup Forge:** `./gradlew build`
- **Test your changes:** `./gradlew runClient` (or run the `GradleStart` class from your IDE).
If you want to run CC:T in a normal Minecraft instance, run `./gradlew build` and copy the `.jar` from `build/libs`.

View File

@@ -1,8 +1,7 @@
// For those who want the bleeding edge
buildscript {
repositories {
jcenter()
mavenCentral()
maven {
name = "forge"
url = "https://files.minecraftforge.net/maven"
@@ -10,8 +9,8 @@ buildscript {
}
dependencies {
classpath 'com.google.code.gson:gson:2.8.1'
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath 'net.sf.proguard:proguard-gradle:6.1.0beta1'
classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.130'
classpath 'net.sf.proguard:proguard-gradle:6.1.0beta2'
classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0'
}
}
@@ -23,7 +22,7 @@ plugins {
id "com.github.breadmoirai.github-release" version "2.2.4"
}
apply plugin: 'net.minecraftforge.gradle.forge'
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.ajoberstar.grgit'
apply plugin: 'maven-publish'
apply plugin: 'maven'
@@ -34,12 +33,35 @@ group = "org.squiddev"
archivesBaseName = "cc-tweaked-${mc_version}"
minecraft {
version = "${mc_version}-${forge_version}"
runDir = "run"
replace '${version}', mod_version
runs {
client {
workingDirectory project.file('run')
property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug'
mappings = mappings_version
makeObfSourceJar = false
mods {
computercraft {
source sourceSets.main
}
}
}
server {
workingDirectory project.file('run')
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
property 'forge.logging.console.level', 'debug'
mods {
computercraft {
source sourceSets.main
}
}
}
}
mappings channel: 'snapshot', version: "${mappings_version}".toString()
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
}
repositories {
@@ -68,13 +90,15 @@ configurations {
}
dependencies {
checkstyle "com.puppycrawl.tools:checkstyle:8.25"
checkstyle "com.puppycrawl.tools:checkstyle:8.21"
deobfProvided "mezz.jei:jei_1.12.2:4.15.0.269:api"
deobfProvided "pl.asie:Charset-Lib:0.5.4.6"
deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
runtime "mezz.jei:jei_1.12.2:4.15.0.269"
compileOnly fg.deobf("mezz.jei:jei-1.14.3:6.0.0.7:api")
// deobfProvided "pl.asie:Charset-Lib:0.5.4.6"
// deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
runtimeOnly fg.deobf("mezz.jei:jei-1.14.3:6.0.0.7")
shade 'org.squiddev:Cobalt:0.5.0-SNAPSHOT'
@@ -84,6 +108,15 @@ dependencies {
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
javadoc {
@@ -94,7 +127,13 @@ jar {
dependsOn javadoc
manifest {
attributes('FMLAT': 'computercraft_at.cfg')
attributes(["Specification-Title": "computercraft",
"Specification-Vendor": "SquidDev",
"Specification-Version": "1",
"Implementation-Title": "CC: Tweaked",
"Implementation-Version": "${mod_version}",
"Implementation-Vendor" :"SquidDev",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")])
}
from (sourceSets.main.allSource) {
@@ -142,13 +181,17 @@ task proguard(type: ProGuardTask, dependsOn: jar) {
dontobfuscate; dontoptimize; keepattributes; keepparameternames
// Proguard will remove directories by default, but that breaks JarMount.
keepdirectories 'assets/computercraft/lua**'
keepdirectories 'data/computercraft/lua**'
// Preserve ComputerCraft classes - we only want to strip shadowed files.
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
dontwarn 'module-info'
dontwarn 'org.apache.**,org.lwjgl.**'
}
task proguardMove(dependsOn: proguard) {
@@ -164,7 +207,7 @@ task proguardMove(dependsOn: proguard) {
}
}
reobfJar.dependsOn proguardMove
processResources {
inputs.property "version", mod_version
@@ -186,8 +229,8 @@ processResources {
inputs.property "commithash", hash
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
include 'assets/computercraft/lua/rom/help/credits.txt'
include 'META-INF/mods.toml'
include 'data/computercraft/lua/rom/help/credits.txt'
expand 'version': mod_version,
'mcversion': mc_version,
@@ -195,12 +238,12 @@ processResources {
}
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
exclude 'assets/computercraft/lua/rom/help/credits.txt'
exclude 'META-INF/mods.toml'
exclude 'data/computercraft/lua/rom/help/credits.txt'
}
}
task compressJson(dependsOn: extractAnnotationsJar) {
task compressJson(dependsOn: jar) {
group "compact"
description "Minifies all JSON files, stripping whitespace"
@@ -298,14 +341,14 @@ task checkRelease {
description "Verifies that everything is ready for a release"
inputs.property "version", mod_version
inputs.file("src/main/resources/assets/computercraft/lua/rom/help/changelog.txt")
inputs.file("src/main/resources/assets/computercraft/lua/rom/help/whatsnew.txt")
inputs.file("src/main/resources/data/computercraft/lua/rom/help/changelog.txt")
inputs.file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt")
doLast {
def ok = true
// Check we're targetting the current version
def whatsnew = new File("src/main/resources/assets/computercraft/lua/rom/help/whatsnew.txt").readLines()
def whatsnew = new File("src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt").readLines()
if (whatsnew[0] != "New features in CC: Tweaked $mod_version") {
ok = false
project.logger.error("Expected `whatsnew.txt' to target $mod_version.")
@@ -322,7 +365,7 @@ task checkRelease {
// Check whatsnew and changelog match.
def versionChangelog = "# " + whatsnew.join("\n")
def changelog = new File("src/main/resources/assets/computercraft/lua/rom/help/changelog.txt").getText()
def changelog = new File("src/main/resources/data/computercraft/lua/rom/help/changelog.txt").getText()
if (!changelog.startsWith(versionChangelog)) {
ok = false
project.logger.error("whatsnew and changelog are not in sync")
@@ -331,13 +374,12 @@ task checkRelease {
if (!ok) throw new IllegalStateException("Could not check release")
}
}
check.dependsOn checkRelease
curseforge {
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
project {
id = '282001'
releaseType = 'release'
releaseType = 'beta'
changelog = "Release notes can be found on the GitHub repository (https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
relations {
@@ -350,7 +392,7 @@ publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourceJar
// artifact sourceJar
}
}
}
@@ -403,19 +445,17 @@ githubRelease {
token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
owner 'SquidDev-CC'
repo 'CC-Tweaked'
try {
targetCommitish = Grgit.open(dir: '.').branch.current().name
} catch(Exception ignored) { }
targetCommitish { Grgit.open(dir: '.').branch.current().name }
tagName "v${mc_version}-${mod_version}"
releaseName "[${mc_version}] ${mod_version}"
body {
"## " + new File("src/main/resources/assets/computercraft/lua/rom/help/whatsnew.txt")
"## " + new File("src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt")
.readLines()
.takeWhile { it != 'Type "help changelog" to see the full version history.' }
.join("\n").trim()
}
prerelease false
prerelease true
}
def uploadTasks = ["uploadArchives", "curseforge", "githubRelease"]
@@ -425,6 +465,3 @@ task uploadAll(dependsOn: uploadTasks) {
group "upload"
description "Uploads to all repositories (Maven, Curse, GitHub release)"
}
runClient.outputs.upToDateWhen { false }
runServer.outputs.upToDateWhen { false }

View File

@@ -14,7 +14,9 @@
<!-- Annotations -->
<module name="AnnotationLocation" />
<module name="AnnotationUseStyle" />
<module name="MissingDeprecated" />
<module name="MissingDeprecated">
<property name="skipNoJavadoc" value="true" />
</module>
<module name="MissingOverride" />
<!-- Blocks -->
@@ -55,9 +57,6 @@
<module name="SimplifyBooleanReturn" />
<module name="StringLiteralEquality" />
<module name="UnnecessaryParentheses" />
<module name="UnnecessarySemicolonAfterTypeMemberDeclaration" />
<module name="UnnecessarySemicolonInTryWithResources" />
<module name="UnnecessarySemicolonInEnumeration" />
<!-- Imports -->
<module name="CustomImportOrder" />
@@ -66,16 +65,10 @@
<module name="UnusedImports" />
<!-- Javadoc -->
<!-- TODO: Missing* checks for the dan200.computercraft.api package? -->
<module name="AtclauseOrder" />
<module name="InvalidJavadocPosition" />
<module name="JavadocBlockTagLocation" />
<module name="JavadocMethod"/>
<module name="JavadocType"/>
<module name="JavadocStyle" />
<!-- TODO: Cleanup our documentation before enabling JavadocMethod, JavadocStyle, JavadocType and SummaryJavadoc. -->
<module name="NonEmptyAtclauseDescription" />
<module name="SingleLineJavadoc" />
<module name="SummaryJavadocCheck"/>
<!-- Misc -->
<module name="ArrayTypeStyle" />
@@ -156,14 +149,11 @@
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true" />
<property name="ignoreEnhancedForColon" value="false" />
<property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,DO_WHILE,EQUAL,GE,GT,LAMBDA,LAND,LCURLY,LE,LITERAL_RETURN,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,RCURLY,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND" />
<property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAMBDA,LAND,LCURLY,LE,LITERAL_RETURN,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,RCURLY,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND" />
</module>
</module>
<module name="FileTabCharacter" />
<module name="NewlineAtEndOfFile" />
<module name="RegexpSingleline">
<property name="format" value="\s+$"/>
<property name="message" value="Trailing whitespace"/>
</module>
</module>

View File

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

View File

@@ -1,7 +1,7 @@
# Mod properties
mod_version=1.85.0
mod_version=1.84.0
# Minecraft properties
mc_version=1.12.2
forge_version=14.23.4.2749
mappings_version=snapshot_20180724
mc_version=1.14.4
forge_version=28.0.11
mappings_version=20190721-1.14.3

Binary file not shown.

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip

View File

@@ -1,30 +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;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.network.NetworkCheckHandler;
import net.minecraftforge.fml.relauncher.Side;
import java.util.Map;
/**
* A stub mod for CC: Tweaked. This doesn't have any functionality (everything of note is done in
* {@link ComputerCraft}), but people may depend on this if they require CC: Tweaked functionality.
*/
@Mod(
modid = "cctweaked", name = ComputerCraft.NAME, version = ComputerCraft.VERSION,
acceptableRemoteVersions = "*"
)
public class CCTweaked
{
@NetworkCheckHandler
public boolean onNetworkConnect( Map<String, String> mods, Side side )
{
return true;
}
}

View File

@@ -7,95 +7,50 @@
package dan200.computercraft;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount;
import dan200.computercraft.api.lua.ILuaAPIFactory;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.media.IMediaProvider;
import dan200.computercraft.api.network.IPacketNetwork;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.api.permissions.ITurtlePermissionProvider;
import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.event.TurtleAction;
import dan200.computercraft.core.apis.AddressPredicate;
import dan200.computercraft.core.apis.ApiFactories;
import dan200.computercraft.core.apis.http.websocket.Websocket;
import dan200.computercraft.core.computer.MainThread;
import dan200.computercraft.core.filesystem.ComboMount;
import dan200.computercraft.core.filesystem.FileMount;
import dan200.computercraft.core.filesystem.JarMount;
import dan200.computercraft.core.tracking.Tracking;
import dan200.computercraft.shared.*;
import dan200.computercraft.shared.computer.blocks.BlockCommandComputer;
import dan200.computercraft.core.filesystem.ResourceMount;
import dan200.computercraft.shared.Config;
import dan200.computercraft.shared.computer.blocks.BlockComputer;
import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
import dan200.computercraft.shared.computer.items.ItemCommandComputer;
import dan200.computercraft.shared.computer.items.ItemComputer;
import dan200.computercraft.shared.media.items.ItemDiskExpanded;
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
import dan200.computercraft.shared.media.items.ItemDisk;
import dan200.computercraft.shared.media.items.ItemPrintout;
import dan200.computercraft.shared.media.items.ItemTreasureDisk;
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
import dan200.computercraft.shared.peripheral.common.ItemPeripheral;
import dan200.computercraft.shared.peripheral.diskdrive.BlockDiskDrive;
import dan200.computercraft.shared.peripheral.modem.wired.BlockCable;
import dan200.computercraft.shared.peripheral.modem.wired.BlockWiredModemFull;
import dan200.computercraft.shared.peripheral.modem.wired.ItemCable;
import dan200.computercraft.shared.peripheral.modem.wireless.BlockAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.ItemAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
import dan200.computercraft.shared.peripheral.modem.wired.ItemBlockCable;
import dan200.computercraft.shared.peripheral.modem.wireless.BlockWirelessModem;
import dan200.computercraft.shared.peripheral.monitor.BlockMonitor;
import dan200.computercraft.shared.peripheral.printer.BlockPrinter;
import dan200.computercraft.shared.peripheral.speaker.BlockSpeaker;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
import dan200.computercraft.shared.turtle.items.ItemTurtleAdvanced;
import dan200.computercraft.shared.turtle.items.ItemTurtleLegacy;
import dan200.computercraft.shared.turtle.items.ItemTurtleNormal;
import dan200.computercraft.shared.turtle.items.ItemTurtle;
import dan200.computercraft.shared.turtle.upgrades.*;
import dan200.computercraft.shared.util.CreativeTabMain;
import dan200.computercraft.shared.util.IDAssigner;
import dan200.computercraft.shared.util.IoUtil;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import dan200.computercraft.shared.wired.WiredNode;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.fml.common.*;
import net.minecraftforge.fml.common.event.*;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraft.resources.IReloadableResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.EnumSet;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@Mod(
modid = ComputerCraft.MOD_ID, name = ComputerCraft.NAME, version = ComputerCraft.VERSION,
guiFactory = "dan200.computercraft.client.gui.GuiConfigCC$Factory",
dependencies = "required:forge@[14.23.4.2746,)"
)
public class ComputerCraft
@Mod( ComputerCraft.MOD_ID )
public final class ComputerCraft
{
public static final String MOD_ID = "computercraft";
static final String VERSION = "${version}";
static final String NAME = "CC: Tweaked";
public static final int DATAFIXER_VERSION = 0;
// Configuration options
public static final String[] DEFAULT_HTTP_WHITELIST = new String[] { "*" };
@@ -157,46 +112,54 @@ public class ComputerCraft
// Blocks and Items
public static final class Blocks
{
public static BlockComputer computer;
public static BlockCommandComputer commandComputer;
public static BlockComputer computerNormal;
public static BlockComputer computerAdvanced;
public static BlockComputer computerCommand;
public static BlockTurtle turtle;
public static BlockTurtle turtleExpanded;
public static BlockTurtle turtleNormal;
public static BlockTurtle turtleAdvanced;
public static BlockPeripheral peripheral;
public static BlockCable cable;
public static BlockAdvancedModem advancedModem;
public static BlockSpeaker speaker;
public static BlockDiskDrive diskDrive;
public static BlockPrinter printer;
public static BlockMonitor monitorNormal;
public static BlockMonitor monitorAdvanced;
public static BlockWirelessModem wirelessModemNormal;
public static BlockWirelessModem wirelessModemAdvanced;
public static BlockWiredModemFull wiredModemFull;
public static BlockCable cable;
}
public static final class Items
{
public static ItemComputer computer;
public static ItemCommandComputer commandComputer;
public static ItemComputer computerNormal;
public static ItemComputer computerAdvanced;
public static ItemComputer computerCommand;
public static ItemTurtleLegacy turtle;
public static ItemTurtleNormal turtleExpanded;
public static ItemTurtleAdvanced turtleAdvanced;
public static ItemPocketComputer pocketComputerNormal;
public static ItemPocketComputer pocketComputerAdvanced;
public static ItemPocketComputer pocketComputer;
public static ItemTurtle turtleNormal;
public static ItemTurtle turtleAdvanced;
public static ItemDiskLegacy disk;
public static ItemDiskExpanded diskExpanded;
public static ItemDisk disk;
public static ItemTreasureDisk treasureDisk;
public static ItemPrintout printout;
public static ItemPrintout printedPage;
public static ItemPrintout printedPages;
public static ItemPrintout printedBook;
public static ItemPeripheral peripheral;
public static ItemAdvancedModem advancedModem;
public static ItemCable cable;
public static ItemBlock wiredModemFull;
public static ItemBlockCable.Cable cable;
public static ItemBlockCable.WiredModem wiredModem;
}
public static final class TurtleUpgrades
{
public static TurtleModem wirelessModem;
public static TurtleModem advancedModem;
public static TurtleModem wirelessModemNormal;
public static TurtleModem wirelessModemAdvanced;
public static TurtleSpeaker speaker;
public static TurtleCraftingTable craftingTable;
@@ -209,457 +172,45 @@ public class ComputerCraft
public static final class PocketUpgrades
{
public static PocketModem wirelessModem;
public static PocketModem advancedModem;
public static PocketModem wirelessModemNormal;
public static PocketModem wirelessModemAdvanced;
public static PocketSpeaker speaker;
@Deprecated
public static PocketSpeaker pocketSpeaker;
}
@Deprecated
public static final class Upgrades
{
public static TurtleModem advancedModem;
}
// Registries
public static final ClientComputerRegistry clientComputerRegistry = new ClientComputerRegistry();
public static final ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry();
// Creative
public static CreativeTabMain mainCreativeTab;
// Logging
public static Logger log;
public static final Logger log = LogManager.getLogger( MOD_ID );
// Peripheral providers. This is still here to ensure compatibility with Plethora and Computronics
public static List<IPeripheralProvider> peripheralProviders = new ArrayList<>();
// Implementation
@Mod.Instance( ComputerCraft.MOD_ID )
public static ComputerCraft instance;
@SidedProxy(
clientSide = "dan200.computercraft.client.proxy.ComputerCraftProxyClient",
serverSide = "dan200.computercraft.shared.proxy.ComputerCraftProxyCommon"
)
private static ComputerCraftProxyCommon proxy;
@Mod.EventHandler
public void preInit( FMLPreInitializationEvent event )
public ComputerCraft()
{
log = event.getModLog();
// Load config
Config.load( event.getSuggestedConfigurationFile() );
proxy.preInit();
}
@Mod.EventHandler
public void init( FMLInitializationEvent event )
{
proxy.init();
}
@Mod.EventHandler
public void onServerStarting( FMLServerStartingEvent event )
{
ComputerCraftProxyCommon.initServer( event.getServer() );
}
@Mod.EventHandler
public void onServerStart( FMLServerStartedEvent event )
{
if( FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER )
{
ComputerCraft.serverComputerRegistry.reset();
WirelessNetwork.resetNetworks();
MainThread.reset();
Tracking.reset();
}
}
@Mod.EventHandler
public void onServerStopped( FMLServerStoppedEvent event )
{
if( FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER )
{
ComputerCraft.serverComputerRegistry.reset();
WirelessNetwork.resetNetworks();
MainThread.reset();
Tracking.reset();
}
Config.load();
}
public static String getVersion()
{
return VERSION;
return "${version}";
}
private static File getBaseDir()
static IMount createResourceMount( String domain, String subPath )
{
return FMLCommonHandler.instance().getMinecraftServerInstance().getDataDirectory();
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
ResourceMount mount = new ResourceMount( domain, subPath, manager );
return mount.exists( "" ) ? mount : null;
}
private static File getResourcePackDir()
{
return new File( getBaseDir(), "resourcepacks" );
}
@Deprecated
public static void registerPermissionProvider( ITurtlePermissionProvider provider )
{
TurtlePermissions.register( provider );
}
@Deprecated
public static void registerPocketUpgrade( IPocketUpgrade upgrade )
{
dan200.computercraft.shared.PocketUpgrades.register( upgrade );
}
@Deprecated
public static void registerPeripheralProvider( IPeripheralProvider provider )
{
Peripherals.register( provider );
}
@Deprecated
public static void registerBundledRedstoneProvider( IBundledRedstoneProvider provider )
{
BundledRedstone.register( provider );
}
@Deprecated
public static void registerMediaProvider( IMediaProvider provider )
{
MediaProviders.register( provider );
}
@Deprecated
public static void registerAPIFactory( ILuaAPIFactory factory )
{
ApiFactories.register( factory );
}
@Deprecated
public static IWiredNode createWiredNodeForElement( IWiredElement element )
{
return new WiredNode( element );
}
@Deprecated
public static IWiredElement getWiredElementAt( IBlockAccess world, BlockPos pos, EnumFacing side )
{
TileEntity tile = world.getTileEntity( pos );
return tile != null && tile.hasCapability( CapabilityWiredElement.CAPABILITY, side )
? tile.getCapability( CapabilityWiredElement.CAPABILITY, side )
: null;
}
@Deprecated
public static int getDefaultBundledRedstoneOutput( World world, BlockPos pos, EnumFacing side )
{
return BundledRedstone.getDefaultOutput( world, pos, side );
}
@Deprecated
public static IPacketNetwork getWirelessNetwork()
{
return WirelessNetwork.getUniversal();
}
@Deprecated
public static int createUniqueNumberedSaveDir( World world, String parentSubPath )
{
return IDAssigner.getNextIDFromDirectory( parentSubPath );
}
@Deprecated
public static IWritableMount createSaveDirMount( World world, String subPath, long capacity )
public static InputStream getResourceFile( String domain, String subPath )
{
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
try
{
return new FileMount( new File( getWorldDir(), subPath ), capacity );
return manager.getResource( new ResourceLocation( domain, subPath ) ).getInputStream();
}
catch( Exception e )
catch( IOException ignored )
{
return null;
}
}
private static void loadFromFile( List<IMount> mounts, File file, String path, boolean allowMissing )
{
try
{
if( file.isFile() )
{
mounts.add( new JarMount( file, path ) );
}
else
{
File subResource = new File( file, path );
if( subResource.exists() ) mounts.add( new FileMount( subResource, 0 ) );
}
}
catch( IOException | RuntimeException e )
{
if( allowMissing && e instanceof FileNotFoundException ) return;
ComputerCraft.log.error( "Could not load mount '" + path + " 'from '" + file.getName() + "'", e );
}
}
@Deprecated
public static IMount createResourceMount( Class<?> modClass, String domain, String subPath )
{
// Start building list of mounts
List<IMount> mounts = new ArrayList<>();
subPath = "assets/" + domain + "/" + subPath;
// Mount from debug dir
File codeDir = getDebugCodeDir( modClass );
if( codeDir != null )
{
File subResource = new File( codeDir, subPath );
if( subResource.exists() )
{
IMount resourcePackMount = new FileMount( subResource, 0 );
mounts.add( resourcePackMount );
}
}
// Mount from mod jars, preferring the specified one.
File modJar = getContainingJar( modClass );
Set<File> otherMods = new HashSet<>();
for( ModContainer container : Loader.instance().getActiveModList() )
{
File modFile = container.getSource();
if( modFile != null && !modFile.equals( modJar ) && modFile.exists() )
{
otherMods.add( container.getSource() );
}
}
for( File file : otherMods )
{
loadFromFile( mounts, file, subPath, true );
}
if( modJar != null )
{
loadFromFile( mounts, modJar, subPath, false );
}
// Mount from resource packs
File resourcePackDir = getResourcePackDir();
if( resourcePackDir.exists() && resourcePackDir.isDirectory() )
{
String[] resourcePacks = resourcePackDir.list();
for( String resourcePackName : resourcePacks )
{
File resourcePack = new File( resourcePackDir, resourcePackName );
loadFromFile( mounts, resourcePack, subPath, true );
}
}
// Return the combination of all the mounts found
if( mounts.size() >= 2 )
{
IMount[] mountArray = new IMount[mounts.size()];
mounts.toArray( mountArray );
return new ComboMount( mountArray );
}
else if( mounts.size() == 1 )
{
return mounts.get( 0 );
}
else
{
return null;
}
}
public static InputStream getResourceFile( Class<?> modClass, String domain, String subPath )
{
// Start searching in possible locations
subPath = "assets/" + domain + "/" + subPath;
// Look in resource packs
File resourcePackDir = getResourcePackDir();
if( resourcePackDir.exists() && resourcePackDir.isDirectory() )
{
String[] resourcePacks = resourcePackDir.list();
for( String resourcePackPath : resourcePacks )
{
File resourcePack = new File( resourcePackDir, resourcePackPath );
if( resourcePack.isDirectory() )
{
// Mount a resource pack from a folder
File subResource = new File( resourcePack, subPath );
if( subResource.exists() && subResource.isFile() )
{
try
{
return new FileInputStream( subResource );
}
catch( FileNotFoundException ignored )
{
}
}
}
else
{
ZipFile zipFile = null;
try
{
final ZipFile zip = zipFile = new ZipFile( resourcePack );
ZipEntry entry = zipFile.getEntry( subPath );
if( entry != null )
{
// Return a custom InputStream which will close the original zip when finished.
return new FilterInputStream( zipFile.getInputStream( entry ) )
{
@Override
public void close() throws IOException
{
super.close();
zip.close();
}
};
}
else
{
IoUtil.closeQuietly( zipFile );
}
}
catch( IOException e )
{
if( zipFile != null ) IoUtil.closeQuietly( zipFile );
}
}
}
}
// Look in debug dir
File codeDir = getDebugCodeDir( modClass );
if( codeDir != null )
{
File subResource = new File( codeDir, subPath );
if( subResource.exists() && subResource.isFile() )
{
try
{
return new FileInputStream( subResource );
}
catch( FileNotFoundException ignored )
{
}
}
}
// Look in class loader
return modClass.getClassLoader().getResourceAsStream( subPath );
}
private static File getContainingJar( Class<?> modClass )
{
String path = modClass.getProtectionDomain().getCodeSource().getLocation().getPath();
int bangIndex = path.indexOf( '!' );
if( bangIndex >= 0 )
{
path = path.substring( 0, bangIndex );
}
URL url;
try
{
url = new URL( path );
}
catch( MalformedURLException e1 )
{
return null;
}
File file;
try
{
file = new File( url.toURI() );
}
catch( URISyntaxException e )
{
file = new File( url.getPath() );
}
return file;
}
private static File getDebugCodeDir( Class<?> modClass )
{
String path = modClass.getProtectionDomain().getCodeSource().getLocation().getPath();
int bangIndex = path.indexOf( '!' );
return bangIndex >= 0 ? null : new File( new File( path ).getParentFile(), "../.." );
}
@Deprecated
public static void registerTurtleUpgrade( ITurtleUpgrade upgrade )
{
dan200.computercraft.shared.TurtleUpgrades.register( upgrade );
}
public static File getWorldDir()
{
return DimensionManager.getCurrentSaveRootDirectory();
}
//region Compatibility
@Deprecated
public static File getWorldDir( World world )
{
return DimensionManager.getCurrentSaveRootDirectory();
}
@Deprecated
public static IMedia getMedia( ItemStack stack )
{
return MediaProviders.get( stack );
}
@Deprecated
public static IPocketUpgrade getPocketUpgrade( ItemStack stack )
{
return dan200.computercraft.shared.PocketUpgrades.get( stack );
}
@Deprecated
public static ITurtleUpgrade getTurtleUpgrade( ItemStack stack )
{
return dan200.computercraft.shared.TurtleUpgrades.get( stack );
}
@Deprecated
public static IPocketUpgrade getPocketUpgrade( String id )
{
return dan200.computercraft.shared.PocketUpgrades.get( id );
}
@Deprecated
public static ITurtleUpgrade getTurtleUpgrade( String id )
{
return dan200.computercraft.shared.TurtleUpgrades.get( id );
}
@Deprecated
public static IPeripheral getPeripheralAt( World world, BlockPos pos, EnumFacing side )
{
return Peripherals.getPeripheral( world, pos, side );
}
@Deprecated
public static boolean canPlayerUseCommands( EntityPlayer player )
{
MinecraftServer server = player.getServer();
return server != null && server.getPlayerList().canSendCommands( player.getGameProfile() );
}
//endregion
}

View File

@@ -0,0 +1,141 @@
/*
* 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;
import dan200.computercraft.api.ComputerCraftAPI.IComputerCraftAPI;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount;
import dan200.computercraft.api.lua.ILuaAPIFactory;
import dan200.computercraft.api.media.IMediaProvider;
import dan200.computercraft.api.network.IPacketNetwork;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.core.apis.ApiFactories;
import dan200.computercraft.core.filesystem.FileMount;
import dan200.computercraft.shared.*;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
import dan200.computercraft.shared.util.IDAssigner;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import dan200.computercraft.shared.wired.WiredNode;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import javax.annotation.Nonnull;
import java.io.File;
public final class ComputerCraftAPIImpl implements IComputerCraftAPI
{
public static final ComputerCraftAPIImpl INSTANCE = new ComputerCraftAPIImpl();
private ComputerCraftAPIImpl()
{
}
@Nonnull
@Override
public String getInstalledVersion()
{
return "${version}";
}
@Override
public int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath )
{
return IDAssigner.getNextId( parentSubPath );
}
@Override
public IWritableMount createSaveDirMount( @Nonnull World world, @Nonnull String subPath, long capacity )
{
try
{
return new FileMount( new File( IDAssigner.getDir(), subPath ), capacity );
}
catch( Exception e )
{
return null;
}
}
@Override
public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
{
return ComputerCraft.createResourceMount( domain, subPath );
}
@Override
public void registerPeripheralProvider( @Nonnull IPeripheralProvider provider )
{
Peripherals.register( provider );
}
@Override
public void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade )
{
TurtleUpgrades.register( upgrade );
}
@Override
public void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider )
{
BundledRedstone.register( provider );
}
@Override
public int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
return BundledRedstone.getDefaultOutput( world, pos, side );
}
@Override
public void registerMediaProvider( @Nonnull IMediaProvider provider )
{
MediaProviders.register( provider );
}
@Override
public void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade )
{
PocketUpgrades.register( upgrade );
}
@Nonnull
@Override
public IPacketNetwork getWirelessNetwork()
{
return WirelessNetwork.getUniversal();
}
@Override
public void registerAPIFactory( @Nonnull ILuaAPIFactory factory )
{
ApiFactories.register( factory );
}
@Nonnull
@Override
public IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element )
{
return new WiredNode( element );
}
@Nonnull
@Override
public LazyOptional<IWiredElement> getWiredElementAt( @Nonnull IBlockReader world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
TileEntity tile = world.getTileEntity( pos );
return tile == null ? LazyOptional.empty() : tile.getCapability( CapabilityWiredElement.CAPABILITY, side );
}
}

View File

@@ -7,10 +7,10 @@ package dan200.computercraft.api;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleUpgradeType;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IItemProvider;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Util;
import javax.annotation.Nonnull;
@@ -22,43 +22,31 @@ import javax.annotation.Nonnull;
public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade
{
private final ResourceLocation id;
private final int legacyId;
private final TurtleUpgradeType type;
private final String adjective;
private final ItemStack stack;
protected AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, String adjective, ItemStack stack )
protected AbstractTurtleUpgrade( ResourceLocation id, TurtleUpgradeType type, String adjective, ItemStack stack )
{
this.id = id;
this.legacyId = legacyId;
this.type = type;
this.adjective = adjective;
this.stack = stack;
}
protected AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, String adjective, Item item )
protected AbstractTurtleUpgrade( ResourceLocation id, TurtleUpgradeType type, String adjective, IItemProvider item )
{
this( id, legacyId, type, adjective, new ItemStack( item ) );
this( id, type, adjective, new ItemStack( item ) );
}
protected AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, String adjective, Block block )
protected AbstractTurtleUpgrade( ResourceLocation id, TurtleUpgradeType type, ItemStack stack )
{
this( id, legacyId, type, adjective, new ItemStack( block ) );
this( id, type, Util.makeTranslationKey( "upgrade", id ) + ".adjective", stack );
}
protected AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, ItemStack stack )
protected AbstractTurtleUpgrade( ResourceLocation id, TurtleUpgradeType type, IItemProvider item )
{
this( id, legacyId, type, "upgrade." + id + ".adjective", stack );
}
protected AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, Item item )
{
this( id, legacyId, type, new ItemStack( item ) );
}
protected AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, Block block )
{
this( id, legacyId, type, new ItemStack( block ) );
this( id, type, new ItemStack( item ) );
}
@Nonnull
@@ -68,12 +56,6 @@ public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade
return id;
}
@Override
public final int getLegacyUpgradeID()
{
return legacyId;
}
@Nonnull
@Override
public final String getUnlocalisedAdjective()

View File

@@ -17,49 +17,29 @@ import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.api.permissions.ITurtlePermissionProvider;
import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.reflect.Method;
/**
* 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 static boolean isInstalled()
{
findCC();
return computerCraft != null;
}
@Nonnull
public static String getInstalledVersion()
{
findCC();
if( computerCraft_getVersion != null )
{
try
{
return (String) computerCraft_getVersion.invoke( null );
}
catch( Exception e )
{
// It failed
}
}
return "";
return getInstance().getInstalledVersion();
}
@Nonnull
@@ -83,19 +63,7 @@ public final class ComputerCraftAPI
*/
public static int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath )
{
findCC();
if( computerCraft_createUniqueNumberedSaveDir != null )
{
try
{
return (Integer) computerCraft_createUniqueNumberedSaveDir.invoke( null, world, parentSubPath );
}
catch( Exception e )
{
// It failed
}
}
return -1;
return getInstance().createUniqueNumberedSaveDir( world, parentSubPath );
}
/**
@@ -119,55 +87,54 @@ public final class ComputerCraftAPI
@Nullable
public static IWritableMount createSaveDirMount( @Nonnull World world, @Nonnull String subPath, long capacity )
{
findCC();
if( computerCraft_createSaveDirMount != null )
{
try
{
return (IWritableMount) computerCraft_createSaveDirMount.invoke( null, world, subPath, capacity );
}
catch( Exception e )
{
// It failed
}
}
return null;
return getInstance().createSaveDirMount( world, subPath, capacity );
}
/**
* Creates a file system mount to a resource folder, and returns it.
*
* Use in conjunction with IComputerAccess.mount() or IComputerAccess.mountWritable() to mount a resource folder
* onto a computer's file system.
* Use in conjunction with {@link IComputerAccess#mount} or {@link IComputerAccess#mountWritable} to mount a
* resource folder onto a computer's file system.
*
* The files in this mount will be a combination of files in the specified mod jar, and resource packs that contain
* The files in this mount will be a combination of files in all mod jar, and data packs that contain
* resources with the same domain and path.
*
* @param modClass A class in whose jar to look first for the resources to mount. Using your main mod class is recommended. eg: MyMod.class
* @param domain The domain under which to look for resources. eg: "mymod".
* @param subPath The domain under which to look for resources. eg: "mymod/lua/myfiles".
* @return The mount, or {@code null} if it could be created for some reason. Use IComputerAccess.mount() or
* IComputerAccess.mountWritable() to mount this on a Computers' file system.
* @param domain The domain under which to look for resources. eg: "mymod".
* @param subPath The subPath under which to look for resources. eg: "lua/myfiles".
* @return The mount, or {@code null} if it could be created for some reason.
* @see IComputerAccess#mount(String, IMount)
* @see IComputerAccess#mountWritable(String, IWritableMount)
* @see IMount
*/
@Nullable
public static IMount createResourceMount( @Nonnull Class<?> modClass, @Nonnull String domain, @Nonnull String subPath )
public static IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
{
findCC();
if( computerCraft_createResourceMount != null )
{
try
{
return (IMount) computerCraft_createResourceMount.invoke( null, modClass, domain, subPath );
}
catch( Exception e )
{
// It failed
}
}
return null;
return getInstance().createResourceMount( domain, subPath );
}
/**
* Creates a file system mount to a resource folder, and returns it.
*
* Use in conjunction with {@link IComputerAccess#mount} or {@link IComputerAccess#mountWritable} to mount a
* resource folder onto a computer's file system.
*
* The files in this mount will be a combination of files in all mod jar, and data packs that contain
* resources with the same domain and path.
*
* @param klass The mod class to which the files belong.
* @param domain The domain under which to look for resources. eg: "mymod".
* @param subPath The subPath under which to look for resources. eg: "lua/myfiles".
* @return The mount, or {@code null} if it could be created for some reason.
* @see IComputerAccess#mount(String, IMount)
* @see IComputerAccess#mountWritable(String, IWritableMount)
* @see IMount
* @deprecated Use {@link #createResourceMount(String, String)} instead.
*/
@Nullable
@Deprecated
public static IMount createResourceMount( Class<?> klass, @Nonnull String domain, @Nonnull String subPath )
{
return getInstance().createResourceMount( domain, subPath );
}
/**
@@ -179,18 +146,7 @@ public final class ComputerCraftAPI
*/
public static void registerPeripheralProvider( @Nonnull IPeripheralProvider provider )
{
findCC();
if( computerCraft_registerPeripheralProvider != null )
{
try
{
computerCraft_registerPeripheralProvider.invoke( null, provider );
}
catch( Exception e )
{
// It failed
}
}
getInstance().registerPeripheralProvider( provider );
}
/**
@@ -203,21 +159,7 @@ public final class ComputerCraftAPI
*/
public static void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade )
{
if( upgrade != null )
{
findCC();
if( computerCraft_registerTurtleUpgrade != null )
{
try
{
computerCraft_registerTurtleUpgrade.invoke( null, upgrade );
}
catch( Exception e )
{
// It failed
}
}
}
getInstance().registerTurtleUpgrade( upgrade );
}
/**
@@ -228,18 +170,7 @@ public final class ComputerCraftAPI
*/
public static void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider )
{
findCC();
if( computerCraft_registerBundledRedstoneProvider != null )
{
try
{
computerCraft_registerBundledRedstoneProvider.invoke( null, provider );
}
catch( Exception e )
{
// It failed
}
}
getInstance().registerBundledRedstoneProvider( provider );
}
/**
@@ -252,83 +183,25 @@ public final class ComputerCraftAPI
* If there is no block capable of emitting bundled redstone at the location, -1 will be returned.
* @see IBundledRedstoneProvider
*/
public static int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side )
public static int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
findCC();
if( computerCraft_getDefaultBundledRedstoneOutput != null )
{
try
{
return (Integer) computerCraft_getDefaultBundledRedstoneOutput.invoke( null, world, pos, side );
}
catch( Exception e )
{
// It failed
}
}
return -1;
return getInstance().getBundledRedstoneOutput( world, pos, side );
}
/**
* 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.
* @see IMediaProvider
*/
public static void registerMediaProvider( @Nonnull IMediaProvider provider )
{
findCC();
if( computerCraft_registerMediaProvider != null )
{
try
{
computerCraft_registerMediaProvider.invoke( null, provider );
}
catch( Exception e )
{
// It failed
}
}
}
/**
* Registers a permission provider to restrict where turtles can move or build.
*
* @param provider The turtle permission provider to register.
* @see ITurtlePermissionProvider
* @deprecated Prefer using {@link dan200.computercraft.api.turtle.event.TurtleBlockEvent} or the standard Forge events.
*/
@Deprecated
public static void registerPermissionProvider( @Nonnull ITurtlePermissionProvider provider )
{
findCC();
if( computerCraft_registerPermissionProvider != null )
{
try
{
computerCraft_registerPermissionProvider.invoke( null, provider );
}
catch( Exception e )
{
// It failed
}
}
getInstance().registerMediaProvider( provider );
}
public static void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade )
{
findCC();
if( computerCraft_registerPocketUpgrade != null )
{
try
{
computerCraft_registerPocketUpgrade.invoke( null, upgrade );
}
catch( Exception e )
{
// It failed
}
}
getInstance().registerPocketUpgrade( upgrade );
}
/**
@@ -338,40 +211,16 @@ public final class ComputerCraftAPI
*/
public static IPacketNetwork getWirelessNetwork()
{
findCC();
if( computerCraft_getWirelessNetwork != null )
{
try
{
return (IPacketNetwork) computerCraft_getWirelessNetwork.invoke( null );
}
catch( Exception e )
{
// It failed;
}
}
return null;
return getInstance().getWirelessNetwork();
}
public static void registerAPIFactory( @Nonnull ILuaAPIFactory upgrade )
public static void registerAPIFactory( @Nonnull ILuaAPIFactory factory )
{
findCC();
if( computerCraft_registerAPIFactory != null )
{
try
{
computerCraft_registerAPIFactory.invoke( null, upgrade );
}
catch( Exception e )
{
// It failed
}
}
getInstance().registerAPIFactory( factory );
}
/**
* 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
* @return The element's node
@@ -380,26 +229,11 @@ public final class ComputerCraftAPI
@Nonnull
public static IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element )
{
findCC();
if( computerCraft_createWiredNodeForElement != null )
{
try
{
return (IWiredNode) computerCraft_createWiredNodeForElement.invoke( null, element );
}
catch( ReflectiveOperationException e )
{
throw new IllegalStateException( "Error creating wired node", e );
}
}
else
{
throw new IllegalStateException( "ComputerCraft cannot be found" );
}
return getInstance().createWiredNodeForElement( element );
}
/**
* 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 pos The position the block exists in
@@ -407,118 +241,64 @@ public final class ComputerCraftAPI
* @return The element's node
* @see IWiredElement#getNode()
*/
@Nullable
public static IWiredElement getWiredElementAt( @Nonnull IBlockAccess world, @Nonnull BlockPos pos, @Nonnull EnumFacing side )
@Nonnull
public static LazyOptional<IWiredElement> getWiredElementAt( @Nonnull IBlockReader world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
findCC();
if( computerCraft_getWiredElementAt != null )
{
try
{
return (IWiredElement) computerCraft_getWiredElementAt.invoke( null, world, pos, side );
}
catch( ReflectiveOperationException ignored )
{
}
}
return null;
return getInstance().getWiredElementAt( world, pos, side );
}
// The functions below here are private, and are used to interface with the non-API ComputerCraft classes.
// Reflection is used here so you can develop your mod without decompiling ComputerCraft and including
// it in your solution, and so your mod won't crash if ComputerCraft is installed.
private static IComputerCraftAPI instance;
private static void findCC()
@Nonnull
private static IComputerCraftAPI getInstance()
{
if( !ccSearched )
{
try
{
computerCraft = Class.forName( "dan200.computercraft.ComputerCraft" );
computerCraft_getVersion = findCCMethod( "getVersion", new Class<?>[] {
} );
computerCraft_createUniqueNumberedSaveDir = findCCMethod( "createUniqueNumberedSaveDir", new Class<?>[] {
World.class, String.class,
} );
computerCraft_createSaveDirMount = findCCMethod( "createSaveDirMount", new Class<?>[] {
World.class, String.class, Long.TYPE,
} );
computerCraft_createResourceMount = findCCMethod( "createResourceMount", new Class<?>[] {
Class.class, String.class, String.class,
} );
computerCraft_registerPeripheralProvider = findCCMethod( "registerPeripheralProvider", new Class<?>[] {
IPeripheralProvider.class,
} );
computerCraft_registerTurtleUpgrade = findCCMethod( "registerTurtleUpgrade", new Class<?>[] {
ITurtleUpgrade.class,
} );
computerCraft_registerBundledRedstoneProvider = findCCMethod( "registerBundledRedstoneProvider", new Class<?>[] {
IBundledRedstoneProvider.class,
} );
computerCraft_getDefaultBundledRedstoneOutput = findCCMethod( "getDefaultBundledRedstoneOutput", new Class<?>[] {
World.class, BlockPos.class, EnumFacing.class,
} );
computerCraft_registerMediaProvider = findCCMethod( "registerMediaProvider", new Class<?>[] {
IMediaProvider.class,
} );
computerCraft_registerPermissionProvider = findCCMethod( "registerPermissionProvider", new Class<?>[] {
ITurtlePermissionProvider.class,
} );
computerCraft_registerPocketUpgrade = findCCMethod( "registerPocketUpgrade", new Class<?>[] {
IPocketUpgrade.class,
} );
computerCraft_getWirelessNetwork = findCCMethod( "getWirelessNetwork", new Class<?>[] {
} );
computerCraft_registerAPIFactory = findCCMethod( "registerAPIFactory", new Class<?>[] {
ILuaAPIFactory.class,
} );
computerCraft_createWiredNodeForElement = findCCMethod( "createWiredNodeForElement", new Class<?>[] {
IWiredElement.class,
} );
computerCraft_getWiredElementAt = findCCMethod( "getWiredElementAt", new Class<?>[] {
IBlockAccess.class, BlockPos.class, EnumFacing.class,
} );
}
catch( Exception e )
{
System.err.println( "ComputerCraftAPI: ComputerCraft not found." );
}
finally
{
ccSearched = true;
}
}
}
if( instance != null ) return instance;
private static Method findCCMethod( String name, Class<?>[] args )
{
try
{
return computerCraft != null ? computerCraft.getMethod( name, args ) : null;
return instance = (IComputerCraftAPI) Class.forName( "dan200.computercraft.ComputerCraftAPIImpl" )
.getField( "INSTANCE" ).get( null );
}
catch( NoSuchMethodException e )
catch( ReflectiveOperationException e )
{
System.err.println( "ComputerCraftAPI: ComputerCraft method " + name + " not found." );
return null;
throw new IllegalStateException( "Cannot find ComputerCraft API", e );
}
}
private static boolean ccSearched = false;
private static Class<?> computerCraft = null;
private static Method computerCraft_getVersion = null;
private static Method computerCraft_createUniqueNumberedSaveDir = null;
private static Method computerCraft_createSaveDirMount = null;
private static Method computerCraft_createResourceMount = null;
private static Method computerCraft_registerPeripheralProvider = null;
private static Method computerCraft_registerTurtleUpgrade = null;
private static Method computerCraft_registerBundledRedstoneProvider = null;
private static Method computerCraft_getDefaultBundledRedstoneOutput = null;
private static Method computerCraft_registerMediaProvider = null;
private static Method computerCraft_registerPermissionProvider = null;
private static Method computerCraft_registerPocketUpgrade = null;
private static Method computerCraft_getWirelessNetwork = null;
private static Method computerCraft_registerAPIFactory = null;
private static Method computerCraft_createWiredNodeForElement = null;
private static Method computerCraft_getWiredElementAt = null;
public interface IComputerCraftAPI
{
@Nonnull
String getInstalledVersion();
int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath );
@Nullable
IWritableMount createSaveDirMount( @Nonnull World world, @Nonnull String subPath, long capacity );
@Nullable
IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath );
void registerPeripheralProvider( @Nonnull IPeripheralProvider provider );
void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade );
void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider );
int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side );
void registerMediaProvider( @Nonnull IMediaProvider provider );
void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade );
@Nonnull
IPacketNetwork getWirelessNetwork();
void registerAPIFactory( @Nonnull ILuaAPIFactory factory );
@Nonnull
IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element );
@Nonnull
LazyOptional<IWiredElement> getWiredElementAt( @Nonnull IBlockReader world, @Nonnull BlockPos pos, @Nonnull Direction side );
}
}

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
* {@link IComputerAccess#mount(String, IMount)}.
* {@link IComputerAccess#mount(String, IMount)}
*
* Ready made implementations of this interface can be created using
* {@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;
/**
* 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".
* @return The size of the file, in bytes.

View File

@@ -1,10 +0,0 @@
/*
* 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.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|FileSystem", apiVersion = "${version}" )
package dan200.computercraft.api.filesystem;
import net.minecraftforge.fml.common.API;

View File

@@ -1,335 +0,0 @@
/*
* 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();
/**
* 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.
*/

View File

@@ -1,10 +0,0 @@
/*
* 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.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Lua", apiVersion = "${version}" )
package dan200.computercraft.api.lua;
import net.minecraftforge.fml.common.API;

View File

@@ -1,10 +0,0 @@
/*
* 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.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Media", apiVersion = "${version}" )
package dan200.computercraft.api.media;
import net.minecraftforge.fml.common.API;

View File

@@ -1,10 +0,0 @@
/*
* 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.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Network", apiVersion = "${version}" )
package dan200.computercraft.api.network;
import net.minecraftforge.fml.common.API;

View File

@@ -1,10 +0,0 @@
/*
* 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.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Network|Wired", apiVersion = "${version}" )
package dan200.computercraft.api.network.wired;
import net.minecraftforge.fml.common.API;

View File

@@ -1,10 +0,0 @@
/*
* 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.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API", apiVersion = "${version}" )
package dan200.computercraft.api;
import net.minecraftforge.fml.common.API;

View File

@@ -6,7 +6,6 @@
package dan200.computercraft.api.peripheral;
import dan200.computercraft.api.lua.ArgumentHelper;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
@@ -59,11 +58,9 @@ public interface IPeripheral
* 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>
* 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,
* Strings, Booleans, Maps, ILuaObject and null be converted to their corresponding lua type. All other types will
* be converted to nil.
* Strings, Booleans, Maps and ILuaObject and null be converted to their corresponding lua type. All other types
* will be converted to nil.
*
* 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
@@ -73,7 +70,6 @@ public interface IPeripheral
* 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.
* @see #getMethodNames
* @see ArgumentHelper
*/
@Nullable
Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException;

View File

@@ -7,7 +7,7 @@
package dan200.computercraft.api.peripheral;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -34,5 +34,5 @@ public interface IPeripheralProvider
* @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider)
*/
@Nullable
IPeripheral getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side );
IPeripheral getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side );
}

View File

@@ -5,7 +5,7 @@
*/
package dan200.computercraft.api.peripheral;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -25,8 +25,8 @@ public interface IPeripheralTile
*
* @param side The side to get the peripheral from.
* @return A peripheral, or {@code null} if there is not a peripheral here.
* @see IPeripheralProvider#getPeripheral(World, BlockPos, EnumFacing)
* @see IPeripheralProvider#getPeripheral(World, BlockPos, Direction)
*/
@Nullable
IPeripheral getPeripheral( @Nonnull EnumFacing side );
IPeripheral getPeripheral( @Nonnull Direction side );
}

View File

@@ -1,10 +0,0 @@
/*
* 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.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Peripheral", apiVersion = "${version}" )
package dan200.computercraft.api.peripheral;
import net.minecraftforge.fml.common.API;

View File

@@ -1,42 +0,0 @@
/*
* 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.permissions;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
/**
* This interface is used to restrict where turtles can move or build.
*
* Turtles will call these methods before attempting to perform an action, allowing them to be cancelled.
*
* @see dan200.computercraft.api.ComputerCraftAPI#registerPermissionProvider(ITurtlePermissionProvider)
*/
public interface ITurtlePermissionProvider
{
/**
* Determine whether a block can be entered by a turtle.
*
* @param world The world the block exists in
* @param pos The location of the block.
* @return Whether the turtle can move into this block.
*/
boolean isBlockEnterable( @Nonnull World world, @Nonnull BlockPos pos );
/**
* Determine whether a block can be modified by a turtle.
*
* This includes breaking and placing blocks.
*
* @param world The world the block exists in
* @param pos The location of the block.
* @return Whether the turtle can modify this block.
*/
boolean isBlockEditable( @Nonnull World world, @Nonnull BlockPos pos );
}

View File

@@ -1,10 +0,0 @@
/*
* 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.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Permissions", apiVersion = "${version}" )
package dan200.computercraft.api.permissions;
import net.minecraftforge.fml.common.API;

View File

@@ -6,7 +6,9 @@
package dan200.computercraft.api.pocket;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IItemProvider;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Util;
import javax.annotation.Nonnull;
@@ -28,9 +30,14 @@ public abstract class AbstractPocketUpgrade implements IPocketUpgrade
this.stack = stack;
}
protected AbstractPocketUpgrade( ResourceLocation id, ItemStack stack )
protected AbstractPocketUpgrade( ResourceLocation id, String adjective, IItemProvider item )
{
this( id, "upgrade." + id + ".adjective", stack );
this( id, adjective, new ItemStack( item ) );
}
protected AbstractPocketUpgrade( ResourceLocation id, IItemProvider item )
{
this( id, Util.makeTranslationKey( "upgrade", id ) + ".adjective", new ItemStack( item ) );
}
@Nonnull

View File

@@ -8,7 +8,7 @@ package dan200.computercraft.api.pocket;
import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.ResourceLocation;
import javax.annotation.Nonnull;
@@ -16,29 +16,19 @@ import javax.annotation.Nullable;
import java.util.Map;
/**
* Wrapper class for pocket computers.
* Wrapper class for pocket computers
*/
public interface IPocketAccess
{
/**
* Gets the entity holding this item.
*
* @return The holding entity. This may be {@code null}.
* @deprecated Use {@link #getValidEntity()} where possible.
*/
@Nullable
@Deprecated
Entity getEntity();
/**
* Gets the entity holding this item with additional safety checks.
*
* This must be called on the server thread.
*
* @return The holding entity, or {@code null} if none exists.
*/
@Nullable
Entity getValidEntity();
Entity getEntity();
/**
* Get the colour of this pocket computer as a RGB number.
@@ -85,7 +75,7 @@ public interface IPocketAccess
* @see #updateUpgradeNBTData()
*/
@Nonnull
NBTTagCompound getUpgradeNBTData();
CompoundNBT getUpgradeNBTData();
/**
* Mark the upgrade-specific NBT as dirty.

View File

@@ -6,7 +6,7 @@
package dan200.computercraft.api.redstone;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -30,5 +30,5 @@ public interface IBundledRedstoneProvider
* handle this block.
* @see dan200.computercraft.api.ComputerCraftAPI#registerBundledRedstoneProvider(IBundledRedstoneProvider)
*/
int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side );
int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side );
}

View File

@@ -1,10 +0,0 @@
/*
* 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.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Redstone", apiVersion = "${version}" )
package dan200.computercraft.api.redstone;
import net.minecraftforge.fml.common.API;

View File

@@ -11,8 +11,8 @@ import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.inventory.IInventory;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
@@ -54,8 +54,7 @@ public interface ITurtleAccess
* @param world The new world to move it to
* @param pos The new position to move it to.
* @return Whether the movement was successful. It may fail if the block was not loaded or the block placement
* was cancelled. Note this will not check
* {@link dan200.computercraft.api.permissions.ITurtlePermissionProvider#isBlockEnterable(World, BlockPos)}.
* was cancelled.
* @throws UnsupportedOperationException When attempting to teleport on the client side.
*/
boolean teleportTo( @Nonnull World world, @Nonnull BlockPos pos );
@@ -84,10 +83,10 @@ public interface ITurtleAccess
* Returns the world direction the turtle is currently facing.
*
* @return The world direction the turtle is currently facing.
* @see #setDirection(EnumFacing)
* @see #setDirection(Direction)
*/
@Nonnull
EnumFacing getDirection();
Direction getDirection();
/**
* Set the direction the turtle is facing. Note that this will not play a rotation animation, you will also need to
@@ -96,7 +95,7 @@ public interface ITurtleAccess
* @param dir The new direction to set. This should be on either the x or z axis (so north, south, east or west).
* @see #getDirection()
*/
void setDirection( @Nonnull EnumFacing dir );
void setDirection( @Nonnull Direction dir );
/**
* Get the currently selected slot in the turtle's inventory.
@@ -295,7 +294,7 @@ public interface ITurtleAccess
* @see #updateUpgradeNBTData(TurtleSide)
*/
@Nonnull
NBTTagCompound getUpgradeNBTData( @Nullable TurtleSide side );
CompoundNBT getUpgradeNBTData( @Nullable TurtleSide side );
/**
* Mark the upgrade-specific data as dirty on a specific side. This is required for the data to be synced to the

View File

@@ -10,15 +10,15 @@ import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.turtle.event.TurtleAttackEvent;
import dan200.computercraft.api.turtle.event.TurtleBlockEvent;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.ModelResourceLocation;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.event.entity.player.AttackEntityEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nonnull;
@@ -44,17 +44,6 @@ public interface ITurtleUpgrade
@Nonnull
ResourceLocation getUpgradeID();
/**
* Gets a numerical identifier representing this type of turtle upgrade,
* for backwards compatibility with pre-1.76 worlds. If your upgrade was
* not released for older ComputerCraft versions, you can return -1 here.
* The turtle will fail registration if an already used positive ID is specified.
*
* @return The legacy ID, or -1 if is needed.
* @see ComputerCraftAPI#registerTurtleUpgrade(ITurtleUpgrade)
*/
int getLegacyUpgradeID();
/**
* Return an unlocalised string to describe this type of turtle in turtle item names.
*
@@ -124,7 +113,7 @@ public interface ITurtleUpgrade
* to be called.
*/
@Nonnull
default TurtleCommandResult useTool( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull EnumFacing direction )
default TurtleCommandResult useTool( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction direction )
{
return TurtleCommandResult.failure();
}
@@ -133,7 +122,7 @@ public interface ITurtleUpgrade
* Called to obtain the model to be used when rendering a turtle peripheral.
*
* This can be obtained from {@link net.minecraft.client.renderer.ItemModelMesher#getItemModel(ItemStack)},
* {@link net.minecraft.client.renderer.block.model.ModelManager#getModel(ModelResourceLocation)} or any other
* {@link net.minecraft.client.renderer.model.ModelManager#getModel(ModelResourceLocation)} or any other
* source.
*
* @param turtle Access to the turtle that the upgrade resides on. This will be null when getting item models!
@@ -142,7 +131,7 @@ public interface ITurtleUpgrade
* a transformation of {@code null} has the same effect as the identify matrix.
*/
@Nonnull
@SideOnly( Side.CLIENT )
@OnlyIn( Dist.CLIENT )
Pair<IBakedModel, Matrix4f> getModel( @Nullable ITurtleAccess turtle, @Nonnull TurtleSide side );
/**

View File

@@ -6,7 +6,7 @@
package dan200.computercraft.api.turtle;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -15,7 +15,7 @@ import javax.annotation.Nullable;
* Used to indicate the result of executing a turtle command.
*
* @see ITurtleCommand#execute(ITurtleAccess)
* @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, EnumFacing)
* @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction)
*/
public final class TurtleCommandResult
{

View File

@@ -12,12 +12,12 @@ package dan200.computercraft.api.turtle;
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,
/**
* 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,
}

View File

@@ -6,24 +6,24 @@
package dan200.computercraft.api.turtle;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
/**
* An enum representing the different actions that an {@link ITurtleUpgrade} of type Tool may be called on to perform by
* a turtle.
*
* @see ITurtleUpgrade#getType()
* @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, EnumFacing)
* @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction)
*/
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,
/**
* 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,
}

View File

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

View File

@@ -8,7 +8,7 @@ package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.TurtleCommandResult;
import net.minecraftforge.fml.common.eventhandler.Cancelable;
import net.minecraftforge.eventbus.api.Cancelable;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

View File

@@ -11,7 +11,7 @@ import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.api.turtle.TurtleVerb;
import net.minecraft.entity.Entity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.event.entity.player.AttackEntityEvent;
@@ -21,7 +21,7 @@ import java.util.Objects;
/**
* Fired when a turtle attempts to attack an entity.
*
* This must be fired by {@link ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, EnumFacing)},
* This must be fired by {@link ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction)},
* as the base {@code turtle.attack()} command does not fire it.
*
* Note that such commands should also fire {@link AttackEntityEvent}, so you do not need to listen to both.

View File

@@ -12,9 +12,9 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.api.turtle.TurtleVerb;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.util.FakePlayer;
@@ -75,7 +75,7 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
/**
* Fired when a turtle attempts to dig a block.
*
* This must be fired by {@link ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, EnumFacing)},
* This must be fired by {@link ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction)},
* as the base {@code turtle.dig()} command does not fire it.
*
* Note that such commands should also fire {@link BlockEvent.BreakEvent}, so you do not need to listen to both.
@@ -84,11 +84,11 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
*/
public static class Dig extends TurtleBlockEvent
{
private final IBlockState block;
private final BlockState block;
private final ITurtleUpgrade upgrade;
private final TurtleSide side;
public Dig( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull IBlockState block, @Nonnull ITurtleUpgrade upgrade, @Nonnull TurtleSide side )
public Dig( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState block, @Nonnull ITurtleUpgrade upgrade, @Nonnull TurtleSide side )
{
super( turtle, TurtleAction.DIG, player, world, pos );
@@ -106,13 +106,13 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
* @return The block which is going to be broken.
*/
@Nonnull
public IBlockState getBlock()
public BlockState getBlock()
{
return block;
}
/**
* Get the upgrade doing the digging.
* Get the upgrade doing the digging
*
* @return The upgrade doing the digging.
*/
@@ -185,10 +185,10 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
*/
public static class Inspect extends TurtleBlockEvent
{
private final IBlockState state;
private final BlockState state;
private final Map<String, Object> data;
public Inspect( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull IBlockState state, @Nonnull Map<String, Object> data )
public Inspect( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nonnull Map<String, Object> data )
{
super( turtle, TurtleAction.INSPECT, player, world, pos );
@@ -204,7 +204,7 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
* @return The inspected block state.
*/
@Nonnull
public IBlockState getState()
public BlockState getState()
{
return state;
}

View File

@@ -7,7 +7,7 @@
package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.turtle.ITurtleAccess;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraftforge.eventbus.api.Event;
import javax.annotation.Nonnull;
import java.util.Objects;

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.
*/

View File

@@ -1,10 +0,0 @@
/*
* 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.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Turtle|Event", apiVersion = "${version}" )
package dan200.computercraft.api.turtle.event;
import net.minecraftforge.fml.common.API;

View File

@@ -1,10 +0,0 @@
/*
* 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.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Turtle", apiVersion = "${version}" )
package dan200.computercraft.api.turtle;
import net.minecraftforge.fml.common.API;

View File

@@ -8,178 +8,161 @@ package dan200.computercraft.client;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.render.TurtleModelLoader;
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
import dan200.computercraft.shared.common.IColouredItem;
import dan200.computercraft.shared.media.items.ItemDisk;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.turtle.items.ItemTurtleBase;
import dan200.computercraft.shared.util.Colour;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ModelBakery;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.IUnbakedModel;
import net.minecraft.client.renderer.model.ModelResourceLocation;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.ColorHandlerEvent;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.BasicState;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Map;
/**
* Registers textures and models for items.
*/
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD )
public final class ClientRegistry
{
private static final String[] EXTRA_MODELS = new String[] {
"turtle_modem_off_left",
"turtle_modem_on_left",
"turtle_modem_off_right",
"turtle_modem_on_right",
"turtle_modem_normal_off_left",
"turtle_modem_normal_on_left",
"turtle_modem_normal_off_right",
"turtle_modem_normal_on_right",
"turtle_modem_advanced_off_left",
"turtle_modem_advanced_on_left",
"turtle_modem_advanced_off_right",
"turtle_modem_advanced_on_right",
"turtle_crafting_table_left",
"turtle_crafting_table_right",
"advanced_turtle_modem_off_left",
"advanced_turtle_modem_on_left",
"advanced_turtle_modem_off_right",
"advanced_turtle_modem_on_right",
"turtle_speaker_upgrade_left",
"turtle_speaker_upgrade_right",
"turtle_white",
"turtle_colour",
"turtle_elf_overlay",
};
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
// model loading code.
"block/turtle_colour",
"block/turtle_elf_overlay",
"block/turtle_crafty_face",
"block/turtle_speaker_face",
};
private ClientRegistry() {}
@SubscribeEvent
public static void registerModels( ModelRegistryEvent event )
{
ModelLoaderRegistry.registerLoader( TurtleModelLoader.INSTANCE );
// Register item models
registerUniversalItemModel( ComputerCraft.Items.computer, "computer" );
registerItemModel( ComputerCraft.Items.commandComputer, 0, "command_computer" );
registerItemModel( ComputerCraft.Items.pocketComputer, 0, "pocket_computer" );
registerItemModel( ComputerCraft.Items.pocketComputer, 1, "advanced_pocket_computer" );
registerItemModel( ComputerCraft.Items.peripheral, 0, "peripheral" );
registerItemModel( ComputerCraft.Items.peripheral, 1, "wireless_modem" );
registerItemModel( ComputerCraft.Items.peripheral, 2, "monitor" );
registerItemModel( ComputerCraft.Items.peripheral, 3, "printer" );
registerItemModel( ComputerCraft.Items.peripheral, 4, "advanced_monitor" );
registerItemModel( ComputerCraft.Items.cable, 0, "cable" );
registerItemModel( ComputerCraft.Items.cable, 1, "wired_modem" );
registerItemModel( ComputerCraft.Items.advancedModem, 0, "advanced_modem" );
registerItemModel( ComputerCraft.Items.peripheral, 5, "speaker" );
registerItemModel( ComputerCraft.Items.wiredModemFull, 0, "wired_modem_full" );
registerUniversalItemModel( ComputerCraft.Items.disk, "disk" );
registerItemModel( ComputerCraft.Items.diskExpanded, 0, "disk_expanded" );
registerItemModel( ComputerCraft.Items.treasureDisk, 0, "treasure_disk" );
registerItemModel( ComputerCraft.Items.printout, 0, "printout" );
registerItemModel( ComputerCraft.Items.printout, 1, "pages" );
registerItemModel( ComputerCraft.Items.printout, 2, "book" );
registerUniversalItemModel( ComputerCraft.Items.turtle, "turtle" );
registerUniversalItemModel( ComputerCraft.Items.turtleExpanded, "turtle" );
registerUniversalItemModel( ComputerCraft.Items.turtleAdvanced, "turtle_advanced" );
}
@SubscribeEvent
public static void onTextureStitchEvent( TextureStitchEvent.Pre event )
{
// Load all textures for the extra models
TextureMap map = event.getMap();
for( String upgrade : EXTRA_MODELS )
/*
IResourceManager manager = Minecraft.getInstance().getResourceManager();
for( String extra : EXTRA_TEXTURES )
{
IModel model = ModelLoaderRegistry.getModelOrMissing( new ResourceLocation( "computercraft", "block/" + upgrade ) );
for( ResourceLocation texture : model.getTextures() ) map.registerSprite( texture );
// TODO: event.getMap().registerSprite( manager, new ResourceLocation( ComputerCraft.MOD_ID, extra ) );
}
*/
}
@SubscribeEvent
public static void onModelBakeEvent( ModelBakeEvent event )
{
// Load all extra models
for( String model : EXTRA_MODELS ) loadBlockModel( event, model );
ModelLoader loader = event.getModelLoader();
Map<ResourceLocation, IBakedModel> registry = event.getModelRegistry();
for( String model : EXTRA_MODELS )
{
IBakedModel bakedModel = bake( loader, loader.getUnbakedModel( new ResourceLocation( ComputerCraft.MOD_ID, "item/" + model ) ) );
if( bakedModel != null )
{
registry.put(
new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, model ), "inventory" ),
bakedModel
);
}
}
// And load the custom turtle models in too.
registry.put(
new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_normal" ), "inventory" ),
bake( loader, TurtleModelLoader.INSTANCE.loadModel( new ResourceLocation( ComputerCraft.MOD_ID, "item/turtle_normal" ) ) )
);
registry.put(
new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_advanced" ), "inventory" ),
bake( loader, TurtleModelLoader.INSTANCE.loadModel( new ResourceLocation( ComputerCraft.MOD_ID, "item/turtle_advanced" ) ) )
);
}
@SubscribeEvent
public static void onItemColours( ColorHandlerEvent.Item event )
{
event.getItemColors().registerItemColorHandler(
( stack, layer ) -> layer == 1 ? ((ItemDiskLegacy) stack.getItem()).getColour( stack ) : 0xFFFFFF,
ComputerCraft.Items.disk, ComputerCraft.Items.diskExpanded
if( ComputerCraft.Items.disk == null || ComputerCraft.Blocks.turtleNormal == null )
{
ComputerCraft.log.warn( "Block/item registration has failed. Skipping registration of item colours." );
return;
}
event.getItemColors().register(
( stack, layer ) -> layer == 1 ? ((ItemDisk) stack.getItem()).getColour( stack ) : 0xFFFFFF,
ComputerCraft.Items.disk
);
event.getItemColors().registerItemColorHandler( ( stack, layer ) -> {
event.getItemColors().register( ( stack, layer ) -> {
switch( layer )
{
case 0:
default:
return 0xFFFFFF;
case 1: // Frame colour
return ComputerCraft.Items.pocketComputer.getColour( stack );
return IColouredItem.getColourBasic( stack );
case 2: // Light colour
{
int light = ItemPocketComputer.getLightState( stack );
return light == -1 ? Colour.Black.getHex() : light;
}
}
}, ComputerCraft.Items.pocketComputer );
}, ComputerCraft.Items.pocketComputerNormal, ComputerCraft.Items.pocketComputerAdvanced );
// Setup turtle colours
event.getItemColors().registerItemColorHandler(
( stack, tintIndex ) -> tintIndex == 0 ? ((ItemTurtleBase) stack.getItem()).getColour( stack ) : 0xFFFFFF,
ComputerCraft.Blocks.turtle, ComputerCraft.Blocks.turtleExpanded, ComputerCraft.Blocks.turtleAdvanced
event.getItemColors().register(
( stack, tintIndex ) -> tintIndex == 0 ? ((IColouredItem) stack.getItem()).getColour( stack ) : 0xFFFFFF,
ComputerCraft.Blocks.turtleNormal, ComputerCraft.Blocks.turtleAdvanced
);
}
private static void registerItemModel( Item item, int damage, String name )
private static IBakedModel bake( ModelLoader loader, IUnbakedModel model )
{
ResourceLocation location = new ResourceLocation( ComputerCraft.MOD_ID, name );
final ModelResourceLocation res = new ModelResourceLocation( location, "inventory" );
ModelBakery.registerItemVariants( item, location );
ModelLoader.setCustomModelResourceLocation( item, damage, res );
}
model.getTextures( loader::getUnbakedModel, new HashSet<>() );
private static void registerUniversalItemModel( Item item, String mainModel )
{
ResourceLocation mainLocation = new ResourceLocation( ComputerCraft.MOD_ID, mainModel );
ModelBakery.registerItemVariants( item, mainLocation );
final ModelResourceLocation mainModelLocation = new ModelResourceLocation( mainLocation, "inventory" );
ModelLoader.setCustomMeshDefinition( item, new ItemMeshDefinition()
{
@Nonnull
@Override
public ModelResourceLocation getModelLocation( @Nonnull ItemStack stack )
{
return mainModelLocation;
}
} );
}
private static void loadBlockModel( ModelBakeEvent event, String name )
{
IModel model = ModelLoaderRegistry.getModelOrMissing( new ResourceLocation( ComputerCraft.MOD_ID, "block/" + name ) );
IBakedModel bakedModel = model.bake(
model.getDefaultState(), DefaultVertexFormats.ITEM,
location -> Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( location.toString() )
return model.bake(
loader,
ModelLoader.defaultTextureGetter(),
new BasicState( model.getDefaultState(), false ), DefaultVertexFormats.BLOCK
);
event.getModelRegistry().putObject( new ModelResourceLocation( ComputerCraft.MOD_ID + ":" + name, "inventory" ), bakedModel );
}
}

View File

@@ -12,8 +12,8 @@ import dan200.computercraft.shared.command.text.TableFormatter;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiNewChat;
import net.minecraft.client.gui.GuiUtilRenderComponents;
import net.minecraft.client.gui.NewChatGui;
import net.minecraft.client.gui.RenderComponentsUtil;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting;
@@ -30,7 +30,7 @@ public class ClientTableFormatter implements TableFormatter
private static FontRenderer renderer()
{
return Minecraft.getMinecraft().fontRenderer;
return Minecraft.getInstance().fontRenderer;
}
@Override
@@ -42,7 +42,7 @@ public class ClientTableFormatter implements TableFormatter
FontRenderer renderer = renderer();
float spaceWidth = renderer.getCharWidth( ' ' );
float spaceWidth = renderer.getStringWidth( " " );
int spaces = MathHelper.floor( extraWidth / spaceWidth );
int extra = extraWidth - (int) (spaces * spaceWidth);
@@ -64,19 +64,19 @@ public class ClientTableFormatter implements TableFormatter
@Override
public void writeLine( int id, ITextComponent component )
{
Minecraft mc = Minecraft.getMinecraft();
GuiNewChat chat = mc.ingameGUI.getChatGUI();
Minecraft mc = Minecraft.getInstance();
NewChatGui chat = mc.ingameGUI.getChatGUI();
// Trim the text if it goes over the allowed length
int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getChatScale() );
List<ITextComponent> list = GuiUtilRenderComponents.splitText( component, maxWidth, mc.fontRenderer, false, false );
int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getScale() );
List<ITextComponent> list = RenderComponentsUtil.splitText( component, maxWidth, mc.fontRenderer, false, false );
if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id );
}
@Override
public int display( TableBuilder table )
{
GuiNewChat chat = Minecraft.getMinecraft().ingameGUI.getChatGUI();
NewChatGui chat = Minecraft.getInstance().ingameGUI.getChatGUI();
int lastHeight = lastHeights.get( table.getId() );

View File

@@ -7,12 +7,12 @@
package dan200.computercraft.client;
import dan200.computercraft.ComputerCraft;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.relauncher.Side;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class FrameInfo
{
private static int tick;

View File

@@ -6,11 +6,11 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@@ -39,7 +39,7 @@ public final class FixedWidthFontRenderer
private FixedWidthFontRenderer()
{
m_textureManager = Minecraft.getMinecraft().getTextureManager();
m_textureManager = Minecraft.getInstance().getTextureManager();
}
private static void greyscaleify( double[] rgb )
@@ -129,9 +129,9 @@ public final class FixedWidthFontRenderer
}
drawQuad( renderer, x + i * FONT_WIDTH, y, colour, FONT_WIDTH, p, greyScale );
}
GlStateManager.disableTexture2D();
GlStateManager.disableTexture();
tessellator.draw();
GlStateManager.enableTexture2D();
GlStateManager.enableTexture();
}
public void drawStringTextPart( int x, int y, TextBuffer s, TextBuffer textColour, boolean greyScale, Palette p )
@@ -195,6 +195,6 @@ public final class FixedWidthFontRenderer
public void bindFont()
{
m_textureManager.bindTexture( FONT );
GlStateManager.glTexParameteri( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
GlStateManager.texParameter( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
}
}

View File

@@ -6,25 +6,25 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.client.gui.widgets.WidgetWrapper;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.IComputer;
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.inventory.Container;
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import net.minecraft.util.text.ITextComponent;
import org.lwjgl.glfw.GLFW;
import java.io.IOException;
public class GuiComputer extends GuiContainer
public final class GuiComputer<T extends ContainerComputerBase> extends ContainerScreen<T>
{
public static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/corners.png" );
public static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/corners_normal.png" );
public static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/corners_advanced.png" );
public static final ResourceLocation BACKGROUND_COMMAND = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/corners_command.png" );
public static final ResourceLocation BACKGROUND_COLOUR = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/corners_colour.png" );
@@ -33,151 +33,154 @@ public class GuiComputer extends GuiContainer
private final ClientComputer m_computer;
private final int m_termWidth;
private final int m_termHeight;
private WidgetTerminal m_terminal;
public GuiComputer( Container container, ComputerFamily family, ClientComputer computer, int termWidth, int termHeight )
private WidgetTerminal terminal;
private WidgetWrapper terminalWrapper;
private GuiComputer(
T container, PlayerInventory player, ITextComponent title, int termWidth, int termHeight
)
{
super( container );
m_family = family;
m_computer = computer;
super( container, player, title );
m_family = container.getFamily();
m_computer = (ClientComputer) container.getComputer();
m_termWidth = termWidth;
m_termHeight = termHeight;
m_terminal = null;
terminal = null;
}
@Deprecated
public GuiComputer( Container container, ComputerFamily family, IComputer computer, int termWidth, int termHeight )
public static GuiComputer<ContainerComputer> create( ContainerComputer container, PlayerInventory inventory, ITextComponent component )
{
this( container, family, (ClientComputer) computer, termWidth, termHeight );
}
public GuiComputer( TileComputer computer )
{
this(
new ContainerComputer( computer ),
computer.getFamily(),
computer.createClientComputer(),
ComputerCraft.terminalWidth_computer,
ComputerCraft.terminalHeight_computer
return new GuiComputer<>(
container, inventory, component,
ComputerCraft.terminalWidth_computer, ComputerCraft.terminalHeight_computer
);
}
@Override
public void initGui()
public static GuiComputer<ContainerPocketComputer> createPocket( ContainerPocketComputer container, PlayerInventory inventory, ITextComponent component )
{
super.initGui();
Keyboard.enableRepeatEvents( true );
return new GuiComputer<>(
container, inventory, component,
ComputerCraft.terminalWidth_pocketComputer, ComputerCraft.terminalHeight_pocketComputer
);
}
m_terminal = new WidgetTerminal( 0, 0, m_termWidth, m_termHeight, () -> m_computer, 2, 2, 2, 2 );
m_terminal.setAllowFocusLoss( false );
xSize = m_terminal.getWidth() + 24;
ySize = m_terminal.getHeight() + 24;
public static GuiComputer<ContainerViewComputer> createView( ContainerViewComputer container, PlayerInventory inventory, ITextComponent component )
{
return new GuiComputer<>(
container, inventory, component,
container.getWidth(), container.getHeight()
);
}
@Override
protected void init()
{
minecraft.keyboardListener.enableRepeatEvents( true );
int termPxWidth = m_termWidth * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = m_termHeight * FixedWidthFontRenderer.FONT_HEIGHT;
xSize = termPxWidth + 4 + 24;
ySize = termPxHeight + 4 + 24;
super.init();
terminal = new WidgetTerminal( minecraft, () -> m_computer, m_termWidth, m_termHeight, 2, 2, 2, 2 );
terminalWrapper = new WidgetWrapper( terminal, 2 + 12 + guiLeft, 2 + 12 + guiTop, termPxWidth, termPxHeight );
children.add( terminalWrapper );
setFocused( terminalWrapper );
}
@Override
public void onGuiClosed()
public void removed()
{
super.onGuiClosed();
Keyboard.enableRepeatEvents( false );
super.removed();
children.remove( terminal );
terminal = null;
minecraft.keyboardListener.enableRepeatEvents( false );
}
@Override
public void updateScreen()
public void tick()
{
super.updateScreen();
m_terminal.update();
super.tick();
terminal.update();
}
@Override
protected void keyTyped( char c, int k ) throws IOException
public boolean keyPressed( int key, int scancode, int modifiers )
{
if( k == 1 )
// Forward the tab key to the terminal, rather than moving between controls.
if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminalWrapper )
{
super.keyTyped( c, k );
}
else
{
if( m_terminal.onKeyTyped( c, k ) ) keyHandled = true;
return getFocused().keyPressed( key, scancode, modifiers );
}
return super.keyPressed( key, scancode, modifiers );
}
@Override
protected void mouseClicked( int x, int y, int button )
{
int startX = (width - m_terminal.getWidth()) / 2;
int startY = (height - m_terminal.getHeight()) / 2;
m_terminal.mouseClicked( x - startX, y - startY, button );
}
@Override
public void handleMouseInput() throws IOException
{
super.handleMouseInput();
int x = Mouse.getEventX() * width / mc.displayWidth;
int y = height - Mouse.getEventY() * height / mc.displayHeight - 1;
int startX = (width - m_terminal.getWidth()) / 2;
int startY = (height - m_terminal.getHeight()) / 2;
m_terminal.handleMouseInput( x - startX, y - startY );
}
@Override
public void handleKeyboardInput() throws IOException
{
super.handleKeyboardInput();
if( m_terminal.onKeyboardInput() ) keyHandled = true;
}
@Override
protected void drawGuiContainerForegroundLayer( int par1, int par2 )
{
}
@Override
protected void drawGuiContainerBackgroundLayer( float var1, int var2, int var3 )
{
}
@Override
public void drawScreen( int mouseX, int mouseY, float partialTicks )
public void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
{
// Work out where to draw
int startX = (width - m_terminal.getWidth()) / 2;
int startY = (height - m_terminal.getHeight()) / 2;
int endX = startX + m_terminal.getWidth();
int endY = startY + m_terminal.getHeight();
// Draw background
drawDefaultBackground();
int startX = terminalWrapper.getX() - 2;
int startY = terminalWrapper.getY() - 2;
int endX = startX + terminalWrapper.getWidth() + 4;
int endY = startY + terminalWrapper.getHeight() + 4;
// Draw terminal
m_terminal.draw( mc, startX, startY, mouseX, mouseY );
terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
// Draw a border around the terminal
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
switch( m_family )
{
case Normal:
default:
mc.getTextureManager().bindTexture( BACKGROUND_NORMAL );
minecraft.getTextureManager().bindTexture( BACKGROUND_NORMAL );
break;
case Advanced:
mc.getTextureManager().bindTexture( BACKGROUND_ADVANCED );
minecraft.getTextureManager().bindTexture( BACKGROUND_ADVANCED );
break;
case Command:
mc.getTextureManager().bindTexture( BACKGROUND_COMMAND );
minecraft.getTextureManager().bindTexture( BACKGROUND_COMMAND );
break;
}
drawTexturedModalRect( startX - 12, startY - 12, 12, 28, 12, 12 );
drawTexturedModalRect( startX - 12, endY, 12, 40, 12, 12 );
drawTexturedModalRect( endX, startY - 12, 24, 28, 12, 12 );
drawTexturedModalRect( endX, endY, 24, 40, 12, 12 );
blit( startX - 12, startY - 12, 12, 28, 12, 12 );
blit( startX - 12, endY, 12, 40, 12, 12 );
blit( endX, startY - 12, 24, 28, 12, 12 );
blit( endX, endY, 24, 40, 12, 12 );
drawTexturedModalRect( startX, startY - 12, 0, 0, endX - startX, 12 );
drawTexturedModalRect( startX, endY, 0, 12, endX - startX, 12 );
blit( startX, startY - 12, 0, 0, endX - startX, 12 );
blit( startX, endY, 0, 12, endX - startX, 12 );
drawTexturedModalRect( startX - 12, startY, 0, 28, 12, endY - startY );
drawTexturedModalRect( endX, startY, 36, 28, 12, endY - startY );
blit( startX - 12, startY, 0, 28, 12, endY - startY );
blit( endX, startY, 36, 28, 12, endY - startY );
}
@Override
public void render( int mouseX, int mouseY, float partialTicks )
{
renderBackground();
super.render( mouseX, mouseY, partialTicks );
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 );
}
@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

@@ -1,50 +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.client.gui;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.Config;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraftforge.fml.client.IModGuiFactory;
import net.minecraftforge.fml.client.config.GuiConfig;
import java.util.Set;
public class GuiConfigCC extends GuiConfig
{
public GuiConfigCC( GuiScreen parentScreen )
{
super( parentScreen, Config.getConfigElements(), ComputerCraft.MOD_ID, false, false, "CC: Tweaked" );
}
public static class Factory implements IModGuiFactory
{
@Override
public void initialize( Minecraft minecraft )
{
}
@Override
public boolean hasConfigGui()
{
return true;
}
@Override
public GuiScreen createConfigGui( GuiScreen parentScreen )
{
return new GuiConfigCC( parentScreen );
}
@Override
public Set<RuntimeOptionCategoryElement> runtimeGuiCategories()
{
return null;
}
}
}

View File

@@ -6,45 +6,43 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
public class GuiDiskDrive extends GuiContainer
public class GuiDiskDrive extends ContainerScreen<ContainerDiskDrive>
{
private static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/diskdrive.png" );
private static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/disk_drive.png" );
private final ContainerDiskDrive m_container;
public GuiDiskDrive( ContainerDiskDrive container )
public GuiDiskDrive( ContainerDiskDrive container, PlayerInventory player, ITextComponent title )
{
super( container );
m_container = container;
super( container, player, title );
}
@Override
protected void drawGuiContainerForegroundLayer( int mouseX, int mouseY )
{
String title = m_container.getDiskDrive().getDisplayName().getUnformattedText();
fontRenderer.drawString( title, (xSize - fontRenderer.getStringWidth( title )) / 2, 6, 0x404040 );
fontRenderer.drawString( I18n.format( "container.inventory" ), 8, ySize - 96 + 2, 0x404040 );
String title = this.title.getFormattedText();
font.drawString( title, (xSize - font.getStringWidth( title )) / 2.0f, 6, 0x404040 );
font.drawString( title, 8, ySize - 96 + 2, 0x404040 );
}
@Override
protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
{
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
mc.getTextureManager().bindTexture( BACKGROUND );
drawTexturedModalRect( guiLeft, guiTop, 0, 0, xSize, ySize );
GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTexture( BACKGROUND );
blit( guiLeft, guiTop, 0, 0, xSize, ySize );
}
@Override
public void drawScreen( int mouseX, int mouseY, float partialTicks )
public void render( int mouseX, int mouseY, float partialTicks )
{
drawDefaultBackground();
super.drawScreen( mouseX, mouseY, partialTicks );
renderBackground();
super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY );
}
}

View File

@@ -1,25 +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.client.gui;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.media.inventory.ContainerHeldItem;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
public class GuiPocketComputer extends GuiComputer
{
public GuiPocketComputer( ContainerHeldItem container )
{
super(
container,
ComputerCraft.Items.pocketComputer.getFamily( container.getStack() ),
ItemPocketComputer.createClientComputer( container.getStack() ),
ComputerCraft.terminalWidth_pocketComputer,
ComputerCraft.terminalHeight_pocketComputer
);
}
}

View File

@@ -6,47 +6,46 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
public class GuiPrinter extends GuiContainer
public class GuiPrinter extends ContainerScreen<ContainerPrinter>
{
private static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/printer.png" );
private final ContainerPrinter container;
public GuiPrinter( ContainerPrinter container )
public GuiPrinter( ContainerPrinter container, PlayerInventory player, ITextComponent title )
{
super( container );
this.container = container;
super( container, player, title );
}
@Override
protected void drawGuiContainerForegroundLayer( int mouseX, int mouseY )
{
String title = container.getPrinter().getDisplayName().getUnformattedText();
fontRenderer.drawString( title, (xSize - fontRenderer.getStringWidth( title )) / 2, 6, 0x404040 );
fontRenderer.drawString( I18n.format( "container.inventory" ), 8, ySize - 96 + 2, 0x404040 );
String title = getTitle().getFormattedText();
font.drawString( title, (xSize - font.getStringWidth( title )) / 2.0f, 6, 0x404040 );
font.drawString( I18n.format( "container.inventory" ), 8, ySize - 96 + 2, 0x404040 );
}
@Override
protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
{
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
mc.getTextureManager().bindTexture( BACKGROUND );
drawTexturedModalRect( guiLeft, guiTop, 0, 0, xSize, ySize );
GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTexture( BACKGROUND );
blit( guiLeft, guiTop, 0, 0, xSize, ySize );
if( container.isPrinting() ) drawTexturedModalRect( guiLeft + 34, guiTop + 21, 176, 0, 25, 45 );
if( getContainer().isPrinting() ) blit( guiLeft + 34, guiTop + 21, 176, 0, 25, 45 );
}
@Override
public void drawScreen( int mouseX, int mouseY, float partialTicks )
public void render( int mouseX, int mouseY, float partialTicks )
{
drawDefaultBackground();
super.drawScreen( mouseX, mouseY, partialTicks );
renderBackground();
super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY );
}
}

View File

@@ -6,18 +6,18 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.media.inventory.ContainerHeldItem;
import dan200.computercraft.shared.common.ContainerHeldItem;
import dan200.computercraft.shared.media.items.ItemPrintout;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import org.lwjgl.input.Mouse;
import java.io.IOException;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.text.ITextComponent;
import org.lwjgl.glfw.GLFW;
import static dan200.computercraft.client.render.PrintoutRenderer.*;
public class GuiPrintout extends GuiContainer
public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
{
private final boolean m_book;
private final int m_pages;
@@ -25,9 +25,9 @@ public class GuiPrintout extends GuiContainer
private final TextBuffer[] m_colours;
private int m_page;
public GuiPrintout( ContainerHeldItem container )
public GuiPrintout( ContainerHeldItem container, PlayerInventory player, ITextComponent title )
{
super( container );
super( container, player, title );
ySize = Y_SIZE;
@@ -41,63 +41,70 @@ public class GuiPrintout extends GuiContainer
m_page = 0;
m_pages = Math.max( m_text.length / ItemPrintout.LINES_PER_PAGE, 1 );
m_book = ItemPrintout.getType( container.getStack() ) == ItemPrintout.Type.Book;
m_book = ((ItemPrintout) container.getStack().getItem()).getType() == ItemPrintout.Type.BOOK;
}
@Override
protected void keyTyped( char c, int k ) throws IOException
public boolean keyPressed( int key, int scancode, int modifiers )
{
super.keyTyped( c, k );
if( super.keyPressed( key, scancode, modifiers ) ) return true;
if( k == 205 )
if( key == GLFW.GLFW_KEY_RIGHT )
{
// Right
if( m_page < m_pages - 1 ) m_page++;
return true;
}
else if( k == 203 )
if( key == GLFW.GLFW_KEY_LEFT )
{
// Left
if( m_page > 0 ) m_page--;
return true;
}
return false;
}
@Override
public void handleMouseInput() throws IOException
public boolean mouseScrolled( double x, double y, double delta )
{
super.handleMouseInput();
int mouseWheelChange = Mouse.getEventDWheel();
if( mouseWheelChange < 0 )
if( super.mouseScrolled( x, y, delta ) ) return true;
if( delta < 0 )
{
// Scroll up goes to the next page
if( m_page < m_pages - 1 ) m_page++;
return true;
}
else if( mouseWheelChange > 0 )
if( delta > 0 )
{
// Scroll down goes to the previous page
if( m_page > 0 ) m_page--;
return true;
}
return false;
}
@Override
protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
public void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
{
// Draw the printout
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.enableDepthTest();
drawBorder( guiLeft, guiTop, zLevel, m_page, m_pages, m_book );
drawBorder( guiLeft, guiTop, blitOffset, m_page, m_pages, m_book );
drawText( guiLeft + X_TEXT_MARGIN, guiTop + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours );
}
@Override
public void drawScreen( int mouseX, int mouseY, float partialTicks )
public void render( int mouseX, int mouseY, float partialTicks )
{
// We must take the background further back in order to not overlap with our printed pages.
zLevel--;
drawDefaultBackground();
zLevel++;
blitOffset--;
renderBackground();
blitOffset++;
super.drawScreen( mouseX, mouseY, partialTicks );
super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY );
}
}

View File

@@ -6,121 +6,104 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
import dan200.computercraft.client.gui.widgets.WidgetWrapper;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import net.minecraft.util.text.ITextComponent;
import org.lwjgl.glfw.GLFW;
import java.io.IOException;
public class GuiTurtle extends GuiContainer
public class GuiTurtle extends ContainerScreen<ContainerTurtle>
{
private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( "computercraft", "textures/gui/turtle.png" );
private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( "computercraft", "textures/gui/turtle_normal.png" );
private static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation( "computercraft", "textures/gui/turtle_advanced.png" );
private ContainerTurtle m_container;
private final ComputerFamily m_family;
private final ClientComputer m_computer;
private WidgetTerminal m_terminalGui;
public GuiTurtle( TileTurtle turtle, ContainerTurtle container )
private WidgetTerminal terminal;
private WidgetWrapper terminalWrapper;
public GuiTurtle( ContainerTurtle container, PlayerInventory player, ITextComponent title )
{
super( container );
super( container, player, title );
m_container = container;
m_family = turtle.getFamily();
m_computer = turtle.getClientComputer();
m_family = container.getFamily();
m_computer = (ClientComputer) container.getComputer();
xSize = 254;
ySize = 217;
}
@Override
public void initGui()
protected void init()
{
super.initGui();
Keyboard.enableRepeatEvents( true );
m_terminalGui = new WidgetTerminal(
guiLeft + 8,
guiTop + 8,
super.init();
minecraft.keyboardListener.enableRepeatEvents( true );
int termPxWidth = ComputerCraft.terminalWidth_turtle * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = ComputerCraft.terminalHeight_turtle * FixedWidthFontRenderer.FONT_HEIGHT;
terminal = new WidgetTerminal(
minecraft, () -> m_computer,
ComputerCraft.terminalWidth_turtle,
ComputerCraft.terminalHeight_turtle,
() -> m_computer,
2, 2, 2, 2
);
m_terminalGui.setAllowFocusLoss( false );
terminalWrapper = new WidgetWrapper( terminal, 2 + 8 + guiLeft, 2 + 8 + guiTop, termPxWidth, termPxHeight );
children.add( terminalWrapper );
setFocused( terminalWrapper );
}
@Override
public void onGuiClosed()
public void removed()
{
super.onGuiClosed();
Keyboard.enableRepeatEvents( false );
super.removed();
children.remove( terminal );
terminal = null;
minecraft.keyboardListener.enableRepeatEvents( false );
}
@Override
public void updateScreen()
public void tick()
{
super.updateScreen();
m_terminalGui.update();
super.tick();
terminal.update();
}
@Override
protected void keyTyped( char c, int k ) throws IOException
public boolean keyPressed( int key, int scancode, int modifiers )
{
if( k == 1 )
// Forward the tab key to the terminal, rather than moving between controls.
if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminalWrapper )
{
super.keyTyped( c, k );
}
else
{
if( m_terminalGui.onKeyTyped( c, k ) ) keyHandled = true;
return getFocused().keyPressed( key, scancode, modifiers );
}
return super.keyPressed( key, scancode, modifiers );
}
@Override
protected void mouseClicked( int x, int y, int button ) throws IOException
{
super.mouseClicked( x, y, button );
m_terminalGui.mouseClicked( x, y, button );
}
@Override
public void handleMouseInput() throws IOException
{
super.handleMouseInput();
int x = Mouse.getEventX() * width / mc.displayWidth;
int y = height - Mouse.getEventY() * height / mc.displayHeight - 1;
m_terminalGui.handleMouseInput( x, y );
}
@Override
public void handleKeyboardInput() throws IOException
{
super.handleKeyboardInput();
if( m_terminalGui.onKeyboardInput() ) keyHandled = true;
}
protected void drawSelectionSlot( boolean advanced )
private void drawSelectionSlot( boolean advanced )
{
// Draw selection slot
int slot = m_container.getSelectedSlot();
if( slot >= 0 )
{
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
int slotX = slot % 4;
int slotY = slot / 4;
mc.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
drawTexturedModalRect( guiLeft + m_container.turtleInvStartX - 2 + slotX * 18, guiTop + m_container.playerInvStartY - 2 + slotY * 18, 0, 217, 24, 24 );
minecraft.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
blit( guiLeft + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18, guiTop + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18, 0, 217, 24, 24 );
}
}
@@ -129,21 +112,21 @@ public class GuiTurtle extends GuiContainer
{
// Draw term
boolean advanced = m_family == ComputerFamily.Advanced;
m_terminalGui.draw( Minecraft.getMinecraft(), 0, 0, mouseX, mouseY );
terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
// Draw border/inventory
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
mc.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
drawTexturedModalRect( guiLeft, guiTop, 0, 0, xSize, ySize );
GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
blit( guiLeft, guiTop, 0, 0, xSize, ySize );
drawSelectionSlot( advanced );
}
@Override
public void drawScreen( int mouseX, int mouseY, float partialTicks )
public void render( int mouseX, int mouseY, float partialTicks )
{
drawDefaultBackground();
super.drawScreen( mouseX, mouseY, partialTicks );
renderBackground();
super.render( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY );
}
}

View File

@@ -1,84 +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.client.gui.widgets;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
public abstract class Widget extends Gui
{
private int m_xPosition;
private int m_yPosition;
private int m_width;
private int m_height;
protected Widget( int x, int y, int width, int height )
{
m_xPosition = x;
m_yPosition = y;
m_width = width;
m_height = height;
}
public int getXPosition()
{
return m_xPosition;
}
public int getYPosition()
{
return m_yPosition;
}
public int getWidth()
{
return m_width;
}
public int getHeight()
{
return m_height;
}
public void update()
{
}
public void draw( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY )
{
}
public void handleMouseInput( int mouseX, int mouseY )
{
}
public boolean onKeyboardInput()
{
return false;
}
@Deprecated
public void handleKeyboardInput()
{
onKeyboardInput();
}
public void mouseClicked( int mouseX, int mouseY, int mouseButton )
{
}
public boolean onKeyTyped( char c, int k )
{
return false;
}
@Deprecated
public void keyTyped( char c, int k )
{
onKeyTyped( c, k );
}
}

View File

@@ -6,375 +6,366 @@
package dan200.computercraft.client.gui.widgets;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.IComputer;
import dan200.computercraft.shared.computer.core.IComputerContainer;
import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.ChatAllowedCharacters;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.SharedConstants;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL11;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.function.Supplier;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.BACKGROUND;
public class WidgetTerminal extends Widget
public class WidgetTerminal implements IGuiEventListener
{
private static final float TERMINATE_TIME = 0.5f;
private final IComputerContainer m_computer;
private final Minecraft client;
private float m_terminateTimer = 0.0f;
private float m_rebootTimer = 0.0f;
private float m_shutdownTimer = 0.0f;
private boolean focused;
private int m_lastClickButton = -1;
private int m_lastClickX = -1;
private int m_lastClickY = -1;
private final Supplier<ClientComputer> computer;
private final int termWidth;
private final int termHeight;
private boolean m_focus = false;
private boolean m_allowFocusLoss = true;
private float terminateTimer = -1;
private float rebootTimer = -1;
private float shutdownTimer = -1;
private int m_leftMargin;
private int m_rightMargin;
private int m_topMargin;
private int m_bottomMargin;
private int lastMouseButton = -1;
private int lastMouseX = -1;
private int lastMouseY = -1;
private final ArrayList<Integer> m_keysDown = new ArrayList<>();
private final int leftMargin;
private final int rightMargin;
private final int topMargin;
private final int bottomMargin;
public WidgetTerminal( int x, int y, int termWidth, int termHeight, IComputerContainer computer, int leftMargin, int rightMargin, int topMargin, int bottomMargin )
private final BitSet keysDown = new BitSet( 256 );
public WidgetTerminal( Minecraft client, Supplier<ClientComputer> computer, int termWidth, int termHeight, int leftMargin, int rightMargin, int topMargin, int bottomMargin )
{
super(
x, y,
leftMargin + rightMargin + termWidth * FixedWidthFontRenderer.FONT_WIDTH,
topMargin + bottomMargin + termHeight * FixedWidthFontRenderer.FONT_HEIGHT
);
m_computer = computer;
m_leftMargin = leftMargin;
m_rightMargin = rightMargin;
m_topMargin = topMargin;
m_bottomMargin = bottomMargin;
}
public void setAllowFocusLoss( boolean allowFocusLoss )
{
m_allowFocusLoss = allowFocusLoss;
m_focus = m_focus || !allowFocusLoss;
this.client = client;
this.computer = computer;
this.termWidth = termWidth;
this.termHeight = termHeight;
this.leftMargin = leftMargin;
this.rightMargin = rightMargin;
this.topMargin = topMargin;
this.bottomMargin = bottomMargin;
}
@Override
public boolean onKeyTyped( char ch, int key )
public boolean charTyped( char ch, int modifiers )
{
if( m_focus )
if( ch >= 32 && ch <= 126 || ch >= 160 && ch <= 255 ) // printable chars in byte range
{
// Ctrl+V for paste
if( ch == 22 )
// Queue the "char" event
queueEvent( "char", Character.toString( ch ) );
}
return true;
}
@Override
public boolean keyPressed( int key, int scancode, int modifiers )
{
if( key == GLFW.GLFW_KEY_ESCAPE ) return false;
if( (modifiers & GLFW.GLFW_MOD_CONTROL) != 0 )
{
switch( key )
{
String clipboard = GuiScreen.getClipboardString();
if( clipboard != null )
{
// Clip to the first occurrence of \r or \n
int newLineIndex1 = clipboard.indexOf( '\r' );
int newLineIndex2 = clipboard.indexOf( '\n' );
if( newLineIndex1 >= 0 && newLineIndex2 >= 0 )
{
clipboard = clipboard.substring( 0, Math.min( newLineIndex1, newLineIndex2 ) );
}
else if( newLineIndex1 >= 0 )
{
clipboard = clipboard.substring( 0, newLineIndex1 );
}
else if( newLineIndex2 >= 0 )
{
clipboard = clipboard.substring( 0, newLineIndex2 );
}
case GLFW.GLFW_KEY_T:
if( terminateTimer < 0 ) terminateTimer = 0;
return true;
case GLFW.GLFW_KEY_S:
if( shutdownTimer < 0 ) shutdownTimer = 0;
return true;
case GLFW.GLFW_KEY_R:
if( rebootTimer < 0 ) rebootTimer = 0;
return true;
// Filter the string
clipboard = ChatAllowedCharacters.filterAllowedCharacters( clipboard );
if( !clipboard.isEmpty() )
case GLFW.GLFW_KEY_V:
// Ctrl+V for paste
String clipboard = client.keyboardListener.getClipboardString();
if( clipboard != null )
{
// Clip to 512 characters
if( clipboard.length() > 512 )
// Clip to the first occurrence of \r or \n
int newLineIndex1 = clipboard.indexOf( "\r" );
int newLineIndex2 = clipboard.indexOf( "\n" );
if( newLineIndex1 >= 0 && newLineIndex2 >= 0 )
{
clipboard = clipboard.substring( 0, 512 );
clipboard = clipboard.substring( 0, Math.min( newLineIndex1, newLineIndex2 ) );
}
else if( newLineIndex1 >= 0 )
{
clipboard = clipboard.substring( 0, newLineIndex1 );
}
else if( newLineIndex2 >= 0 )
{
clipboard = clipboard.substring( 0, newLineIndex2 );
}
// Queue the "paste" event
queueEvent( "paste", new Object[] { clipboard } );
}
}
return true;
}
// Filter the string
clipboard = SharedConstants.filterAllowedCharacters( clipboard );
if( !clipboard.isEmpty() )
{
// Clip to 512 characters and queue the event
if( clipboard.length() > 512 ) clipboard = clipboard.substring( 0, 512 );
queueEvent( "paste", clipboard );
}
// Regular keys normally
if( m_terminateTimer <= 0.0f && m_rebootTimer <= 0.0f && m_shutdownTimer <= 0.0f )
return true;
}
}
}
if( key >= 0 && terminateTimer < 0 && rebootTimer < 0 && shutdownTimer < 0 )
{
// Queue the "key" event and add to the down set
boolean repeat = keysDown.get( key );
keysDown.set( key );
IComputer computer = this.computer.get();
if( computer != null ) computer.keyDown( key, repeat );
}
return true;
}
@Override
public boolean keyReleased( int key, int scancode, int modifiers )
{
// Queue the "key_up" event and remove from the down set
if( key >= 0 && keysDown.get( key ) )
{
keysDown.set( key, false );
IComputer computer = this.computer.get();
if( computer != null ) computer.keyUp( key );
}
switch( key )
{
case GLFW.GLFW_KEY_T:
terminateTimer = -1;
break;
case GLFW.GLFW_KEY_R:
rebootTimer = -1;
break;
case GLFW.GLFW_KEY_S:
shutdownTimer = -1;
break;
case GLFW.GLFW_KEY_LEFT_CONTROL:
case GLFW.GLFW_KEY_RIGHT_CONTROL:
terminateTimer = rebootTimer = shutdownTimer = -1;
break;
}
return true;
}
@Override
public boolean mouseClicked( double mouseX, double mouseY, int button )
{
ClientComputer computer = this.computer.get();
if( computer == null || !computer.isColour() || button < 0 || button > 2 ) return false;
Terminal term = computer.getTerminal();
if( term != null )
{
int charX = (int) (mouseX / FixedWidthFontRenderer.FONT_WIDTH);
int charY = (int) (mouseY / FixedWidthFontRenderer.FONT_HEIGHT);
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
computer.mouseClick( button + 1, charX + 1, charY + 1 );
lastMouseButton = button;
lastMouseX = charX;
lastMouseY = charY;
}
return true;
}
@Override
public boolean mouseReleased( double mouseX, double mouseY, int button )
{
ClientComputer computer = this.computer.get();
if( computer == null || !computer.isColour() || button < 0 || button > 2 ) return false;
Terminal term = computer.getTerminal();
if( term != null )
{
int charX = (int) (mouseX / FixedWidthFontRenderer.FONT_WIDTH);
int charY = (int) (mouseY / FixedWidthFontRenderer.FONT_HEIGHT);
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
if( lastMouseButton == button )
{
boolean repeat = Keyboard.isRepeatEvent();
boolean handled = false;
if( key > 0 )
{
if( !repeat )
{
m_keysDown.add( key );
}
// Queue the "key" event
IComputer computer = m_computer.getComputer();
if( computer != null ) computer.keyDown( key, repeat );
handled = true;
}
if( (ch >= 32 && ch <= 126) || (ch >= 160 && ch <= 255) ) // printable chars in byte range
{
// Queue the "char" event
queueEvent( "char", new Object[] { Character.toString( ch ) } );
handled = true;
}
return handled;
computer.mouseUp( lastMouseButton + 1, charX + 1, charY + 1 );
lastMouseButton = -1;
}
lastMouseX = charX;
lastMouseY = charY;
}
return false;
}
@Override
public void mouseClicked( int mouseX, int mouseY, int button )
public boolean mouseDragged( double mouseX, double mouseY, int button, double v2, double v3 )
{
if( mouseX >= getXPosition() && mouseX < getXPosition() + getWidth() &&
mouseY >= getYPosition() && mouseY < getYPosition() + getHeight() )
ClientComputer computer = this.computer.get();
if( computer == null || !computer.isColour() || button < 0 || button > 2 ) return false;
Terminal term = computer.getTerminal();
if( term != null )
{
if( !m_focus && button == 0 )
{
m_focus = true;
}
int charX = (int) (mouseX / FixedWidthFontRenderer.FONT_WIDTH);
int charY = (int) (mouseY / FixedWidthFontRenderer.FONT_HEIGHT);
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
if( m_focus )
{
IComputer computer = m_computer.getComputer();
if( computer != null && computer.isColour() && button >= 0 && button <= 2 )
{
Terminal term = computer.getTerminal();
if( term != null )
{
int charX = (mouseX - (getXPosition() + m_leftMargin)) / FixedWidthFontRenderer.FONT_WIDTH;
int charY = (mouseY - (getYPosition() + m_topMargin)) / FixedWidthFontRenderer.FONT_HEIGHT;
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
computer.mouseDrag( button + 1, charX + 1, charY + 1 );
computer.mouseClick( button + 1, charX + 1, charY + 1 );
m_lastClickButton = button;
m_lastClickX = charX;
m_lastClickY = charY;
}
}
}
}
else
{
if( m_focus && button == 0 && m_allowFocusLoss )
{
m_focus = false;
}
lastMouseX = charX;
lastMouseY = charY;
lastMouseButton = button;
}
return false;
}
@Override
public boolean onKeyboardInput()
public boolean mouseScrolled( double mouseX, double mouseY, double delta )
{
boolean handled = false;
for( int i = m_keysDown.size() - 1; i >= 0; --i )
ClientComputer computer = this.computer.get();
if( computer == null || !computer.isColour() || delta == 0 ) return false;
Terminal term = computer.getTerminal();
if( term != null )
{
int key = m_keysDown.get( i );
if( !Keyboard.isKeyDown( key ) )
{
m_keysDown.remove( i );
if( m_focus )
{
// Queue the "key_up" event
IComputer computer = m_computer.getComputer();
if( computer != null ) computer.keyUp( key );
handled = true;
}
}
int charX = (int) (mouseX / FixedWidthFontRenderer.FONT_WIDTH);
int charY = (int) (mouseY / FixedWidthFontRenderer.FONT_HEIGHT);
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
computer.mouseScroll( delta < 0 ? 1 : -1, charX + 1, charY + 1 );
lastMouseX = charX;
lastMouseY = charY;
}
return handled;
return true;
}
@Override
public void handleMouseInput( int mouseX, int mouseY )
{
IComputer computer = m_computer.getComputer();
if( mouseX >= getXPosition() && mouseX < getXPosition() + getWidth() &&
mouseY >= getYPosition() && mouseY < getYPosition() + getHeight() &&
computer != null && computer.isColour() )
{
Terminal term = computer.getTerminal();
if( term != null )
{
int charX = (mouseX - (getXPosition() + m_leftMargin)) / FixedWidthFontRenderer.FONT_WIDTH;
int charY = (mouseY - (getYPosition() + m_topMargin)) / FixedWidthFontRenderer.FONT_HEIGHT;
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
if( m_lastClickButton >= 0 && !Mouse.isButtonDown( m_lastClickButton ) )
{
if( m_focus ) computer.mouseUp( m_lastClickButton + 1, charX + 1, charY + 1 );
m_lastClickButton = -1;
}
int wheelChange = Mouse.getEventDWheel();
if( wheelChange == 0 && m_lastClickButton == -1 )
{
return;
}
if( m_focus )
{
if( wheelChange < 0 )
{
computer.mouseScroll( 1, charX + 1, charY + 1 );
}
else if( wheelChange > 0 )
{
computer.mouseScroll( -1, charX + 1, charY + 1 );
}
if( m_lastClickButton >= 0 && (charX != m_lastClickX || charY != m_lastClickY) )
{
computer.mouseDrag( m_lastClickButton + 1, charX + 1, charY + 1 );
m_lastClickX = charX;
m_lastClickY = charY;
}
}
}
}
}
@Override
public void update()
{
// Handle special keys
if( m_focus && (Keyboard.isKeyDown( 29 ) || Keyboard.isKeyDown( 157 )) )
if( terminateTimer >= 0 && terminateTimer < TERMINATE_TIME && (terminateTimer += 0.05f) > TERMINATE_TIME )
{
// Ctrl+T for terminate
if( Keyboard.isKeyDown( 20 ) )
{
if( m_terminateTimer < TERMINATE_TIME )
{
m_terminateTimer += 0.05f;
if( m_terminateTimer >= TERMINATE_TIME ) queueEvent( "terminate" );
}
}
else
{
m_terminateTimer = 0.0f;
}
// Ctrl+R for reboot
if( Keyboard.isKeyDown( 19 ) )
{
if( m_rebootTimer < TERMINATE_TIME )
{
m_rebootTimer += 0.05f;
if( m_rebootTimer >= TERMINATE_TIME )
{
IComputer computer = m_computer.getComputer();
if( computer != null ) computer.reboot();
}
}
}
else
{
m_rebootTimer = 0.0f;
}
// Ctrl+S for shutdown
if( Keyboard.isKeyDown( 31 ) )
{
if( m_shutdownTimer < TERMINATE_TIME )
{
m_shutdownTimer += 0.05f;
if( m_shutdownTimer >= TERMINATE_TIME )
{
IComputer computer = m_computer.getComputer();
if( computer != null ) computer.shutdown();
}
}
}
else
{
m_shutdownTimer = 0.0f;
}
queueEvent( "terminate" );
}
else
if( shutdownTimer >= 0 && shutdownTimer < TERMINATE_TIME && (shutdownTimer += 0.05f) > TERMINATE_TIME )
{
m_terminateTimer = 0.0f;
m_rebootTimer = 0.0f;
m_shutdownTimer = 0.0f;
ClientComputer computer = this.computer.get();
if( computer != null ) computer.shutdown();
}
if( rebootTimer >= 0 && rebootTimer < TERMINATE_TIME && (rebootTimer += 0.05f) > TERMINATE_TIME )
{
ClientComputer computer = this.computer.get();
if( computer != null ) computer.reboot();
}
}
@Override
public void draw( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY )
public boolean changeFocus( boolean reversed )
{
int startX = xOrigin + getXPosition();
int startY = yOrigin + getYPosition();
if( focused )
{
// When blurring, we should make all keys go up
for( int key = 0; key < keysDown.size(); key++ )
{
if( keysDown.get( key ) ) queueEvent( "key_up", key );
}
keysDown.clear();
synchronized( m_computer )
// When blurring, we should make the last mouse button go up
if( lastMouseButton > 0 )
{
IComputer computer = this.computer.get();
if( computer != null ) computer.mouseUp( lastMouseButton + 1, lastMouseX + 1, lastMouseY + 1 );
lastMouseButton = -1;
}
shutdownTimer = terminateTimer = rebootTimer = -1;
}
focused = !focused;
return true;
}
public void draw( int originX, int originY )
{
synchronized( computer )
{
// Draw the screen contents
IComputer computer = m_computer.getComputer();
ClientComputer computer = this.computer.get();
Terminal terminal = computer != null ? computer.getTerminal() : null;
if( terminal != null )
{
// Draw the terminal
boolean greyscale = !computer.isColour();
Palette palette = terminal.getPalette();
// Get the data from the terminal first
// Unfortunately we have to keep the lock for the whole of drawing, so the text doesn't change under us.
FixedWidthFontRenderer fontRenderer = FixedWidthFontRenderer.instance();
boolean tblink = m_focus && terminal.getCursorBlink() && FrameInfo.getGlobalCursorBlink();
boolean tblink = terminal.getCursorBlink() && FrameInfo.getGlobalCursorBlink();
int tw = terminal.getWidth();
int th = terminal.getHeight();
int tx = terminal.getCursorX();
int ty = terminal.getCursorY();
int x = startX + m_leftMargin;
int y = startY + m_topMargin;
// Draw margins
TextBuffer emptyLine = new TextBuffer( ' ', tw );
if( m_topMargin > 0 )
if( topMargin > 0 )
{
fontRenderer.drawString( emptyLine, x, startY, terminal.getTextColourLine( 0 ), terminal.getBackgroundColourLine( 0 ), m_leftMargin, m_rightMargin, greyscale, palette );
fontRenderer.drawString( emptyLine, originX, originY - topMargin,
terminal.getTextColourLine( 0 ), terminal.getBackgroundColourLine( 0 ),
leftMargin, rightMargin, greyscale, palette );
}
if( m_bottomMargin > 0 )
if( bottomMargin > 0 )
{
fontRenderer.drawString( emptyLine, x, startY + 2 * m_bottomMargin + (th - 1) * FixedWidthFontRenderer.FONT_HEIGHT, terminal.getTextColourLine( th - 1 ), terminal.getBackgroundColourLine( th - 1 ), m_leftMargin, m_rightMargin, greyscale, palette );
fontRenderer.drawString( emptyLine, originX, originY + bottomMargin + (th - 1) * FixedWidthFontRenderer.FONT_HEIGHT,
terminal.getTextColourLine( th - 1 ), terminal.getBackgroundColourLine( th - 1 ),
leftMargin, rightMargin, greyscale, palette );
}
// Draw lines
int y = originY;
for( int line = 0; line < th; line++ )
{
TextBuffer text = terminal.getLine( line );
TextBuffer colour = terminal.getTextColourLine( line );
TextBuffer backgroundColour = terminal.getBackgroundColourLine( line );
fontRenderer.drawString( text, x, y, colour, backgroundColour, m_leftMargin, m_rightMargin, greyscale, palette );
fontRenderer.drawString( text, originX, y, colour, backgroundColour, leftMargin, rightMargin, greyscale, palette );
y += FixedWidthFontRenderer.FONT_HEIGHT;
}
@@ -385,8 +376,8 @@ public class WidgetTerminal extends Widget
fontRenderer.drawString(
cursor,
x + FixedWidthFontRenderer.FONT_WIDTH * tx,
startY + m_topMargin + FixedWidthFontRenderer.FONT_HEIGHT * ty,
originX + FixedWidthFontRenderer.FONT_WIDTH * tx,
originY + FixedWidthFontRenderer.FONT_HEIGHT * ty,
cursorColour, null,
0, 0,
greyscale,
@@ -397,16 +388,29 @@ public class WidgetTerminal extends Widget
else
{
// Draw a black background
mc.getTextureManager().bindTexture( BACKGROUND );
Colour black = Colour.Black;
GlStateManager.color( black.getR(), black.getG(), black.getB(), 1.0f );
GlStateManager.color4f( black.getR(), black.getG(), black.getB(), 1.0f );
try
{
drawTexturedModalRect( startX, startY, 0, 0, getWidth(), getHeight() );
int x = originX - leftMargin;
int y = originY - rightMargin;
int width = termWidth * FixedWidthFontRenderer.FONT_WIDTH + leftMargin + rightMargin;
int height = termHeight * FixedWidthFontRenderer.FONT_HEIGHT + topMargin + bottomMargin;
client.getTextureManager().bindTexture( BACKGROUND );
Tessellator tesslector = Tessellator.getInstance();
BufferBuilder buffer = tesslector.getBuffer();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX );
buffer.pos( x, y + height, 0 ).tex( 0 / 256.0, height / 256.0 ).endVertex();
buffer.pos( x + width, y + height, 0 ).tex( width / 256.0, height / 256.0 ).endVertex();
buffer.pos( x + width, y, 0 ).tex( width / 256.0, 0 / 256.0 ).endVertex();
buffer.pos( x, y, 0 ).tex( 0 / 256.0, 0 / 256.0 ).endVertex();
tesslector.draw();
}
finally
{
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
}
}
}
@@ -414,13 +418,13 @@ public class WidgetTerminal extends Widget
private void queueEvent( String event )
{
IComputer computer = m_computer.getComputer();
ClientComputer computer = this.computer.get();
if( computer != null ) computer.queueEvent( event );
}
private void queueEvent( String event, Object[] args )
private void queueEvent( String event, Object... args )
{
IComputer computer = m_computer.getComputer();
ClientComputer computer = this.computer.get();
if( computer != null ) computer.queueEvent( event, args );
}
}

View File

@@ -0,0 +1,98 @@
/*
* 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.client.gui.widgets;
import net.minecraft.client.gui.IGuiEventListener;
public class WidgetWrapper implements IGuiEventListener
{
private final IGuiEventListener listener;
private final int x;
private final int y;
private final int width;
private final int height;
public WidgetWrapper( IGuiEventListener listener, int x, int y, int width, int height )
{
this.listener = listener;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
@Override
public boolean changeFocus( boolean b )
{
return listener.changeFocus( b );
}
@Override
public boolean mouseClicked( double x, double y, int button )
{
double dx = x - this.x, dy = y - this.y;
return dx >= 0 && dx < width && dy >= 0 && dy < height && listener.mouseClicked( dx, dy, button );
}
@Override
public boolean mouseReleased( double x, double y, int button )
{
double dx = x - this.x, dy = y - this.y;
return dx >= 0 && dx < width && dy >= 0 && dy < height && listener.mouseReleased( dx, dy, button );
}
@Override
public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
{
double dx = x - this.x, dy = y - this.y;
return dx >= 0 && dx < width && dy >= 0 && dy < height && listener.mouseDragged( dx, dy, button, deltaX, deltaY );
}
@Override
public boolean mouseScrolled( double x, double y, double delta )
{
return listener.mouseScrolled( x, y, delta );
}
@Override
public boolean keyPressed( int key, int scancode, int modifiers )
{
return listener.keyPressed( key, scancode, modifiers );
}
@Override
public boolean keyReleased( int key, int scancode, int modifiers )
{
return listener.keyReleased( key, scancode, modifiers );
}
@Override
public boolean charTyped( char character, int modifiers )
{
return listener.charTyped( character, modifiers );
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public int getWidth()
{
return width;
}
public int getHeight()
{
return height;
}
}

View File

@@ -7,56 +7,68 @@
package dan200.computercraft.client.proxy;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.gui.*;
import dan200.computercraft.client.render.TileEntityCableRenderer;
import dan200.computercraft.client.render.TileEntityMonitorRenderer;
import dan200.computercraft.client.render.TileEntityTurtleRenderer;
import dan200.computercraft.shared.command.CommandCopy;
import dan200.computercraft.shared.common.ContainerHeldItem;
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
import dan200.computercraft.shared.peripheral.modem.wired.TileCable;
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import net.minecraftforge.client.ClientCommandHandler;
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
import net.minecraft.client.gui.ScreenManager;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD )
public final class ComputerCraftProxyClient
{
@Override
public void preInit()
@SubscribeEvent
public static void setupClient( FMLClientSetupEvent event )
{
super.preInit();
registerContainers();
// Register any client-specific commands
ClientCommandHandler.instance.registerCommand( CommandCopy.INSTANCE );
}
@Override
public void init()
{
super.init();
// Setup renderers
// Setup TESRs
ClientRegistry.bindTileEntitySpecialRenderer( TileMonitor.class, new TileEntityMonitorRenderer() );
ClientRegistry.bindTileEntitySpecialRenderer( TileCable.class, new TileEntityCableRenderer() );
ClientRegistry.bindTileEntitySpecialRenderer( TileTurtle.class, new TileEntityTurtleRenderer() );
}
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
private static void registerContainers()
{
// My IDE doesn't think so, but we do actually need these generics.
ScreenManager.<ContainerComputer, GuiComputer<ContainerComputer>>registerFactory( ContainerComputer.TYPE, GuiComputer::create );
ScreenManager.<ContainerPocketComputer, GuiComputer<ContainerPocketComputer>>registerFactory( ContainerPocketComputer.TYPE, GuiComputer::createPocket );
ScreenManager.registerFactory( ContainerTurtle.TYPE, GuiTurtle::new );
ScreenManager.registerFactory( ContainerPrinter.TYPE, GuiPrinter::new );
ScreenManager.registerFactory( ContainerDiskDrive.TYPE, GuiDiskDrive::new );
ScreenManager.registerFactory( ContainerHeldItem.PRINTOUT_TYPE, GuiPrintout::new );
ScreenManager.<ContainerViewComputer, GuiComputer<ContainerViewComputer>>registerFactory( ContainerViewComputer.TYPE, GuiComputer::createView );
}
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public static final class ForgeHandlers
{
@SubscribeEvent
public static void onWorldUnload( WorldEvent.Unload event )
{
if( event.getWorld().isRemote )
if( event.getWorld().isRemote() )
{
ClientMonitor.destroyAll();
}
}
}
}

View File

@@ -6,217 +6,85 @@
package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.modem.wired.BlockCable;
import dan200.computercraft.shared.peripheral.modem.wired.CableBounds;
import dan200.computercraft.shared.peripheral.modem.wired.CableShapes;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import org.lwjgl.opengl.GL11;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class CableHighlightRenderer
{
private static final float EXPAND = 0.002f;
private static final double MIN = CableBounds.MIN - EXPAND;
private static final double MAX = CableBounds.MAX + EXPAND;
private CableHighlightRenderer()
{
}
/**
* Draw an outline for a specific part of a cable "Multipart".
*
* @param event The event to observe
* @see WorldRenderer#drawSelectionBox(ActiveRenderInfo, RayTraceResult, int)
*/
@SubscribeEvent
public static void drawHighlight( DrawBlockHighlightEvent event )
{
if( event.getTarget().typeOfHit != RayTraceResult.Type.BLOCK ) return;
if( event.getTarget().getType() != RayTraceResult.Type.BLOCK ) return;
BlockPos pos = event.getTarget().getBlockPos();
World world = event.getPlayer().getEntityWorld();
BlockRayTraceResult hit = (BlockRayTraceResult) event.getTarget();
BlockPos pos = hit.getPos();
World world = event.getInfo().getRenderViewEntity().getEntityWorld();
ActiveRenderInfo info = event.getInfo();
IBlockState state = world.getBlockState( pos );
if( state.getBlock() != ComputerCraft.Blocks.cable ) return;
BlockState state = world.getBlockState( pos );
state = state.getActualState( world, pos );
// We only care about instances with both cable and modem.
if( state.getBlock() != ComputerCraft.Blocks.cable || state.get( BlockCable.MODEM ).getFacing() == null || !state.get( BlockCable.CABLE ) )
{
return;
}
event.setCanceled( true );
PeripheralType type = BlockCable.getPeripheralType( state );
Minecraft mc = Minecraft.getInstance();
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate( GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0 );
GlStateManager.color( 0.0f, 0.0f, 0.0f, 0.4f );
GL11.glLineWidth( 2.0F );
GlStateManager.disableTexture2D();
GlStateManager.blendFuncSeparate( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO );
GlStateManager.lineWidth( Math.max( 2.5F, mc.mainWindow.getFramebufferWidth() / 1920.0F * 2.5F ) );
GlStateManager.disableTexture();
GlStateManager.depthMask( false );
GlStateManager.matrixMode( GL11.GL_PROJECTION );
GlStateManager.pushMatrix();
GlStateManager.scalef( 1.0F, 1.0F, 0.999F );
{
EntityPlayer player = event.getPlayer();
double x = player.lastTickPosX + (player.posX - player.lastTickPosX) * event.getPartialTicks();
double y = player.lastTickPosY + (player.posY - player.lastTickPosY) * event.getPartialTicks();
double z = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * event.getPartialTicks();
VoxelShape shape = WorldUtil.isVecInside( CableShapes.getModemShape( state ), hit.getHitVec().subtract( pos.getX(), pos.getY(), pos.getZ() ) )
? CableShapes.getModemShape( state )
: CableShapes.getCableShape( state );
GlStateManager.translate( -x + pos.getX(), -y + pos.getY(), -z + pos.getZ() );
}
if( type != PeripheralType.Cable && WorldUtil.isVecInsideInclusive( CableBounds.getModemBounds( state ), event.getTarget().hitVec.subtract( pos.getX(), pos.getY(), pos.getZ() ) ) )
{
RenderGlobal.drawSelectionBoundingBox( CableBounds.getModemBounds( state ), 0, 0, 0, 0.4f );
}
else
{
int flags = 0;
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
for( EnumFacing facing : EnumFacing.VALUES )
{
if( BlockCable.doesConnectVisually( state, world, pos, facing ) )
{
flags |= 1 << facing.ordinal();
switch( facing.getAxis() )
{
case X:
{
double offset = facing == EnumFacing.WEST ? -EXPAND : 1 + EXPAND;
double centre = facing == EnumFacing.WEST ? MIN : MAX;
buffer.begin( GL11.GL_LINE_STRIP, DefaultVertexFormats.POSITION );
buffer.pos( offset, MIN, MIN ).endVertex();
buffer.pos( offset, MAX, MIN ).endVertex();
buffer.pos( offset, MAX, MAX ).endVertex();
buffer.pos( offset, MIN, MAX ).endVertex();
buffer.pos( offset, MIN, MIN ).endVertex();
tessellator.draw();
buffer.begin( GL11.GL_LINES, DefaultVertexFormats.POSITION );
buffer.pos( offset, MIN, MIN ).endVertex();
buffer.pos( centre, MIN, MIN ).endVertex();
buffer.pos( offset, MAX, MIN ).endVertex();
buffer.pos( centre, MAX, MIN ).endVertex();
buffer.pos( offset, MAX, MAX ).endVertex();
buffer.pos( centre, MAX, MAX ).endVertex();
buffer.pos( offset, MIN, MAX ).endVertex();
buffer.pos( centre, MIN, MAX ).endVertex();
tessellator.draw();
break;
}
case Y:
{
double offset = facing == EnumFacing.DOWN ? -EXPAND : 1 + EXPAND;
double centre = facing == EnumFacing.DOWN ? MIN : MAX;
buffer.begin( GL11.GL_LINE_STRIP, DefaultVertexFormats.POSITION );
buffer.pos( MIN, offset, MIN ).endVertex();
buffer.pos( MAX, offset, MIN ).endVertex();
buffer.pos( MAX, offset, MAX ).endVertex();
buffer.pos( MIN, offset, MAX ).endVertex();
buffer.pos( MIN, offset, MIN ).endVertex();
tessellator.draw();
buffer.begin( GL11.GL_LINES, DefaultVertexFormats.POSITION );
buffer.pos( MIN, offset, MIN ).endVertex();
buffer.pos( MIN, centre, MIN ).endVertex();
buffer.pos( MAX, offset, MIN ).endVertex();
buffer.pos( MAX, centre, MIN ).endVertex();
buffer.pos( MAX, offset, MAX ).endVertex();
buffer.pos( MAX, centre, MAX ).endVertex();
buffer.pos( MIN, offset, MAX ).endVertex();
buffer.pos( MIN, centre, MAX ).endVertex();
tessellator.draw();
break;
}
case Z:
{
double offset = facing == EnumFacing.NORTH ? -EXPAND : 1 + EXPAND;
double centre = facing == EnumFacing.NORTH ? MIN : MAX;
buffer.begin( GL11.GL_LINE_STRIP, DefaultVertexFormats.POSITION );
buffer.pos( MIN, MIN, offset ).endVertex();
buffer.pos( MAX, MIN, offset ).endVertex();
buffer.pos( MAX, MAX, offset ).endVertex();
buffer.pos( MIN, MAX, offset ).endVertex();
buffer.pos( MIN, MIN, offset ).endVertex();
tessellator.draw();
buffer.begin( GL11.GL_LINES, DefaultVertexFormats.POSITION );
buffer.pos( MIN, MIN, offset ).endVertex();
buffer.pos( MIN, MIN, centre ).endVertex();
buffer.pos( MAX, MIN, offset ).endVertex();
buffer.pos( MAX, MIN, centre ).endVertex();
buffer.pos( MAX, MAX, offset ).endVertex();
buffer.pos( MAX, MAX, centre ).endVertex();
buffer.pos( MIN, MAX, offset ).endVertex();
buffer.pos( MIN, MAX, centre ).endVertex();
tessellator.draw();
break;
}
}
}
}
buffer.begin( GL11.GL_LINES, DefaultVertexFormats.POSITION );
draw( buffer, flags, EnumFacing.WEST, EnumFacing.DOWN, EnumFacing.Axis.Z );
draw( buffer, flags, EnumFacing.WEST, EnumFacing.UP, EnumFacing.Axis.Z );
draw( buffer, flags, EnumFacing.EAST, EnumFacing.DOWN, EnumFacing.Axis.Z );
draw( buffer, flags, EnumFacing.EAST, EnumFacing.UP, EnumFacing.Axis.Z );
draw( buffer, flags, EnumFacing.WEST, EnumFacing.NORTH, EnumFacing.Axis.Y );
draw( buffer, flags, EnumFacing.WEST, EnumFacing.SOUTH, EnumFacing.Axis.Y );
draw( buffer, flags, EnumFacing.EAST, EnumFacing.NORTH, EnumFacing.Axis.Y );
draw( buffer, flags, EnumFacing.EAST, EnumFacing.SOUTH, EnumFacing.Axis.Y );
draw( buffer, flags, EnumFacing.DOWN, EnumFacing.NORTH, EnumFacing.Axis.X );
draw( buffer, flags, EnumFacing.DOWN, EnumFacing.SOUTH, EnumFacing.Axis.X );
draw( buffer, flags, EnumFacing.UP, EnumFacing.NORTH, EnumFacing.Axis.X );
draw( buffer, flags, EnumFacing.UP, EnumFacing.SOUTH, EnumFacing.Axis.X );
tessellator.draw();
}
Vec3d cameraPos = info.getProjectedView();
WorldRenderer.drawShape(
shape, pos.getX() - cameraPos.getX(), pos.getY() - cameraPos.getY(), pos.getZ() - cameraPos.getZ(),
0.0F, 0.0F, 0.0F, 0.4F
);
GlStateManager.popMatrix();
GlStateManager.matrixMode( GL11.GL_MODELVIEW );
GlStateManager.depthMask( true );
GlStateManager.enableTexture2D();
GlStateManager.enableTexture();
GlStateManager.disableBlend();
}
private static void draw( BufferBuilder buffer, int flags, EnumFacing a, EnumFacing b, EnumFacing.Axis other )
{
if( ((flags >> a.ordinal()) & 1) != ((flags >> b.ordinal()) & 1) ) return;
double offA = a.getAxisDirection() == EnumFacing.AxisDirection.NEGATIVE ? MIN : MAX;
double offB = b.getAxisDirection() == EnumFacing.AxisDirection.NEGATIVE ? MIN : MAX;
switch( other )
{
case X:
buffer.pos( MIN, offA, offB ).endVertex();
buffer.pos( MAX, offA, offB ).endVertex();
break;
case Y:
buffer.pos( offA, MIN, offB ).endVertex();
buffer.pos( offA, MAX, offB ).endVertex();
break;
case Z:
buffer.pos( offA, offB, MIN ).endVertex();
buffer.pos( offA, offB, MAX ).endVertex();
break;
}
}
}

View File

@@ -6,38 +6,38 @@
package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GlStateManager;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.client.renderer.FirstPersonRenderer;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumHandSide;
import net.minecraft.util.Hand;
import net.minecraft.util.HandSide;
import net.minecraft.util.math.MathHelper;
public abstract class ItemMapLikeRenderer
{
/**
* The main rendering method for the item.
* The main rendering method for the item
*
* @param stack The stack to render
* @see ItemRenderer#renderMapFirstPerson(ItemStack)
* @see FirstPersonRenderer#renderMapFirstPerson(ItemStack)
*/
protected abstract void renderItem( ItemStack stack );
protected void renderItemFirstPerson( EnumHand hand, float pitch, float equipProgress, float swingProgress, ItemStack stack )
protected void renderItemFirstPerson( Hand hand, float pitch, float equipProgress, float swingProgress, ItemStack stack )
{
EntityPlayer player = Minecraft.getMinecraft().player;
PlayerEntity player = Minecraft.getInstance().player;
GlStateManager.pushMatrix();
if( hand == EnumHand.MAIN_HAND && player.getHeldItemOffhand().isEmpty() )
if( hand == Hand.MAIN_HAND && player.getHeldItemOffhand().isEmpty() )
{
renderItemFirstPersonCenter( pitch, equipProgress, swingProgress, stack );
}
else
{
renderItemFirstPersonSide(
hand == EnumHand.MAIN_HAND ? player.getPrimaryHand() : player.getPrimaryHand().opposite(),
hand == Hand.MAIN_HAND ? player.getPrimaryHand() : player.getPrimaryHand().opposite(),
equipProgress, swingProgress, stack
);
}
@@ -51,35 +51,35 @@ public abstract class ItemMapLikeRenderer
* @param equipProgress The equip progress of this item
* @param swingProgress The swing progress of this item
* @param stack The stack to render
* @see ItemRenderer#renderMapFirstPersonSide(float, EnumHandSide, float, ItemStack)
* @see FirstPersonRenderer#renderMapFirstPersonSide(float, HandSide, float, ItemStack)
*/
private void renderItemFirstPersonSide( EnumHandSide side, float equipProgress, float swingProgress, ItemStack stack )
private void renderItemFirstPersonSide( HandSide side, float equipProgress, float swingProgress, ItemStack stack )
{
Minecraft minecraft = Minecraft.getMinecraft();
float offset = side == EnumHandSide.RIGHT ? 1f : -1f;
GlStateManager.translate( offset * 0.125f, -0.125f, 0f );
Minecraft minecraft = Minecraft.getInstance();
float offset = side == HandSide.RIGHT ? 1f : -1f;
GlStateManager.translatef( offset * 0.125f, -0.125f, 0f );
// If the player is not invisible then render a single arm
if( !minecraft.player.isInvisible() )
{
GlStateManager.pushMatrix();
GlStateManager.rotate( offset * 10f, 0f, 0f, 1f );
minecraft.getItemRenderer().renderArmFirstPerson( equipProgress, swingProgress, side );
GlStateManager.rotatef( offset * 10f, 0f, 0f, 1f );
minecraft.getFirstPersonRenderer().renderArmFirstPerson( equipProgress, swingProgress, side );
GlStateManager.popMatrix();
}
// Setup the appropriate transformations. This is just copied from the
// corresponding method in ItemRenderer.
GlStateManager.pushMatrix();
GlStateManager.translate( offset * 0.51f, -0.08f + equipProgress * -1.2f, -0.75f );
GlStateManager.translatef( offset * 0.51f, -0.08f + equipProgress * -1.2f, -0.75f );
float f1 = MathHelper.sqrt( swingProgress );
float f2 = MathHelper.sin( f1 * (float) Math.PI );
float f3 = -0.5f * f2;
float f4 = 0.4f * MathHelper.sin( f1 * ((float) Math.PI * 2f) );
float f5 = -0.3f * MathHelper.sin( swingProgress * (float) Math.PI );
GlStateManager.translate( offset * f3, f4 - 0.3f * f2, f5 );
GlStateManager.rotate( f2 * -45f, 1f, 0f, 0f );
GlStateManager.rotate( offset * f2 * -30f, 0f, 1f, 0f );
GlStateManager.translatef( offset * f3, f4 - 0.3f * f2, f5 );
GlStateManager.rotatef( f2 * -45f, 1f, 0f, 0f );
GlStateManager.rotatef( offset * f2 * -30f, 0f, 1f, 0f );
renderItem( stack );
@@ -87,31 +87,31 @@ 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 equipProgress The equip progress of this item
* @param swingProgress The swing progress of this item
* @param stack The stack to render
* @see ItemRenderer#renderMapFirstPerson(float, float, float)
* @see FirstPersonRenderer#renderMapFirstPerson(float, float, float)
*/
private void renderItemFirstPersonCenter( float pitch, float equipProgress, float swingProgress, ItemStack stack )
{
ItemRenderer itemRenderer = Minecraft.getMinecraft().getItemRenderer();
FirstPersonRenderer renderer = Minecraft.getInstance().getFirstPersonRenderer();
// Setup the appropriate transformations. This is just copied from the
// corresponding method in ItemRenderer.
float swingRt = MathHelper.sqrt( swingProgress );
float tX = -0.2f * MathHelper.sin( swingProgress * (float) Math.PI );
float tZ = -0.4f * MathHelper.sin( swingRt * (float) Math.PI );
GlStateManager.translate( 0f, -tX / 2f, tZ );
float pitchAngle = itemRenderer.getMapAngleFromPitch( pitch );
GlStateManager.translate( 0f, 0.04f + equipProgress * -1.2f + pitchAngle * -0.5f, -0.72f );
GlStateManager.rotate( pitchAngle * -85f, 1f, 0f, 0f );
itemRenderer.renderArms();
GlStateManager.translatef( 0f, -tX / 2f, tZ );
float pitchAngle = renderer.getMapAngleFromPitch( pitch );
GlStateManager.translatef( 0f, 0.04f + equipProgress * -1.2f + pitchAngle * -0.5f, -0.72f );
GlStateManager.rotatef( pitchAngle * -85f, 1f, 0f, 0f );
renderer.renderArms();
float rX = MathHelper.sin( swingRt * (float) Math.PI );
GlStateManager.rotate( rX * 20f, 1f, 0f, 0f );
GlStateManager.scale( 2f, 2f, 2f );
GlStateManager.rotatef( rX * 20f, 1f, 0f, 0f );
GlStateManager.scalef( 2f, 2f, 2f );
renderItem( stack );
}

View File

@@ -6,6 +6,7 @@
package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
@@ -18,23 +19,22 @@ import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderSpecificHandEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import org.lwjgl.opengl.GL11;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.*;
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 = Side.CLIENT )
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class ItemPocketRenderer extends ItemMapLikeRenderer
{
private static final int MARGIN = 2;
@@ -83,19 +83,20 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
GlStateManager.disableDepth();
GlStateManager.disableDepthTest();
GlStateManager.rotate( 180f, 0f, 1f, 0f );
GlStateManager.rotate( 180f, 0f, 0f, 1f );
GlStateManager.scale( 0.5, 0.5, 0.5 );
GlStateManager.rotatef( 180f, 0f, 1f, 0f );
GlStateManager.rotatef( 180f, 0f, 0f, 1f );
GlStateManager.scalef( 0.5f, 0.5f, 0.5f );
double scale = 0.75 / Math.max( width + FRAME * 2, height + FRAME * 2 + LIGHT_HEIGHT );
GlStateManager.scale( scale, scale, 0 );
GlStateManager.translate( -0.5 * width, -0.5 * height, 0 );
GlStateManager.scaled( scale, scale, 0 );
GlStateManager.translated( -0.5 * width, -0.5 * height, 0 );
// Render the main frame
ComputerFamily family = ComputerCraft.Items.pocketComputer.getFamily( stack );
int frameColour = ComputerCraft.Items.pocketComputer.getColour( stack );
ItemPocketComputer item = (ItemPocketComputer) stack.getItem();
ComputerFamily family = item.getFamily();
int frameColour = item.getColour( stack );
renderFrame( family, frameColour, width, height );
// Render the light
@@ -111,7 +112,7 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
else
{
// Otherwise render a plain background
Minecraft.getMinecraft().getTextureManager().bindTexture( BACKGROUND );
Minecraft.getInstance().getTextureManager().bindTexture( BACKGROUND );
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
@@ -122,7 +123,7 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
tessellator.draw();
}
GlStateManager.enableDepth();
GlStateManager.enableDepthTest();
GlStateManager.enableLighting();
GlStateManager.popMatrix();
}
@@ -130,7 +131,7 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
private static void renderFrame( ComputerFamily family, int colour, int width, int height )
{
Minecraft.getMinecraft().getTextureManager().bindTexture( colour != -1
Minecraft.getInstance().getTextureManager().bindTexture( colour != -1
? BACKGROUND_COLOUR
: family == ComputerFamily.Normal ? BACKGROUND_NORMAL : BACKGROUND_ADVANCED
);
@@ -172,7 +173,7 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
private static void renderLight( int colour, int width, int height )
{
GlStateManager.enableBlend();
GlStateManager.disableTexture2D();
GlStateManager.disableTexture();
float r = ((colour >>> 16) & 0xFF) / 255.0f;
float g = ((colour >>> 8) & 0xFF) / 255.0f;
@@ -187,7 +188,7 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
buffer.pos( width - LIGHT_HEIGHT * 2, height + FRAME / 2.0f, 0.0D ).color( r, g, b, 1.0f ).endVertex();
tessellator.draw();
GlStateManager.enableTexture2D();
GlStateManager.enableTexture();
}
private static void renderTerminal( Terminal terminal, boolean greyscale, int width, int height )

View File

@@ -6,15 +6,15 @@
package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.media.items.ItemPrintout;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderItemInFrameEvent;
import net.minecraftforge.client.event.RenderSpecificHandEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH;
@@ -23,9 +23,9 @@ import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAG
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 = Side.CLIENT )
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
{
private static final ItemPrintoutRenderer INSTANCE = new ItemPrintoutRenderer();
@@ -38,10 +38,9 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
public static void onRenderInHand( RenderSpecificHandEvent event )
{
ItemStack stack = event.getItemStack();
if( stack.getItem() != ComputerCraft.Items.printout ) return;
if( !(stack.getItem() instanceof ItemPrintout) ) return;
event.setCanceled( true );
INSTANCE.renderItemFirstPerson( event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack() );
}
@@ -49,13 +48,13 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
protected void renderItem( ItemStack stack )
{
// Setup various transformations. Note that these are partially adapated from the corresponding method
// in ItemRenderer.renderMapFirstPerson
// in FirstPersonRenderer.renderFirstPersonMap
GlStateManager.disableLighting();
GlStateManager.rotate( 180f, 0f, 1f, 0f );
GlStateManager.rotate( 180f, 0f, 0f, 1f );
GlStateManager.scale( 0.42f, 0.42f, -0.42f );
GlStateManager.translate( -0.5f, -0.48f, 0.0f );
GlStateManager.rotatef( 180f, 0f, 1f, 0f );
GlStateManager.rotatef( 180f, 0f, 0f, 1f );
GlStateManager.scalef( 0.42f, 0.42f, -0.42f );
GlStateManager.translatef( -0.5f, -0.48f, 0.0f );
drawPrintout( stack );
@@ -66,17 +65,17 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
public static void onRenderInFrame( RenderItemInFrameEvent event )
{
ItemStack stack = event.getItem();
if( stack.getItem() != ComputerCraft.Items.printout ) return;
if( !(stack.getItem() instanceof ItemPrintout) ) return;
event.setCanceled( true );
GlStateManager.disableLighting();
// Move a little bit forward to ensure we're not clipping with the frame
GlStateManager.translate( 0.0f, 0.0f, -0.001f );
GlStateManager.rotate( 180f, 0f, 0f, 1f );
GlStateManager.scale( 0.95f, 0.95f, -0.95f );
GlStateManager.translate( -0.5f, -0.5f, 0.0f );
GlStateManager.translatef( 0.0f, 0.0f, -0.001f );
GlStateManager.rotatef( 180f, 0f, 0f, 1f );
GlStateManager.scalef( 0.95f, 0.95f, -0.95f );
GlStateManager.translatef( -0.5f, -0.5f, 0.0f );
drawPrintout( stack );
@@ -87,7 +86,7 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
private static void drawPrintout( ItemStack stack )
{
int pages = ItemPrintout.getPageCount( stack );
boolean book = ItemPrintout.getType( stack ) == ItemPrintout.Type.Book;
boolean book = ((ItemPrintout) stack.getItem()).getType() == ItemPrintout.Type.BOOK;
double width = LINE_MAX_LENGTH * FONT_WIDTH + X_TEXT_MARGIN * 2;
double height = LINES_PER_PAGE * FONT_HEIGHT + Y_TEXT_MARGIN * 2;
@@ -108,8 +107,8 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
// Scale the printout to fit correctly.
double scale = 1.0 / max;
GlStateManager.scale( scale, scale, scale );
GlStateManager.translate( (max - width) / 2.0f, (max - height) / 2.0f, 0.0f );
GlStateManager.scaled( scale, scale, scale );
GlStateManager.translated( (max - width) / 2.0, (max - height) / 2.0, 0.0 );
drawBorder( 0, 0, -0.01, 0, pages, book );
drawText( X_TEXT_MARGIN, Y_TEXT_MARGIN, 0, ItemPrintout.getText( stack ), ItemPrintout.getColours( stack ) );

View File

@@ -6,10 +6,10 @@
package dan200.computercraft.client.render;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
import net.minecraftforge.client.model.pipeline.LightUtil;
import net.minecraftforge.client.model.pipeline.VertexTransformer;
@@ -102,7 +102,7 @@ public final class ModelTransformer
}
@Override
public void setQuadOrientation( @Nonnull EnumFacing orientation )
public void setQuadOrientation( @Nonnull Direction orientation )
{
super.setQuadOrientation( orientation == null ? orientation : TRSRTransformation.rotate( positionMatrix, orientation ) );
}
@@ -187,7 +187,7 @@ public final class ModelTransformer
private final int[] vertexData;
private int vertexIndex = 0, elementIndex = 0;
private EnumFacing orientation;
private Direction orientation;
private int quadTint;
private boolean diffuse;
private TextureAtlasSprite texture;
@@ -212,7 +212,7 @@ public final class ModelTransformer
}
@Override
public void setQuadOrientation( @Nonnull EnumFacing orientation )
public void setQuadOrientation( @Nonnull Direction orientation )
{
this.orientation = orientation;
}

View File

@@ -6,29 +6,31 @@
package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import org.lwjgl.opengl.GL11;
import java.util.EnumSet;
import static net.minecraft.util.EnumFacing.*;
import static net.minecraft.util.Direction.*;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class MonitorHighlightRenderer
{
private static final float EXPAND = 0.002f;
@@ -40,12 +42,13 @@ public final class MonitorHighlightRenderer
@SubscribeEvent
public static void drawHighlight( DrawBlockHighlightEvent event )
{
if( event.getTarget().typeOfHit != RayTraceResult.Type.BLOCK || event.getPlayer().isSneaking() ) return;
if( event.getTarget().getType() != RayTraceResult.Type.BLOCK || event.getInfo().getRenderViewEntity().isSneaking() )
{
return;
}
World world = event.getPlayer().getEntityWorld();
BlockPos pos = event.getTarget().getBlockPos();
if( world.getBlockState( pos ).getBlock() != ComputerCraft.Blocks.peripheral ) return;
World world = event.getInfo().getRenderViewEntity().getEntityWorld();
BlockPos pos = ((BlockRayTraceResult) event.getTarget()).getPos();
TileEntity tile = world.getTileEntity( pos );
if( !(tile instanceof TileMonitor) ) return;
@@ -54,8 +57,8 @@ public final class MonitorHighlightRenderer
event.setCanceled( true );
// Determine which sides are part of the external faces of the monitor, and so which need to be rendered.
EnumSet<EnumFacing> faces = EnumSet.allOf( EnumFacing.class );
EnumFacing front = monitor.getFront();
EnumSet<Direction> faces = EnumSet.allOf( Direction.class );
Direction front = monitor.getFront();
faces.remove( front );
if( monitor.getXIndex() != 0 ) faces.remove( monitor.getRight().getOpposite() );
if( monitor.getXIndex() != monitor.getWidth() - 1 ) faces.remove( monitor.getRight() );
@@ -63,18 +66,14 @@ public final class MonitorHighlightRenderer
if( monitor.getYIndex() != monitor.getHeight() - 1 ) faces.remove( monitor.getDown() );
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO );
GL11.glLineWidth( 2.0F );
GlStateManager.disableTexture2D();
GlStateManager.blendFuncSeparate( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO );
GlStateManager.lineWidth( Math.max( 2.5F, (float) Minecraft.getInstance().mainWindow.getFramebufferWidth() / 1920.0F * 2.5F ) );
GlStateManager.disableTexture();
GlStateManager.depthMask( false );
GlStateManager.pushMatrix();
EntityPlayer player = event.getPlayer();
double x = player.lastTickPosX + (player.posX - player.lastTickPosX) * event.getPartialTicks();
double y = player.lastTickPosY + (player.posY - player.lastTickPosY) * event.getPartialTicks();
double z = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * event.getPartialTicks();
GlStateManager.translate( -x + pos.getX(), -y + pos.getY(), -z + pos.getZ() );
Vec3d cameraPos = event.getInfo().getProjectedView();
GlStateManager.translated( pos.getX() - cameraPos.getX(), pos.getY() - cameraPos.getY(), pos.getZ() - cameraPos.getZ() );
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
@@ -98,11 +97,11 @@ public final class MonitorHighlightRenderer
GlStateManager.popMatrix();
GlStateManager.depthMask( true );
GlStateManager.enableTexture2D();
GlStateManager.enableTexture();
GlStateManager.disableBlend();
}
private static void line( BufferBuilder buffer, int x, int y, int z, EnumFacing direction )
private static void line( BufferBuilder buffer, int x, int y, int z, Direction direction )
{
double minX = x == 0 ? -EXPAND : 1 + EXPAND;
double minY = y == 0 ? -EXPAND : 1 + EXPAND;

View File

@@ -6,14 +6,14 @@
package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
import com.mojang.blaze3d.platform.GlStateManager.SourceFactor;
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GlStateManager.DestFactor;
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
@@ -28,32 +28,32 @@ public final class PrintoutRenderer
private static final double BG_SIZE = 256.0;
/**
* Width of a page.
* Width of a page
*/
public static final int X_SIZE = 172;
/**
* Height of a page.
* Height of a page
*/
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;
/**
* 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;
/**
* Width of the extra page texture.
* Width of the extra page texture
*/
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;
@@ -74,10 +74,10 @@ public final class PrintoutRenderer
public static void drawText( int x, int y, int start, String[] text, String[] colours )
{
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.enableBlend();
GlStateManager.enableTexture2D();
GlStateManager.tryBlendFuncSeparate( SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO );
GlStateManager.enableTexture();
GlStateManager.blendFuncSeparate( SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO );
FixedWidthFontRenderer fontRenderer = FixedWidthFontRenderer.instance();
@@ -89,12 +89,12 @@ public final class PrintoutRenderer
public static void drawBorder( double x, double y, double z, int page, int pages, boolean isBook )
{
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.enableBlend();
GlStateManager.enableTexture2D();
GlStateManager.tryBlendFuncSeparate( SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO );
GlStateManager.enableTexture();
GlStateManager.blendFuncSeparate( SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO );
Minecraft.getMinecraft().getTextureManager().bindTexture( BG );
Minecraft.getInstance().getTextureManager().bindTexture( BG );
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();

View File

@@ -6,86 +6,94 @@
package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.modem.wired.BlockCable;
import dan200.computercraft.shared.peripheral.modem.wired.BlockCableModemVariant;
import dan200.computercraft.shared.peripheral.modem.wired.CableBounds;
import dan200.computercraft.shared.peripheral.modem.wired.CableModemVariant;
import dan200.computercraft.shared.peripheral.modem.wired.CableShapes;
import dan200.computercraft.shared.peripheral.modem.wired.TileCable;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.client.model.data.EmptyModelData;
import org.lwjgl.opengl.GL11;
import javax.annotation.Nonnull;
import java.util.Random;
/**
* Render breaking animation only over part of a {@link TileCable}.
*/
public class TileEntityCableRenderer extends TileEntitySpecialRenderer<TileCable>
public class TileEntityCableRenderer extends TileEntityRenderer<TileCable>
{
private static final ResourceLocation[] DESTROY_STAGES = new ResourceLocation[10];
private static final Random random = new Random();
static
{
for( int i = 0; i < DESTROY_STAGES.length; i++ )
{
DESTROY_STAGES[i] = new ResourceLocation( "block/destroy_stage_" + i );
}
}
@Override
public void render( @Nonnull TileCable te, double x, double y, double z, float partialTicks, int destroyStage, float alpha )
public void render( @Nonnull TileCable te, double x, double y, double z, float partialTicks, int destroyStage )
{
if( destroyStage < 0 ) return;
BlockPos pos = te.getPos();
Minecraft mc = Minecraft.getMinecraft();
Minecraft mc = Minecraft.getInstance();
RayTraceResult hit = mc.objectMouseOver;
if( hit == null || !hit.getBlockPos().equals( pos ) ) return;
if( MinecraftForgeClient.getRenderPass() != 0 ) return;
if( hit == null || hit.getType() != RayTraceResult.Type.BLOCK || !((BlockRayTraceResult) hit).getPos().equals( pos ) )
{
return;
}
World world = te.getWorld();
IBlockState state = world.getBlockState( pos );
BlockState state = world.getBlockState( pos );
Block block = state.getBlock();
if( block != ComputerCraft.Blocks.cable ) return;
state = state.getActualState( world, pos );
if( te.getPeripheralType() != PeripheralType.Cable && WorldUtil.isVecInsideInclusive( CableBounds.getModemBounds( state ), hit.hitVec.subtract( pos.getX(), pos.getY(), pos.getZ() ) ) )
{
state = block.getDefaultState().withProperty( BlockCable.MODEM, state.getValue( BlockCable.MODEM ) );
}
else
{
state = state.withProperty( BlockCable.MODEM, BlockCableModemVariant.None );
}
state = WorldUtil.isVecInside( CableShapes.getModemShape( state ), hit.getHitVec().subtract( pos.getX(), pos.getY(), pos.getZ() ) )
? block.getDefaultState().with( BlockCable.MODEM, state.get( BlockCable.MODEM ) )
: state.with( BlockCable.MODEM, CableModemVariant.None );
IBakedModel model = mc.getBlockRendererDispatcher().getModelForState( state );
if( model == null ) return;
preRenderDamagedBlocks();
ForgeHooksClient.setRenderLayer( block.getRenderLayer() );
// See BlockRendererDispatcher#renderBlockDamage
TextureAtlasSprite breakingTexture = mc.getTextureMap().getSprite( DESTROY_STAGES[destroyStage] );
BufferBuilder buffer = Tessellator.getInstance().getBuffer();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.BLOCK );
buffer.setTranslation( x - pos.getX(), y - pos.getY(), z - pos.getZ() );
buffer.noColor();
ForgeHooksClient.setRenderLayer( block.getRenderLayer() );
// See BlockRendererDispatcher#renderBlockDamage
TextureAtlasSprite breakingTexture = mc.getTextureMapBlocks().getAtlasSprite( "minecraft:blocks/destroy_stage_" + destroyStage );
Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelRenderer().renderModel(
mc.getBlockRendererDispatcher().getBlockModelRenderer().renderModel(
world,
ForgeHooksClient.getDamageModel( model, breakingTexture, state, world, pos ),
state, pos, buffer, true
ForgeHooksClient.getDamageModel( model, breakingTexture, state, world, pos, 0 ),
state, pos, buffer, true, random, state.getPositionRandom( pos ), EmptyModelData.INSTANCE
);
ForgeHooksClient.setRenderLayer( BlockRenderLayer.SOLID );
@@ -97,34 +105,30 @@ public class TileEntityCableRenderer extends TileEntitySpecialRenderer<TileCable
}
/**
* Set up the state for rendering block-breaking progress.
*
* @see RenderGlobal#preRenderDamagedBlocks()
* @see WorldRenderer#preRenderDamagedBlocks()
*/
private void preRenderDamagedBlocks()
{
GlStateManager.disableLighting();
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate( GlStateManager.SourceFactor.DST_COLOR, GlStateManager.DestFactor.SRC_COLOR, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO );
GlStateManager.blendFuncSeparate( GlStateManager.SourceFactor.DST_COLOR, GlStateManager.DestFactor.SRC_COLOR, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO );
GlStateManager.enableBlend();
GlStateManager.color( 1.0F, 1.0F, 1.0F, 0.5F );
GlStateManager.doPolygonOffset( -3.0F, -3.0F );
GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 0.5F );
GlStateManager.polygonOffset( -3.0F, -3.0F );
GlStateManager.enablePolygonOffset();
GlStateManager.alphaFunc( 516, 0.1F );
GlStateManager.enableAlpha();
GlStateManager.enableAlphaTest();
GlStateManager.pushMatrix();
}
/**
* Tear down the state for rendering block-breaking progress.
*
* @see RenderGlobal#postRenderDamagedBlocks()
* @see WorldRenderer#postRenderDamagedBlocks()
*/
private void postRenderDamagedBlocks()
{
GlStateManager.disableAlpha();
GlStateManager.doPolygonOffset( 0.0F, 0.0F );
GlStateManager.disableAlphaTest();
GlStateManager.polygonOffset( 0.0F, 0.0F );
GlStateManager.disablePolygonOffset();
GlStateManager.disablePolygonOffset();
GlStateManager.depthMask( true );

View File

@@ -6,6 +6,8 @@
package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GLX;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
import dan200.computercraft.core.terminal.Terminal;
@@ -17,19 +19,17 @@ import dan200.computercraft.shared.util.DirectionUtil;
import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import org.lwjgl.opengl.GL11;
public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMonitor>
public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
{
@Override
public void render( TileMonitor tileEntity, double posX, double posY, double posZ, float f, int i, float f2 )
public void render( TileMonitor tileEntity, double posX, double posY, double posZ, float f, int i )
{
if( tileEntity != null )
{
@@ -64,8 +64,8 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
posZ += originPos.getZ() - monitorPos.getZ();
// Determine orientation
EnumFacing dir = origin.getDirection();
EnumFacing front = origin.getFront();
Direction dir = origin.getDirection();
Direction front = origin.getFront();
float yaw = dir.getHorizontalAngle();
float pitch = DirectionUtil.toPitchAngle( front );
@@ -73,19 +73,19 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
try
{
// Setup initial transform
GlStateManager.translate( posX + 0.5, posY + 0.5, posZ + 0.5 );
GlStateManager.rotate( -yaw, 0.0f, 1.0f, 0.0f );
GlStateManager.rotate( pitch, 1.0f, 0.0f, 0.0f );
GlStateManager.translate(
GlStateManager.translated( posX + 0.5, posY + 0.5, posZ + 0.5 );
GlStateManager.rotatef( -yaw, 0.0f, 1.0f, 0.0f );
GlStateManager.rotatef( pitch, 1.0f, 0.0f, 0.0f );
GlStateManager.translated(
-0.5 + TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN,
origin.getHeight() - 0.5 - (TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN),
origin.getHeight() - 0.5 - (TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN) + 0,
0.5
);
double xSize = origin.getWidth() - 2.0 * (TileMonitor.RENDER_MARGIN + TileMonitor.RENDER_BORDER);
double ySize = origin.getHeight() - 2.0 * (TileMonitor.RENDER_MARGIN + TileMonitor.RENDER_BORDER);
// Get renderers
Minecraft mc = Minecraft.getMinecraft();
Minecraft mc = Minecraft.getInstance();
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder renderer = tessellator.getBuffer();
@@ -94,9 +94,9 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
// Draw the contents
GlStateManager.depthMask( false );
OpenGlHelper.setLightmapTextureCoords( OpenGlHelper.lightmapTexUnit, 0xFF, 0xFF );
GLX.glMultiTexCoord2f( GLX.GL_TEXTURE1, 0xFFFF, 0xFFFF );
GlStateManager.disableLighting();
mc.entityRenderer.disableLightmap();
mc.gameRenderer.disableLightmap();
try
{
Terminal terminal = originTerminal.getTerminal();
@@ -124,14 +124,14 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
{
double xScale = xSize / (width * FixedWidthFontRenderer.FONT_WIDTH);
double yScale = ySize / (height * FixedWidthFontRenderer.FONT_HEIGHT);
GlStateManager.scale( xScale, -yScale, 1.0 );
GlStateManager.scaled( xScale, -yScale, 1.0 );
// Draw background
mc.getTextureManager().bindTexture( FixedWidthFontRenderer.BACKGROUND );
if( redraw )
{
// Build background display list
GlStateManager.glNewList( originTerminal.renderDisplayLists[0], GL11.GL_COMPILE );
GlStateManager.newList( originTerminal.renderDisplayLists[0], GL11.GL_COMPILE );
try
{
double marginXSize = TileMonitor.RENDER_MARGIN / xScale;
@@ -142,10 +142,10 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
GlStateManager.pushMatrix();
try
{
GlStateManager.scale( 1.0, marginSquash, 1.0 );
GlStateManager.translate( 0.0, -marginYSize / marginSquash, 0.0 );
GlStateManager.scaled( 1.0, marginSquash, 1.0 );
GlStateManager.translated( 0.0, -marginYSize / marginSquash, 0.0 );
fontRenderer.drawStringBackgroundPart( 0, 0, terminal.getBackgroundColourLine( 0 ), marginXSize, marginXSize, greyscale, palette );
GlStateManager.translate( 0.0, (marginYSize + height * FixedWidthFontRenderer.FONT_HEIGHT) / marginSquash, 0.0 );
GlStateManager.translated( 0.0, (marginYSize + height * FixedWidthFontRenderer.FONT_HEIGHT) / marginSquash, 0.0 );
fontRenderer.drawStringBackgroundPart( 0, 0, terminal.getBackgroundColourLine( height - 1 ), marginXSize, marginXSize, greyscale, palette );
}
finally
@@ -167,18 +167,18 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
}
finally
{
GlStateManager.glEndList();
GlStateManager.endList();
}
}
GlStateManager.callList( originTerminal.renderDisplayLists[0] );
GlStateManager.resetColor();
GlStateManager.clearCurrentColor();
// Draw text
fontRenderer.bindFont();
if( redraw )
{
// Build text display list
GlStateManager.glNewList( originTerminal.renderDisplayLists[1], GL11.GL_COMPILE );
GlStateManager.newList( originTerminal.renderDisplayLists[1], GL11.GL_COMPILE );
try
{
// Lines
@@ -195,18 +195,18 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
}
finally
{
GlStateManager.glEndList();
GlStateManager.endList();
}
}
GlStateManager.callList( originTerminal.renderDisplayLists[1] );
GlStateManager.resetColor();
GlStateManager.clearCurrentColor();
// Draw cursor
fontRenderer.bindFont();
if( redraw )
{
// Build cursor display list
GlStateManager.glNewList( originTerminal.renderDisplayLists[2], GL11.GL_COMPILE );
GlStateManager.newList( originTerminal.renderDisplayLists[2], GL11.GL_COMPILE );
try
{
// Cursor
@@ -227,13 +227,13 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
}
finally
{
GlStateManager.glEndList();
GlStateManager.endList();
}
}
if( FrameInfo.getGlobalCursorBlink() )
{
GlStateManager.callList( originTerminal.renderDisplayLists[2] );
GlStateManager.resetColor();
GlStateManager.clearCurrentColor();
}
}
finally
@@ -262,7 +262,7 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
finally
{
GlStateManager.depthMask( true );
mc.entityRenderer.enableLightmap();
mc.gameRenderer.enableLightmap();
GlStateManager.enableLighting();
}
@@ -285,7 +285,7 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
}
finally
{
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.popMatrix();
}
}

View File

@@ -6,46 +6,51 @@
package dan200.computercraft.client.render;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.util.DirectionUtil;
import dan200.computercraft.shared.util.Holiday;
import dan200.computercraft.shared.util.HolidayUtil;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ModelManager;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.ModelManager;
import net.minecraft.client.renderer.model.ModelResourceLocation;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.pipeline.LightUtil;
import org.apache.commons.lang3.tuple.Pair;
import org.lwjgl.opengl.GL11;
import javax.vecmath.Matrix4f;
import java.util.List;
import java.util.Random;
public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurtle>
public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
{
private static final ModelResourceLocation NORMAL_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle", "inventory" );
private static final ModelResourceLocation NORMAL_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_normal", "inventory" );
private static final ModelResourceLocation ADVANCED_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_advanced", "inventory" );
private static final ModelResourceLocation COLOUR_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_white", "inventory" );
private static final ModelResourceLocation COLOUR_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_colour", "inventory" );
private static final ModelResourceLocation ELF_OVERLAY_MODEL = new ModelResourceLocation( "computercraft:turtle_elf_overlay", "inventory" );
@Override
public void render( TileTurtle tileEntity, double posX, double posY, double posZ, float partialTicks, int breaking, float f2 )
public void render( TileTurtle tileEntity, double posX, double posY, double posZ, float partialTicks, int breaking )
{
if( tileEntity != null ) renderTurtleAt( tileEntity, posX, posY, posZ, partialTicks );
}
@@ -82,13 +87,14 @@ public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurt
{
// Render the label
String label = turtle.createProxy().getLabel();
if( label != null && rendererDispatcher.cameraHitResult != null && turtle.getPos().equals( rendererDispatcher.cameraHitResult.getBlockPos() ) )
RayTraceResult hit = rendererDispatcher.cameraHitResult;
if( label != null && hit.getType() == RayTraceResult.Type.BLOCK && turtle.getPos().equals( ((BlockRayTraceResult) hit).getPos() ) )
{
setLightmapDisabled( true );
EntityRenderer.drawNameplate(
GameRenderer.drawNameplate(
getFontRenderer(), label,
(float) posX + 0.5F, (float) posY + 1.2F, (float) posZ + 0.5F, 0,
rendererDispatcher.entityYaw, rendererDispatcher.entityPitch, false, false
rendererDispatcher.renderInfo.getYaw(), rendererDispatcher.renderInfo.getPitch(), false
);
setLightmapDisabled( false );
}
@@ -96,22 +102,21 @@ public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurt
GlStateManager.pushMatrix();
try
{
IBlockState state = turtle.getWorld().getBlockState( turtle.getPos() );
BlockState state = turtle.getBlockState();
// Setup the transform
Vec3d offset = turtle.getRenderOffset( partialTicks );
float yaw = turtle.getRenderYaw( partialTicks );
GlStateManager.translate( posX + offset.x, posY + offset.y, posZ + offset.z );
GlStateManager.translated( posX + offset.x, posY + offset.y, posZ + offset.z );
// Render the turtle
GlStateManager.translate( 0.5f, 0.5f, 0.5f );
GlStateManager.rotate( 180.0f - yaw, 0.0f, 1.0f, 0.0f );
GlStateManager.translatef( 0.5f, 0.5f, 0.5f );
GlStateManager.rotatef( 180.0f - yaw, 0.0f, 1.0f, 0.0f );
if( label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" )) )
{
// Flip the model and swap the cull face as winding order will have changed.
GlStateManager.scale( 1.0f, -1.0f, 1.0f );
GlStateManager.scalef( 1.0f, -1.0f, 1.0f );
GlStateManager.cullFace( GlStateManager.CullFace.FRONT );
}
GlStateManager.translate( -0.5f, -0.5f, -0.5f );
GlStateManager.translatef( -0.5f, -0.5f, -0.5f );
// Render the turtle
int colour = turtle.getColour();
ComputerFamily family = turtle.getFamily();
@@ -151,7 +156,7 @@ public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurt
}
}
private static void renderUpgrade( IBlockState state, TileTurtle turtle, TurtleSide side, float f )
private void renderUpgrade( BlockState state, TileTurtle turtle, TurtleSide side, float f )
{
ITurtleUpgrade upgrade = turtle.getUpgrade( side );
if( upgrade != null )
@@ -160,9 +165,9 @@ public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurt
try
{
float toolAngle = turtle.getToolRenderAngle( side, f );
GlStateManager.translate( 0.0f, 0.5f, 0.5f );
GlStateManager.rotate( -toolAngle, 1.0f, 0.0f, 0.0f );
GlStateManager.translate( 0.0f, -0.5f, -0.5f );
GlStateManager.translatef( 0.0f, 0.5f, 0.5f );
GlStateManager.rotatef( -toolAngle, 1.0f, 0.0f, 0.0f );
GlStateManager.translatef( 0.0f, -0.5f, -0.5f );
Pair<IBakedModel, Matrix4f> pair = upgrade.getModel( turtle.getAccess(), side );
if( pair != null )
@@ -184,22 +189,22 @@ public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurt
}
}
private static void renderModel( IBlockState state, ModelResourceLocation modelLocation, int[] tints )
private void renderModel( BlockState state, ModelResourceLocation modelLocation, int[] tints )
{
Minecraft mc = Minecraft.getMinecraft();
ModelManager modelManager = mc.getRenderItem().getItemModelMesher().getModelManager();
Minecraft mc = Minecraft.getInstance();
ModelManager modelManager = mc.getItemRenderer().getItemModelMesher().getModelManager();
renderModel( state, modelManager.getModel( modelLocation ), tints );
}
private static void renderModel( IBlockState state, IBakedModel model, int[] tints )
private void renderModel( BlockState state, IBakedModel model, int[] tints )
{
Minecraft mc = Minecraft.getMinecraft();
Random random = new Random( 0 );
Tessellator tessellator = Tessellator.getInstance();
mc.getTextureManager().bindTexture( TextureMap.LOCATION_BLOCKS_TEXTURE );
renderQuads( tessellator, model.getQuads( state, null, 0 ), tints );
for( EnumFacing facing : EnumFacing.VALUES )
rendererDispatcher.textureManager.bindTexture( AtlasTexture.LOCATION_BLOCKS_TEXTURE );
renderQuads( tessellator, model.getQuads( state, null, random, EmptyModelData.INSTANCE ), tints );
for( Direction facing : DirectionUtil.FACINGS )
{
renderQuads( tessellator, model.getQuads( state, facing, 0 ), tints );
renderQuads( tessellator, model.getQuads( state, facing, random, EmptyModelData.INSTANCE ), tints );
}
}

View File

@@ -6,26 +6,29 @@
package dan200.computercraft.client.render;
import com.google.common.collect.ImmutableMap;
import dan200.computercraft.ComputerCraft;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.IUnbakedModel;
import net.minecraft.client.renderer.model.ModelBakery;
import net.minecraft.client.renderer.texture.ISprite;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.ICustomModelLoader;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.common.model.IModelState;
import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
public final class TurtleModelLoader implements ICustomModelLoader
{
private static final ResourceLocation NORMAL_TURTLE_MODEL = new ResourceLocation( ComputerCraft.MOD_ID, "block/turtle" );
private static final ResourceLocation ADVANCED_TURTLE_MODEL = new ResourceLocation( ComputerCraft.MOD_ID, "block/advanced_turtle" );
private static final ResourceLocation COLOUR_TURTLE_MODEL = new ResourceLocation( ComputerCraft.MOD_ID, "block/turtle_white" );
private static final ResourceLocation NORMAL_TURTLE_MODEL = new ResourceLocation( ComputerCraft.MOD_ID, "block/turtle_normal" );
private static final ResourceLocation ADVANCED_TURTLE_MODEL = new ResourceLocation( ComputerCraft.MOD_ID, "block/turtle_advanced" );
private static final ResourceLocation COLOUR_TURTLE_MODEL = new ResourceLocation( ComputerCraft.MOD_ID, "block/turtle_colour" );
public static final TurtleModelLoader INSTANCE = new TurtleModelLoader();
@@ -42,80 +45,60 @@ public final class TurtleModelLoader implements ICustomModelLoader
public boolean accepts( @Nonnull ResourceLocation name )
{
return name.getNamespace().equals( ComputerCraft.MOD_ID )
&& (name.getPath().equals( "turtle" ) || name.getPath().equals( "turtle_advanced" ));
&& (name.getPath().equals( "item/turtle_normal" ) || name.getPath().equals( "item/turtle_advanced" ));
}
@Nonnull
@Override
public IModel loadModel( @Nonnull ResourceLocation name ) throws Exception
public IUnbakedModel loadModel( @Nonnull ResourceLocation name )
{
if( name.getNamespace().equals( ComputerCraft.MOD_ID ) )
{
IModel colourModel = ModelLoaderRegistry.getModel( COLOUR_TURTLE_MODEL );
switch( name.getPath() )
{
case "turtle":
return new TurtleModel( ModelLoaderRegistry.getModel( NORMAL_TURTLE_MODEL ), colourModel );
case "turtle_advanced":
return new TurtleModel( ModelLoaderRegistry.getModel( ADVANCED_TURTLE_MODEL ), colourModel );
case "item/turtle_normal":
return new TurtleModel( NORMAL_TURTLE_MODEL );
case "item/turtle_advanced":
return new TurtleModel( ADVANCED_TURTLE_MODEL );
}
}
throw new IllegalStateException( "Loader does not accept " + name );
}
private static final class TurtleModel implements IModel
private static final class TurtleModel implements IUnbakedModel
{
private final IModel family;
private final IModel colour;
private final ResourceLocation family;
private TurtleModel( IModel family, IModel colour )
private TurtleModel( ResourceLocation family )
{
this.family = family;
this.colour = colour;
}
@Nonnull
@Override
public IBakedModel bake( @Nonnull IModelState state, @Nonnull VertexFormat format, @Nonnull Function<ResourceLocation, TextureAtlasSprite> function )
public Collection<ResourceLocation> getDependencies()
{
return Arrays.asList( family, COLOUR_TURTLE_MODEL );
}
@Nonnull
@Override
public Collection<ResourceLocation> getTextures( @Nonnull Function<ResourceLocation, IUnbakedModel> modelGetter, @Nonnull Set<String> missingTextureErrors )
{
return getDependencies().stream()
.flatMap( x -> modelGetter.apply( x ).getTextures( modelGetter, missingTextureErrors ).stream() )
.collect( Collectors.toSet() );
}
@Nonnull
@Override
public IBakedModel bake( @Nonnull ModelBakery bakery, @Nonnull Function<ResourceLocation, TextureAtlasSprite> spriteGetter, @Nonnull ISprite sprite, @Nonnull VertexFormat format )
{
return new TurtleSmartItemModel(
family.bake( state, format, function ),
colour.bake( state, format, function )
bakery.getBakedModel( family, sprite, spriteGetter, format ),
bakery.getBakedModel( COLOUR_TURTLE_MODEL, sprite, spriteGetter, format )
);
}
private TurtleModel copy( IModel family, IModel colour )
{
return this.family == family && this.colour == colour ? this : new TurtleModel( family, colour );
}
@Nonnull
@Override
public IModel smoothLighting( boolean value )
{
return copy( family.smoothLighting( value ), colour.smoothLighting( value ) );
}
@Nonnull
@Override
public IModel gui3d( boolean value )
{
return copy( family.gui3d( value ), colour.gui3d( value ) );
}
@Nonnull
@Override
public IModel uvlock( boolean value )
{
return copy( family.uvlock( value ), colour.uvlock( value ) );
}
@Nonnull
@Override
public IModel retexture( ImmutableMap<String, String> textures )
{
return copy( family.retexture( textures ), colour.retexture( textures ) );
}
}
}

View File

@@ -6,20 +6,18 @@
package dan200.computercraft.client.render;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.block.model.ItemOverrideList;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.ItemOverrideList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import javax.annotation.Nonnull;
import javax.vecmath.Matrix4f;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.*;
public class TurtleMultiModel implements IBakedModel
{
@@ -31,7 +29,7 @@ public class TurtleMultiModel implements IBakedModel
private final IBakedModel m_rightUpgradeModel;
private final Matrix4f m_rightUpgradeTransform;
private List<BakedQuad> m_generalQuads = null;
private Map<EnumFacing, List<BakedQuad>> m_faceQuads = new EnumMap<>( EnumFacing.class );
private Map<Direction, List<BakedQuad>> m_faceQuads = new EnumMap<>( Direction.class );
public TurtleMultiModel( IBakedModel baseModel, IBakedModel overlayModel, Matrix4f generalTransform, IBakedModel leftUpgradeModel, Matrix4f leftUpgradeTransform, IBakedModel rightUpgradeModel, Matrix4f rightUpgradeTransform )
{
@@ -47,7 +45,15 @@ public class TurtleMultiModel implements IBakedModel
@Nonnull
@Override
public List<BakedQuad> getQuads( IBlockState state, EnumFacing side, long rand )
@Deprecated
public List<BakedQuad> getQuads( BlockState state, Direction side, @Nonnull Random rand )
{
return getQuads( state, side, rand, EmptyModelData.INSTANCE );
}
@Nonnull
@Override
public List<BakedQuad> getQuads( BlockState state, Direction side, @Nonnull Random rand, @Nonnull IModelData data )
{
if( side != null )
{
@@ -61,17 +67,13 @@ public class TurtleMultiModel implements IBakedModel
}
}
private List<BakedQuad> buildQuads( IBlockState state, EnumFacing side, long rand )
private List<BakedQuad> buildQuads( BlockState state, Direction side, Random rand )
{
ArrayList<BakedQuad> quads = new ArrayList<>();
ModelTransformer.transformQuadsTo( quads, m_baseModel.getQuads( state, side, rand ), m_generalTransform );
ModelTransformer.transformQuadsTo( quads, m_baseModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), m_generalTransform );
if( m_overlayModel != null )
{
ModelTransformer.transformQuadsTo( quads, m_overlayModel.getQuads( state, side, rand ), m_generalTransform );
}
if( m_overlayModel != null )
{
ModelTransformer.transformQuadsTo( quads, m_overlayModel.getQuads( state, side, rand ), m_generalTransform );
ModelTransformer.transformQuadsTo( quads, m_overlayModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), m_generalTransform );
}
if( m_leftUpgradeModel != null )
{
@@ -81,7 +83,7 @@ public class TurtleMultiModel implements IBakedModel
upgradeTransform = new Matrix4f( m_generalTransform );
upgradeTransform.mul( m_leftUpgradeTransform );
}
ModelTransformer.transformQuadsTo( quads, m_leftUpgradeModel.getQuads( state, side, rand ), upgradeTransform );
ModelTransformer.transformQuadsTo( quads, m_leftUpgradeModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
}
if( m_rightUpgradeModel != null )
{
@@ -91,7 +93,7 @@ public class TurtleMultiModel implements IBakedModel
upgradeTransform = new Matrix4f( m_generalTransform );
upgradeTransform.mul( m_rightUpgradeTransform );
}
ModelTransformer.transformQuadsTo( quads, m_rightUpgradeModel.getQuads( state, side, rand ), upgradeTransform );
ModelTransformer.transformQuadsTo( quads, m_rightUpgradeModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
}
quads.trimToSize();
return quads;
@@ -117,6 +119,7 @@ public class TurtleMultiModel implements IBakedModel
@Nonnull
@Override
@Deprecated
public TextureAtlasSprite getParticleTexture()
{
return m_baseModel.getParticleTexture();
@@ -125,7 +128,7 @@ public class TurtleMultiModel implements IBakedModel
@Nonnull
@Override
@Deprecated
public ItemCameraTransforms getItemCameraTransforms()
public net.minecraft.client.renderer.model.ItemCameraTransforms getItemCameraTransforms()
{
return m_baseModel.getItemCameraTransforms();
}
@@ -134,6 +137,6 @@ public class TurtleMultiModel implements IBakedModel
@Override
public ItemOverrideList getOverrides()
{
return ItemOverrideList.NONE;
return ItemOverrideList.EMPTY;
}
}

View File

@@ -9,26 +9,27 @@ package dan200.computercraft.client.render;
import com.google.common.base.Objects;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.shared.turtle.items.ItemTurtleBase;
import dan200.computercraft.shared.turtle.items.ItemTurtle;
import dan200.computercraft.shared.util.Holiday;
import dan200.computercraft.shared.util.HolidayUtil;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.*;
import net.minecraft.client.renderer.model.*;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.client.model.data.IModelData;
import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
public class TurtleSmartItemModel implements IBakedModel
{
@@ -106,13 +107,13 @@ public class TurtleSmartItemModel implements IBakedModel
this.colourModel = colourModel;
m_cachedModels = new HashMap<>();
m_overrides = new ItemOverrideList( new ArrayList<>() )
m_overrides = new ItemOverrideList()
{
@Nonnull
@Override
public IBakedModel handleItemState( @Nonnull IBakedModel originalModel, @Nonnull ItemStack stack, @Nullable World world, @Nullable EntityLivingBase entity )
public IBakedModel getModelWithOverrides( @Nonnull IBakedModel originalModel, @Nonnull ItemStack stack, @Nullable World world, @Nullable LivingEntity entity )
{
ItemTurtleBase turtle = (ItemTurtleBase) stack.getItem();
ItemTurtle turtle = (ItemTurtle) stack.getItem();
int colour = turtle.getColour( stack );
ITurtleUpgrade leftUpgrade = turtle.getUpgrade( stack, TurtleSide.Left );
ITurtleUpgrade rightUpgrade = turtle.getUpgrade( stack, TurtleSide.Right );
@@ -138,8 +139,8 @@ public class TurtleSmartItemModel implements IBakedModel
private IBakedModel buildModel( TurtleModelCombination combo )
{
Minecraft mc = Minecraft.getMinecraft();
ModelManager modelManager = mc.getRenderItem().getItemModelMesher().getModelManager();
Minecraft mc = Minecraft.getInstance();
ModelManager modelManager = mc.getItemRenderer().getItemModelMesher().getModelManager();
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.m_overlay, combo.m_christmas );
IBakedModel baseModel = combo.m_colour ? colourModel : familyModel;
@@ -167,11 +168,20 @@ public class TurtleSmartItemModel implements IBakedModel
@Nonnull
@Override
public List<BakedQuad> getQuads( IBlockState state, EnumFacing facing, long rand )
@Deprecated
public List<BakedQuad> getQuads( BlockState state, Direction facing, @Nonnull Random rand )
{
return familyModel.getQuads( state, facing, rand );
}
@Nonnull
@Override
@Deprecated
public List<BakedQuad> getQuads( BlockState state, Direction facing, @Nonnull Random rand, @Nonnull IModelData data )
{
return familyModel.getQuads( state, facing, rand, data );
}
@Override
public boolean isAmbientOcclusion()
{
@@ -192,6 +202,7 @@ public class TurtleSmartItemModel implements IBakedModel
@Nonnull
@Override
@Deprecated
public TextureAtlasSprite getParticleTexture()
{
return familyModel.getParticleTexture();

View File

@@ -12,6 +12,7 @@ import dan200.computercraft.ComputerCraft;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
@@ -50,6 +51,11 @@ public class AddressPredicate
private final List<HostRange> ranges;
public AddressPredicate( String... filters )
{
this( Arrays.asList( filters ) );
}
public AddressPredicate( Iterable<? extends String> filters )
{
List<Pattern> wildcards = this.wildcards = new ArrayList<>();
List<HostRange> ranges = this.ranges = new ArrayList<>();
@@ -154,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.
* @return Whether it matches any of these patterns.

View File

@@ -23,7 +23,7 @@ public final class ApiFactories
private static final Collection<ILuaAPIFactory> factories = new LinkedHashSet<>();
private static final Collection<ILuaAPIFactory> factoriesView = Collections.unmodifiableCollection( factories );
public static void register( @Nonnull ILuaAPIFactory factory )
public static synchronized void register( @Nonnull ILuaAPIFactory factory )
{
Objects.requireNonNull( factory, "provider cannot be null" );
factories.add( factory );

View File

@@ -13,106 +13,256 @@ import javax.annotation.Nullable;
import java.util.Map;
/**
* A stub for any mods which depended on this version of the argument helper.
*
* @deprecated Use {@link dan200.computercraft.api.lua.ArgumentHelper}.
* Various helpers for arguments
*/
@Deprecated
public final class ArgumentHelper
{
private ArgumentHelper()
{
throw new IllegalStateException( "Cannot instantiate singleton " + getClass().getName() );
}
@Nonnull
public static String getType( @Nullable Object type )
{
return dan200.computercraft.api.lua.ArgumentHelper.getType( type );
if( type == null ) return "nil";
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
public static LuaException badArgument( int index, @Nonnull String expected, @Nullable Object actual )
{
return dan200.computercraft.api.lua.ArgumentHelper.badArgumentOf( index, expected, actual );
return badArgument( index, expected, getType( actual ) );
}
@Nonnull
public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual )
{
return dan200.computercraft.api.lua.ArgumentHelper.badArgument( index, expected, actual );
return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" );
}
public static double getNumber( @Nonnull Object[] args, int index ) throws LuaException
{
return dan200.computercraft.api.lua.ArgumentHelper.getDouble( args, index );
if( index >= args.length ) throw badArgument( index, "number", "nil" );
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
{
return dan200.computercraft.api.lua.ArgumentHelper.getInt( args, index );
return (int) getLong( args, index );
}
public static long getLong( @Nonnull Object[] args, int index ) throws LuaException
{
return dan200.computercraft.api.lua.ArgumentHelper.getLong( args, index );
if( index >= args.length ) throw badArgument( index, "number", "nil" );
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
{
return dan200.computercraft.api.lua.ArgumentHelper.getFiniteDouble( args, index );
return checkReal( index, getNumber( args, index ) );
}
public static boolean getBoolean( @Nonnull Object[] args, int index ) throws LuaException
{
return dan200.computercraft.api.lua.ArgumentHelper.getBoolean( args, index );
if( index >= args.length ) throw badArgument( index, "boolean", "nil" );
Object value = args[index];
if( value instanceof Boolean )
{
return (Boolean) value;
}
else
{
throw badArgument( index, "boolean", value );
}
}
@Nonnull
public static String getString( @Nonnull Object[] args, int index ) throws LuaException
{
return dan200.computercraft.api.lua.ArgumentHelper.getString( args, index );
if( index >= args.length ) throw badArgument( index, "string", "nil" );
Object value = args[index];
if( value instanceof String )
{
return (String) value;
}
else
{
throw badArgument( index, "string", value );
}
}
@Nonnull
@SuppressWarnings( "unchecked" )
@Nonnull
public static Map<Object, Object> getTable( @Nonnull Object[] args, int index ) throws LuaException
{
return (Map<Object, Object>) dan200.computercraft.api.lua.ArgumentHelper.getTable( args, index );
if( index >= args.length ) throw badArgument( index, "table", "nil" );
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
{
return dan200.computercraft.api.lua.ArgumentHelper.optDouble( args, index, def );
Object value = index < args.length ? args[index] : null;
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
{
return dan200.computercraft.api.lua.ArgumentHelper.optInt( args, index, def );
return (int) optLong( args, index, def );
}
public static long optLong( @Nonnull Object[] args, int index, long def ) throws LuaException
{
return dan200.computercraft.api.lua.ArgumentHelper.optLong( args, index, def );
Object value = index < args.length ? args[index] : null;
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
{
return dan200.computercraft.api.lua.ArgumentHelper.optFiniteDouble( args, index, def );
return checkReal( index, optNumber( args, index, def ) );
}
public static boolean optBoolean( @Nonnull Object[] args, int index, boolean def ) throws LuaException
{
return dan200.computercraft.api.lua.ArgumentHelper.optBoolean( args, index, def );
Object value = index < args.length ? args[index] : null;
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
{
return dan200.computercraft.api.lua.ArgumentHelper.optString( args, index, def );
Object value = index < args.length ? args[index] : null;
if( value == null )
{
return def;
}
else if( value instanceof String )
{
return (String) value;
}
else
{
throw badArgument( index, "string", value );
}
}
@SuppressWarnings( "unchecked" )
public static Map<Object, Object> optTable( @Nonnull Object[] args, int index, Map<Object, Object> def ) throws LuaException
{
return (Map<Object, Object>) dan200.computercraft.api.lua.ArgumentHelper.optTable( args, index, def );
Object value = index < args.length ? args[index] : null;
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.function.Function;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
public class FSAPI implements ILuaAPI
{

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,17 +6,14 @@
package dan200.computercraft.core.apis;
import dan200.computercraft.api.lua.ArgumentHelper;
import dan200.computercraft.api.lua.LuaException;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
import static dan200.computercraft.api.lua.ArgumentHelper.getNumericType;
/**
* Various helpers for tables.
* Various helpers for tables
*/
public final class TableHelper
{
@@ -203,7 +200,21 @@ public final class TableHelper
private static double checkReal( @Nonnull String key, double value ) throws LuaException
{
if( !Double.isFinite( value ) ) throw badKey( key, "number", getNumericType( value ) );
return value;
if( Double.isNaN( 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 static dan200.computercraft.api.lua.ArgumentHelper.*;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
public class TermAPI implements ILuaAPI
{
@@ -242,9 +242,9 @@ public class TermAPI implements ILuaAPI
}
else
{
double r = getFiniteDouble( args, 1 );
double g = getFiniteDouble( args, 2 );
double b = getFiniteDouble( args, 3 );
double r = getReal( args, 1 );
double g = getReal( args, 2 );
double b = getReal( args, 3 );
setColour( m_terminal, colour, r, g, b );
}
return null;

View File

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

View File

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

View File

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

View File

@@ -16,8 +16,8 @@ import java.io.IOException;
import java.nio.channels.Channel;
import java.nio.channels.SeekableByteChannel;
import static dan200.computercraft.api.lua.ArgumentHelper.optLong;
import static dan200.computercraft.api.lua.ArgumentHelper.optString;
import static dan200.computercraft.core.apis.ArgumentHelper.optLong;
import static dan200.computercraft.core.apis.ArgumentHelper.optString;
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 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
* @throws HTTPRequestException If the host is not permitted.

View File

@@ -20,8 +20,6 @@ import java.util.function.Consumer;
/**
* 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
{
@@ -44,9 +42,8 @@ public abstract class Resource<T extends Resource<T>> implements Closeable
}
/**
* Checks if this has been cancelled. If so, it'll clean up any existing resources and cancel any pending futures.
*
* @return Whether this resource has been closed.
* Checks if this has been cancelled. If so, it'll clean up any
* existing resources and cancel any pending futures.
*/
public final boolean checkClosed()
{
@@ -83,7 +80,6 @@ public abstract class Resource<T extends Resource<T>> implements Closeable
/**
* 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
* @return The weak reference.
*/

View File

@@ -14,8 +14,6 @@ import java.util.function.Supplier;
/**
* 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>>
{

View File

@@ -12,8 +12,6 @@ import java.util.function.Supplier;
/**
* 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>
{

View File

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

View File

@@ -226,11 +226,7 @@ public final class HttpRequestHandler extends SimpleChannelInboundHandler<HttpOb
}
/**
* 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.
* Determine the redirect from this response
*/
private URI getRedirect( HttpResponseStatus status, HttpHeaders headers )
{

View File

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

View File

@@ -7,9 +7,7 @@
package dan200.computercraft.core.computer;
import com.google.common.base.Objects;
import dan200.computercraft.api.filesystem.IWritableMount;
import dan200.computercraft.api.lua.ILuaAPI;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IWorkMonitor;
import dan200.computercraft.core.apis.IAPIEnvironment;
import dan200.computercraft.core.filesystem.FileSystem;
@@ -219,37 +217,4 @@ public class Computer
{
executor.addApi( api );
}
@Deprecated
public IPeripheral getPeripheral( int side )
{
return internalEnvironment.getPeripheral( ComputerSide.valueOf( side ) );
}
@Deprecated
public void setPeripheral( int side, IPeripheral peripheral )
{
internalEnvironment.setPeripheral( ComputerSide.valueOf( side ), peripheral );
}
@Deprecated
public void addAPI( dan200.computercraft.core.apis.ILuaAPI api )
{
addApi( api );
}
@Deprecated
public void advance( double dt )
{
tick();
}
@Deprecated
public IWritableMount getRootMount()
{
return executor.getRootMount();
}
@Deprecated
public static final String[] s_sideNames = ComputerSide.NAMES;
}

View File

@@ -268,7 +268,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 args The event's arguments

View File

@@ -6,11 +6,13 @@
package dan200.computercraft.core.computer;
import net.minecraft.util.Direction;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* A side on a computer. Unlike {@link net.minecraft.util.EnumFacing}, this is relative to the direction the computer is
* A side on a computer. Unlike {@link Direction}, this is relative to the direction the computer is
* facing..
*/
public enum ComputerSide

View File

@@ -50,7 +50,7 @@ import static dan200.computercraft.core.computer.TimeoutState.TIMEOUT;
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
*/
@@ -83,7 +83,7 @@ public final class ComputerThread
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;
@@ -105,7 +105,7 @@ public final class ComputerThread
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 ) -> {
if( a == b ) return 0; // Should never happen, but let's be consistent here
@@ -126,7 +126,7 @@ public final class ComputerThread
private ComputerThread() {}
/**
* Start the computer thread.
* Start the computer thread
*/
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
* be called from {@code enqueue}.
@@ -244,8 +244,6 @@ public final class ComputerThread
* {@link #minimumVirtualRuntime} based on the current tasks.
*
* 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 )
{
@@ -323,7 +321,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
* @see #DEFAULT_LATENCY
@@ -338,7 +336,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.
*/

View File

@@ -36,12 +36,12 @@ import java.util.concurrent.TimeUnit;
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 );
/**
* 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 );
@@ -111,8 +111,6 @@ public final class TimeoutState
/**
* If the machine should be passively aborted.
*
* @return {@code true} if we should throw a timeout error.
*/
public boolean isSoftAborted()
{
@@ -120,9 +118,7 @@ public final class TimeoutState
}
/**
* Determine if the machine should be forcibly aborted.
*
* @return {@code true} if the machine should be forcibly shut down.
* If the machine should be forcibly aborted.
*/
public boolean isHardAborted()
{
@@ -150,7 +146,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()
*/

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